From 06fe9fb4182177fb046e6d934f80254dd90956ea Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Mon, 28 Sep 2009 21:43:57 -0400 Subject: tree-wide: fix a very frequent spelling mistake something-bility is spelled as something-blity so a grep for 'blit' would find these lines this is so trivial that I didn't split it by subsystem / copy additional maintainers - all changes are to comments The only purpose is to get fewer false positives when grepping around the kernel sources. Signed-off-by: Dirk Hohndel Signed-off-by: Jiri Kosina --- drivers/media/dvb/dvb-core/dvb_net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 0241a7c5c34..8b8558fcb04 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -1396,7 +1396,7 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file, return ret; } - /* binary compatiblity cruft */ + /* binary compatibility cruft */ case __NET_ADD_IF_OLD: { struct __dvb_net_if_old *dvbnetif = parg; -- cgit v1.2.3-70-g09d2 From b71a8eb0fa64ec6d00175f479e3ef851703568af Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 6 Oct 2009 12:42:51 +0200 Subject: tree-wide: fix typos "selct" + "slect" -> "select" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch was generated by git grep -E -i -l 's(le|el)ct' | xargs -r perl -p -i -e 's/([Ss])(le|el)ct/$1elect/ with only skipping net/netfilter/xt_SECMARK.c and include/linux/netfilter/xt_SECMARK.h which have a struct member called selctx. Signed-off-by: Uwe Kleine-König Signed-off-by: Jiri Kosina --- drivers/media/video/ov772x.c | 2 +- drivers/scsi/aic7xxx/aic79xx.seq | 2 +- drivers/scsi/aic7xxx/aic79xx_osm.c | 2 +- drivers/scsi/aic7xxx/aic7xxx.seq | 2 +- drivers/scsi/aic7xxx/aic7xxx_osm.c | 2 +- drivers/scsi/dc395x.c | 2 +- include/linux/spi/spi_bitbang.h | 2 +- kernel/time/clocksource.c | 2 +- sound/pci/hda/patch_cirrus.c | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c index eccb40ab7fe..20522933346 100644 --- a/drivers/media/video/ov772x.c +++ b/drivers/media/video/ov772x.c @@ -247,7 +247,7 @@ /* COM5 */ #define AFR_ON_OFF 0x80 /* Auto frame rate control ON/OFF selection */ -#define AFR_SPPED 0x40 /* Auto frame rate control speed slection */ +#define AFR_SPPED 0x40 /* Auto frame rate control speed selection */ /* Auto frame rate max rate control */ #define AFR_NO_RATE 0x00 /* No reduction of frame rate */ #define AFR_1p2 0x10 /* Max reduction to 1/2 frame rate */ diff --git a/drivers/scsi/aic7xxx/aic79xx.seq b/drivers/scsi/aic7xxx/aic79xx.seq index 58bc17591b5..3b66b5ae3d9 100644 --- a/drivers/scsi/aic7xxx/aic79xx.seq +++ b/drivers/scsi/aic7xxx/aic79xx.seq @@ -1281,7 +1281,7 @@ END_CRITICAL; * Is it a disconnect message? Set a flag in the SCB to remind us * and await the bus going free. If this is an untagged transaction * store the SCB id for it in our untagged target table for lookup on - * a reselction. + * a reselection. */ mesgin_disconnect: /* diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 75b23317bd2..1222a7ac698 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -2335,7 +2335,7 @@ ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd) /* * The sequencer will never re-reference the * in-core SCB. To make sure we are notified - * during reslection, set the MK_MESSAGE flag in + * during reselection, set the MK_MESSAGE flag in * the card's copy of the SCB. */ ahd_outb(ahd, SCB_CONTROL, diff --git a/drivers/scsi/aic7xxx/aic7xxx.seq b/drivers/scsi/aic7xxx/aic7xxx.seq index 15196390e28..5a4cfc954a9 100644 --- a/drivers/scsi/aic7xxx/aic7xxx.seq +++ b/drivers/scsi/aic7xxx/aic7xxx.seq @@ -1693,7 +1693,7 @@ if ((ahc->flags & AHC_INITIATORROLE) != 0) { * Is it a disconnect message? Set a flag in the SCB to remind us * and await the bus going free. If this is an untagged transaction * store the SCB id for it in our untagged target table for lookup on - * a reselction. + * a reselection. */ mesgin_disconnect: /* diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index fd2b9785ff4..8cb05dc8e6a 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -2290,7 +2290,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) * In the non-paging case, the sequencer will * never re-reference the in-core SCB. * To make sure we are notified during - * reslection, set the MK_MESSAGE flag in + * reselection, set the MK_MESSAGE flag in * the card's copy of the SCB. */ if ((ahc->flags & AHC_PAGESCBS) == 0) { diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index 075e2397273..6c59c02c1ed 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -1509,7 +1509,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb, * Try anyway? * * We could, BUT: Sometimes the TRM_S1040 misses to produce a Selection - * Timeout, a Disconnect or a Reselction IRQ, so we would be screwed! + * Timeout, a Disconnect or a Reselection IRQ, so we would be screwed! * (This is likely to be a bug in the hardware. Obviously, most people * only have one initiator per SCSI bus.) * Instead let this fail and have the timer make sure the command is diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h index eed4254bd50..3274c507b8a 100644 --- a/include/linux/spi/spi_bitbang.h +++ b/include/linux/spi/spi_bitbang.h @@ -15,7 +15,7 @@ * Some hardware works well with requests at spi_transfer scope: * * - Drivers leveraging smarter hardware, with fifos or DMA; or for half - * duplex (MicroWire) controllers. Provide chipslect() and txrx_bufs(), + * duplex (MicroWire) controllers. Provide chipselect() and txrx_bufs(), * and custom setup()/cleanup() methods. */ diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 5e18c6ab2c6..c403567f78c 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c @@ -580,7 +580,7 @@ sysfs_show_current_clocksources(struct sys_device *dev, * @count: length of buffer * * Takes input from sysfs interface for manually overriding the default - * clocksource selction. + * clocksource selection. */ static ssize_t sysfs_override_clocksource(struct sys_device *dev, struct sysdev_attribute *attr, diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 8ba306856d3..7b0446fa600 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -947,7 +947,7 @@ static void init_input(struct hda_codec *codec) coef |= 0x0500; /* DMIC2 enable 2 channels, disable GPIO1 */ if (is_active_pin(codec, CS_DMIC1_PIN_NID)) coef |= 0x1800; /* DMIC1 enable 2 channels, disable GPIO0 - * No effect if SPDIF_OUT2 is slected in + * No effect if SPDIF_OUT2 is selected in * IDX_SPDIF_CTL. */ cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); -- cgit v1.2.3-70-g09d2 From 21ae2956ce289f61f11863cc67080f9a28101ae0 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 7 Oct 2009 15:21:09 +0200 Subject: tree-wide: fix typos "aquire" -> "acquire", "cumsumed" -> "consumed" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch was generated by git grep -E -i -l '[Aa]quire' | xargs -r perl -p -i -e 's/([Aa])quire/$1cquire/' and the cumsumed was found by checking the diff for aquire. Signed-off-by: Uwe Kleine-König Signed-off-by: Jiri Kosina --- drivers/cpuidle/governor.c | 4 ++-- drivers/infiniband/hw/cxgb3/cxio_hal.c | 2 +- drivers/media/dvb/frontends/drx397xD.c | 2 +- drivers/net/ps3_gelic_wireless.h | 2 +- drivers/net/qla3xxx.c | 2 +- drivers/net/wireless/b43/main.c | 2 +- drivers/net/wireless/b43legacy/main.c | 2 +- include/linux/dm-log-userspace.h | 2 +- mm/kmemleak.c | 4 ++-- mm/memcontrol.c | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/media') diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c index 70b59642a70..724c164d31c 100644 --- a/drivers/cpuidle/governor.c +++ b/drivers/cpuidle/governor.c @@ -21,7 +21,7 @@ struct cpuidle_governor *cpuidle_curr_governor; * __cpuidle_find_governor - finds a governor of the specified name * @str: the name * - * Must be called with cpuidle_lock aquired. + * Must be called with cpuidle_lock acquired. */ static struct cpuidle_governor * __cpuidle_find_governor(const char *str) { @@ -39,7 +39,7 @@ static struct cpuidle_governor * __cpuidle_find_governor(const char *str) * @gov: the new target governor * * NOTE: "gov" can be NULL to specify disabled - * Must be called with cpuidle_lock aquired. + * Must be called with cpuidle_lock acquired. */ int cpuidle_switch_governor(struct cpuidle_governor *gov) { diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c index 72ed3396b72..0677fc7dfd5 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.c +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c @@ -589,7 +589,7 @@ static int cxio_hal_destroy_ctrl_qp(struct cxio_rdev *rdev_p) /* write len bytes of data into addr (32B aligned address) * If data is NULL, clear len byte of memory to zero. - * caller aquires the ctrl_qp lock before the call + * caller acquires the ctrl_qp lock before the call */ static int cxio_hal_ctrl_qp_write_mem(struct cxio_rdev *rdev_p, u32 addr, u32 len, void *data) diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c index 01007553522..868b78bfae7 100644 --- a/drivers/media/dvb/frontends/drx397xD.c +++ b/drivers/media/dvb/frontends/drx397xD.c @@ -81,7 +81,7 @@ static struct { #include "drx397xD_fw.h" }; -/* use only with writer lock aquired */ +/* use only with writer lock acquired */ static void _drx_release_fw(struct drx397xD_state *s, enum fw_ix ix) { memset(&fw[ix].data[0], 0, sizeof(fw[0].data)); diff --git a/drivers/net/ps3_gelic_wireless.h b/drivers/net/ps3_gelic_wireless.h index 5b631c6c977..0a88b535197 100644 --- a/drivers/net/ps3_gelic_wireless.h +++ b/drivers/net/ps3_gelic_wireless.h @@ -199,7 +199,7 @@ struct gelic_eurus_rssi_info { /* for 'stat' member of gelic_wl_info */ enum gelic_wl_info_status_bit { GELIC_WL_STAT_CONFIGURED, - GELIC_WL_STAT_CH_INFO, /* ch info aquired */ + GELIC_WL_STAT_CH_INFO, /* ch info acquired */ GELIC_WL_STAT_ESSID_SET, /* ESSID specified by userspace */ GELIC_WL_STAT_BSSID_SET, /* BSSID specified by userspace */ GELIC_WL_STAT_WPA_PSK_SET, /* PMK specified by userspace */ diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index 4c610511eb4..f72643313ba 100644 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -3651,7 +3651,7 @@ static int ql_adapter_up(struct ql3_adapter *qdev) ql_sem_unlock(qdev, QL_DRVR_SEM_MASK); } else { printk(KERN_ERR PFX - "%s: Could not aquire driver lock.\n", + "%s: Could not acquire driver lock.\n", ndev->name); goto err_lock; } diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 86f35827f00..f66efea6166 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2955,7 +2955,7 @@ static void do_periodic_work(struct b43_wldev *dev) /* Periodic work locking policy: * The whole periodic work handler is protected by * wl->mutex. If another lock is needed somewhere in the - * pwork callchain, it's aquired in-place, where it's needed. + * pwork callchain, it's acquired in-place, where it's needed. */ static void b43_periodic_work_handler(struct work_struct *work) { diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 4b60148a5e6..881784b18b0 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -2277,7 +2277,7 @@ static void do_periodic_work(struct b43legacy_wldev *dev) /* Periodic work locking policy: * The whole periodic work handler is protected by * wl->mutex. If another lock is needed somewhere in the - * pwork callchain, it's aquired in-place, where it's needed. + * pwork callchain, it's acquired in-place, where it's needed. */ static void b43legacy_periodic_work_handler(struct work_struct *work) { diff --git a/include/linux/dm-log-userspace.h b/include/linux/dm-log-userspace.h index 8a1f972c0fe..0c3c3a2110c 100644 --- a/include/linux/dm-log-userspace.h +++ b/include/linux/dm-log-userspace.h @@ -363,7 +363,7 @@ * various request types above. The remaining 24-bits are currently * set to zero and are reserved for future use and compatibility concerns. * - * User-space should always use DM_ULOG_REQUEST_TYPE to aquire the + * User-space should always use DM_ULOG_REQUEST_TYPE to acquire the * request type from the 'request_type' field to maintain forward compatibility. */ #define DM_ULOG_REQUEST_MASK 0xFF diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 8bf765c4f58..13f33b3081e 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -1050,8 +1050,8 @@ static void scan_object(struct kmemleak_object *object) unsigned long flags; /* - * Once the object->lock is aquired, the corresponding memory block - * cannot be freed (the same lock is aquired in delete_object). + * Once the object->lock is acquired, the corresponding memory block + * cannot be freed (the same lock is acquired in delete_object). */ spin_lock_irqsave(&object->lock, flags); if (object->flags & OBJECT_NO_SCAN) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index f99f5991d6b..7226e60e52a 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1720,7 +1720,7 @@ int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm, /* * While swap-in, try_charge -> commit or cancel, the page is locked. * And when try_charge() successfully returns, one refcnt to memcg without - * struct page_cgroup is aquired. This refcnt will be cumsumed by + * struct page_cgroup is acquired. This refcnt will be consumed by * "commit()" or removed by "cancel()" */ int mem_cgroup_try_charge_swapin(struct mm_struct *mm, -- cgit v1.2.3-70-g09d2 From 9d440a087b9f1b43acbcad2a45d8605059b82e59 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Tue, 29 Sep 2009 02:19:00 +0200 Subject: media/video: add __init/__exit macros to various drivers Trivial patch which adds the __init/__exit macros to the module_init/ module_exit functions of the following drivers in media video: drivers/media/video/ivtv/ivtv-driver.c drivers/media/video/cx18/cx18-driver.c drivers/media/video/davinci/dm355_ccdc.c drivers/media/video/davinci/dm644x_ccdc.c drivers/media/video/saa7164/saa7164-core.c drivers/media/video/saa7134/saa7134-core.c drivers/media/video/cx23885/cx23885-core.c Signed-off-by: Peter Huewe Acked-by: Andy Walls Acked-by: Laurent Pinchart Acked-by: Muralidharan Karicheri Acked-By: Steven Toth Signed-off-by: Jiri Kosina --- drivers/media/video/cx18/cx18-driver.c | 4 ++-- drivers/media/video/cx23885/cx23885-core.c | 4 ++-- drivers/media/video/davinci/dm355_ccdc.c | 4 ++-- drivers/media/video/davinci/dm644x_ccdc.c | 4 ++-- drivers/media/video/ivtv/ivtv-driver.c | 4 ++-- drivers/media/video/saa7134/saa7134-core.c | 4 ++-- drivers/media/video/saa7164/saa7164-core.c | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 6dd51e27582..e12082b8a08 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -1200,7 +1200,7 @@ static struct pci_driver cx18_pci_driver = { .remove = cx18_remove, }; -static int module_start(void) +static int __init module_start(void) { printk(KERN_INFO "cx18: Start initialization, version %s\n", CX18_VERSION); @@ -1224,7 +1224,7 @@ static int module_start(void) return 0; } -static void module_cleanup(void) +static void __exit module_cleanup(void) { pci_unregister_driver(&cx18_pci_driver); } diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index c31284ba19d..fa2d350e20f 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -1957,7 +1957,7 @@ static struct pci_driver cx23885_pci_driver = { .resume = NULL, }; -static int cx23885_init(void) +static int __init cx23885_init(void) { printk(KERN_INFO "cx23885 driver version %d.%d.%d loaded\n", (CX23885_VERSION_CODE >> 16) & 0xff, @@ -1970,7 +1970,7 @@ static int cx23885_init(void) return pci_register_driver(&cx23885_pci_driver); } -static void cx23885_fini(void) +static void __exit cx23885_fini(void) { pci_unregister_driver(&cx23885_pci_driver); } diff --git a/drivers/media/video/davinci/dm355_ccdc.c b/drivers/media/video/davinci/dm355_ccdc.c index 4629cabe3f2..56fbefe036a 100644 --- a/drivers/media/video/davinci/dm355_ccdc.c +++ b/drivers/media/video/davinci/dm355_ccdc.c @@ -959,7 +959,7 @@ static struct ccdc_hw_device ccdc_hw_dev = { }, }; -static int dm355_ccdc_init(void) +static int __init dm355_ccdc_init(void) { printk(KERN_NOTICE "dm355_ccdc_init\n"); if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0) @@ -969,7 +969,7 @@ static int dm355_ccdc_init(void) return 0; } -static void dm355_ccdc_exit(void) +static void __exit dm355_ccdc_exit(void) { vpfe_unregister_ccdc_device(&ccdc_hw_dev); } diff --git a/drivers/media/video/davinci/dm644x_ccdc.c b/drivers/media/video/davinci/dm644x_ccdc.c index 2f19a919f47..d5fa193f32d 100644 --- a/drivers/media/video/davinci/dm644x_ccdc.c +++ b/drivers/media/video/davinci/dm644x_ccdc.c @@ -859,7 +859,7 @@ static struct ccdc_hw_device ccdc_hw_dev = { }, }; -static int dm644x_ccdc_init(void) +static int __init dm644x_ccdc_init(void) { printk(KERN_NOTICE "dm644x_ccdc_init\n"); if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0) @@ -869,7 +869,7 @@ static int dm644x_ccdc_init(void) return 0; } -static void dm644x_ccdc_exit(void) +static void __exit dm644x_ccdc_exit(void) { vpfe_unregister_ccdc_device(&ccdc_hw_dev); } diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 463ec3457d7..7cdbc1a8f21 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -1361,7 +1361,7 @@ static struct pci_driver ivtv_pci_driver = { .remove = ivtv_remove, }; -static int module_start(void) +static int __init module_start(void) { printk(KERN_INFO "ivtv: Start initialization, version %s\n", IVTV_VERSION); @@ -1385,7 +1385,7 @@ static int module_start(void) return 0; } -static void module_cleanup(void) +static void __exit module_cleanup(void) { pci_unregister_driver(&ivtv_pci_driver); } diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index f87757fccc7..c673901cb2b 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -1319,7 +1319,7 @@ static struct pci_driver saa7134_pci_driver = { #endif }; -static int saa7134_init(void) +static int __init saa7134_init(void) { INIT_LIST_HEAD(&saa7134_devlist); printk(KERN_INFO "saa7130/34: v4l2 driver version %d.%d.%d loaded\n", @@ -1333,7 +1333,7 @@ static int saa7134_init(void) return pci_register_driver(&saa7134_pci_driver); } -static void saa7134_fini(void) +static void __exit saa7134_fini(void) { pci_unregister_driver(&saa7134_pci_driver); } diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c index 709affc3104..e6aa0fbd1e9 100644 --- a/drivers/media/video/saa7164/saa7164-core.c +++ b/drivers/media/video/saa7164/saa7164-core.c @@ -724,13 +724,13 @@ static struct pci_driver saa7164_pci_driver = { .resume = NULL, }; -static int saa7164_init(void) +static int __init saa7164_init(void) { printk(KERN_INFO "saa7164 driver loaded\n"); return pci_register_driver(&saa7164_pci_driver); } -static void saa7164_fini(void) +static void __exit saa7164_fini(void) { pci_unregister_driver(&saa7164_pci_driver); } -- cgit v1.2.3-70-g09d2 From 3addbb8075c00e2a2408c192bd1002dead26b2aa Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 5 Nov 2009 13:26:32 -0300 Subject: V4L/DVB (13321): radio-gemtek-pci: fix double mutex_lock Double mutexlock found by the Linux Driver Verification project and reported by Alexander Strakh. Signed-off-by: Hans Verkuil CC: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-gemtek-pci.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index c3f579de6e7..c6cf1166186 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c @@ -181,12 +181,10 @@ static void gemtek_pci_mute(struct gemtek_pci *card) static void gemtek_pci_unmute(struct gemtek_pci *card) { - mutex_lock(&card->lock); if (card->mute) { gemtek_pci_setfrequency(card, card->current_frequency); card->mute = false; } - mutex_unlock(&card->lock); } static int gemtek_pci_getsignal(struct gemtek_pci *card) -- cgit v1.2.3-70-g09d2 From f39c1ab3c3878f1a50ca129e55d17ae63215fcbe Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 9 Nov 2009 16:11:34 -0300 Subject: V4L/DVB (13343): v4l: add more missing linux/sched.h includes Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/mx1_camera.c | 1 + drivers/media/video/mx3_camera.c | 1 + drivers/media/video/sh_mobile_ceu_camera.c | 1 + drivers/media/video/videobuf-dma-contig.c | 1 + 4 files changed, 4 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index 5f37952c75c..72802291e81 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index dff2e5e2d8c..7db82bdf6f3 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 2f78b4f263f..55afe3e98e1 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c index 635ffc7b039..c3065c4bcba 100644 --- a/drivers/media/video/videobuf-dma-contig.c +++ b/drivers/media/video/videobuf-dma-contig.c @@ -19,6 +19,7 @@ #include #include #include +#include #include struct videobuf_dma_contig_memory { -- cgit v1.2.3-70-g09d2 From 64ff9ba5f1d771e8405ec766c31f6b32c9708285 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 9 Nov 2009 16:12:37 -0300 Subject: V4L/DVB (13344): soc-camera: properly initialise the device object when reusing Commit ef373189f62413803b7b816c972fc154c488cdc0 "fix use-after-free Oops, resulting from a driver-core API change" fixed the Oops, but didn't correct missing device object initialisation. This patch makes unloading and reloading of soc-camera host- and client-drivers possible again. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/soc_camera.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 36e617bd13c..95fdeb23c2c 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -1097,6 +1097,13 @@ static int default_s_crop(struct soc_camera_device *icd, struct v4l2_crop *a) return v4l2_subdev_call(sd, video, s_crop, a); } +static void soc_camera_device_init(struct device *dev, void *pdata) +{ + dev->platform_data = pdata; + dev->bus = &soc_camera_bus_type; + dev->release = dummy_release; +} + int soc_camera_host_register(struct soc_camera_host *ici) { struct soc_camera_host *ix; @@ -1158,6 +1165,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici) list_for_each_entry(icd, &devices, list) { if (icd->iface == ici->nr) { + void *pdata = icd->dev.platform_data; /* The bus->remove will be called */ device_unregister(&icd->dev); /* @@ -1169,6 +1177,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici) * device private data. */ memset(&icd->dev, 0, sizeof(icd->dev)); + soc_camera_device_init(&icd->dev, pdata); } } @@ -1200,10 +1209,7 @@ static int soc_camera_device_register(struct soc_camera_device *icd) * man, stay reasonable... */ return -ENOMEM; - icd->devnum = num; - icd->dev.bus = &soc_camera_bus_type; - - icd->dev.release = dummy_release; + icd->devnum = num; icd->use_count = 0; icd->host_priv = NULL; mutex_init(&icd->video_lock); @@ -1311,12 +1317,13 @@ static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev) icd->iface = icl->bus_id; icd->pdev = &pdev->dev; platform_set_drvdata(pdev, icd); - icd->dev.platform_data = icl; ret = soc_camera_device_register(icd); if (ret < 0) goto escdevreg; + soc_camera_device_init(&icd->dev, icl); + icd->user_width = DEFAULT_WIDTH; icd->user_height = DEFAULT_HEIGHT; -- cgit v1.2.3-70-g09d2 From 055e05a08b462feabbd6b7a33fd2b9f1f23d4476 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 9 Nov 2009 16:13:24 -0300 Subject: V4L/DVB (13345): soc-camera: sh_mobile_ceu_camera: call pm_runtime_disable pm_runtime_disable is needed if it failed or removed Signed-off-by: Kuninori Morimoto Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/sh_mobile_ceu_camera.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 55afe3e98e1..afdea0d26fc 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -1724,10 +1724,12 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev) err = soc_camera_host_register(&pcdev->ici); if (err) - goto exit_free_irq; + goto exit_free_clk; return 0; +exit_free_clk: + pm_runtime_disable(&pdev->dev); exit_free_irq: free_irq(pcdev->irq, pcdev); exit_release_mem: @@ -1748,6 +1750,7 @@ static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev) struct sh_mobile_ceu_dev, ici); soc_camera_host_unregister(soc_host); + pm_runtime_disable(&pdev->dev); free_irq(pcdev->irq, pcdev); if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) dma_release_declared_memory(&pdev->dev); -- cgit v1.2.3-70-g09d2 From 28f4ddd1e8e341907d8f4f4b9ebf9f441f30420a Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 4 Oct 2009 12:59:35 -0300 Subject: V4L/DVB (13366): em28xx: fix Reddo DVB-C USB TV Box GPIO Set device GPIOs only once. There is no need for .dvb_gpio to select between analog and digital because device is digital only. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-cards.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index bdb249bd9d5..c0fd5c6feea 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -1584,8 +1584,8 @@ struct em28xx_board em28xx_boards[] = { [EM2870_BOARD_REDDO_DVB_C_USB_BOX] = { .name = "Reddo DVB-C USB TV Box", .tuner_type = TUNER_ABSENT, + .tuner_gpio = reddo_dvb_c_usb_box, .has_dvb = 1, - .dvb_gpio = reddo_dvb_c_usb_box, }, }; const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); -- cgit v1.2.3-70-g09d2 From 934949d816004ff66e21adbab225e9cb7f20015a Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 9 Nov 2009 09:05:11 -0300 Subject: V4L/DVB (13371): davinci: remove stray duplicate config pointer The vpif_config struct was renamed to vpif_display_config, but there is still a stray vpif_config *config pointer in vpif_display.c, preventing it from compiling. Remove this old duplicate pointer. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/davinci/vpif_display.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c index c015da813dd..d14cfb200ed 100644 --- a/drivers/media/video/davinci/vpif_display.c +++ b/drivers/media/video/davinci/vpif_display.c @@ -1426,7 +1426,6 @@ static __init int vpif_probe(struct platform_device *pdev) struct vpif_display_config *config; int i, j = 0, k, q, m, err = 0; struct i2c_adapter *i2c_adap; - struct vpif_config *config; struct common_obj *common; struct channel_obj *ch; struct video_device *vfd; -- cgit v1.2.3-70-g09d2 From 8366fc390865bfb1497fe19a518fe5713f96ba3b Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Fri, 27 Nov 2009 11:24:13 +0100 Subject: media/radio: New driver for the radio FM module on Miro PCM20 sound card This is recreated driver for the FM module found on Miro PCM20 sound cards. This driver was removed around the 2.6.2x kernels because it relied on the removed OSS module. Now, it uses a current ALSA module (snd-miro) and is adapted to v4l2 layer. It provides only basic functionality: frequency changing and FM module muting. Signed-off-by: Krzysztof Helt Reviewed-by: Hans Verkuil Acked-by: Mauro Carvalho Chehab Signed-off-by: Takashi Iwai --- drivers/media/radio/Kconfig | 18 +++ drivers/media/radio/Makefile | 1 + drivers/media/radio/radio-miropcm20.c | 270 ++++++++++++++++++++++++++++++++++ 3 files changed, 289 insertions(+) create mode 100644 drivers/media/radio/radio-miropcm20.c (limited to 'drivers/media') diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index a87a477c87f..b134553eb3b 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -195,6 +195,24 @@ config RADIO_MAESTRO To compile this driver as a module, choose M here: the module will be called radio-maestro. +config RADIO_MIROPCM20 + tristate "miroSOUND PCM20 radio" + depends on ISA && VIDEO_V4L2 + select SND_MIRO + ---help--- + Choose Y here if you have this FM radio card. You also need to enable + the ALSA sound system. This choice automatically selects the ALSA + sound card driver "Miro miroSOUND PCM1pro/PCM12/PCM20radio" as this + is required for the radio-miropcm20. + + In order to control your radio card, you will need to use programs + that are compatible with the Video For Linux API. Information on + this API and pointers to "v4l" programs may be found at + . + + To compile this driver as a module, choose M here: the + module will be called radio-miropcm20. + config RADIO_SF16FMI tristate "SF16FMI Radio" depends on ISA && VIDEO_V4L2 diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile index 2a1be3bf4f7..8a63d543ae4 100644 --- a/drivers/media/radio/Makefile +++ b/drivers/media/radio/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_RADIO_TRUST) += radio-trust.o obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o +obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o obj-$(CONFIG_USB_DSBR) += dsbr100.o obj-$(CONFIG_RADIO_SI470X) += si470x/ obj-$(CONFIG_USB_MR800) += radio-mr800.o diff --git a/drivers/media/radio/radio-miropcm20.c b/drivers/media/radio/radio-miropcm20.c new file mode 100644 index 00000000000..4ff885445fd --- /dev/null +++ b/drivers/media/radio/radio-miropcm20.c @@ -0,0 +1,270 @@ +/* Miro PCM20 radio driver for Linux radio support + * (c) 1998 Ruurd Reitsma + * Thanks to Norberto Pellici for the ACI device interface specification + * The API part is based on the radiotrack driver by M. Kirkwood + * This driver relies on the aci mixer provided by the snd-miro + * ALSA driver. + * Look there for further info... + */ + +/* What ever you think about the ACI, version 0x07 is not very well! + * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono + * conditions... Robert + */ + +#include +#include +#include +#include +#include +#include + +static int radio_nr = -1; +module_param(radio_nr, int, 0); +MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)"); + +static int mono; +module_param(mono, bool, 0); +MODULE_PARM_DESC(mono, "Force tuner into mono mode."); + +struct pcm20 { + struct v4l2_device v4l2_dev; + struct video_device vdev; + unsigned long freq; + int muted; + struct snd_miro_aci *aci; +}; + +static struct pcm20 pcm20_card = { + .freq = 87*16000, + .muted = 1, +}; + +static int pcm20_mute(struct pcm20 *dev, unsigned char mute) +{ + dev->muted = mute; + return snd_aci_cmd(dev->aci, ACI_SET_TUNERMUTE, mute, -1); +} + +static int pcm20_stereo(struct pcm20 *dev, unsigned char stereo) +{ + return snd_aci_cmd(dev->aci, ACI_SET_TUNERMONO, !stereo, -1); +} + +static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq) +{ + unsigned char freql; + unsigned char freqh; + struct snd_miro_aci *aci = dev->aci; + + dev->freq = freq; + + freq /= 160; + if (!(aci->aci_version == 0x07 || aci->aci_version >= 0xb0)) + freq /= 10; /* I don't know exactly which version + * needs this hack */ + freql = freq & 0xff; + freqh = freq >> 8; + + pcm20_stereo(dev, !mono); + return snd_aci_cmd(aci, ACI_WRITE_TUNE, freql, freqh); +} + +static const struct v4l2_file_operations pcm20_fops = { + .owner = THIS_MODULE, + .ioctl = video_ioctl2, +}; + +static int vidioc_querycap(struct file *file, void *priv, + struct v4l2_capability *v) +{ + strlcpy(v->driver, "Miro PCM20", sizeof(v->driver)); + strlcpy(v->card, "Miro PCM20", sizeof(v->card)); + strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); + v->version = 0x1; + v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + return 0; +} + +static int vidioc_g_tuner(struct file *file, void *priv, + struct v4l2_tuner *v) +{ + if (v->index) /* Only 1 tuner */ + return -EINVAL; + strlcpy(v->name, "FM", sizeof(v->name)); + v->type = V4L2_TUNER_RADIO; + v->rangelow = 87*16000; + v->rangehigh = 108*16000; + v->signal = 0xffff; + v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; + v->capability = V4L2_TUNER_CAP_LOW; + v->audmode = V4L2_TUNER_MODE_MONO; + return 0; +} + +static int vidioc_s_tuner(struct file *file, void *priv, + struct v4l2_tuner *v) +{ + return v->index ? -EINVAL : 0; +} + +static int vidioc_g_frequency(struct file *file, void *priv, + struct v4l2_frequency *f) +{ + struct pcm20 *dev = video_drvdata(file); + + if (f->tuner != 0) + return -EINVAL; + + f->type = V4L2_TUNER_RADIO; + f->frequency = dev->freq; + return 0; +} + + +static int vidioc_s_frequency(struct file *file, void *priv, + struct v4l2_frequency *f) +{ + struct pcm20 *dev = video_drvdata(file); + + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) + return -EINVAL; + + dev->freq = f->frequency; + pcm20_setfreq(dev, f->frequency); + return 0; +} + +static int vidioc_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *qc) +{ + switch (qc->id) { + case V4L2_CID_AUDIO_MUTE: + return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); + } + return -EINVAL; +} + +static int vidioc_g_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct pcm20 *dev = video_drvdata(file); + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + ctrl->value = dev->muted; + break; + default: + return -EINVAL; + } + return 0; +} + +static int vidioc_s_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct pcm20 *dev = video_drvdata(file); + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + pcm20_mute(dev, ctrl->value); + break; + default: + return -EINVAL; + } + return 0; +} + +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) +{ + *i = 0; + return 0; +} + +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) +{ + return i ? -EINVAL : 0; +} + +static int vidioc_g_audio(struct file *file, void *priv, + struct v4l2_audio *a) +{ + a->index = 0; + strlcpy(a->name, "Radio", sizeof(a->name)); + a->capability = V4L2_AUDCAP_STEREO; + return 0; +} + +static int vidioc_s_audio(struct file *file, void *priv, + struct v4l2_audio *a) +{ + return a->index ? -EINVAL : 0; +} + +static const struct v4l2_ioctl_ops pcm20_ioctl_ops = { + .vidioc_querycap = vidioc_querycap, + .vidioc_g_tuner = vidioc_g_tuner, + .vidioc_s_tuner = vidioc_s_tuner, + .vidioc_g_frequency = vidioc_g_frequency, + .vidioc_s_frequency = vidioc_s_frequency, + .vidioc_queryctrl = vidioc_queryctrl, + .vidioc_g_ctrl = vidioc_g_ctrl, + .vidioc_s_ctrl = vidioc_s_ctrl, + .vidioc_g_audio = vidioc_g_audio, + .vidioc_s_audio = vidioc_s_audio, + .vidioc_g_input = vidioc_g_input, + .vidioc_s_input = vidioc_s_input, +}; + +static int __init pcm20_init(void) +{ + struct pcm20 *dev = &pcm20_card; + struct v4l2_device *v4l2_dev = &dev->v4l2_dev; + int res; + + dev->aci = snd_aci_get_aci(); + if (dev->aci == NULL) { + v4l2_err(v4l2_dev, + "you must load the snd-miro driver first!\n"); + return -ENODEV; + } + strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name)); + + + res = v4l2_device_register(NULL, v4l2_dev); + if (res < 0) { + v4l2_err(v4l2_dev, "could not register v4l2_device\n"); + return -EINVAL; + } + + strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); + dev->vdev.v4l2_dev = v4l2_dev; + dev->vdev.fops = &pcm20_fops; + dev->vdev.ioctl_ops = &pcm20_ioctl_ops; + dev->vdev.release = video_device_release_empty; + video_set_drvdata(&dev->vdev, dev); + + if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) + goto fail; + + v4l2_info(v4l2_dev, "Mirosound PCM20 Radio tuner\n"); + return 0; +fail: + v4l2_device_unregister(v4l2_dev); + return -EINVAL; +} + +MODULE_AUTHOR("Ruurd Reitsma, Krzysztof Helt"); +MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card."); +MODULE_LICENSE("GPL"); + +static void __exit pcm20_cleanup(void) +{ + struct pcm20 *dev = &pcm20_card; + + video_unregister_device(&dev->vdev); + v4l2_device_unregister(&dev->v4l2_dev); +} + +module_init(pcm20_init); +module_exit(pcm20_cleanup); -- cgit v1.2.3-70-g09d2 From d02b217a719a8c4debf66ea81ea1b95dbb00e265 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 20 Nov 2009 16:16:52 -0300 Subject: V4L/DVB (13412): SMS_SIANO_MDTV should depend on HAS_DMA When building for Sun 3: drivers/built-in.o: In function `smscore_unregister_device': drivers/media/dvb/siano/smscoreapi.c:723: undefined reference to `dma_free_coherent' drivers/built-in.o: In function `smscore_register_device': drivers/media/dvb/siano/smscoreapi.c:365: undefined reference to `dma_alloc_coherent' Signed-off-by: Geert Uytterhoeven Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/Kconfig b/drivers/media/dvb/siano/Kconfig index 8c1aed77ea3..85a222c4eaa 100644 --- a/drivers/media/dvb/siano/Kconfig +++ b/drivers/media/dvb/siano/Kconfig @@ -4,7 +4,7 @@ config SMS_SIANO_MDTV tristate "Siano SMS1xxx based MDTV receiver" - depends on DVB_CORE && INPUT + depends on DVB_CORE && INPUT && HAS_DMA ---help--- Choose Y or M here if you have MDTV receiver with a Siano chipset. -- cgit v1.2.3-70-g09d2 From 0bc3518019f917a370935055f07698a4e9b3ea20 Mon Sep 17 00:00:00 2001 From: Robert Lowery Date: Sun, 8 Nov 2009 00:00:11 -0300 Subject: V4L/DVB (13436): cxusb: Fix hang on DViCO FusionHDTV DVB-T Dual Digital 4 (rev 1) Address yet another regression introduced by the introduction of the zl10353 disable_i2c_gate field. djh - I unmangled the patch which apparently got screwed up in the user's email client. Signed-off-by: Robert Lowery Signed-off-by: Devin Heitmueller CC: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/cxusb.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index f65591fb7ce..2a53dd096ee 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -663,6 +663,14 @@ static struct zl10353_config cxusb_zl10353_xc3028_config = { .parallel_ts = 1, }; +static struct zl10353_config cxusb_zl10353_xc3028_config_no_i2c_gate = { + .demod_address = 0x0f, + .if2 = 45600, + .no_tuner = 1, + .parallel_ts = 1, + .disable_i2c_gate_ctrl = 1, +}; + static struct mt352_config cxusb_mt352_xc3028_config = { .demod_address = 0x0f, .if2 = 4560, @@ -894,7 +902,7 @@ static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap) cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); if ((adap->fe = dvb_attach(zl10353_attach, - &cxusb_zl10353_xc3028_config, + &cxusb_zl10353_xc3028_config_no_i2c_gate, &adap->dev->i2c_adap)) == NULL) return -EIO; -- cgit v1.2.3-70-g09d2 From 9807362e4768cf807c9cfad3c10243020365d1ce Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 25 Nov 2009 14:32:57 -0300 Subject: V4L/DVB (13481): sh_mobile_ceu_camera: fix compile warning Trivial fix for this compile warning: v4l/sh_mobile_ceu_camera.c:1789: warning: label 'exit_free_irq' defined but not used Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/sh_mobile_ceu_camera.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index afdea0d26fc..9c8b7c7b89e 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -1730,7 +1730,6 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev) exit_free_clk: pm_runtime_disable(&pdev->dev); -exit_free_irq: free_irq(pcdev->irq, pcdev); exit_release_mem: if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) -- cgit v1.2.3-70-g09d2 From 361c95119a60adb7f84946af648b7c87cdc55e17 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 26 Nov 2009 12:22:11 -0300 Subject: V4L/DVB (13530): Fix wrong parameter order in memset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Edwin Török found the following: In function ‘memset’, inlined from ‘ir_input_init’ at drivers/media/common/ir-functions.c:67: /home/edwin/builds/linux-2.6/arch/x86/include/asm/string_64.h:61: warning: call to ‘__warn_memset_zero_len’ declared with attribute warning: memset used with constant zero length parameter; this could be due to transposed parameters memset(ir->ir_codes, sizeof(ir->ir_codes), 0); In actual practice the only caller I can find happens to already have cleared the buffer before calling ir_input_init. Signed-off-by: Alan Cox Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-functions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c index 655474b29e2..abd4791acb0 100644 --- a/drivers/media/common/ir-functions.c +++ b/drivers/media/common/ir-functions.c @@ -64,7 +64,7 @@ void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, ir->ir_type = ir_type; - memset(ir->ir_codes, sizeof(ir->ir_codes), 0); + memset(ir->ir_codes, 0, sizeof(ir->ir_codes)); /* * FIXME: This is a temporary workaround to use the new IR tables -- cgit v1.2.3-70-g09d2 From 4c4cb1b1605e50983afd7924980c9434b214599f Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 1 Dec 2009 13:17:41 -0800 Subject: drivers/media/dvb/dvb-core/dvb_frontend.c: needs semaphore.h Fixes: v4l/dvb_frontend.c: In function 'dvb_frontend_stop': v4l/dvb_frontend.c:707: error: implicit declaration of function 'init_MUTEX' Addresses http://bugzilla.kernel.org/show_bug.cgi?id=14609 Reported-by: Cc: Mauro Carvalho Chehab Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-core/dvb_frontend.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index ddf639ed2fd..98082416aa5 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3-70-g09d2 From af901ca181d92aac3a7dc265144a9081a86d8f39 Mon Sep 17 00:00:00 2001 From: André Goddard Rosa Date: Sat, 14 Nov 2009 13:09:05 -0200 Subject: tree-wide: fix assorted typos all over the place MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That is "success", "unknown", "through", "performance", "[re|un]mapping" , "access", "default", "reasonable", "[con]currently", "temperature" , "channel", "[un]used", "application", "example","hierarchy", "therefore" , "[over|under]flow", "contiguous", "threshold", "enough" and others. Signed-off-by: André Goddard Rosa Signed-off-by: Jiri Kosina --- Documentation/ABI/testing/procfs-diskstats | 2 +- Documentation/ABI/testing/sysfs-block | 2 +- Documentation/DocBook/mtdnand.tmpl | 2 +- Documentation/DocBook/v4l/videodev2.h.xml | 2 +- Documentation/DocBook/writing-an-alsa-driver.tmpl | 2 +- Documentation/dvb/README.dvb-usb | 2 +- Documentation/lguest/lguest.c | 2 +- Documentation/scsi/ChangeLog.megaraid_sas | 2 +- Documentation/spi/spi-summary | 2 +- Documentation/sysctl/vm.txt | 2 +- Documentation/video4linux/gspca.txt | 2 +- Documentation/vm/page-types.c | 2 +- arch/alpha/mm/numa.c | 2 +- arch/arm/common/scoop.c | 2 +- .../mach-bcmring/include/mach/csp/dmacHw_priv.h | 2 +- arch/arm/mach-bcmring/include/mach/dma.h | 2 +- arch/arm/mach-lh7a40x/include/mach/hardware.h | 2 +- arch/arm/mach-orion5x/pci.c | 2 +- arch/arm/mach-pxa/include/mach/palmld.h | 2 +- arch/arm/mach-pxa/include/mach/palmt5.h | 2 +- arch/arm/mach-pxa/include/mach/palmtc.h | 2 +- arch/arm/mach-pxa/include/mach/palmte2.h | 2 +- arch/arm/mach-pxa/include/mach/palmtx.h | 2 +- arch/arm/mach-pxa/include/mach/palmz72.h | 2 +- arch/arm/mach-s3c6400/setup-sdhci.c | 2 +- arch/arm/mach-s3c6410/setup-sdhci.c | 2 +- arch/arm/mach-sa1100/dma.c | 2 +- arch/arm/plat-mxc/include/mach/iomux-mx3.h | 2 +- arch/arm/plat-mxc/include/mach/iomux-mxc91231.h | 2 +- arch/arm/plat-mxc/pwm.c | 2 +- arch/arm/plat-omap/dma.c | 2 +- arch/arm/plat-omap/include/mach/omap16xx.h | 2 +- arch/arm/plat-s3c24xx/include/plat/map.h | 2 +- arch/avr32/boards/hammerhead/Kconfig | 2 +- arch/blackfin/kernel/traps.c | 2 +- .../mach-bf518/include/mach/defBF51x_base.h | 4 +- .../mach-bf527/include/mach/defBF52x_base.h | 4 +- arch/blackfin/mach-bf537/include/mach/defBF534.h | 4 +- arch/blackfin/mach-bf548/include/mach/defBF544.h | 4 +- arch/blackfin/mach-bf548/include/mach/defBF547.h | 4 +- arch/blackfin/mach-bf548/include/mach/defBF548.h | 4 +- arch/blackfin/mach-bf548/include/mach/defBF549.h | 4 +- arch/cris/mm/fault.c | 2 +- arch/ia64/hp/common/sba_iommu.c | 2 +- arch/ia64/ia32/ia32_entry.S | 2 +- arch/ia64/include/asm/perfmon_default_smpl.h | 2 +- arch/ia64/include/asm/sn/shubio.h | 2 +- arch/ia64/kernel/esi.c | 2 +- arch/ia64/kernel/perfmon.c | 2 +- arch/m68k/ifpsp060/src/fpsp.S | 28 +++++----- arch/m68k/ifpsp060/src/pfpsp.S | 26 ++++----- arch/m68k/include/asm/bootinfo.h | 2 +- arch/microblaze/lib/memcpy.c | 2 +- arch/microblaze/lib/memmove.c | 2 +- arch/microblaze/lib/memset.c | 2 +- arch/mips/include/asm/mach-pnx833x/gpio.h | 2 +- arch/mips/include/asm/sgi/ioc.h | 2 +- arch/mips/include/asm/sibyte/sb1250_mac.h | 2 +- arch/mips/include/asm/sn/sn0/hubio.h | 2 +- arch/mips/kernel/smtc.c | 2 +- arch/mips/math-emu/dp_sub.c | 2 +- arch/mips/txx9/generic/smsc_fdc37m81x.c | 2 +- arch/powerpc/include/asm/reg_fsl_emb.h | 2 +- arch/powerpc/kernel/kgdb.c | 2 +- arch/powerpc/kernel/tau_6xx.c | 2 +- arch/powerpc/oprofile/op_model_cell.c | 4 +- arch/powerpc/platforms/52xx/mpc52xx_pci.c | 2 +- arch/powerpc/platforms/powermac/pci.c | 2 +- arch/powerpc/sysdev/dart_iommu.c | 2 +- arch/s390/math-emu/math.c | 4 +- arch/x86/include/asm/desc_defs.h | 4 +- arch/x86/include/asm/mmzone_32.h | 2 +- arch/x86/include/asm/uv/uv_bau.h | 2 +- arch/x86/kernel/acpi/boot.c | 2 +- arch/x86/kernel/amd_iommu.c | 4 +- arch/x86/kernel/cpu/perf_event.c | 2 +- arch/x86/kernel/kprobes.c | 4 +- arch/x86/mm/kmmio.c | 4 +- block/blk-iopoll.c | 2 +- drivers/ata/ata_piix.c | 2 +- drivers/ata/sata_fsl.c | 6 +-- drivers/atm/iphase.c | 2 +- drivers/base/dd.c | 2 +- drivers/bluetooth/btmrvl_sdio.c | 2 +- drivers/bluetooth/hci_ldisc.c | 2 +- drivers/char/mem.c | 2 +- drivers/char/mspec.c | 2 +- drivers/char/n_r3964.c | 2 +- drivers/char/rio/route.h | 2 +- drivers/crypto/hifn_795x.c | 2 +- drivers/dma/at_hdmac.c | 2 +- drivers/firewire/core-topology.c | 2 +- drivers/gpu/drm/drm_crtc.c | 4 +- drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/intel_fb.c | 2 +- drivers/gpu/drm/i915/intel_sdvo.c | 2 +- drivers/gpu/drm/radeon/r600.c | 4 +- drivers/gpu/drm/radeon/radeon_fb.c | 2 +- drivers/gpu/drm/radeon/radeon_state.c | 2 +- drivers/gpu/drm/radeon/radeon_ttm.c | 2 +- drivers/gpu/drm/radeon/rv770.c | 4 +- drivers/gpu/drm/ttm/ttm_bo_util.c | 2 +- drivers/hwmon/adm1029.c | 2 +- drivers/hwmon/lm93.c | 2 +- drivers/ieee1394/dv1394.c | 2 +- drivers/infiniband/hw/ipath/ipath_iba6110.c | 2 +- drivers/infiniband/hw/ipath/ipath_sd7220.c | 4 +- drivers/infiniband/hw/mlx4/qp.c | 2 +- drivers/input/serio/hp_sdc.c | 2 +- drivers/input/serio/hp_sdc_mlc.c | 2 +- drivers/input/touchscreen/atmel-wm97xx.c | 2 +- drivers/input/touchscreen/mainstone-wm97xx.c | 4 +- drivers/input/touchscreen/zylonite-wm97xx.c | 2 +- drivers/isdn/capi/capidrv.c | 2 +- drivers/isdn/hardware/eicon/di.c | 2 +- drivers/isdn/hardware/eicon/maintidi.c | 4 +- drivers/isdn/hardware/mISDN/hfcsusb.c | 2 +- drivers/isdn/hardware/mISDN/hfcsusb.h | 2 +- drivers/isdn/hardware/mISDN/mISDNisar.c | 2 +- drivers/isdn/hisax/hfc_usb.c | 2 +- drivers/isdn/i4l/isdn_ppp.c | 6 +-- drivers/isdn/i4l/isdn_ttyfax.c | 2 +- drivers/isdn/mISDN/dsp_core.c | 2 +- drivers/isdn/mISDN/tei.c | 2 +- drivers/macintosh/therm_windtunnel.c | 2 +- drivers/media/common/saa7146_i2c.c | 2 +- drivers/media/dvb/dvb-core/dvb_frontend.h | 2 +- drivers/media/dvb/dvb-usb/anysee.c | 2 +- drivers/media/dvb/dvb-usb/dibusb-mb.c | 2 +- drivers/media/dvb/dvb-usb/dvb-usb-remote.c | 2 +- drivers/media/dvb/dvb-usb/usb-urb.c | 4 +- drivers/media/dvb/frontends/au8522_decoder.c | 2 +- drivers/media/dvb/frontends/cx24110.c | 4 +- drivers/media/dvb/frontends/cx24113.c | 2 +- drivers/media/dvb/frontends/dib3000mb.c | 2 +- drivers/media/dvb/frontends/lgdt330x.c | 4 +- drivers/media/dvb/frontends/stb0899_drv.c | 2 +- drivers/media/dvb/ttpci/av7110.c | 4 +- drivers/media/dvb/ttpci/budget-patch.c | 2 +- drivers/media/radio/radio-mr800.c | 2 +- drivers/media/video/cx231xx/cx231xx-avcore.c | 8 +-- drivers/media/video/cx23885/cx23885-dvb.c | 2 +- drivers/media/video/cx88/cx88-core.c | 2 +- drivers/media/video/davinci/dm355_ccdc.c | 2 +- drivers/media/video/davinci/vpss.c | 2 +- drivers/media/video/gspca/sonixb.c | 2 +- drivers/media/video/gspca/spca500.c | 2 +- drivers/media/video/gspca/spca501.c | 6 +-- drivers/media/video/gspca/sunplus.c | 2 +- drivers/media/video/gspca/zc3xx.c | 2 +- drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | 2 +- drivers/media/video/s2255drv.c | 2 +- drivers/media/video/zoran/zoran.h | 2 +- drivers/message/i2o/i2o_block.c | 2 +- drivers/message/i2o/iop.c | 4 +- drivers/misc/sgi-gru/grufile.c | 2 +- drivers/mmc/host/s3cmci.c | 2 +- drivers/mtd/devices/slram.c | 2 +- drivers/mtd/nand/diskonchip.c | 2 +- drivers/mtd/nand/nand_ecc.c | 2 +- drivers/mtd/nand/s3c2410.c | 2 +- drivers/net/82596.c | 2 +- drivers/net/amd8111e.c | 7 ++- drivers/net/appletalk/cops.c | 2 +- drivers/net/ariadne.h | 2 +- drivers/net/atl1c/atl1c_main.c | 2 +- drivers/net/benet/be_cmds.h | 2 +- drivers/net/benet/be_main.c | 2 +- drivers/net/bnx2x_reg.h | 2 +- drivers/net/cxgb3/sge.c | 2 +- drivers/net/ehea/ehea_ethtool.c | 4 +- drivers/net/hamradio/baycom_ser_fdx.c | 2 +- drivers/net/iseries_veth.c | 2 +- drivers/net/lasi_82596.c | 2 +- drivers/net/lib82596.c | 2 +- drivers/net/mlx4/en_rx.c | 2 +- drivers/net/mlx4/en_tx.c | 2 +- drivers/net/mlx4/mlx4_en.h | 2 +- drivers/net/ps3_gelic_net.c | 2 +- drivers/net/sis900.c | 4 +- drivers/net/skfp/h/smc.h | 8 +-- drivers/net/skfp/skfddi.c | 2 +- drivers/net/smsc911x.c | 2 +- drivers/net/smsc911x.h | 2 +- drivers/net/spider_net.c | 2 +- drivers/net/stmmac/gmac.c | 2 +- drivers/net/stmmac/gmac.h | 4 +- drivers/net/tokenring/smctr.c | 2 +- drivers/net/ucc_geth.c | 2 +- drivers/net/ucc_geth.h | 20 +++---- drivers/net/usb/smsc95xx.c | 2 +- drivers/net/wan/lmc/lmc_main.c | 2 +- drivers/net/wimax/i2400m/rx.c | 2 +- drivers/net/wireless/ath/ath5k/phy.c | 6 +-- drivers/net/wireless/ath/ath9k/rc.c | 2 +- drivers/net/wireless/ipw2x00/ipw2100.c | 6 +-- drivers/net/wireless/ipw2x00/ipw2200.c | 8 +-- drivers/net/wireless/ipw2x00/libipw_module.c | 2 +- drivers/net/wireless/iwmc3200wifi/hal.c | 2 +- drivers/net/wireless/iwmc3200wifi/rx.c | 2 +- drivers/net/wireless/libertas/if_sdio.c | 2 +- drivers/net/wireless/prism54/isl_ioctl.c | 4 +- drivers/net/wireless/rt2x00/rt2400pci.h | 2 +- drivers/net/wireless/rt2x00/rt2500pci.h | 2 +- drivers/net/wireless/rt2x00/rt2500usb.h | 2 +- drivers/net/wireless/rt2x00/rt61pci.h | 2 +- drivers/net/wireless/rt2x00/rt73usb.h | 2 +- drivers/net/wireless/wavelan_cs.c | 2 +- drivers/net/wireless/zd1211rw/zd_mac.c | 2 +- drivers/parisc/ccio-dma.c | 2 +- drivers/platform/x86/thinkpad_acpi.c | 2 +- drivers/pnp/pnpbios/rsparser.c | 8 +-- drivers/ps3/ps3-sys-manager.c | 2 +- drivers/rtc/rtc-v3020.c | 2 +- drivers/s390/char/fs3270.c | 2 +- drivers/s390/cio/chp.c | 2 +- drivers/s390/cio/cmf.c | 2 +- drivers/sbus/char/envctrl.c | 4 +- drivers/scsi/53c700.c | 2 +- drivers/scsi/aacraid/aacraid.h | 6 +-- drivers/scsi/aacraid/comminit.c | 2 +- drivers/scsi/aic7xxx/aic79xx.seq | 2 +- drivers/scsi/aic7xxx/aic79xx_core.c | 2 +- drivers/scsi/aic7xxx/aic7xxx_core.c | 2 +- drivers/scsi/bfa/include/defs/bfa_defs_pport.h | 2 +- drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h | 2 +- drivers/scsi/hptiop.c | 2 +- drivers/scsi/libfc/fc_lport.c | 2 +- drivers/scsi/libiscsi_tcp.c | 2 +- drivers/scsi/lpfc/lpfc_attr.c | 4 +- drivers/scsi/lpfc/lpfc_els.c | 4 +- drivers/scsi/lpfc/lpfc_init.c | 62 +++++++++++----------- drivers/scsi/lpfc/lpfc_sli.c | 10 ++-- drivers/scsi/megaraid.h | 2 +- drivers/scsi/megaraid/mbox_defs.h | 2 +- drivers/scsi/megaraid/megaraid_mbox.c | 2 +- drivers/scsi/mpt2sas/mpt2sas_scsih.c | 2 +- drivers/scsi/ncr53c8xx.c | 2 +- drivers/scsi/pmcraid.c | 6 +-- drivers/scsi/pmcraid.h | 6 +-- drivers/scsi/scsi_netlink.c | 2 +- drivers/scsi/scsi_transport_sas.c | 6 +-- drivers/scsi/sym53c8xx_2/sym_glue.c | 2 +- drivers/scsi/sym53c8xx_2/sym_hipd.c | 2 +- drivers/scsi/sym53c8xx_2/sym_hipd.h | 2 +- drivers/serial/8250_pnp.c | 4 +- drivers/serial/pmac_zilog.h | 2 +- drivers/serial/ucc_uart.c | 2 +- drivers/telephony/ixj.c | 4 +- drivers/usb/atm/ueagle-atm.c | 2 +- drivers/usb/class/usbtmc.c | 2 +- drivers/usb/core/message.c | 2 +- drivers/usb/gadget/f_acm.c | 2 +- drivers/usb/gadget/pxa27x_udc.c | 2 +- drivers/usb/host/fhci-sched.c | 2 +- drivers/usb/wusbcore/crypto.c | 2 +- drivers/usb/wusbcore/wa-xfer.c | 4 +- drivers/uwb/i1480/dfu/usb.c | 2 +- drivers/uwb/wlp/txrx.c | 2 +- drivers/video/aty/atyfb_base.c | 4 +- drivers/video/backlight/atmel-pwm-bl.c | 2 +- drivers/video/backlight/tosa_lcd.c | 2 +- drivers/video/console/sticore.c | 2 +- drivers/video/gbefb.c | 2 +- drivers/video/stifb.c | 4 +- drivers/video/tdfxfb.c | 2 +- drivers/video/via/dvi.c | 4 +- drivers/video/vt8623fb.c | 2 +- drivers/watchdog/coh901327_wdt.c | 2 +- drivers/watchdog/machzwd.c | 2 +- drivers/watchdog/wdrtas.c | 6 +-- fs/binfmt_elf.c | 2 +- fs/bio.c | 2 +- fs/btrfs/extent_map.c | 2 +- fs/cifs/README | 2 +- fs/cifs/cifsglob.h | 2 +- fs/cifs/inode.c | 4 +- fs/cifs/smbdes.c | 2 +- fs/dlm/plock.c | 2 +- fs/ext4/inode.c | 6 +-- fs/ext4/mballoc.c | 2 +- fs/jffs2/compr.c | 2 +- fs/jffs2/readinode.c | 2 +- fs/jffs2/xattr.c | 2 +- fs/jfs/jfs_dmap.c | 4 +- fs/ncpfs/ioctl.c | 2 +- fs/ntfs/compress.c | 2 +- fs/ntfs/file.c | 4 +- fs/ntfs/logfile.c | 2 +- fs/ocfs2/alloc.c | 2 +- fs/ocfs2/dlm/dlmmaster.c | 2 +- fs/ocfs2/dlmglue.c | 2 +- fs/ocfs2/journal.c | 2 +- fs/ocfs2/refcounttree.c | 2 +- fs/omfs/bitmap.c | 2 +- fs/ubifs/recovery.c | 2 +- fs/xfs/quota/xfs_dquot.h | 2 +- include/asm-generic/memory_model.h | 2 +- include/asm-generic/unistd.h | 2 +- include/linux/chio.h | 2 +- include/linux/mfd/ezx-pcap.h | 4 +- include/linux/pktcdvd.h | 2 +- include/linux/serial_reg.h | 8 +-- include/linux/videodev2.h | 2 +- include/net/sctp/structs.h | 2 +- include/net/tcp.h | 2 +- include/net/wimax.h | 2 +- include/sound/wm8993.h | 2 +- kernel/perf_event.c | 4 +- lib/Kconfig.debug | 2 +- lib/decompress_bunzip2.c | 2 +- lib/dma-debug.c | 2 +- lib/swiotlb.c | 2 +- mm/filemap.c | 2 +- mm/memcontrol.c | 4 +- mm/memory-failure.c | 2 +- net/ipv4/netfilter/ipt_ECN.c | 2 +- net/irda/irlap.c | 14 ++--- net/irda/irlap_event.c | 2 +- net/irda/irlmp.c | 4 +- net/mac80211/mesh_pathtbl.c | 4 +- net/netlabel/netlabel_domainhash.c | 2 +- net/sctp/sm_sideeffect.c | 2 +- net/sunrpc/xprtrdma/svc_rdma_sendto.c | 2 +- net/wimax/op-reset.c | 2 +- scripts/kconfig/mconf.c | 2 +- security/selinux/netlabel.c | 2 +- security/selinux/ss/services.c | 2 +- sound/Kconfig | 2 +- sound/isa/cs423x/cs4236.c | 2 +- sound/isa/opti9xx/miro.c | 2 +- sound/isa/opti9xx/opti92x-ad1848.c | 2 +- sound/oss/dmasound/dmasound_paula.c | 2 +- sound/pci/ca0106/ca0106_proc.c | 2 +- sound/pci/cs46xx/imgs/cwcdma.asp | 9 ++-- sound/pci/emu10k1/emu10k1x.c | 2 +- sound/pci/hda/patch_cmedia.c | 2 +- sound/pci/hda/patch_realtek.c | 2 +- sound/pci/rme9652/hdspm.c | 4 +- sound/soc/codecs/uda134x.c | 4 +- sound/soc/codecs/wm8903.c | 6 +-- sound/soc/codecs/wm8993.c | 4 +- sound/soc/s3c24xx/s3c24xx_simtec.c | 2 +- sound/soc/s6000/s6000-pcm.c | 2 +- sound/sound_core.c | 2 +- 345 files changed, 516 insertions(+), 508 deletions(-) (limited to 'drivers/media') diff --git a/Documentation/ABI/testing/procfs-diskstats b/Documentation/ABI/testing/procfs-diskstats index 99233902e09..f91a973a37f 100644 --- a/Documentation/ABI/testing/procfs-diskstats +++ b/Documentation/ABI/testing/procfs-diskstats @@ -8,7 +8,7 @@ Description: 1 - major number 2 - minor mumber 3 - device name - 4 - reads completed succesfully + 4 - reads completed successfully 5 - reads merged 6 - sectors read 7 - time spent reading (ms) diff --git a/Documentation/ABI/testing/sysfs-block b/Documentation/ABI/testing/sysfs-block index 5f3bedaf8e3..d2f90334bb9 100644 --- a/Documentation/ABI/testing/sysfs-block +++ b/Documentation/ABI/testing/sysfs-block @@ -4,7 +4,7 @@ Contact: Jerome Marchand Description: The /sys/block//stat files displays the I/O statistics of disk . They contain 11 fields: - 1 - reads completed succesfully + 1 - reads completed successfully 2 - reads merged 3 - sectors read 4 - time spent reading (ms) diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl index df0d089d0fb..f508a8a27fe 100644 --- a/Documentation/DocBook/mtdnand.tmpl +++ b/Documentation/DocBook/mtdnand.tmpl @@ -362,7 +362,7 @@ module_exit(board_cleanup); Multiple chip control - The nand driver can control chip arrays. Therefor the + The nand driver can control chip arrays. Therefore the board driver must provide an own select_chip function. This function must (de)select the requested chip. The function pointer in the nand_chip structure must diff --git a/Documentation/DocBook/v4l/videodev2.h.xml b/Documentation/DocBook/v4l/videodev2.h.xml index 97002060ac4..26303e58345 100644 --- a/Documentation/DocBook/v4l/videodev2.h.xml +++ b/Documentation/DocBook/v4l/videodev2.h.xml @@ -492,7 +492,7 @@ struct v4l2_jpegcompression { * you do, leave them untouched. * Inluding less markers will make the * resulting code smaller, but there will - * be fewer aplications which can read it. + * be fewer applications which can read it. * The presence of the APP and COM marker * is influenced by APP_len and COM_len * ONLY, not by this property! */ diff --git a/Documentation/DocBook/writing-an-alsa-driver.tmpl b/Documentation/DocBook/writing-an-alsa-driver.tmpl index 7a2e0e98986..0d0f7b4d4b1 100644 --- a/Documentation/DocBook/writing-an-alsa-driver.tmpl +++ b/Documentation/DocBook/writing-an-alsa-driver.tmpl @@ -5318,7 +5318,7 @@ struct _snd_pcm_runtime { pages of the given size and map them onto the virtually contiguous memory. The virtual pointer is addressed in runtime->dma_area. The physical address (runtime->dma_addr) is set to zero, - because the buffer is physically non-contigous. + because the buffer is physically non-contiguous. The physical address table is set up in sgbuf->table. You can get the physical address at a certain offset via snd_pcm_sgbuf_get_addr(). diff --git a/Documentation/dvb/README.dvb-usb b/Documentation/dvb/README.dvb-usb index bf2a9cdfe7b..c8238e44ed6 100644 --- a/Documentation/dvb/README.dvb-usb +++ b/Documentation/dvb/README.dvb-usb @@ -85,7 +85,7 @@ http://www.linuxtv.org/wiki/index.php/DVB_USB - moved transfer control (pid filter, fifo control) from usb driver to frontend, it seems better settled there (added xfer_ops-struct) - created a common files for frontends (mc/p/mb) - 2004-09-28 - added support for a new device (Unkown, vendor ID is Hyper-Paltek) + 2004-09-28 - added support for a new device (Unknown, vendor ID is Hyper-Paltek) 2004-09-20 - added support for a new device (Compro DVB-U2000), thanks to Amaury Demol for reporting - changed usb TS transfer method (several urbs, stopping transfer diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index 098de5bce00..42208511b5c 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c @@ -304,7 +304,7 @@ static void *map_zeroed_pages(unsigned int num) addr = mmap(NULL, getpagesize() * num, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd, 0); if (addr == MAP_FAILED) - err(1, "Mmaping %u pages of /dev/zero", num); + err(1, "Mmapping %u pages of /dev/zero", num); /* * One neat mmap feature is that you can close the fd, and it diff --git a/Documentation/scsi/ChangeLog.megaraid_sas b/Documentation/scsi/ChangeLog.megaraid_sas index c851ef49779..84524e0cf9c 100644 --- a/Documentation/scsi/ChangeLog.megaraid_sas +++ b/Documentation/scsi/ChangeLog.megaraid_sas @@ -185,7 +185,7 @@ ii. FW enables WCE bit in Mode Sense cmd for drives that are configured Disks are exposed with WCE=1. User is advised to enable Write Back mode only when the controller has battery backup. At this time Synhronize cache is not supported by the FW. Driver will short-cycle - the cmd and return sucess without sending down to FW. + the cmd and return success without sending down to FW. 1 Release Date : Sun Jan. 14 11:21:32 PDT 2007 - Sumant Patro /Bo Yang diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary index deab51ddc33..4884cb33845 100644 --- a/Documentation/spi/spi-summary +++ b/Documentation/spi/spi-summary @@ -538,7 +538,7 @@ SPI MESSAGE QUEUE The bulk of the driver will be managing the I/O queue fed by transfer(). That queue could be purely conceptual. For example, a driver used only -for low-frequency sensor acess might be fine using synchronous PIO. +for low-frequency sensor access might be fine using synchronous PIO. But the queue will probably be very real, using message->queue, PIO, often DMA (especially if the root filesystem is in SPI flash), and diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index a6e360d2055..fc5790d36cd 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -370,7 +370,7 @@ The default is 1 percent. mmap_min_addr This file indicates the amount of address space which a user process will -be restricted from mmaping. Since kernel null dereference bugs could +be restricted from mmapping. Since kernel null dereference bugs could accidentally operate based on the information in the first couple of pages of memory userspace processes should not be allowed to write to them. By default this value is set to 0 and no protections will be enforced by the diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt index 3f61825be49..6b29555b58b 100644 --- a/Documentation/video4linux/gspca.txt +++ b/Documentation/video4linux/gspca.txt @@ -6,7 +6,7 @@ The modules are: xxxx vend:prod ---- -spca501 0000:0000 MystFromOri Unknow Camera +spca501 0000:0000 MystFromOri Unknown Camera m5602 0402:5602 ALi Video Camera Controller spca501 040a:0002 Kodak DVC-325 spca500 040a:0300 Kodak EZ200 diff --git a/Documentation/vm/page-types.c b/Documentation/vm/page-types.c index 3ec4f2a2258..aa7f4d0639c 100644 --- a/Documentation/vm/page-types.c +++ b/Documentation/vm/page-types.c @@ -301,7 +301,7 @@ static char *page_flag_name(uint64_t flags) present = (flags >> i) & 1; if (!page_flag_names[i]) { if (present) - fatal("unkown flag bit %d\n", i); + fatal("unknown flag bit %d\n", i); continue; } buf[j++] = present ? page_flag_names[i][0] : '_'; diff --git a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c index 10b403554b6..7b2c56d8f93 100644 --- a/arch/alpha/mm/numa.c +++ b/arch/alpha/mm/numa.c @@ -197,7 +197,7 @@ setup_memory_node(int nid, void *kernel_end) } if (bootmap_start == -1) - panic("couldn't find a contigous place for the bootmap"); + panic("couldn't find a contiguous place for the bootmap"); /* Allocate the bootmap and mark the whole MM as reserved. */ bootmap_size = init_bootmem_node(NODE_DATA(nid), bootmap_start, diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c index 7713a08bb10..37bda5f3dde 100644 --- a/arch/arm/common/scoop.c +++ b/arch/arm/common/scoop.c @@ -82,7 +82,7 @@ static int scoop_gpio_get(struct gpio_chip *chip, unsigned offset) { struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio); - /* XXX: I'm usure, but it seems so */ + /* XXX: I'm unsure, but it seems so */ return ioread16(sdev->base + SCOOP_GPRR) & (1 << (offset + 1)); } diff --git a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h index 375066ad018..cbf334d1c76 100644 --- a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h +++ b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h @@ -83,7 +83,7 @@ typedef struct { * @brief Get next available transaction width * * -* @return On sucess : Next avail able transaction width +* @return On success : Next available transaction width * On failure : dmacHw_TRANSACTION_WIDTH_8 * * @note diff --git a/arch/arm/mach-bcmring/include/mach/dma.h b/arch/arm/mach-bcmring/include/mach/dma.h index 847980c85c8..1f2c5319c05 100644 --- a/arch/arm/mach-bcmring/include/mach/dma.h +++ b/arch/arm/mach-bcmring/include/mach/dma.h @@ -651,7 +651,7 @@ int dma_map_add_region(DMA_MemMap_t *memMap, /* Stores state information about t /** * Creates a descriptor ring from a memory mapping. * -* @return 0 on sucess, error code otherwise. +* @return 0 on success, error code otherwise. */ /****************************************************************************/ diff --git a/arch/arm/mach-lh7a40x/include/mach/hardware.h b/arch/arm/mach-lh7a40x/include/mach/hardware.h index 48e827d2fa5..59d2ace3521 100644 --- a/arch/arm/mach-lh7a40x/include/mach/hardware.h +++ b/arch/arm/mach-lh7a40x/include/mach/hardware.h @@ -31,7 +31,7 @@ /* * This __REG() version gives the same results as the one above, except * that we are fooling gcc somehow so it generates far better and smaller - * assembly code for access to contigous registers. It's a shame that gcc + * assembly code for access to contiguous registers. It's a shame that gcc * doesn't guess this by itself. */ #include diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c index 36dc5413cc9..bdf96eb523b 100644 --- a/arch/arm/mach-orion5x/pci.c +++ b/arch/arm/mach-orion5x/pci.c @@ -463,7 +463,7 @@ static void __init orion5x_setup_pci_wins(struct mbus_dram_target_info *dram) writel(win_enable, PCI_BAR_ENABLE); /* - * Disable automatic update of address remaping when writing to BARs. + * Disable automatic update of address remapping when writing to BARs. */ orion5x_setbits(PCI_ADDR_DECODE_CTRL, 1); } diff --git a/arch/arm/mach-pxa/include/mach/palmld.h b/arch/arm/mach-pxa/include/mach/palmld.h index 8721b801022..ae536e86d8e 100644 --- a/arch/arm/mach-pxa/include/mach/palmld.h +++ b/arch/arm/mach-pxa/include/mach/palmld.h @@ -91,7 +91,7 @@ /* BATTERY */ #define PALMLD_BAT_MAX_VOLTAGE 4000 /* 4.00V maximum voltage */ #define PALMLD_BAT_MIN_VOLTAGE 3550 /* 3.55V critical voltage */ -#define PALMLD_BAT_MAX_CURRENT 0 /* unknokn */ +#define PALMLD_BAT_MAX_CURRENT 0 /* unknown */ #define PALMLD_BAT_MIN_CURRENT 0 /* unknown */ #define PALMLD_BAT_MAX_CHARGE 1 /* unknown */ #define PALMLD_BAT_MIN_CHARGE 1 /* unknown */ diff --git a/arch/arm/mach-pxa/include/mach/palmt5.h b/arch/arm/mach-pxa/include/mach/palmt5.h index d15662aba00..6baf7469d4e 100644 --- a/arch/arm/mach-pxa/include/mach/palmt5.h +++ b/arch/arm/mach-pxa/include/mach/palmt5.h @@ -66,7 +66,7 @@ /* BATTERY */ #define PALMT5_BAT_MAX_VOLTAGE 4000 /* 4.00v current voltage */ #define PALMT5_BAT_MIN_VOLTAGE 3550 /* 3.55v critical voltage */ -#define PALMT5_BAT_MAX_CURRENT 0 /* unknokn */ +#define PALMT5_BAT_MAX_CURRENT 0 /* unknown */ #define PALMT5_BAT_MIN_CURRENT 0 /* unknown */ #define PALMT5_BAT_MAX_CHARGE 1 /* unknown */ #define PALMT5_BAT_MIN_CHARGE 1 /* unknown */ diff --git a/arch/arm/mach-pxa/include/mach/palmtc.h b/arch/arm/mach-pxa/include/mach/palmtc.h index 3dc9b074ab4..3f9dd3fd463 100644 --- a/arch/arm/mach-pxa/include/mach/palmtc.h +++ b/arch/arm/mach-pxa/include/mach/palmtc.h @@ -68,7 +68,7 @@ /* BATTERY */ #define PALMTC_BAT_MAX_VOLTAGE 4000 /* 4.00V maximum voltage */ #define PALMTC_BAT_MIN_VOLTAGE 3550 /* 3.55V critical voltage */ -#define PALMTC_BAT_MAX_CURRENT 0 /* unknokn */ +#define PALMTC_BAT_MAX_CURRENT 0 /* unknown */ #define PALMTC_BAT_MIN_CURRENT 0 /* unknown */ #define PALMTC_BAT_MAX_CHARGE 1 /* unknown */ #define PALMTC_BAT_MIN_CHARGE 1 /* unknown */ diff --git a/arch/arm/mach-pxa/include/mach/palmte2.h b/arch/arm/mach-pxa/include/mach/palmte2.h index 12361341f9d..f89e989a763 100644 --- a/arch/arm/mach-pxa/include/mach/palmte2.h +++ b/arch/arm/mach-pxa/include/mach/palmte2.h @@ -59,7 +59,7 @@ /* BATTERY */ #define PALMTE2_BAT_MAX_VOLTAGE 4000 /* 4.00v current voltage */ #define PALMTE2_BAT_MIN_VOLTAGE 3550 /* 3.55v critical voltage */ -#define PALMTE2_BAT_MAX_CURRENT 0 /* unknokn */ +#define PALMTE2_BAT_MAX_CURRENT 0 /* unknown */ #define PALMTE2_BAT_MIN_CURRENT 0 /* unknown */ #define PALMTE2_BAT_MAX_CHARGE 1 /* unknown */ #define PALMTE2_BAT_MIN_CHARGE 1 /* unknown */ diff --git a/arch/arm/mach-pxa/include/mach/palmtx.h b/arch/arm/mach-pxa/include/mach/palmtx.h index 1be0db6ed55..10abc4f2e8e 100644 --- a/arch/arm/mach-pxa/include/mach/palmtx.h +++ b/arch/arm/mach-pxa/include/mach/palmtx.h @@ -94,7 +94,7 @@ /* BATTERY */ #define PALMTX_BAT_MAX_VOLTAGE 4000 /* 4.00v current voltage */ #define PALMTX_BAT_MIN_VOLTAGE 3550 /* 3.55v critical voltage */ -#define PALMTX_BAT_MAX_CURRENT 0 /* unknokn */ +#define PALMTX_BAT_MAX_CURRENT 0 /* unknown */ #define PALMTX_BAT_MIN_CURRENT 0 /* unknown */ #define PALMTX_BAT_MAX_CHARGE 1 /* unknown */ #define PALMTX_BAT_MIN_CHARGE 1 /* unknown */ diff --git a/arch/arm/mach-pxa/include/mach/palmz72.h b/arch/arm/mach-pxa/include/mach/palmz72.h index 2806ef69ba5..2bbcf70dd93 100644 --- a/arch/arm/mach-pxa/include/mach/palmz72.h +++ b/arch/arm/mach-pxa/include/mach/palmz72.h @@ -49,7 +49,7 @@ /* Battery */ #define PALMZ72_BAT_MAX_VOLTAGE 4000 /* 4.00v current voltage */ #define PALMZ72_BAT_MIN_VOLTAGE 3550 /* 3.55v critical voltage */ -#define PALMZ72_BAT_MAX_CURRENT 0 /* unknokn */ +#define PALMZ72_BAT_MAX_CURRENT 0 /* unknown */ #define PALMZ72_BAT_MIN_CURRENT 0 /* unknown */ #define PALMZ72_BAT_MAX_CHARGE 1 /* unknown */ #define PALMZ72_BAT_MIN_CHARGE 1 /* unknown */ diff --git a/arch/arm/mach-s3c6400/setup-sdhci.c b/arch/arm/mach-s3c6400/setup-sdhci.c index b93dafbee1f..1039937403b 100644 --- a/arch/arm/mach-s3c6400/setup-sdhci.c +++ b/arch/arm/mach-s3c6400/setup-sdhci.c @@ -30,7 +30,7 @@ char *s3c6400_hsmmc_clksrcs[4] = { [0] = "hsmmc", [1] = "hsmmc", [2] = "mmc_bus", - /* [3] = "48m", - note not succesfully used yet */ + /* [3] = "48m", - note not successfully used yet */ }; void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev, diff --git a/arch/arm/mach-s3c6410/setup-sdhci.c b/arch/arm/mach-s3c6410/setup-sdhci.c index 20666f3bd47..816d2d9f9ef 100644 --- a/arch/arm/mach-s3c6410/setup-sdhci.c +++ b/arch/arm/mach-s3c6410/setup-sdhci.c @@ -30,7 +30,7 @@ char *s3c6410_hsmmc_clksrcs[4] = { [0] = "hsmmc", [1] = "hsmmc", [2] = "mmc_bus", - /* [3] = "48m", - note not succesfully used yet */ + /* [3] = "48m", - note not successfully used yet */ }; diff --git a/arch/arm/mach-sa1100/dma.c b/arch/arm/mach-sa1100/dma.c index cb4521a6f42..ad660350c29 100644 --- a/arch/arm/mach-sa1100/dma.c +++ b/arch/arm/mach-sa1100/dma.c @@ -65,7 +65,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id) /** - * sa1100_request_dma - allocate one of the SA11x0's DMA chanels + * sa1100_request_dma - allocate one of the SA11x0's DMA channels * @device: The SA11x0 peripheral targeted by this request * @device_id: An ascii name for the claiming device * @callback: Function to be called when the DMA completes diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h index 446f8676381..0c7802bbecc 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h @@ -112,7 +112,7 @@ enum iomux_gp_func { * setups a single pin: * - reserves the pin so that it is not claimed by another driver * - setups the iomux according to the configuration - * - if the pin is configured as a GPIO, we claim it throug kernel gpiolib + * - if the pin is configured as a GPIO, we claim it through kernel gpiolib */ int mxc_iomux_alloc_pin(const unsigned int pin, const char *label); /* diff --git a/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h b/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h index 9f13061192c..3887f3fe29d 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h @@ -48,7 +48,7 @@ * setups a single pin: * - reserves the pin so that it is not claimed by another driver * - setups the iomux according to the configuration - * - if the pin is configured as a GPIO, we claim it throug kernel gpiolib + * - if the pin is configured as a GPIO, we claim it through kernel gpiolib */ int mxc_iomux_alloc_pin(const unsigned int pin_mode, const char *label); /* diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c index 5cdbd605ac0..4ff6dfe0428 100644 --- a/arch/arm/plat-mxc/pwm.c +++ b/arch/arm/plat-mxc/pwm.c @@ -94,7 +94,7 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) * register to follow the ratio of duty_ns vs. period_ns * accordingly. * - * This is good enought for programming the brightness of + * This is good enough for programming the brightness of * the LCD backlight. * * The real implementation would divide PERCLK[0] first by diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index b53125f4129..0e308913291 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -1232,7 +1232,7 @@ static void create_dma_lch_chain(int lch_head, int lch_queue) * OMAP_DMA_DYNAMIC_CHAIN * @params - Channel parameters * - * @return - Succes : 0 + * @return - Success : 0 * Failure: -EINVAL/-ENOMEM */ int omap_request_dma_chain(int dev_id, const char *dev_name, diff --git a/arch/arm/plat-omap/include/mach/omap16xx.h b/arch/arm/plat-omap/include/mach/omap16xx.h index 0e69b504c25..7560b4d583a 100644 --- a/arch/arm/plat-omap/include/mach/omap16xx.h +++ b/arch/arm/plat-omap/include/mach/omap16xx.h @@ -124,7 +124,7 @@ #define TIPB_SWITCH_BASE (0xfffbc800) #define OMAP16XX_MMCSD2_SSW_MPU_CONF (TIPB_SWITCH_BASE + 0x160) -/* UART3 Registers Maping through MPU bus */ +/* UART3 Registers Mapping through MPU bus */ #define UART3_RHR (OMAP_UART3_BASE + 0) #define UART3_THR (OMAP_UART3_BASE + 0) #define UART3_DLL (OMAP_UART3_BASE + 0) diff --git a/arch/arm/plat-s3c24xx/include/plat/map.h b/arch/arm/plat-s3c24xx/include/plat/map.h index c4d133436fc..bd534d32b99 100644 --- a/arch/arm/plat-s3c24xx/include/plat/map.h +++ b/arch/arm/plat-s3c24xx/include/plat/map.h @@ -64,7 +64,7 @@ /* the calculation for the VA of this must ensure that * it is the same distance apart from the UART in the * phsyical address space, as the initial mapping for the IO - * is done as a 1:1 maping. This puts it (currently) at + * is done as a 1:1 mapping. This puts it (currently) at * 0xFA800000, which is not in the way of any current mapping * by the base system. */ diff --git a/arch/avr32/boards/hammerhead/Kconfig b/arch/avr32/boards/hammerhead/Kconfig index fda2331f978..5c13d785cc7 100644 --- a/arch/avr32/boards/hammerhead/Kconfig +++ b/arch/avr32/boards/hammerhead/Kconfig @@ -24,7 +24,7 @@ config BOARD_HAMMERHEAD_SND bool "Atmel AC97 Sound support" help This enables Sound support for the Hammerhead board. You may - also go trough the ALSA settings to get it working. + also go through the ALSA settings to get it working. Choose 'Y' here if you have ordered a Corona daugther board and want to make your board funky. diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 6b7325d634a..78cb3d38f89 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -619,7 +619,7 @@ asmlinkage notrace void trap_c(struct pt_regs *fp) /* * Similar to get_user, do some address checking, then dereference - * Return true on sucess, false on bad address + * Return true on success, false on bad address */ static bool get_instruction(unsigned short *val, unsigned short *address) { diff --git a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h index e06f4112c69..f9fd2b2a295 100644 --- a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h +++ b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h @@ -542,7 +542,7 @@ #define HMDMA0_CONTROL 0xFFC03300 /* Handshake MDMA0 Control Register */ #define HMDMA0_ECINIT 0xFFC03304 /* HMDMA0 Initial Edge Count Register */ #define HMDMA0_BCINIT 0xFFC03308 /* HMDMA0 Initial Block Count Register */ -#define HMDMA0_ECURGENT 0xFFC0330C /* HMDMA0 Urgent Edge Count Threshhold Register */ +#define HMDMA0_ECURGENT 0xFFC0330C /* HMDMA0 Urgent Edge Count Threshold Register */ #define HMDMA0_ECOVERFLOW 0xFFC03310 /* HMDMA0 Edge Count Overflow Interrupt Register */ #define HMDMA0_ECOUNT 0xFFC03314 /* HMDMA0 Current Edge Count Register */ #define HMDMA0_BCOUNT 0xFFC03318 /* HMDMA0 Current Block Count Register */ @@ -550,7 +550,7 @@ #define HMDMA1_CONTROL 0xFFC03340 /* Handshake MDMA1 Control Register */ #define HMDMA1_ECINIT 0xFFC03344 /* HMDMA1 Initial Edge Count Register */ #define HMDMA1_BCINIT 0xFFC03348 /* HMDMA1 Initial Block Count Register */ -#define HMDMA1_ECURGENT 0xFFC0334C /* HMDMA1 Urgent Edge Count Threshhold Register */ +#define HMDMA1_ECURGENT 0xFFC0334C /* HMDMA1 Urgent Edge Count Threshold Register */ #define HMDMA1_ECOVERFLOW 0xFFC03350 /* HMDMA1 Edge Count Overflow Interrupt Register */ #define HMDMA1_ECOUNT 0xFFC03354 /* HMDMA1 Current Edge Count Register */ #define HMDMA1_BCOUNT 0xFFC03358 /* HMDMA1 Current Block Count Register */ diff --git a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h index f821700716e..b9dbb73d7ef 100644 --- a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h +++ b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h @@ -544,7 +544,7 @@ #define HMDMA0_CONTROL 0xFFC03300 /* Handshake MDMA0 Control Register */ #define HMDMA0_ECINIT 0xFFC03304 /* HMDMA0 Initial Edge Count Register */ #define HMDMA0_BCINIT 0xFFC03308 /* HMDMA0 Initial Block Count Register */ -#define HMDMA0_ECURGENT 0xFFC0330C /* HMDMA0 Urgent Edge Count Threshhold Register */ +#define HMDMA0_ECURGENT 0xFFC0330C /* HMDMA0 Urgent Edge Count Threshold Register */ #define HMDMA0_ECOVERFLOW 0xFFC03310 /* HMDMA0 Edge Count Overflow Interrupt Register */ #define HMDMA0_ECOUNT 0xFFC03314 /* HMDMA0 Current Edge Count Register */ #define HMDMA0_BCOUNT 0xFFC03318 /* HMDMA0 Current Block Count Register */ @@ -552,7 +552,7 @@ #define HMDMA1_CONTROL 0xFFC03340 /* Handshake MDMA1 Control Register */ #define HMDMA1_ECINIT 0xFFC03344 /* HMDMA1 Initial Edge Count Register */ #define HMDMA1_BCINIT 0xFFC03348 /* HMDMA1 Initial Block Count Register */ -#define HMDMA1_ECURGENT 0xFFC0334C /* HMDMA1 Urgent Edge Count Threshhold Register */ +#define HMDMA1_ECURGENT 0xFFC0334C /* HMDMA1 Urgent Edge Count Threshold Register */ #define HMDMA1_ECOVERFLOW 0xFFC03350 /* HMDMA1 Edge Count Overflow Interrupt Register */ #define HMDMA1_ECOUNT 0xFFC03354 /* HMDMA1 Current Edge Count Register */ #define HMDMA1_BCOUNT 0xFFC03358 /* HMDMA1 Current Block Count Register */ diff --git a/arch/blackfin/mach-bf537/include/mach/defBF534.h b/arch/blackfin/mach-bf537/include/mach/defBF534.h index cebb14feb1b..a6d20ca5768 100644 --- a/arch/blackfin/mach-bf537/include/mach/defBF534.h +++ b/arch/blackfin/mach-bf537/include/mach/defBF534.h @@ -934,7 +934,7 @@ #define HMDMA0_CONTROL 0xFFC03300 /* Handshake MDMA0 Control Register */ #define HMDMA0_ECINIT 0xFFC03304 /* HMDMA0 Initial Edge Count Register */ #define HMDMA0_BCINIT 0xFFC03308 /* HMDMA0 Initial Block Count Register */ -#define HMDMA0_ECURGENT 0xFFC0330C /* HMDMA0 Urgent Edge Count Threshhold Register */ +#define HMDMA0_ECURGENT 0xFFC0330C /* HMDMA0 Urgent Edge Count Threshold Register */ #define HMDMA0_ECOVERFLOW 0xFFC03310 /* HMDMA0 Edge Count Overflow Interrupt Register */ #define HMDMA0_ECOUNT 0xFFC03314 /* HMDMA0 Current Edge Count Register */ #define HMDMA0_BCOUNT 0xFFC03318 /* HMDMA0 Current Block Count Register */ @@ -942,7 +942,7 @@ #define HMDMA1_CONTROL 0xFFC03340 /* Handshake MDMA1 Control Register */ #define HMDMA1_ECINIT 0xFFC03344 /* HMDMA1 Initial Edge Count Register */ #define HMDMA1_BCINIT 0xFFC03348 /* HMDMA1 Initial Block Count Register */ -#define HMDMA1_ECURGENT 0xFFC0334C /* HMDMA1 Urgent Edge Count Threshhold Register */ +#define HMDMA1_ECURGENT 0xFFC0334C /* HMDMA1 Urgent Edge Count Threshold Register */ #define HMDMA1_ECOVERFLOW 0xFFC03350 /* HMDMA1 Edge Count Overflow Interrupt Register */ #define HMDMA1_ECOUNT 0xFFC03354 /* HMDMA1 Current Edge Count Register */ #define HMDMA1_BCOUNT 0xFFC03358 /* HMDMA1 Current Block Count Register */ diff --git a/arch/blackfin/mach-bf548/include/mach/defBF544.h b/arch/blackfin/mach-bf548/include/mach/defBF544.h index dd414ae4ba4..39f588dcd38 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF544.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF544.h @@ -491,7 +491,7 @@ #define HMDMA0_CONTROL 0xffc04500 /* Handshake MDMA0 Control Register */ #define HMDMA0_ECINIT 0xffc04504 /* Handshake MDMA0 Initial Edge Count Register */ #define HMDMA0_BCINIT 0xffc04508 /* Handshake MDMA0 Initial Block Count Register */ -#define HMDMA0_ECURGENT 0xffc0450c /* Handshake MDMA0 Urgent Edge Count Threshhold Register */ +#define HMDMA0_ECURGENT 0xffc0450c /* Handshake MDMA0 Urgent Edge Count Threshold Register */ #define HMDMA0_ECOVERFLOW 0xffc04510 /* Handshake MDMA0 Edge Count Overflow Interrupt Register */ #define HMDMA0_ECOUNT 0xffc04514 /* Handshake MDMA0 Current Edge Count Register */ #define HMDMA0_BCOUNT 0xffc04518 /* Handshake MDMA0 Current Block Count Register */ @@ -501,7 +501,7 @@ #define HMDMA1_CONTROL 0xffc04540 /* Handshake MDMA1 Control Register */ #define HMDMA1_ECINIT 0xffc04544 /* Handshake MDMA1 Initial Edge Count Register */ #define HMDMA1_BCINIT 0xffc04548 /* Handshake MDMA1 Initial Block Count Register */ -#define HMDMA1_ECURGENT 0xffc0454c /* Handshake MDMA1 Urgent Edge Count Threshhold Register */ +#define HMDMA1_ECURGENT 0xffc0454c /* Handshake MDMA1 Urgent Edge Count Threshold Register */ #define HMDMA1_ECOVERFLOW 0xffc04550 /* Handshake MDMA1 Edge Count Overflow Interrupt Register */ #define HMDMA1_ECOUNT 0xffc04554 /* Handshake MDMA1 Current Edge Count Register */ #define HMDMA1_BCOUNT 0xffc04558 /* Handshake MDMA1 Current Block Count Register */ diff --git a/arch/blackfin/mach-bf548/include/mach/defBF547.h b/arch/blackfin/mach-bf548/include/mach/defBF547.h index 5a9dbabe0a6..c4dcf302d9f 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF547.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF547.h @@ -470,7 +470,7 @@ #define HMDMA0_CONTROL 0xffc04500 /* Handshake MDMA0 Control Register */ #define HMDMA0_ECINIT 0xffc04504 /* Handshake MDMA0 Initial Edge Count Register */ #define HMDMA0_BCINIT 0xffc04508 /* Handshake MDMA0 Initial Block Count Register */ -#define HMDMA0_ECURGENT 0xffc0450c /* Handshake MDMA0 Urgent Edge Count Threshhold Register */ +#define HMDMA0_ECURGENT 0xffc0450c /* Handshake MDMA0 Urgent Edge Count Threshold Register */ #define HMDMA0_ECOVERFLOW 0xffc04510 /* Handshake MDMA0 Edge Count Overflow Interrupt Register */ #define HMDMA0_ECOUNT 0xffc04514 /* Handshake MDMA0 Current Edge Count Register */ #define HMDMA0_BCOUNT 0xffc04518 /* Handshake MDMA0 Current Block Count Register */ @@ -480,7 +480,7 @@ #define HMDMA1_CONTROL 0xffc04540 /* Handshake MDMA1 Control Register */ #define HMDMA1_ECINIT 0xffc04544 /* Handshake MDMA1 Initial Edge Count Register */ #define HMDMA1_BCINIT 0xffc04548 /* Handshake MDMA1 Initial Block Count Register */ -#define HMDMA1_ECURGENT 0xffc0454c /* Handshake MDMA1 Urgent Edge Count Threshhold Register */ +#define HMDMA1_ECURGENT 0xffc0454c /* Handshake MDMA1 Urgent Edge Count Threshold Register */ #define HMDMA1_ECOVERFLOW 0xffc04550 /* Handshake MDMA1 Edge Count Overflow Interrupt Register */ #define HMDMA1_ECOUNT 0xffc04554 /* Handshake MDMA1 Current Edge Count Register */ #define HMDMA1_BCOUNT 0xffc04558 /* Handshake MDMA1 Current Block Count Register */ diff --git a/arch/blackfin/mach-bf548/include/mach/defBF548.h b/arch/blackfin/mach-bf548/include/mach/defBF548.h index 82cd593f739..a5079980968 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF548.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF548.h @@ -853,7 +853,7 @@ #define HMDMA0_CONTROL 0xffc04500 /* Handshake MDMA0 Control Register */ #define HMDMA0_ECINIT 0xffc04504 /* Handshake MDMA0 Initial Edge Count Register */ #define HMDMA0_BCINIT 0xffc04508 /* Handshake MDMA0 Initial Block Count Register */ -#define HMDMA0_ECURGENT 0xffc0450c /* Handshake MDMA0 Urgent Edge Count Threshhold Register */ +#define HMDMA0_ECURGENT 0xffc0450c /* Handshake MDMA0 Urgent Edge Count Threshold Register */ #define HMDMA0_ECOVERFLOW 0xffc04510 /* Handshake MDMA0 Edge Count Overflow Interrupt Register */ #define HMDMA0_ECOUNT 0xffc04514 /* Handshake MDMA0 Current Edge Count Register */ #define HMDMA0_BCOUNT 0xffc04518 /* Handshake MDMA0 Current Block Count Register */ @@ -863,7 +863,7 @@ #define HMDMA1_CONTROL 0xffc04540 /* Handshake MDMA1 Control Register */ #define HMDMA1_ECINIT 0xffc04544 /* Handshake MDMA1 Initial Edge Count Register */ #define HMDMA1_BCINIT 0xffc04548 /* Handshake MDMA1 Initial Block Count Register */ -#define HMDMA1_ECURGENT 0xffc0454c /* Handshake MDMA1 Urgent Edge Count Threshhold Register */ +#define HMDMA1_ECURGENT 0xffc0454c /* Handshake MDMA1 Urgent Edge Count Threshold Register */ #define HMDMA1_ECOVERFLOW 0xffc04550 /* Handshake MDMA1 Edge Count Overflow Interrupt Register */ #define HMDMA1_ECOUNT 0xffc04554 /* Handshake MDMA1 Current Edge Count Register */ #define HMDMA1_BCOUNT 0xffc04558 /* Handshake MDMA1 Current Block Count Register */ diff --git a/arch/blackfin/mach-bf548/include/mach/defBF549.h b/arch/blackfin/mach-bf548/include/mach/defBF549.h index 6fc6e39ab61..f7f043560c6 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF549.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF549.h @@ -1024,7 +1024,7 @@ #define HMDMA0_CONTROL 0xffc04500 /* Handshake MDMA0 Control Register */ #define HMDMA0_ECINIT 0xffc04504 /* Handshake MDMA0 Initial Edge Count Register */ #define HMDMA0_BCINIT 0xffc04508 /* Handshake MDMA0 Initial Block Count Register */ -#define HMDMA0_ECURGENT 0xffc0450c /* Handshake MDMA0 Urgent Edge Count Threshhold Register */ +#define HMDMA0_ECURGENT 0xffc0450c /* Handshake MDMA0 Urgent Edge Count Threshold Register */ #define HMDMA0_ECOVERFLOW 0xffc04510 /* Handshake MDMA0 Edge Count Overflow Interrupt Register */ #define HMDMA0_ECOUNT 0xffc04514 /* Handshake MDMA0 Current Edge Count Register */ #define HMDMA0_BCOUNT 0xffc04518 /* Handshake MDMA0 Current Block Count Register */ @@ -1034,7 +1034,7 @@ #define HMDMA1_CONTROL 0xffc04540 /* Handshake MDMA1 Control Register */ #define HMDMA1_ECINIT 0xffc04544 /* Handshake MDMA1 Initial Edge Count Register */ #define HMDMA1_BCINIT 0xffc04548 /* Handshake MDMA1 Initial Block Count Register */ -#define HMDMA1_ECURGENT 0xffc0454c /* Handshake MDMA1 Urgent Edge Count Threshhold Register */ +#define HMDMA1_ECURGENT 0xffc0454c /* Handshake MDMA1 Urgent Edge Count Threshold Register */ #define HMDMA1_ECOVERFLOW 0xffc04550 /* Handshake MDMA1 Edge Count Overflow Interrupt Register */ #define HMDMA1_ECOUNT 0xffc04554 /* Handshake MDMA1 Current Edge Count Register */ #define HMDMA1_BCOUNT 0xffc04558 /* Handshake MDMA1 Current Block Count Register */ diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c index 4a7cdd9ea1e..380df1a73a6 100644 --- a/arch/cris/mm/fault.c +++ b/arch/cris/mm/fault.c @@ -209,7 +209,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs, /* Are we prepared to handle this kernel fault? * * (The kernel has valid exception-points in the source - * when it acesses user-memory. When it fails in one + * when it accesses user-memory. When it fails in one * of those points, we find it in a table and do a jump * to some fixup code that loads an appropriate error * code) diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index 674a8374c6d..f332e3fe423 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -1381,7 +1381,7 @@ sba_coalesce_chunks(struct ioc *ioc, struct device *dev, #endif /* - ** Not virtually contigous. + ** Not virtually contiguous. ** Terminate prev chunk. ** Start a new chunk. ** diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S index af9405cd70e..02d1fb73295 100644 --- a/arch/ia64/ia32/ia32_entry.S +++ b/arch/ia64/ia32/ia32_entry.S @@ -79,7 +79,7 @@ GLOBAL_ENTRY(ia32_ret_from_clone) (p6) br.cond.spnt .ia32_strace_check_retval ;; // prevent RAW on r8 END(ia32_ret_from_clone) - // fall thrugh + // fall through GLOBAL_ENTRY(ia32_ret_from_syscall) PT_REGS_UNWIND_INFO(0) diff --git a/arch/ia64/include/asm/perfmon_default_smpl.h b/arch/ia64/include/asm/perfmon_default_smpl.h index 48822c0811d..74724b24c2b 100644 --- a/arch/ia64/include/asm/perfmon_default_smpl.h +++ b/arch/ia64/include/asm/perfmon_default_smpl.h @@ -67,7 +67,7 @@ typedef struct { unsigned long ip; /* where did the overflow interrupt happened */ unsigned long tstamp; /* ar.itc when entering perfmon intr. handler */ - unsigned short cpu; /* cpu on which the overfow occured */ + unsigned short cpu; /* cpu on which the overflow occured */ unsigned short set; /* event set active when overflow ocurred */ int tgid; /* thread group id (for NPTL, this is getpid()) */ } pfm_default_smpl_entry_t; diff --git a/arch/ia64/include/asm/sn/shubio.h b/arch/ia64/include/asm/sn/shubio.h index 22a6f18a531..6052422a22b 100644 --- a/arch/ia64/include/asm/sn/shubio.h +++ b/arch/ia64/include/asm/sn/shubio.h @@ -3289,7 +3289,7 @@ typedef ii_icrb0_e_u_t icrbe_t; #define IIO_IIDSR_LVL_SHIFT 0 #define IIO_IIDSR_LVL_MASK 0x000000ff -/* Xtalk timeout threshhold register (IIO_IXTT) */ +/* Xtalk timeout threshold register (IIO_IXTT) */ #define IXTT_RRSP_TO_SHFT 55 /* read response timeout */ #define IXTT_RRSP_TO_MASK (0x1FULL << IXTT_RRSP_TO_SHFT) #define IXTT_RRSP_PS_SHFT 32 /* read responsed TO prescalar */ diff --git a/arch/ia64/kernel/esi.c b/arch/ia64/kernel/esi.c index d5764a3d74a..b091111270c 100644 --- a/arch/ia64/kernel/esi.c +++ b/arch/ia64/kernel/esi.c @@ -84,7 +84,7 @@ static int __init esi_init (void) case ESI_DESC_ENTRY_POINT: break; default: - printk(KERN_WARNING "Unkown table type %d found in " + printk(KERN_WARNING "Unknown table type %d found in " "ESI table, ignoring rest of table\n", *p); return -ENODEV; } diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index f1782705b1f..b3a1cb3e6b2 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -3523,7 +3523,7 @@ pfm_use_debug_registers(struct task_struct *task) * IA64_THREAD_DBG_VALID set. This indicates a task which was * able to use the debug registers for debugging purposes via * ptrace(). Therefore we know it was not using them for - * perfmormance monitoring, so we only decrement the number + * performance monitoring, so we only decrement the number * of "ptraced" debug register users to keep the count up to date */ int diff --git a/arch/m68k/ifpsp060/src/fpsp.S b/arch/m68k/ifpsp060/src/fpsp.S index 6c1a9a21788..73613b5f1ee 100644 --- a/arch/m68k/ifpsp060/src/fpsp.S +++ b/arch/m68k/ifpsp060/src/fpsp.S @@ -753,7 +753,7 @@ fovfl_ovfl_on: bra.l _real_ovfl -# overflow occurred but is disabled. meanwhile, inexact is enabled. therefore, +# overflow occurred but is disabled. meanwhile, inexact is enabled. Therefore, # we must jump to real_inex(). fovfl_inex_on: @@ -1015,7 +1015,7 @@ funfl_unfl_on2: bra.l _real_unfl -# undeflow occurred but is disabled. meanwhile, inexact is enabled. therefore, +# underflow occurred but is disabled. meanwhile, inexact is enabled. Therefore, # we must jump to real_inex(). funfl_inex_on: @@ -2963,7 +2963,7 @@ iea_disabled: tst.w %d0 # is instr fmovm? bmi.b iea_dis_fmovm # yes -# instruction is using an extended precision immediate operand. therefore, +# instruction is using an extended precision immediate operand. Therefore, # the total instruction length is 16 bytes. iea_dis_immed: mov.l &0x10,%d0 # 16 bytes of instruction @@ -9624,7 +9624,7 @@ sok_dnrm: bge.b sok_norm2 # thank goodness no # the multiply factor that we're trying to create should be a denorm -# for the multiply to work. therefore, we're going to actually do a +# for the multiply to work. Therefore, we're going to actually do a # multiply with a denorm which will cause an unimplemented data type # exception to be put into the machine which will be caught and corrected # later. we don't do this with the DENORMs above because this method @@ -12216,7 +12216,7 @@ fin_sd_unfl_dis: # # operand will underflow AND underflow or inexact is enabled. -# therefore, we must return the result rounded to extended precision. +# Therefore, we must return the result rounded to extended precision. # fin_sd_unfl_ena: mov.l FP_SCR0_HI(%a6),FP_SCR1_HI(%a6) @@ -12746,7 +12746,7 @@ fdiv_zero_load_p: # # The destination was In Range and the source was a ZERO. The result, -# therefore, is an INF w/ the proper sign. +# Therefore, is an INF w/ the proper sign. # So, determine the sign and return a new INF (w/ the j-bit cleared). # global fdiv_inf_load # global for fsgldiv @@ -12996,7 +12996,7 @@ fneg_sd_unfl_dis: # # operand will underflow AND underflow is enabled. -# therefore, we must return the result rounded to extended precision. +# Therefore, we must return the result rounded to extended precision. # fneg_sd_unfl_ena: mov.l FP_SCR0_HI(%a6),FP_SCR1_HI(%a6) @@ -13611,7 +13611,7 @@ fabs_sd_unfl_dis: # # operand will underflow AND underflow is enabled. -# therefore, we must return the result rounded to extended precision. +# Therefore, we must return the result rounded to extended precision. # fabs_sd_unfl_ena: mov.l FP_SCR0_HI(%a6),FP_SCR1_HI(%a6) @@ -14973,7 +14973,7 @@ fadd_zero_2: # # the ZEROes have opposite signs: -# - therefore, we return +ZERO if the rounding modes are RN,RZ, or RP. +# - Therefore, we return +ZERO if the rounding modes are RN,RZ, or RP. # - -ZERO is returned in the case of RM. # fadd_zero_2_chk_rm: @@ -15425,7 +15425,7 @@ fsub_zero_2: # # the ZEROes have the same signs: -# - therefore, we return +ZERO if the rounding mode is RN,RZ, or RP +# - Therefore, we return +ZERO if the rounding mode is RN,RZ, or RP # - -ZERO is returned in the case of RM. # fsub_zero_2_chk_rm: @@ -15693,7 +15693,7 @@ fsqrt_sd_unfl_dis: # # operand will underflow AND underflow is enabled. -# therefore, we must return the result rounded to extended precision. +# Therefore, we must return the result rounded to extended precision. # fsqrt_sd_unfl_ena: mov.l FP_SCR0_HI(%a6),FP_SCR1_HI(%a6) @@ -21000,7 +21000,7 @@ fout_pack_type: tst.l %d0 bne.b fout_pack_set # "mantissa" is all zero which means that the answer is zero. but, the '040 -# algorithm allows the exponent to be non-zero. the 881/2 do not. therefore, +# algorithm allows the exponent to be non-zero. the 881/2 do not. Therefore, # if the mantissa is zero, I will zero the exponent, too. # the question now is whether the exponents sign bit is allowed to be non-zero # for a zero, also... @@ -21743,7 +21743,7 @@ denorm_set_stky: rts # # -# dnrm_lp(): normalize exponent/mantissa to specified threshhold # +# dnrm_lp(): normalize exponent/mantissa to specified threshold # # # # INPUT: # # %a0 : points to the operand to be denormalized # @@ -22402,7 +22402,7 @@ unnorm_shift: bgt.b unnorm_nrm_zero # yes; denorm only until exp = 0 # -# exponent would not go < 0. therefore, number stays normalized +# exponent would not go < 0. Therefore, number stays normalized # sub.w %d0, %d1 # shift exponent value mov.w FTEMP_EX(%a0), %d0 # load old exponent diff --git a/arch/m68k/ifpsp060/src/pfpsp.S b/arch/m68k/ifpsp060/src/pfpsp.S index 51b9f7d879d..e71ba0ab013 100644 --- a/arch/m68k/ifpsp060/src/pfpsp.S +++ b/arch/m68k/ifpsp060/src/pfpsp.S @@ -752,7 +752,7 @@ fovfl_ovfl_on: bra.l _real_ovfl -# overflow occurred but is disabled. meanwhile, inexact is enabled. therefore, +# overflow occurred but is disabled. meanwhile, inexact is enabled. Therefore, # we must jump to real_inex(). fovfl_inex_on: @@ -1014,7 +1014,7 @@ funfl_unfl_on2: bra.l _real_unfl -# undeflow occurred but is disabled. meanwhile, inexact is enabled. therefore, +# underflow occurred but is disabled. meanwhile, inexact is enabled. Therefore, # we must jump to real_inex(). funfl_inex_on: @@ -2962,7 +2962,7 @@ iea_disabled: tst.w %d0 # is instr fmovm? bmi.b iea_dis_fmovm # yes -# instruction is using an extended precision immediate operand. therefore, +# instruction is using an extended precision immediate operand. Therefore, # the total instruction length is 16 bytes. iea_dis_immed: mov.l &0x10,%d0 # 16 bytes of instruction @@ -5865,7 +5865,7 @@ denorm_set_stky: rts # # -# dnrm_lp(): normalize exponent/mantissa to specified threshhold # +# dnrm_lp(): normalize exponent/mantissa to specified threshold # # # # INPUT: # # %a0 : points to the operand to be denormalized # @@ -6524,7 +6524,7 @@ unnorm_shift: bgt.b unnorm_nrm_zero # yes; denorm only until exp = 0 # -# exponent would not go < 0. therefore, number stays normalized +# exponent would not go < 0. Therefore, number stays normalized # sub.w %d0, %d1 # shift exponent value mov.w FTEMP_EX(%a0), %d0 # load old exponent @@ -7901,7 +7901,7 @@ fout_pack_type: tst.l %d0 bne.b fout_pack_set # "mantissa" is all zero which means that the answer is zero. but, the '040 -# algorithm allows the exponent to be non-zero. the 881/2 do not. therefore, +# algorithm allows the exponent to be non-zero. the 881/2 do not. Therefore, # if the mantissa is zero, I will zero the exponent, too. # the question now is whether the exponents sign bit is allowed to be non-zero # for a zero, also... @@ -8647,7 +8647,7 @@ fin_sd_unfl_dis: # # operand will underflow AND underflow or inexact is enabled. -# therefore, we must return the result rounded to extended precision. +# Therefore, we must return the result rounded to extended precision. # fin_sd_unfl_ena: mov.l FP_SCR0_HI(%a6),FP_SCR1_HI(%a6) @@ -9177,7 +9177,7 @@ fdiv_zero_load_p: # # The destination was In Range and the source was a ZERO. The result, -# therefore, is an INF w/ the proper sign. +# Therefore, is an INF w/ the proper sign. # So, determine the sign and return a new INF (w/ the j-bit cleared). # global fdiv_inf_load # global for fsgldiv @@ -9427,7 +9427,7 @@ fneg_sd_unfl_dis: # # operand will underflow AND underflow is enabled. -# therefore, we must return the result rounded to extended precision. +# Therefore, we must return the result rounded to extended precision. # fneg_sd_unfl_ena: mov.l FP_SCR0_HI(%a6),FP_SCR1_HI(%a6) @@ -10042,7 +10042,7 @@ fabs_sd_unfl_dis: # # operand will underflow AND underflow is enabled. -# therefore, we must return the result rounded to extended precision. +# Therefore, we must return the result rounded to extended precision. # fabs_sd_unfl_ena: mov.l FP_SCR0_HI(%a6),FP_SCR1_HI(%a6) @@ -11404,7 +11404,7 @@ fadd_zero_2: # # the ZEROes have opposite signs: -# - therefore, we return +ZERO if the rounding modes are RN,RZ, or RP. +# - Therefore, we return +ZERO if the rounding modes are RN,RZ, or RP. # - -ZERO is returned in the case of RM. # fadd_zero_2_chk_rm: @@ -11856,7 +11856,7 @@ fsub_zero_2: # # the ZEROes have the same signs: -# - therefore, we return +ZERO if the rounding mode is RN,RZ, or RP +# - Therefore, we return +ZERO if the rounding mode is RN,RZ, or RP # - -ZERO is returned in the case of RM. # fsub_zero_2_chk_rm: @@ -12124,7 +12124,7 @@ fsqrt_sd_unfl_dis: # # operand will underflow AND underflow is enabled. -# therefore, we must return the result rounded to extended precision. +# Therefore, we must return the result rounded to extended precision. # fsqrt_sd_unfl_ena: mov.l FP_SCR0_HI(%a6),FP_SCR1_HI(%a6) diff --git a/arch/m68k/include/asm/bootinfo.h b/arch/m68k/include/asm/bootinfo.h index fb8a06b9ab6..67e7a78ad96 100644 --- a/arch/m68k/include/asm/bootinfo.h +++ b/arch/m68k/include/asm/bootinfo.h @@ -145,7 +145,7 @@ struct bi_record { /* * Macintosh hardware profile data - unused, see macintosh.h for - * resonable type values + * reasonable type values */ #define BI_MAC_VIA1BASE 0x8010 /* Mac VIA1 base address (always present) */ diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c index 6a907c58a4b..cc2108b6b26 100644 --- a/arch/microblaze/lib/memcpy.c +++ b/arch/microblaze/lib/memcpy.c @@ -9,7 +9,7 @@ * It is based on demo code originally Copyright 2001 by Intel Corp, taken from * http://www.embedded.com/showArticle.jhtml?articleID=19205567 * - * Attempts were made, unsuccesfully, to contact the original + * Attempts were made, unsuccessfully, to contact the original * author of this code (Michael Morrow, Intel). Below is the original * copyright notice. * diff --git a/arch/microblaze/lib/memmove.c b/arch/microblaze/lib/memmove.c index d4e9f49a71f..0929198c5e6 100644 --- a/arch/microblaze/lib/memmove.c +++ b/arch/microblaze/lib/memmove.c @@ -9,7 +9,7 @@ * It is based on demo code originally Copyright 2001 by Intel Corp, taken from * http://www.embedded.com/showArticle.jhtml?articleID=19205567 * - * Attempts were made, unsuccesfully, to contact the original + * Attempts were made, unsuccessfully, to contact the original * author of this code (Michael Morrow, Intel). Below is the original * copyright notice. * diff --git a/arch/microblaze/lib/memset.c b/arch/microblaze/lib/memset.c index 941dc8f94b0..4df851d41a2 100644 --- a/arch/microblaze/lib/memset.c +++ b/arch/microblaze/lib/memset.c @@ -9,7 +9,7 @@ * It is based on demo code originally Copyright 2001 by Intel Corp, taken from * http://www.embedded.com/showArticle.jhtml?articleID=19205567 * - * Attempts were made, unsuccesfully, to contact the original + * Attempts were made, unsuccessfully, to contact the original * author of this code (Michael Morrow, Intel). Below is the original * copyright notice. * diff --git a/arch/mips/include/asm/mach-pnx833x/gpio.h b/arch/mips/include/asm/mach-pnx833x/gpio.h index 8de0eb9c98a..ed3a88da70f 100644 --- a/arch/mips/include/asm/mach-pnx833x/gpio.h +++ b/arch/mips/include/asm/mach-pnx833x/gpio.h @@ -24,7 +24,7 @@ /* BIG FAT WARNING: races danger! No protections exist here. Current users are only early init code, - when locking is not needed because no cuncurency yet exists there, + when locking is not needed because no concurrency yet exists there, and GPIO IRQ dispatcher, which does locking. However, if many uses will ever happen, proper locking will be needed - including locking between different uses diff --git a/arch/mips/include/asm/sgi/ioc.h b/arch/mips/include/asm/sgi/ioc.h index 343ed15f8dc..57a971904cf 100644 --- a/arch/mips/include/asm/sgi/ioc.h +++ b/arch/mips/include/asm/sgi/ioc.h @@ -164,7 +164,7 @@ struct sgioc_regs { u32 _unused5; u8 _write[3]; volatile u8 write; -#define SGIOC_WRITE_NTHRESH 0x01 /* use 4.5db threshhold */ +#define SGIOC_WRITE_NTHRESH 0x01 /* use 4.5db threshold */ #define SGIOC_WRITE_TPSPEED 0x02 /* use 100ohm TP speed */ #define SGIOC_WRITE_EPSEL 0x04 /* force cable mode: 1=AUI 0=TP */ #define SGIOC_WRITE_EASEL 0x08 /* 1=autoselect 0=manual cable selection */ diff --git a/arch/mips/include/asm/sibyte/sb1250_mac.h b/arch/mips/include/asm/sibyte/sb1250_mac.h index b6faf08ca81..591b9061fd8 100644 --- a/arch/mips/include/asm/sibyte/sb1250_mac.h +++ b/arch/mips/include/asm/sibyte/sb1250_mac.h @@ -212,7 +212,7 @@ #define G_MAC_TXD_WEIGHT1(x) _SB_GETVALUE(x, S_MAC_TXD_WEIGHT1, M_MAC_TXD_WEIGHT1) /* - * MAC Fifo Threshhold registers (Table 9-14) + * MAC Fifo Threshold registers (Table 9-14) * Register: MAC_THRSH_CFG_0 * Register: MAC_THRSH_CFG_1 * Register: MAC_THRSH_CFG_2 diff --git a/arch/mips/include/asm/sn/sn0/hubio.h b/arch/mips/include/asm/sn/sn0/hubio.h index d0c29d4de08..31c76c021bb 100644 --- a/arch/mips/include/asm/sn/sn0/hubio.h +++ b/arch/mips/include/asm/sn/sn0/hubio.h @@ -825,7 +825,7 @@ typedef union iprb_u { struct { u64 rsvd1: 15, error: 1, /* Widget rcvd wr resp pkt w/ error */ - ovflow: 5, /* Over flow count. perf measurement */ + ovflow: 5, /* Overflow count. perf measurement */ fire_and_forget: 1, /* Launch Write without response */ mode: 2, /* Widget operation Mode */ rsvd2: 2, diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 24630fd8ef6..a38e3ee9551 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -1331,7 +1331,7 @@ void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) if (!((asid += ASID_INC) & ASID_MASK) ) { if (cpu_has_vtag_icache) flush_icache_all(); - /* Traverse all online CPUs (hack requires contigous range) */ + /* Traverse all online CPUs (hack requires contiguous range) */ for_each_online_cpu(i) { /* * We don't need to worry about our own CPU, nor those of diff --git a/arch/mips/math-emu/dp_sub.c b/arch/mips/math-emu/dp_sub.c index b30c5b1f1a2..a2127d685a0 100644 --- a/arch/mips/math-emu/dp_sub.c +++ b/arch/mips/math-emu/dp_sub.c @@ -110,7 +110,7 @@ ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; - /* FAAL THOROUGH */ + /* FALL THROUGH */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): /* normalize ym,ye */ diff --git a/arch/mips/txx9/generic/smsc_fdc37m81x.c b/arch/mips/txx9/generic/smsc_fdc37m81x.c index a2b2d62d88e..8ebc3848f3a 100644 --- a/arch/mips/txx9/generic/smsc_fdc37m81x.c +++ b/arch/mips/txx9/generic/smsc_fdc37m81x.c @@ -117,7 +117,7 @@ unsigned long __init smsc_fdc37m81x_init(unsigned long port) if (chip_id == SMSC_FDC37M81X_CHIP_ID) smsc_fdc37m81x_config_end(); else { - printk(KERN_WARNING "%s: unknow chip id 0x%02x\n", __func__, + printk(KERN_WARNING "%s: unknown chip id 0x%02x\n", __func__, chip_id); g_smsc_fdc37m81x_base = 0; } diff --git a/arch/powerpc/include/asm/reg_fsl_emb.h b/arch/powerpc/include/asm/reg_fsl_emb.h index 1e180a59458..0de404dfee8 100644 --- a/arch/powerpc/include/asm/reg_fsl_emb.h +++ b/arch/powerpc/include/asm/reg_fsl_emb.h @@ -39,7 +39,7 @@ #define PMRN_PMLCB2 0x112 /* PM Local Control B2 */ #define PMRN_PMLCB3 0x113 /* PM Local Control B3 */ -#define PMLCB_THRESHMUL_MASK 0x0700 /* Threshhold Multiple Field */ +#define PMLCB_THRESHMUL_MASK 0x0700 /* Threshold Multiple Field */ #define PMLCB_THRESHMUL_SHIFT 8 #define PMLCB_THRESHOLD_MASK 0x003f /* Threshold Field */ diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index 641c74bb8e2..b6bd1eaa1c2 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c @@ -52,7 +52,7 @@ static struct hard_trap_info { 0x2030, 0x08 /* SIGFPE */ }, /* spe fp data */ { 0x2040, 0x08 /* SIGFPE */ }, /* spe fp data */ { 0x2050, 0x08 /* SIGFPE */ }, /* spe fp round */ - { 0x2060, 0x0e /* SIGILL */ }, /* performace monitor */ + { 0x2060, 0x0e /* SIGILL */ }, /* performance monitor */ { 0x2900, 0x08 /* SIGFPE */ }, /* apu unavailable */ { 0x3100, 0x0e /* SIGALRM */ }, /* fixed interval timer */ { 0x3200, 0x02 /* SIGINT */ }, /* watchdog */ diff --git a/arch/powerpc/kernel/tau_6xx.c b/arch/powerpc/kernel/tau_6xx.c index c3a56d65c5a..a753b72efbc 100644 --- a/arch/powerpc/kernel/tau_6xx.c +++ b/arch/powerpc/kernel/tau_6xx.c @@ -59,7 +59,7 @@ void set_thresholds(unsigned long cpu) mtspr(SPRN_THRM1, THRM1_THRES(tau[cpu].low) | THRM1_V | THRM1_TIE | THRM1_TID); /* setup THRM2, - * threshold, valid bit, enable interrupts, interrupt when above threshhold + * threshold, valid bit, enable interrupts, interrupt when above threshold */ mtspr (SPRN_THRM2, THRM1_THRES(tau[cpu].high) | THRM1_V | THRM1_TIE); #else diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c index 52c98edcd70..2c9e5226729 100644 --- a/arch/powerpc/oprofile/op_model_cell.c +++ b/arch/powerpc/oprofile/op_model_cell.c @@ -1594,7 +1594,7 @@ static void cell_handle_interrupt_spu(struct pt_regs *regs, * to a latch. The new values (interrupt setting bits, reset * counter value etc.) are not copied to the actual registers * until the performance monitor is enabled. In order to get - * this to work as desired, the permormance monitor needs to + * this to work as desired, the performance monitor needs to * be disabled while writing to the latches. This is a * HW design issue. */ @@ -1668,7 +1668,7 @@ static void cell_handle_interrupt_ppu(struct pt_regs *regs, * to a latch. The new values (interrupt setting bits, reset * counter value etc.) are not copied to the actual registers * until the performance monitor is enabled. In order to get - * this to work as desired, the permormance monitor needs to + * this to work as desired, the performance monitor needs to * be disabled while writing to the latches. This is a * HW design issue. */ diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c index dd43114e968..da110bd8834 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c @@ -100,7 +100,7 @@ const struct of_device_id mpc52xx_pci_ids[] __initdata = { }; /* ======================================================================== */ -/* PCI configuration acess */ +/* PCI configuration access */ /* ======================================================================== */ static int diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index e81403b245b..ab2027cdf89 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -302,7 +302,7 @@ static void __init setup_chaos(struct pci_controller *hose, * 1 -> Skip the device but act as if the access was successfull * (return 0xff's on reads, eventually, cache config space * accesses in a later version) - * -1 -> Hide the device (unsuccessful acess) + * -1 -> Hide the device (unsuccessful access) */ static int u3_ht_skip_device(struct pci_controller *hose, struct pci_bus *bus, unsigned int devfn) diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index ae3c4db86fe..bafc3f85360 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c @@ -160,7 +160,7 @@ static int dart_build(struct iommu_table *tbl, long index, dp = ((unsigned int*)tbl->it_base) + index; - /* On U3, all memory is contigous, so we can move this + /* On U3, all memory is contiguous, so we can move this * out of the loop. */ l = npages; diff --git a/arch/s390/math-emu/math.c b/arch/s390/math-emu/math.c index 3ee78ccb617..cd4e9c168dd 100644 --- a/arch/s390/math-emu/math.c +++ b/arch/s390/math-emu/math.c @@ -2088,7 +2088,7 @@ int math_emu_ldr(__u8 *opcode) { __u16 opc = *((__u16 *) opcode); if ((opc & 0x90) == 0) { /* test if rx in {0,2,4,6} */ - /* we got an exception therfore ry can't be in {0,2,4,6} */ + /* we got an exception therefore ry can't be in {0,2,4,6} */ asm volatile( /* load rx from fp_regs.fprs[ry] */ " bras 1,0f\n" " ld 0,0(%1)\n" @@ -2118,7 +2118,7 @@ int math_emu_ler(__u8 *opcode) { __u16 opc = *((__u16 *) opcode); if ((opc & 0x90) == 0) { /* test if rx in {0,2,4,6} */ - /* we got an exception therfore ry can't be in {0,2,4,6} */ + /* we got an exception therefore ry can't be in {0,2,4,6} */ asm volatile( /* load rx from fp_regs.fprs[ry] */ " bras 1,0f\n" " le 0,0(%1)\n" diff --git a/arch/x86/include/asm/desc_defs.h b/arch/x86/include/asm/desc_defs.h index 9d6684849fd..278441f3985 100644 --- a/arch/x86/include/asm/desc_defs.h +++ b/arch/x86/include/asm/desc_defs.h @@ -12,9 +12,9 @@ #include /* - * FIXME: Acessing the desc_struct through its fields is more elegant, + * FIXME: Accessing the desc_struct through its fields is more elegant, * and should be the one valid thing to do. However, a lot of open code - * still touches the a and b acessors, and doing this allow us to do it + * still touches the a and b accessors, and doing this allow us to do it * incrementally. We keep the signature as a struct, rather than an union, * so we can get rid of it transparently in the future -- glommer */ diff --git a/arch/x86/include/asm/mmzone_32.h b/arch/x86/include/asm/mmzone_32.h index ede6998bd92..91df7c51806 100644 --- a/arch/x86/include/asm/mmzone_32.h +++ b/arch/x86/include/asm/mmzone_32.h @@ -47,7 +47,7 @@ static inline void resume_map_numa_kva(pgd_t *pgd) {} /* * generic node memory support, the following assumptions apply: * - * 1) memory comes in 64Mb contigious chunks which are either present or not + * 1) memory comes in 64Mb contiguous chunks which are either present or not * 2) we will not have more than 64Gb in total * * for now assume that 64Gb is max amount of RAM for whole system diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index 80e2984f521..b414d2b401f 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h @@ -55,7 +55,7 @@ #define DESC_STATUS_SOURCE_TIMEOUT 3 /* - * source side threshholds at which message retries print a warning + * source side thresholds at which message retries print a warning */ #define SOURCE_TIMEOUT_LIMIT 20 #define DESTINATION_TIMEOUT_LIMIT 20 diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 67e929b8987..1c2c4838d35 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -1122,7 +1122,7 @@ static int __init acpi_parse_madt_ioapic_entries(void) if (!acpi_sci_override_gsi) acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0); - /* Fill in identity legacy mapings where no override */ + /* Fill in identity legacy mappings where no override */ mp_config_acpi_legacy_irqs(); count = diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 0285521e0a9..42ac5e00099 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -1637,7 +1637,7 @@ retry: goto out; /* - * aperture was sucessfully enlarged by 128 MB, try + * aperture was successfully enlarged by 128 MB, try * allocation again */ goto retry; @@ -2396,7 +2396,7 @@ int __init amd_iommu_init_passthrough(void) struct pci_dev *dev = NULL; u16 devid, devid2; - /* allocate passthroug domain */ + /* allocate passthrough domain */ pt_domain = protection_domain_alloc(); if (!pt_domain) return -ENOMEM; diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index b5801c31184..35be5802ac1 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1229,7 +1229,7 @@ x86_perf_event_set_period(struct perf_event *event, return 0; /* - * If we are way outside a reasoable range then just skip forward: + * If we are way outside a reasonable range then just skip forward: */ if (unlikely(left <= -period)) { left = period; diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index 7b5169d2b00..7d377379fa4 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c @@ -514,7 +514,7 @@ static int __kprobes reenter_kprobe(struct kprobe *p, struct pt_regs *regs, /* * Interrupts are disabled on entry as trap3 is an interrupt gate and they - * remain disabled thorough out this function. + * remain disabled throughout this function. */ static int __kprobes kprobe_handler(struct pt_regs *regs) { @@ -851,7 +851,7 @@ no_change: /* * Interrupts are disabled on entry as trap1 is an interrupt gate and they - * remain disabled thoroughout this function. + * remain disabled throughout this function. */ static int __kprobes post_kprobe_handler(struct pt_regs *regs) { diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c index 16ccbd77917..d16d576beeb 100644 --- a/arch/x86/mm/kmmio.c +++ b/arch/x86/mm/kmmio.c @@ -203,7 +203,7 @@ static void disarm_kmmio_fault_page(struct kmmio_fault_page *f) */ /* * Interrupts are disabled on entry as trap3 is an interrupt gate - * and they remain disabled thorough out this function. + * and they remain disabled throughout this function. */ int kmmio_handler(struct pt_regs *regs, unsigned long addr) { @@ -302,7 +302,7 @@ no_kmmio: /* * Interrupts are disabled on entry as trap1 is an interrupt gate - * and they remain disabled thorough out this function. + * and they remain disabled throughout this function. * This must always get called as the pair to kmmio_handler(). */ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) diff --git a/block/blk-iopoll.c b/block/blk-iopoll.c index ca564202ed7..58916afbbda 100644 --- a/block/blk-iopoll.c +++ b/block/blk-iopoll.c @@ -28,7 +28,7 @@ static DEFINE_PER_CPU(struct list_head, blk_cpu_iopoll); * Description: * Add this blk_iopoll structure to the pending poll list and trigger the * raise of the blk iopoll softirq. The driver must already have gotten a - * succesful return from blk_iopoll_sched_prep() before calling this. + * successful return from blk_iopoll_sched_prep() before calling this. **/ void blk_iopoll_sched(struct blk_iopoll *iop) { diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 9ac4e378992..3aadded05a0 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -599,7 +599,7 @@ static const struct ich_laptop ich_laptop[] = { { 0x27DF, 0x1028, 0x02b0 }, /* ICH7 on unknown Dell */ { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */ { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */ - { 0x27DF, 0x103C, 0x361a }, /* ICH7 on unkown HP */ + { 0x27DF, 0x103C, 0x361a }, /* ICH7 on unknown HP */ { 0x27DF, 0x1071, 0xD221 }, /* ICH7 on Hercules EC-900 */ { 0x27DF, 0x152D, 0x0778 }, /* ICH7 on unknown Intel */ { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */ diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index d344db42a00..0d9d2f20788 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -43,9 +43,9 @@ enum { /* * SATA-FSL host controller supports a max. of (15+1) direct PRDEs, and * chained indirect PRDEs upto a max count of 63. - * We are allocating an array of 63 PRDEs contigiously, but PRDE#15 will + * We are allocating an array of 63 PRDEs contiguously, but PRDE#15 will * be setup as an indirect descriptor, pointing to it's next - * (contigious) PRDE. Though chained indirect PRDE arrays are + * (contiguous) PRDE. Though chained indirect PRDE arrays are * supported,it will be more efficient to use a direct PRDT and * a single chain/link to indirect PRDE array/PRDT. */ @@ -314,7 +314,7 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, u32 ttl_dwords = 0; /* - * NOTE : direct & indirect prdt's are contigiously allocated + * NOTE : direct & indirect prdt's are contiguously allocated */ struct prde *prd = (struct prde *)&((struct command_desc *) cmd_desc)->prdt; diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index b2c1b37ab2e..f734b345ac7 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c @@ -1132,7 +1132,7 @@ static int rx_pkt(struct atm_dev *dev) IF_ERR(printk(" cause: packet time out\n");) } else { - IF_ERR(printk(" cause: buffer over flow\n");) + IF_ERR(printk(" cause: buffer overflow\n");) } goto out_free_desc; } diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 979d159b5cd..ee95c76bfd3 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -188,7 +188,7 @@ EXPORT_SYMBOL_GPL(wait_for_device_probe); * @dev: device to try to bind to the driver * * This function returns -ENODEV if the device is not registered, - * 1 if the device is bound sucessfully and 0 otherwise. + * 1 if the device is bound successfully and 0 otherwise. * * This function must be called with @dev->sem held. When called for a * USB interface, @dev->parent->sem must be held as well. diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 5b33b85790f..63bfc543679 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -535,7 +535,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) break; default: - BT_ERR("Unknow packet type:%d", type); + BT_ERR("Unknown packet type:%d", type); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, payload, blksz * buf_block_len); diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 4895f0e0532..aa0919386b8 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -214,7 +214,7 @@ static int hci_uart_send_frame(struct sk_buff *skb) struct hci_uart *hu; if (!hdev) { - BT_ERR("Frame for uknown device (hdev=NULL)"); + BT_ERR("Frame for unknown device (hdev=NULL)"); return -ENODEV; } diff --git a/drivers/char/mem.c b/drivers/char/mem.c index a074fceb67d..42e65cf8ab5 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -5,7 +5,7 @@ * * Added devfs support. * Jan-11-1998, C. Scott Ananian - * Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar + * Shared /dev/zero mmapping support, Feb 2000, Kanoj Sarcar */ #include diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c index 1997270bb6f..ecb89d798e3 100644 --- a/drivers/char/mspec.c +++ b/drivers/char/mspec.c @@ -248,7 +248,7 @@ static const struct vm_operations_struct mspec_vm_ops = { /* * mspec_mmap * - * Called when mmaping the device. Initializes the vma with a fault handler + * Called when mmapping the device. Initializes the vma with a fault handler * and private data structure necessary to allocate, track, and free the * underlying pages. */ diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c index 6934025a1ac..c1d8b54c816 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c @@ -602,7 +602,7 @@ static void receive_char(struct r3964_info *pInfo, const unsigned char c) } break; case R3964_WAIT_FOR_RX_REPEAT: - /* FALLTROUGH */ + /* FALLTHROUGH */ case R3964_IDLE: if (c == STX) { /* Prevent rx_queue from overflow: */ diff --git a/drivers/char/rio/route.h b/drivers/char/rio/route.h index 20ed73f3fd7..46e963771c3 100644 --- a/drivers/char/rio/route.h +++ b/drivers/char/rio/route.h @@ -67,7 +67,7 @@ typedef struct COST_ROUTE COST_ROUTE; struct COST_ROUTE { unsigned char cost; /* Cost down this link */ - unsigned char route[NODE_BYTES]; /* Nodes thorough this route */ + unsigned char route[NODE_BYTES]; /* Nodes through this route */ }; typedef struct ROUTE_STR ROUTE_STR; diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index 5f753fc0873..09ad9154d86 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -863,7 +863,7 @@ static int hifn_init_pubrng(struct hifn_device *dev) dev->dmareg |= HIFN_DMAIER_PUBDONE; hifn_write_1(dev, HIFN_1_DMA_IER, dev->dmareg); - dprintk("Chip %s: Public key engine has been sucessfully " + dprintk("Chip %s: Public key engine has been successfully " "initialised.\n", dev->name); } diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 7585c4164bd..c52ac9efd0b 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -99,7 +99,7 @@ static struct at_desc *atc_alloc_descriptor(struct dma_chan *chan, } /** - * atc_desc_get - get a unsused descriptor from free_list + * atc_desc_get - get an unused descriptor from free_list * @atchan: channel we want a new descriptor for */ static struct at_desc *atc_desc_get(struct at_dma_chan *atchan) diff --git a/drivers/firewire/core-topology.c b/drivers/firewire/core-topology.c index fddf2b35893..d373d17257e 100644 --- a/drivers/firewire/core-topology.c +++ b/drivers/firewire/core-topology.c @@ -183,7 +183,7 @@ static inline struct fw_node *fw_node(struct list_head *l) * This function builds the tree representation of the topology given * by the self IDs from the latest bus reset. During the construction * of the tree, the function checks that the self IDs are valid and - * internally consistent. On succcess this function returns the + * internally consistent. On success this function returns the * fw_node corresponding to the local card otherwise NULL. */ static struct fw_node *build_tree(struct fw_card *card, diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 5cae0b3eee9..3f7c500b211 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -272,7 +272,7 @@ EXPORT_SYMBOL(drm_mode_object_find); * functions & device file and adds it to the master fd list. * * RETURNS: - * Zero on success, error code on falure. + * Zero on success, error code on failure. */ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb, const struct drm_framebuffer_funcs *funcs) @@ -2328,7 +2328,7 @@ int drm_mode_connector_property_set_ioctl(struct drm_device *dev, } else if (connector->funcs->set_property) ret = connector->funcs->set_property(connector, property, out_resp->value); - /* store the property value if succesful */ + /* store the property value if successful */ if (!ret) drm_connector_property_set_value(connector, property, out_resp->value); out: diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index abfc27b0c2e..a2a3fa59992 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1309,7 +1309,7 @@ out_free_list: * i915_gem_release_mmap - remove physical page mappings * @obj: obj in question * - * Preserve the reservation of the mmaping with the DRM core code, but + * Preserve the reservation of the mmapping with the DRM core code, but * relinquish ownership of the pages back to the system. * * It is vital that we remove the page mapping if we have mapped a tiled diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 2b0fe54cd92..40fcf6fdef3 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -70,7 +70,7 @@ static struct drm_fb_helper_funcs intel_fb_helper_funcs = { /** - * Curretly it is assumed that the old framebuffer is reused. + * Currently it is assumed that the old framebuffer is reused. * * LOCKING * caller should hold the mode config lock. diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 083bec2e50f..e7fa3279e2f 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2726,7 +2726,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) /* Wrap with our custom algo which switches to DDC mode */ intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; - /* In defaut case sdvo lvds is false */ + /* In default case sdvo lvds is false */ intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps); if (intel_sdvo_output_setup(intel_output, diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 609719490ec..00c739c4484 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -389,11 +389,11 @@ int r600_mc_init(struct radeon_device *rdev) * AGP so that GPU can catch out of VRAM/AGP access */ if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) { - /* Enought place before */ + /* Enough place before */ rdev->mc.vram_location = rdev->mc.gtt_location - rdev->mc.mc_vram_size; } else if (tmp > rdev->mc.mc_vram_size) { - /* Enought place after */ + /* Enough place after */ rdev->mc.vram_location = rdev->mc.gtt_location + rdev->mc.gtt_size; } else { diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index b38c4c8e2c6..d10eb43645c 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c @@ -59,7 +59,7 @@ static struct fb_ops radeonfb_ops = { }; /** - * Curretly it is assumed that the old framebuffer is reused. + * Currently it is assumed that the old framebuffer is reused. * * LOCKING * caller should hold the mode config lock. diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index 38537d971a3..067167cb39c 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c @@ -1950,7 +1950,7 @@ static void radeon_apply_surface_regs(int surf_index, * Note that refcount can be at most 2, since during a free refcount=3 * might mean we have to allocate a new surface which might not always * be available. - * For example : we allocate three contigous surfaces ABC. If B is + * For example : we allocate three contiguous surfaces ABC. If B is * freed, we suddenly need two surfaces to store A and C, which might * not always be available. */ diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 765bd184b6f..5a664000bf7 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -372,7 +372,7 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, new_mem->mem_type == TTM_PL_SYSTEM) || (old_mem->mem_type == TTM_PL_SYSTEM && new_mem->mem_type == TTM_PL_TT)) { - /* bind is enought */ + /* bind is enough */ radeon_move_null(bo, new_mem); return 0; } diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 595ac638039..9e9826ace30 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -807,11 +807,11 @@ int rv770_mc_init(struct radeon_device *rdev) * AGP so that GPU can catch out of VRAM/AGP access */ if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) { - /* Enought place before */ + /* Enough place before */ rdev->mc.vram_location = rdev->mc.gtt_location - rdev->mc.mc_vram_size; } else if (tmp > rdev->mc.mc_vram_size) { - /* Enought place after */ + /* Enough place after */ rdev->mc.vram_location = rdev->mc.gtt_location + rdev->mc.gtt_size; } else { diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index c70927ecda2..61c5572d2b9 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -427,7 +427,7 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo, /* * We need to use vmap to get the desired page protection - * or to make the buffer object look contigous. + * or to make the buffer object look contiguous. */ prot = (mem->placement & TTM_PL_FLAG_CACHED) ? PAGE_KERNEL : diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c index 36718150b47..e845b75ccee 100644 --- a/drivers/hwmon/adm1029.c +++ b/drivers/hwmon/adm1029.c @@ -432,7 +432,7 @@ static int adm1029_remove(struct i2c_client *client) } /* -function that update the status of the chips (temperature for exemple) +function that update the status of the chips (temperature for example) */ static struct adm1029_data *adm1029_update_device(struct device *dev) { diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index fc36cadf36f..c48a284b831 100644 --- a/drivers/hwmon/lm93.c +++ b/drivers/hwmon/lm93.c @@ -928,7 +928,7 @@ static void lm93_update_client_common(struct lm93_data *data, data->prochot_interval = lm93_read_byte(client, LM93_REG_PROCHOT_INTERVAL); - /* Fan Boost Termperature registers */ + /* Fan Boost Temperature registers */ for (i = 0; i < 4; i++) data->boost[i] = lm93_read_byte(client, LM93_REG_BOOST(i)); diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c index 2cd00b5b45b..9fd4a0d3206 100644 --- a/drivers/ieee1394/dv1394.c +++ b/drivers/ieee1394/dv1394.c @@ -125,7 +125,7 @@ 0 - no debugging messages 1 - some debugging messages, but none during DMA frame transmission 2 - lots of messages, including during DMA frame transmission - (will cause undeflows if your machine is too slow!) + (will cause underflows if your machine is too slow!) */ #define DV1394_DEBUG_LEVEL 0 diff --git a/drivers/infiniband/hw/ipath/ipath_iba6110.c b/drivers/infiniband/hw/ipath/ipath_iba6110.c index 4bd39c8af80..37d12e5efa4 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba6110.c +++ b/drivers/infiniband/hw/ipath/ipath_iba6110.c @@ -381,7 +381,7 @@ static const ipath_err_t infinipath_hwe_htclnkbbyte1crcerr = #define IPATH_GPIO_SCL \ (1ULL << (_IPATH_GPIO_SCL_NUM+INFINIPATH_EXTC_GPIOOE_SHIFT)) -/* keep the code below somewhat more readonable; not used elsewhere */ +/* keep the code below somewhat more readable; not used elsewhere */ #define _IPATH_HTLINK0_CRCBITS (infinipath_hwe_htclnkabyte0crcerr | \ infinipath_hwe_htclnkabyte1crcerr) #define _IPATH_HTLINK1_CRCBITS (infinipath_hwe_htclnkbbyte0crcerr | \ diff --git a/drivers/infiniband/hw/ipath/ipath_sd7220.c b/drivers/infiniband/hw/ipath/ipath_sd7220.c index aa47eb54952..2a68d9f624d 100644 --- a/drivers/infiniband/hw/ipath/ipath_sd7220.c +++ b/drivers/infiniband/hw/ipath/ipath_sd7220.c @@ -614,7 +614,7 @@ static int epb_trans(struct ipath_devdata *dd, u16 reg, u64 i_val, u64 *o_vp) * @wd: Write Data - value to set in register * @mask: ones where data should be spliced into reg. * - * Basic register read/modify/write, with un-needed acesses elided. That is, + * Basic register read/modify/write, with un-needed accesses elided. That is, * a mask of zero will prevent write, while a mask of 0xFF will prevent read. * returns current (presumed, if a write was done) contents of selected * register, or <0 if errors. @@ -989,7 +989,7 @@ static struct rxeq_init { /* Set DFELTHFDR/HDR thresholds */ RXEQ_VAL(7, 8, 0, 0, 0, 0), /* FDR */ RXEQ_VAL(7, 0x21, 0, 0, 0, 0), /* HDR */ - /* Set TLTHFDR/HDR theshold */ + /* Set TLTHFDR/HDR threshold */ RXEQ_VAL(7, 9, 2, 2, 2, 2), /* FDR */ RXEQ_VAL(7, 0x23, 2, 2, 2, 2), /* HDR */ /* Set Preamp setting 2 (ZFR/ZCNT) */ diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 219b10397b4..256a00c6aee 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -352,7 +352,7 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, * anymore, so we do this only if selective signaling is off. * * Further, on 32-bit platforms, we can't use vmap() to make - * the QP buffer virtually contigious. Thus we have to use + * the QP buffer virtually contiguous. Thus we have to use * constant-sized WRs to make sure a WR is always fully within * a single page-sized chunk. * diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c index 1c9410d1822..bcc2d30ec24 100644 --- a/drivers/input/serio/hp_sdc.c +++ b/drivers/input/serio/hp_sdc.c @@ -955,7 +955,7 @@ static int __init hp_sdc_init_hppa(struct parisc_device *d) INIT_DELAYED_WORK(&moduleloader_work, request_module_delayed); ret = hp_sdc_init(); - /* after sucessfull initialization give SDC some time to settle + /* after successfull initialization give SDC some time to settle * and then load the hp_sdc_mlc upper layer driver */ if (!ret) schedule_delayed_work(&moduleloader_work, diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c index 820e51673b2..7d2b820ef58 100644 --- a/drivers/input/serio/hp_sdc_mlc.c +++ b/drivers/input/serio/hp_sdc_mlc.c @@ -125,7 +125,7 @@ static void hp_sdc_mlc_isr (int irq, void *dev_id, break; default: - printk(KERN_WARNING PREFIX "Unkown HIL Error status (%x)!\n", data); + printk(KERN_WARNING PREFIX "Unknown HIL Error status (%x)!\n", data); break; } diff --git a/drivers/input/touchscreen/atmel-wm97xx.c b/drivers/input/touchscreen/atmel-wm97xx.c index 35377f583e2..a12242f77e2 100644 --- a/drivers/input/touchscreen/atmel-wm97xx.c +++ b/drivers/input/touchscreen/atmel-wm97xx.c @@ -59,7 +59,7 @@ #define ATMEL_WM97XX_AC97C_IRQ (29) #define ATMEL_WM97XX_GPIO_DEFAULT (32+16) /* Pin 16 on port B. */ #else -#error Unkown CPU, this driver only supports AT32AP700X CPUs. +#error Unknown CPU, this driver only supports AT32AP700X CPUs. #endif struct continuous { diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c index 8fc3b08deb3..6cdcf2a6e03 100644 --- a/drivers/input/touchscreen/mainstone-wm97xx.c +++ b/drivers/input/touchscreen/mainstone-wm97xx.c @@ -14,7 +14,7 @@ * * Notes: * This is a wm97xx extended touch driver to capture touch - * data in a continuous manner on the Intel XScale archictecture + * data in a continuous manner on the Intel XScale architecture * * Features: * - codecs supported:- WM9705, WM9712, WM9713 @@ -131,7 +131,7 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm) /* When the AC97 queue has been drained we need to allow time * to buffer up samples otherwise we end up spinning polling * for samples. The controller can't have a suitably low - * threashold set to use the notifications it gives. + * threshold set to use the notifications it gives. */ schedule_timeout_uninterruptible(1); diff --git a/drivers/input/touchscreen/zylonite-wm97xx.c b/drivers/input/touchscreen/zylonite-wm97xx.c index 41e4359c277..eca54dbdf49 100644 --- a/drivers/input/touchscreen/zylonite-wm97xx.c +++ b/drivers/input/touchscreen/zylonite-wm97xx.c @@ -96,7 +96,7 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm) /* When the AC97 queue has been drained we need to allow time * to buffer up samples otherwise we end up spinning polling * for samples. The controller can't have a suitably low - * threashold set to use the notifications it gives. + * threshold set to use the notifications it gives. */ msleep(1); diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c index 3e6d17f42a9..66b7d7a8647 100644 --- a/drivers/isdn/capi/capidrv.c +++ b/drivers/isdn/capi/capidrv.c @@ -830,7 +830,7 @@ static void handle_controller(_cmsg * cmsg) case 0: break; case 1: s = "unknown class"; break; case 2: s = "unknown function"; break; - default: s = "unkown error"; break; + default: s = "unknown error"; break; } if (s) printk(KERN_INFO "capidrv-%d: %s from controller 0x%x function %d: %s\n", diff --git a/drivers/isdn/hardware/eicon/di.c b/drivers/isdn/hardware/eicon/di.c index b029d130eb2..cb14ae3e715 100644 --- a/drivers/isdn/hardware/eicon/di.c +++ b/drivers/isdn/hardware/eicon/di.c @@ -806,7 +806,7 @@ static void xdi_xlog_request (byte Adapter, byte Id, DELIVERY - indication entered isdn_rc function RNR=... - application had returned RNR=... after the look ahead callback - RNum=0 - aplication had not returned any buffer to copy + RNum=0 - application had not returned any buffer to copy this indication and will copy it self COMPLETE - XDI had copied the data to the buffers provided bu the application and is about to issue the diff --git a/drivers/isdn/hardware/eicon/maintidi.c b/drivers/isdn/hardware/eicon/maintidi.c index 23960cb6eaa..e7cfb3b5647 100644 --- a/drivers/isdn/hardware/eicon/maintidi.c +++ b/drivers/isdn/hardware/eicon/maintidi.c @@ -385,7 +385,7 @@ static int SuperTraceMessageInput (void* hLib) { } break; default: - diva_mnt_internal_dprintf (0, DLI_ERR, "Unknon IDI Ind (DMA mode): %02x", Ind); + diva_mnt_internal_dprintf (0, DLI_ERR, "Unknown IDI Ind (DMA mode): %02x", Ind); } p += (this_ind_length+1); total_length -= (4 + this_ind_length); @@ -420,7 +420,7 @@ static int SuperTraceMessageInput (void* hLib) { } break; default: - diva_mnt_internal_dprintf (0, DLI_ERR, "Unknon IDI Ind: %02x", Ind); + diva_mnt_internal_dprintf (0, DLI_ERR, "Unknown IDI Ind: %02x", Ind); } } } diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c index fc46a26cb14..a64bb6c67ba 100644 --- a/drivers/isdn/hardware/mISDN/hfcsusb.c +++ b/drivers/isdn/hardware/mISDN/hfcsusb.c @@ -721,7 +721,7 @@ hfcsusb_setup_bch(struct bchannel *bch, int protocol) switch (protocol) { case (-1): /* used for init */ bch->state = -1; - /* fall trough */ + /* fall through */ case (ISDN_P_NONE): if (bch->state == ISDN_P_NONE) return 0; /* already in idle state */ diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.h b/drivers/isdn/hardware/mISDN/hfcsusb.h index 43efe7358fa..369196adae0 100644 --- a/drivers/isdn/hardware/mISDN/hfcsusb.h +++ b/drivers/isdn/hardware/mISDN/hfcsusb.h @@ -150,7 +150,7 @@ symbolic(struct hfcusb_symbolic_list list[], const int num) for (i = 0; list[i].name != NULL; i++) if (list[i].num == num) return list[i].name; - return ""; + return ""; } /* USB descriptor need to contain one of the following EndPoint combination: */ diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c index de352a17673..09095c74711 100644 --- a/drivers/isdn/hardware/mISDN/mISDNisar.c +++ b/drivers/isdn/hardware/mISDN/mISDNisar.c @@ -860,7 +860,7 @@ isar_pump_statev_modem(struct isar_ch *ch, u8 devt) { pr_debug("%s: pump stev GSTN CLEAR\n", ch->is->name); break; default: - pr_info("u%s: nknown pump stev %x\n", ch->is->name, devt); + pr_info("u%s: unknown pump stev %x\n", ch->is->name, devt); break; } } diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index 9de54202c90..ad5831f37d8 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c @@ -1086,7 +1086,7 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) break; default: DBG(HFCUSB_DBG_STATES, - "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x", pr); + "HFC_USB: hfc_usb_d_l2l1: unknown state : %#x", pr); break; } } diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c index 2d14b64202a..0f4ea7d16a1 100644 --- a/drivers/isdn/i4l/isdn_ppp.c +++ b/drivers/isdn/i4l/isdn_ppp.c @@ -836,7 +836,7 @@ isdn_ppp_write(int min, struct file *file, const char __user *buf, int count) unsigned short hl; struct sk_buff *skb; /* - * we need to reserve enought space in front of + * we need to reserve enough space in front of * sk_buff. old call to dev_alloc_skb only reserved * 16 bytes, now we are looking what the driver want */ @@ -1326,7 +1326,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev) struct sk_buff *new_skb; unsigned short hl; /* - * we need to reserve enought space in front of + * we need to reserve enough space in front of * sk_buff. old call to dev_alloc_skb only reserved * 16 bytes, now we are looking what the driver want. */ @@ -1685,7 +1685,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, * * try to accomplish several tasks: * - reassemble any complete fragment sequence (non-null 'start' - * indicates there is a continguous sequence present) + * indicates there is a contiguous sequence present) * - discard any incomplete sequences that are below minseq -- due * to the fact that sender always increment sequence number, if there * is an incomplete sequence below minseq, no new fragments would diff --git a/drivers/isdn/i4l/isdn_ttyfax.c b/drivers/isdn/i4l/isdn_ttyfax.c index 78f7660c1d0..4c41f191d4e 100644 --- a/drivers/isdn/i4l/isdn_ttyfax.c +++ b/drivers/isdn/i4l/isdn_ttyfax.c @@ -470,7 +470,7 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info) } return 0; } - /* BADMUL=value - dummy 0=disable errorchk disabled (treshold multiplier) */ + /* BADMUL=value - dummy 0=disable errorchk disabled (threshold multiplier) */ if (!strncmp(p[0], "BADMUL", 6)) { p[0] += 6; switch (*p[0]) { diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c index 77ee2867c8b..43ff4d3b046 100644 --- a/drivers/isdn/mISDN/dsp_core.c +++ b/drivers/isdn/mISDN/dsp_core.c @@ -110,7 +110,7 @@ * crossconnections and conferences via software if not possible through * hardware. If hardware capability is available, hardware is used. * - * Echo: Is generated by CMX and is used to check performane of hard and + * Echo: Is generated by CMX and is used to check performance of hard and * software CMX. * * The CMX has special functions for conferences with one, two and more diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c index e04bad6c5ba..6d4da609588 100644 --- a/drivers/isdn/mISDN/tei.c +++ b/drivers/isdn/mISDN/tei.c @@ -725,7 +725,7 @@ tei_id_ver_tout_net(struct FsmInst *fi, int event, void *arg) if (tm->rcnt == 1) { if (*debug & DEBUG_L2_TEI) tm->tei_m.printdebug(fi, - "check req for tei %d sucessful\n", tm->l2->tei); + "check req for tei %d successful\n", tm->l2->tei); mISDN_FsmChangeState(fi, ST_TEI_NOP); } else if (tm->rcnt > 1) { /* duplicate assignment; remove */ diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index 8b9364434aa..3fbe41b0ac0 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c @@ -15,7 +15,7 @@ * * WARNING: This driver has only been testen on Apple's * 1.25 MHz Dual G4 (March 03). It is tuned for a CPU - * temperatur around 57 C. + * temperature around 57 C. * * Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se) * diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c index 7e8f5681599..48cb154c7a4 100644 --- a/drivers/media/common/saa7146_i2c.c +++ b/drivers/media/common/saa7146_i2c.c @@ -98,7 +98,7 @@ static int saa7146_i2c_msg_cleanup(const struct i2c_msg *m, int num, __le32 *op) op_count++; - /* loop throgh all bytes of message i */ + /* loop through all bytes of message i */ for(j = 0; j < m[i].len; j++) { /* write back all bytes that could have been read */ m[i].buf[j] = (le32_to_cpu(op[op_count/3]) >> ((3-(op_count%3))*8)); diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index 810f07d6324..52e4ce4304e 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -160,7 +160,7 @@ struct tuner_state { * search callback possible return status * * DVBFE_ALGO_SEARCH_SUCCESS - * The frontend search algorithm completed and returned succesfully + * The frontend search algorithm completed and returned successfully * * DVBFE_ALGO_SEARCH_ASLEEP * The frontend search algorithm is sleeping diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index 2ae7f648eff..bb69f3719f9 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c @@ -344,7 +344,7 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) if (ret) return ret; - err("Unkown Anysee version: %02x %02x %02x. "\ + err("Unknown Anysee version: %02x %02x %02x. "\ "Please report the .", hw_info[0], hw_info[1], hw_info[2]); diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index eeef50bff4f..5c0126dc1ff 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c @@ -242,7 +242,7 @@ static struct dvb_usb_device_properties dibusb1_1_properties = { { &dibusb_dib3000mb_table[9], &dibusb_dib3000mb_table[11], NULL }, { &dibusb_dib3000mb_table[10], &dibusb_dib3000mb_table[12], NULL }, }, - { "Unkown USB1.1 DVB-T device ???? please report the name to the author", + { "Unknown USB1.1 DVB-T device ???? please report the name to the author", { &dibusb_dib3000mb_table[13], NULL }, { &dibusb_dib3000mb_table[14], NULL }, }, diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index edde87c6aa3..6b5ded9e7d5 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c @@ -259,7 +259,7 @@ int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d, *state = REMOTE_KEY_REPEAT; break; default: - deb_err("unkown type of remote status: %d\n",keybuf[0]); + deb_err("unknown type of remote status: %d\n",keybuf[0]); break; } return 0; diff --git a/drivers/media/dvb/dvb-usb/usb-urb.c b/drivers/media/dvb/dvb-usb/usb-urb.c index 9da2cc95ca1..f9702e3756b 100644 --- a/drivers/media/dvb/dvb-usb/usb-urb.c +++ b/drivers/media/dvb/dvb-usb/usb-urb.c @@ -56,7 +56,7 @@ static void usb_urb_complete(struct urb *urb) stream->complete(stream, b, urb->actual_length); break; default: - err("unkown endpoint type in completition handler."); + err("unknown endpoint type in completition handler."); return; } usb_submit_urb(urb,GFP_ATOMIC); @@ -228,7 +228,7 @@ int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properti case USB_ISOC: return usb_isoc_urb_init(stream); default: - err("unkown URB-type for data transfer."); + err("unknown URB-type for data transfer."); return -EINVAL; } } diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c index 74981ee923c..7c6431fe33e 100644 --- a/drivers/media/dvb/frontends/au8522_decoder.c +++ b/drivers/media/dvb/frontends/au8522_decoder.c @@ -315,7 +315,7 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode) if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 || input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) { /* Despite what the table says, for the HVR-950q we still need - to be in CVBS mode for the S-Video input (reason uknown). */ + to be in CVBS mode for the S-Video input (reason unknown). */ /* filter_coef_type = 3; */ filter_coef_type = 5; } else { diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c index ffbcfabd83f..00a4e8f0330 100644 --- a/drivers/media/dvb/frontends/cx24110.c +++ b/drivers/media/dvb/frontends/cx24110.c @@ -1,4 +1,4 @@ - /* +/* cx24110 - Single Chip Satellite Channel Receiver driver module Copyright (C) 2002 Peter Hettkamp based on @@ -96,7 +96,7 @@ static struct {u8 reg; u8 data;} cx24110_regdata[]= {0x42,0x00}, /* @ middle bytes " */ {0x43,0x00}, /* @ LSB " */ /* leave the carrier tracking loop parameters on default */ - /* leave the bit timing loop parameters at gefault */ + /* leave the bit timing loop parameters at default */ {0x56,0x4d}, /* set the filtune voltage to 2.7V, as recommended by */ /* the cx24108 data sheet for symbol rates above 15MS/s */ {0x57,0x00}, /* @ Filter sigma delta enabled, positive */ diff --git a/drivers/media/dvb/frontends/cx24113.c b/drivers/media/dvb/frontends/cx24113.c index 075b2b57cf0..e9ee55592fd 100644 --- a/drivers/media/dvb/frontends/cx24113.c +++ b/drivers/media/dvb/frontends/cx24113.c @@ -589,7 +589,7 @@ struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe, info("detected CX24113 variant\n"); break; case REV_CX24113: - info("sucessfully detected\n"); + info("successfully detected\n"); break; default: err("unsupported device id: %x\n", state->rev); diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c index 136b9d2164d..ad4c8cfd809 100644 --- a/drivers/media/dvb/frontends/dib3000mb.c +++ b/drivers/media/dvb/frontends/dib3000mb.c @@ -154,7 +154,7 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, case BANDWIDTH_AUTO: return -EOPNOTSUPP; default: - err("unkown bandwidth value."); + err("unknown bandwidth value."); return -EINVAL; } } diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c index 056387b41a8..43971e63baa 100644 --- a/drivers/media/dvb/frontends/lgdt330x.c +++ b/drivers/media/dvb/frontends/lgdt330x.c @@ -479,7 +479,7 @@ static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status) switch (state->current_modulation) { case QAM_256: case QAM_64: - /* Need to undestand why there are 3 lock levels here */ + /* Need to understand why there are 3 lock levels here */ if ((buf[0] & 0x07) == 0x07) *status |= FE_HAS_CARRIER; break; @@ -520,7 +520,7 @@ static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status) switch (state->current_modulation) { case QAM_256: case QAM_64: - /* Need to undestand why there are 3 lock levels here */ + /* Need to understand why there are 3 lock levels here */ if ((buf[0] & 0x07) == 0x07) *status |= FE_HAS_CARRIER; else diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c index a04c782fff8..1570669837e 100644 --- a/drivers/media/dvb/frontends/stb0899_drv.c +++ b/drivers/media/dvb/frontends/stb0899_drv.c @@ -1571,7 +1571,7 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvb_fron * stb0899_track * periodically check the signal level against a specified * threshold level and perform derotator centering. - * called once we have a lock from a succesful search + * called once we have a lock from a successful search * event. * * Will be called periodically called to maintain the diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 8d65c652ba5..baf3159a3aa 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c @@ -2425,7 +2425,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called */ saa7146_write(dev, EC1SSR, (0x03<<2) | 3 ); - /* set event counter 1 treshold to maximum allowed value (rEC p55) */ + /* set event counter 1 threshold to maximum allowed value (rEC p55) */ saa7146_write(dev, ECT1R, 0x3fff ); #endif /* Set RPS1 Address register to point to RPS code (r108 p42) */ @@ -2559,7 +2559,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called */ saa7146_write(dev, EC1SSR, (0x03<<2) | 3 ); - /* set event counter 1 treshold to maximum allowed value (rEC p55) */ + /* set event counter 1 threshold to maximum allowed value (rEC p55) */ saa7146_write(dev, ECT1R, 0x3fff ); #endif /* Setup BUDGETPATCH MAIN RPS1 "program" (p35) */ diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c index 60136688a9a..9c92f9ddd22 100644 --- a/drivers/media/dvb/ttpci/budget-patch.c +++ b/drivers/media/dvb/ttpci/budget-patch.c @@ -456,7 +456,7 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte // use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled // use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called saa7146_write(dev, EC1SSR, (0x03<<2) | 3 ); - // set event counter 1 treshold to maximum allowed value (rEC p55) + // set event counter 1 threshold to maximum allowed value (rEC p55) saa7146_write(dev, ECT1R, 0x3fff ); #endif // Fix VSYNC level diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index a1239083472..5f79acb56e4 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -28,7 +28,7 @@ * http://av-usbradio.sourceforge.net/index.php * http://sourceforge.net/projects/av-usbradio/ * Latest release of theirs project was in 2005. - * Probably, this driver could be improved trough using their + * Probably, this driver could be improved through using their * achievements (specifications given). * Also, Faidon Liambotis wrote nice driver for this radio * in 2007. He allowed to use his driver to improve current mr800 radio driver. diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c index 28f48f41f21..c2174413ab2 100644 --- a/drivers/media/video/cx231xx/cx231xx-avcore.c +++ b/drivers/media/video/cx231xx/cx231xx-avcore.c @@ -2414,9 +2414,11 @@ int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev) cx231xx_info("No ACK after %d msec -GPIO I2C failed!", nInit * 10); - /* readAck - throuth clock stretch ,slave has given a SCL signal, - so the SDA data can be directly read. */ + /* + * readAck + * through clock stretch, slave has given a SCL signal, + * so the SDA data can be directly read. + */ status = cx231xx_get_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); if ((dev->gpio_val & 1 << dev->board.tuner_sda_gpio) == 0) { diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 45e13ee66dc..16c6a921f40 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -940,7 +940,7 @@ int cx23885_dvb_register(struct cx23885_tsport *port) int err, i; /* Here we need to allocate the correct number of frontends, - * as reflected in the cards struct. The reality is that currrently + * as reflected in the cards struct. The reality is that currently * no cx23885 boards support this - yet. But, if we don't modify this * code then the second frontend would never be allocated (later) * and fail with error before the attach in dvb_register(). diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index cf634606ba9..b35411160f0 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c @@ -624,7 +624,7 @@ int cx88_reset(struct cx88_core *core) /* setup image format */ cx_andor(MO_COLOR_CTRL, 0x4000, 0x4000); - /* setup FIFO Threshholds */ + /* setup FIFO Thresholds */ cx_write(MO_PDMA_STHRSH, 0x0807); cx_write(MO_PDMA_DTHRSH, 0x0807); diff --git a/drivers/media/video/davinci/dm355_ccdc.c b/drivers/media/video/davinci/dm355_ccdc.c index 56fbefe036a..31439001637 100644 --- a/drivers/media/video/davinci/dm355_ccdc.c +++ b/drivers/media/video/davinci/dm355_ccdc.c @@ -285,7 +285,7 @@ static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam) if ((ccdcparam->med_filt_thres < 0) || (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) { - dev_dbg(dev, "Invalid value of median filter thresold\n"); + dev_dbg(dev, "Invalid value of median filter threshold\n"); return -EINVAL; } diff --git a/drivers/media/video/davinci/vpss.c b/drivers/media/video/davinci/vpss.c index 6d709ca8cfb..453236bd755 100644 --- a/drivers/media/video/davinci/vpss.c +++ b/drivers/media/video/davinci/vpss.c @@ -53,7 +53,7 @@ struct vpss_hw_ops { int (*enable_clock)(enum vpss_clock_sel clock_sel, int en); /* select input to ccdc */ void (*select_ccdc_source)(enum vpss_ccdc_source_sel src_sel); - /* clear wbl overlflow bit */ + /* clear wbl overflow bit */ int (*clear_wbl_overflow)(enum vpss_wbl_sel wbl_sel); }; diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index cf3af8de6e9..e39efb45fa1 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -304,7 +304,7 @@ static const __u8 initOv6650[] = { }; static const __u8 ov6650_sensor_init[][8] = { - /* Bright, contrast, etc are set througth SCBB interface. + /* Bright, contrast, etc are set through SCBB interface. * AVCAP on win2 do not send any data on this controls. */ /* Anyway, some registers appears to alter bright and constrat */ diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index fab7ef85a6c..7dbd5eea6cc 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c @@ -589,7 +589,7 @@ static void spca500_reinit(struct gspca_dev *gspca_dev) int err; __u8 Data; - /* some unknow command from Aiptek pocket dv and family300 */ + /* some unknown command from Aiptek pocket dv and family300 */ reg_w(gspca_dev, 0x00, 0x0d01, 0x01); reg_w(gspca_dev, 0x00, 0x0d03, 0x00); diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c index b74a34218da..66f9f005614 100644 --- a/drivers/media/video/gspca/spca501.c +++ b/drivers/media/video/gspca/spca501.c @@ -1636,7 +1636,7 @@ static const __u16 spca501c_arowana_init_data[][3] = { {} }; -/* Unknow camera from Ori Usbid 0x0000:0x0000 */ +/* Unknown camera from Ori Usbid 0x0000:0x0000 */ /* Based on snoops from Ori Cohen */ static const __u16 spca501c_mysterious_open_data[][3] = { {0x02, 0x000f, 0x0005}, @@ -1945,7 +1945,7 @@ static int sd_init(struct gspca_dev *gspca_dev) goto error; break; case MystFromOriUnknownCamera: - /* UnKnow Ori CMOS Camera data */ + /* Unknown Ori CMOS Camera data */ if (write_vector(gspca_dev, spca501c_mysterious_open_data)) goto error; break; @@ -1978,7 +1978,7 @@ static int sd_start(struct gspca_dev *gspca_dev) write_vector(gspca_dev, spca501c_arowana_open_data); break; case MystFromOriUnknownCamera: - /* UnKnow CMOS Camera data */ + /* Unknown CMOS Camera data */ write_vector(gspca_dev, spca501c_mysterious_init_data); break; default: diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index aa8f995ce04..1a9af2ebdbe 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c @@ -631,7 +631,7 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, count = 200; while (--count > 0) { msleep(10); - /* gsmart mini2 write a each wait setting 1 ms is enought */ + /* gsmart mini2 write a each wait setting 1 ms is enough */ /* reg_w_riv(dev, req, idx, val); */ status = reg_r_12(gspca_dev, 0x01, 0x0001, 1); if (status == endcode) { diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index cdf3357b4c9..49c3c1226e0 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -7065,7 +7065,7 @@ static int sd_config(struct gspca_dev *gspca_dev, break; default: PDEBUG(D_PROBE, - "Sensor UNKNOW_0 force Tas5130"); + "Sensor UNKNOWN_0 force Tas5130"); sd->sensor = SENSOR_TAS5130CXX; } break; diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index 5b152ff20bd..5fcad28211d 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h @@ -332,7 +332,7 @@ struct pvr2_hdw { /* Bit mask of PVR2_CVAL_INPUT choices which are valid for the hardware */ unsigned int input_avail_mask; - /* Bit mask of PVR2_CVAL_INPUT choices which are currenly allowed */ + /* Bit mask of PVR2_CVAL_INPUT choices which are currently allowed */ unsigned int input_allowed_mask; /* Location of eeprom or a negative number if none */ diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 9e3262c0ba3..a4c84368eb1 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c @@ -1985,7 +1985,7 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) wake_up(&dev->fw_data->wait_fw); break; default: - printk(KERN_INFO "s2255 unknwn resp\n"); + printk(KERN_INFO "s2255 unknown resp\n"); } default: pdata++; diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h index d439c76b27e..cb1de7ea197 100644 --- a/drivers/media/video/zoran/zoran.h +++ b/drivers/media/video/zoran/zoran.h @@ -106,7 +106,7 @@ struct zoran_params { unsigned long jpeg_markers; /* Which markers should go into the JPEG output. * Unless you exactly know what you do, leave them untouched. * Inluding less markers will make the resulting code - * smaller, but there will be fewer aplications + * smaller, but there will be fewer applications * which can read it. * The presence of the APP and COM marker is * influenced by APP0_len and COM_len ONLY! */ diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index d505b68cd37..e39986a7827 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -940,7 +940,7 @@ static const struct block_device_operations i2o_block_fops = { * Allocate memory for the i2o_block_device struct, gendisk and request * queue and initialize them as far as no additional information is needed. * - * Returns a pointer to the allocated I2O Block device on succes or a + * Returns a pointer to the allocated I2O Block device on success or a * negative error code on failure. */ static struct i2o_block_device *i2o_block_device_alloc(void) diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c index 27cf4af0e13..e5ab6214150 100644 --- a/drivers/message/i2o/iop.c +++ b/drivers/message/i2o/iop.c @@ -132,7 +132,7 @@ u32 i2o_cntxt_list_add(struct i2o_controller * c, void *ptr) * Removes a previously added pointer from the context list and returns * the matching context id. * - * Returns context id on succes or 0 on failure. + * Returns context id on success or 0 on failure. */ u32 i2o_cntxt_list_remove(struct i2o_controller * c, void *ptr) { @@ -198,7 +198,7 @@ void *i2o_cntxt_list_get(struct i2o_controller *c, u32 context) * @c: controller to which the context list belong * @ptr: pointer to which the context id should be fetched * - * Returns context id which matches to the pointer on succes or 0 on + * Returns context id which matches to the pointer on success or 0 on * failure. */ u32 i2o_cntxt_list_get_ptr(struct i2o_controller * c, void *ptr) diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c index 41c8fe2a928..ce5eda985ab 100644 --- a/drivers/misc/sgi-gru/grufile.c +++ b/drivers/misc/sgi-gru/grufile.c @@ -92,7 +92,7 @@ static void gru_vma_close(struct vm_area_struct *vma) /* * gru_file_mmap * - * Called when mmaping the device. Initializes the vma with a fault handler + * Called when mmapping the device. Initializes the vma with a fault handler * and private data structure necessary to allocate, track, and free the * underlying pages. */ diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 99b74a35102..941a4d35ef8 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -1360,7 +1360,7 @@ static struct mmc_host_ops s3cmci_ops = { static struct s3c24xx_mci_pdata s3cmci_def_pdata = { /* This is currently here to avoid a number of if (host->pdata) - * checks. Any zero fields to ensure reaonable defaults are picked. */ + * checks. Any zero fields to ensure reasonable defaults are picked. */ }; #ifdef CONFIG_CPU_FREQ diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index 3aa05cd18ea..592016a0668 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c @@ -18,7 +18,7 @@ to specify the offset instead of the absolute address NOTE: - With slram it's only possible to map a contigous memory region. Therfore + With slram it's only possible to map a contiguous memory region. Therefore if there's a device mapped somewhere in the region specified slram will fail to load (see kernel log if modprobe fails). diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index e51c1ed7ac1..b126cf88747 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c @@ -1056,7 +1056,7 @@ static struct nand_ecclayout doc200x_oobinfo = { }; /* Find the (I)NFTL Media Header, and optionally also the mirror media header. - On sucessful return, buf will contain a copy of the media header for + On successful return, buf will contain a copy of the media header for further processing. id is the string to scan for, and will presumably be either "ANAND" or "BNAND". If findmirror=1, also look for the mirror media header. The page #s of the found media headers are placed in mh0_page and diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c index db7ae9d6a29..92320a64327 100644 --- a/drivers/mtd/nand/nand_ecc.c +++ b/drivers/mtd/nand/nand_ecc.c @@ -475,7 +475,7 @@ int __nand_correct_data(unsigned char *buf, * * The b2 shift is there to get rid of the lowest two bits. * We could also do addressbits[b2] >> 1 but for the - * performace it does not make any difference + * performance it does not make any difference */ if (eccsize_mult == 1) byte_addr = (addressbits[b1] << 4) + addressbits[b0]; diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 11dc7e69c4f..68b5b3a486a 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -875,7 +875,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, * @info: The controller instance. * @nmtd: The driver version of the MTD instance. * - * This routine is called after the chip probe has succesfully completed + * This routine is called after the chip probe has successfully completed * and the relevant per-chip information updated. This call ensure that * we update the internal state accordingly. * diff --git a/drivers/net/82596.c b/drivers/net/82596.c index ea6b139b812..1663bc9e45d 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -19,7 +19,7 @@ TBD: * look at deferring rx frames rather than discarding (as per tulip) * handle tx ring full as per tulip - * performace test to tune rx_copybreak + * performance test to tune rx_copybreak Most of my modifications relate to the braindead big-endian implementation by Intel. When the i596 is operating in diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index 4e6359fff0e..766aabfdfc7 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -1633,8 +1633,13 @@ static int amd8111e_enable_link_change(struct amd8111e_priv* lp) readl(lp->mmio + CMD7); return 0; } -/* This function is called when a packet transmission fails to complete within a resonable period, on the assumption that an interrupts have been failed or the interface is locked up. This function will reinitialize the hardware */ +/* + * This function is called when a packet transmission fails to complete + * within a reasonable period, on the assumption that an interrupt have + * failed or the interface is locked up. This function will reinitialize + * the hardware. + */ static void amd8111e_tx_timeout(struct net_device *dev) { struct amd8111e_priv* lp = netdev_priv(dev); diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c index b5dc7f55072..9d828aed968 100644 --- a/drivers/net/appletalk/cops.c +++ b/drivers/net/appletalk/cops.c @@ -120,7 +120,7 @@ static int irq = 5; /* Default IRQ */ * DAYNA driver mode: * Dayna DL2000/DaynaTalk PC (Half Length), COPS LT-95, * Farallon PhoneNET PC III, Farallon PhoneNET PC II - * Other cards possibly supported mode unkown though: + * Other cards possibly supported mode unknown though: * Dayna DL2000 (Full length), COPS LT/M (Micro-Channel) * * Cards NOT supported by this driver but supported by the ltpc.c diff --git a/drivers/net/ariadne.h b/drivers/net/ariadne.h index bb613f292e0..727be5cdd1e 100644 --- a/drivers/net/ariadne.h +++ b/drivers/net/ariadne.h @@ -244,7 +244,7 @@ struct Am79C960 { #define DLNKTST 0x0010 /* Disable Link Status */ #define DAPC 0x0008 /* Disable Automatic Polarity Correction */ #define MENDECL 0x0004 /* MENDEC Loopback Mode */ -#define LRTTSEL 0x0002 /* Low Receive Treshold/Transmit Mode Select */ +#define LRTTSEL 0x0002 /* Low Receive Threshold/Transmit Mode Select */ #define PORTSEL1 0x0001 /* Port Select Bits */ #define PORTSEL2 0x8000 /* Port Select Bits */ #define INTL 0x4000 /* Internal Loopback */ diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 1372e9a99f5..96506eacc13 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -1543,7 +1543,7 @@ static irqreturn_t atl1c_intr(int irq, void *data) if (status & ISR_OVER) if (netif_msg_intr(adapter)) dev_warn(&pdev->dev, - "TX/RX over flow (status = 0x%x)\n", + "TX/RX overflow (status = 0x%x)\n", status & ISR_OVER); /* link event */ diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 49953787e41..f0bb62b5ca9 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -435,7 +435,7 @@ enum be_if_flags { * filtering capabilities. */ struct be_cmd_req_if_create { struct be_cmd_req_hdr hdr; - u32 version; /* ignore currntly */ + u32 version; /* ignore currently */ u32 capability_flags; u32 enable_flags; u8 mac_addr[ETH_ALEN]; diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 1f941f02771..02a0908707e 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1876,7 +1876,7 @@ int be_load_fw(struct be_adapter *adapter, u8 *func) goto fw_exit; } - dev_info(&adapter->pdev->dev, "Firmware flashed succesfully\n"); + dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n"); fw_exit: release_firmware(fw); diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h index aa76cbada5e..732eafdeb0f 100644 --- a/drivers/net/bnx2x_reg.h +++ b/drivers/net/bnx2x_reg.h @@ -2536,7 +2536,7 @@ /* [RC 1] A flag to indicate that overflow error occurred in one of the queues. */ #define QM_REG_OVFERROR 0x16805c -/* [RC 7] the Q were the qverflow occurs */ +/* [RC 7] the Q where the overflow occurs */ #define QM_REG_OVFQNUM 0x168058 /* [R 16] Pause state for physical queues 15-0 */ #define QM_REG_PAUSESTATE0 0x168410 diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index f86612857a7..56ba872be9c 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -1285,7 +1285,7 @@ netdev_tx_t t3_eth_xmit(struct sk_buff *skb, struct net_device *dev) /* * We do not use Tx completion interrupts to free DMAd Tx packets. - * This is good for performamce but means that we rely on new Tx + * This is good for performance but means that we rely on new Tx * packets arriving to run the destructors of completed packets, * which open up space in their sockets' send queues. Sometimes * we do not get such new packets causing Tx to stall. A single diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c index d7688522336..75b099ce49c 100644 --- a/drivers/net/ehea/ehea_ethtool.c +++ b/drivers/net/ehea/ehea_ethtool.c @@ -118,7 +118,7 @@ doit: ret = ehea_set_portspeed(port, sp); if (!ret) - ehea_info("%s: Port speed succesfully set: %dMbps " + ehea_info("%s: Port speed successfully set: %dMbps " "%s Duplex", port->netdev->name, port->port_speed, port->full_duplex == 1 ? "Full" : "Half"); @@ -134,7 +134,7 @@ static int ehea_nway_reset(struct net_device *dev) ret = ehea_set_portspeed(port, EHEA_SPEED_AUTONEG); if (!ret) - ehea_info("%s: Port speed succesfully set: %dMbps " + ehea_info("%s: Port speed successfully set: %dMbps " "%s Duplex", port->netdev->name, port->port_speed, port->full_duplex == 1 ? "Full" : "Half"); diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c index ed60fd66427..0cab992b3d1 100644 --- a/drivers/net/hamradio/baycom_ser_fdx.c +++ b/drivers/net/hamradio/baycom_ser_fdx.c @@ -35,7 +35,7 @@ * driver only supports standard serial hardware (8250, 16450, 16550A) * * This modem usually draws its supply current out of the otherwise unused - * TXD pin of the serial port. Thus a contignuous stream of 0x00-bytes + * TXD pin of the serial port. Thus a contiguous stream of 0x00-bytes * is transmitted to achieve a positive supply voltage. * * hsk: This is a 4800 baud FSK modem, designed for TNC use. It works fine diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index aa7286bc436..8739ba850f8 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -1384,7 +1384,7 @@ static inline void veth_build_dma_list(struct dma_chunk *list, unsigned long done; int i = 1; - /* FIXME: skbs are continguous in real addresses. Do we + /* FIXME: skbs are contiguous in real addresses. Do we * really need to break it into PAGE_SIZE chunks, or can we do * it just at the granularity of iSeries real->absolute * mapping? Indeed, given the way the allocator works, can we diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c index a0c578585a5..b77238dbafb 100644 --- a/drivers/net/lasi_82596.c +++ b/drivers/net/lasi_82596.c @@ -47,7 +47,7 @@ TBD: * look at deferring rx frames rather than discarding (as per tulip) * handle tx ring full as per tulip - * performace test to tune rx_copybreak + * performance test to tune rx_copybreak Most of my modifications relate to the braindead big-endian implementation by Intel. When the i596 is operating in diff --git a/drivers/net/lib82596.c b/drivers/net/lib82596.c index 51e11c3e53e..c0dbfc185b5 100644 --- a/drivers/net/lib82596.c +++ b/drivers/net/lib82596.c @@ -47,7 +47,7 @@ TBD: * look at deferring rx frames rather than discarding (as per tulip) * handle tx ring full as per tulip - * performace test to tune rx_copybreak + * performance test to tune rx_copybreak Most of my modifications relate to the braindead big-endian implementation by Intel. When the i596 is operating in diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index 03b781a7a18..829b9ec9ff6 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c @@ -204,7 +204,7 @@ static void mlx4_en_free_rx_desc(struct mlx4_en_priv *priv, en_dbg(DRV, priv, "Freeing fragment:%d\n", nr); dma = be64_to_cpu(rx_desc->data[nr].addr); - en_dbg(DRV, priv, "Unmaping buffer at dma:0x%llx\n", (u64) dma); + en_dbg(DRV, priv, "Unmapping buffer at dma:0x%llx\n", (u64) dma); pci_unmap_single(mdev->pdev, dma, skb_frags[nr].size, PCI_DMA_FROMDEVICE); put_page(skb_frags[nr].page); diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c index 8c7279965b4..3d1396af946 100644 --- a/drivers/net/mlx4/en_tx.c +++ b/drivers/net/mlx4/en_tx.c @@ -47,7 +47,7 @@ enum { static int inline_thold __read_mostly = MAX_INLINE; module_param_named(inline_thold, inline_thold, int, 0444); -MODULE_PARM_DESC(inline_thold, "treshold for using inline data"); +MODULE_PARM_DESC(inline_thold, "threshold for using inline data"); int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, struct mlx4_en_tx_ring *ring, u32 size, diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index 4376147b0ea..82c3ebc584e 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h @@ -162,7 +162,7 @@ enum { #define MLX4_EN_DEF_RX_PAUSE 1 #define MLX4_EN_DEF_TX_PAUSE 1 -/* Interval between sucessive polls in the Tx routine when polling is used +/* Interval between successive polls in the Tx routine when polling is used instead of interrupts (in per-core Tx rings) - should be power of 2 */ #define MLX4_EN_TX_POLL_MODER 16 #define MLX4_EN_TX_POLL_TIMEOUT (HZ / 4) diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index b211613e9db..86fde1a90a5 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c @@ -296,7 +296,7 @@ static void gelic_card_reset_chain(struct gelic_card *card, * @card: card structure * @descr: descriptor to re-init * - * return 0 on succes, <0 on failure + * return 0 on success, <0 on failure * * allocates a new rx skb, iommu-maps it and attaches it to the descriptor. * Activate the descriptor state-wise diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index c072f7f36ac..9d94a141555 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -1760,7 +1760,7 @@ static int sis900_rx(struct net_device *net_dev) sis_priv->rx_ring[entry].bufptr, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); - /* refill the Rx buffer, what if there is not enought + /* refill the Rx buffer, what if there is not enough * memory for new socket buffer ?? */ if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) { /* @@ -1775,7 +1775,7 @@ static int sis900_rx(struct net_device *net_dev) } /* This situation should never happen, but due to - some unknow bugs, it is possible that + some unknown bugs, it is possible that we are working on NULL sk_buff :-( */ if (sis_priv->rx_skbuff[entry] == NULL) { if (netif_msg_rx_err(sis_priv)) diff --git a/drivers/net/skfp/h/smc.h b/drivers/net/skfp/h/smc.h index 1758d954836..026a83b9f74 100644 --- a/drivers/net/skfp/h/smc.h +++ b/drivers/net/skfp/h/smc.h @@ -393,10 +393,10 @@ struct smt_config { */ u_long mac_d_max ; /* MAC : D_Max timer value */ - u_long lct_short ; /* LCT : error threshhold */ - u_long lct_medium ; /* LCT : error threshhold */ - u_long lct_long ; /* LCT : error threshhold */ - u_long lct_extended ; /* LCT : error threshhold */ + u_long lct_short ; /* LCT : error threshold */ + u_long lct_medium ; /* LCT : error threshold */ + u_long lct_long ; /* LCT : error threshold */ + u_long lct_extended ; /* LCT : error threshold */ } ; #ifdef DEBUG diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c index b27156eaf26..db216a72850 100644 --- a/drivers/net/skfp/skfddi.c +++ b/drivers/net/skfp/skfddi.c @@ -1002,7 +1002,7 @@ static int skfp_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } break; default: - printk("ioctl for %s: unknow cmd: %04x\n", dev->name, ioc.cmd); + printk("ioctl for %s: unknown cmd: %04x\n", dev->name, ioc.cmd); status = -EOPNOTSUPP; } // switch diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index ccdd196f529..4a00940d0a5 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -816,7 +816,7 @@ static int smsc911x_mii_probe(struct net_device *dev) SMSC_TRACE(HW, "Passed Loop Back Test"); #endif /* USE_PHY_WORK_AROUND */ - SMSC_TRACE(HW, "phy initialised succesfully"); + SMSC_TRACE(HW, "phy initialised successfully"); return 0; } diff --git a/drivers/net/smsc911x.h b/drivers/net/smsc911x.h index b5716bd8a59..016360c65ce 100644 --- a/drivers/net/smsc911x.h +++ b/drivers/net/smsc911x.h @@ -30,7 +30,7 @@ #define SMSC_NAPI_WEIGHT 16 /* implements a PHY loopback test at initialisation time, to ensure a packet - * can be succesfully looped back */ + * can be successfully looped back */ #define USE_PHY_WORK_AROUND #define DPRINTK(nlevel, klevel, fmt, args...) \ diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 90e663f4515..40b51e6bc77 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -409,7 +409,7 @@ spider_net_free_rx_chain_contents(struct spider_net_card *card) * @card: card structure * @descr: descriptor to re-init * - * Return 0 on succes, <0 on failure. + * Return 0 on success, <0 on failure. * * Allocates a new rx skb, iommu-maps it and attaches it to the * descriptor. Mark the descriptor as activated, ready-to-use. diff --git a/drivers/net/stmmac/gmac.c b/drivers/net/stmmac/gmac.c index b624bb5bae0..52586ee6895 100644 --- a/drivers/net/stmmac/gmac.c +++ b/drivers/net/stmmac/gmac.c @@ -112,7 +112,7 @@ static void gmac_dma_operation_mode(unsigned long ioaddr, int txmode, " (threshold = %d)\n", txmode); csr6 &= ~DMA_CONTROL_TSF; csr6 &= DMA_CONTROL_TC_TX_MASK; - /* Set the transmit threashold */ + /* Set the transmit threshold */ if (txmode <= 32) csr6 |= DMA_CONTROL_TTC_32; else if (txmode <= 64) diff --git a/drivers/net/stmmac/gmac.h b/drivers/net/stmmac/gmac.h index 684a363120a..2e82d6c9a14 100644 --- a/drivers/net/stmmac/gmac.h +++ b/drivers/net/stmmac/gmac.h @@ -154,14 +154,14 @@ enum rx_tx_priority_ratio { #define DMA_CONTROL_DT 0x04000000 /* Disable Drop TCP/IP csum error */ #define DMA_CONTROL_RSF 0x02000000 /* Receive Store and Forward */ #define DMA_CONTROL_DFF 0x01000000 /* Disaable flushing */ -/* Theshold for Activating the FC */ +/* Threshold for Activating the FC */ enum rfa { act_full_minus_1 = 0x00800000, act_full_minus_2 = 0x00800200, act_full_minus_3 = 0x00800400, act_full_minus_4 = 0x00800600, }; -/* Theshold for Deactivating the FC */ +/* Threshold for Deactivating the FC */ enum rfd { deac_full_minus_1 = 0x00400000, deac_full_minus_2 = 0x00400800, diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c index ebda61bc4c2..78e12b5e3ac 100644 --- a/drivers/net/tokenring/smctr.c +++ b/drivers/net/tokenring/smctr.c @@ -426,7 +426,7 @@ static int smctr_alloc_shared_memory(struct net_device *dev) smctr_malloc(dev, 1L); /* Allocate Non-MAC receive data buffers. - * To guarantee a minimum of 256 contigous memory to + * To guarantee a minimum of 256 contiguous memory to * UM_Receive_Packet's lookahead pointer, before a page * change or ring end is encountered, place each rx buffer on * a 256 byte boundary. diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 4469f2451a6..5e9adbaf674 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3798,7 +3798,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma prop = of_get_property(np, "tx-clock", NULL); if (!prop) { printk(KERN_ERR - "ucc_geth: mising tx-clock-name property\n"); + "ucc_geth: missing tx-clock-name property\n"); return -EINVAL; } if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) { diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index 03a6ca016d5..a007e2acf65 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h @@ -80,16 +80,16 @@ struct ucc_geth { frames) received that were between 128 (Including FCS length==4) and 255 octets */ u32 txok; /* Total number of octets residing in frames - that where involved in succesfull + that where involved in successfull transmission */ u16 txcf; /* Total number of PAUSE control frames transmitted by this MAC */ u8 res4[0x2]; u32 tmca; /* Total number of frames that were transmitted - succesfully with the group address bit set + successfully with the group address bit set that are not broadcast frames */ u32 tbca; /* Total number of frames transmitted - succesfully that had destination address + successfully that had destination address field equal to the broadcast address */ u32 rxfok; /* Total number of frames received OK */ u32 rxbok; /* Total number of octets received OK */ @@ -98,9 +98,9 @@ struct ucc_geth { HW because it includes octets in frames that never even reach the UCC */ u32 rmca; /* Total number of frames that were received - succesfully with the group address bit set + successfully with the group address bit set that are not broadcast frames */ - u32 rbca; /* Total number of frames received succesfully + u32 rbca; /* Total number of frames received successfully that had destination address equal to the broadcast address */ u32 scar; /* Statistics carry register */ @@ -759,15 +759,15 @@ struct ucc_geth_hardware_statistics { frames) received that were between 128 (Including FCS length==4) and 255 octets */ u32 txok; /* Total number of octets residing in frames - that where involved in succesfull + that where involved in successfull transmission */ u16 txcf; /* Total number of PAUSE control frames transmitted by this MAC */ u32 tmca; /* Total number of frames that were transmitted - succesfully with the group address bit set + successfully with the group address bit set that are not broadcast frames */ u32 tbca; /* Total number of frames transmitted - succesfully that had destination address + successfully that had destination address field equal to the broadcast address */ u32 rxfok; /* Total number of frames received OK */ u32 rxbok; /* Total number of octets received OK */ @@ -776,9 +776,9 @@ struct ucc_geth_hardware_statistics { HW because it includes octets in frames that never even reach the UCC */ u32 rmca; /* Total number of frames that were received - succesfully with the group address bit set + successfully with the group address bit set that are not broadcast frames */ - u32 rbca; /* Total number of frames received succesfully + u32 rbca; /* Total number of frames received successfully that had destination address equal to the broadcast address */ } __attribute__ ((packed)); diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index c6c922247d0..0c3c738d741 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -748,7 +748,7 @@ static int smsc95xx_phy_initialize(struct usbnet *dev) mii_nway_restart(&dev->mii); if (netif_msg_ifup(dev)) - devdbg(dev, "phy initialised succesfully"); + devdbg(dev, "phy initialised successfully"); return 0; } diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c index 7ea71b33d2e..ee784e091f6 100644 --- a/drivers/net/wan/lmc/lmc_main.c +++ b/drivers/net/wan/lmc/lmc_main.c @@ -927,7 +927,7 @@ static int __devinit lmc_init_one(struct pci_dev *pdev, sc->lmc_media = &lmc_t1_media; break; default: - printk(KERN_WARNING "%s: LMC UNKOWN CARD!\n", dev->name); + printk(KERN_WARNING "%s: LMC UNKNOWN CARD!\n", dev->name); break; } diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c index 07c32e68909..99d27473ba3 100644 --- a/drivers/net/wimax/i2400m/rx.c +++ b/drivers/net/wimax/i2400m/rx.c @@ -1114,7 +1114,7 @@ error: * device. See the file header for the format. Run all checks on the * buffer header, then run over each payload's descriptors, verify * their consistency and act on each payload's contents. If - * everything is succesful, update the device's statistics. + * everything is successful, update the device's statistics. * * Note: You need to set the skb to contain only the length of the * received buffer; for that, use skb_trim(skb, RECEIVED_SIZE). diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 1a039f2bd73..6f04cc758dc 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -117,7 +117,7 @@ static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah, /* * This code is used to optimize rf gain on different environments - * (temprature mostly) based on feedback from a power detector. + * (temperature mostly) based on feedback from a power detector. * * It's only used on RF5111 and RF5112, later RF chips seem to have * auto adjustment on hw -notice they have a much smaller BANK 7 and @@ -2675,7 +2675,7 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah, /* Fill curves in reverse order * from lower power (max gain) * to higher power. Use curve -> idx - * backmaping we did on eeprom init */ + * backmapping we did on eeprom init */ u8 idx = pdg_curve_to_idx[pdg]; /* Grab the needed curves by index */ @@ -2777,7 +2777,7 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah, /* Now we have a set of curves for this * channel on tmpL (x range is table_max - table_min * and y values are tmpL[pdg][]) sorted in the same - * order as EEPROM (because we've used the backmaping). + * order as EEPROM (because we've used the backmapping). * So for RF5112 it's from higher power to lower power * and for RF2413 it's from lower power to higher power. * For RF5111 we only have one curve. */ diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 1895d63aad0..0a35ee62a02 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -969,7 +969,7 @@ static bool ath_rc_update_per(struct ath_softc *sc, * Since this probe succeeded, we allow the next * probe twice as soon. This allows the maxRate * to move up faster if the probes are - * succesful. + * successful. */ ath_rc_priv->probe_time = now_msec - rate_table->probe_interval / 2; diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index a741d37fd96..e1b33002320 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -551,7 +551,7 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord, /* get number of entries */ field_count = *(((u16 *) & field_info) + 1); - /* abort if no enought memory */ + /* abort if no enough memory */ total_length = field_len * field_count; if (total_length > *len) { *len = total_length; @@ -3044,7 +3044,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv) IPW_MAX_BDS)) { /* TODO: Support merging buffers if more than * IPW_MAX_BDS are used */ - IPW_DEBUG_INFO("%s: Maximum BD theshold exceeded. " + IPW_DEBUG_INFO("%s: Maximum BD threshold exceeded. " "Increase fragmentation level.\n", priv->net_dev->name); } @@ -6823,7 +6823,7 @@ static int ipw2100_wx_get_range(struct net_device *dev, range->max_qual.updated = 7; /* Updated all three */ range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */ - /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ + /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ range->avg_qual.level = 20 + IPW2100_RSSI_TO_DBM; range->avg_qual.noise = 0; range->avg_qual.updated = 7; /* Updated all three */ diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 9b0f2c0646e..b2aa960b834 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -787,7 +787,7 @@ static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len) /* get number of entries */ field_count = *(((u16 *) & field_info) + 1); - /* abort if not enought memory */ + /* abort if not enough memory */ total_len = field_len * field_count; if (total_len > *len) { *len = total_len; @@ -7751,7 +7751,7 @@ static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv, case SEC_LEVEL_0: break; default: - printk(KERN_ERR "Unknow security level %d\n", + printk(KERN_ERR "Unknown security level %d\n", priv->ieee->sec.level); break; } @@ -8917,7 +8917,7 @@ static int ipw_wx_get_range(struct net_device *dev, range->max_qual.updated = 7; /* Updated all three */ range->avg_qual.qual = 70; - /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ + /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ range->avg_qual.level = 0; /* FIXME to real average level */ range->avg_qual.noise = 0; range->avg_qual.updated = 7; /* Updated all three */ @@ -10290,7 +10290,7 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct libipw_txb *txb, case SEC_LEVEL_0: break; default: - printk(KERN_ERR "Unknow security level %d\n", + printk(KERN_ERR "Unknown security level %d\n", priv->ieee->sec.level); break; } diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c index be5b809ec97..20b8a8a2064 100644 --- a/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/ipw2x00/libipw_module.c @@ -199,7 +199,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv, int monitor) ieee->host_decrypt = 1; ieee->host_mc_decrypt = 1; - /* Host fragementation in Open mode. Default is enabled. + /* Host fragmentation in Open mode. Default is enabled. * Note: host fragmentation is always enabled if host encryption * is enabled. For cards can do hardware encryption, they must do * hardware fragmentation as well. So we don't need a variable diff --git a/drivers/net/wireless/iwmc3200wifi/hal.c b/drivers/net/wireless/iwmc3200wifi/hal.c index c430418248b..d13c8853ee8 100644 --- a/drivers/net/wireless/iwmc3200wifi/hal.c +++ b/drivers/net/wireless/iwmc3200wifi/hal.c @@ -411,7 +411,7 @@ static void iwm_build_lmac_hdr(struct iwm_priv *iwm, struct iwm_lmac_hdr *hdr, /* * iwm_hal_send_host_cmd(): sends commands to the UMAC or the LMAC. * Sending command to the LMAC is equivalent to sending a - * regular UMAC command with the LMAC passtrough or the LMAC + * regular UMAC command with the LMAC passthrough or the LMAC * wrapper UMAC command IDs. */ int iwm_hal_send_host_cmd(struct iwm_priv *iwm, diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c index 771a301003c..8ddb51a2a97 100644 --- a/drivers/net/wireless/iwmc3200wifi/rx.c +++ b/drivers/net/wireless/iwmc3200wifi/rx.c @@ -1448,7 +1448,7 @@ static void iwm_rx_process_packet(struct iwm_priv *iwm, kfree_skb(packet->skb); break; default: - IWM_ERR(iwm, "Unknow ticket action: %d\n", + IWM_ERR(iwm, "Unknown ticket action: %d\n", le16_to_cpu(ticket_node->ticket->action)); kfree_skb(packet->skb); } diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 485a8d40652..afe6abecc04 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -934,7 +934,7 @@ static int if_sdio_probe(struct sdio_func *func, } if (i == ARRAY_SIZE(if_sdio_models)) { - lbs_pr_err("unkown card model 0x%x\n", card->model); + lbs_pr_err("unknown card model 0x%x\n", card->model); ret = -ENODEV; goto free; } diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index bc08464d832..f7f5c793514 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c @@ -1897,7 +1897,7 @@ prism54_get_mac(struct net_device *ndev, struct iw_request_info *info, return 0; } -/* Setting policy also clears the MAC acl, even if we don't change the defaut +/* Setting policy also clears the MAC acl, even if we don't change the default * policy */ @@ -2323,7 +2323,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid, case DOT11_OID_BEACON: send_formatted_event(priv, - "Received a beacon from an unkown AP", + "Received a beacon from an unknown AP", mlme, 0); break; diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h index ccd644104ad..aced0577569 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.h +++ b/drivers/net/wireless/rt2x00/rt2400pci.h @@ -35,7 +35,7 @@ /* * Signal information. - * Defaul offset is required for RSSI <-> dBm conversion. + * Default offset is required for RSSI <-> dBm conversion. */ #define DEFAULT_RSSI_OFFSET 100 diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h index 54d37957883..3db9041838a 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.h +++ b/drivers/net/wireless/rt2x00/rt2500pci.h @@ -46,7 +46,7 @@ /* * Signal information. - * Defaul offset is required for RSSI <-> dBm conversion. + * Default offset is required for RSSI <-> dBm conversion. */ #define DEFAULT_RSSI_OFFSET 121 diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h index b01edca4258..d3000827883 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.h +++ b/drivers/net/wireless/rt2x00/rt2500usb.h @@ -46,7 +46,7 @@ /* * Signal information. - * Defaul offset is required for RSSI <-> dBm conversion. + * Default offset is required for RSSI <-> dBm conversion. */ #define DEFAULT_RSSI_OFFSET 120 diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index 93eb699165c..77b5116f549 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h @@ -37,7 +37,7 @@ /* * Signal information. - * Defaul offset is required for RSSI <-> dBm conversion. + * Default offset is required for RSSI <-> dBm conversion. */ #define DEFAULT_RSSI_OFFSET 120 diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index 81fe0be51c4..e194332dac5 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h @@ -37,7 +37,7 @@ /* * Signal information. - * Defaul offset is required for RSSI <-> dBm conversion. + * Default offset is required for RSSI <-> dBm conversion. */ #define DEFAULT_RSSI_OFFSET 120 diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c index 431a20ec6db..b3b0b5b685c 100644 --- a/drivers/net/wireless/wavelan_cs.c +++ b/drivers/net/wireless/wavelan_cs.c @@ -4011,7 +4011,7 @@ wavelan_interrupt(int irq, #endif /* Prevent reentrancy. We need to do that because we may have - * multiple interrupt handler running concurently. + * multiple interrupt handler running concurrently. * It is safe because interrupts are disabled before aquiring * the spinlock. */ spin_lock(&lp->spinlock); diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 6d666359a42..2b7f9659437 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -312,7 +312,7 @@ static void tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, * zd_mac_tx_failed - callback for failed frames * @dev: the mac80211 wireless device * - * This function is called if a frame couldn't be succesfully be + * This function is called if a frame couldn't be successfully be * transferred. The first frame from the tx queue, will be selected and * reported as error to the upper layers. */ diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index a6b4a5a53d4..f511e70d454 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -650,7 +650,7 @@ ccio_clear_io_tlb(struct ioc *ioc, dma_addr_t iovp, size_t byte_cnt) * Mark the I/O Pdir entries invalid and blow away the corresponding I/O * TLB entries. * - * FIXME: at some threshhold it might be "cheaper" to just blow + * FIXME: at some threshold it might be "cheaper" to just blow * away the entire I/O TLB instead of individual entries. * * FIXME: Uturn has 256 TLB entries. We don't need to purge every diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index d93108d148f..36db20a8f89 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -6533,7 +6533,7 @@ static struct ibm_struct volume_driver_data = { * The speeds are stored on handles * (FANA:FAN9), (FANC:FANB), (FANE:FAND). * - * There are three default speed sets, acessible as handles: + * There are three default speed sets, accessible as handles: * FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H * * ACPI DSDT switches which set is in use depending on various diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index 87b4f49a525..a5135ebe5f0 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c @@ -191,7 +191,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(struct pnp_dev *dev, return (unsigned char *)p; break; - default: /* an unkown tag */ + default: /* an unknown tag */ len_err: dev_err(&dev->dev, "unknown tag %#x length %d\n", tag, len); @@ -405,7 +405,7 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, case SMALL_TAG_END: return p + 2; - default: /* an unkown tag */ + default: /* an unknown tag */ len_err: dev_err(&dev->dev, "unknown tag %#x length %d\n", tag, len); @@ -475,7 +475,7 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p, return (unsigned char *)p; break; - default: /* an unkown tag */ + default: /* an unknown tag */ len_err: dev_err(&dev->dev, "unknown tag %#x length %d\n", tag, len); @@ -744,7 +744,7 @@ static unsigned char *pnpbios_encode_allocated_resource_data(struct pnp_dev return (unsigned char *)p; break; - default: /* an unkown tag */ + default: /* an unknown tag */ len_err: dev_err(&dev->dev, "unknown tag %#x length %d\n", tag, len); diff --git a/drivers/ps3/ps3-sys-manager.c b/drivers/ps3/ps3-sys-manager.c index 88cb7408861..3cbaf1811bd 100644 --- a/drivers/ps3/ps3-sys-manager.c +++ b/drivers/ps3/ps3-sys-manager.c @@ -46,7 +46,7 @@ /** * struct ps3_sys_manager_header - System manager message header. * @version: Header version, currently 1. - * @size: Header size in bytes, curently 16. + * @size: Header size in bytes, currently 16. * @payload_size: Message payload size in bytes. * @service_id: Message type, one of enum ps3_sys_manager_service_id. * @request_tag: Unique number to identify reply. diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c index ad164056feb..434e92fdb96 100644 --- a/drivers/rtc/rtc-v3020.c +++ b/drivers/rtc/rtc-v3020.c @@ -335,7 +335,7 @@ static int rtc_probe(struct platform_device *pdev) goto err_io; } - /* Make sure frequency measurment mode, test modes, and lock + /* Make sure frequency measurement mode, test modes, and lock * are all disabled */ v3020_set_reg(chip, V3020_STATUS_0, 0x0); diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index 097d3846a82..f54b1eec6dd 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c @@ -74,7 +74,7 @@ fs3270_do_io(struct raw3270_view *view, struct raw3270_request *rq) } rc = raw3270_start(view, rq); if (rc == 0) { - /* Started sucessfully. Now wait for completion. */ + /* Started successfully. Now wait for completion. */ wait_event(fp->wait, raw3270_request_final(rq)); } } while (rc == -EACCES); diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index 8ab51608da5..c268a2e5b7c 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -65,7 +65,7 @@ static void set_chp_logically_online(struct chp_id chpid, int onoff) chpid_to_chp(chpid)->state = onoff; } -/* On succes return 0 if channel-path is varied offline, 1 if it is varied +/* On success return 0 if channel-path is varied offline, 1 if it is varied * online. Return -ENODEV if channel-path is not registered. */ int chp_get_status(struct chp_id chpid) { diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c index 30f51611130..2985eb43948 100644 --- a/drivers/s390/cio/cmf.c +++ b/drivers/s390/cio/cmf.c @@ -462,7 +462,7 @@ static struct cmb_area cmb_area = { * block of memory, which can not be moved as long as any channel * is active. Therefore, a maximum number of subchannels needs to * be defined somewhere. This is a module parameter, defaulting to - * a resonable value of 1024, or 32 kb of memory. + * a reasonable value of 1024, or 32 kb of memory. * Current kernels don't allow kmalloc with more than 128kb, so the * maximum is 4096. */ diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index 58e583b61e6..aa2b60a868b 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c @@ -92,11 +92,11 @@ #define ENVCTRL_CPUTEMP_MON 1 /* cpu temperature monitor */ #define ENVCTRL_CPUVOLTAGE_MON 2 /* voltage monitor */ #define ENVCTRL_FANSTAT_MON 3 /* fan status monitor */ -#define ENVCTRL_ETHERTEMP_MON 4 /* ethernet temperarture */ +#define ENVCTRL_ETHERTEMP_MON 4 /* ethernet temperature */ /* monitor */ #define ENVCTRL_VOLTAGESTAT_MON 5 /* voltage status monitor */ #define ENVCTRL_MTHRBDTEMP_MON 6 /* motherboard temperature */ -#define ENVCTRL_SCSITEMP_MON 7 /* scsi temperarture */ +#define ENVCTRL_SCSITEMP_MON 7 /* scsi temperature */ #define ENVCTRL_GLOBALADDR_MON 8 /* global address */ /* Child device type. diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index f5a9addb705..07ce9bfcdf0 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -1491,7 +1491,7 @@ NCR_700_intr(int irq, void *dev_id) unsigned long flags; int handled = 0; - /* Use the host lock to serialise acess to the 53c700 + /* Use the host lock to serialise access to the 53c700 * hardware. Note: In future, we may need to take the queue * lock to enter the done routines. When that happens, we * need to ensure that for this driver, the host lock and the diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index cdbdec9f4fb..83986ed8655 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -526,10 +526,10 @@ struct aac_driver_ident /* * The adapter interface specs all queues to be located in the same - * physically contigous block. The host structure that defines the + * physically contiguous block. The host structure that defines the * commuication queues will assume they are each a separate physically - * contigous memory region that will support them all being one big - * contigous block. + * contiguous memory region that will support them all being one big + * contiguous block. * There is a command and response queue for each level and direction of * commuication. These regions are accessed by both the host and adapter. */ diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index d598eba630d..666d5151d62 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c @@ -226,7 +226,7 @@ static int aac_comm_init(struct aac_dev * dev) spin_lock_init(&dev->fib_lock); /* - * Allocate the physically contigous space for the commuication + * Allocate the physically contiguous space for the commuication * queue headers. */ diff --git a/drivers/scsi/aic7xxx/aic79xx.seq b/drivers/scsi/aic7xxx/aic79xx.seq index 3b66b5ae3d9..2fb78e35a9e 100644 --- a/drivers/scsi/aic7xxx/aic79xx.seq +++ b/drivers/scsi/aic7xxx/aic79xx.seq @@ -217,7 +217,7 @@ BEGIN_CRITICAL; scbdma_tohost_done: test CCSCBCTL, CCARREN jz fill_qoutfifo_dmadone; /* - * An SCB has been succesfully uploaded to the host. + * An SCB has been successfully uploaded to the host. * If the SCB was uploaded for some reason other than * bad SCSI status (currently only for underruns), we * queue the SCB for normal completion. Otherwise, we diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 63b521d615f..4d419c155ce 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c @@ -2487,7 +2487,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) /* * Although the driver does not care about the * 'Selection in Progress' status bit, the busy - * LED does. SELINGO is only cleared by a sucessfull + * LED does. SELINGO is only cleared by a successfull * selection, so we must manually clear it to insure * the LED turns off just incase no future successful * selections occur (e.g. no devices on the bus). diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c index 8dfb59d5899..45aa728a76b 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_core.c +++ b/drivers/scsi/aic7xxx/aic7xxx_core.c @@ -1733,7 +1733,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat) /* * Although the driver does not care about the * 'Selection in Progress' status bit, the busy - * LED does. SELINGO is only cleared by a sucessfull + * LED does. SELINGO is only cleared by a successfull * selection, so we must manually clear it to insure * the LED turns off just incase no future successful * selections occur (e.g. no devices on the bus). diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h index a000bc4e2d4..bf320412ee2 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h @@ -61,7 +61,7 @@ enum bfa_pport_speed { * Port operational type (in sync with SNIA port type). */ enum bfa_pport_type { - BFA_PPORT_TYPE_UNKNOWN = 1, /* port type is unkown */ + BFA_PPORT_TYPE_UNKNOWN = 1, /* port type is unknown */ BFA_PPORT_TYPE_TRUNKED = 2, /* Trunked mode */ BFA_PPORT_TYPE_NPORT = 5, /* P2P with switched fabric */ BFA_PPORT_TYPE_NLPORT = 6, /* public loop */ diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h b/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h index 31881d21851..ade763dbc8c 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h @@ -25,7 +25,7 @@ * Temperature sensor status values */ enum bfa_tsensor_status { - BFA_TSENSOR_STATUS_UNKNOWN = 1, /* unkown status */ + BFA_TSENSOR_STATUS_UNKNOWN = 1, /* unknown status */ BFA_TSENSOR_STATUS_FAULTY = 2, /* sensor is faulty */ BFA_TSENSOR_STATUS_BELOW_MIN = 3, /* temperature below mininum */ BFA_TSENSOR_STATUS_NOMINAL = 4, /* normal temperature */ diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c index a0e7e711ff9..5be67a6fca9 100644 --- a/drivers/scsi/hptiop.c +++ b/drivers/scsi/hptiop.c @@ -834,7 +834,7 @@ static int hptiop_reset_hba(struct hptiop_hba *hba) atomic_read(&hba->resetting) == 0, 60 * HZ); if (atomic_read(&hba->resetting)) { - /* IOP is in unkown state, abort reset */ + /* IOP is in unknown state, abort reset */ printk(KERN_ERR "scsi%d: reset failed\n", hba->host->host_no); return -1; } diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index bd2f7719744..6486ae4591b 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c @@ -56,7 +56,7 @@ * at the same time. * * When discovery succeeds or fails a callback is made to the lport as - * notification. Currently, succesful discovery causes the lport to take no + * notification. Currently, successful discovery causes the lport to take no * action. A failure will cause the lport to reset. There is likely a circular * locking problem with this implementation. */ diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index 2e0746d7030..ca25ee5190b 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c @@ -1004,7 +1004,7 @@ static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task) * iscsi_tcp_task_xmit - xmit normal PDU task * @task: iscsi command task * - * We're expected to return 0 when everything was transmitted succesfully, + * We're expected to return 0 when everything was transmitted successfully, * -EAGAIN if there's still data in the queue, or != 0 for any other kind * of error. */ diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index e1a30a16a9f..9bd19aa1424 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -654,7 +654,7 @@ lpfc_selective_reset(struct lpfc_hba *phba) * Notes: * Assumes any error from lpfc_selective_reset() will be negative. * If lpfc_selective_reset() returns zero then the length of the buffer - * is returned which indicates succcess + * is returned which indicates success * * Returns: * -EINVAL if the buffer does not contain the string "selective" @@ -3147,7 +3147,7 @@ sysfs_ctlreg_write(struct kobject *kobj, struct bin_attribute *bin_attr, * sysfs_ctlreg_read - Read method for reading from ctlreg * @kobj: kernel kobject that contains the kernel class device. * @bin_attr: kernel attributes passed to us. - * @buf: if succesful contains the data from the adapter IOREG space. + * @buf: if successful contains the data from the adapter IOREG space. * @off: offset into buffer to beginning of data. * @count: bytes to transfer. * diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 45337cd23fe..a14ab4580d4 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -802,7 +802,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, /* FLOGI completes successfully */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, - "0101 FLOGI completes sucessfully " + "0101 FLOGI completes successfully " "Data: x%x x%x x%x x%x\n", irsp->un.ulpWord[4], sp->cmn.e_d_tov, sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution); @@ -4133,7 +4133,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, /* Indicate we are walking fc_rscn_id_list on this vport */ vport->fc_rscn_flush = 1; spin_unlock_irq(shost->host_lock); - /* Get the array count after sucessfully have the token */ + /* Get the array count after successfully have the token */ rscn_cnt = vport->fc_rscn_id_cnt; /* If we are already processing an RSCN, save the received * RSCN payload buffer, cmdiocb->context2 to process later. diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 562d8cee874..82f8ab5c72c 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -645,7 +645,7 @@ lpfc_hba_down_prep(struct lpfc_hba *phba) * down the SLI Layer. * * Return codes - * 0 - sucess. + * 0 - success. * Any other value - error. **/ static int @@ -700,7 +700,7 @@ lpfc_hba_down_post_s3(struct lpfc_hba *phba) * down the SLI Layer. * * Return codes - * 0 - sucess. + * 0 - success. * Any other value - error. **/ static int @@ -755,7 +755,7 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba) * uninitialization after the HBA is reset when bring down the SLI Layer. * * Return codes - * 0 - sucess. + * 0 - success. * Any other value - error. **/ int @@ -1254,7 +1254,7 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) * routine from the API jump table function pointer from the lpfc_hba struct. * * Return codes - * 0 - sucess. + * 0 - success. * Any other value - error. **/ void @@ -3124,7 +3124,7 @@ static void lpfc_log_intr_mode(struct lpfc_hba *phba, uint32_t intr_mode) * PCI devices. * * Return codes - * 0 - sucessful + * 0 - successful * other values - error **/ static int @@ -3220,7 +3220,7 @@ lpfc_reset_hba(struct lpfc_hba *phba) * support the SLI-3 HBA device it attached to. * * Return codes - * 0 - sucessful + * 0 - successful * other values - error **/ static int @@ -3321,7 +3321,7 @@ lpfc_sli_driver_resource_unset(struct lpfc_hba *phba) * support the SLI-4 HBA device it attached to. * * Return codes - * 0 - sucessful + * 0 - successful * other values - error **/ static int @@ -3642,7 +3642,7 @@ lpfc_init_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp) * device specific resource setup to support the HBA device it attached to. * * Return codes - * 0 - sucessful + * 0 - successful * other values - error **/ static int @@ -3688,7 +3688,7 @@ lpfc_setup_driver_resource_phase1(struct lpfc_hba *phba) * device specific resource setup to support the HBA device it attached to. * * Return codes - * 0 - sucessful + * 0 - successful * other values - error **/ static int @@ -3753,7 +3753,7 @@ lpfc_free_iocb_list(struct lpfc_hba *phba) * list and set up the IOCB tag array accordingly. * * Return codes - * 0 - sucessful + * 0 - successful * other values - error **/ static int @@ -3872,7 +3872,7 @@ lpfc_free_active_sgl(struct lpfc_hba *phba) * list and set up the sgl xritag tag array accordingly. * * Return codes - * 0 - sucessful + * 0 - successful * other values - error **/ static int @@ -3986,7 +3986,7 @@ out_free_mem: * enabled and the driver is reinitializing the device. * * Return codes - * 0 - sucessful + * 0 - successful * ENOMEM - No availble memory * EIO - The mailbox failed to complete successfully. **/ @@ -4146,7 +4146,7 @@ lpfc_sli4_remove_rpi_hdrs(struct lpfc_hba *phba) * PCI device data structure is set. * * Return codes - * pointer to @phba - sucessful + * pointer to @phba - successful * NULL - error **/ static struct lpfc_hba * @@ -4202,7 +4202,7 @@ lpfc_hba_free(struct lpfc_hba *phba) * host with it. * * Return codes - * 0 - sucessful + * 0 - successful * other values - error **/ static int @@ -4365,7 +4365,7 @@ lpfc_post_init_setup(struct lpfc_hba *phba) * with SLI-3 interface spec. * * Return codes - * 0 - sucessful + * 0 - successful * other values - error **/ static int @@ -4662,7 +4662,7 @@ lpfc_sli4_bar2_register_memmap(struct lpfc_hba *phba, uint32_t vf) * this routine. * * Return codes - * 0 - sucessful + * 0 - successful * ENOMEM - could not allocated memory. **/ static int @@ -4761,7 +4761,7 @@ lpfc_destroy_bootstrap_mbox(struct lpfc_hba *phba) * allocation for the port. * * Return codes - * 0 - sucessful + * 0 - successful * ENOMEM - No availble memory * EIO - The mailbox failed to complete successfully. **/ @@ -4861,7 +4861,7 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) * HBA consistent with the SLI-4 interface spec. * * Return codes - * 0 - sucessful + * 0 - successful * ENOMEM - No availble memory * EIO - The mailbox failed to complete successfully. **/ @@ -4910,7 +4910,7 @@ lpfc_setup_endian_order(struct lpfc_hba *phba) * we just use some constant number as place holder. * * Return codes - * 0 - sucessful + * 0 - successful * ENOMEM - No availble memory * EIO - The mailbox failed to complete successfully. **/ @@ -5218,7 +5218,7 @@ out_error: * operation. * * Return codes - * 0 - sucessful + * 0 - successful * ENOMEM - No availble memory * EIO - The mailbox failed to complete successfully. **/ @@ -5286,7 +5286,7 @@ lpfc_sli4_queue_destroy(struct lpfc_hba *phba) * operation. * * Return codes - * 0 - sucessful + * 0 - successful * ENOMEM - No availble memory * EIO - The mailbox failed to complete successfully. **/ @@ -5552,7 +5552,7 @@ out_error: * operation. * * Return codes - * 0 - sucessful + * 0 - successful * ENOMEM - No availble memory * EIO - The mailbox failed to complete successfully. **/ @@ -5599,7 +5599,7 @@ lpfc_sli4_queue_unset(struct lpfc_hba *phba) * Later, this can be used for all the slow-path events. * * Return codes - * 0 - sucessful + * 0 - successful * -ENOMEM - No availble memory **/ static int @@ -5760,7 +5760,7 @@ lpfc_sli4_cq_event_release_all(struct lpfc_hba *phba) * all resources assigned to the PCI function which originates this request. * * Return codes - * 0 - sucessful + * 0 - successful * ENOMEM - No availble memory * EIO - The mailbox failed to complete successfully. **/ @@ -5923,7 +5923,7 @@ lpfc_sli4_fcfi_unreg(struct lpfc_hba *phba, uint16_t fcfi) * with SLI-4 interface spec. * * Return codes - * 0 - sucessful + * 0 - successful * other values - error **/ static int @@ -6052,7 +6052,7 @@ lpfc_sli4_pci_mem_unset(struct lpfc_hba *phba) * will be left with MSI-X enabled and leaks its vectors. * * Return codes - * 0 - sucessful + * 0 - successful * other values - error **/ static int @@ -6184,7 +6184,7 @@ lpfc_sli_disable_msix(struct lpfc_hba *phba) * is done in this function. * * Return codes - * 0 - sucessful + * 0 - successful * other values - error */ static int @@ -6243,7 +6243,7 @@ lpfc_sli_disable_msi(struct lpfc_hba *phba) * MSI-X -> MSI -> IRQ. * * Return codes - * 0 - sucessful + * 0 - successful * other values - error **/ static uint32_t @@ -6333,7 +6333,7 @@ lpfc_sli_disable_intr(struct lpfc_hba *phba) * enabled and leaks its vectors. * * Return codes - * 0 - sucessful + * 0 - successful * other values - error **/ static int @@ -6443,7 +6443,7 @@ lpfc_sli4_disable_msix(struct lpfc_hba *phba) * which is done in this function. * * Return codes - * 0 - sucessful + * 0 - successful * other values - error **/ static int @@ -6508,7 +6508,7 @@ lpfc_sli4_disable_msi(struct lpfc_hba *phba) * MSI-X -> MSI -> IRQ. * * Return codes - * 0 - sucessful + * 0 - successful * other values - error **/ static uint32_t diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 43cbe336f1f..42d4f3dae1d 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -1794,7 +1794,7 @@ lpfc_sli_handle_mb_event(struct lpfc_hba *phba) */ if (lpfc_sli_chk_mbx_command(pmbox->mbxCommand) == MBX_SHUTDOWN) { - /* Unknow mailbox command compl */ + /* Unknown mailbox command compl */ lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, "(%d):0323 Unknown Mailbox command " "x%x (x%x) Cmpl\n", @@ -4163,7 +4163,7 @@ lpfc_sli4_read_fcoe_params(struct lpfc_hba *phba, * addition, this routine gets the port vpd data. * * Return codes - * 0 - sucessful + * 0 - successful * ENOMEM - could not allocated memory. **/ static int @@ -11091,7 +11091,7 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba) * sequential. * * Return codes - * 0 - sucessful + * 0 - successful * EIO - The mailbox failed to complete successfully. * When this error occurs, the driver is not guaranteed * to have any rpi regions posted to the device and @@ -11129,7 +11129,7 @@ lpfc_sli4_post_all_rpi_hdrs(struct lpfc_hba *phba) * maps up to 64 rpi context regions. * * Return codes - * 0 - sucessful + * 0 - successful * ENOMEM - No available memory * EIO - The mailbox failed to complete successfully. **/ @@ -11191,7 +11191,7 @@ lpfc_sli4_post_rpi_hdr(struct lpfc_hba *phba, struct lpfc_rpi_hdr *rpi_page) * PAGE_SIZE modulo 64 rpi context headers. * * Returns - * A nonzero rpi defined as rpi_base <= rpi < max_rpi if sucessful + * A nonzero rpi defined as rpi_base <= rpi < max_rpi if successful * LPFC_RPI_ALLOC_ERROR if no rpis are available. **/ int diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h index 512c2cc1a33..d310f49d077 100644 --- a/drivers/scsi/megaraid.h +++ b/drivers/scsi/megaraid.h @@ -381,7 +381,7 @@ typedef struct { u8 battery_status; /* * BIT 0: battery module missing * BIT 1: VBAD - * BIT 2: temprature high + * BIT 2: temperature high * BIT 3: battery pack missing * BIT 4,5: * 00 - charge complete diff --git a/drivers/scsi/megaraid/mbox_defs.h b/drivers/scsi/megaraid/mbox_defs.h index b25b74764ec..ce2487a888e 100644 --- a/drivers/scsi/megaraid/mbox_defs.h +++ b/drivers/scsi/megaraid/mbox_defs.h @@ -497,7 +497,7 @@ typedef struct { * @inserted_drive : channel:Id of inserted drive * @battery_status : bit 0: battery module missing * bit 1: VBAD - * bit 2: temprature high + * bit 2: temperature high * bit 3: battery pack missing * bit 4,5: * 00 - charge complete diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index 234f0b7eb21..f9ae8037a71 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -2704,7 +2704,7 @@ megaraid_reset_handler(struct scsi_cmnd *scp) } else { con_log(CL_ANN, (KERN_NOTICE - "megaraid mbox: reset sequence completed sucessfully\n")); + "megaraid mbox: reset sequence completed successfully\n")); } diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 86ab32d7ab1..756e509d495 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -2894,7 +2894,7 @@ _scsih_normalize_sense(char *sense_buffer, struct sense_info *data) #ifdef CONFIG_SCSI_MPT2SAS_LOGGING /** - * _scsih_scsi_ioc_info - translated non-succesfull SCSI_IO request + * _scsih_scsi_ioc_info - translated non-successfull SCSI_IO request * @ioc: per adapter object * @scmd: pointer to scsi command object * @mpi_reply: reply mf payload returned from firmware diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index e3c482aa87b..a2d56982830 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -6495,7 +6495,7 @@ static void ncr_int_ma (struct ncb *np) ** we force a SIR_NEGO_PROTO interrupt (it is a hack that avoids ** bloat for such a should_not_happen situation). ** In all other situation, we reset the BUS. - ** Are these assumptions reasonnable ? (Wait and see ...) + ** Are these assumptions reasonable ? (Wait and see ...) */ unexpected_phase: dsp -= 8; diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index f7c70e2a822..d3d39f86fcf 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -3342,7 +3342,7 @@ static int pmcraid_chr_fasync(int fd, struct file *filep, int mode) * @direction : data transfer direction * * Return value - * 0 on sucess, non-zero error code on failure + * 0 on success, non-zero error code on failure */ static int pmcraid_build_passthrough_ioadls( struct pmcraid_cmd *cmd, @@ -3401,7 +3401,7 @@ static int pmcraid_build_passthrough_ioadls( * @direction: data transfer direction * * Return value - * 0 on sucess, non-zero error code on failure + * 0 on success, non-zero error code on failure */ static void pmcraid_release_passthrough_ioadls( struct pmcraid_cmd *cmd, @@ -3429,7 +3429,7 @@ static void pmcraid_release_passthrough_ioadls( * @arg: pointer to pmcraid_passthrough_buffer user buffer * * Return value - * 0 on sucess, non-zero error code on failure + * 0 on success, non-zero error code on failure */ static long pmcraid_ioctl_passthrough( struct pmcraid_instance *pinstance, diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h index 3441b3f9082..2752b56cad5 100644 --- a/drivers/scsi/pmcraid.h +++ b/drivers/scsi/pmcraid.h @@ -771,11 +771,11 @@ static struct pmcraid_ioasc_error pmcraid_ioasc_error_table[] = { {0x01180600, IOASC_LOG_LEVEL_MUST, "Recovered Error, soft media error, sector reassignment suggested"}, {0x015D0000, IOASC_LOG_LEVEL_MUST, - "Recovered Error, failure prediction thresold exceeded"}, + "Recovered Error, failure prediction threshold exceeded"}, {0x015D9200, IOASC_LOG_LEVEL_MUST, - "Recovered Error, soft Cache Card Battery error thresold"}, + "Recovered Error, soft Cache Card Battery error threshold"}, {0x015D9200, IOASC_LOG_LEVEL_MUST, - "Recovered Error, soft Cache Card Battery error thresold"}, + "Recovered Error, soft Cache Card Battery error threshold"}, {0x02048000, IOASC_LOG_LEVEL_MUST, "Not Ready, IOA Reset Required"}, {0x02408500, IOASC_LOG_LEVEL_MUST, diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c index 723fdecd91b..0fd6ae6911a 100644 --- a/drivers/scsi/scsi_netlink.c +++ b/drivers/scsi/scsi_netlink.c @@ -613,7 +613,7 @@ EXPORT_SYMBOL_GPL(scsi_nl_send_transport_msg); * @data_buf: pointer to vendor unique data buffer * * Returns: - * 0 on succesful return + * 0 on successful return * otherwise, failing error code * * Notes: diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index fd47cb1bee1..f27e52d963d 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -666,7 +666,7 @@ EXPORT_SYMBOL(sas_phy_add); * * Note: * This function must only be called on a PHY that has not - * sucessfully been added using sas_phy_add(). + * successfully been added using sas_phy_add(). */ void sas_phy_free(struct sas_phy *phy) { @@ -896,7 +896,7 @@ EXPORT_SYMBOL(sas_port_add); * * Note: * This function must only be called on a PORT that has not - * sucessfully been added using sas_port_add(). + * successfully been added using sas_port_add(). */ void sas_port_free(struct sas_port *port) { @@ -1476,7 +1476,7 @@ EXPORT_SYMBOL(sas_rphy_add); * * Note: * This function must only be called on a remote - * PHY that has not sucessfully been added using + * PHY that has not successfully been added using * sas_rphy_add() (or has been sas_rphy_remove()'d) */ void sas_rphy_free(struct sas_rphy *rphy) diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 45374d66d26..2b38f6ad6e1 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -1864,7 +1864,7 @@ static pci_ers_result_t sym2_io_slot_dump(struct pci_dev *pdev) * * This routine is similar to sym_set_workarounds(), except * that, at this point, we already know that the device was - * succesfully intialized at least once before, and so most + * successfully intialized at least once before, and so most * of the steps taken there are un-needed here. */ static void sym2_reset_workarounds(struct pci_dev *pdev) diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c index 297deb817a5..a7bc8b7b09a 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c @@ -2692,7 +2692,7 @@ static void sym_int_ma (struct sym_hcb *np) * we force a SIR_NEGO_PROTO interrupt (it is a hack that avoids * bloat for such a should_not_happen situation). * In all other situation, we reset the BUS. - * Are these assumptions reasonnable ? (Wait and see ...) + * Are these assumptions reasonable ? (Wait and see ...) */ unexpected_phase: dsp -= 8; diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h index 053e63c8682..5a80cbac3f9 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.h +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h @@ -54,7 +54,7 @@ * * SYM_OPT_LIMIT_COMMAND_REORDERING * When this option is set, the driver tries to limit tagged - * command reordering to some reasonnable value. + * command reordering to some reasonable value. * (set for Linux) */ #if 0 diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c index d71dfe39894..36ede02ceac 100644 --- a/drivers/serial/8250_pnp.c +++ b/drivers/serial/8250_pnp.c @@ -361,9 +361,9 @@ static const struct pnp_device_id pnp_dev_table[] = { { "LTS0001", 0 }, /* Rockwell's (PORALiNK) 33600 INT PNP */ { "WCI0003", 0 }, - /* Unkown PnP modems */ + /* Unknown PnP modems */ { "PNPCXXX", UNKNOWN_DEV }, - /* More unkown PnP modems */ + /* More unknown PnP modems */ { "PNPDXXX", UNKNOWN_DEV }, { "", 0 } }; diff --git a/drivers/serial/pmac_zilog.h b/drivers/serial/pmac_zilog.h index 570b0d925e8..f6e77f12acd 100644 --- a/drivers/serial/pmac_zilog.h +++ b/drivers/serial/pmac_zilog.h @@ -73,7 +73,7 @@ static inline struct uart_pmac_port *pmz_get_port_A(struct uart_pmac_port *uap) } /* - * Register acessors. Note that we don't need to enforce a recovery + * Register accessors. Note that we don't need to enforce a recovery * delay on PCI PowerMac hardware, it's dealt in HW by the MacIO chip, * though if we try to use this driver on older machines, we might have * to add it back diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c index 0c08f286a2e..46de564aaea 100644 --- a/drivers/serial/ucc_uart.c +++ b/drivers/serial/ucc_uart.c @@ -313,7 +313,7 @@ static void qe_uart_stop_tx(struct uart_port *port) * This function will attempt to stuff of all the characters from the * kernel's transmit buffer into TX BDs. * - * A return value of non-zero indicates that it sucessfully stuffed all + * A return value of non-zero indicates that it successfully stuffed all * characters from the kernel buffer. * * A return value of zero indicates that there are still characters in the diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c index 40de151f278..e89304c7256 100644 --- a/drivers/telephony/ixj.c +++ b/drivers/telephony/ixj.c @@ -4190,7 +4190,7 @@ static void ixj_aec_start(IXJ *j, int level) ixj_WriteDSPCommand(0x1224, j); ixj_WriteDSPCommand(0xE014, j); - ixj_WriteDSPCommand(0x0003, j); /* Lock threashold at 3dB */ + ixj_WriteDSPCommand(0x0003, j); /* Lock threshold at 3dB */ ixj_WriteDSPCommand(0xE338, j); /* Set Echo Suppresser Attenuation to 0dB */ @@ -4235,7 +4235,7 @@ static void ixj_aec_start(IXJ *j, int level) ixj_WriteDSPCommand(0x1224, j); ixj_WriteDSPCommand(0xE014, j); - ixj_WriteDSPCommand(0x0003, j); /* Lock threashold at 3dB */ + ixj_WriteDSPCommand(0x0003, j); /* Lock threshold at 3dB */ ixj_WriteDSPCommand(0xE338, j); /* Set Echo Suppresser Attenuation to 0dB */ diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index d171b563e94..bba4d3eabe0 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -1958,7 +1958,7 @@ static void uea_dispatch_cmv_e1(struct uea_softc *sc, struct intr_pkt *intr) goto bad1; /* FIXME : ADI930 reply wrong preambule (func = 2, sub = 2) to - * the first MEMACESS cmv. Ignore it... + * the first MEMACCESS cmv. Ignore it... */ if (cmv->bFunction != dsc->function) { if (UEA_CHIP_VERSION(sc) == ADI930 diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 2473cf0c6b1..b4bd2411c66 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -1,5 +1,5 @@ /** - * drivers/usb/class/usbtmc.c - USB Test & Measurment class driver + * drivers/usb/class/usbtmc.c - USB Test & Measurement class driver * * Copyright (C) 2007 Stefan Kopp, Gechingen, Germany * Copyright (C) 2008 Novell, Inc. diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index da718e84d58..e80f1af438c 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1890,7 +1890,7 @@ static void cancel_async_set_config(struct usb_device *udev) * routine gets around the normal restrictions by using a work thread to * submit the change-config request. * - * Returns 0 if the request was succesfully queued, error code otherwise. + * Returns 0 if the request was successfully queued, error code otherwise. * The caller has no way to know whether the queued request will eventually * succeed. */ diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index 7953948bfe4..4e3657808b0 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -432,7 +432,7 @@ static void acm_disable(struct usb_function *f) * @length: size of data * Context: irqs blocked, acm->lock held, acm_notify_req non-null * - * Returns zero on sucess or a negative errno. + * Returns zero on success or a negative errno. * * See section 6.3.5 of the CDC 1.1 specification for information * about the only notification we issue: SerialState change. diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 1937d8c7b43..adda1208a1e 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -1524,7 +1524,7 @@ static int pxa_udc_get_frame(struct usb_gadget *_gadget) * pxa_udc_wakeup - Force udc device out of suspend * @_gadget: usb gadget * - * Returns 0 if succesfull, error code otherwise + * Returns 0 if successfull, error code otherwise */ static int pxa_udc_wakeup(struct usb_gadget *_gadget) { diff --git a/drivers/usb/host/fhci-sched.c b/drivers/usb/host/fhci-sched.c index 62a226b6167..00a29855d0c 100644 --- a/drivers/usb/host/fhci-sched.c +++ b/drivers/usb/host/fhci-sched.c @@ -627,7 +627,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd) /* - * Process normal completions(error or sucess) and clean the schedule. + * Process normal completions(error or success) and clean the schedule. * * This is the main path for handing urbs back to drivers. The only other patth * is process_del_list(),which unlinks URBs by scanning EDs,instead of scanning diff --git a/drivers/usb/wusbcore/crypto.c b/drivers/usb/wusbcore/crypto.c index 9ec7fd5da48..9579cf4c38b 100644 --- a/drivers/usb/wusbcore/crypto.c +++ b/drivers/usb/wusbcore/crypto.c @@ -111,7 +111,7 @@ struct aes_ccm_b1 { * * CCM uses Ax blocks to generate a keystream with which the MIC and * the message's payload are encoded. A0 always encrypts/decrypts the - * MIC. Ax (x>0) are used for the sucesive payload blocks. + * MIC. Ax (x>0) are used for the successive payload blocks. * * The x is the counter, and is increased for each block. */ diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c index 613a5fc490d..489b47833e2 100644 --- a/drivers/usb/wusbcore/wa-xfer.c +++ b/drivers/usb/wusbcore/wa-xfer.c @@ -558,7 +558,7 @@ static void wa_seg_dto_cb(struct urb *urb) /* * Callback for the segment request * - * If succesful transition state (unless already transitioned or + * If successful transition state (unless already transitioned or * outbound transfer); otherwise, take a note of the error, mark this * segment done and try completion. * @@ -1364,7 +1364,7 @@ segment_aborted: /* * Callback for the IN data phase * - * If succesful transition state; otherwise, take a note of the + * If successful transition state; otherwise, take a note of the * error, mark this segment done and try completion. * * Note we don't access until we are sure that the transfer hasn't diff --git a/drivers/uwb/i1480/dfu/usb.c b/drivers/uwb/i1480/dfu/usb.c index c7080d49731..0bb665a0c02 100644 --- a/drivers/uwb/i1480/dfu/usb.c +++ b/drivers/uwb/i1480/dfu/usb.c @@ -229,7 +229,7 @@ void i1480_usb_neep_cb(struct urb *urb) * will verify it. * * Set i1480->evt_result with the result of getting the event or its - * size (if succesful). + * size (if successful). * * Delivers the data directly to i1480->evt_buf */ diff --git a/drivers/uwb/wlp/txrx.c b/drivers/uwb/wlp/txrx.c index 86a853b8411..7350ed6909f 100644 --- a/drivers/uwb/wlp/txrx.c +++ b/drivers/uwb/wlp/txrx.c @@ -282,7 +282,7 @@ EXPORT_SYMBOL_GPL(wlp_receive_frame); * and transmission will be done by the calling function. * @dst: On return this will contain the device address to which the * frame is destined. - * @returns: 0 on success no tx : WLP header sucessfully applied to skb buffer, + * @returns: 0 on success no tx : WLP header successfully applied to skb buffer, * calling function can proceed with tx * 1 on success with tx : WLP will take over transmission of this * frame diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 913b4a47ae5..1ddeb4c3476 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -3276,7 +3276,7 @@ static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base) txtformat = "24 bit interface"; break; default: - txtformat = "unkown format"; + txtformat = "unknown format"; } } else { switch (format & 7) { @@ -3299,7 +3299,7 @@ static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base) txtformat = "262144 colours (FDPI-2 mode)"; break; default: - txtformat = "unkown format"; + txtformat = "unknown format"; } } PRINTKI("%s%s %s monitor detected: %s\n", diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c index 505c0823a10..2cf7ba52f67 100644 --- a/drivers/video/backlight/atmel-pwm-bl.c +++ b/drivers/video/backlight/atmel-pwm-bl.c @@ -158,7 +158,7 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev) goto err_free_pwm; } - /* Turn display off by defatult. */ + /* Turn display off by default. */ retval = gpio_direction_output(pwmbl->gpio_on, 0 ^ pdata->on_active_low); if (retval) diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c index 50ec17dfc51..fa32b94a454 100644 --- a/drivers/video/backlight/tosa_lcd.c +++ b/drivers/video/backlight/tosa_lcd.c @@ -177,7 +177,7 @@ static int __devinit tosa_lcd_probe(struct spi_device *spi) if (!data) return -ENOMEM; - data->is_vga = true; /* defaut to VGA mode */ + data->is_vga = true; /* default to VGA mode */ /* * bits_per_word cannot be configured in platform data diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index 857b3668b3b..6468a297e34 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -436,7 +436,7 @@ sti_init_glob_cfg(struct sti_struct *sti, (offs < PCI_BASE_ADDRESS_0 || offs > PCI_BASE_ADDRESS_5)) { printk (KERN_WARNING - "STI pci region maping for region %d (%02x) can't be mapped\n", + "STI pci region mapping for region %d (%02x) can't be mapped\n", i,sti->rm_entry[i]); continue; } diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c index 1a83709f961..492e6e64b65 100644 --- a/drivers/video/gbefb.c +++ b/drivers/video/gbefb.c @@ -701,7 +701,7 @@ static int gbefb_set_par(struct fb_info *info) blocks of 512x128, 256x128 or 128x128 pixels, respectively for 8bit, 16bit and 32 bit modes (64 kB). They cover the screen with partial tiles on the right and/or bottom of the screen if needed. - For exemple in 640x480 8 bit mode the mapping is: + For example in 640x480 8 bit mode the mapping is: <-------- 640 -----> <---- 512 ----><128|384 offscreen> diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index 6120f0c526f..876648e15e9 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c @@ -756,9 +756,9 @@ hyperResetPlanes(struct stifb_info *fb, int enable) if (fb->info.var.bits_per_pixel == 32) controlPlaneReg = 0x04000F00; else - controlPlaneReg = 0x00000F00; /* 0x00000800 should be enought, but lets clear all 4 bits */ + controlPlaneReg = 0x00000F00; /* 0x00000800 should be enough, but lets clear all 4 bits */ else - controlPlaneReg = 0x00000F00; /* 0x00000100 should be enought, but lets clear all 4 bits */ + controlPlaneReg = 0x00000F00; /* 0x00000100 should be enough, but lets clear all 4 bits */ switch (enable) { case ENABLE: diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c index ff43c888502..98054839004 100644 --- a/drivers/video/tdfxfb.c +++ b/drivers/video/tdfxfb.c @@ -52,7 +52,7 @@ * * 0.1.3 (released 1999-11-02) added Attila's panning support, code * reorg, hwcursor address page size alignment - * (for mmaping both frame buffer and regs), + * (for mmapping both frame buffer and regs), * and my changes to get rid of hardcoded * VGA i/o register locations (uses PCI * configuration info now) diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index c5c32b6b6e6..67b36932212 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c @@ -467,7 +467,7 @@ static int dvi_get_panel_size_from_DDCv1(void) default: viaparinfo->tmds_setting_info->dvi_panel_size = VIA_RES_1024X768; - DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d !\ + DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d !\ set default panel size.\n", max_h); break; } @@ -534,7 +534,7 @@ static int dvi_get_panel_size_from_DDCv2(void) default: viaparinfo->tmds_setting_info->dvi_panel_size = VIA_RES_1024X768; - DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d!\ + DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d!\ set default panel size.\n", HSize); break; } diff --git a/drivers/video/vt8623fb.c b/drivers/video/vt8623fb.c index 3df17dc8c3d..65ccd215d49 100644 --- a/drivers/video/vt8623fb.c +++ b/drivers/video/vt8623fb.c @@ -446,7 +446,7 @@ static int vt8623fb_set_par(struct fb_info *info) svga_wseq_mask(0x1E, 0xF0, 0xF0); // DI/DVP bus svga_wseq_mask(0x2A, 0x0F, 0x0F); // DI/DVP bus - svga_wseq_mask(0x16, 0x08, 0xBF); // FIFO read treshold + svga_wseq_mask(0x16, 0x08, 0xBF); // FIFO read threshold vga_wseq(NULL, 0x17, 0x1F); // FIFO depth vga_wseq(NULL, 0x18, 0x4E); svga_wseq_mask(0x1A, 0x08, 0x08); // enable MMIO ? diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c index 381026c0bd7..923cc68dba2 100644 --- a/drivers/watchdog/coh901327_wdt.c +++ b/drivers/watchdog/coh901327_wdt.c @@ -508,7 +508,7 @@ void coh901327_watchdog_reset(void) * deactivating the watchdog before it is shut down by it. * * NOTE: on future versions of the watchdog, this restriction is - * gone: the watchdog will be reloaded with a defaul value (1 min) + * gone: the watchdog will be reloaded with a default value (1 min) * instead of last value, and you can conveniently set the watchdog * timeout to 10ms (value = 1) without any problems. */ diff --git a/drivers/watchdog/machzwd.c b/drivers/watchdog/machzwd.c index b6b3f59ab44..47d719717a3 100644 --- a/drivers/watchdog/machzwd.c +++ b/drivers/watchdog/machzwd.c @@ -21,7 +21,7 @@ * wd#1 - 2 seconds; * wd#2 - 7.2 ms; * After the expiration of wd#1, it can generate a NMI, SCI, SMI, or - * a system RESET and it starts wd#2 that unconditionaly will RESET + * a system RESET and it starts wd#2 that unconditionally will RESET * the system when the counter reaches zero. * * 14-Dec-2001 Matt Domsch diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c index 3bde56bce63..5bfb1f2c531 100644 --- a/drivers/watchdog/wdrtas.c +++ b/drivers/watchdog/wdrtas.c @@ -542,7 +542,7 @@ static struct notifier_block wdrtas_notifier = { /** * wdrtas_get_tokens - reads in RTAS tokens * - * returns 0 on succes, <0 on failure + * returns 0 on success, <0 on failure * * wdrtas_get_tokens reads in the tokens for the RTAS calls used in * this watchdog driver. It tolerates, if "get-sensor-state" and @@ -598,7 +598,7 @@ static void wdrtas_unregister_devs(void) /** * wdrtas_register_devs - registers the misc dev handlers * - * returns 0 on succes, <0 on failure + * returns 0 on success, <0 on failure * * wdrtas_register_devs registers the watchdog and temperature watchdog * misc devs @@ -630,7 +630,7 @@ static int wdrtas_register_devs(void) /** * wdrtas_init - init function of the watchdog driver * - * returns 0 on succes, <0 on failure + * returns 0 on success, <0 on failure * * registers the file handlers and the reboot notifier */ diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index b9b3bb51b1e..d15ea1790bf 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -767,7 +767,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) current->mm->start_stack = bprm->p; - /* Now we do a little grungy work by mmaping the ELF image into + /* Now we do a little grungy work by mmapping the ELF image into the correct location in memory. */ for(i = 0, elf_ppnt = elf_phdata; i < loc->elf_ex.e_phnum; i++, elf_ppnt++) { diff --git a/fs/bio.c b/fs/bio.c index 12da5db8682..2bd671a08e3 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -272,7 +272,7 @@ EXPORT_SYMBOL(bio_init); * for a &struct bio to become free. If a %NULL @bs is passed in, we will * fall back to just using @kmalloc to allocate the required memory. * - * Note that the caller must set ->bi_destructor on succesful return + * Note that the caller must set ->bi_destructor on successful return * of a bio, to do the appropriate freeing of the bio once the reference * count drops to zero. **/ diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 2c726b7b9fa..6815d2a84b9 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -256,7 +256,7 @@ out: * Insert @em into @tree or perform a simple forward/backward merge with * existing mappings. The extent_map struct passed in will be inserted * into the tree directly, with an additional reference taken, or a - * reference dropped if the merge attempt was sucessfull. + * reference dropped if the merge attempt was successfull. */ int add_extent_mapping(struct extent_map_tree *tree, struct extent_map *em) diff --git a/fs/cifs/README b/fs/cifs/README index 79c1a93400b..a727b7cb075 100644 --- a/fs/cifs/README +++ b/fs/cifs/README @@ -423,7 +423,7 @@ A partial list of the supported mount options follows: source name to use to represent the client netbios machine name when doing the RFC1001 netbios session initialize. direct Do not do inode data caching on files opened on this mount. - This precludes mmaping files on this mount. In some cases + This precludes mmapping files on this mount. In some cases with fast networks and little or no caching benefits on the client (e.g. when the application is doing large sequential reads bigger than page size without rereading the same data) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 5d0fde18039..4b35f7ec058 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -39,7 +39,7 @@ /* * MAX_REQ is the maximum number of requests that WE will send - * on one socket concurently. It also matches the most common + * on one socket concurrently. It also matches the most common * value of max multiplex returned by servers. We may * eventually want to use the negotiated value (in case * future servers can handle more) when we are more confident that diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 5e2492535da..83580213fca 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -917,8 +917,8 @@ undo_setattr: /* * If dentry->d_inode is null (usually meaning the cached dentry * is a negative dentry) then we would attempt a standard SMB delete, but - * if that fails we can not attempt the fall back mechanisms on EACESS - * but will return the EACESS to the caller. Note that the VFS does not call + * if that fails we can not attempt the fall back mechanisms on EACCESS + * but will return the EACCESS to the caller. Note that the VFS does not call * unlink on negative dentries currently. */ int cifs_unlink(struct inode *dir, struct dentry *dentry) diff --git a/fs/cifs/smbdes.c b/fs/cifs/smbdes.c index 224a1f47896..b6b6dcb500b 100644 --- a/fs/cifs/smbdes.c +++ b/fs/cifs/smbdes.c @@ -371,7 +371,7 @@ E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24) smbhash(p24 + 16, c8, p21 + 14, 1); } -#if 0 /* currently unsued */ +#if 0 /* currently unused */ static void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out) { diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c index 16f682e26c0..b540aa5d1f6 100644 --- a/fs/dlm/plock.c +++ b/fs/dlm/plock.c @@ -143,7 +143,7 @@ out: } EXPORT_SYMBOL_GPL(dlm_posix_lock); -/* Returns failure iff a succesful lock operation should be canceled */ +/* Returns failure iff a successful lock operation should be canceled */ static int dlm_plock_callback(struct plock_op *op) { struct file *file; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 618ca95cbb5..0282ec78cf8 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2932,7 +2932,7 @@ retry: ret = write_cache_pages(mapping, wbc, __mpage_da_writepage, &mpd); /* - * If we have a contigous extent of pages and we + * If we have a contiguous extent of pages and we * haven't done the I/O yet, map the blocks and submit * them for I/O. */ @@ -5370,7 +5370,7 @@ static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk) * worse case, the indexs blocks spread over different block groups * * If datablocks are discontiguous, they are possible to spread over - * different block groups too. If they are contiugous, with flexbg, + * different block groups too. If they are contiuguous, with flexbg, * they could still across block group boundary. * * Also account for superblock, inode, quota and xattr blocks @@ -5446,7 +5446,7 @@ int ext4_writepage_trans_blocks(struct inode *inode) * Calculate the journal credits for a chunk of data modification. * * This is called from DIO, fallocate or whoever calling - * ext4_get_blocks() to map/allocate a chunk of contigous disk blocks. + * ext4_get_blocks() to map/allocate a chunk of contiguous disk blocks. * * journal buffers for data blocks are not included here, as DIO * and fallocate do no need to journal data buffers. diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index bba12824def..74e495dabe0 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -142,7 +142,7 @@ * 2 blocks and the order of allocation is >= sbi->s_mb_order2_reqs. The * value of s_mb_order2_reqs can be tuned via * /sys/fs/ext4//mb_order2_req. If the request len is equal to - * stripe size (sbi->s_stripe), we try to search for contigous block in + * stripe size (sbi->s_stripe), we try to search for contiguous block in * stripe size. This should result in better allocation on RAID setups. If * not, we search in the specific group using bitmap for best extents. The * tunable min_to_scan and max_to_scan control the behaviour here. diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c index f25e70c1b51..f0294410868 100644 --- a/fs/jffs2/compr.c +++ b/fs/jffs2/compr.c @@ -177,7 +177,7 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, spin_unlock(&jffs2_compressor_list_lock); break; default: - printk(KERN_ERR "JFFS2: unknow compression mode.\n"); + printk(KERN_ERR "JFFS2: unknown compression mode.\n"); } out: if (ret == JFFS2_COMPR_NONE) { diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 1a80301004b..378991cfe40 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c @@ -931,7 +931,7 @@ static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_re * Helper function for jffs2_get_inode_nodes(). * The function detects whether more data should be read and reads it if yes. * - * Returns: 0 on succes; + * Returns: 0 on success; * negative error code on failure. */ static int read_more(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index 082e844ab2d..4b107881acd 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c @@ -31,7 +31,7 @@ * is used to release xattr name/value pair and detach from c->xattrindex. * reclaim_xattr_datum(c) * is used to reclaim xattr name/value pairs on the xattr name/value pair cache when - * memory usage by cache is over c->xdatum_mem_threshold. Currentry, this threshold + * memory usage by cache is over c->xdatum_mem_threshold. Currently, this threshold * is hard coded as 32KiB. * do_verify_xattr_datum(c, xd) * is used to load the xdatum informations without name/value pair from the medium. diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index 2bc7d8aa574..d9b031cf69f 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -755,7 +755,7 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results) * allocation group. */ if ((blkno & (bmp->db_agsize - 1)) == 0) - /* check if the AG is currenly being written to. + /* check if the AG is currently being written to. * if so, call dbNextAG() to find a non-busy * AG with sufficient free space. */ @@ -3337,7 +3337,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks) for (i = 0, n = 0; i < agno; n++) { bmp->db_agfree[n] = 0; /* init collection point */ - /* coalesce cotiguous k AGs; */ + /* coalesce contiguous k AGs; */ for (j = 0; j < k && i < agno; j++, i++) { /* merge AGi to AGn */ bmp->db_agfree[n] += bmp->db_agfree[i]; diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c index 0d58caf4a6e..ec8f45f12e0 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c @@ -835,7 +835,7 @@ static int ncp_ioctl_need_write(unsigned int cmd) case NCP_IOC_SETROOT: return 0; default: - /* unkown IOCTL command, assume write */ + /* unknown IOCTL command, assume write */ return 1; } } diff --git a/fs/ntfs/compress.c b/fs/ntfs/compress.c index 9669541d011..08f7530e934 100644 --- a/fs/ntfs/compress.c +++ b/fs/ntfs/compress.c @@ -927,7 +927,7 @@ lock_retry_remap: return 0; ntfs_debug("Failed. Returning error code %s.", err == -EOVERFLOW ? - "EOVERFLOW" : (!err ? "EIO" : "unkown error")); + "EOVERFLOW" : (!err ? "EIO" : "unknown error")); return err < 0 ? err : -EIO; read_err: diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 663c0e341f8..43179ddd336 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -399,7 +399,7 @@ static inline void ntfs_fault_in_pages_readable_iovec(const struct iovec *iov, * @cached_page: allocated but as yet unused page * @lru_pvec: lru-buffering pagevec of caller * - * Obtain @nr_pages locked page cache pages from the mapping @maping and + * Obtain @nr_pages locked page cache pages from the mapping @mapping and * starting at index @index. * * If a page is newly created, increment its refcount and add it to the @@ -1281,7 +1281,7 @@ rl_not_mapped_enoent: /* * Copy as much as we can into the pages and return the number of bytes which - * were sucessfully copied. If a fault is encountered then clear the pages + * were successfully copied. If a fault is encountered then clear the pages * out to (ofs + bytes) and return the number of bytes which were copied. */ static inline size_t ntfs_copy_from_user(struct page **pages, diff --git a/fs/ntfs/logfile.c b/fs/ntfs/logfile.c index 89b02985c05..4dadcdf3d45 100644 --- a/fs/ntfs/logfile.c +++ b/fs/ntfs/logfile.c @@ -338,7 +338,7 @@ err_out: * copy of the complete multi sector transfer deprotected page. On failure, * *@wrp is undefined. * - * Simillarly, if @lsn is not NULL, on succes *@lsn will be set to the current + * Simillarly, if @lsn is not NULL, on success *@lsn will be set to the current * logfile lsn according to this restart page. On failure, *@lsn is undefined. * * The following error codes are defined: diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 38a42f5d59f..7c7198a5bc9 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c @@ -2398,7 +2398,7 @@ static int ocfs2_leftmost_rec_contains(struct ocfs2_extent_list *el, u32 cpos) * * The array is assumed to be large enough to hold an entire path (tree depth). * - * Upon succesful return from this function: + * Upon successful return from this function: * * - The 'right_path' array will contain a path to the leaf block * whose range contains e_cpos. diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 83bcaf266b3..03ccf9a7b1f 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -2586,7 +2586,7 @@ fail: * is complete everywhere. if the target dies while this is * going on, some nodes could potentially see the target as the * master, so it is important that my recovery finds the migration - * mle and sets the master to UNKNONWN. */ + * mle and sets the master to UNKNOWN. */ /* wait for new node to assert master */ diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 0d38d67194c..c5e4a49e3a1 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c @@ -1855,7 +1855,7 @@ int ocfs2_file_lock(struct file *file, int ex, int trylock) * outstanding lock request, so a cancel convert is * required. We intentionally overwrite 'ret' - if the * cancel fails and the lock was granted, it's easier - * to just bubble sucess back up to the user. + * to just bubble success back up to the user. */ ret = ocfs2_flock_handle_signal(lockres, level); } else if (!ret && (level > lockres->l_level)) { diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 54c16b66327..bf34c491ae9 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c @@ -659,7 +659,7 @@ static int __ocfs2_journal_access(handle_t *handle, default: status = -EINVAL; - mlog(ML_ERROR, "Uknown access type!\n"); + mlog(ML_ERROR, "Unknown access type!\n"); } if (!status && ocfs2_meta_ecc(osb) && triggers) jbd2_journal_set_triggers(bh, &triggers->ot_triggers); diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 60287fc56bc..d00c658ca15 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c @@ -2431,7 +2431,7 @@ out: * we gonna touch and whether we need to create new blocks. * * Normally the refcount blocks store these refcount should be - * continguous also, so that we can get the number easily. + * contiguous also, so that we can get the number easily. * As for meta_ac, we will at most add split 2 refcount record and * 2 more refcount block, so just check it in a rough way. * diff --git a/fs/omfs/bitmap.c b/fs/omfs/bitmap.c index e1c0ec0ae98..082234581d0 100644 --- a/fs/omfs/bitmap.c +++ b/fs/omfs/bitmap.c @@ -85,7 +85,7 @@ out: } /* - * Tries to allocate exactly one block. Returns true if sucessful. + * Tries to allocate exactly one block. Returns true if successful. */ int omfs_allocate_block(struct super_block *sb, u64 block) { diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index f94ddf7efba..868a55ee080 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c @@ -23,7 +23,7 @@ /* * This file implements functions needed to recover from unclean un-mounts. * When UBIFS is mounted, it checks a flag on the master node to determine if - * an un-mount was completed sucessfully. If not, the process of mounting + * an un-mount was completed successfully. If not, the process of mounting * incorparates additional checking and fixing of on-flash data structures. * UBIFS always cleans away all remnants of an unclean un-mount, so that * errors do not accumulate. However UBIFS defers recovery if it is mounted diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h index 6533ead9b88..a2c16bcee90 100644 --- a/fs/xfs/quota/xfs_dquot.h +++ b/fs/xfs/quota/xfs_dquot.h @@ -98,7 +98,7 @@ typedef struct xfs_dquot { #define dq_flags q_lists.dqm_flags /* - * Lock hierachy for q_qlock: + * Lock hierarchy for q_qlock: * XFS_QLOCK_NORMAL is the implicit default, * XFS_QLOCK_NESTED is the dquot with the higher id in xfs_dqlock2 */ diff --git a/include/asm-generic/memory_model.h b/include/asm-generic/memory_model.h index 4c8d0afae71..fb2d63f13f4 100644 --- a/include/asm-generic/memory_model.h +++ b/include/asm-generic/memory_model.h @@ -47,7 +47,7 @@ #elif defined(CONFIG_SPARSEMEM_VMEMMAP) -/* memmap is virtually contigious. */ +/* memmap is virtually contiguous. */ #define __pfn_to_page(pfn) (vmemmap + (pfn)) #define __page_to_pfn(page) (unsigned long)((page) - vmemmap) diff --git a/include/asm-generic/unistd.h b/include/asm-generic/unistd.h index d76b66acea9..7c38c147e5e 100644 --- a/include/asm-generic/unistd.h +++ b/include/asm-generic/unistd.h @@ -631,7 +631,7 @@ __SYSCALL(__NR_perf_event_open, sys_perf_event_open) * these are provided for both review and as a porting * help for the C library version. * - * Last chance: are any of these important enought to + * Last chance: are any of these important enough to * enable by default? */ #ifdef __ARCH_WANT_SYSCALL_NO_AT diff --git a/include/linux/chio.h b/include/linux/chio.h index 519248d8b2b..d9bac7f9728 100644 --- a/include/linux/chio.h +++ b/include/linux/chio.h @@ -21,7 +21,7 @@ * query vendor-specific element types * * accessing elements works by specifing type and unit of the element. - * for eample, storage elements are addressed with type = CHET_ST and + * for example, storage elements are addressed with type = CHET_ST and * unit = 0 .. cp_nslots-1 * */ diff --git a/include/linux/mfd/ezx-pcap.h b/include/linux/mfd/ezx-pcap.h index e5124ceea76..3402042ddc3 100644 --- a/include/linux/mfd/ezx-pcap.h +++ b/include/linux/mfd/ezx-pcap.h @@ -45,7 +45,7 @@ void pcap_set_ts_bits(struct pcap_chip *, u32); #define PCAP_CLEAR_INTERRUPT_REGISTER 0x01ffffff #define PCAP_MASK_ALL_INTERRUPT 0x01ffffff -/* registers acessible by both pcap ports */ +/* registers accessible by both pcap ports */ #define PCAP_REG_ISR 0x0 /* Interrupt Status */ #define PCAP_REG_MSR 0x1 /* Interrupt Mask */ #define PCAP_REG_PSTAT 0x2 /* Processor Status */ @@ -67,7 +67,7 @@ void pcap_set_ts_bits(struct pcap_chip *, u32); #define PCAP_REG_VENDOR_TEST1 0x1e #define PCAP_REG_VENDOR_TEST2 0x1f -/* registers acessible by pcap port 1 only (a1200, e2 & e6) */ +/* registers accessible by pcap port 1 only (a1200, e2 & e6) */ #define PCAP_REG_INT_SEL 0x3 /* Interrupt Select */ #define PCAP_REG_SWCTRL 0x4 /* Switching Regulator Control */ #define PCAP_REG_VREG1 0x5 /* Regulator Bank 1 Control */ diff --git a/include/linux/pktcdvd.h b/include/linux/pktcdvd.h index d745f5b6c7b..76e5053e1fa 100644 --- a/include/linux/pktcdvd.h +++ b/include/linux/pktcdvd.h @@ -30,7 +30,7 @@ /* * use drive write caching -- we need deferred error handling to be - * able to sucessfully recover with this option (drive will return good + * able to successfully recover with this option (drive will return good * status as soon as the cdb is validated). */ #if defined(CONFIG_CDROM_PKTCDVD_WCACHE) diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h index 850db2e8051..cf9327c051a 100644 --- a/include/linux/serial_reg.h +++ b/include/linux/serial_reg.h @@ -216,10 +216,10 @@ #define UART_IIR_TOD 0x08 /* Character Timeout Indication Detected */ -#define UART_FCR_PXAR1 0x00 /* receive FIFO treshold = 1 */ -#define UART_FCR_PXAR8 0x40 /* receive FIFO treshold = 8 */ -#define UART_FCR_PXAR16 0x80 /* receive FIFO treshold = 16 */ -#define UART_FCR_PXAR32 0xc0 /* receive FIFO treshold = 32 */ +#define UART_FCR_PXAR1 0x00 /* receive FIFO threshold = 1 */ +#define UART_FCR_PXAR8 0x40 /* receive FIFO threshold = 8 */ +#define UART_FCR_PXAR16 0x80 /* receive FIFO threshold = 16 */ +#define UART_FCR_PXAR32 0xc0 /* receive FIFO threshold = 32 */ diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index b59e78c5716..dfd4745a955 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -490,7 +490,7 @@ struct v4l2_jpegcompression { * you do, leave them untouched. * Inluding less markers will make the * resulting code smaller, but there will - * be fewer aplications which can read it. + * be fewer applications which can read it. * The presence of the APP and COM marker * is influenced by APP_len and COM_len * ONLY, not by this property! */ diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 6e5f0e0c796..ca4789e4f1e 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -988,7 +988,7 @@ struct sctp_transport { int init_sent_count; /* state : The current state of this destination, - * : i.e. SCTP_ACTIVE, SCTP_INACTIVE, SCTP_UNKOWN. + * : i.e. SCTP_ACTIVE, SCTP_INACTIVE, SCTP_UNKNOWN. */ int state; diff --git a/include/net/tcp.h b/include/net/tcp.h index 03a49c70337..1827e7f217d 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1260,7 +1260,7 @@ static inline struct sk_buff *tcp_write_queue_prev(struct sock *sk, struct sk_bu skb_queue_walk_from_safe(&(sk)->sk_write_queue, skb, tmp) /* This function calculates a "timeout" which is equivalent to the timeout of a - * TCP connection after "boundary" unsucessful, exponentially backed-off + * TCP connection after "boundary" unsuccessful, exponentially backed-off * retransmissions with an initial RTO of TCP_RTO_MIN. */ static inline bool retransmits_timed_out(const struct sock *sk, diff --git a/include/net/wimax.h b/include/net/wimax.h index 2af7bf839f2..3b07f6aad10 100644 --- a/include/net/wimax.h +++ b/include/net/wimax.h @@ -79,7 +79,7 @@ * drivers have to only report state changes due to external * conditions. * - * All API operations are 'atomic', serialized thorough a mutex in the + * All API operations are 'atomic', serialized through a mutex in the * `struct wimax_dev`. * * EXPORTING TO USER SPACE THROUGH GENERIC NETLINK diff --git a/include/sound/wm8993.h b/include/sound/wm8993.h index 9c661f2f8cd..eee19f63c0d 100644 --- a/include/sound/wm8993.h +++ b/include/sound/wm8993.h @@ -36,7 +36,7 @@ struct wm8993_platform_data { unsigned int micbias1_lvl:1; unsigned int micbias2_lvl:1; - /* Jack detect threashold levels, see datasheet for values */ + /* Jack detect threshold levels, see datasheet for values */ unsigned int jd_scthr:2; unsigned int jd_thr:2; }; diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 7f29643c898..759a629cc4b 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -419,7 +419,7 @@ static void perf_event_remove_from_context(struct perf_event *event) if (!task) { /* * Per cpu events are removed via an smp call and - * the removal is always sucessful. + * the removal is always successful. */ smp_call_function_single(event->cpu, __perf_event_remove_from_context, @@ -827,7 +827,7 @@ perf_install_in_context(struct perf_event_context *ctx, if (!task) { /* * Per cpu events are installed via an smp call and - * the install is always sucessful. + * the install is always successful. */ smp_call_function_single(cpu, __perf_install_in_context, event, 1); diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 234ceb10861..456b2bc6b1f 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -105,7 +105,7 @@ config DEBUG_SECTION_MISMATCH bool "Enable full Section mismatch analysis" depends on UNDEFINED # This option is on purpose disabled for now. - # It will be enabled when we are down to a resonable number + # It will be enabled when we are down to a reasonable number # of section mismatch warnings (< 10 for an allyesconfig build) help The section mismatch analysis checks if there are illegal diff --git a/lib/decompress_bunzip2.c b/lib/decompress_bunzip2.c index 600f473a561..76074209f9a 100644 --- a/lib/decompress_bunzip2.c +++ b/lib/decompress_bunzip2.c @@ -299,7 +299,7 @@ static int INIT get_next_block(struct bunzip_data *bd) again when using them (during symbol decoding).*/ base = hufGroup->base-1; limit = hufGroup->limit-1; - /* Calculate permute[]. Concurently, initialize + /* Calculate permute[]. Concurrently, initialize * temp[] and limit[]. */ pp = 0; for (i = minLen; i <= maxLen; i++) { diff --git a/lib/dma-debug.c b/lib/dma-debug.c index ce6b7eabf67..d9b08e0f7f5 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c @@ -259,7 +259,7 @@ static struct dma_debug_entry *hash_bucket_find(struct hash_bucket *bucket, * times. Without a hardware IOMMU this results in the * same device addresses being put into the dma-debug * hash multiple times too. This can result in false - * positives being reported. Therfore we implement a + * positives being reported. Therefore we implement a * best-fit algorithm here which returns the entry from * the hash which fits best to the reference value * instead of the first-fit. diff --git a/lib/swiotlb.c b/lib/swiotlb.c index ac25cd28e80..853907e4586 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -453,7 +453,7 @@ do_unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir) /* * Return the buffer to the free list by setting the corresponding - * entries to indicate the number of contigous entries available. + * entries to indicate the number of contiguous entries available. * While returning the entries to the free list, we merge the entries * with slots below and above the pool being returned. */ diff --git a/mm/filemap.c b/mm/filemap.c index ef169f37156..c3d3506ecab 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1844,7 +1844,7 @@ static size_t __iovec_copy_from_user_inatomic(char *vaddr, /* * Copy as much as we can into the page and return the number of bytes which - * were sucessfully copied. If a fault is encountered then return the number of + * were successfully copied. If a fault is encountered then return the number of * bytes which were copied. */ size_t iov_iter_copy_from_user_atomic(struct page *page, diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 7226e60e52a..c31a310aa14 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -209,7 +209,7 @@ struct mem_cgroup { int prev_priority; /* for recording reclaim priority */ /* - * While reclaiming in a hiearchy, we cache the last child we + * While reclaiming in a hierarchy, we cache the last child we * reclaimed from. */ int last_scanned_child; @@ -2466,7 +2466,7 @@ static int mem_cgroup_hierarchy_write(struct cgroup *cont, struct cftype *cft, cgroup_lock(); /* - * If parent's use_hiearchy is set, we can't make any modifications + * If parent's use_hierarchy is set, we can't make any modifications * in the child subtrees. If it is unset, then the change can * occur, provided the current cgroup has no children. * diff --git a/mm/memory-failure.c b/mm/memory-failure.c index dacc6418387..1ac49fef95a 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -174,7 +174,7 @@ static void kill_procs_ao(struct list_head *to_kill, int doit, int trapno, list_for_each_entry_safe (tk, next, to_kill, nd) { if (doit) { /* - * In case something went wrong with munmaping + * In case something went wrong with munmapping * make sure the process doesn't catch the * signal and then access the memory. Just kill it. * the signal handlers diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c index f7e2fa0974d..16ad251c972 100644 --- a/net/ipv4/netfilter/ipt_ECN.c +++ b/net/ipv4/netfilter/ipt_ECN.c @@ -50,7 +50,7 @@ set_ect_tcp(struct sk_buff *skb, const struct ipt_ECN_info *einfo) struct tcphdr _tcph, *tcph; __be16 oldval; - /* Not enought header? */ + /* Not enough header? */ tcph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_tcph), &_tcph); if (!tcph) return false; diff --git a/net/irda/irlap.c b/net/irda/irlap.c index 356e65b1dc4..783c5f367d2 100644 --- a/net/irda/irlap.c +++ b/net/irda/irlap.c @@ -450,10 +450,10 @@ void irlap_disconnect_request(struct irlap_cb *self) /* Check if we are in the right state for disconnecting */ switch (self->state) { - case LAP_XMIT_P: /* FALLTROUGH */ - case LAP_XMIT_S: /* FALLTROUGH */ - case LAP_CONN: /* FALLTROUGH */ - case LAP_RESET_WAIT: /* FALLTROUGH */ + case LAP_XMIT_P: /* FALLTHROUGH */ + case LAP_XMIT_S: /* FALLTHROUGH */ + case LAP_CONN: /* FALLTHROUGH */ + case LAP_RESET_WAIT: /* FALLTHROUGH */ case LAP_RESET_CHECK: irlap_do_event(self, DISCONNECT_REQUEST, NULL, NULL); break; @@ -485,9 +485,9 @@ void irlap_disconnect_indication(struct irlap_cb *self, LAP_REASON reason) IRDA_DEBUG(1, "%s(), Sending reset request!\n", __func__); irlap_do_event(self, RESET_REQUEST, NULL, NULL); break; - case LAP_NO_RESPONSE: /* FALLTROUGH */ - case LAP_DISC_INDICATION: /* FALLTROUGH */ - case LAP_FOUND_NONE: /* FALLTROUGH */ + case LAP_NO_RESPONSE: /* FALLTHROUGH */ + case LAP_DISC_INDICATION: /* FALLTHROUGH */ + case LAP_FOUND_NONE: /* FALLTHROUGH */ case LAP_MEDIA_BUSY: irlmp_link_disconnect_indication(self->notify.instance, self, reason, NULL); diff --git a/net/irda/irlap_event.c b/net/irda/irlap_event.c index c5c51959e3c..94a9884d714 100644 --- a/net/irda/irlap_event.c +++ b/net/irda/irlap_event.c @@ -1741,7 +1741,7 @@ static int irlap_state_reset(struct irlap_cb *self, IRLAP_EVENT event, * Function irlap_state_xmit_s (event, skb, info) * * XMIT_S, The secondary station has been given the right to transmit, - * and we therefor do not expect to receive any transmissions from other + * and we therefore do not expect to receive any transmissions from other * stations. */ static int irlap_state_xmit_s(struct irlap_cb *self, IRLAP_EVENT event, diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c index 7bf5b913828..0e7d8bde145 100644 --- a/net/irda/irlmp.c +++ b/net/irda/irlmp.c @@ -105,7 +105,7 @@ int __init irlmp_init(void) init_timer(&irlmp->discovery_timer); - /* Do discovery every 3 seconds, conditionaly */ + /* Do discovery every 3 seconds, conditionally */ if (sysctl_discovery) irlmp_start_discovery_timer(irlmp, sysctl_discovery_timeout*HZ); @@ -1842,7 +1842,7 @@ LM_REASON irlmp_convert_lap_reason( LAP_REASON lap_reason) reason = LM_CONNECT_FAILURE; break; default: - IRDA_DEBUG(1, "%s(), Unknow IrLAP disconnect reason %d!\n", + IRDA_DEBUG(1, "%s(), Unknown IrLAP disconnect reason %d!\n", __func__, lap_reason); reason = LM_LAP_DISCONNECT; break; diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 751c4d0e2b3..719ddbc9e48 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -244,7 +244,7 @@ struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data * @addr: destination address of the path (ETH_ALEN length) * @sdata: local subif * - * Returns: 0 on sucess + * Returns: 0 on success * * State: the initial state of the new path is set to 0 */ @@ -530,7 +530,7 @@ static void mesh_path_node_reclaim(struct rcu_head *rp) * @addr: dst address (ETH_ALEN length) * @sdata: local subif * - * Returns: 0 if succesful + * Returns: 0 if successful */ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) { diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index 7a10bbe02c1..c5d9f97ef21 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c @@ -682,7 +682,7 @@ struct netlbl_domaddr6_map *netlbl_domhsh_getentry_af6(const char *domain, * buckets and @skip_chain entries. For each entry in the table call * @callback, if @callback returns a negative value stop 'walking' through the * table and return. Updates the values in @skip_bkt and @skip_chain on - * return. Returns zero on succcess, negative values on failure. + * return. Returns zero on success, negative values on failure. * */ int netlbl_domhsh_walk(u32 *skip_bkt, diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 8674d491955..29d8501bf15 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -719,7 +719,7 @@ static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds, if (sctp_style(sk, TCP)) { /* Change the sk->sk_state of a TCP-style socket that has - * sucessfully completed a connect() call. + * successfully completed a connect() call. */ if (sctp_state(asoc, ESTABLISHED) && sctp_sstate(sk, CLOSED)) sk->sk_state = SCTP_SS_ESTABLISHED; diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index f11be72a1a8..b15e1ebb2bf 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -54,7 +54,7 @@ * Assumptions: * - head[0] is physically contiguous. * - tail[0] is physically contiguous. - * - pages[] is not physically or virtually contigous and consists of + * - pages[] is not physically or virtually contiguous and consists of * PAGE_SIZE elements. * * Output: diff --git a/net/wimax/op-reset.c b/net/wimax/op-reset.c index ca269178c4d..35f370091f4 100644 --- a/net/wimax/op-reset.c +++ b/net/wimax/op-reset.c @@ -62,7 +62,7 @@ * Called when wanting to reset the device for any reason. Device is * taken back to power on status. * - * This call blocks; on succesful return, the device has completed the + * This call blocks; on successful return, the device has completed the * reset process and is ready to operate. */ int wimax_reset(struct wimax_dev *wimax_dev) diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index d8295357358..8413cf38ed2 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -213,7 +213,7 @@ load_config_help[] = N_( "to modify that configuration.\n" "\n" "If you are uncertain, then you have probably never used alternate\n" - "configuration files. You should therefor leave this blank to abort.\n"), + "configuration files. You should therefore leave this blank to abort.\n"), save_config_text[] = N_( "Enter a filename to which this configuration should be saved " "as an alternate. Leave blank to abort."), diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index e68823741ad..2534400317c 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -204,7 +204,7 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, * * Description * Call the NetLabel mechanism to set the label of a packet using @sid. - * Returns zero on auccess, negative values on failure. + * Returns zero on success, negative values on failure. * */ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index ff17820d35e..5914eeb0b33 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -741,7 +741,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid) goto out; } - /* type/domain unchaned */ + /* type/domain unchanged */ if (old_context->type == new_context->type) { rc = 0; goto out; diff --git a/sound/Kconfig b/sound/Kconfig index 4b5365ad6b4..fcad760f569 100644 --- a/sound/Kconfig +++ b/sound/Kconfig @@ -55,7 +55,7 @@ config SOUND_OSS_CORE_PRECLAIM Please read Documentation/feature-removal-schedule.txt for details. - If unusre, say Y. + If unsure, say Y. source "sound/oss/dmasound/Kconfig" diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index a076a6ce807..a828baaab63 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c @@ -177,7 +177,7 @@ static struct pnp_card_device_id snd_cs423x_pnpids[] = { { .id = "CSC0437", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, /* Digital PC 5000 Onboard - CS4236B */ { .id = "CSC0735", .devs = { { "CSC0000" }, { "CSC0010" } } }, - /* some uknown CS4236B */ + /* some unknown CS4236B */ { .id = "CSC0b35", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, /* Intel PR440FX Onboard sound */ { .id = "CSC0b36", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c index 02e30d7c6a9..ddad60ef3f3 100644 --- a/sound/isa/opti9xx/miro.c +++ b/sound/isa/opti9xx/miro.c @@ -137,7 +137,7 @@ struct snd_miro { static void snd_miro_proc_init(struct snd_miro * miro); static char * snd_opti9xx_names[] = { - "unkown", + "unknown", "82C928", "82C929", "82C924", "82C925", "82C930", "82C931", "82C933" diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 5cd555325b9..848007508ff 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -185,7 +185,7 @@ MODULE_DEVICE_TABLE(pnp_card, snd_opti9xx_pnpids); #endif static char * snd_opti9xx_names[] = { - "unkown", + "unknown", "82C928", "82C929", "82C924", "82C925", "82C930", "82C931", "82C933" diff --git a/sound/oss/dmasound/dmasound_paula.c b/sound/oss/dmasound/dmasound_paula.c index 06e9e88e4c0..bb14e4c67e8 100644 --- a/sound/oss/dmasound/dmasound_paula.c +++ b/sound/oss/dmasound/dmasound_paula.c @@ -657,7 +657,7 @@ static int AmiStateInfo(char *buffer, size_t space) len += sprintf(buffer+len, "\tsound.volume_right = %d [0...64]\n", dmasound.volume_right); if (len >= space) { - printk(KERN_ERR "dmasound_paula: overlowed state buffer alloc.\n") ; + printk(KERN_ERR "dmasound_paula: overflowed state buffer alloc.\n") ; len = space ; } return len; diff --git a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c index c62b7d10ec6..8d13092300d 100644 --- a/sound/pci/ca0106/ca0106_proc.c +++ b/sound/pci/ca0106/ca0106_proc.c @@ -233,7 +233,7 @@ static void snd_ca0106_proc_dump_iec958( struct snd_info_buffer *buffer, u32 val snd_iprintf(buffer, "user-defined\n"); break; default: - snd_iprintf(buffer, "unkown\n"); + snd_iprintf(buffer, "unknown\n"); break; } snd_iprintf(buffer, "Sample Bits: "); diff --git a/sound/pci/cs46xx/imgs/cwcdma.asp b/sound/pci/cs46xx/imgs/cwcdma.asp index 09d24c76f03..a65e1193c89 100644 --- a/sound/pci/cs46xx/imgs/cwcdma.asp +++ b/sound/pci/cs46xx/imgs/cwcdma.asp @@ -26,10 +26,11 @@ // // // The purpose of this code is very simple: make it possible to tranfser -// the samples 'as they are' with no alteration from a PCMreader SCB (DMA from host) -// to any other SCB. This is useful for AC3 throug SPDIF. SRC (source rate converters) -// task always alters the samples in some how, however it's from 48khz -> 48khz. The -// alterations are not audible, but AC3 wont work. +// the samples 'as they are' with no alteration from a PCMreader +// SCB (DMA from host) to any other SCB. This is useful for AC3 through SPDIF. +// SRC (source rate converters) task always alters the samples in somehow, +// however it's from 48khz -> 48khz. +// The alterations are not audible, but AC3 wont work. // // ... // | diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index 36e08bd2b3c..360e3809a60 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c @@ -184,7 +184,7 @@ MODULE_PARM_DESC(enable, "Enable the EMU10K1X soundcard."); * The hardware has 3 channels for playback and 1 for capture. * - channel 0 is the front channel * - channel 1 is the rear channel - * - channel 2 is the center/lfe chanel + * - channel 2 is the center/lfe channel * Volume is controlled by the AC97 for the front and rear channels by * the PCM Playback Volume, Sigmatel Surround Playback Volume and * Surround Playback Volume. The Sigmatel 4-Speaker Stereo switch affects diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index 780e1a72114..8917071d5b6 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c @@ -66,7 +66,7 @@ struct cmi_spec { struct hda_pcm pcm_rec[2]; /* PCM information */ - /* pin deafault configuration */ + /* pin default configuration */ hda_nid_t pin_nid[NUM_PINS]; unsigned int def_conf[NUM_PINS]; unsigned int pin_def_confs; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ff20048504b..872731eb49e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6619,7 +6619,7 @@ static struct hda_input_mux alc889A_mb31_capture_source = { /* Front Mic (0x01) unused */ { "Line", 0x2 }, /* Line 2 (0x03) unused */ - /* CD (0x04) unsused? */ + /* CD (0x04) unused? */ }, }; diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 0dce331a2a3..a1b10d1a384 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -3017,7 +3017,7 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry, insel = "Coaxial"; break; default: - insel = "Unkown"; + insel = "Unknown"; } switch (hdspm->control_register & HDSPM_SyncRefMask) { @@ -3028,7 +3028,7 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry, syncref = "MADI"; break; default: - syncref = "Unkown"; + syncref = "Unknown"; } snd_iprintf(buffer, "Inputsel = %s, SyncRef = %s\n", insel, syncref); diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index c33b92edbde..8ce1c9b2e5b 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -101,7 +101,7 @@ static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg, pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value); if (reg >= UDA134X_REGS_NUM) { - printk(KERN_ERR "%s unkown register: reg: %u", + printk(KERN_ERR "%s unknown register: reg: %u", __func__, reg); return -EINVAL; } @@ -552,7 +552,7 @@ static int uda134x_soc_probe(struct platform_device *pdev) ARRAY_SIZE(uda1341_snd_controls)); break; default: - printk(KERN_ERR "%s unkown codec type: %d", + printk(KERN_ERR "%s unknown codec type: %d", __func__, pd->model); return -EINVAL; } diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index fe1307b500c..d72347d90b7 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -607,7 +607,7 @@ SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1, SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0), SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0), SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1), -SOC_SINGLE_TLV("DRC Compressor Threashold Volume", WM8903_DRC_3, 5, 124, 1, +SOC_SINGLE_TLV("DRC Compressor Threshold Volume", WM8903_DRC_3, 5, 124, 1, drc_tlv_thresh), SOC_SINGLE_TLV("DRC Volume", WM8903_DRC_3, 0, 30, 1, drc_tlv_amp), SOC_SINGLE_TLV("DRC Minimum Gain Volume", WM8903_DRC_1, 2, 3, 1, drc_tlv_min), @@ -617,11 +617,11 @@ SOC_ENUM("DRC Decay Rate", drc_decay), SOC_ENUM("DRC FF Delay", drc_ff_delay), SOC_SINGLE("DRC Anticlip Switch", WM8903_DRC_0, 1, 1, 0), SOC_SINGLE("DRC QR Switch", WM8903_DRC_0, 2, 1, 0), -SOC_SINGLE_TLV("DRC QR Threashold Volume", WM8903_DRC_0, 6, 3, 0, drc_tlv_max), +SOC_SINGLE_TLV("DRC QR Threshold Volume", WM8903_DRC_0, 6, 3, 0, drc_tlv_max), SOC_ENUM("DRC QR Decay Rate", drc_qr_decay), SOC_SINGLE("DRC Smoothing Switch", WM8903_DRC_0, 3, 1, 0), SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8903_DRC_0, 0, 1, 0), -SOC_ENUM("DRC Smoothing Threashold", drc_smoothing), +SOC_ENUM("DRC Smoothing Threshold", drc_smoothing), SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup), SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT, diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index d9987999e92..bc033687b22 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -689,7 +689,7 @@ SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8993_DIGITAL_SIDE_TONE, SOC_SINGLE("DRC Switch", WM8993_DRC_CONTROL_1, 15, 1, 0), SOC_ENUM("DRC Path", drc_path), -SOC_SINGLE_TLV("DRC Compressor Threashold Volume", WM8993_DRC_CONTROL_2, +SOC_SINGLE_TLV("DRC Compressor Threshold Volume", WM8993_DRC_CONTROL_2, 2, 60, 1, drc_comp_threash), SOC_SINGLE_TLV("DRC Compressor Amplitude Volume", WM8993_DRC_CONTROL_3, 11, 30, 1, drc_comp_amp), @@ -709,7 +709,7 @@ SOC_SINGLE_TLV("DRC Quick Release Volume", WM8993_DRC_CONTROL_3, 2, 3, 0, SOC_ENUM("DRC Quick Release Rate", drc_qr_rate), SOC_SINGLE("DRC Smoothing Switch", WM8993_DRC_CONTROL_1, 11, 1, 0), SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8993_DRC_CONTROL_1, 8, 1, 0), -SOC_ENUM("DRC Smoothing Hysteresis Threashold", drc_smooth), +SOC_ENUM("DRC Smoothing Hysteresis Threshold", drc_smooth), SOC_SINGLE_TLV("DRC Startup Volume", WM8993_DRC_CONTROL_4, 8, 18, 0, drc_startup_tlv), diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.c b/sound/soc/s3c24xx/s3c24xx_simtec.c index 1966e0d5652..3c7ccb78b6a 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec.c +++ b/sound/soc/s3c24xx/s3c24xx_simtec.c @@ -270,7 +270,7 @@ static int attach_gpio_amp(struct device *dev, gpio_direction_output(pd->amp_gain[1], 0); } - /* note, curently we assume GPA0 isn't valid amp */ + /* note, currently we assume GPA0 isn't valid amp */ if (pdata->amp_gpio > 0) { ret = gpio_request(pd->amp_gpio, "gpio-amp"); if (ret) { diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c index 83b8028e209..81d6f983f51 100644 --- a/sound/soc/s6000/s6000-pcm.c +++ b/sound/soc/s6000/s6000-pcm.c @@ -196,7 +196,7 @@ static int s6000_pcm_start(struct snd_pcm_substream *substream) 0 /* destination skip after chunk (impossible) */, 4 /* 16 byte burst size */, -1 /* don't conserve bandwidth */, - 0 /* low watermark irq descriptor theshold */, + 0 /* low watermark irq descriptor threshold */, 0 /* disable hardware timestamps */, 1 /* enable channel */); diff --git a/sound/sound_core.c b/sound/sound_core.c index 49c99818659..dbca7c909a3 100644 --- a/sound/sound_core.c +++ b/sound/sound_core.c @@ -353,7 +353,7 @@ static struct sound_unit *chains[SOUND_STEP]; * @dev: device pointer * * Allocate a special sound device by minor number from the sound - * subsystem. The allocated number is returned on succes. On failure + * subsystem. The allocated number is returned on success. On failure * a negative error code is returned. */ -- cgit v1.2.3-70-g09d2 From 6070d81eb5f2d4943223c96e7609a53cdc984364 Mon Sep 17 00:00:00 2001 From: Adam Buchbinder Date: Fri, 4 Dec 2009 15:47:01 -0500 Subject: tree-wide: fix misspelling of "definition" in comments "Definition" is misspelled "defintion" in several comments; this patch fixes them. No code changes. Signed-off-by: Adam Buchbinder Signed-off-by: Jiri Kosina --- arch/arm/mach-bcmring/include/csp/reg.h | 2 +- arch/arm/mach-bcmring/include/mach/csp/mm_addr.h | 2 +- arch/arm/mach-u300/include/mach/u300-regs.h | 2 +- arch/sh/include/mach-common/mach/titan.h | 2 +- arch/x86/include/asm/sigcontext.h | 4 ++-- drivers/block/cciss_cmd.h | 2 +- drivers/gpu/drm/radeon/atombios.h | 16 ++++++++-------- drivers/media/video/cx18/cx18-av-core.h | 2 +- drivers/media/video/cx18/cx18-mailbox.h | 2 +- drivers/net/wireless/ath/ath5k/base.h | 2 +- drivers/s390/net/qeth_core_mpc.h | 2 +- drivers/scsi/advansys.c | 2 +- drivers/scsi/aic94xx/aic94xx_reg_def.h | 2 +- drivers/scsi/bfa/include/protocol/ct.h | 4 ++-- drivers/scsi/dmx3191d.c | 2 +- drivers/scsi/wd7000.c | 2 +- drivers/staging/otus/80211core/pub_zfi.h | 2 +- drivers/staging/otus/zdcompat.h | 2 +- drivers/staging/rtl8192su/r8192S_phyreg.h | 2 +- fs/cifs/cifspdu.h | 2 +- fs/compat_ioctl.c | 2 +- include/linux/cciss_ioctl.h | 2 +- include/linux/in6.h | 2 +- include/linux/usb/wusb.h | 2 +- 24 files changed, 33 insertions(+), 33 deletions(-) (limited to 'drivers/media') diff --git a/arch/arm/mach-bcmring/include/csp/reg.h b/arch/arm/mach-bcmring/include/csp/reg.h index e5f60bf5a1f..56654d23c3d 100644 --- a/arch/arm/mach-bcmring/include/csp/reg.h +++ b/arch/arm/mach-bcmring/include/csp/reg.h @@ -16,7 +16,7 @@ /** * @file reg.h * -* @brief Generic register defintions used in CSP +* @brief Generic register definitions used in CSP */ /****************************************************************************/ diff --git a/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h b/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h index 86bb58d4f58..ad58cf87337 100644 --- a/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h +++ b/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h @@ -16,7 +16,7 @@ /** * @file mm_addr.h * -* @brief Memory Map address defintions +* @brief Memory Map address definitions * * @note * None diff --git a/arch/arm/mach-u300/include/mach/u300-regs.h b/arch/arm/mach-u300/include/mach/u300-regs.h index 88333dfb19f..56721a0cd2a 100644 --- a/arch/arm/mach-u300/include/mach/u300-regs.h +++ b/arch/arm/mach-u300/include/mach/u300-regs.h @@ -6,7 +6,7 @@ * Copyright (C) 2006-2009 ST-Ericsson AB * License terms: GNU General Public License (GPL) version 2 * Basic register address definitions in physical memory and - * some block defintions for core devices like the timer. + * some block definitions for core devices like the timer. * Author: Linus Walleij */ diff --git a/arch/sh/include/mach-common/mach/titan.h b/arch/sh/include/mach-common/mach/titan.h index 03f3583c891..4a674d27cbb 100644 --- a/arch/sh/include/mach-common/mach/titan.h +++ b/arch/sh/include/mach-common/mach/titan.h @@ -1,5 +1,5 @@ /* - * Platform defintions for Titan + * Platform definitions for Titan */ #ifndef _ASM_SH_TITAN_H #define _ASM_SH_TITAN_H diff --git a/arch/x86/include/asm/sigcontext.h b/arch/x86/include/asm/sigcontext.h index 72e5a449166..04459d25e66 100644 --- a/arch/x86/include/asm/sigcontext.h +++ b/arch/x86/include/asm/sigcontext.h @@ -124,7 +124,7 @@ struct sigcontext { * fpstate is really (struct _fpstate *) or (struct _xstate *) * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end - * of extended memory layout. See comments at the defintion of + * of extended memory layout. See comments at the definition of * (struct _fpx_sw_bytes) */ void __user *fpstate; /* zero when no FPU/extended context */ @@ -219,7 +219,7 @@ struct sigcontext { * fpstate is really (struct _fpstate *) or (struct _xstate *) * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end - * of extended memory layout. See comments at the defintion of + * of extended memory layout. See comments at the definition of * (struct _fpx_sw_bytes) */ void __user *fpstate; /* zero when no FPU/extended context */ diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h index dbaed1ea0da..8098fccdbec 100644 --- a/drivers/block/cciss_cmd.h +++ b/drivers/block/cciss_cmd.h @@ -5,7 +5,7 @@ //########################################################################### #define CISS_VERSION "1.00" -//general boundary defintions +//general boundary definitions #define SENSEINFOBYTES 32//note that this value may vary between host implementations #define MAXSGENTRIES 31 #define MAXREPLYQS 256 diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index 5d402086bc4..81117890741 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h @@ -1141,7 +1141,7 @@ typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS { /* ucTableFormatRevision=1,ucTableContentRevision=2 */ typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS_V2 { USHORT usPixelClock; /* in 10KHz; for bios convenient */ - UCHAR ucMisc; /* see PANEL_ENCODER_MISC_xx defintions below */ + UCHAR ucMisc; /* see PANEL_ENCODER_MISC_xx definitions below */ UCHAR ucAction; /* 0: turn off encoder */ /* 1: setup and turn on encoder */ UCHAR ucTruncate; /* bit0=0: Disable truncate */ @@ -1424,7 +1424,7 @@ typedef struct _ATOM_MULTIMEDIA_CONFIG_INFO { /* Structures used in FirmwareInfoTable */ /****************************************************************************/ -/* usBIOSCapability Defintion: */ +/* usBIOSCapability Definition: */ /* Bit 0 = 0: Bios image is not Posted, =1:Bios image is Posted; */ /* Bit 1 = 0: Dual CRTC is not supported, =1: Dual CRTC is supported; */ /* Bit 2 = 0: Extended Desktop is not supported, =1: Extended Desktop is supported; */ @@ -2386,7 +2386,7 @@ typedef struct _ATOM_ANALOG_TV_INFO_V1_2 { } ATOM_ANALOG_TV_INFO_V1_2; /**************************************************************************/ -/* VRAM usage and their defintions */ +/* VRAM usage and their definitions */ /* One chunk of VRAM used by Bios are for HWICON surfaces,EDID data. */ /* Current Mode timing and Dail Timing and/or STD timing data EACH device. They can be broken down as below. */ @@ -3046,7 +3046,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_DC 2 #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_LITEAC 3 -/* Byte aligned defintion for BIOS usage */ +/* Byte aligned definition for BIOS usage */ #define ATOM_S0_CRT1_MONOb0 0x01 #define ATOM_S0_CRT1_COLORb0 0x02 #define ATOM_S0_CRT1_MASKb0 (ATOM_S0_CRT1_MONOb0+ATOM_S0_CRT1_COLORb0) @@ -3131,7 +3131,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S2_DISPLAY_ROTATION_DEGREE_SHIFT 30 #define ATOM_S2_DISPLAY_ROTATION_ANGLE_MASK 0xC0000000L -/* Byte aligned defintion for BIOS usage */ +/* Byte aligned definition for BIOS usage */ #define ATOM_S2_TV1_STANDARD_MASKb0 0x0F #define ATOM_S2_CURRENT_BL_LEVEL_MASKb1 0xFF #define ATOM_S2_CRT1_DPMS_STATEb2 0x01 @@ -3190,7 +3190,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S3_ALLOW_FAST_PWR_SWITCH 0x40000000L #define ATOM_S3_RQST_GPU_USE_MIN_PWR 0x80000000L -/* Byte aligned defintion for BIOS usage */ +/* Byte aligned definition for BIOS usage */ #define ATOM_S3_CRT1_ACTIVEb0 0x01 #define ATOM_S3_LCD1_ACTIVEb0 0x02 #define ATOM_S3_TV1_ACTIVEb0 0x04 @@ -3230,7 +3230,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S4_LCD1_REFRESH_MASK 0x0000FF00L #define ATOM_S4_LCD1_REFRESH_SHIFT 8 -/* Byte aligned defintion for BIOS usage */ +/* Byte aligned definition for BIOS usage */ #define ATOM_S4_LCD1_PANEL_ID_MASKb0 0x0FF #define ATOM_S4_LCD1_REFRESH_MASKb1 ATOM_S4_LCD1_PANEL_ID_MASKb0 #define ATOM_S4_VRAM_INFO_MASKb2 ATOM_S4_LCD1_PANEL_ID_MASKb0 @@ -3310,7 +3310,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S6_VRI_BRIGHTNESS_CHANGE 0x40000000L #define ATOM_S6_CONFIG_DISPLAY_CHANGE_MASK 0x80000000L -/* Byte aligned defintion for BIOS usage */ +/* Byte aligned definition for BIOS usage */ #define ATOM_S6_DEVICE_CHANGEb0 0x01 #define ATOM_S6_SCALER_CHANGEb0 0x02 #define ATOM_S6_LID_CHANGEb0 0x04 diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h index 9b84a0c58e0..cafb7e99b9a 100644 --- a/drivers/media/video/cx18/cx18-av-core.h +++ b/drivers/media/video/cx18/cx18-av-core.h @@ -294,7 +294,7 @@ struct cx18_av_state { #define CXADEC_QAM_CONST_DEC 0x924 #define CXADEC_QAM_ROTATOR_FREQ 0x948 -/* Bit defintions / settings used in Mako Audio */ +/* Bit definitions / settings used in Mako Audio */ #define CXADEC_PREF_MODE_MONO_LANGA 0 #define CXADEC_PREF_MODE_MONO_LANGB 1 #define CXADEC_PREF_MODE_MONO_LANGC 2 diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h index e23aaac5b28..522ad534034 100644 --- a/drivers/media/video/cx18/cx18-mailbox.h +++ b/drivers/media/video/cx18/cx18-mailbox.h @@ -41,7 +41,7 @@ struct cx18; /* * This structure is used by CPU to provide completed buffers information * Its structure is dictrated by the layout of the SCB, required by the - * firmware, but its defintion needs to be here, instead of in cx18-scb.h, + * firmware, but its definition needs to be here, instead of in cx18-scb.h, * for mailbox work order scheduling */ struct cx18_mdl_ack { diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index c79a65044b6..4da02941046 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -36,7 +36,7 @@ */ /* - * Defintions for the Atheros Wireless LAN controller driver. + * Definitions for the Atheros Wireless LAN controller driver. */ #ifndef _DEV_ATH_ATHVAR_H #define _DEV_ATH_ATHVAR_H diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index eecb2ee62e8..de7bccef49f 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h @@ -507,7 +507,7 @@ extern unsigned char ULP_ENABLE[]; (PDU_ENCAPSULATION(buffer) + 0x17) #define QETH_ULP_ENABLE_RESP_LINK_TYPE(buffer) \ (PDU_ENCAPSULATION(buffer) + 0x2b) -/* Layer 2 defintions */ +/* Layer 2 definitions */ #define QETH_PROT_LAYER2 0x08 #define QETH_PROT_TCPIP 0x03 #define QETH_PROT_OSN2 0x0a diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index b756041f0b2..22626abdb63 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -7969,7 +7969,7 @@ static int advansys_reset(struct scsi_cmnd *scp) ASC_DBG(1, "before AscInitAsc1000Driver()\n"); status = AscInitAsc1000Driver(asc_dvc); - /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */ + /* Refer to ASC_IERR_* definitions for meaning of 'err_code'. */ if (asc_dvc->err_code) { scmd_printk(KERN_INFO, scp, "SCSI bus reset error: " "0x%x\n", asc_dvc->err_code); diff --git a/drivers/scsi/aic94xx/aic94xx_reg_def.h b/drivers/scsi/aic94xx/aic94xx_reg_def.h index a43e8cdf4ee..28aaf349c11 100644 --- a/drivers/scsi/aic94xx/aic94xx_reg_def.h +++ b/drivers/scsi/aic94xx/aic94xx_reg_def.h @@ -1,5 +1,5 @@ /* - * Aic94xx SAS/SATA driver hardware registers defintions. + * Aic94xx SAS/SATA driver hardware registers definitions. * * Copyright (C) 2004 Adaptec, Inc. All rights reserved. * Copyright (C) 2004 David Chaw diff --git a/drivers/scsi/bfa/include/protocol/ct.h b/drivers/scsi/bfa/include/protocol/ct.h index c59d6630b07..79d16a9ab28 100644 --- a/drivers/scsi/bfa/include/protocol/ct.h +++ b/drivers/scsi/bfa/include/protocol/ct.h @@ -82,7 +82,7 @@ enum { }; /* - * defintions for CT reason code + * definitions for CT reason code */ enum { CT_RSN_INV_CMD = 0x01, @@ -129,7 +129,7 @@ enum { }; /* - * defintions for the explanation code for all servers + * definitions for the explanation code for all servers */ enum { CT_EXP_AUTH_EXCEPTION = 0xF1, diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c index fa738ec8692..207352cc70c 100644 --- a/drivers/scsi/dmx3191d.c +++ b/drivers/scsi/dmx3191d.c @@ -31,7 +31,7 @@ #include /* - * Defintions for the generic 5380 driver. + * Definitions for the generic 5380 driver. */ #define AUTOSENSE diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c index 093610bcfcc..2f6e9d8eaf7 100644 --- a/drivers/scsi/wd7000.c +++ b/drivers/scsi/wd7000.c @@ -161,7 +161,7 @@ * * 2003/02/12 - Christoph Hellwig * - * Cleaned up host template defintion + * Cleaned up host template definition * Removed now obsolete wd7000.h */ diff --git a/drivers/staging/otus/80211core/pub_zfi.h b/drivers/staging/otus/80211core/pub_zfi.h index a35bd5d41d2..60b7d1c56de 100644 --- a/drivers/staging/otus/80211core/pub_zfi.h +++ b/drivers/staging/otus/80211core/pub_zfi.h @@ -20,7 +20,7 @@ #include "../oal_dt.h" /***** Section 1 : Tunable Parameters *****/ -/* The defintions in this section are tunabel parameters */ +/* The definitions in this section are tunabel parameters */ /* Maximum number of BSS that could be scaned */ #define ZM_MAX_BSS 128 diff --git a/drivers/staging/otus/zdcompat.h b/drivers/staging/otus/zdcompat.h index 84ac43356b7..cdcaef54afc 100644 --- a/drivers/staging/otus/zdcompat.h +++ b/drivers/staging/otus/zdcompat.h @@ -17,7 +17,7 @@ /* Module Name : zdcompat.h */ /* */ /* Abstract */ -/* This module contains function defintion for compatibility. */ +/* This module contains function definition for compatibility. */ /* */ /* NOTES */ /* Platform dependent. */ diff --git a/drivers/staging/rtl8192su/r8192S_phyreg.h b/drivers/staging/rtl8192su/r8192S_phyreg.h index 96c7cfa9254..acf644f430a 100644 --- a/drivers/staging/rtl8192su/r8192S_phyreg.h +++ b/drivers/staging/rtl8192su/r8192S_phyreg.h @@ -38,7 +38,7 @@ // 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 // 3. RF register 0x00-2E // 4. Bit Mask for BB/RF register -// 5. Other defintion for BB/RF R/W +// 5. Other definition for BB/RF R/W // diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 2d07f890a84..3877737f96a 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -1227,7 +1227,7 @@ typedef struct smb_com_setattr_rsp { /* empty wct response to setattr */ /*******************************************************/ -/* NT Transact structure defintions follow */ +/* NT Transact structure definitions follow */ /* Currently only ioctl, acl (get security descriptor) */ /* and notify are implemented */ /*******************************************************/ diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index f91fd51b32e..5fc8e52ee30 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -2655,7 +2655,7 @@ COMPATIBLE_IOCTL(TIOCSLTC) #endif #ifdef TIOCSTART /* - * For these two we have defintions in ioctls.h and/or termios.h on + * For these two we have definitions in ioctls.h and/or termios.h on * some architectures but no actual implemention. Some applications * like bash call them if they are defined in the headers, so we provide * entries here to avoid syslog message spew. diff --git a/include/linux/cciss_ioctl.h b/include/linux/cciss_ioctl.h index cb57c30081a..eb130b4d8e7 100644 --- a/include/linux/cciss_ioctl.h +++ b/include/linux/cciss_ioctl.h @@ -39,7 +39,7 @@ typedef __u32 DriverVer_type; #ifndef CCISS_CMD_H // This defines are duplicated in cciss_cmd.h in the driver directory -//general boundary defintions +//general boundary definitions #define SENSEINFOBYTES 32//note that this value may vary between host implementations //Command Status value diff --git a/include/linux/in6.h b/include/linux/in6.h index 718bf21c575..010290dd79b 100644 --- a/include/linux/in6.h +++ b/include/linux/in6.h @@ -113,7 +113,7 @@ struct in6_flowlabel_req #define IPV6_FLOWINFO_FLOWLABEL 0x000fffff #define IPV6_FLOWINFO_PRIORITY 0x0ff00000 -/* These defintions are obsolete */ +/* These definitions are obsolete */ #define IPV6_PRIORITY_UNCHARACTERIZED 0x0000 #define IPV6_PRIORITY_FILLER 0x0100 #define IPV6_PRIORITY_UNATTENDED 0x0200 diff --git a/include/linux/usb/wusb.h b/include/linux/usb/wusb.h index 429c631d2aa..63ebdcc5dda 100644 --- a/include/linux/usb/wusb.h +++ b/include/linux/usb/wusb.h @@ -74,7 +74,7 @@ enum { * WUSB defines that CHIDs, CDIDs and CKs are a 16 byte string of * data. In order to avoid confusion and enforce types, we wrap it. * - * Make it packed, as we use it in some hw defintions. + * Make it packed, as we use it in some hw definitions. */ struct wusb_ckhdid { u8 data[16]; -- cgit v1.2.3-70-g09d2 From 8d64827172ae680d34d0611a1e865b546e6a5f08 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 23 Sep 2009 04:59:24 -0300 Subject: V4L/DVB (13040): V4L2: Add a v4l2-subdev (soc-camera) driver for OmniVision OV9640 sensor Signed-off-by: Marek Vasut Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 6 + drivers/media/video/Makefile | 1 + drivers/media/video/ov9640.c | 801 ++++++++++++++++++++++++++++++++++++++++ drivers/media/video/ov9640.h | 209 +++++++++++ include/media/v4l2-chip-ident.h | 1 + 5 files changed, 1018 insertions(+) create mode 100644 drivers/media/video/ov9640.c create mode 100644 drivers/media/video/ov9640.h (limited to 'drivers/media') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index e6186b338a1..c318676f2d2 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -865,6 +865,12 @@ config SOC_CAMERA_OV772X help This is a ov772x camera driver +config SOC_CAMERA_OV9640 + tristate "ov9640 camera support" + depends on SOC_CAMERA && I2C + help + This is a ov9640 camera driver + config MX1_VIDEO bool diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index e541932a789..e706ceecef8 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -77,6 +77,7 @@ obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o +obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o # And now the v4l2 drivers: diff --git a/drivers/media/video/ov9640.c b/drivers/media/video/ov9640.c new file mode 100644 index 00000000000..c81ae219288 --- /dev/null +++ b/drivers/media/video/ov9640.c @@ -0,0 +1,801 @@ +/* + * OmniVision OV96xx Camera Driver + * + * Copyright (C) 2009 Marek Vasut + * + * Based on ov772x camera driver: + * + * Copyright (C) 2008 Renesas Solutions Corp. + * Kuninori Morimoto + * + * Based on ov7670 and soc_camera_platform driver, + * + * Copyright 2006-7 Jonathan Corbet + * Copyright (C) 2008 Magnus Damm + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ov9640.h" + +/* default register setup */ +static const struct ov9640_reg ov9640_regs_dflt[] = { + { OV9640_COM5, OV9640_COM5_SYSCLK | OV9640_COM5_LONGEXP }, + { OV9640_COM6, OV9640_COM6_OPT_BLC | OV9640_COM6_ADBLC_BIAS | + OV9640_COM6_FMT_RST | OV9640_COM6_ADBLC_OPTEN }, + { OV9640_PSHFT, OV9640_PSHFT_VAL(0x01) }, + { OV9640_ACOM, OV9640_ACOM_2X_ANALOG | OV9640_ACOM_RSVD }, + { OV9640_TSLB, OV9640_TSLB_YUYV_UYVY }, + { OV9640_COM16, OV9640_COM16_RB_AVG }, + + /* Gamma curve P */ + { 0x6c, 0x40 }, { 0x6d, 0x30 }, { 0x6e, 0x4b }, { 0x6f, 0x60 }, + { 0x70, 0x70 }, { 0x71, 0x70 }, { 0x72, 0x70 }, { 0x73, 0x70 }, + { 0x74, 0x60 }, { 0x75, 0x60 }, { 0x76, 0x50 }, { 0x77, 0x48 }, + { 0x78, 0x3a }, { 0x79, 0x2e }, { 0x7a, 0x28 }, { 0x7b, 0x22 }, + + /* Gamma curve T */ + { 0x7c, 0x04 }, { 0x7d, 0x07 }, { 0x7e, 0x10 }, { 0x7f, 0x28 }, + { 0x80, 0x36 }, { 0x81, 0x44 }, { 0x82, 0x52 }, { 0x83, 0x60 }, + { 0x84, 0x6c }, { 0x85, 0x78 }, { 0x86, 0x8c }, { 0x87, 0x9e }, + { 0x88, 0xbb }, { 0x89, 0xd2 }, { 0x8a, 0xe6 }, +}; + +/* Configurations + * NOTE: for YUV, alter the following registers: + * COM12 |= OV9640_COM12_YUV_AVG + * + * for RGB, alter the following registers: + * COM7 |= OV9640_COM7_RGB + * COM13 |= OV9640_COM13_RGB_AVG + * COM15 |= proper RGB color encoding mode + */ +static const struct ov9640_reg ov9640_regs_qqcif[] = { + { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x0f) }, + { OV9640_COM1, OV9640_COM1_QQFMT | OV9640_COM1_HREF_2SKIP }, + { OV9640_COM4, OV9640_COM4_QQ_VP | OV9640_COM4_RSVD }, + { OV9640_COM7, OV9640_COM7_QCIF }, + { OV9640_COM12, OV9640_COM12_RSVD }, + { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN }, + { OV9640_COM15, OV9640_COM15_OR_10F0 }, +}; + +static const struct ov9640_reg ov9640_regs_qqvga[] = { + { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x07) }, + { OV9640_COM1, OV9640_COM1_QQFMT | OV9640_COM1_HREF_2SKIP }, + { OV9640_COM4, OV9640_COM4_QQ_VP | OV9640_COM4_RSVD }, + { OV9640_COM7, OV9640_COM7_QVGA }, + { OV9640_COM12, OV9640_COM12_RSVD }, + { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN }, + { OV9640_COM15, OV9640_COM15_OR_10F0 }, +}; + +static const struct ov9640_reg ov9640_regs_qcif[] = { + { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x07) }, + { OV9640_COM4, OV9640_COM4_QQ_VP | OV9640_COM4_RSVD }, + { OV9640_COM7, OV9640_COM7_QCIF }, + { OV9640_COM12, OV9640_COM12_RSVD }, + { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN }, + { OV9640_COM15, OV9640_COM15_OR_10F0 }, +}; + +static const struct ov9640_reg ov9640_regs_qvga[] = { + { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x03) }, + { OV9640_COM4, OV9640_COM4_QQ_VP | OV9640_COM4_RSVD }, + { OV9640_COM7, OV9640_COM7_QVGA }, + { OV9640_COM12, OV9640_COM12_RSVD }, + { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN }, + { OV9640_COM15, OV9640_COM15_OR_10F0 }, +}; + +static const struct ov9640_reg ov9640_regs_cif[] = { + { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x03) }, + { OV9640_COM3, OV9640_COM3_VP }, + { OV9640_COM7, OV9640_COM7_CIF }, + { OV9640_COM12, OV9640_COM12_RSVD }, + { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN }, + { OV9640_COM15, OV9640_COM15_OR_10F0 }, +}; + +static const struct ov9640_reg ov9640_regs_vga[] = { + { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x01) }, + { OV9640_COM3, OV9640_COM3_VP }, + { OV9640_COM7, OV9640_COM7_VGA }, + { OV9640_COM12, OV9640_COM12_RSVD }, + { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN }, + { OV9640_COM15, OV9640_COM15_OR_10F0 }, +}; + +static const struct ov9640_reg ov9640_regs_sxga[] = { + { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x01) }, + { OV9640_COM3, OV9640_COM3_VP }, + { OV9640_COM7, 0 }, + { OV9640_COM12, OV9640_COM12_RSVD }, + { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN }, + { OV9640_COM15, OV9640_COM15_OR_10F0 }, +}; + +static const struct ov9640_reg ov9640_regs_yuv[] = { + { OV9640_MTX1, 0x58 }, + { OV9640_MTX2, 0x48 }, + { OV9640_MTX3, 0x10 }, + { OV9640_MTX4, 0x28 }, + { OV9640_MTX5, 0x48 }, + { OV9640_MTX6, 0x70 }, + { OV9640_MTX7, 0x40 }, + { OV9640_MTX8, 0x40 }, + { OV9640_MTX9, 0x40 }, + { OV9640_MTXS, 0x0f }, +}; + +static const struct ov9640_reg ov9640_regs_rgb[] = { + { OV9640_MTX1, 0x71 }, + { OV9640_MTX2, 0x3e }, + { OV9640_MTX3, 0x0c }, + { OV9640_MTX4, 0x33 }, + { OV9640_MTX5, 0x72 }, + { OV9640_MTX6, 0x00 }, + { OV9640_MTX7, 0x2b }, + { OV9640_MTX8, 0x66 }, + { OV9640_MTX9, 0xd2 }, + { OV9640_MTXS, 0x65 }, +}; + +/* + * TODO: this sensor also supports RGB555 and RGB565 formats, but support for + * them has not yet been sufficiently tested and so it is not included with + * this version of the driver. To test and debug these formats add two entries + * to the below array, see ov722x.c for an example. + */ +static const struct soc_camera_data_format ov9640_fmt_lists[] = { + { + .name = "UYVY", + .fourcc = V4L2_PIX_FMT_UYVY, + .depth = 16, + .colorspace = V4L2_COLORSPACE_JPEG, + }, +}; + +static const struct v4l2_queryctrl ov9640_controls[] = { + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Vertically", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Horizontally", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, +}; + +/* read a register */ +static int ov9640_reg_read(struct i2c_client *client, u8 reg, u8 *val) +{ + int ret; + u8 data = reg; + struct i2c_msg msg = { + .addr = client->addr, + .flags = 0, + .len = 1, + .buf = &data, + }; + + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret < 0) + goto err; + + msg.flags = I2C_M_RD; + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret < 0) + goto err; + + *val = data; + return 0; + +err: + dev_err(&client->dev, "Failed reading register 0x%02x!\n", reg); + return ret; +} + +/* write a register */ +static int ov9640_reg_write(struct i2c_client *client, u8 reg, u8 val) +{ + int ret; + u8 _val; + unsigned char data[2] = { reg, val }; + struct i2c_msg msg = { + .addr = client->addr, + .flags = 0, + .len = 2, + .buf = data, + }; + + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret < 0) { + dev_err(&client->dev, "Failed writing register 0x%02x!\n", reg); + return ret; + } + + /* we have to read the register back ... no idea why, maybe HW bug */ + ret = ov9640_reg_read(client, reg, &_val); + if (ret) + dev_err(&client->dev, + "Failed reading back register 0x%02x!\n", reg); + + return 0; +} + + +/* Read a register, alter its bits, write it back */ +static int ov9640_reg_rmw(struct i2c_client *client, u8 reg, u8 set, u8 unset) +{ + u8 val; + int ret; + + ret = ov9640_reg_read(client, reg, &val); + if (ret) { + dev_err(&client->dev, + "[Read]-Modify-Write of register %02x failed!\n", reg); + return val; + } + + val |= set; + val &= ~unset; + + ret = ov9640_reg_write(client, reg, val); + if (ret) + dev_err(&client->dev, + "Read-Modify-[Write] of register %02x failed!\n", reg); + + return ret; +} + +/* Soft reset the camera. This has nothing to do with the RESET pin! */ +static int ov9640_reset(struct i2c_client *client) +{ + int ret; + + ret = ov9640_reg_write(client, OV9640_COM7, OV9640_COM7_SCCB_RESET); + if (ret) + dev_err(&client->dev, + "An error occured while entering soft reset!\n"); + + return ret; +} + +/* Start/Stop streaming from the device */ +static int ov9640_s_stream(struct v4l2_subdev *sd, int enable) +{ + return 0; +} + +/* Alter bus settings on camera side */ +static int ov9640_set_bus_param(struct soc_camera_device *icd, + unsigned long flags) +{ + return 0; +} + +/* Request bus settings on camera side */ +static unsigned long ov9640_query_bus_param(struct soc_camera_device *icd) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + + /* + * REVISIT: the camera probably can do 10 bit transfers, but I don't + * have those pins connected on my hardware. + */ + unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER | + SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH | + SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8; + + return soc_camera_apply_sensor_flags(icl, flags); +} + +/* Get status of additional camera capabilities */ +static int ov9640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = sd->priv; + struct ov9640_priv *priv = container_of(i2c_get_clientdata(client), + struct ov9640_priv, subdev); + + switch (ctrl->id) { + case V4L2_CID_VFLIP: + ctrl->value = priv->flag_vflip; + break; + case V4L2_CID_HFLIP: + ctrl->value = priv->flag_hflip; + break; + } + return 0; +} + +/* Set status of additional camera capabilities */ +static int ov9640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = sd->priv; + struct ov9640_priv *priv = container_of(i2c_get_clientdata(client), + struct ov9640_priv, subdev); + + int ret = 0; + + switch (ctrl->id) { + case V4L2_CID_VFLIP: + priv->flag_vflip = ctrl->value; + if (ctrl->value) + ret = ov9640_reg_rmw(client, OV9640_MVFP, + OV9640_MVFP_V, 0); + else + ret = ov9640_reg_rmw(client, OV9640_MVFP, + 0, OV9640_MVFP_V); + break; + case V4L2_CID_HFLIP: + priv->flag_hflip = ctrl->value; + if (ctrl->value) + ret = ov9640_reg_rmw(client, OV9640_MVFP, + OV9640_MVFP_H, 0); + else + ret = ov9640_reg_rmw(client, OV9640_MVFP, + 0, OV9640_MVFP_H); + break; + } + + return ret; +} + +/* Get chip identification */ +static int ov9640_g_chip_ident(struct v4l2_subdev *sd, + struct v4l2_dbg_chip_ident *id) +{ + struct i2c_client *client = sd->priv; + struct ov9640_priv *priv = container_of(i2c_get_clientdata(client), + struct ov9640_priv, subdev); + + id->ident = priv->model; + id->revision = priv->revision; + + return 0; +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int ov9640_get_register(struct v4l2_subdev *sd, + struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = sd->priv; + int ret; + u8 val; + + if (reg->reg & ~0xff) + return -EINVAL; + + reg->size = 1; + + ret = ov9640_reg_read(client, reg->reg, &val); + if (ret) + return ret; + + reg->val = (__u64)val; + + return 0; +} + +static int ov9640_set_register(struct v4l2_subdev *sd, + struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = sd->priv; + + if (reg->reg & ~0xff || reg->val & ~0xff) + return -EINVAL; + + return ov9640_reg_write(client, reg->reg, reg->val); +} +#endif + +/* select nearest higher resolution for capture */ +static void ov9640_res_roundup(u32 *width, u32 *height) +{ + int i; + enum { QQCIF, QQVGA, QCIF, QVGA, CIF, VGA, SXGA }; + int res_x[] = { 88, 160, 176, 320, 352, 640, 1280 }; + int res_y[] = { 72, 120, 144, 240, 288, 480, 960 }; + + for (i = 0; i < ARRAY_SIZE(res_x); i++) { + if (res_x[i] >= *width && res_y[i] >= *height) { + *width = res_x[i]; + *height = res_y[i]; + return; + } + } + + *width = res_x[SXGA]; + *height = res_y[SXGA]; +} + +/* Prepare necessary register changes depending on color encoding */ +static void ov9640_alter_regs(u32 pixfmt, struct ov9640_reg_alt *alt) +{ + switch (pixfmt) { + case V4L2_PIX_FMT_UYVY: + alt->com12 = OV9640_COM12_YUV_AVG; + alt->com13 = OV9640_COM13_Y_DELAY_EN | + OV9640_COM13_YUV_DLY(0x01); + break; + case V4L2_PIX_FMT_RGB555: + alt->com7 = OV9640_COM7_RGB; + alt->com13 = OV9640_COM13_RGB_AVG; + alt->com15 = OV9640_COM15_RGB_555; + break; + case V4L2_PIX_FMT_RGB565: + alt->com7 = OV9640_COM7_RGB; + alt->com13 = OV9640_COM13_RGB_AVG; + alt->com15 = OV9640_COM15_RGB_565; + break; + }; +} + +/* Setup registers according to resolution and color encoding */ +static int ov9640_write_regs(struct i2c_client *client, + u32 width, u32 pixfmt, struct ov9640_reg_alt *alts) +{ + const struct ov9640_reg *ov9640_regs, *matrix_regs; + int ov9640_regs_len, matrix_regs_len; + int i, ret; + u8 val; + + /* select register configuration for given resolution */ + switch (width) { + case W_QQCIF: + ov9640_regs = ov9640_regs_qqcif; + ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qqcif); + break; + case W_QQVGA: + ov9640_regs = ov9640_regs_qqvga; + ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qqvga); + break; + case W_QCIF: + ov9640_regs = ov9640_regs_qcif; + ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qcif); + break; + case W_QVGA: + ov9640_regs = ov9640_regs_qvga; + ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qvga); + break; + case W_CIF: + ov9640_regs = ov9640_regs_cif; + ov9640_regs_len = ARRAY_SIZE(ov9640_regs_cif); + break; + case W_VGA: + ov9640_regs = ov9640_regs_vga; + ov9640_regs_len = ARRAY_SIZE(ov9640_regs_vga); + break; + case W_SXGA: + ov9640_regs = ov9640_regs_sxga; + ov9640_regs_len = ARRAY_SIZE(ov9640_regs_sxga); + break; + default: + dev_err(&client->dev, "Failed to select resolution!\n"); + return -EINVAL; + } + + /* select color matrix configuration for given color encoding */ + if (pixfmt == V4L2_PIX_FMT_UYVY) { + matrix_regs = ov9640_regs_yuv; + matrix_regs_len = ARRAY_SIZE(ov9640_regs_yuv); + } else { + matrix_regs = ov9640_regs_rgb; + matrix_regs_len = ARRAY_SIZE(ov9640_regs_rgb); + } + + /* write register settings into the module */ + for (i = 0; i < ov9640_regs_len; i++) { + val = ov9640_regs[i].val; + + switch (ov9640_regs[i].reg) { + case OV9640_COM7: + val |= alts->com7; + break; + case OV9640_COM12: + val |= alts->com12; + break; + case OV9640_COM13: + val |= alts->com13; + break; + case OV9640_COM15: + val |= alts->com15; + break; + } + + ret = ov9640_reg_write(client, ov9640_regs[i].reg, val); + if (ret) + return ret; + } + + /* write color matrix configuration into the module */ + for (i = 0; i < matrix_regs_len; i++) { + ret = ov9640_reg_write(client, matrix_regs[i].reg, + matrix_regs[i].val); + if (ret) + return ret; + } + + return 0; +} + +/* program default register values */ +static int ov9640_prog_dflt(struct i2c_client *client) +{ + int i, ret; + + for (i = 0; i < ARRAY_SIZE(ov9640_regs_dflt); i++) { + ret = ov9640_reg_write(client, ov9640_regs_dflt[i].reg, + ov9640_regs_dflt[i].val); + if (ret) + return ret; + } + + /* wait for the changes to actually happen, 140ms are not enough yet */ + mdelay(150); + + return 0; +} + +/* set the format we will capture in */ +static int ov9640_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +{ + struct i2c_client *client = sd->priv; + struct v4l2_pix_format *pix = &f->fmt.pix; + struct ov9640_reg_alt alts = {0}; + int ret; + + ov9640_res_roundup(&pix->width, &pix->height); + ov9640_alter_regs(pix->pixelformat, &alts); + + ov9640_reset(client); + + ret = ov9640_prog_dflt(client); + if (ret) + return ret; + + return ov9640_write_regs(client, pix->width, pix->pixelformat, &alts); +} + +static int ov9640_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +{ + struct v4l2_pix_format *pix = &f->fmt.pix; + + ov9640_res_roundup(&pix->width, &pix->height); + pix->field = V4L2_FIELD_NONE; + + return 0; +} + +static int ov9640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) +{ + a->c.left = 0; + a->c.top = 0; + a->c.width = W_SXGA; + a->c.height = H_SXGA; + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + return 0; +} + +static int ov9640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) +{ + a->bounds.left = 0; + a->bounds.top = 0; + a->bounds.width = W_SXGA; + a->bounds.height = H_SXGA; + a->defrect = a->bounds; + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + a->pixelaspect.numerator = 1; + a->pixelaspect.denominator = 1; + + return 0; +} + + + +static int ov9640_video_probe(struct soc_camera_device *icd, + struct i2c_client *client) +{ + struct ov9640_priv *priv = i2c_get_clientdata(client); + u8 pid, ver, midh, midl; + const char *devname; + int ret = 0; + + /* + * We must have a parent by now. And it cannot be a wrong one. + * So this entire test is completely redundant. + */ + if (!icd->dev.parent || + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) { + dev_err(&client->dev, "Parent missing or invalid!\n"); + ret = -ENODEV; + goto err; + } + + icd->formats = ov9640_fmt_lists; + icd->num_formats = ARRAY_SIZE(ov9640_fmt_lists); + + /* + * check and show product ID and manufacturer ID + */ + + ret = ov9640_reg_read(client, OV9640_PID, &pid); + if (ret) + goto err; + + ret = ov9640_reg_read(client, OV9640_VER, &ver); + if (ret) + goto err; + + ret = ov9640_reg_read(client, OV9640_MIDH, &midh); + if (ret) + goto err; + + ret = ov9640_reg_read(client, OV9640_MIDL, &midl); + if (ret) + goto err; + + switch (VERSION(pid, ver)) { + case OV9640_V2: + devname = "ov9640"; + priv->model = V4L2_IDENT_OV9640; + priv->revision = 2; + case OV9640_V3: + devname = "ov9640"; + priv->model = V4L2_IDENT_OV9640; + priv->revision = 3; + break; + default: + dev_err(&client->dev, "Product ID error %x:%x\n", pid, ver); + ret = -ENODEV; + goto err; + } + + dev_info(&client->dev, "%s Product ID %0x:%0x Manufacturer ID %x:%x\n", + devname, pid, ver, midh, midl); + +err: + return ret; +} + +static struct soc_camera_ops ov9640_ops = { + .set_bus_param = ov9640_set_bus_param, + .query_bus_param = ov9640_query_bus_param, + .controls = ov9640_controls, + .num_controls = ARRAY_SIZE(ov9640_controls), +}; + +static struct v4l2_subdev_core_ops ov9640_core_ops = { + .g_ctrl = ov9640_g_ctrl, + .s_ctrl = ov9640_s_ctrl, + .g_chip_ident = ov9640_g_chip_ident, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .g_register = ov9640_get_register, + .s_register = ov9640_set_register, +#endif + +}; + +static struct v4l2_subdev_video_ops ov9640_video_ops = { + .s_stream = ov9640_s_stream, + .s_fmt = ov9640_s_fmt, + .try_fmt = ov9640_try_fmt, + .cropcap = ov9640_cropcap, + .g_crop = ov9640_g_crop, + +}; + +static struct v4l2_subdev_ops ov9640_subdev_ops = { + .core = &ov9640_core_ops, + .video = &ov9640_video_ops, +}; + +/* + * i2c_driver function + */ +static int ov9640_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct ov9640_priv *priv; + struct soc_camera_device *icd = client->dev.platform_data; + struct soc_camera_link *icl; + int ret; + + if (!icd) { + dev_err(&client->dev, "Missing soc-camera data!\n"); + return -EINVAL; + } + + icl = to_soc_camera_link(icd); + if (!icl) { + dev_err(&client->dev, "Missing platform_data for driver\n"); + return -EINVAL; + } + + priv = kzalloc(sizeof(struct ov9640_priv), GFP_KERNEL); + if (!priv) { + dev_err(&client->dev, + "Failed to allocate memory for private data!\n"); + return -ENOMEM; + } + + v4l2_i2c_subdev_init(&priv->subdev, client, &ov9640_subdev_ops); + + icd->ops = &ov9640_ops; + + ret = ov9640_video_probe(icd, client); + + if (ret) { + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + kfree(priv); + } + + return ret; +} + +static int ov9640_remove(struct i2c_client *client) +{ + struct ov9640_priv *priv = i2c_get_clientdata(client); + + i2c_set_clientdata(client, NULL); + kfree(priv); + return 0; +} + +static const struct i2c_device_id ov9640_id[] = { + { "ov9640", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ov9640_id); + +static struct i2c_driver ov9640_i2c_driver = { + .driver = { + .name = "ov9640", + }, + .probe = ov9640_probe, + .remove = ov9640_remove, + .id_table = ov9640_id, +}; + +static int __init ov9640_module_init(void) +{ + return i2c_add_driver(&ov9640_i2c_driver); +} + +static void __exit ov9640_module_exit(void) +{ + i2c_del_driver(&ov9640_i2c_driver); +} + +module_init(ov9640_module_init); +module_exit(ov9640_module_exit); + +MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV96xx"); +MODULE_AUTHOR("Marek Vasut "); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/video/ov9640.h b/drivers/media/video/ov9640.h new file mode 100644 index 00000000000..f8a51b70792 --- /dev/null +++ b/drivers/media/video/ov9640.h @@ -0,0 +1,209 @@ +/* + * OmniVision OV96xx Camera Header File + * + * Copyright (C) 2009 Marek Vasut + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __DRIVERS_MEDIA_VIDEO_OV9640_H__ +#define __DRIVERS_MEDIA_VIDEO_OV9640_H__ + +/* Register definitions */ +#define OV9640_GAIN 0x00 +#define OV9640_BLUE 0x01 +#define OV9640_RED 0x02 +#define OV9640_VFER 0x03 +#define OV9640_COM1 0x04 +#define OV9640_BAVE 0x05 +#define OV9640_GEAVE 0x06 +#define OV9640_RSID 0x07 +#define OV9640_RAVE 0x08 +#define OV9640_COM2 0x09 +#define OV9640_PID 0x0a +#define OV9640_VER 0x0b +#define OV9640_COM3 0x0c +#define OV9640_COM4 0x0d +#define OV9640_COM5 0x0e +#define OV9640_COM6 0x0f +#define OV9640_AECH 0x10 +#define OV9640_CLKRC 0x11 +#define OV9640_COM7 0x12 +#define OV9640_COM8 0x13 +#define OV9640_COM9 0x14 +#define OV9640_COM10 0x15 +/* 0x16 - RESERVED */ +#define OV9640_HSTART 0x17 +#define OV9640_HSTOP 0x18 +#define OV9640_VSTART 0x19 +#define OV9640_VSTOP 0x1a +#define OV9640_PSHFT 0x1b +#define OV9640_MIDH 0x1c +#define OV9640_MIDL 0x1d +#define OV9640_MVFP 0x1e +#define OV9640_LAEC 0x1f +#define OV9640_BOS 0x20 +#define OV9640_GBOS 0x21 +#define OV9640_GROS 0x22 +#define OV9640_ROS 0x23 +#define OV9640_AEW 0x24 +#define OV9640_AEB 0x25 +#define OV9640_VPT 0x26 +#define OV9640_BBIAS 0x27 +#define OV9640_GBBIAS 0x28 +/* 0x29 - RESERVED */ +#define OV9640_EXHCH 0x2a +#define OV9640_EXHCL 0x2b +#define OV9640_RBIAS 0x2c +#define OV9640_ADVFL 0x2d +#define OV9640_ADVFH 0x2e +#define OV9640_YAVE 0x2f +#define OV9640_HSYST 0x30 +#define OV9640_HSYEN 0x31 +#define OV9640_HREF 0x32 +#define OV9640_CHLF 0x33 +#define OV9640_ARBLM 0x34 +/* 0x35..0x36 - RESERVED */ +#define OV9640_ADC 0x37 +#define OV9640_ACOM 0x38 +#define OV9640_OFON 0x39 +#define OV9640_TSLB 0x3a +#define OV9640_COM11 0x3b +#define OV9640_COM12 0x3c +#define OV9640_COM13 0x3d +#define OV9640_COM14 0x3e +#define OV9640_EDGE 0x3f +#define OV9640_COM15 0x40 +#define OV9640_COM16 0x41 +#define OV9640_COM17 0x42 +/* 0x43..0x4e - RESERVED */ +#define OV9640_MTX1 0x4f +#define OV9640_MTX2 0x50 +#define OV9640_MTX3 0x51 +#define OV9640_MTX4 0x52 +#define OV9640_MTX5 0x53 +#define OV9640_MTX6 0x54 +#define OV9640_MTX7 0x55 +#define OV9640_MTX8 0x56 +#define OV9640_MTX9 0x57 +#define OV9640_MTXS 0x58 +/* 0x59..0x61 - RESERVED */ +#define OV9640_LCC1 0x62 +#define OV9640_LCC2 0x63 +#define OV9640_LCC3 0x64 +#define OV9640_LCC4 0x65 +#define OV9640_LCC5 0x66 +#define OV9640_MANU 0x67 +#define OV9640_MANV 0x68 +#define OV9640_HV 0x69 +#define OV9640_MBD 0x6a +#define OV9640_DBLV 0x6b +#define OV9640_GSP 0x6c /* ... till 0x7b */ +#define OV9640_GST 0x7c /* ... till 0x8a */ + +#define OV9640_CLKRC_DPLL_EN 0x80 +#define OV9640_CLKRC_DIRECT 0x40 +#define OV9640_CLKRC_DIV(x) ((x) & 0x3f) + +#define OV9640_PSHFT_VAL(x) ((x) & 0xff) + +#define OV9640_ACOM_2X_ANALOG 0x80 +#define OV9640_ACOM_RSVD 0x12 + +#define OV9640_MVFP_V 0x10 +#define OV9640_MVFP_H 0x20 + +#define OV9640_COM1_HREF_NOSKIP 0x00 +#define OV9640_COM1_HREF_2SKIP 0x04 +#define OV9640_COM1_HREF_3SKIP 0x08 +#define OV9640_COM1_QQFMT 0x20 + +#define OV9640_COM2_SSM 0x10 + +#define OV9640_COM3_VP 0x04 + +#define OV9640_COM4_QQ_VP 0x80 +#define OV9640_COM4_RSVD 0x40 + +#define OV9640_COM5_SYSCLK 0x80 +#define OV9640_COM5_LONGEXP 0x01 + +#define OV9640_COM6_OPT_BLC 0x40 +#define OV9640_COM6_ADBLC_BIAS 0x08 +#define OV9640_COM6_FMT_RST 0x82 +#define OV9640_COM6_ADBLC_OPTEN 0x01 + +#define OV9640_COM7_RAW_RGB 0x01 +#define OV9640_COM7_RGB 0x04 +#define OV9640_COM7_QCIF 0x08 +#define OV9640_COM7_QVGA 0x10 +#define OV9640_COM7_CIF 0x20 +#define OV9640_COM7_VGA 0x40 +#define OV9640_COM7_SCCB_RESET 0x80 + +#define OV9640_TSLB_YVYU_YUYV 0x04 +#define OV9640_TSLB_YUYV_UYVY 0x08 + +#define OV9640_COM12_YUV_AVG 0x04 +#define OV9640_COM12_RSVD 0x40 + +#define OV9640_COM13_GAMMA_NONE 0x00 +#define OV9640_COM13_GAMMA_Y 0x40 +#define OV9640_COM13_GAMMA_RAW 0x80 +#define OV9640_COM13_RGB_AVG 0x20 +#define OV9640_COM13_MATRIX_EN 0x10 +#define OV9640_COM13_Y_DELAY_EN 0x08 +#define OV9640_COM13_YUV_DLY(x) ((x) & 0x07) + +#define OV9640_COM15_OR_00FF 0x00 +#define OV9640_COM15_OR_01FE 0x40 +#define OV9640_COM15_OR_10F0 0xc0 +#define OV9640_COM15_RGB_NORM 0x00 +#define OV9640_COM15_RGB_565 0x10 +#define OV9640_COM15_RGB_555 0x30 + +#define OV9640_COM16_RB_AVG 0x01 + +/* IDs */ +#define OV9640_V2 0x9648 +#define OV9640_V3 0x9649 +#define VERSION(pid, ver) (((pid) << 8) | ((ver) & 0xFF)) + +/* supported resolutions */ +enum { + W_QQCIF = 88, + W_QQVGA = 160, + W_QCIF = 176, + W_QVGA = 320, + W_CIF = 352, + W_VGA = 640, + W_SXGA = 1280 +}; +#define H_SXGA 960 + +/* Misc. structures */ +struct ov9640_reg_alt { + u8 com7; + u8 com12; + u8 com13; + u8 com15; +}; + +struct ov9640_reg { + u8 reg; + u8 val; +}; + +struct ov9640_priv { + struct v4l2_subdev subdev; + + int model; + int revision; + + bool flag_vflip; + bool flag_hflip; +}; + +#endif /* __DRIVERS_MEDIA_VIDEO_OV9640_H__ */ diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index cf16689adba..5ce56f90f31 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h @@ -64,6 +64,7 @@ enum { V4L2_IDENT_OV9650 = 254, V4L2_IDENT_OV9655 = 255, V4L2_IDENT_SOI968 = 256, + V4L2_IDENT_OV9640 = 257, /* module saa7146: reserved range 300-309 */ V4L2_IDENT_SAA7146 = 300, -- cgit v1.2.3-70-g09d2 From aa15c0a347be6d5d16c557ed5b6b72345be48bdd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 26 Sep 2009 13:29:35 -0300 Subject: V4L/DVB (13042): Add NEC protocol to firmware v1.2 handler Currently, dvb_usb_dib0700_ir_proto is supported only with firmwares older than 1.2. Adds support for it also with the newer firmware. This is needed in order to support PixelView SBTVD IR. Cc: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 61 +++++++++++++++++------------ 1 file changed, 37 insertions(+), 24 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 6bd8951ea02..81569deaa19 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -558,8 +558,7 @@ static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event, struct dib0700_rc_response { u8 report_id; u8 data_state; - u8 system_msb; - u8 system_lsb; + u16 system; u8 data; u8 not_data; }; @@ -589,37 +588,51 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event, return 0; } - if (actlen != sizeof(buf)) { - /* We didn't get back the 6 byte message we expected */ - err("Unexpected RC response size [%d]", actlen); - return -1; - } + printk("IR raw %2X %2X %2X %2X %2X %2X (len %d)\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], actlen); - poll_reply.report_id = buf[0]; - poll_reply.data_state = buf[1]; - poll_reply.system_msb = buf[2]; - poll_reply.system_lsb = buf[3]; - poll_reply.data = buf[4]; - poll_reply.not_data = buf[5]; + switch (dvb_usb_dib0700_ir_proto) { + case 0: + poll_reply.report_id = 0; + poll_reply.data_state = 1; + poll_reply.system = buf[2]; + poll_reply.data = buf[4]; + poll_reply.not_data = buf[5]; - /* - info("rid=%02x ds=%02x sm=%02x sl=%02x d=%02x nd=%02x\n", - poll_reply.report_id, poll_reply.data_state, - poll_reply.system_msb, poll_reply.system_lsb, - poll_reply.data, poll_reply.not_data); - */ + /* NEC protocol sends repeat code as 0 0 0 FF */ + if ((poll_reply.system == 0x00) && (poll_reply.data == 0x00) + && (poll_reply.not_data == 0xff)) { + poll_reply.data_state = 2; + break; + } + break; + default: + if (actlen != sizeof(buf)) { + /* We didn't get back the 6 byte message we expected */ + err("Unexpected RC response size [%d]", actlen); + return -1; + } + + poll_reply.report_id = buf[0]; + poll_reply.data_state = buf[1]; + poll_reply.system = (buf[2] << 8) | buf[3]; + poll_reply.data = buf[4]; + poll_reply.not_data = buf[5]; + + break; + } if ((poll_reply.data + poll_reply.not_data) != 0xff) { /* Key failed integrity check */ - err("key failed integrity check: %02x %02x %02x %02x", - poll_reply.system_msb, poll_reply.system_lsb, + err("key failed integrity check: %04x %02x %02x", + poll_reply.system, poll_reply.data, poll_reply.not_data); return -1; } + /* Find the key in the map */ for (i = 0; i < d->props.rc_key_map_size; i++) { - if (rc5_custom(&keymap[i]) == poll_reply.system_lsb && + if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) && rc5_data(&keymap[i]) == poll_reply.data) { *event = keymap[i].event; found = 1; @@ -628,8 +641,8 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event, } if (found == 0) { - err("Unknown remote controller key: %02x %02x %02x %02x", - poll_reply.system_msb, poll_reply.system_lsb, + err("Unknown remote controller key: %04x %02x %02x", + poll_reply.system, poll_reply.data, poll_reply.not_data); d->last_event = 0; return 0; -- cgit v1.2.3-70-g09d2 From 4c5128b30dc079d625bd109a94d5937d14f93ece Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 26 Sep 2009 13:31:31 -0300 Subject: V4L/DVB (13043): Add support for Pixelview SBTVD IR This IR uses NEC protocol. In order to use, dvb_usb_dib0700_ir_proto=0 should be used. Cc: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 81569deaa19..599e03bbb43 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -887,6 +887,37 @@ static struct dvb_usb_rc_key dib0700_rc_keys[] = { { 0x1d37, KEY_RECORD }, { 0x1d3b, KEY_GOTO }, { 0x1d3d, KEY_POWER }, + + /* Key codes for the Pixelview SBTVD remote (proto NEC) */ + { 0x8613, KEY_MUTE }, + { 0x8612, KEY_POWER }, + { 0x8601, KEY_1 }, + { 0x8602, KEY_2 }, + { 0x8603, KEY_3 }, + { 0x8604, KEY_4 }, + { 0x8605, KEY_5 }, + { 0x8606, KEY_6 }, + { 0x8607, KEY_7 }, + { 0x8608, KEY_8 }, + { 0x8609, KEY_9 }, + { 0x8600, KEY_0 }, + { 0x860d, KEY_CHANNELUP }, + { 0x8619, KEY_CHANNELDOWN }, + { 0x8610, KEY_VOLUMEUP }, + { 0x860c, KEY_VOLUMEDOWN }, + + { 0x860a, KEY_CAMERA }, + { 0x860b, KEY_ZOOM }, + { 0x861b, KEY_BACKSPACE }, + { 0x8615, KEY_ENTER }, + + { 0x861d, KEY_UP }, + { 0x861e, KEY_DOWN }, + { 0x860e, KEY_LEFT }, + { 0x860f, KEY_RIGHT }, + + { 0x8618, KEY_RECORD }, + { 0x861a, KEY_STOP }, }; /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */ -- cgit v1.2.3-70-g09d2 From 61b1e58f0e1b9dd0e6ab7199f19b93948af4baa1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 26 Sep 2009 13:45:03 -0300 Subject: V4L/DVB (13044): dib0700: Be less verbose when an IR key is pressed Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 599e03bbb43..bf8e83187cb 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -588,7 +588,6 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event, return 0; } - printk("IR raw %2X %2X %2X %2X %2X %2X (len %d)\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], actlen); switch (dvb_usb_dib0700_ir_proto) { case 0: -- cgit v1.2.3-70-g09d2 From 8171c2059cc4b0507faf3a0e0fdf28cc83d8ac62 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Sat, 19 Sep 2009 08:37:40 -0300 Subject: V4L/DVB (13045): Fix debug messaging for stv0900 demod. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0900_core.c | 58 +++++++++++++++--------------- drivers/media/dvb/frontends/stv0900_priv.h | 2 +- drivers/media/dvb/frontends/stv0900_sw.c | 31 ++++++++-------- 3 files changed, 46 insertions(+), 45 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c index 3bde3324a03..768a1611e8c 100644 --- a/drivers/media/dvb/frontends/stv0900_core.c +++ b/drivers/media/dvb/frontends/stv0900_core.c @@ -34,7 +34,7 @@ #include "stv0900_priv.h" #include "stv0900_init.h" -static int stvdebug = 1; +int stvdebug = 1; module_param_named(debug, stvdebug, int, 0644); /* internal params node */ @@ -146,7 +146,7 @@ void stv0900_write_reg(struct stv0900_internal *i_params, u16 reg_addr, ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1); if (ret != 1) - dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret); + dprintk("%s: i2c error %d\n", __func__, ret); } u8 stv0900_read_reg(struct stv0900_internal *i_params, u16 reg) @@ -170,7 +170,7 @@ u8 stv0900_read_reg(struct stv0900_internal *i_params, u16 reg) ret = i2c_transfer(i_params->i2c_adap, msg, 2); if (ret != 2) - dprintk(KERN_ERR "%s: i2c error %d, reg[0x%02x]\n", + dprintk("%s: i2c error %d, reg[0x%02x]\n", __func__, ret, reg); return buf; @@ -281,7 +281,7 @@ u32 stv0900_get_mclk_freq(struct stv0900_internal *i_params, u32 ext_clk) mclk = (div + 1) * ext_clk / ad_div; - dprintk(KERN_INFO "%s: Calculated Mclk = %d\n", __func__, mclk); + dprintk("%s: Calculated Mclk = %d\n", __func__, mclk); return mclk; } @@ -291,7 +291,7 @@ enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *i_params, u32 mc enum fe_stv0900_error error = STV0900_NO_ERROR; u32 m_div, clk_sel; - dprintk(KERN_INFO "%s: Mclk set to %d, Quartz = %d\n", __func__, mclk, + dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk, i_params->quartz); if (i_params == NULL) @@ -381,7 +381,7 @@ static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params, enum fe_stv0900_clock_type path2_ts) { - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); if (i_params->chip_id >= 0x20) { switch (path1_ts) { @@ -423,7 +423,7 @@ static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params, case STV0900_DVBCI_CLOCK: stv0900_write_reg(i_params, R0900_TSGENERAL, 0x0A); - dprintk(KERN_INFO "%s: 0x0a\n", __func__); + dprintk("%s: 0x0a\n", __func__); break; } break; @@ -469,7 +469,7 @@ static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params, case STV0900_DVBCI_CLOCK: stv0900_write_reg(i_params, R0900_TSGENERAL1X, 0x12); - dprintk(KERN_INFO "%s: 0x12\n", __func__); + dprintk("%s: 0x12\n", __func__); break; } @@ -584,7 +584,7 @@ static s32 stv0900_get_rf_level(struct stv0900_internal *i_params, i, rf_lvl = 0; - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); if ((lookup != NULL) && lookup->size) { switch (demod) { @@ -622,7 +622,7 @@ static s32 stv0900_get_rf_level(struct stv0900_internal *i_params, } - dprintk(KERN_INFO "%s: RFLevel = %d\n", __func__, rf_lvl); + dprintk("%s: RFLevel = %d\n", __func__, rf_lvl); return rf_lvl; } @@ -654,7 +654,7 @@ static s32 stv0900_carr_get_quality(struct dvb_frontend *fe, noise_field1, noise_field0; - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); dmd_reg(lock_flag_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF); @@ -876,7 +876,7 @@ void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params, s32 regflist, i; - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); dmd_reg(regflist, R0900_P1_MODCODLST0, R0900_P2_MODCODLST0); @@ -893,7 +893,7 @@ void stv0900_activate_s2_modcode(struct stv0900_internal *i_params, reg_index, field_index; - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); if (i_params->chip_id <= 0x11) { msleep(5); @@ -979,7 +979,7 @@ void stv0900_activate_s2_modcode_single(struct stv0900_internal *i_params, { u32 reg_index; - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); switch (demod) { case STV0900_DEMOD_1: @@ -1012,7 +1012,7 @@ static enum dvbfe_algo stv0900_frontend_algo(struct dvb_frontend *fe) static int stb0900_set_property(struct dvb_frontend *fe, struct dtv_property *tvp) { - dprintk(KERN_INFO "%s(..)\n", __func__); + dprintk("%s(..)\n", __func__); return 0; } @@ -1020,7 +1020,7 @@ static int stb0900_set_property(struct dvb_frontend *fe, static int stb0900_get_property(struct dvb_frontend *fe, struct dtv_property *tvp) { - dprintk(KERN_INFO "%s(..)\n", __func__); + dprintk("%s(..)\n", __func__); return 0; } @@ -1191,7 +1191,7 @@ u8 stv0900_get_optim_carr_loop(s32 srate, enum fe_stv0900_modcode modcode, s32 i; const struct stv0900_car_loop_optim *car_loop_s2; - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); if (chip_id <= 0x12) car_loop_s2 = FE_STV0900_S2CarLoop; @@ -1294,7 +1294,7 @@ u8 stv0900_get_optim_short_carr_loop(s32 srate, enum fe_stv0900_modulation modul u8 aclc_value = 0x0b; - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); switch (modulation) { case STV0900_QPSK: @@ -1351,7 +1351,7 @@ static enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *i_ { enum fe_stv0900_error error = STV0900_NO_ERROR; - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); switch (LDPC_Mode) { case STV0900_DUAL: @@ -1398,12 +1398,12 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe, struct stv0900_inode *temp_int = find_inode(state->i2c_adap, state->config->demod_address); - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); if (temp_int != NULL) { state->internal = temp_int->internal; (state->internal->dmds_used)++; - dprintk(KERN_INFO "%s: Find Internal Structure!\n", __func__); + dprintk("%s: Find Internal Structure!\n", __func__); return STV0900_NO_ERROR; } else { state->internal = kmalloc(sizeof(struct stv0900_internal), GFP_KERNEL); @@ -1413,7 +1413,7 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe, state->internal->i2c_addr = state->config->demod_address; state->internal->clkmode = state->config->clkmode; state->internal->errs = STV0900_NO_ERROR; - dprintk(KERN_INFO "%s: Create New Internal Structure!\n", __func__); + dprintk("%s: Create New Internal Structure!\n", __func__); } if (state->internal != NULL) { @@ -1551,7 +1551,7 @@ static enum dvbfe_search stv0900_search(struct dvb_frontend *fe, enum fe_stv0900_error error = STV0900_NO_ERROR; - dprintk(KERN_INFO "%s: ", __func__); + dprintk("%s: ", __func__); p_result.locked = FALSE; p_search.path = state->demod; @@ -1652,10 +1652,10 @@ static enum dvbfe_search stv0900_search(struct dvb_frontend *fe, error = STV0900_BAD_PARAMETER; if ((p_result.locked == TRUE) && (error == STV0900_NO_ERROR)) { - dprintk(KERN_INFO "Search Success\n"); + dprintk("Search Success\n"); return DVBFE_ALGO_SEARCH_SUCCESS; } else { - dprintk(KERN_INFO "Search Fail\n"); + dprintk("Search Fail\n"); return DVBFE_ALGO_SEARCH_FAILED; } @@ -1723,7 +1723,7 @@ static int stv0900_diseqc_init(struct dvb_frontend *fe) static int stv0900_init(struct dvb_frontend *fe) { - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); stv0900_stop_ts(fe, 1); stv0900_diseqc_init(fe); @@ -1865,7 +1865,7 @@ static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) enum fe_stv0900_demod_num demod = state->demod; s32 mode_field, reset_field; - dprintk(KERN_INFO "%s: %s\n", __func__, ((tone == 0) ? "Off" : "On")); + dprintk("%s: %s\n", __func__, ((tone == 0) ? "Off" : "On")); dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE); dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET); @@ -1889,11 +1889,11 @@ static void stv0900_release(struct dvb_frontend *fe) { struct stv0900_state *state = fe->demodulator_priv; - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); if ((--(state->internal->dmds_used)) <= 0) { - dprintk(KERN_INFO "%s: Actually removing\n", __func__); + dprintk("%s: Actually removing\n", __func__); remove_inode(state->internal); kfree(state->internal); diff --git a/drivers/media/dvb/frontends/stv0900_priv.h b/drivers/media/dvb/frontends/stv0900_priv.h index 5ed7a145c7d..5f4414f8da2 100644 --- a/drivers/media/dvb/frontends/stv0900_priv.h +++ b/drivers/media/dvb/frontends/stv0900_priv.h @@ -60,7 +60,7 @@ } \ } while (0) -static int stvdebug; +extern int stvdebug; #define dprintk(args...) \ do { \ diff --git a/drivers/media/dvb/frontends/stv0900_sw.c b/drivers/media/dvb/frontends/stv0900_sw.c index 962fde1437c..8c83c8b306a 100644 --- a/drivers/media/dvb/frontends/stv0900_sw.c +++ b/drivers/media/dvb/frontends/stv0900_sw.c @@ -527,7 +527,7 @@ static void stv0900_set_symbol_rate(struct stv0900_internal *i_params, s32 sfr_init_reg; u32 symb; - dprintk(KERN_INFO "%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk, + dprintk("%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk, srate, demod); dmd_reg(sfr_init_reg, R0900_P1_SFRINIT1, R0900_P2_SFRINIT1); @@ -952,7 +952,7 @@ static void stv0900_set_viterbi_tracq(struct stv0900_internal *i_params, s32 vth_reg; - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12); @@ -973,7 +973,7 @@ static void stv0900_set_viterbi_standard(struct stv0900_internal *i_params, s32 fecmReg, prvitReg; - dprintk(KERN_INFO "%s: ViterbiStandard = ", __func__); + dprintk("%s: ViterbiStandard = ", __func__); switch (demod) { case STV0900_DEMOD_1: @@ -1055,7 +1055,7 @@ static void stv0900_track_optimization(struct dvb_frontend *fe) enum fe_stv0900_rolloff rolloff; enum fe_stv0900_modcode foundModcod; - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); srate += stv0900_get_timing_offst(i_params, srate, demod); @@ -1370,7 +1370,7 @@ static int stv0900_get_fec_lock(struct stv0900_internal *i_params, enum fe_stv09 enum fe_stv0900_search_state dmd_state; - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); dmd_reg(pktdelin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK); @@ -1414,7 +1414,7 @@ static int stv0900_wait_for_lock(struct stv0900_internal *i_params, s32 timer = 0, lock = 0, str_merg_rst_fld, str_merg_lock_fld; - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); dmd_reg(str_merg_rst_fld, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE); dmd_reg(str_merg_lock_fld, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK); @@ -1427,7 +1427,8 @@ static int stv0900_wait_for_lock(struct stv0900_internal *i_params, if (lock) { lock = 0; - dprintk(KERN_INFO "%s: Timer = %d, time_out = %d\n", __func__, timer, fec_timeout); + dprintk("%s: Timer = %d, time_out = %d\n", __func__, timer, + fec_timeout); while ((timer < fec_timeout) && (lock == 0)) { lock = stv0900_get_bits(i_params, str_merg_lock_fld); @@ -1437,9 +1438,9 @@ static int stv0900_wait_for_lock(struct stv0900_internal *i_params, } if (lock) - dprintk(KERN_INFO "%s: DEMOD LOCK OK\n", __func__); + dprintk("%s: DEMOD LOCK OK\n", __func__); else - dprintk(KERN_INFO "%s: DEMOD LOCK FAIL\n", __func__); + dprintk("%s: DEMOD LOCK FAIL\n", __func__); if (lock) return TRUE; @@ -1456,7 +1457,7 @@ enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe, s32 state_field, dss_dvb_field; - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); dmd_reg(state_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); dmd_reg(dss_dvb_field, F0900_P1_DSS_DVB, F0900_P2_DSS_DVB); @@ -1820,7 +1821,7 @@ static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *i_params, s32 i, j, nb_steps, direction; - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); switch (demod) { case STV0900_DEMOD_1: @@ -2274,7 +2275,7 @@ static int stv0900_blind_search_algo(struct dvb_frontend *fe) u16 agc2_integr; u8 dstatus2; - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); if (i_params->chip_id < 0x20) { k_ref_tmg_max = 233; @@ -2397,7 +2398,7 @@ static void stv0900_set_viterbi_acq(struct stv0900_internal *i_params, { s32 vth_reg; - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12); @@ -2415,7 +2416,7 @@ static void stv0900_set_search_standard(struct stv0900_internal *i_params, int sstndrd; - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); sstndrd = i_params->dmd1_srch_standard; if (demod == 1) @@ -2578,7 +2579,7 @@ enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe) enum fe_stv0900_search_algo algo; int no_signal = FALSE; - dprintk(KERN_INFO "%s\n", __func__); + dprintk("%s\n", __func__); switch (demod) { case STV0900_DEMOD_1: -- cgit v1.2.3-70-g09d2 From f8731f4ddedb78693ae05e40aac5c4817f740518 Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Fri, 18 Sep 2009 04:08:43 -0300 Subject: V4L/DVB (13049): dib8000: SNR in 10th of dB dib7000p/dib8000: added pid filtering dib8000: the SNR is in 10th of dB (not in dB) dib7000p and dib8000: added the pid filtering. This feature is enabled by module option (dvb-usb module). Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 71 +++++++++++++++++++++++++++++ drivers/media/dvb/frontends/dib7000p.c | 18 ++++++++ drivers/media/dvb/frontends/dib7000p.h | 13 ++++++ drivers/media/dvb/frontends/dib8000.c | 21 ++++++++- drivers/media/dvb/frontends/dib8000.h | 14 ++++++ 5 files changed, 136 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index bf8e83187cb..cda60291c06 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1252,6 +1252,16 @@ static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap) return 0; } +static int stk70x0p_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) +{ + return dib7000p_pid_filter(adapter->fe, index, pid, onoff); +} + +static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) +{ + return dib7000p_pid_filter_ctrl(adapter->fe, onoff); +} + static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = { 60000, 15000, // internal, sampling 1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass @@ -1543,6 +1553,15 @@ static int dib807x_tuner_attach(struct dvb_usb_adapter *adap) return 0; } +static int stk807x_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) +{ + return dib8000_pid_filter(adapter->fe, index, pid, onoff); +} + +static int stk807x_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) +{ + return dib8000_pid_filter_ctrl(adapter->fe, onoff); +} /* STK807x */ static int stk807x_frontend_attach(struct dvb_usb_adapter *adap) @@ -1938,6 +1957,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, .frontend_attach = stk7700p_frontend_attach, .tuner_attach = stk7700p_tuner_attach, @@ -2019,11 +2042,19 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 2, .adapter = { { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, .frontend_attach = stk7700d_frontend_attach, .tuner_attach = stk7700d_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }, { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, .frontend_attach = stk7700d_frontend_attach, .tuner_attach = stk7700d_tuner_attach, @@ -2066,6 +2097,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, .frontend_attach = stk7700P2_frontend_attach, .tuner_attach = stk7700d_tuner_attach, @@ -2098,6 +2133,14 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, .frontend_attach = stk7070p_frontend_attach, .tuner_attach = dib7070p_tuner_attach, @@ -2200,6 +2243,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 2, .adapter = { { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, .frontend_attach = stk7070pd_frontend_attach0, .tuner_attach = dib7070p_tuner_attach, @@ -2207,6 +2254,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { .size_of_priv = sizeof(struct dib0700_adapter_state), }, { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, .frontend_attach = stk7070pd_frontend_attach1, .tuner_attach = dib7070p_tuner_attach, @@ -2253,6 +2304,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, .frontend_attach = stk7700ph_frontend_attach, .tuner_attach = stk7700ph_tuner_attach, @@ -2365,6 +2420,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, .frontend_attach = stk7070p_frontend_attach, .tuner_attach = dib7770p_tuner_attach, @@ -2396,6 +2455,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk807x_pid_filter, + .pid_filter_ctrl = stk807x_pid_filter_ctrl, .frontend_attach = stk807x_frontend_attach, .tuner_attach = dib807x_tuner_attach, @@ -2427,6 +2490,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 2, .adapter = { { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk807x_pid_filter, + .pid_filter_ctrl = stk807x_pid_filter_ctrl, .frontend_attach = stk807xpvr_frontend_attach0, .tuner_attach = dib807x_tuner_attach, @@ -2436,6 +2503,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { sizeof(struct dib0700_adapter_state), }, { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk807x_pid_filter, + .pid_filter_ctrl = stk807x_pid_filter_ctrl, .frontend_attach = stk807xpvr_frontend_attach1, .tuner_attach = dib807x_tuner_attach, diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index 0781f94e05d..60e1aaaec5b 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c @@ -1302,6 +1302,24 @@ struct i2c_adapter * dib7000p_get_i2c_master(struct dvb_frontend *demod, enum di } EXPORT_SYMBOL(dib7000p_get_i2c_master); +int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) +{ + struct dib7000p_state *state = fe->demodulator_priv; + u16 val = dib7000p_read_word(state, 235) & 0xffef; + val |= (onoff & 0x1) << 4; + dprintk("PID filter enabled %d", onoff); + return dib7000p_write_word(state, 235, val); +} +EXPORT_SYMBOL(dib7000p_pid_filter_ctrl); + +int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) +{ + struct dib7000p_state *state = fe->demodulator_priv; + dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff); + return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0); +} +EXPORT_SYMBOL(dib7000p_pid_filter); + int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]) { struct dib7000p_state st = { .i2c_adap = i2c }; diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h index 02a4c82f0c7..3a769df3c86 100644 --- a/drivers/media/dvb/frontends/dib7000p.h +++ b/drivers/media/dvb/frontends/dib7000p.h @@ -51,6 +51,8 @@ extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value); extern int dib7000pc_detection(struct i2c_adapter *i2c_adap); +extern int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff); +extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff); #else static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, @@ -95,6 +97,17 @@ static inline int dib7000pc_detection(struct i2c_adapter *i2c_adap) printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; } +static inline int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} + +static inline int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, uint8_t onoff) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} #endif #endif diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c index 852c790d09d..44c2dc9b4f1 100644 --- a/drivers/media/dvb/frontends/dib8000.c +++ b/drivers/media/dvb/frontends/dib8000.c @@ -2121,7 +2121,7 @@ static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr) else result -= intlog10(2) * 10 * noise_exp - 100; - *snr = result / (1 << 24); + *snr = result / ((1 << 24) / 10); return 0; } @@ -2195,6 +2195,25 @@ struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000 EXPORT_SYMBOL(dib8000_get_i2c_master); +int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) +{ + struct dib8000_state *st = fe->demodulator_priv; + u16 val = dib8000_read_word(st, 299) & 0xffef; + val |= (onoff & 0x1) << 4; + + dprintk("pid filter enabled %d", onoff); + return dib8000_write_word(st, 299, val); +} +EXPORT_SYMBOL(dib8000_pid_filter_ctrl); + +int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) +{ + struct dib8000_state *st = fe->demodulator_priv; + dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff); + return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0); +} +EXPORT_SYMBOL(dib8000_pid_filter); + static const struct dvb_frontend_ops dib8000_ops = { .info = { .name = "DiBcom 8000 ISDB-T", diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h index a86de340dd5..8c89482b738 100644 --- a/drivers/media/dvb/frontends/dib8000.h +++ b/drivers/media/dvb/frontends/dib8000.h @@ -44,6 +44,8 @@ extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value); +extern int dib8000_pid_filter_ctrl(struct dvb_frontend *, u8 onoff); +extern int dib8000_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff); #else static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg) { @@ -74,6 +76,18 @@ int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value) printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; } + +int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} + +int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} #endif #endif -- cgit v1.2.3-70-g09d2 From eac1fe1050f223d28ebe5bb73b438d82ffd5b675 Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Wed, 23 Sep 2009 13:41:27 -0300 Subject: V4L/DVB (13051): DiB7000P: improve rebostness of HAS_LOCK indicator Update the dib7000p: The status is HAS_LOCK only if the demod is able to decode the TPS. Sometimes, there is a TPS data lock, even if the demod is not able to decode it (ex: no RF signal). For the STK7770P: correct value for the charge pump Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 1 + drivers/media/dvb/frontends/dib7000p.c | 15 ++++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index cda60291c06..3b7e07749c3 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1176,6 +1176,7 @@ static struct dib0070_config dib7770p_dib0070_config = { .clock_khz = 12000, .clock_pad_drive = 0, .flip_chip = 1, + .charge_pump = 2, }; static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index 60e1aaaec5b..750ae61a20f 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c @@ -108,7 +108,7 @@ static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode) outreg = 0; fifo_threshold = 1792; - smo_mode = (dib7000p_read_word(state, 235) & 0x0010) | (1 << 1); + smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1); dprintk( "setting output mode for demod %p to %d", &state->demod, mode); @@ -162,18 +162,19 @@ static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff) if (state->div_force_off) { dprintk( "diversity combination deactivated - forced by COFDM parameters"); onoff = 0; - } + dib7000p_write_word(state, 207, 0); + } else + dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0)); + state->div_state = (u8)onoff; if (onoff) { dib7000p_write_word(state, 204, 6); dib7000p_write_word(state, 205, 16); /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */ - dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0)); } else { dib7000p_write_word(state, 204, 1); dib7000p_write_word(state, 205, 0); - dib7000p_write_word(state, 207, 0); } return 0; @@ -1188,7 +1189,7 @@ static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t *stat) *stat |= FE_HAS_VITERBI; if (lock & 0x0010) *stat |= FE_HAS_SYNC; - if (lock & 0x0008) + if ((lock & 0x0038) == 0x38) *stat |= FE_HAS_LOCK; return 0; @@ -1332,8 +1333,10 @@ int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau /* designated i2c address */ new_addr = (0x40 + k) << 1; st.i2c_addr = new_addr; + dib7000p_write_word(&st, 1287, 0x0003); /* sram lead in, rdy */ if (dib7000p_identify(&st) != 0) { st.i2c_addr = default_addr; + dib7000p_write_word(&st, 1287, 0x0003); /* sram lead in, rdy */ if (dib7000p_identify(&st) != 0) { dprintk("DiB7000P #%d: not identified\n", k); return -EIO; @@ -1390,6 +1393,8 @@ struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, demod->demodulator_priv = st; memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops)); + dib7000p_write_word(st, 1287, 0x0003); /* sram lead in, rdy */ + if (dib7000p_identify(st) != 0) goto error; -- cgit v1.2.3-70-g09d2 From 8a378e8543f044b3e54ddbbb03c349bf054fcedf Mon Sep 17 00:00:00 2001 From: S?rgio Fortier Date: Mon, 28 Sep 2009 04:19:21 -0300 Subject: V4L/DVB (13052): DiB0700: EvolutePC TvWay+ USB ISDB-Tb fullseg device support Patch for EvolutePC TvWay+ USB ISDB-Tb fullseg device support. Signed-off-by: S?rgio C Fortier Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 7 ++++++- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 3b7e07749c3..1ec1a4cb047 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1924,6 +1924,7 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) }, { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) }, { USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) }, + { USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -2470,7 +2471,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .num_device_descs = 2, + .num_device_descs = 3, .devices = { { "DiBcom STK807xP reference design", { &dib0700_usb_id_table[62], NULL }, @@ -2480,6 +2481,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[63], NULL }, { NULL }, }, + { "EvolutePC TVWay+", + { &dib0700_usb_id_table[64], NULL }, + { NULL }, + }, }, .rc_interval = DEFAULT_RC_INTERVAL, diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index a548c14c194..e852eac8cb5 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -61,6 +61,7 @@ #define USB_VID_XTENSIONS 0x1ae7 #define USB_VID_HUMAX_COEX 0x10b9 #define USB_VID_774 0x7a69 +#define USB_VID_EVOLUTEPC 0x1e59 /* Product IDs */ #define USB_PID_ADSTECH_USB2_COLD 0xa333 @@ -276,5 +277,6 @@ #define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000 #define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM 0x5001 #define USB_PID_FRIIO_WHITE 0x0001 +#define USB_PID_TVWAY_PLUS 0x0002 #endif -- cgit v1.2.3-70-g09d2 From 486ba12b7ae1edd5549494ae1cbfaa4794d1af5a Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Fri, 18 Sep 2009 13:37:57 -0300 Subject: V4L/DVB (13054): af9015: add USB ID for KWorld PlusTV DVB-T PCI Pro Card (DVB-T PC160-T) Add USB ID 1b80:c161 for KWorld PlusTV DVB-T PCI Pro Card (DVB-T PC160-T). Thanks to Andrew Cruickshank for reporting this. Cc: Andrew Cruickshank Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/af9015.c | 9 ++++++++- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index cf042b309b4..ac21c1a8075 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -1283,6 +1283,7 @@ static struct usb_device_id af9015_usb_table[] = { {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)}, {USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)}, /* 25 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)}, + {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)}, {0}, }; MODULE_DEVICE_TABLE(usb, af9015_usb_table); @@ -1554,7 +1555,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { .i2c_algo = &af9015_i2c_algo, - .num_device_descs = 4, /* max 9 */ + .num_device_descs = 5, /* max 9 */ .devices = { { .name = "AverMedia AVerTV Volar GPS 805 (A805)", @@ -1577,6 +1578,12 @@ static struct dvb_usb_device_properties af9015_properties[] = { .cold_ids = {&af9015_usb_table[24], NULL}, .warm_ids = {NULL}, }, + { + .name = "KWorld PlusTV DVB-T PCI Pro Card " \ + "(DVB-T PC160-T)", + .cold_ids = {&af9015_usb_table[26], NULL}, + .warm_ids = {NULL}, + }, } }, }; diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index e852eac8cb5..128fca63df9 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -116,6 +116,7 @@ #define USB_PID_KWORLD_395U_3 0xe395 #define USB_PID_KWORLD_MC810 0xc810 #define USB_PID_KWORLD_PC160_2T 0xc160 +#define USB_PID_KWORLD_PC160_T 0xc161 #define USB_PID_KWORLD_VSTREAM_COLD 0x17de #define USB_PID_KWORLD_VSTREAM_WARM 0x17df #define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055 -- cgit v1.2.3-70-g09d2 From 0254294f378cd4c50de550ce0a32c70aba668f17 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 16 Sep 2009 20:33:03 -0300 Subject: V4L/DVB (13055): af9015: fix few typos Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/af9015.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index ac21c1a8075..7a885264e86 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -1297,7 +1297,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { .firmware = "dvb-usb-af9015.fw", .no_reconnect = 1, - .size_of_priv = sizeof(struct af9015_state), \ + .size_of_priv = sizeof(struct af9015_state), .num_adapters = 2, .adapter = { @@ -1403,7 +1403,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { .firmware = "dvb-usb-af9015.fw", .no_reconnect = 1, - .size_of_priv = sizeof(struct af9015_state), \ + .size_of_priv = sizeof(struct af9015_state), .num_adapters = 2, .adapter = { @@ -1509,7 +1509,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { .firmware = "dvb-usb-af9015.fw", .no_reconnect = 1, - .size_of_priv = sizeof(struct af9015_state), \ + .size_of_priv = sizeof(struct af9015_state), .num_adapters = 2, .adapter = { -- cgit v1.2.3-70-g09d2 From 641342dde7f9cbfcc6b9f6c890c90f99edcae6ca Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 21 Sep 2009 18:56:12 -0300 Subject: V4L/DVB (13056): af9015: add LeadTek Y04G0051 remote buttons Add missing LeadTek Y04G0051 remote buttons. Thanks to Matthew Skinner Cc: Matthew Skinner Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/af9015.h | 143 +++++++++++++++++++++++-------------- 1 file changed, 88 insertions(+), 55 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h index c41f30e4a1b..c1e2b7d1d41 100644 --- a/drivers/media/dvb/dvb-usb/af9015.h +++ b/drivers/media/dvb/dvb-usb/af9015.h @@ -119,6 +119,7 @@ enum af9015_remote { /* 5 */ AF9015_REMOTE_AVERMEDIA_KS, }; +/* LeadTek - Y04G0051 */ /* Leadtek WinFast DTV Dongle Gold */ static struct dvb_usb_rc_key af9015_rc_keys_leadtek[] = { { 0x001e, KEY_1 }, @@ -131,64 +132,96 @@ static struct dvb_usb_rc_key af9015_rc_keys_leadtek[] = { { 0x0025, KEY_8 }, { 0x0026, KEY_9 }, { 0x0027, KEY_0 }, - { 0x0028, KEY_ENTER }, - { 0x004f, KEY_VOLUMEUP }, - { 0x0050, KEY_VOLUMEDOWN }, - { 0x0051, KEY_CHANNELDOWN }, - { 0x0052, KEY_CHANNELUP }, + { 0x0028, KEY_OK }, + { 0x004f, KEY_RIGHT }, + { 0x0050, KEY_LEFT }, + { 0x0051, KEY_DOWN }, + { 0x0052, KEY_UP }, + { 0x011a, KEY_POWER2 }, + { 0x04b4, KEY_TV }, + { 0x04b3, KEY_RED }, + { 0x04b2, KEY_GREEN }, + { 0x04b1, KEY_YELLOW }, + { 0x04b0, KEY_BLUE }, + { 0x003d, KEY_TEXT }, + { 0x0113, KEY_SLEEP }, + { 0x0010, KEY_MUTE }, + { 0x0105, KEY_ESC }, + { 0x0009, KEY_SCREEN }, + { 0x010f, KEY_MENU }, + { 0x003f, KEY_CHANNEL }, + { 0x0013, KEY_REWIND }, + { 0x0012, KEY_PLAY }, + { 0x0011, KEY_FASTFORWARD }, + { 0x0005, KEY_PREVIOUS }, + { 0x0029, KEY_STOP }, + { 0x002b, KEY_NEXT }, + { 0x0041, KEY_EPG }, + { 0x0019, KEY_VIDEO }, + { 0x0016, KEY_AUDIO }, + { 0x0037, KEY_DOT }, + { 0x002a, KEY_AGAIN }, + { 0x002c, KEY_CAMERA }, + { 0x003c, KEY_NEW }, + { 0x0115, KEY_RECORD }, + { 0x010b, KEY_TIME }, + { 0x0043, KEY_VOLUMEUP }, + { 0x0042, KEY_VOLUMEDOWN }, + { 0x004b, KEY_CHANNELUP }, + { 0x004e, KEY_CHANNELDOWN }, }; static u8 af9015_ir_table_leadtek[] = { - 0x03, 0xfc, 0x00, 0xff, 0x1a, 0x01, 0x00, - 0x03, 0xfc, 0x56, 0xa9, 0x00, 0x00, 0x00, - 0x03, 0xfc, 0x4b, 0xb4, 0x00, 0x00, 0x00, - 0x03, 0xfc, 0x4c, 0xb3, 0xb2, 0x04, 0x00, - 0x03, 0xfc, 0x4d, 0xb2, 0x00, 0x00, 0x00, - 0x03, 0xfc, 0x4e, 0xb1, 0x00, 0x00, 0x00, - 0x03, 0xfc, 0x1f, 0xe0, 0x3d, 0x00, 0x00, - 0x03, 0xfc, 0x40, 0xbf, 0x13, 0x01, 0x00, - 0x03, 0xfc, 0x14, 0xeb, 0x10, 0x00, 0x00, - 0x03, 0xfc, 0x49, 0xb6, 0x05, 0x01, 0x00, - 0x03, 0xfc, 0x50, 0xaf, 0x29, 0x00, 0x00, - 0x03, 0xfc, 0x0c, 0xf3, 0x52, 0x00, 0x00, - 0x03, 0xfc, 0x03, 0xfc, 0x09, 0x00, 0x00, - 0x03, 0xfc, 0x08, 0xf7, 0x50, 0x00, 0x00, - 0x03, 0xfc, 0x13, 0xec, 0x28, 0x00, 0x00, - 0x03, 0xfc, 0x04, 0xfb, 0x4f, 0x00, 0x00, - 0x03, 0xfc, 0x4f, 0xb0, 0x0f, 0x01, 0x00, - 0x03, 0xfc, 0x10, 0xef, 0x51, 0x00, 0x00, - 0x03, 0xfc, 0x51, 0xae, 0x3f, 0x00, 0x00, - 0x03, 0xfc, 0x42, 0xbd, 0x13, 0x00, 0x00, - 0x03, 0xfc, 0x43, 0xbc, 0x00, 0x00, 0x00, - 0x03, 0xfc, 0x44, 0xbb, 0x11, 0x00, 0x00, - 0x03, 0xfc, 0x52, 0xad, 0x19, 0x00, 0x00, - 0x03, 0xfc, 0x54, 0xab, 0x05, 0x00, 0x00, - 0x03, 0xfc, 0x46, 0xb9, 0x29, 0x00, 0x00, - 0x03, 0xfc, 0x55, 0xaa, 0x2b, 0x00, 0x00, - 0x03, 0xfc, 0x53, 0xac, 0x41, 0x00, 0x00, - 0x03, 0xfc, 0x05, 0xfa, 0x1e, 0x00, 0x00, - 0x03, 0xfc, 0x06, 0xf9, 0x1f, 0x00, 0x00, - 0x03, 0xfc, 0x07, 0xf8, 0x20, 0x00, 0x00, - 0x03, 0xfc, 0x1e, 0xe1, 0x19, 0x00, 0x00, - 0x03, 0xfc, 0x09, 0xf6, 0x21, 0x00, 0x00, - 0x03, 0xfc, 0x0a, 0xf5, 0x22, 0x00, 0x00, - 0x03, 0xfc, 0x0b, 0xf4, 0x23, 0x00, 0x00, - 0x03, 0xfc, 0x1b, 0xe4, 0x16, 0x00, 0x00, - 0x03, 0xfc, 0x0d, 0xf2, 0x24, 0x00, 0x00, - 0x03, 0xfc, 0x0e, 0xf1, 0x25, 0x00, 0x00, - 0x03, 0xfc, 0x0f, 0xf0, 0x26, 0x00, 0x00, - 0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00, - 0x03, 0xfc, 0x41, 0xbe, 0x37, 0x00, 0x00, - 0x03, 0xfc, 0x12, 0xed, 0x27, 0x00, 0x00, - 0x03, 0xfc, 0x11, 0xee, 0x2a, 0x00, 0x00, - 0x03, 0xfc, 0x48, 0xb7, 0x2c, 0x00, 0x00, - 0x03, 0xfc, 0x4a, 0xb5, 0x3c, 0x00, 0x00, - 0x03, 0xfc, 0x47, 0xb8, 0x15, 0x01, 0x00, - 0x03, 0xfc, 0x45, 0xba, 0x0b, 0x01, 0x00, - 0x03, 0xfc, 0x5e, 0xa1, 0x43, 0x00, 0x00, - 0x03, 0xfc, 0x5a, 0xa5, 0x42, 0x00, 0x00, - 0x03, 0xfc, 0x5b, 0xa4, 0x4b, 0x00, 0x00, - 0x03, 0xfc, 0x5f, 0xa0, 0x4e, 0x00, 0x00, + 0x03, 0xfc, 0x00, 0xff, 0x1a, 0x01, 0x00, /* KEY_POWER2 */ + 0x03, 0xfc, 0x56, 0xa9, 0xb4, 0x04, 0x00, /* KEY_TV */ + 0x03, 0xfc, 0x4b, 0xb4, 0xb3, 0x04, 0x00, /* KEY_RED */ + 0x03, 0xfc, 0x4c, 0xb3, 0xb2, 0x04, 0x00, /* KEY_GREEN */ + 0x03, 0xfc, 0x4d, 0xb2, 0xb1, 0x04, 0x00, /* KEY_YELLOW */ + 0x03, 0xfc, 0x4e, 0xb1, 0xb0, 0x04, 0x00, /* KEY_BLUE */ + 0x03, 0xfc, 0x1f, 0xe0, 0x3d, 0x00, 0x00, /* KEY_TEXT */ + 0x03, 0xfc, 0x40, 0xbf, 0x13, 0x01, 0x00, /* KEY_SLEEP */ + 0x03, 0xfc, 0x14, 0xeb, 0x10, 0x00, 0x00, /* KEY_MUTE */ + 0x03, 0xfc, 0x49, 0xb6, 0x05, 0x01, 0x00, /* KEY_ESC */ + 0x03, 0xfc, 0x50, 0xaf, 0x29, 0x00, 0x00, /* KEY_STOP (1)*/ + 0x03, 0xfc, 0x0c, 0xf3, 0x52, 0x00, 0x00, /* KEY_UP */ + 0x03, 0xfc, 0x03, 0xfc, 0x09, 0x00, 0x00, /* KEY_SCREEN */ + 0x03, 0xfc, 0x08, 0xf7, 0x50, 0x00, 0x00, /* KEY_LEFT */ + 0x03, 0xfc, 0x13, 0xec, 0x28, 0x00, 0x00, /* KEY_OK (1) */ + 0x03, 0xfc, 0x04, 0xfb, 0x4f, 0x00, 0x00, /* KEY_RIGHT */ + 0x03, 0xfc, 0x4f, 0xb0, 0x0f, 0x01, 0x00, /* KEY_MENU */ + 0x03, 0xfc, 0x10, 0xef, 0x51, 0x00, 0x00, /* KEY_DOWN */ + 0x03, 0xfc, 0x51, 0xae, 0x3f, 0x00, 0x00, /* KEY_CHANNEL */ + 0x03, 0xfc, 0x42, 0xbd, 0x13, 0x00, 0x00, /* KEY_REWIND */ + 0x03, 0xfc, 0x43, 0xbc, 0x12, 0x00, 0x00, /* KEY_PLAY */ + 0x03, 0xfc, 0x44, 0xbb, 0x11, 0x00, 0x00, /* KEY_FASTFORWARD */ + 0x03, 0xfc, 0x52, 0xad, 0x19, 0x00, 0x00, /* KEY_VIDEO (1) */ + 0x03, 0xfc, 0x54, 0xab, 0x05, 0x00, 0x00, /* KEY_PREVIOUS */ + 0x03, 0xfc, 0x46, 0xb9, 0x29, 0x00, 0x00, /* KEY_STOP (2) */ + 0x03, 0xfc, 0x55, 0xaa, 0x2b, 0x00, 0x00, /* KEY_NEXT */ + 0x03, 0xfc, 0x53, 0xac, 0x41, 0x00, 0x00, /* KEY_EPG */ + 0x03, 0xfc, 0x05, 0xfa, 0x1e, 0x00, 0x00, /* KEY_1 */ + 0x03, 0xfc, 0x06, 0xf9, 0x1f, 0x00, 0x00, /* KEY_2 */ + 0x03, 0xfc, 0x07, 0xf8, 0x20, 0x00, 0x00, /* KEY_3 */ + 0x03, 0xfc, 0x1e, 0xe1, 0x19, 0x00, 0x00, /* KEY_VIDEO (2) */ + 0x03, 0xfc, 0x09, 0xf6, 0x21, 0x00, 0x00, /* KEY_4 */ + 0x03, 0xfc, 0x0a, 0xf5, 0x22, 0x00, 0x00, /* KEY_5 */ + 0x03, 0xfc, 0x0b, 0xf4, 0x23, 0x00, 0x00, /* KEY_6 */ + 0x03, 0xfc, 0x1b, 0xe4, 0x16, 0x00, 0x00, /* KEY_AUDIO */ + 0x03, 0xfc, 0x0d, 0xf2, 0x24, 0x00, 0x00, /* KEY_7 */ + 0x03, 0xfc, 0x0e, 0xf1, 0x25, 0x00, 0x00, /* KEY_8 */ + 0x03, 0xfc, 0x0f, 0xf0, 0x26, 0x00, 0x00, /* KEY_9 */ + 0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00, /* KEY_OK (2) */ + 0x03, 0xfc, 0x41, 0xbe, 0x37, 0x00, 0x00, /* KEY_DOT */ + 0x03, 0xfc, 0x12, 0xed, 0x27, 0x00, 0x00, /* KEY_0 */ + 0x03, 0xfc, 0x11, 0xee, 0x2a, 0x00, 0x00, /* KEY_AGAIN */ + 0x03, 0xfc, 0x48, 0xb7, 0x2c, 0x00, 0x00, /* KEY_CAMERA */ + 0x03, 0xfc, 0x4a, 0xb5, 0x3c, 0x00, 0x00, /* KEY_NEW */ + 0x03, 0xfc, 0x47, 0xb8, 0x15, 0x01, 0x00, /* KEY_RECORD */ + 0x03, 0xfc, 0x45, 0xba, 0x0b, 0x01, 0x00, /* KEY_TIME */ + 0x03, 0xfc, 0x5e, 0xa1, 0x43, 0x00, 0x00, /* KEY_VOLUMEUP */ + 0x03, 0xfc, 0x5a, 0xa5, 0x42, 0x00, 0x00, /* KEY_VOLUMEDOWN */ + 0x03, 0xfc, 0x5b, 0xa4, 0x4b, 0x00, 0x00, /* KEY_CHANNELUP */ + 0x03, 0xfc, 0x5f, 0xa0, 0x4e, 0x00, 0x00, /* KEY_CHANNELDOWN */ }; /* TwinHan AzureWave AD-TU700(704J) */ -- cgit v1.2.3-70-g09d2 From e1a7ff84a4c26893ffca19c1c35d008caa89bfde Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 21 Sep 2009 20:52:44 -0300 Subject: V4L/DVB (13057): af9015: add MSI DIGIVOX mini III remote Support for MSI DIGIVOX mini III remote. Thanks to Aleksandr V. Piskunov Thanks to Roman Cc: Aleksandr V. Piskunov Cc: Roman Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/af9015.c | 10 ++++++ drivers/media/dvb/dvb-usb/af9015.h | 71 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 7a885264e86..5c898b07ae1 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -868,6 +868,16 @@ static int af9015_read_config(struct usb_device *udev) af9015_config.ir_table_size = ARRAY_SIZE(af9015_ir_table_avermedia); break; + case USB_VID_MSI_2: + af9015_properties[i].rc_key_map = + af9015_rc_keys_msi_digivox_iii; + af9015_properties[i].rc_key_map_size = + ARRAY_SIZE(af9015_rc_keys_msi_digivox_iii); + af9015_config.ir_table = + af9015_ir_table_msi_digivox_iii; + af9015_config.ir_table_size = + ARRAY_SIZE(af9015_ir_table_msi_digivox_iii); + break; } } } diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h index c1e2b7d1d41..e237c4a0702 100644 --- a/drivers/media/dvb/dvb-usb/af9015.h +++ b/drivers/media/dvb/dvb-usb/af9015.h @@ -779,4 +779,75 @@ static u8 af9015_ir_table_trekstor[] = { 0x00, 0xff, 0x84, 0x7b, 0x27, 0x07, 0x00, }; +/* MSI DIGIVOX mini III */ +static struct dvb_usb_rc_key af9015_rc_keys_msi_digivox_iii[] = { + { 0x0713, KEY_POWER }, /* [red power button] */ + { 0x073b, KEY_VIDEO }, /* Source */ + { 0x073e, KEY_ZOOM }, /* Zoom */ + { 0x070b, KEY_POWER2 }, /* ShutDown */ + { 0x071e, KEY_1 }, + { 0x071f, KEY_2 }, + { 0x0720, KEY_3 }, + { 0x0721, KEY_4 }, + { 0x0722, KEY_5 }, + { 0x0723, KEY_6 }, + { 0x0724, KEY_7 }, + { 0x0725, KEY_8 }, + { 0x0726, KEY_9 }, + { 0x0727, KEY_0 }, + { 0x0752, KEY_CHANNELUP }, /* CH+ */ + { 0x0751, KEY_CHANNELDOWN }, /* CH- */ + { 0x0750, KEY_VOLUMEUP }, /* Vol+ */ + { 0x074f, KEY_VOLUMEDOWN }, /* Vol- */ + { 0x0705, KEY_ESC }, /* [back up arrow] */ + { 0x0708, KEY_OK }, /* [enter arrow] */ + { 0x073f, KEY_RECORD }, /* Rec */ + { 0x0716, KEY_STOP }, /* Stop */ + { 0x072a, KEY_PLAY }, /* Play */ + { 0x073c, KEY_MUTE }, /* Mute */ + { 0x0718, KEY_UP }, + { 0x0707, KEY_DOWN }, + { 0x070f, KEY_LEFT }, + { 0x0715, KEY_RIGHT }, + { 0x0736, KEY_RED }, + { 0x0737, KEY_GREEN }, + { 0x072d, KEY_YELLOW }, + { 0x072e, KEY_BLUE }, +}; + +static u8 af9015_ir_table_msi_digivox_iii[] = { + 0x61, 0xd6, 0x43, 0xbc, 0x13, 0x07, 0x00, /* KEY_POWER */ + 0x61, 0xd6, 0x01, 0xfe, 0x3b, 0x07, 0x00, /* KEY_VIDEO */ + 0x61, 0xd6, 0x0b, 0xf4, 0x3e, 0x07, 0x00, /* KEY_ZOOM */ + 0x61, 0xd6, 0x03, 0xfc, 0x0b, 0x07, 0x00, /* KEY_POWER2 */ + 0x61, 0xd6, 0x04, 0xfb, 0x1e, 0x07, 0x00, /* KEY_1 */ + 0x61, 0xd6, 0x08, 0xf7, 0x1f, 0x07, 0x00, /* KEY_2 */ + 0x61, 0xd6, 0x02, 0xfd, 0x20, 0x07, 0x00, /* KEY_3 */ + 0x61, 0xd6, 0x0f, 0xf0, 0x21, 0x07, 0x00, /* KEY_4 */ + 0x61, 0xd6, 0x05, 0xfa, 0x22, 0x07, 0x00, /* KEY_5 */ + 0x61, 0xd6, 0x06, 0xf9, 0x23, 0x07, 0x00, /* KEY_6 */ + 0x61, 0xd6, 0x0c, 0xf3, 0x24, 0x07, 0x00, /* KEY_7 */ + 0x61, 0xd6, 0x0d, 0xf2, 0x25, 0x07, 0x00, /* KEY_8 */ + 0x61, 0xd6, 0x0a, 0xf5, 0x26, 0x07, 0x00, /* KEY_9 */ + 0x61, 0xd6, 0x11, 0xee, 0x27, 0x07, 0x00, /* KEY_0 */ + 0x61, 0xd6, 0x09, 0xf6, 0x52, 0x07, 0x00, /* KEY_CHANNELUP */ + 0x61, 0xd6, 0x07, 0xf8, 0x51, 0x07, 0x00, /* KEY_CHANNELDOWN */ + 0x61, 0xd6, 0x0e, 0xf1, 0x50, 0x07, 0x00, /* KEY_VOLUMEUP */ + 0x61, 0xd6, 0x13, 0xec, 0x4f, 0x07, 0x00, /* KEY_VOLUMEDOWN */ + 0x61, 0xd6, 0x10, 0xef, 0x05, 0x07, 0x00, /* KEY_ESC */ + 0x61, 0xd6, 0x12, 0xed, 0x08, 0x07, 0x00, /* KEY_OK */ + 0x61, 0xd6, 0x14, 0xeb, 0x3f, 0x07, 0x00, /* KEY_RECORD */ + 0x61, 0xd6, 0x15, 0xea, 0x16, 0x07, 0x00, /* KEY_STOP */ + 0x61, 0xd6, 0x16, 0xe9, 0x2a, 0x07, 0x00, /* KEY_PLAY */ + 0x61, 0xd6, 0x17, 0xe8, 0x3c, 0x07, 0x00, /* KEY_MUTE */ + 0x61, 0xd6, 0x18, 0xe7, 0x18, 0x07, 0x00, /* KEY_UP */ + 0x61, 0xd6, 0x19, 0xe6, 0x07, 0x07, 0x00, /* KEY_DOWN */ + 0x61, 0xd6, 0x1a, 0xe5, 0x0f, 0x07, 0x00, /* KEY_LEFT */ + 0x61, 0xd6, 0x1b, 0xe4, 0x15, 0x07, 0x00, /* KEY_RIGHT */ + 0x61, 0xd6, 0x1c, 0xe3, 0x36, 0x07, 0x00, /* KEY_RED */ + 0x61, 0xd6, 0x1d, 0xe2, 0x37, 0x07, 0x00, /* KEY_GREEN */ + 0x61, 0xd6, 0x1e, 0xe1, 0x2d, 0x07, 0x00, /* KEY_YELLOW */ + 0x61, 0xd6, 0x1f, 0xe0, 0x2e, 0x07, 0x00, /* KEY_BLUE */ +}; + #endif -- cgit v1.2.3-70-g09d2 From 0f017212567793ecedf86f709f43ca40f9b84655 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 21 Sep 2009 21:26:37 -0300 Subject: V4L/DVB (13058): af9015: enable remote polling when eeprom contains 0x04 Looks like eeprom IR mode byte value 0x04 means there is remote which should be polled. Patch enables polling also in case of 0x04. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/af9015.c | 2 +- drivers/media/dvb/dvb-usb/af9015.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 5c898b07ae1..bad3e10f372 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -730,7 +730,7 @@ static int af9015_read_config(struct usb_device *udev) goto error; deb_info("%s: IR mode:%d\n", __func__, val); for (i = 0; i < af9015_properties_count; i++) { - if (val == AF9015_IR_MODE_DISABLED || val == 0x04) { + if (val == AF9015_IR_MODE_DISABLED) { af9015_properties[i].rc_key_map = NULL; af9015_properties[i].rc_key_map_size = 0; } else if (dvb_usb_af9015_remote) { diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h index e237c4a0702..931c8515830 100644 --- a/drivers/media/dvb/dvb-usb/af9015.h +++ b/drivers/media/dvb/dvb-usb/af9015.h @@ -95,6 +95,7 @@ enum af9015_ir_mode { AF9015_IR_MODE_HID, AF9015_IR_MODE_RLC, AF9015_IR_MODE_RC6, + AF9015_IR_MODE_POLLING, /* just guess */ }; struct af9015_state { -- cgit v1.2.3-70-g09d2 From 4aebc2893eada9e054a37df8bb342a53f8ca0d2a Mon Sep 17 00:00:00 2001 From: David Ellingsworth Date: Tue, 22 Sep 2009 21:22:19 -0300 Subject: V4L/DVB (13060): radio-mr800: implement proper locking Implement proper locking Signed-off-by: David Ellingsworth Acked-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-mr800.c | 181 ++++++++++++++++++++++---------------- 1 file changed, 106 insertions(+), 75 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index a1239083472..75c69755a04 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -168,11 +168,7 @@ static int amradio_set_mute(struct amradio_device *radio, char argument) int retval; int size; - /* safety check */ - if (radio->removed) - return -EIO; - - mutex_lock(&radio->lock); + BUG_ON(!mutex_is_locked(&radio->lock)); radio->buffer[0] = 0x00; radio->buffer[1] = 0x55; @@ -186,15 +182,11 @@ static int amradio_set_mute(struct amradio_device *radio, char argument) retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - if (retval < 0 || size != BUFFER_LENGTH) { - mutex_unlock(&radio->lock); + if (retval < 0 || size != BUFFER_LENGTH) return retval; - } radio->muted = argument; - mutex_unlock(&radio->lock); - return retval; } @@ -205,11 +197,7 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) int size; unsigned short freq_send = 0x10 + (freq >> 3) / 25; - /* safety check */ - if (radio->removed) - return -EIO; - - mutex_lock(&radio->lock); + BUG_ON(!mutex_is_locked(&radio->lock)); radio->buffer[0] = 0x00; radio->buffer[1] = 0x55; @@ -223,10 +211,8 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - if (retval < 0 || size != BUFFER_LENGTH) { - mutex_unlock(&radio->lock); + if (retval < 0 || size != BUFFER_LENGTH) return retval; - } /* frequency is calculated from freq_send and placed in first 2 bytes */ radio->buffer[0] = (freq_send >> 8) & 0xff; @@ -240,13 +226,6 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - if (retval < 0 || size != BUFFER_LENGTH) { - mutex_unlock(&radio->lock); - return retval; - } - - mutex_unlock(&radio->lock); - return retval; } @@ -255,11 +234,7 @@ static int amradio_set_stereo(struct amradio_device *radio, char argument) int retval; int size; - /* safety check */ - if (radio->removed) - return -EIO; - - mutex_lock(&radio->lock); + BUG_ON(!mutex_is_locked(&radio->lock)); radio->buffer[0] = 0x00; radio->buffer[1] = 0x55; @@ -275,14 +250,11 @@ static int amradio_set_stereo(struct amradio_device *radio, char argument) if (retval < 0 || size != BUFFER_LENGTH) { radio->stereo = -1; - mutex_unlock(&radio->lock); return retval; } radio->stereo = 1; - mutex_unlock(&radio->lock); - return retval; } @@ -325,12 +297,18 @@ static int vidioc_g_tuner(struct file *file, void *priv, struct amradio_device *radio = video_get_drvdata(video_devdata(file)); int retval; + mutex_lock(&radio->lock); + /* safety check */ - if (radio->removed) - return -EIO; + if (radio->removed) { + retval = -EIO; + goto unlock; + } - if (v->index > 0) - return -EINVAL; + if (v->index > 0) { + retval = -EINVAL; + goto unlock; + } /* TODO: Add function which look is signal stereo or not * amradio_getstat(radio); @@ -357,7 +335,10 @@ static int vidioc_g_tuner(struct file *file, void *priv, v->audmode = V4L2_TUNER_MODE_MONO; v->signal = 0xffff; /* Can't get the signal strength, sad.. */ v->afc = 0; /* Don't know what is this */ - return 0; + +unlock: + mutex_unlock(&radio->lock); + return retval; } /* vidioc_s_tuner - set tuner attributes */ @@ -367,12 +348,18 @@ static int vidioc_s_tuner(struct file *file, void *priv, struct amradio_device *radio = video_get_drvdata(video_devdata(file)); int retval; + mutex_lock(&radio->lock); + /* safety check */ - if (radio->removed) - return -EIO; + if (radio->removed) { + retval = -EIO; + goto unlock; + } - if (v->index > 0) - return -EINVAL; + if (v->index > 0) { + retval = -EINVAL; + goto unlock; + } /* mono/stereo selector */ switch (v->audmode) { @@ -389,10 +376,12 @@ static int vidioc_s_tuner(struct file *file, void *priv, "set stereo failed\n"); break; default: - return -EINVAL; + retval = -EINVAL; } - return 0; +unlock: + mutex_unlock(&radio->lock); + return retval; } /* vidioc_s_frequency - set tuner radio frequency */ @@ -402,19 +391,24 @@ static int vidioc_s_frequency(struct file *file, void *priv, struct amradio_device *radio = video_get_drvdata(video_devdata(file)); int retval; + mutex_lock(&radio->lock); + /* safety check */ - if (radio->removed) - return -EIO; + if (radio->removed) { + retval = -EIO; + goto unlock; + } - mutex_lock(&radio->lock); radio->curfreq = f->frequency; - mutex_unlock(&radio->lock); retval = amradio_setfreq(radio, radio->curfreq); if (retval < 0) amradio_dev_warn(&radio->videodev->dev, "set frequency failed\n"); - return 0; + +unlock: + mutex_unlock(&radio->lock); + return retval; } /* vidioc_g_frequency - get tuner radio frequency */ @@ -422,14 +416,22 @@ static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); + int retval = 0; + + mutex_lock(&radio->lock); /* safety check */ - if (radio->removed) - return -EIO; + if (radio->removed) { + retval = -EIO; + goto unlock; + } f->type = V4L2_TUNER_RADIO; f->frequency = radio->curfreq; - return 0; + +unlock: + mutex_unlock(&radio->lock); + return retval; } /* vidioc_queryctrl - enumerate control items */ @@ -449,17 +451,26 @@ static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); + int retval = -EINVAL; + + mutex_lock(&radio->lock); /* safety check */ - if (radio->removed) - return -EIO; + if (radio->removed) { + retval = -EIO; + goto unlock; + } switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: ctrl->value = radio->muted; - return 0; + retval = 0; + break; } - return -EINVAL; + +unlock: + mutex_unlock(&radio->lock); + return retval; } /* vidioc_s_ctrl - set the value of a control */ @@ -467,11 +478,15 @@ static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - int retval; + int retval = -EINVAL; + + mutex_lock(&radio->lock); /* safety check */ - if (radio->removed) - return -EIO; + if (radio->removed) { + retval = -EIO; + goto unlock; + } switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -480,19 +495,20 @@ static int vidioc_s_ctrl(struct file *file, void *priv, if (retval < 0) { amradio_dev_warn(&radio->videodev->dev, "amradio_stop failed\n"); - return -1; } } else { retval = amradio_set_mute(radio, AMRADIO_START); if (retval < 0) { amradio_dev_warn(&radio->videodev->dev, "amradio_start failed\n"); - return -1; } } - return 0; + break; } - return -EINVAL; + +unlock: + mutex_unlock(&radio->lock); + return retval; } /* vidioc_g_audio - get audio attributes */ @@ -535,9 +551,14 @@ static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) static int usb_amradio_open(struct file *file) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - int retval; + int retval = 0; - lock_kernel(); + mutex_lock(&radio->lock); + + if (radio->removed) { + retval = -EIO; + goto unlock; + } radio->users = 1; radio->muted = 1; @@ -547,8 +568,7 @@ static int usb_amradio_open(struct file *file) amradio_dev_warn(&radio->videodev->dev, "radio did not start up properly\n"); radio->users = 0; - unlock_kernel(); - return -EIO; + goto unlock; } retval = amradio_set_stereo(radio, WANT_STEREO); @@ -561,22 +581,25 @@ static int usb_amradio_open(struct file *file) amradio_dev_warn(&radio->videodev->dev, "set frequency failed\n"); - unlock_kernel(); - return 0; +unlock: + mutex_unlock(&radio->lock); + return retval; } /*close device */ static int usb_amradio_close(struct file *file) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - int retval; - - if (!radio) - return -ENODEV; + int retval = 0; mutex_lock(&radio->lock); + + if (radio->removed) { + retval = -EIO; + goto unlock; + } + radio->users = 0; - mutex_unlock(&radio->lock); if (!radio->removed) { retval = amradio_set_mute(radio, AMRADIO_STOP); @@ -585,7 +608,9 @@ static int usb_amradio_close(struct file *file) "amradio_stop failed\n"); } - return 0; +unlock: + mutex_unlock(&radio->lock); + return retval; } /* Suspend device - stop device. Need to be checked and fixed */ @@ -594,12 +619,15 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) struct amradio_device *radio = usb_get_intfdata(intf); int retval; + mutex_lock(&radio->lock); + retval = amradio_set_mute(radio, AMRADIO_STOP); if (retval < 0) dev_warn(&intf->dev, "amradio_stop failed\n"); dev_info(&intf->dev, "going into suspend..\n"); + mutex_unlock(&radio->lock); return 0; } @@ -609,12 +637,15 @@ static int usb_amradio_resume(struct usb_interface *intf) struct amradio_device *radio = usb_get_intfdata(intf); int retval; + mutex_lock(&radio->lock); + retval = amradio_set_mute(radio, AMRADIO_START); if (retval < 0) dev_warn(&intf->dev, "amradio_start failed\n"); dev_info(&intf->dev, "coming out of suspend..\n"); + mutex_unlock(&radio->lock); return 0; } -- cgit v1.2.3-70-g09d2 From 7a7d92e061ed13052d306cadad6972d52acea931 Mon Sep 17 00:00:00 2001 From: David Ellingsworth Date: Tue, 22 Sep 2009 21:37:30 -0300 Subject: V4L/DVB (13061): radio-mr800: simplify video_device allocation simplify video_device allocation Signed-off-by: David Ellingsworth Acked-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-mr800.c | 53 ++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 32 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 75c69755a04..dd36ba0baab 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -129,7 +129,7 @@ static int usb_amradio_resume(struct usb_interface *intf); struct amradio_device { /* reference to USB and video device */ struct usb_device *usbdev; - struct video_device *videodev; + struct video_device videodev; struct v4l2_device v4l2_dev; unsigned char *buffer; @@ -272,7 +272,7 @@ static void usb_amradio_disconnect(struct usb_interface *intf) mutex_unlock(&radio->lock); usb_set_intfdata(intf, NULL); - video_unregister_device(radio->videodev); + video_unregister_device(&radio->videodev); v4l2_device_disconnect(&radio->v4l2_dev); } @@ -320,7 +320,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, */ retval = amradio_set_stereo(radio, WANT_STEREO); if (retval < 0) - amradio_dev_warn(&radio->videodev->dev, + amradio_dev_warn(&radio->videodev.dev, "set stereo failed\n"); strcpy(v->name, "FM"); @@ -366,13 +366,13 @@ static int vidioc_s_tuner(struct file *file, void *priv, case V4L2_TUNER_MODE_MONO: retval = amradio_set_stereo(radio, WANT_MONO); if (retval < 0) - amradio_dev_warn(&radio->videodev->dev, + amradio_dev_warn(&radio->videodev.dev, "set mono failed\n"); break; case V4L2_TUNER_MODE_STEREO: retval = amradio_set_stereo(radio, WANT_STEREO); if (retval < 0) - amradio_dev_warn(&radio->videodev->dev, + amradio_dev_warn(&radio->videodev.dev, "set stereo failed\n"); break; default: @@ -403,7 +403,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, retval = amradio_setfreq(radio, radio->curfreq); if (retval < 0) - amradio_dev_warn(&radio->videodev->dev, + amradio_dev_warn(&radio->videodev.dev, "set frequency failed\n"); unlock: @@ -493,13 +493,13 @@ static int vidioc_s_ctrl(struct file *file, void *priv, if (ctrl->value) { retval = amradio_set_mute(radio, AMRADIO_STOP); if (retval < 0) { - amradio_dev_warn(&radio->videodev->dev, + amradio_dev_warn(&radio->videodev.dev, "amradio_stop failed\n"); } } else { retval = amradio_set_mute(radio, AMRADIO_START); if (retval < 0) { - amradio_dev_warn(&radio->videodev->dev, + amradio_dev_warn(&radio->videodev.dev, "amradio_start failed\n"); } } @@ -565,7 +565,7 @@ static int usb_amradio_open(struct file *file) retval = amradio_set_mute(radio, AMRADIO_START); if (retval < 0) { - amradio_dev_warn(&radio->videodev->dev, + amradio_dev_warn(&radio->videodev.dev, "radio did not start up properly\n"); radio->users = 0; goto unlock; @@ -573,12 +573,12 @@ static int usb_amradio_open(struct file *file) retval = amradio_set_stereo(radio, WANT_STEREO); if (retval < 0) - amradio_dev_warn(&radio->videodev->dev, + amradio_dev_warn(&radio->videodev.dev, "set stereo failed\n"); retval = amradio_setfreq(radio, radio->curfreq); if (retval < 0) - amradio_dev_warn(&radio->videodev->dev, + amradio_dev_warn(&radio->videodev.dev, "set frequency failed\n"); unlock: @@ -604,7 +604,7 @@ static int usb_amradio_close(struct file *file) if (!radio->removed) { retval = amradio_set_mute(radio, AMRADIO_STOP); if (retval < 0) - amradio_dev_warn(&radio->videodev->dev, + amradio_dev_warn(&radio->videodev.dev, "amradio_stop failed\n"); } @@ -676,9 +676,6 @@ static void usb_amradio_video_device_release(struct video_device *videodev) { struct amradio_device *radio = video_get_drvdata(videodev); - /* we call v4l to free radio->videodev */ - video_device_release(videodev); - v4l2_device_unregister(&radio->v4l2_dev); /* free rest memory */ @@ -718,20 +715,12 @@ static int usb_amradio_probe(struct usb_interface *intf, return retval; } - radio->videodev = video_device_alloc(); - - if (!radio->videodev) { - dev_err(&intf->dev, "video_device_alloc failed\n"); - kfree(radio->buffer); - kfree(radio); - return -ENOMEM; - } - - strlcpy(radio->videodev->name, v4l2_dev->name, sizeof(radio->videodev->name)); - radio->videodev->v4l2_dev = v4l2_dev; - radio->videodev->fops = &usb_amradio_fops; - radio->videodev->ioctl_ops = &usb_amradio_ioctl_ops; - radio->videodev->release = usb_amradio_video_device_release; + strlcpy(radio->videodev.name, v4l2_dev->name, + sizeof(radio->videodev.name)); + radio->videodev.v4l2_dev = v4l2_dev; + radio->videodev.fops = &usb_amradio_fops; + radio->videodev.ioctl_ops = &usb_amradio_ioctl_ops; + radio->videodev.release = usb_amradio_video_device_release; radio->removed = 0; radio->users = 0; @@ -741,12 +730,12 @@ static int usb_amradio_probe(struct usb_interface *intf, mutex_init(&radio->lock); - video_set_drvdata(radio->videodev, radio); + video_set_drvdata(&radio->videodev, radio); - retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); + retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, + radio_nr); if (retval < 0) { dev_err(&intf->dev, "could not register video device\n"); - video_device_release(radio->videodev); v4l2_device_unregister(v4l2_dev); kfree(radio->buffer); kfree(radio); -- cgit v1.2.3-70-g09d2 From 1b8bbb3c0a719f3baac22ea4a7eb1d636383ba3b Mon Sep 17 00:00:00 2001 From: David Ellingsworth Date: Tue, 22 Sep 2009 21:43:19 -0300 Subject: V4L/DVB (13062): radio-mr800: simplify error paths in usb probe callback Simplify error paths in usb probe callback. Signed-off-by: David Ellingsworth Acked-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-mr800.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index dd36ba0baab..0c5d734b00f 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -689,30 +689,29 @@ static int usb_amradio_probe(struct usb_interface *intf, { struct amradio_device *radio; struct v4l2_device *v4l2_dev; - int retval; + int retval = 0; radio = kzalloc(sizeof(struct amradio_device), GFP_KERNEL); if (!radio) { dev_err(&intf->dev, "kmalloc for amradio_device failed\n"); - return -ENOMEM; + retval = -ENOMEM; + goto err; } radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL); if (!radio->buffer) { dev_err(&intf->dev, "kmalloc for radio->buffer failed\n"); - kfree(radio); - return -ENOMEM; + retval = -ENOMEM; + goto err_nobuf; } v4l2_dev = &radio->v4l2_dev; retval = v4l2_device_register(&intf->dev, v4l2_dev); if (retval < 0) { dev_err(&intf->dev, "couldn't register v4l2_device\n"); - kfree(radio->buffer); - kfree(radio); - return retval; + goto err_v4l2; } strlcpy(radio->videodev.name, v4l2_dev->name, @@ -736,14 +735,20 @@ static int usb_amradio_probe(struct usb_interface *intf, radio_nr); if (retval < 0) { dev_err(&intf->dev, "could not register video device\n"); - v4l2_device_unregister(v4l2_dev); - kfree(radio->buffer); - kfree(radio); - return -EIO; + goto err_vdev; } usb_set_intfdata(intf, radio); return 0; + +err_vdev: + v4l2_device_unregister(v4l2_dev); +err_v4l2: + kfree(radio->buffer); +err_nobuf: + kfree(radio); +err: + return retval; } static int __init amradio_init(void) -- cgit v1.2.3-70-g09d2 From d1939e4c5f053e34dd432b448e221f55586a68ec Mon Sep 17 00:00:00 2001 From: David Ellingsworth Date: Tue, 22 Sep 2009 21:48:43 -0300 Subject: V4L/DVB (13063): radio-mr800: remove unnecessary local variable Remove unnecessary local variable. Signed-off-by: David Ellingsworth Acked-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-mr800.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 0c5d734b00f..24c55a5a6ca 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -688,7 +688,6 @@ static int usb_amradio_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct amradio_device *radio; - struct v4l2_device *v4l2_dev; int retval = 0; radio = kzalloc(sizeof(struct amradio_device), GFP_KERNEL); @@ -707,16 +706,15 @@ static int usb_amradio_probe(struct usb_interface *intf, goto err_nobuf; } - v4l2_dev = &radio->v4l2_dev; - retval = v4l2_device_register(&intf->dev, v4l2_dev); + retval = v4l2_device_register(&intf->dev, &radio->v4l2_dev); if (retval < 0) { dev_err(&intf->dev, "couldn't register v4l2_device\n"); goto err_v4l2; } - strlcpy(radio->videodev.name, v4l2_dev->name, + strlcpy(radio->videodev.name, radio->v4l2_dev.name, sizeof(radio->videodev.name)); - radio->videodev.v4l2_dev = v4l2_dev; + radio->videodev.v4l2_dev = &radio->v4l2_dev; radio->videodev.fops = &usb_amradio_fops; radio->videodev.ioctl_ops = &usb_amradio_ioctl_ops; radio->videodev.release = usb_amradio_video_device_release; @@ -742,7 +740,7 @@ static int usb_amradio_probe(struct usb_interface *intf, return 0; err_vdev: - v4l2_device_unregister(v4l2_dev); + v4l2_device_unregister(&radio->v4l2_dev); err_v4l2: kfree(radio->buffer); err_nobuf: -- cgit v1.2.3-70-g09d2 From ceb99e1b5a093ae8f439fc55aac28d007145c8ec Mon Sep 17 00:00:00 2001 From: David Ellingsworth Date: Wed, 23 Sep 2009 17:45:31 -0300 Subject: V4L/DVB (13064): radio-mr800: simplify access to amradio_device Simplify access to amradio_device. Signed-off-by: David Ellingsworth Acked-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-mr800.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 24c55a5a6ca..5401952004b 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -141,6 +141,8 @@ struct amradio_device { int muted; }; +#define vdev_to_amradio(r) container_of(r, struct amradio_device, videodev) + /* USB Device ID List */ static struct usb_device_id usb_amradio_device_table[] = { {USB_DEVICE_AND_INTERFACE_INFO(USB_AMRADIO_VENDOR, USB_AMRADIO_PRODUCT, @@ -280,7 +282,7 @@ static void usb_amradio_disconnect(struct usb_interface *intf) static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *v) { - struct amradio_device *radio = video_drvdata(file); + struct amradio_device *radio = file->private_data; strlcpy(v->driver, "radio-mr800", sizeof(v->driver)); strlcpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card)); @@ -294,7 +296,7 @@ static int vidioc_querycap(struct file *file, void *priv, static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct amradio_device *radio = video_get_drvdata(video_devdata(file)); + struct amradio_device *radio = file->private_data; int retval; mutex_lock(&radio->lock); @@ -345,7 +347,7 @@ unlock: static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct amradio_device *radio = video_get_drvdata(video_devdata(file)); + struct amradio_device *radio = file->private_data; int retval; mutex_lock(&radio->lock); @@ -388,7 +390,7 @@ unlock: static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct amradio_device *radio = video_get_drvdata(video_devdata(file)); + struct amradio_device *radio = file->private_data; int retval; mutex_lock(&radio->lock); @@ -415,7 +417,7 @@ unlock: static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct amradio_device *radio = video_get_drvdata(video_devdata(file)); + struct amradio_device *radio = file->private_data; int retval = 0; mutex_lock(&radio->lock); @@ -450,7 +452,7 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct amradio_device *radio = video_get_drvdata(video_devdata(file)); + struct amradio_device *radio = file->private_data; int retval = -EINVAL; mutex_lock(&radio->lock); @@ -477,7 +479,7 @@ unlock: static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct amradio_device *radio = video_get_drvdata(video_devdata(file)); + struct amradio_device *radio = file->private_data; int retval = -EINVAL; mutex_lock(&radio->lock); @@ -550,7 +552,7 @@ static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) /* open device - amradio_start() and amradio_setfreq() */ static int usb_amradio_open(struct file *file) { - struct amradio_device *radio = video_get_drvdata(video_devdata(file)); + struct amradio_device *radio = vdev_to_amradio(video_devdata(file)); int retval = 0; mutex_lock(&radio->lock); @@ -560,6 +562,7 @@ static int usb_amradio_open(struct file *file) goto unlock; } + file->private_data = radio; radio->users = 1; radio->muted = 1; @@ -589,7 +592,7 @@ unlock: /*close device */ static int usb_amradio_close(struct file *file) { - struct amradio_device *radio = video_get_drvdata(video_devdata(file)); + struct amradio_device *radio = file->private_data; int retval = 0; mutex_lock(&radio->lock); @@ -674,7 +677,7 @@ static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = { static void usb_amradio_video_device_release(struct video_device *videodev) { - struct amradio_device *radio = video_get_drvdata(videodev); + struct amradio_device *radio = vdev_to_amradio(videodev); v4l2_device_unregister(&radio->v4l2_dev); -- cgit v1.2.3-70-g09d2 From eac000a90e70b990c7d847ac40ff1c33a5f00636 Mon Sep 17 00:00:00 2001 From: David Ellingsworth Date: Wed, 23 Sep 2009 17:49:36 -0300 Subject: V4L/DVB (13065): radio-mr800: simplify locking in ioctl callbacks Simplify locking in ioctl callbacks. Signed-off-by: David Ellingsworth Acked-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-mr800.c | 109 +++++++++++--------------------------- 1 file changed, 30 insertions(+), 79 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 5401952004b..0498c4c60d8 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -299,18 +299,8 @@ static int vidioc_g_tuner(struct file *file, void *priv, struct amradio_device *radio = file->private_data; int retval; - mutex_lock(&radio->lock); - - /* safety check */ - if (radio->removed) { - retval = -EIO; - goto unlock; - } - - if (v->index > 0) { - retval = -EINVAL; - goto unlock; - } + if (v->index > 0) + return -EINVAL; /* TODO: Add function which look is signal stereo or not * amradio_getstat(radio); @@ -338,8 +328,6 @@ static int vidioc_g_tuner(struct file *file, void *priv, v->signal = 0xffff; /* Can't get the signal strength, sad.. */ v->afc = 0; /* Don't know what is this */ -unlock: - mutex_unlock(&radio->lock); return retval; } @@ -348,20 +336,10 @@ static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { struct amradio_device *radio = file->private_data; - int retval; - - mutex_lock(&radio->lock); - - /* safety check */ - if (radio->removed) { - retval = -EIO; - goto unlock; - } + int retval = -EINVAL; - if (v->index > 0) { - retval = -EINVAL; - goto unlock; - } + if (v->index > 0) + return -EINVAL; /* mono/stereo selector */ switch (v->audmode) { @@ -377,12 +355,8 @@ static int vidioc_s_tuner(struct file *file, void *priv, amradio_dev_warn(&radio->videodev.dev, "set stereo failed\n"); break; - default: - retval = -EINVAL; } -unlock: - mutex_unlock(&radio->lock); return retval; } @@ -391,15 +365,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { struct amradio_device *radio = file->private_data; - int retval; - - mutex_lock(&radio->lock); - - /* safety check */ - if (radio->removed) { - retval = -EIO; - goto unlock; - } + int retval = 0; radio->curfreq = f->frequency; @@ -408,8 +374,6 @@ static int vidioc_s_frequency(struct file *file, void *priv, amradio_dev_warn(&radio->videodev.dev, "set frequency failed\n"); -unlock: - mutex_unlock(&radio->lock); return retval; } @@ -418,22 +382,11 @@ static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { struct amradio_device *radio = file->private_data; - int retval = 0; - - mutex_lock(&radio->lock); - - /* safety check */ - if (radio->removed) { - retval = -EIO; - goto unlock; - } f->type = V4L2_TUNER_RADIO; f->frequency = radio->curfreq; -unlock: - mutex_unlock(&radio->lock); - return retval; + return 0; } /* vidioc_queryctrl - enumerate control items */ @@ -453,26 +406,14 @@ static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { struct amradio_device *radio = file->private_data; - int retval = -EINVAL; - - mutex_lock(&radio->lock); - - /* safety check */ - if (radio->removed) { - retval = -EIO; - goto unlock; - } switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: ctrl->value = radio->muted; - retval = 0; - break; + return 0; } -unlock: - mutex_unlock(&radio->lock); - return retval; + return -EINVAL; } /* vidioc_s_ctrl - set the value of a control */ @@ -482,14 +423,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv, struct amradio_device *radio = file->private_data; int retval = -EINVAL; - mutex_lock(&radio->lock); - - /* safety check */ - if (radio->removed) { - retval = -EIO; - goto unlock; - } - switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: if (ctrl->value) { @@ -508,8 +441,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv, break; } -unlock: - mutex_unlock(&radio->lock); return retval; } @@ -616,6 +547,26 @@ unlock: return retval; } +static long usb_amradio_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct amradio_device *radio = file->private_data; + long retval = 0; + + mutex_lock(&radio->lock); + + if (radio->removed) { + retval = -EIO; + goto unlock; + } + + retval = video_ioctl2(file, cmd, arg); + +unlock: + mutex_unlock(&radio->lock); + return retval; +} + /* Suspend device - stop device. Need to be checked and fixed */ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) { @@ -657,7 +608,7 @@ static const struct v4l2_file_operations usb_amradio_fops = { .owner = THIS_MODULE, .open = usb_amradio_open, .release = usb_amradio_close, - .ioctl = video_ioctl2, + .ioctl = usb_amradio_ioctl, }; static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = { -- cgit v1.2.3-70-g09d2 From 26452bfef4ae4798b96281ad8d3aed6e2d79846e Mon Sep 17 00:00:00 2001 From: David Ellingsworth Date: Wed, 23 Sep 2009 17:52:17 -0300 Subject: V4L/DVB (13066): radio-mr800: remove device removed indicator Remove device removed indicator Signed-off-by: David Ellingsworth Acked-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-mr800.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 0498c4c60d8..c4f4cd8dbb6 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -137,7 +137,6 @@ struct amradio_device { int curfreq; int stereo; int users; - int removed; int muted; }; @@ -270,7 +269,7 @@ static void usb_amradio_disconnect(struct usb_interface *intf) struct amradio_device *radio = usb_get_intfdata(intf); mutex_lock(&radio->lock); - radio->removed = 1; + radio->usbdev = NULL; mutex_unlock(&radio->lock); usb_set_intfdata(intf, NULL); @@ -488,7 +487,7 @@ static int usb_amradio_open(struct file *file) mutex_lock(&radio->lock); - if (radio->removed) { + if (!radio->usbdev) { retval = -EIO; goto unlock; } @@ -528,19 +527,17 @@ static int usb_amradio_close(struct file *file) mutex_lock(&radio->lock); - if (radio->removed) { + if (!radio->usbdev) { retval = -EIO; goto unlock; } radio->users = 0; - if (!radio->removed) { - retval = amradio_set_mute(radio, AMRADIO_STOP); - if (retval < 0) - amradio_dev_warn(&radio->videodev.dev, - "amradio_stop failed\n"); - } + retval = amradio_set_mute(radio, AMRADIO_STOP); + if (retval < 0) + amradio_dev_warn(&radio->videodev.dev, + "amradio_stop failed\n"); unlock: mutex_unlock(&radio->lock); @@ -555,7 +552,7 @@ static long usb_amradio_ioctl(struct file *file, unsigned int cmd, mutex_lock(&radio->lock); - if (radio->removed) { + if (!radio->usbdev) { retval = -EIO; goto unlock; } @@ -673,7 +670,6 @@ static int usb_amradio_probe(struct usb_interface *intf, radio->videodev.ioctl_ops = &usb_amradio_ioctl_ops; radio->videodev.release = usb_amradio_video_device_release; - radio->removed = 0; radio->users = 0; radio->usbdev = interface_to_usbdev(intf); radio->curfreq = 95.16 * FREQ_MUL; -- cgit v1.2.3-70-g09d2 From 4e3616576e9e65d53f9381b9f334257299c7262e Mon Sep 17 00:00:00 2001 From: David Ellingsworth Date: Wed, 23 Sep 2009 18:03:52 -0300 Subject: V4L/DVB (13067): radio-mr800: fix potential use after free Fix portential use after free. Signed-off-by: David Ellingsworth Acked-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-mr800.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index c4f4cd8dbb6..dbae50ba250 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -273,8 +273,8 @@ static void usb_amradio_disconnect(struct usb_interface *intf) mutex_unlock(&radio->lock); usb_set_intfdata(intf, NULL); - video_unregister_device(&radio->videodev); v4l2_device_disconnect(&radio->v4l2_dev); + video_unregister_device(&radio->videodev); } /* vidioc_querycap - query device capabilities */ -- cgit v1.2.3-70-g09d2 From 8a7cd16f1fa31ef6db9cfc16b1eb0356566e974d Mon Sep 17 00:00:00 2001 From: David Ellingsworth Date: Wed, 23 Sep 2009 18:09:01 -0300 Subject: V4L/DVB (13068): radio-mr800: remove device initialization from open/close Remove device initialization from open/close. Signed-off-by: David Ellingsworth Acked-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-mr800.c | 35 ++--------------------------------- 1 file changed, 2 insertions(+), 33 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index dbae50ba250..399032e8cc1 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -136,7 +136,6 @@ struct amradio_device { struct mutex lock; /* buffer locking */ int curfreq; int stereo; - int users; int muted; }; @@ -493,26 +492,6 @@ static int usb_amradio_open(struct file *file) } file->private_data = radio; - radio->users = 1; - radio->muted = 1; - - retval = amradio_set_mute(radio, AMRADIO_START); - if (retval < 0) { - amradio_dev_warn(&radio->videodev.dev, - "radio did not start up properly\n"); - radio->users = 0; - goto unlock; - } - - retval = amradio_set_stereo(radio, WANT_STEREO); - if (retval < 0) - amradio_dev_warn(&radio->videodev.dev, - "set stereo failed\n"); - - retval = amradio_setfreq(radio, radio->curfreq); - if (retval < 0) - amradio_dev_warn(&radio->videodev.dev, - "set frequency failed\n"); unlock: mutex_unlock(&radio->lock); @@ -527,19 +506,9 @@ static int usb_amradio_close(struct file *file) mutex_lock(&radio->lock); - if (!radio->usbdev) { + if (!radio->usbdev) retval = -EIO; - goto unlock; - } - - radio->users = 0; - retval = amradio_set_mute(radio, AMRADIO_STOP); - if (retval < 0) - amradio_dev_warn(&radio->videodev.dev, - "amradio_stop failed\n"); - -unlock: mutex_unlock(&radio->lock); return retval; } @@ -670,10 +639,10 @@ static int usb_amradio_probe(struct usb_interface *intf, radio->videodev.ioctl_ops = &usb_amradio_ioctl_ops; radio->videodev.release = usb_amradio_video_device_release; - radio->users = 0; radio->usbdev = interface_to_usbdev(intf); radio->curfreq = 95.16 * FREQ_MUL; radio->stereo = -1; + radio->muted = 1; mutex_init(&radio->lock); -- cgit v1.2.3-70-g09d2 From 502d50166cdef6cc8f63ab8c6ab35694ee39f608 Mon Sep 17 00:00:00 2001 From: David Ellingsworth Date: Wed, 23 Sep 2009 18:13:50 -0300 Subject: V4L/DVB (13069): radio-mr800: ensure the radio is initialized to a consistent state Ensure the radio is initialized to a consistent state. Signed-off-by: David Ellingsworth Acked-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-mr800.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 399032e8cc1..7db992d3b0d 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -85,6 +85,9 @@ MODULE_LICENSE("GPL"); #define amradio_dev_warn(dev, fmt, arg...) \ dev_warn(dev, MR800_DRIVER_NAME " - " fmt, ##arg) +#define amradio_dev_err(dev, fmt, arg...) \ + dev_err(dev, MR800_DRIVER_NAME " - " fmt, ##arg) + /* Probably USB_TIMEOUT should be modified in module parameter */ #define BUFFER_LENGTH 8 #define USB_TIMEOUT 500 @@ -137,6 +140,7 @@ struct amradio_device { int curfreq; int stereo; int muted; + int initialized; }; #define vdev_to_amradio(r) container_of(r, struct amradio_device, videodev) @@ -478,6 +482,31 @@ static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) return 0; } +static int usb_amradio_init(struct amradio_device *radio) +{ + int retval; + + retval = amradio_set_mute(radio, AMRADIO_STOP); + if (retval < 0) { + amradio_dev_warn(&radio->videodev.dev, "amradio_stop failed\n"); + goto out_err; + } + + retval = amradio_set_stereo(radio, WANT_STEREO); + if (retval < 0) { + amradio_dev_warn(&radio->videodev.dev, "set stereo failed\n"); + goto out_err; + } + + radio->initialized = 1; + goto out; + +out_err: + amradio_dev_err(&radio->videodev.dev, "initialization failed\n"); +out: + return retval; +} + /* open device - amradio_start() and amradio_setfreq() */ static int usb_amradio_open(struct file *file) { @@ -493,6 +522,9 @@ static int usb_amradio_open(struct file *file) file->private_data = radio; + if (unlikely(!radio->initialized)) + retval = usb_amradio_init(radio); + unlock: mutex_unlock(&radio->lock); return retval; @@ -641,8 +673,6 @@ static int usb_amradio_probe(struct usb_interface *intf, radio->usbdev = interface_to_usbdev(intf); radio->curfreq = 95.16 * FREQ_MUL; - radio->stereo = -1; - radio->muted = 1; mutex_init(&radio->lock); -- cgit v1.2.3-70-g09d2 From 30dd4508b97155a3f826f877d5750d8888bc3183 Mon Sep 17 00:00:00 2001 From: David Ellingsworth Date: Wed, 23 Sep 2009 18:16:38 -0300 Subject: V4L/DVB (13070): radio-mr800: fix behavior of set_stereo function Fix behavior of set_stereo function. Signed-off-by: David Ellingsworth Acked-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-mr800.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 7db992d3b0d..9764eca2c49 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -252,12 +252,13 @@ static int amradio_set_stereo(struct amradio_device *radio, char argument) retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - if (retval < 0 || size != BUFFER_LENGTH) { - radio->stereo = -1; + if (retval < 0 || size != BUFFER_LENGTH) return retval; - } - radio->stereo = 1; + if (argument == WANT_STEREO) + radio->stereo = 1; + else + radio->stereo = 0; return retval; } -- cgit v1.2.3-70-g09d2 From d8970e5fd9eace437bc2f1aaff1c2a05fb3448ea Mon Sep 17 00:00:00 2001 From: David Ellingsworth Date: Wed, 23 Sep 2009 18:24:47 -0300 Subject: V4L/DVB (13071): radio-mr800: preserve radio state during suspend/resume Preserve radio state during suspend/resume. Signed-off-by: David Ellingsworth Acked-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-mr800.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 9764eca2c49..ac210737894 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -574,9 +574,12 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) mutex_lock(&radio->lock); - retval = amradio_set_mute(radio, AMRADIO_STOP); - if (retval < 0) - dev_warn(&intf->dev, "amradio_stop failed\n"); + if (!radio->muted && radio->initialized) { + retval = amradio_set_mute(radio, AMRADIO_STOP); + if (retval < 0) + dev_warn(&intf->dev, "amradio_stop failed\n"); + radio->muted = 0; + } dev_info(&intf->dev, "going into suspend..\n"); @@ -592,10 +595,30 @@ static int usb_amradio_resume(struct usb_interface *intf) mutex_lock(&radio->lock); - retval = amradio_set_mute(radio, AMRADIO_START); + if (unlikely(!radio->initialized)) + goto unlock; + + if (radio->stereo) + retval = amradio_set_stereo(radio, WANT_STEREO); + else + retval = amradio_set_stereo(radio, WANT_MONO); + if (retval < 0) - dev_warn(&intf->dev, "amradio_start failed\n"); + amradio_dev_warn(&radio->videodev.dev, "set stereo failed\n"); + retval = amradio_setfreq(radio, radio->curfreq); + if (retval < 0) + amradio_dev_warn(&radio->videodev.dev, + "set frequency failed\n"); + + if (!radio->muted) { + retval = amradio_set_mute(radio, AMRADIO_START); + if (retval < 0) + dev_warn(&radio->videodev.dev, + "amradio_start failed\n"); + } + +unlock: dev_info(&intf->dev, "coming out of suspend..\n"); mutex_unlock(&radio->lock); -- cgit v1.2.3-70-g09d2 From 16a72f41bb82573d7fe1dfea1cb8356dee307db4 Mon Sep 17 00:00:00 2001 From: David Ellingsworth Date: Wed, 23 Sep 2009 18:28:02 -0300 Subject: V4L/DVB (13072): radio-mr800: simplify device warnings Simplify device warnings. Signed-off-by: David Ellingsworth Acked-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-mr800.c | 78 +++++++++++++-------------------------- 1 file changed, 26 insertions(+), 52 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index ac210737894..5506fac5fd4 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -186,8 +186,10 @@ static int amradio_set_mute(struct amradio_device *radio, char argument) retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - if (retval < 0 || size != BUFFER_LENGTH) + if (retval < 0 || size != BUFFER_LENGTH) { + amradio_dev_warn(&radio->videodev.dev, "set mute failed\n"); return retval; + } radio->muted = argument; @@ -216,7 +218,7 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); if (retval < 0 || size != BUFFER_LENGTH) - return retval; + goto out_err; /* frequency is calculated from freq_send and placed in first 2 bytes */ radio->buffer[0] = (freq_send >> 8) & 0xff; @@ -230,6 +232,14 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); + if (retval < 0 || size != BUFFER_LENGTH) + goto out_err; + + goto out; + +out_err: + amradio_dev_warn(&radio->videodev.dev, "set frequency failed\n"); +out: return retval; } @@ -252,8 +262,10 @@ static int amradio_set_stereo(struct amradio_device *radio, char argument) retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - if (retval < 0 || size != BUFFER_LENGTH) + if (retval < 0 || size != BUFFER_LENGTH) { + amradio_dev_warn(&radio->videodev.dev, "set stereo failed\n"); return retval; + } if (argument == WANT_STEREO) radio->stereo = 1; @@ -314,9 +326,6 @@ static int vidioc_g_tuner(struct file *file, void *priv, * amradio_set_stereo shouldn't be here */ retval = amradio_set_stereo(radio, WANT_STEREO); - if (retval < 0) - amradio_dev_warn(&radio->videodev.dev, - "set stereo failed\n"); strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; @@ -348,15 +357,9 @@ static int vidioc_s_tuner(struct file *file, void *priv, switch (v->audmode) { case V4L2_TUNER_MODE_MONO: retval = amradio_set_stereo(radio, WANT_MONO); - if (retval < 0) - amradio_dev_warn(&radio->videodev.dev, - "set mono failed\n"); break; case V4L2_TUNER_MODE_STEREO: retval = amradio_set_stereo(radio, WANT_STEREO); - if (retval < 0) - amradio_dev_warn(&radio->videodev.dev, - "set stereo failed\n"); break; } @@ -373,9 +376,6 @@ static int vidioc_s_frequency(struct file *file, void *priv, radio->curfreq = f->frequency; retval = amradio_setfreq(radio, radio->curfreq); - if (retval < 0) - amradio_dev_warn(&radio->videodev.dev, - "set frequency failed\n"); return retval; } @@ -428,19 +428,11 @@ static int vidioc_s_ctrl(struct file *file, void *priv, switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: - if (ctrl->value) { + if (ctrl->value) retval = amradio_set_mute(radio, AMRADIO_STOP); - if (retval < 0) { - amradio_dev_warn(&radio->videodev.dev, - "amradio_stop failed\n"); - } - } else { + else retval = amradio_set_mute(radio, AMRADIO_START); - if (retval < 0) { - amradio_dev_warn(&radio->videodev.dev, - "amradio_start failed\n"); - } - } + break; } @@ -488,16 +480,12 @@ static int usb_amradio_init(struct amradio_device *radio) int retval; retval = amradio_set_mute(radio, AMRADIO_STOP); - if (retval < 0) { - amradio_dev_warn(&radio->videodev.dev, "amradio_stop failed\n"); + if (retval) goto out_err; - } retval = amradio_set_stereo(radio, WANT_STEREO); - if (retval < 0) { - amradio_dev_warn(&radio->videodev.dev, "set stereo failed\n"); + if (retval) goto out_err; - } radio->initialized = 1; goto out; @@ -570,14 +558,11 @@ unlock: static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) { struct amradio_device *radio = usb_get_intfdata(intf); - int retval; mutex_lock(&radio->lock); if (!radio->muted && radio->initialized) { - retval = amradio_set_mute(radio, AMRADIO_STOP); - if (retval < 0) - dev_warn(&intf->dev, "amradio_stop failed\n"); + amradio_set_mute(radio, AMRADIO_STOP); radio->muted = 0; } @@ -591,7 +576,6 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) static int usb_amradio_resume(struct usb_interface *intf) { struct amradio_device *radio = usb_get_intfdata(intf); - int retval; mutex_lock(&radio->lock); @@ -599,24 +583,14 @@ static int usb_amradio_resume(struct usb_interface *intf) goto unlock; if (radio->stereo) - retval = amradio_set_stereo(radio, WANT_STEREO); + amradio_set_stereo(radio, WANT_STEREO); else - retval = amradio_set_stereo(radio, WANT_MONO); + amradio_set_stereo(radio, WANT_MONO); - if (retval < 0) - amradio_dev_warn(&radio->videodev.dev, "set stereo failed\n"); + amradio_setfreq(radio, radio->curfreq); - retval = amradio_setfreq(radio, radio->curfreq); - if (retval < 0) - amradio_dev_warn(&radio->videodev.dev, - "set frequency failed\n"); - - if (!radio->muted) { - retval = amradio_set_mute(radio, AMRADIO_START); - if (retval < 0) - dev_warn(&radio->videodev.dev, - "amradio_start failed\n"); - } + if (!radio->muted) + amradio_set_mute(radio, AMRADIO_START); unlock: dev_info(&intf->dev, "coming out of suspend..\n"); -- cgit v1.2.3-70-g09d2 From 798166dbecafa98ec9b28d056774ec2fc80290df Mon Sep 17 00:00:00 2001 From: David Ellingsworth Date: Wed, 23 Sep 2009 18:31:26 -0300 Subject: V4L/DVB (13073): radio-mr800: set radio frequency only upon success Set radio frequency only upon success. Signed-off-by: David Ellingsworth Acked-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-mr800.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 5506fac5fd4..4064109c420 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -235,6 +235,7 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) if (retval < 0 || size != BUFFER_LENGTH) goto out_err; + radio->curfreq = freq; goto out; out_err: @@ -371,13 +372,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { struct amradio_device *radio = file->private_data; - int retval = 0; - - radio->curfreq = f->frequency; - retval = amradio_setfreq(radio, radio->curfreq); - - return retval; + return amradio_setfreq(radio, f->frequency); } /* vidioc_g_frequency - get tuner radio frequency */ -- cgit v1.2.3-70-g09d2 From d7009cdc286d7c9714b357b0e85b3fcbbf9e03a4 Mon Sep 17 00:00:00 2001 From: "Beholder Intl. Ltd. Dmitry Belimov" Date: Thu, 24 Sep 2009 13:13:28 -0300 Subject: V4L/DVB (13075): xc5000: add FM radio support Add FM radio for the xc5000 silicon tuner chip. Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/xc5000.c | 66 +++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index f4ffcdc9b84..fc7cb74256d 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c @@ -739,15 +739,12 @@ static int xc5000_is_firmware_loaded(struct dvb_frontend *fe) return ret; } -static int xc5000_set_analog_params(struct dvb_frontend *fe, +static int xc5000_set_tv_freq(struct dvb_frontend *fe, struct analog_parameters *params) { struct xc5000_priv *priv = fe->tuner_priv; int ret; - if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) - xc_load_fw_and_init_tuner(fe); - dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n", __func__, params->frequency); @@ -827,6 +824,67 @@ tune_channel: return 0; } +static int xc5000_set_radio_freq(struct dvb_frontend *fe, + struct analog_parameters *params) +{ + struct xc5000_priv *priv = fe->tuner_priv; + int ret = -EINVAL; + + dprintk(1, "%s() frequency=%d (in units of khz)\n", + __func__, params->frequency); + + priv->freq_hz = params->frequency * 125 / 2; + + priv->rf_mode = XC_RF_MODE_AIR; + + ret = xc_SetTVStandard(priv, + XC5000_Standard[FM_Radio_INPUT1].VideoMode, + XC5000_Standard[FM_Radio_INPUT1].AudioMode); + + if (ret != XC_RESULT_SUCCESS) { + printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n"); + return -EREMOTEIO; + } + + ret = xc_SetSignalSource(priv, priv->rf_mode); + if (ret != XC_RESULT_SUCCESS) { + printk(KERN_ERR + "xc5000: xc_SetSignalSource(%d) failed\n", + priv->rf_mode); + return -EREMOTEIO; + } + + xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG); + + return 0; +} + +static int xc5000_set_analog_params(struct dvb_frontend *fe, + struct analog_parameters *params) +{ + struct xc5000_priv *priv = fe->tuner_priv; + int ret = -EINVAL; + + if (priv->i2c_props.adap == NULL) + return -EINVAL; + + if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) + xc_load_fw_and_init_tuner(fe); + + switch (params->mode) { + case V4L2_TUNER_RADIO: + ret = xc5000_set_radio_freq(fe, params); + break; + case V4L2_TUNER_ANALOG_TV: + case V4L2_TUNER_DIGITAL_TV: + ret = xc5000_set_tv_freq(fe, params); + break; + } + + return ret; +} + + static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq) { struct xc5000_priv *priv = fe->tuner_priv; -- cgit v1.2.3-70-g09d2 From 496e9057adf55d0e6c9be3805f0bc61288409317 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Thu, 24 Sep 2009 13:27:24 -0300 Subject: V4L/DVB (13076): xc5000: make the definition of the FM input part of the xc5000 config struct Remove hard-coded definition of the xc5000 FM radio input, making it a parameter passed in when doing the attach call. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/xc5000.c | 25 ++++++++++++++++++++++--- drivers/media/common/tuners/xc5000.h | 6 ++++++ 2 files changed, 28 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index fc7cb74256d..d33bf831e76 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c @@ -61,6 +61,7 @@ struct xc5000_priv { u32 bandwidth; u8 video_standard; u8 rf_mode; + u8 radio_input; }; /* Misc Defines */ @@ -829,17 +830,32 @@ static int xc5000_set_radio_freq(struct dvb_frontend *fe, { struct xc5000_priv *priv = fe->tuner_priv; int ret = -EINVAL; + u8 radio_input; dprintk(1, "%s() frequency=%d (in units of khz)\n", __func__, params->frequency); + if (priv->radio_input == XC5000_RADIO_NOT_CONFIGURED) { + dprintk(1, "%s() radio input not configured\n", __func__); + return -EINVAL; + } + + if (priv->radio_input == XC5000_RADIO_FM1) + radio_input = FM_Radio_INPUT1; + else if (priv->radio_input == XC5000_RADIO_FM2) + radio_input = FM_Radio_INPUT2; + else { + dprintk(1, "%s() unknown radio input %d\n", __func__, + priv->radio_input); + return -EINVAL; + } + priv->freq_hz = params->frequency * 125 / 2; priv->rf_mode = XC_RF_MODE_AIR; - ret = xc_SetTVStandard(priv, - XC5000_Standard[FM_Radio_INPUT1].VideoMode, - XC5000_Standard[FM_Radio_INPUT1].AudioMode); + ret = xc_SetTVStandard(priv, XC5000_Standard[radio_input].VideoMode, + XC5000_Standard[radio_input].AudioMode); if (ret != XC_RESULT_SUCCESS) { printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n"); @@ -1058,6 +1074,9 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, priv->if_khz = cfg->if_khz; } + if (priv->radio_input == 0) + priv->radio_input = cfg->radio_input; + /* Check if firmware has been loaded. It is possible that another instance of the driver has loaded the firmware. */ diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h index f4c146698a0..e6d7236c9ea 100644 --- a/drivers/media/common/tuners/xc5000.h +++ b/drivers/media/common/tuners/xc5000.h @@ -30,11 +30,17 @@ struct i2c_adapter; struct xc5000_config { u8 i2c_address; u32 if_khz; + u8 radio_input; }; /* xc5000 callback command */ #define XC5000_TUNER_RESET 0 +/* Possible Radio inputs */ +#define XC5000_RADIO_NOT_CONFIGURED 0 +#define XC5000_RADIO_FM1 1 +#define XC5000_RADIO_FM2 2 + /* For each bridge framework, when it attaches either analog or digital, * it has to store a reference back to its _core equivalent structure, * so that it can service the hardware by steering gpio's etc. -- cgit v1.2.3-70-g09d2 From f91cb65b94114f30cf43738ff923f272e4f2ae13 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 30 Sep 2009 22:44:19 -0300 Subject: V4L/DVB (13077): em28xx: Add support for new variant of KWorld 2800d Seems that the reference design used for the KWorld 2800d switched from the em2860 to em2862, so we need to add the new USB id (and the i2c hash remains so all we need is the default em2862 id. Thanks to Ian Young for reporting the issue and testing the fix. Cc: Ian Young Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.em28xx | 2 +- drivers/media/video/em28xx/em28xx-cards.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index b8afef4c0e0..f8ea8acdd89 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx @@ -1,5 +1,5 @@ 0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800] - 1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883,eb1a:2868] + 1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2862,eb1a:2870,eb1a:2881,eb1a:2883,eb1a:2868] 2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036] 3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208] 4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200,2040:4201] diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index c0fd5c6feea..a41256f78d6 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -1608,6 +1608,8 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM2820_BOARD_UNKNOWN }, { USB_DEVICE(0xeb1a, 0x2861), .driver_info = EM2820_BOARD_UNKNOWN }, + { USB_DEVICE(0xeb1a, 0x2862), + .driver_info = EM2820_BOARD_UNKNOWN }, { USB_DEVICE(0xeb1a, 0x2870), .driver_info = EM2820_BOARD_UNKNOWN }, { USB_DEVICE(0xeb1a, 0x2881), -- cgit v1.2.3-70-g09d2 From ec994d0505fc3dde5f46203602c76b527e2ac69d Mon Sep 17 00:00:00 2001 From: UroÅ¡ Vampl Date: Wed, 30 Sep 2009 22:53:37 -0300 Subject: V4L/DVB (13078): em28xx: fix support for Terratec Cinergy T XS (005e) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make analog audio, dvb and the remote work on a Terratec Cinergy Hybrid XS (em2882). Note by djh: Thanks go out fo Andrej Suligoi for his contribution in providing and testing pretty much the exact same patch as provided by Uros. Between the two of them, they got all the core functionality working for the device. Cc: Andrej Suligoi Signed-off-by: UroÅ¡ Vampl Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-cards.c | 6 ++++++ drivers/media/video/em28xx/em28xx-dvb.c | 1 + 2 files changed, 7 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index a41256f78d6..4cfaa83b64d 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -1384,7 +1384,12 @@ struct em28xx_board em28xx_boards[] = { .valid = EM28XX_BOARD_NOT_VALIDATED, .tuner_type = TUNER_XC2028, .tuner_gpio = default_tuner_gpio, + .mts_firmware = 1, .decoder = EM28XX_TVP5150, + .has_dvb = 1, + .dvb_gpio = hauppauge_wintv_hvr_900_digital, + .ir_codes = &ir_codes_terratec_cinergy_xs_table, + .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = TVP5150_COMPOSITE0, @@ -2052,6 +2057,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) switch (dev->model) { case EM2880_BOARD_EMPIRE_DUAL_TV: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: + case EM2882_BOARD_TERRATEC_HYBRID_XS: ctl->demod = XC3028_FE_ZARLINK456; break; case EM2880_BOARD_TERRATEC_HYBRID_XS: diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index db749461e5c..19f5156f653 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c @@ -493,6 +493,7 @@ static int dvb_init(struct em28xx *dev) } break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: + case EM2882_BOARD_TERRATEC_HYBRID_XS: case EM2880_BOARD_EMPIRE_DUAL_TV: dvb->frontend = dvb_attach(zl10353_attach, &em28xx_zl10353_xc3028_no_i2c_gate, -- cgit v1.2.3-70-g09d2 From 2930992c40ad9c665e2e6e2b8870d3f56428a83d Mon Sep 17 00:00:00 2001 From: "Beholder Intl. Ltd. Dmitry Belimov" Date: Wed, 30 Sep 2009 23:02:21 -0300 Subject: V4L/DVB (13080): saa7134: add support for the digital side of the Behold X7 Add support for the digital side of the Behold X7 Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-cards.c | 1 + drivers/media/video/saa7134/saa7134-dvb.c | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 09013229d4a..7de7f1f0add 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -5239,6 +5239,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, + .mpeg = SAA7134_MPEG_DVB, .inputs = { { .name = name_tv, .vmux = 2, diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index a26e997a9ce..204e2bc9fe7 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -40,6 +40,7 @@ #include "tda1004x.h" #include "nxt200x.h" #include "tuner-xc2028.h" +#include "xc5000.h" #include "tda10086.h" #include "tda826x.h" @@ -871,6 +872,20 @@ static struct zl10353_config behold_h6_config = { .disable_i2c_gate_ctrl = 1, }; +static struct xc5000_config behold_x7_tunerconfig = { + .i2c_address = 0xc2>>1, + .if_khz = 4560, + .radio_input = 1, +}; + +static struct zl10353_config behold_x7_config = { + .demod_address = 0x1e>>1, + .if2 = 45600, + .no_tuner = 1, + .parallel_ts = 1, + .disable_i2c_gate_ctrl = 1, +}; + /* ================================================================== * tda10086 based DVB-S cards, helper functions */ @@ -1482,6 +1497,15 @@ static int dvb_init(struct saa7134_dev *dev) TUNER_PHILIPS_FMD1216MEX_MK3); } break; + case SAA7134_BOARD_BEHOLD_X7: + fe0->dvb.frontend = dvb_attach(zl10353_attach, + &behold_x7_config, + &dev->i2c_adap); + if (fe0->dvb.frontend) { + dvb_attach(xc5000_attach, fe0->dvb.frontend, + &dev->i2c_adap, &behold_x7_tunerconfig); + } + break; case SAA7134_BOARD_AVERMEDIA_A700_PRO: case SAA7134_BOARD_AVERMEDIA_A700_HYBRID: /* Zarlink ZL10313 */ -- cgit v1.2.3-70-g09d2 From 2a0d056015222d534e32e7556de1a684ad9e61f5 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 30 Sep 2009 23:04:39 -0300 Subject: V4L/DVB (13081): saa7134: use the #define for the xc5000 radio_input field Dmitri's patch for the Behold X7 didn't use the #define I had setup for XC5000_RADIO_FM1, so cut over to using that instead of "1". Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-dvb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 204e2bc9fe7..058b56bf671 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -875,7 +875,7 @@ static struct zl10353_config behold_h6_config = { static struct xc5000_config behold_x7_tunerconfig = { .i2c_address = 0xc2>>1, .if_khz = 4560, - .radio_input = 1, + .radio_input = XC5000_RADIO_FM1, }; static struct zl10353_config behold_x7_config = { -- cgit v1.2.3-70-g09d2 From 2e3c4723d5c2d6b4fa705c3dcd062b5004ab9b2f Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 30 Sep 2009 23:10:17 -0300 Subject: V4L/DVB (13082): em28xx: remove "not validated" status from Terratec Cinergy T XS (005e) The board support has been validated by the user, so get rid of the warning that shows up on board load. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-cards.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 4cfaa83b64d..7ccac2095b7 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -1381,7 +1381,6 @@ struct em28xx_board em28xx_boards[] = { }, [EM2882_BOARD_TERRATEC_HYBRID_XS] = { .name = "Terratec Hybrid XS (em2882)", - .valid = EM28XX_BOARD_NOT_VALIDATED, .tuner_type = TUNER_XC2028, .tuner_gpio = default_tuner_gpio, .mts_firmware = 1, -- cgit v1.2.3-70-g09d2 From 74618244003a5a9e11240af8c5795ae747d9a2e0 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 26 Sep 2009 22:50:44 -0300 Subject: V4L/DVB (13085): cx23885: Fix support for v4l2-dbg access to CX2388[578] and CX23417 regs This changes corrects the ioctl() operations for both the CX2388[578] analog video and MPEG video device nodes to properly and consistently support VIDIOC_G_CHIP_IDENT, VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER ioctl()s. This caused some ioctl() support routines to be broken out into a separate source file. Now v4l2-dbg can be used to manipulate CX2388[578] and CX23417 registers including the CX2388[57] functions handled by the cx25840 module. This was done in anticipation of developing a new v4l2_subdev for the integrated IR controller of the CX23888. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/Makefile | 1 + drivers/media/video/cx23885/cx23885-417.c | 10 +- drivers/media/video/cx23885/cx23885-ioctl.c | 197 ++++++++++++++++++++++++++++ drivers/media/video/cx23885/cx23885-ioctl.h | 39 ++++++ drivers/media/video/cx23885/cx23885-video.c | 34 +---- drivers/media/video/cx23885/cx23885.h | 4 + 6 files changed, 253 insertions(+), 32 deletions(-) create mode 100644 drivers/media/video/cx23885/cx23885-ioctl.c create mode 100644 drivers/media/video/cx23885/cx23885-ioctl.h (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile index ab8ea35c9bf..93a954c23f4 100644 --- a/drivers/media/video/cx23885/Makefile +++ b/drivers/media/video/cx23885/Makefile @@ -1,5 +1,6 @@ cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \ cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \ + cx23885-ioctl.o \ netup-init.o cimax2.o netup-eeprom.o obj-$(CONFIG_VIDEO_CX23885) += cx23885.o diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 6c3b51ce337..0eed852c61e 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c @@ -37,6 +37,7 @@ #include #include "cx23885.h" +#include "cx23885-ioctl.h" #define CX23885_FIRM_IMAGE_SIZE 376836 #define CX23885_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw" @@ -318,7 +319,7 @@ static int mc417_wait_ready(struct cx23885_dev *dev) } } -static int mc417_register_write(struct cx23885_dev *dev, u16 address, u32 value) +int mc417_register_write(struct cx23885_dev *dev, u16 address, u32 value) { u32 regval; @@ -382,7 +383,7 @@ static int mc417_register_write(struct cx23885_dev *dev, u16 address, u32 value) return mc417_wait_ready(dev); } -static int mc417_register_read(struct cx23885_dev *dev, u16 address, u32 *value) +int mc417_register_read(struct cx23885_dev *dev, u16 address, u32 *value) { int retval; u32 regval; @@ -1724,6 +1725,11 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { .vidioc_log_status = vidioc_log_status, .vidioc_querymenu = vidioc_querymenu, .vidioc_queryctrl = vidioc_queryctrl, + .vidioc_g_chip_ident = cx23885_g_chip_ident, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .vidioc_g_register = cx23885_g_register, + .vidioc_s_register = cx23885_s_register, +#endif }; static struct video_device cx23885_mpeg_template = { diff --git a/drivers/media/video/cx23885/cx23885-ioctl.c b/drivers/media/video/cx23885/cx23885-ioctl.c new file mode 100644 index 00000000000..3a497b6c4fd --- /dev/null +++ b/drivers/media/video/cx23885/cx23885-ioctl.c @@ -0,0 +1,197 @@ +/* + * Driver for the Conexant CX23885/7/8 PCIe bridge + * + * Various common ioctl() support functions + * + * Copyright (c) 2009 Andy Walls + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "cx23885.h" +#include + +int cx23885_g_chip_ident(struct file *file, void *fh, + struct v4l2_dbg_chip_ident *chip) +{ + struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; + int err = 0; + u8 rev; + + chip->ident = V4L2_IDENT_NONE; + chip->revision = 0; + switch (chip->match.type) { + case V4L2_CHIP_MATCH_HOST: + switch (chip->match.addr) { + case 0: + rev = cx_read(RDR_CFG2) & 0xff; + switch (dev->pci->device) { + case 0x8852: + /* rev 0x04 could be '885 or '888. Pick '888. */ + if (rev == 0x04) + chip->ident = V4L2_IDENT_CX23888; + else + chip->ident = V4L2_IDENT_CX23885; + break; + case 0x8880: + if (rev == 0x0e || rev == 0x0f) + chip->ident = V4L2_IDENT_CX23887; + else + chip->ident = V4L2_IDENT_CX23888; + break; + default: + chip->ident = V4L2_IDENT_UNKNOWN; + break; + } + chip->revision = (dev->pci->device << 16) | (rev << 8) | + (dev->hwrevision & 0xff); + break; + case 1: + if (dev->v4l_device != NULL) { + chip->ident = V4L2_IDENT_CX23417; + chip->revision = 0; + } + break; + default: + err = -EINVAL; /* per V4L2 spec */ + break; + } + break; + case V4L2_CHIP_MATCH_I2C_DRIVER: + /* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */ + call_all(dev, core, g_chip_ident, chip); + break; + case V4L2_CHIP_MATCH_I2C_ADDR: + /* + * We could return V4L2_IDENT_UNKNOWN, but we don't do the work + * to look if a chip is at the address with no driver. That's a + * dangerous thing to do with EEPROMs anyway. + */ + call_all(dev, core, g_chip_ident, chip); + break; + default: + err = -EINVAL; + break; + } + return err; +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int cx23885_g_host_register(struct cx23885_dev *dev, + struct v4l2_dbg_register *reg) +{ + if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0)) + return -EINVAL; + + reg->size = 4; + reg->val = cx_read(reg->reg); + return 0; +} + +static int cx23417_g_register(struct cx23885_dev *dev, + struct v4l2_dbg_register *reg) +{ + u32 value; + + if (dev->v4l_device == NULL) + return -EINVAL; + + if ((reg->reg & 0x3) != 0 || reg->reg >= 0x10000) + return -EINVAL; + + if (mc417_register_read(dev, (u16) reg->reg, &value)) + return -EINVAL; /* V4L2 spec, but -EREMOTEIO really */ + + reg->size = 4; + reg->val = value; + return 0; +} + +int cx23885_g_register(struct file *file, void *fh, + struct v4l2_dbg_register *reg) +{ + struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (reg->match.type == V4L2_CHIP_MATCH_HOST) { + switch (reg->match.addr) { + case 0: + return cx23885_g_host_register(dev, reg); + case 1: + return cx23417_g_register(dev, reg); + default: + break; + } + } + + /* FIXME - any error returns should not be ignored */ + call_all(dev, core, g_register, reg); + return 0; +} + +static int cx23885_s_host_register(struct cx23885_dev *dev, + struct v4l2_dbg_register *reg) +{ + if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0)) + return -EINVAL; + + reg->size = 4; + cx_write(reg->reg, reg->val); + return 0; +} + +static int cx23417_s_register(struct cx23885_dev *dev, + struct v4l2_dbg_register *reg) +{ + if (dev->v4l_device == NULL) + return -EINVAL; + + if ((reg->reg & 0x3) != 0 || reg->reg >= 0x10000) + return -EINVAL; + + if (mc417_register_write(dev, (u16) reg->reg, (u32) reg->val)) + return -EINVAL; /* V4L2 spec, but -EREMOTEIO really */ + + reg->size = 4; + return 0; +} + +int cx23885_s_register(struct file *file, void *fh, + struct v4l2_dbg_register *reg) +{ + struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (reg->match.type == V4L2_CHIP_MATCH_HOST) { + switch (reg->match.addr) { + case 0: + return cx23885_s_host_register(dev, reg); + case 1: + return cx23417_s_register(dev, reg); + default: + break; + } + } + + /* FIXME - any error returns should not be ignored */ + call_all(dev, core, s_register, reg); + return 0; +} +#endif diff --git a/drivers/media/video/cx23885/cx23885-ioctl.h b/drivers/media/video/cx23885/cx23885-ioctl.h new file mode 100644 index 00000000000..80b0f4923c6 --- /dev/null +++ b/drivers/media/video/cx23885/cx23885-ioctl.h @@ -0,0 +1,39 @@ +/* + * Driver for the Conexant CX23885/7/8 PCIe bridge + * + * Various common ioctl() support functions + * + * Copyright (c) 2009 Andy Walls + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _CX23885_IOCTL_H_ +#define _CX23885_IOCTL_H_ + +int cx23885_g_chip_ident(struct file *file, void *fh, + struct v4l2_dbg_chip_ident *chip); + +#ifdef CONFIG_VIDEO_ADV_DEBUG +int cx23885_g_register(struct file *file, void *fh, + struct v4l2_dbg_register *reg); + + +int cx23885_s_register(struct file *file, void *fh, + struct v4l2_dbg_register *reg); + +#endif +#endif diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 654cc253cd5..3f1d07e6490 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -35,6 +35,7 @@ #include "cx23885.h" #include #include +#include "cx23885-ioctl.h" MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards"); MODULE_AUTHOR("Steven Toth "); @@ -1312,34 +1313,6 @@ static int vidioc_s_frequency(struct file *file, void *priv, cx23885_set_freq(dev, f); } -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int vidioc_g_register(struct file *file, void *fh, - struct v4l2_dbg_register *reg) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; - - if (!v4l2_chip_match_host(®->match)) - return -EINVAL; - - call_all(dev, core, g_register, reg); - - return 0; -} - -static int vidioc_s_register(struct file *file, void *fh, - struct v4l2_dbg_register *reg) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; - - if (!v4l2_chip_match_host(®->match)) - return -EINVAL; - - call_all(dev, core, s_register, reg); - - return 0; -} -#endif - /* ----------------------------------------------------------- */ static void cx23885_vid_timeout(unsigned long data) @@ -1449,9 +1422,10 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_s_tuner = vidioc_s_tuner, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, + .vidioc_g_chip_ident = cx23885_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG - .vidioc_g_register = vidioc_g_register, - .vidioc_s_register = vidioc_s_register, + .vidioc_g_register = cx23885_g_register, + .vidioc_s_register = cx23885_s_register, #endif }; diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index cc7a165561f..f4c4108f23f 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h @@ -515,6 +515,10 @@ extern void cx23885_417_check_encoder(struct cx23885_dev *dev); extern void cx23885_mc417_init(struct cx23885_dev *dev); extern int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value); extern int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value); +extern int mc417_register_read(struct cx23885_dev *dev, + u16 address, u32 *value); +extern int mc417_register_write(struct cx23885_dev *dev, + u16 address, u32 value); extern void mc417_gpio_set(struct cx23885_dev *dev, u32 mask); extern void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask); extern void mc417_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput); -- cgit v1.2.3-70-g09d2 From 29f8a0a50ac32ac4bc1937dcfdf8de6c406a5f10 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 26 Sep 2009 23:17:30 -0300 Subject: V4L/DVB (13086): cx23885: Add skeleton v4l2_subdev for the CX23888 integrated IR controller This change adds a skeletal implementation of a v4l2_subdevice to provide encapsulation and abstraction of the CX23888's integrated consumer infrared controller. This change also instantiates the cx23888_ir subdev for the HVR-1850 which has IR hardware physically wired up to a CX23888. The cx23888_ir subdev code is being written with long-term objectives to: 1. port it to the cx25840 module for the CX2584x, CX2583x, CX23885, & CX231xx IR controllers 2. possibly port it to the cx18 module for the CX23418 IR controller 3. have the IR subdevice accessed abstractly in the cx23885 module, so the driver can ignore the difference between the CX23885 and CX23888. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/Makefile | 2 +- drivers/media/video/cx23885/cx23885-cards.c | 11 +- drivers/media/video/cx23885/cx23885-core.c | 20 +++ drivers/media/video/cx23885/cx23885-ioctl.c | 11 ++ drivers/media/video/cx23885/cx23885.h | 8 + drivers/media/video/cx23885/cx23888-ir.c | 233 ++++++++++++++++++++++++++++ drivers/media/video/cx23885/cx23888-ir.h | 28 ++++ 7 files changed, 310 insertions(+), 3 deletions(-) create mode 100644 drivers/media/video/cx23885/cx23888-ir.c create mode 100644 drivers/media/video/cx23885/cx23888-ir.h (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile index 93a954c23f4..3832a1cb768 100644 --- a/drivers/media/video/cx23885/Makefile +++ b/drivers/media/video/cx23885/Makefile @@ -1,6 +1,6 @@ cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \ cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \ - cx23885-ioctl.o \ + cx23885-ioctl.o cx23888-ir.o \ netup-init.o cimax2.o netup-eeprom.o obj-$(CONFIG_VIDEO_CX23885) += cx23885.o diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index bfdf79f1033..4b5aa08036f 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -28,6 +28,7 @@ #include "cx23885.h" #include "tuner-xc2028.h" #include "netup-init.h" +#include "cx23888-ir.h" /* ------------------------------------------------------------------ */ /* board config info */ @@ -801,6 +802,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) int cx23885_ir_init(struct cx23885_dev *dev) { + int ret = 0; switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1250: case CX23885_BOARD_HAUPPAUGE_HVR1500: @@ -812,15 +814,20 @@ int cx23885_ir_init(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1275: case CX23885_BOARD_HAUPPAUGE_HVR1255: case CX23885_BOARD_HAUPPAUGE_HVR1210: - case CX23885_BOARD_HAUPPAUGE_HVR1850: /* FIXME: Implement me */ break; + case CX23885_BOARD_HAUPPAUGE_HVR1850: + ret = cx23888_ir_probe(dev); + if (ret) + break; + dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_888_IR); + break; case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: request_module("ir-kbd-i2c"); break; } - return 0; + return ret; } void cx23885_card_setup(struct cx23885_dev *dev) diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index c31284ba19d..73be16b0d2a 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -32,6 +32,7 @@ #include "cx23885.h" #include "cimax2.h" +#include "cx23888-ir.h" MODULE_DESCRIPTION("Driver for cx23885 based TV cards"); MODULE_AUTHOR("Steven Toth "); @@ -753,6 +754,23 @@ static void cx23885_dev_checkrevision(struct cx23885_dev *dev) __func__, dev->hwrevision); } +/* Find the first v4l2_subdev member of the group id in hw */ +struct v4l2_subdev *cx23885_find_hw(struct cx23885_dev *dev, u32 hw) +{ + struct v4l2_subdev *result = NULL; + struct v4l2_subdev *sd; + + spin_lock(&dev->v4l2_dev.lock); + v4l2_device_for_each_subdev(sd, &dev->v4l2_dev) { + if (sd->grp_id == hw) { + result = sd; + break; + } + } + spin_unlock(&dev->v4l2_dev.lock); + return result; +} + static int cx23885_dev_setup(struct cx23885_dev *dev) { int i; @@ -1914,6 +1932,8 @@ static void __devexit cx23885_finidev(struct pci_dev *pci_dev) cx23885_shutdown(dev); + cx23888_ir_remove(dev); + pci_disable_device(pci_dev); /* unregister stuff */ diff --git a/drivers/media/video/cx23885/cx23885-ioctl.c b/drivers/media/video/cx23885/cx23885-ioctl.c index 3a497b6c4fd..dfb4627fb34 100644 --- a/drivers/media/video/cx23885/cx23885-ioctl.c +++ b/drivers/media/video/cx23885/cx23885-ioctl.c @@ -65,6 +65,17 @@ int cx23885_g_chip_ident(struct file *file, void *fh, chip->revision = 0; } break; + case 2: + /* + * The integrated IR controller on the CX23888 is + * host chip 2. It may not be used/initialized or sd_ir + * may be pointing at the cx25840 subdevice for the + * IR controller on the CX23885. Thus we find it + * without using the dev->sd_ir pointer. + */ + call_hw(dev, CX23885_HW_888_IR, core, g_chip_ident, + chip); + break; default: err = -EINVAL; /* per V4L2 spec */ break; diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index f4c4108f23f..f7ed146566d 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h @@ -355,6 +355,7 @@ struct cx23885_dev { unsigned char radio_addr; unsigned int has_radio; struct v4l2_subdev *sd_cx25840; + struct v4l2_subdev *sd_ir; /* V4l */ u32 freq; @@ -383,6 +384,13 @@ static inline struct cx23885_dev *to_cx23885(struct v4l2_device *v4l2_dev) #define call_all(dev, o, f, args...) \ v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args) +#define CX23885_HW_888_IR (1 << 0) + +#define call_hw(dev, grpid, o, f, args...) \ + v4l2_device_call_all(&dev->v4l2_dev, grpid, o, f, ##args) + +extern struct v4l2_subdev *cx23885_find_hw(struct cx23885_dev *dev, u32 hw); + extern struct list_head cx23885_devlist; #define SRAM_CH01 0 /* Video A */ diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c new file mode 100644 index 00000000000..12df0e3a235 --- /dev/null +++ b/drivers/media/video/cx23885/cx23888-ir.c @@ -0,0 +1,233 @@ +/* + * Driver for the Conexant CX23885/7/8 PCIe bridge + * + * CX23888 Integrated Consumer Infrared Controller + * + * Copyright (C) 2009 Andy Walls + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#include +#include + +#include "cx23885.h" + +#define CX23888_IR_REG_BASE 0x170000 +/* + * These CX23888 register offsets have a straightforward one to one mapping + * to the CX23885 register offsets of 0x200 through 0x218 + */ +#define CX23888_IR_CNTRL_REG 0x170000 +#define CX23888_IR_TXCLK_REG 0x170004 +#define CX23888_IR_RXCLK_REG 0x170008 +#define CX23888_IR_CDUTY_REG 0x17000C +#define CX23888_IR_STATS_REG 0x170010 +#define CX23888_IR_IRQEN_REG 0x170014 +#define CX23888_IR_FILTR_REG 0x170018 +/* This register doesn't follow the pattern; it's 0x23C on a CX23885 */ +#define CX23888_IR_FIFO_REG 0x170040 + +/* CX23888 unique registers */ +#define CX23888_IR_SEEDP_REG 0x17001C +#define CX23888_IR_TIMOL_REG 0x170020 +#define CX23888_IR_WAKE0_REG 0x170024 +#define CX23888_IR_WAKE1_REG 0x170028 +#define CX23888_IR_WAKE2_REG 0x17002C +#define CX23888_IR_MASK0_REG 0x170030 +#define CX23888_IR_MASK1_REG 0x170034 +#define CX23888_IR_MAKS2_REG 0x170038 +#define CX23888_IR_DPIPG_REG 0x17003C +#define CX23888_IR_LEARN_REG 0x170044 + + +struct cx23888_ir_state { + struct v4l2_subdev sd; + struct cx23885_dev *dev; + u32 id; + u32 rev; +}; + +static inline struct cx23888_ir_state *to_state(struct v4l2_subdev *sd) +{ + return v4l2_get_subdevdata(sd); +} + +static int cx23888_ir_write(struct cx23885_dev *dev, u32 addr, u8 value) +{ + u32 reg = (addr & ~3); + int shift = (addr & 3) * 8; + u32 x = cx_read(reg); + + x = (x & ~(0xff << shift)) | ((u32)value << shift); + cx_write(reg, x); + return 0; +} + +static +inline int cx23888_ir_write4(struct cx23885_dev *dev, u32 addr, u32 value) +{ + cx_write(addr, value); + return 0; +} + +static u8 cx23888_ir_read(struct cx23885_dev *dev, u32 addr) +{ + u32 x = cx_read((addr & ~3)); + int shift = (addr & 3) * 8; + + return (x >> shift) & 0xff; +} + +static inline u32 cx23888_ir_read4(struct cx23885_dev *dev, u32 addr) +{ + return cx_read(addr); +} + +static int cx23888_ir_and_or(struct cx23885_dev *dev, u32 addr, + unsigned and_mask, u8 or_value) +{ + return cx23888_ir_write(dev, addr, + (cx23888_ir_read(dev, addr) & and_mask) | + or_value); +} + +static inline int cx23888_ir_and_or4(struct cx23885_dev *dev, u32 addr, + u32 and_mask, u32 or_value) +{ + cx_andor(addr, and_mask, or_value); + return 0; +} + +static int cx23888_ir_log_status(struct v4l2_subdev *sd) +{ + struct cx23888_ir_state *state = to_state(sd); + struct cx23885_dev *dev = state->dev; + u8 cntrl = cx23888_ir_read(dev, CX23888_IR_CNTRL_REG+1); + v4l2_info(sd, "receiver %sabled\n", cntrl & 0x1 ? "en" : "dis"); + v4l2_info(sd, "transmitter %sabled\n", cntrl & 0x2 ? "en" : "dis"); + return 0; +} + +static inline int cx23888_ir_dbg_match(const struct v4l2_dbg_match *match) +{ + return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 2; +} + +static int cx23888_ir_g_chip_ident(struct v4l2_subdev *sd, + struct v4l2_dbg_chip_ident *chip) +{ + struct cx23888_ir_state *state = to_state(sd); + + if (cx23888_ir_dbg_match(&chip->match)) { + chip->ident = state->id; + chip->revision = state->rev; + } + return 0; +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int cx23888_ir_g_register(struct v4l2_subdev *sd, + struct v4l2_dbg_register *reg) +{ + struct cx23888_ir_state *state = to_state(sd); + u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg; + + if (!cx23888_ir_dbg_match(®->match)) + return -EINVAL; + if ((addr & 0x3) != 0) + return -EINVAL; + if (addr < CX23888_IR_CNTRL_REG || addr > CX23888_IR_LEARN_REG) + return -EINVAL; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + reg->size = 4; + reg->val = cx23888_ir_read4(state->dev, addr); + return 0; +} + +static int cx23888_ir_s_register(struct v4l2_subdev *sd, + struct v4l2_dbg_register *reg) +{ + struct cx23888_ir_state *state = to_state(sd); + u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg; + + if (!cx23888_ir_dbg_match(®->match)) + return -EINVAL; + if ((addr & 0x3) != 0) + return -EINVAL; + if (addr < CX23888_IR_CNTRL_REG || addr > CX23888_IR_LEARN_REG) + return -EINVAL; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + cx23888_ir_write4(state->dev, addr, reg->val); + return 0; +} +#endif + +static const struct v4l2_subdev_core_ops cx23888_ir_core_ops = { + .g_chip_ident = cx23888_ir_g_chip_ident, + .log_status = cx23888_ir_log_status, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .g_register = cx23888_ir_g_register, + .s_register = cx23888_ir_s_register, +#endif +}; + +static const struct v4l2_subdev_ops cx23888_ir_controller_ops = { + .core = &cx23888_ir_core_ops, +}; + +int cx23888_ir_probe(struct cx23885_dev *dev) +{ + struct cx23888_ir_state *state; + struct v4l2_subdev *sd; + + state = kzalloc(sizeof(struct cx23888_ir_state), GFP_KERNEL); + if (state == NULL) + return -ENOMEM; + + state->dev = dev; + state->id = V4L2_IDENT_CX23888_IR; + state->rev = 0; + sd = &state->sd; + + v4l2_subdev_init(sd, &cx23888_ir_controller_ops); + v4l2_set_subdevdata(sd, state); + /* FIXME - fix the formatting of dev->v4l2_dev.name and use it */ + snprintf(sd->name, sizeof(sd->name), "%s/888-ir", dev->name); + sd->grp_id = CX23885_HW_888_IR; + return v4l2_device_register_subdev(&dev->v4l2_dev, sd); +} + +int cx23888_ir_remove(struct cx23885_dev *dev) +{ + struct v4l2_subdev *sd; + struct cx23888_ir_state *state; + + sd = cx23885_find_hw(dev, CX23885_HW_888_IR); + if (sd == NULL) + return -ENODEV; + + /* Disable receiver and transmitter */ + cx23888_ir_and_or(dev, CX23888_IR_CNTRL_REG+1, 0xfc, 0); + + state = to_state(sd); + v4l2_device_unregister_subdev(sd); + kfree(state); + /* Nothing more to free() as state held the actual v4l2_subdev object */ + return 0; +} diff --git a/drivers/media/video/cx23885/cx23888-ir.h b/drivers/media/video/cx23885/cx23888-ir.h new file mode 100644 index 00000000000..3d446f9eb94 --- /dev/null +++ b/drivers/media/video/cx23885/cx23888-ir.h @@ -0,0 +1,28 @@ +/* + * Driver for the Conexant CX23885/7/8 PCIe bridge + * + * CX23888 Integrated Consumer Infrared Controller + * + * Copyright (C) 2009 Andy Walls + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#ifndef _CX23888_IR_H_ +#define _CX23888_IR_H_ +int cx23888_ir_probe(struct cx23885_dev *dev); +int cx23888_ir_remove(struct cx23885_dev *dev); +#endif -- cgit v1.2.3-70-g09d2 From c7dd1ecdc0112b9700ed6ad20a6e4e07d125044b Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 26 Sep 2009 23:32:54 -0300 Subject: V4L/DVB (13087): cx25840: Improve detection of CX2388[578] A/V cores Add improved logic to detect the exact CX2388[578] A/V core that is being probed. Also cleaned up detection and logging for CX2310[12], CX2583[67], and CX2584[0123] cores and chips. Also added code to identify a CX2388[578] A/V decoder core that is not responding properly. Typical symptoms include registers 0x00-0xff responding properly but all other registers returning the same value (0x13 and 0x5 have been observed). This state will cause proper detection of '885 vs. '887 vs. '888 to fail and the chip won't respond to get configured properly anyway. I have no method of reseting the core to a working state at this time; but I didn't try too hard to work one out either. The problem likely only occurs in development. I suspect configuring the SYS PLL VCO to oscillate too slowly (286.3 MHz?) before post divide may be the root cause, when encountered. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx25840/cx25840-core.c | 97 ++++++++++++++++++++++++------ 1 file changed, 79 insertions(+), 18 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 1aeaf18a9be..e8365672999 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -1521,12 +1521,35 @@ static const struct v4l2_subdev_ops cx25840_ops = { /* ----------------------------------------------------------------------- */ +static u32 get_cx2388x_ident(struct i2c_client *client) +{ + u32 ret; + + /* Come out of digital power down */ + cx25840_write(client, 0x000, 0); + + if (cx25840_read4(client, 0x204) & 0xffff) { + /* IR Tx Clk Divider register exists; chip must be a CX23885 */ + ret = V4L2_IDENT_CX23885_AV; + } else if (cx25840_read4(client, 0x300) & 0x0fffffff) { + /* DIF PLL Freq Word reg exists; chip must be a CX23888 */ + ret = V4L2_IDENT_CX23888_AV; + } else { + /* A CX23887 A/V core has neither IR nor DIF */ + ret = V4L2_IDENT_CX23887_AV; + } + + /* Back into digital power down */ + cx25840_write(client, 0x000, 2); + return ret; +} + static int cx25840_probe(struct i2c_client *client, const struct i2c_device_id *did) { struct cx25840_state *state; struct v4l2_subdev *sd; - u32 id; + u32 id = V4L2_IDENT_NONE; u16 device_id; /* Check if the adapter supports the needed features */ @@ -1543,17 +1566,22 @@ static int cx25840_probe(struct i2c_client *client, * 0x83 for the cx2583x and 0x84 for the cx2584x */ if ((device_id & 0xff00) == 0x8300) { id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6; - } - else if ((device_id & 0xff00) == 0x8400) { + } else if ((device_id & 0xff00) == 0x8400) { id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf); } else if (device_id == 0x0000) { - id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6; - } else if (device_id == 0x1313) { - id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6; + id = get_cx2388x_ident(client); } else if ((device_id & 0xfff0) == 0x5A30) { - id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf); - } - else { + /* The CX23100 (0x5A3C = 23100) doesn't have an A/V decoder */ + id = V4L2_IDENT_CX2310X_AV; + } else if ((device_id & 0xff) == (device_id >> 8)) { + v4l_err(client, + "likely a confused/unresponsive cx2388[578] A/V decoder" + " found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); + v4l_err(client, "A method to reset it from the cx25840 driver" + " software is not known at this time\n"); + return -ENODEV; + } else { v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n"); return -ENODEV; } @@ -1564,17 +1592,50 @@ static int cx25840_probe(struct i2c_client *client, sd = &state->sd; v4l2_i2c_subdev_init(sd, client, &cx25840_ops); - /* Note: revision '(device_id & 0x0f) == 2' was never built. The - marking skips from 0x1 == 22 to 0x3 == 23. */ - v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n", - (device_id & 0xfff0) >> 4, - (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : (device_id & 0x0f), - client->addr << 1, client->adapter->name); + switch (id) { + case V4L2_IDENT_CX23885_AV: + state->is_cx23885 = 1; + v4l_info(client, "cx23885 A/V decoder found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); + break; + case V4L2_IDENT_CX23887_AV: + state->is_cx23885 = 1; + v4l_info(client, "cx23887 A/V decoder found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); + break; + case V4L2_IDENT_CX23888_AV: + state->is_cx23885 = 1; + v4l_info(client, "cx23888 A/V decoder found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); + break; + case V4L2_IDENT_CX2310X_AV: + state->is_cx231xx = 1; + v4l_info(client, "cx%d A/V decoder found @ 0x%x (%s)\n", + device_id, client->addr << 1, client->adapter->name); + break; + case V4L2_IDENT_CX25840: + case V4L2_IDENT_CX25841: + case V4L2_IDENT_CX25842: + case V4L2_IDENT_CX25843: + /* Note: revision '(device_id & 0x0f) == 2' was never built. The + marking skips from 0x1 == 22 to 0x3 == 23. */ + v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n", + (device_id & 0xfff0) >> 4, + (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 + : (device_id & 0x0f), + client->addr << 1, client->adapter->name); + break; + case V4L2_IDENT_CX25836: + case V4L2_IDENT_CX25837: + state->is_cx25836 = 1; + default: + v4l_info(client, "cx25%3x-%x found @ 0x%x (%s)\n", + (device_id & 0xfff0) >> 4, device_id & 0x0f, + client->addr << 1, client->adapter->name); + break; + } state->c = client; - state->is_cx25836 = ((device_id & 0xff00) == 0x8300); - state->is_cx23885 = (device_id == 0x0000) || (device_id == 0x1313); - state->is_cx231xx = (device_id == 0x5a3e); state->vid_input = CX25840_COMPOSITE7; state->aud_input = CX25840_AUDIO8; state->audclk_freq = 48000; -- cgit v1.2.3-70-g09d2 From 2a03f03471d3232037e656570ccaf3ff2ffd01e8 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 26 Sep 2009 23:47:21 -0300 Subject: V4L/DVB (13088): cx25840: Convert chip/core family checks to static inline functions Change logic to check for various chip or core families to inline functions. Checks for specific chips should be made against the state->id field now. This is in preparation for chip/core specific code for setting up PLLs for the CX2388[578] family of cores, that all run with different crystal frequencies. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx25840/cx25840-audio.c | 44 ++++++++++----------- drivers/media/video/cx25840/cx25840-core.c | 55 ++++++++++++-------------- drivers/media/video/cx25840/cx25840-core.h | 22 +++++++++-- drivers/media/video/cx25840/cx25840-firmware.c | 10 ++--- 4 files changed, 71 insertions(+), 60 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c index 2f846f5e0f9..fbccbdce26e 100644 --- a/drivers/media/video/cx25840/cx25840-audio.c +++ b/drivers/media/video/cx25840/cx25840-audio.c @@ -32,19 +32,19 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) /* common for all inputs and rates */ /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ - if (!state->is_cx23885 && !state->is_cx231xx) + if (!is_cx2388x(state) && !is_cx231xx(state)) cx25840_write(client, 0x127, 0x50); if (state->aud_input != CX25840_AUDIO_SERIAL) { switch (freq) { case 32000: - if (state->is_cx23885) { + if (is_cx2388x(state)) { /* We don't have register values * so avoid destroying registers. */ break; } - if (!state->is_cx231xx) { + if (!is_cx231xx(state)) { /* VID_PLL and AUX_PLL */ cx25840_write4(client, 0x108, 0x1006040f); @@ -52,7 +52,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) cx25840_write4(client, 0x110, 0x01bb39ee); } - if (state->is_cx25836) + if (is_cx2583x(state)) break; /* src3/4/6_ctl = 0x0801f77f */ @@ -62,13 +62,13 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) break; case 44100: - if (state->is_cx23885) { + if (is_cx2388x(state)) { /* We don't have register values * so avoid destroying registers. */ break; } - if (!state->is_cx231xx) { + if (!is_cx231xx(state)) { /* VID_PLL and AUX_PLL */ cx25840_write4(client, 0x108, 0x1009040f); @@ -76,7 +76,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) cx25840_write4(client, 0x110, 0x00ec6bd6); } - if (state->is_cx25836) + if (is_cx2583x(state)) break; /* src3/4/6_ctl = 0x08016d59 */ @@ -86,13 +86,13 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) break; case 48000: - if (state->is_cx23885) { + if (is_cx2388x(state)) { /* We don't have register values * so avoid destroying registers. */ break; } - if (!state->is_cx231xx) { + if (!is_cx231xx(state)) { /* VID_PLL and AUX_PLL */ cx25840_write4(client, 0x108, 0x100a040f); @@ -100,7 +100,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) cx25840_write4(client, 0x110, 0x0098d6e5); } - if (state->is_cx25836) + if (is_cx2583x(state)) break; /* src3/4/6_ctl = 0x08014faa */ @@ -112,13 +112,13 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) } else { switch (freq) { case 32000: - if (state->is_cx23885) { + if (is_cx2388x(state)) { /* We don't have register values * so avoid destroying registers. */ break; } - if (!state->is_cx231xx) { + if (!is_cx231xx(state)) { /* VID_PLL and AUX_PLL */ cx25840_write4(client, 0x108, 0x1e08040f); @@ -126,7 +126,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) cx25840_write4(client, 0x110, 0x012a0869); } - if (state->is_cx25836) + if (is_cx2583x(state)) break; /* src1_ctl = 0x08010000 */ @@ -142,14 +142,14 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) break; case 44100: - if (state->is_cx23885) { + if (is_cx2388x(state)) { /* We don't have register values * so avoid destroying registers. */ break; } - if (!state->is_cx231xx) { + if (!is_cx231xx(state)) { /* VID_PLL and AUX_PLL */ cx25840_write4(client, 0x108, 0x1809040f); @@ -157,7 +157,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) cx25840_write4(client, 0x110, 0x00ec6bd6); } - if (state->is_cx25836) + if (is_cx2583x(state)) break; /* src1_ctl = 0x08010000 */ @@ -170,7 +170,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) break; case 48000: - if (!state->is_cx23885 && !state->is_cx231xx) { + if (!is_cx2388x(state) && !is_cx231xx(state)) { /* VID_PLL and AUX_PLL */ cx25840_write4(client, 0x108, 0x180a040f); @@ -178,10 +178,10 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) cx25840_write4(client, 0x110, 0x0098d6e5); } - if (state->is_cx25836) + if (is_cx2583x(state)) break; - if (!state->is_cx23885 && !state->is_cx231xx) { + if (!is_cx2388x(state) && !is_cx231xx(state)) { /* src1_ctl */ cx25840_write4(client, 0x8f8, 0x08018000); @@ -243,7 +243,7 @@ void cx25840_audio_set_path(struct i2c_client *client) cx25840_and_or(client, 0x810, ~0x1, 0x00); /* Ensure the controller is running when we exit */ - if (state->is_cx23885 || state->is_cx231xx) + if (is_cx2388x(state) || is_cx231xx(state)) cx25840_and_or(client, 0x803, ~0x10, 0x10); } @@ -383,7 +383,7 @@ int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq) struct cx25840_state *state = to_state(sd); int retval; - if (!state->is_cx25836) + if (!is_cx2583x(state)) cx25840_and_or(client, 0x810, ~0x1, 1); if (state->aud_input != CX25840_AUDIO_SERIAL) { cx25840_and_or(client, 0x803, ~0x10, 0); @@ -392,7 +392,7 @@ int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq) retval = set_audclk_freq(client, freq); if (state->aud_input != CX25840_AUDIO_SERIAL) cx25840_and_or(client, 0x803, ~0x10, 0x10); - if (!state->is_cx25836) + if (!is_cx2583x(state)) cx25840_and_or(client, 0x810, ~0x1, 0); return retval; } diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index e8365672999..a6446e637f1 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -494,7 +494,7 @@ void cx25840_std_setup(struct i2c_client *client) } /* DEBUG: Displays configured PLL frequency */ - if (!state->is_cx231xx) { + if (!is_cx231xx(state)) { pll_int = cx25840_read(client, 0x108); pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff; pll_post = cx25840_read(client, 0x109); @@ -678,7 +678,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp * configuration in reg (for the cx23885) so we have no * need to attempt to flip bits for earlier av decoders. */ - if (!state->is_cx23885 && !state->is_cx231xx) { + if (!is_cx2388x(state) && !is_cx231xx(state)) { switch (aud_input) { case CX25840_AUDIO_SERIAL: /* do nothing, use serial audio input */ @@ -701,7 +701,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp /* Set INPUT_MODE to Composite (0) or S-Video (1) */ cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02); - if (!state->is_cx23885 && !state->is_cx231xx) { + if (!is_cx2388x(state) && !is_cx231xx(state)) { /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0); /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2&CH3 */ @@ -720,12 +720,12 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp state->vid_input = vid_input; state->aud_input = aud_input; - if (!state->is_cx25836) { + if (!is_cx2583x(state)) { cx25840_audio_set_path(client); input_change(client); } - if (state->is_cx23885) { + if (is_cx2388x(state)) { /* Audio channel 1 src : Parallel 1 */ cx25840_write(client, 0x124, 0x03); @@ -741,7 +741,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp */ cx25840_write(client, 0x918, 0xa0); cx25840_write(client, 0x919, 0x01); - } else if (state->is_cx231xx) { + } else if (is_cx231xx(state)) { /* Audio channel 1 src : Parallel 1 */ cx25840_write(client, 0x124, 0x03); @@ -805,7 +805,7 @@ static int set_v4lstd(struct i2c_client *client) cx25840_and_or(client, 0x400, ~0xf, fmt); cx25840_and_or(client, 0x403, ~0x3, pal_m); cx25840_std_setup(client); - if (!state->is_cx25836) + if (!is_cx2583x(state)) input_change(client); return 0; } @@ -868,7 +868,7 @@ static int cx25840_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) case V4L2_CID_AUDIO_TREBLE: case V4L2_CID_AUDIO_BALANCE: case V4L2_CID_AUDIO_MUTE: - if (state->is_cx25836) + if (is_cx2583x(state)) return -EINVAL; return cx25840_audio_s_ctrl(sd, ctrl); @@ -905,7 +905,7 @@ static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) case V4L2_CID_AUDIO_TREBLE: case V4L2_CID_AUDIO_BALANCE: case V4L2_CID_AUDIO_MUTE: - if (state->is_cx25836) + if (is_cx2583x(state)) return -EINVAL; return cx25840_audio_g_ctrl(sd, ctrl); default: @@ -1209,11 +1209,11 @@ static int cx25840_load_fw(struct v4l2_subdev *sd) if (!state->is_initialized) { /* initialize and load firmware */ state->is_initialized = 1; - if (state->is_cx25836) + if (is_cx2583x(state)) cx25836_initialize(client); - else if (state->is_cx23885) + else if (is_cx2388x(state)) cx23885_initialize(client); - else if (state->is_cx231xx) + else if (is_cx231xx(state)) cx231xx_initialize(client); else cx25840_initialize(client); @@ -1256,17 +1256,17 @@ static int cx25840_s_stream(struct v4l2_subdev *sd, int enable) v4l_dbg(1, cx25840_debug, client, "%s output\n", enable ? "enable" : "disable"); if (enable) { - if (state->is_cx23885 || state->is_cx231xx) { + if (is_cx2388x(state) || is_cx231xx(state)) { u8 v = (cx25840_read(client, 0x421) | 0x0b); cx25840_write(client, 0x421, v); } else { cx25840_write(client, 0x115, - state->is_cx25836 ? 0x0c : 0x8c); + is_cx2583x(state) ? 0x0c : 0x8c); cx25840_write(client, 0x116, - state->is_cx25836 ? 0x04 : 0x07); + is_cx2583x(state) ? 0x04 : 0x07); } } else { - if (state->is_cx23885 || state->is_cx231xx) { + if (is_cx2388x(state) || is_cx231xx(state)) { u8 v = cx25840_read(client, 0x421) & ~(0x0b); cx25840_write(client, 0x421, v); } else { @@ -1292,7 +1292,7 @@ static int cx25840_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) default: break; } - if (state->is_cx25836) + if (is_cx2583x(state)) return -EINVAL; switch (qc->id) { @@ -1346,7 +1346,7 @@ static int cx25840_s_audio_routing(struct v4l2_subdev *sd, struct cx25840_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - if (state->is_cx25836) + if (is_cx2583x(state)) return -EINVAL; return set_input(client, state->vid_input, input); } @@ -1356,7 +1356,7 @@ static int cx25840_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *fr struct cx25840_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - if (!state->is_cx25836) + if (!is_cx2583x(state)) input_change(client); return 0; } @@ -1373,7 +1373,7 @@ static int cx25840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) return 0; vt->signal = vpres ? 0xffff : 0x0; - if (state->is_cx25836) + if (is_cx2583x(state)) return 0; vt->capability |= @@ -1404,7 +1404,7 @@ static int cx25840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) struct cx25840_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - if (state->radio || state->is_cx25836) + if (state->radio || is_cx2583x(state)) return 0; switch (vt->audmode) { @@ -1445,11 +1445,11 @@ static int cx25840_reset(struct v4l2_subdev *sd, u32 val) struct cx25840_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - if (state->is_cx25836) + if (is_cx2583x(state)) cx25836_initialize(client); - else if (state->is_cx23885) + else if (is_cx2388x(state)) cx23885_initialize(client); - else if (state->is_cx231xx) + else if (is_cx231xx(state)) cx231xx_initialize(client); else cx25840_initialize(client); @@ -1470,7 +1470,7 @@ static int cx25840_log_status(struct v4l2_subdev *sd) struct i2c_client *client = v4l2_get_subdevdata(sd); log_video_status(client); - if (!state->is_cx25836) + if (!is_cx2583x(state)) log_audio_status(client); return 0; } @@ -1594,22 +1594,18 @@ static int cx25840_probe(struct i2c_client *client, v4l2_i2c_subdev_init(sd, client, &cx25840_ops); switch (id) { case V4L2_IDENT_CX23885_AV: - state->is_cx23885 = 1; v4l_info(client, "cx23885 A/V decoder found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); break; case V4L2_IDENT_CX23887_AV: - state->is_cx23885 = 1; v4l_info(client, "cx23887 A/V decoder found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); break; case V4L2_IDENT_CX23888_AV: - state->is_cx23885 = 1; v4l_info(client, "cx23888 A/V decoder found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); break; case V4L2_IDENT_CX2310X_AV: - state->is_cx231xx = 1; v4l_info(client, "cx%d A/V decoder found @ 0x%x (%s)\n", device_id, client->addr << 1, client->adapter->name); break; @@ -1627,7 +1623,6 @@ static int cx25840_probe(struct i2c_client *client, break; case V4L2_IDENT_CX25836: case V4L2_IDENT_CX25837: - state->is_cx25836 = 1; default: v4l_info(client, "cx25%3x-%x found @ 0x%x (%s)\n", (device_id & 0xfff0) >> 4, device_id & 0x0f, diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h index 814b5653699..55345444417 100644 --- a/drivers/media/video/cx25840/cx25840-core.h +++ b/drivers/media/video/cx25840/cx25840-core.h @@ -23,6 +23,7 @@ #include #include +#include #include /* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is @@ -48,9 +49,6 @@ struct cx25840_state { int vbi_line_offset; u32 id; u32 rev; - int is_cx25836; - int is_cx23885; - int is_cx231xx; int is_initialized; wait_queue_head_t fw_wait; /* wake up when the fw load is finished */ struct work_struct fw_work; /* work entry for fw load */ @@ -61,6 +59,24 @@ static inline struct cx25840_state *to_state(struct v4l2_subdev *sd) return container_of(sd, struct cx25840_state, sd); } +static inline bool is_cx2583x(struct cx25840_state *state) +{ + return state->id == V4L2_IDENT_CX25836 || + state->id == V4L2_IDENT_CX25837; +} + +static inline bool is_cx231xx(struct cx25840_state *state) +{ + return state->id == V4L2_IDENT_CX2310X_AV; +} + +static inline bool is_cx2388x(struct cx25840_state *state) +{ + return state->id == V4L2_IDENT_CX23885_AV || + state->id == V4L2_IDENT_CX23887_AV || + state->id == V4L2_IDENT_CX23888_AV; +} + /* ----------------------------------------------------------------------- */ /* cx25850-core.c */ int cx25840_write(struct i2c_client *client, u16 addr, u8 value); diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c index 1f483c1d0db..8150200511d 100644 --- a/drivers/media/video/cx25840/cx25840-firmware.c +++ b/drivers/media/video/cx25840/cx25840-firmware.c @@ -67,9 +67,9 @@ static const char *get_fw_name(struct i2c_client *client) if (firmware[0]) return firmware; - if (state->is_cx23885) + if (is_cx2388x(state)) return "v4l-cx23885-avcore-01.fw"; - if (state->is_cx231xx) + if (is_cx231xx(state)) return "v4l-cx231xx-avcore-01.fw"; return "v4l-cx25840.fw"; } @@ -112,13 +112,13 @@ int cx25840_loadfw(struct i2c_client *client) int MAX_BUF_SIZE = FWSEND; u32 gpio_oe = 0, gpio_da = 0; - if (state->is_cx23885) { + if (is_cx2388x(state)) { /* Preserve the GPIO OE and output bits */ gpio_oe = cx25840_read(client, 0x160); gpio_da = cx25840_read(client, 0x164); } - if ((state->is_cx231xx) && MAX_BUF_SIZE > 16) { + if (is_cx231xx(state) && MAX_BUF_SIZE > 16) { v4l_err(client, " Firmware download size changed to 16 bytes max length\n"); MAX_BUF_SIZE = 16; /* cx231xx cannot accept more than 16 bytes at a time */ } @@ -156,7 +156,7 @@ int cx25840_loadfw(struct i2c_client *client) size = fw->size; release_firmware(fw); - if (state->is_cx23885) { + if (is_cx2388x(state)) { /* Restore GPIO configuration after f/w load */ cx25840_write(client, 0x160, gpio_oe); cx25840_write(client, 0x164, gpio_da); -- cgit v1.2.3-70-g09d2 From 9eef550a9a98c1e3d15aaf490812949fdeb01c7c Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 26 Sep 2009 23:54:20 -0300 Subject: V4L/DVB (13089): cx25840: Separate set_audclk_freq functionality for the different chips Separate out the set_audclk_freq() function into separate functions for the four families of cores. These cores all use slightly different sample clock schemes and may be assuming slightly (+/- 3 Hz) different reference frequencies. The code resuse was not worth the maintenance and testing headache of have all chips use the same function peppered with conditional logic. Added comments on how PLL and SRC parameters values are computed. Fixed a few bugs related to the shared code having a large number of conditional statements. Noted inconsistencies with FIXME in the comments. This is done in preparation for getting the CX2388[578] PLL/clock setting logic cleaned up for CX23888 analog video and IR (which need the VID PLL set right). Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx25840/cx25840-audio.c | 437 +++++++++++++++++++++------- 1 file changed, 332 insertions(+), 105 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c index fbccbdce26e..45608d50529 100644 --- a/drivers/media/video/cx25840/cx25840-audio.c +++ b/drivers/media/video/cx25840/cx25840-audio.c @@ -23,87 +23,137 @@ #include "cx25840-core.h" -static int set_audclk_freq(struct i2c_client *client, u32 freq) +/* + * Note: The PLL and SRC parameters are based on a reference frequency that + * would ideally be: + * + * NTSC Color subcarrier freq * 8 = 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz + * + * However, it's not the exact reference frequency that matters, only that the + * firmware and modules that comprise the driver for a particular board all + * use the same value (close to the ideal value). + * + * Comments below will note which reference frequency is assumed for various + * parameters. They will usually be one of + * + * ref_freq = 28.636360 MHz + * or + * ref_freq = 28.636363 MHz + */ + +static int cx25840_set_audclk_freq(struct i2c_client *client, u32 freq) { struct cx25840_state *state = to_state(i2c_get_clientdata(client)); - if (freq != 32000 && freq != 44100 && freq != 48000) - return -EINVAL; - - /* common for all inputs and rates */ - /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ - if (!is_cx2388x(state) && !is_cx231xx(state)) - cx25840_write(client, 0x127, 0x50); - if (state->aud_input != CX25840_AUDIO_SERIAL) { switch (freq) { case 32000: - if (is_cx2388x(state)) { - /* We don't have register values - * so avoid destroying registers. */ - break; - } - - if (!is_cx231xx(state)) { - /* VID_PLL and AUX_PLL */ - cx25840_write4(client, 0x108, 0x1006040f); - - /* AUX_PLL_FRAC */ - cx25840_write4(client, 0x110, 0x01bb39ee); - } + /* + * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04 + * AUX_PLL Integer = 0x06, AUX PLL Post Divider = 0x10 + */ + cx25840_write4(client, 0x108, 0x1006040f); + + /* + * VID_PLL Fraction (register 0x10c) = 0x2be2fe + * 28636360 * 0xf.15f17f0/4 = 108 MHz + * 432 MHz pre-postdivide + */ + + /* + * AUX_PLL Fraction = 0x1bb39ee + * 28636363 * 0x6.dd9cf70/0x10 = 32000 * 384 + * 196.6 MHz pre-postdivide + * FIXME < 200 MHz is out of specified valid range + * FIXME 28636363 ref_freq doesn't match VID PLL ref + */ + cx25840_write4(client, 0x110, 0x01bb39ee); + + /* + * SA_MCLK_SEL = 1 + * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider + */ + cx25840_write(client, 0x127, 0x50); if (is_cx2583x(state)) break; - /* src3/4/6_ctl = 0x0801f77f */ + /* src3/4/6_ctl */ + /* 0x1.f77f = (4 * 28636360/8 * 2/455) / 32000 */ cx25840_write4(client, 0x900, 0x0801f77f); cx25840_write4(client, 0x904, 0x0801f77f); cx25840_write4(client, 0x90c, 0x0801f77f); break; case 44100: - if (is_cx2388x(state)) { - /* We don't have register values - * so avoid destroying registers. */ - break; - } - - if (!is_cx231xx(state)) { - /* VID_PLL and AUX_PLL */ - cx25840_write4(client, 0x108, 0x1009040f); - - /* AUX_PLL_FRAC */ - cx25840_write4(client, 0x110, 0x00ec6bd6); - } + /* + * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04 + * AUX_PLL Integer = 0x09, AUX PLL Post Divider = 0x10 + */ + cx25840_write4(client, 0x108, 0x1009040f); + + /* + * VID_PLL Fraction (register 0x10c) = 0x2be2fe + * 28636360 * 0xf.15f17f0/4 = 108 MHz + * 432 MHz pre-postdivide + */ + + /* + * AUX_PLL Fraction = 0x0ec6bd6 + * 28636363 * 0x9.7635eb0/0x10 = 44100 * 384 + * 271 MHz pre-postdivide + * FIXME 28636363 ref_freq doesn't match VID PLL ref + */ + cx25840_write4(client, 0x110, 0x00ec6bd6); + + /* + * SA_MCLK_SEL = 1 + * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider + */ + cx25840_write(client, 0x127, 0x50); if (is_cx2583x(state)) break; - /* src3/4/6_ctl = 0x08016d59 */ + /* src3/4/6_ctl */ + /* 0x1.6d59 = (4 * 28636360/8 * 2/455) / 44100 */ cx25840_write4(client, 0x900, 0x08016d59); cx25840_write4(client, 0x904, 0x08016d59); cx25840_write4(client, 0x90c, 0x08016d59); break; case 48000: - if (is_cx2388x(state)) { - /* We don't have register values - * so avoid destroying registers. */ - break; - } - - if (!is_cx231xx(state)) { - /* VID_PLL and AUX_PLL */ - cx25840_write4(client, 0x108, 0x100a040f); - - /* AUX_PLL_FRAC */ - cx25840_write4(client, 0x110, 0x0098d6e5); - } + /* + * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04 + * AUX_PLL Integer = 0x0a, AUX PLL Post Divider = 0x10 + */ + cx25840_write4(client, 0x108, 0x100a040f); + + /* + * VID_PLL Fraction (register 0x10c) = 0x2be2fe + * 28636360 * 0xf.15f17f0/4 = 108 MHz + * 432 MHz pre-postdivide + */ + + /* + * AUX_PLL Fraction = 0x098d6e5 + * 28636363 * 0xa.4c6b728/0x10 = 48000 * 384 + * 295 MHz pre-postdivide + * FIXME 28636363 ref_freq doesn't match VID PLL ref + */ + cx25840_write4(client, 0x110, 0x0098d6e5); + + /* + * SA_MCLK_SEL = 1 + * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider + */ + cx25840_write(client, 0x127, 0x50); if (is_cx2583x(state)) break; - /* src3/4/6_ctl = 0x08014faa */ + /* src3/4/6_ctl */ + /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */ cx25840_write4(client, 0x900, 0x08014faa); cx25840_write4(client, 0x904, 0x08014faa); cx25840_write4(client, 0x90c, 0x08014faa); @@ -112,91 +162,173 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) } else { switch (freq) { case 32000: - if (is_cx2388x(state)) { - /* We don't have register values - * so avoid destroying registers. */ - break; - } - - if (!is_cx231xx(state)) { - /* VID_PLL and AUX_PLL */ - cx25840_write4(client, 0x108, 0x1e08040f); - - /* AUX_PLL_FRAC */ - cx25840_write4(client, 0x110, 0x012a0869); - } + /* + * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04 + * AUX_PLL Integer = 0x08, AUX PLL Post Divider = 0x1e + */ + cx25840_write4(client, 0x108, 0x1e08040f); + + /* + * VID_PLL Fraction (register 0x10c) = 0x2be2fe + * 28636360 * 0xf.15f17f0/4 = 108 MHz + * 432 MHz pre-postdivide + */ + + /* + * AUX_PLL Fraction = 0x12a0869 + * 28636363 * 0x8.9504348/0x1e = 32000 * 256 + * 246 MHz pre-postdivide + * FIXME 28636363 ref_freq doesn't match VID PLL ref + */ + cx25840_write4(client, 0x110, 0x012a0869); + + /* + * SA_MCLK_SEL = 1 + * SA_MCLK_DIV = 0x14 = 256/384 * AUX_PLL post dvivider + */ + cx25840_write(client, 0x127, 0x54); if (is_cx2583x(state)) break; - /* src1_ctl = 0x08010000 */ + /* src1_ctl */ + /* 0x1.0000 = 32000/32000 */ cx25840_write4(client, 0x8f8, 0x08010000); - /* src3/4/6_ctl = 0x08020000 */ + /* src3/4/6_ctl */ + /* 0x2.0000 = 2 * (32000/32000) */ cx25840_write4(client, 0x900, 0x08020000); cx25840_write4(client, 0x904, 0x08020000); cx25840_write4(client, 0x90c, 0x08020000); - - /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */ - cx25840_write(client, 0x127, 0x54); break; case 44100: - if (is_cx2388x(state)) { - /* We don't have register values - * so avoid destroying registers. */ - break; - } - - - if (!is_cx231xx(state)) { - /* VID_PLL and AUX_PLL */ - cx25840_write4(client, 0x108, 0x1809040f); - - /* AUX_PLL_FRAC */ - cx25840_write4(client, 0x110, 0x00ec6bd6); - } + /* + * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04 + * AUX_PLL Integer = 0x09, AUX PLL Post Divider = 0x18 + */ + cx25840_write4(client, 0x108, 0x1809040f); + + /* + * VID_PLL Fraction (register 0x10c) = 0x2be2fe + * 28636360 * 0xf.15f17f0/4 = 108 MHz + * 432 MHz pre-postdivide + */ + + /* + * AUX_PLL Fraction = 0x0ec6bd6 + * 28636363 * 0x9.7635eb0/0x18 = 44100 * 256 + * 271 MHz pre-postdivide + * FIXME 28636363 ref_freq doesn't match VID PLL ref + */ + cx25840_write4(client, 0x110, 0x00ec6bd6); + + /* + * SA_MCLK_SEL = 1 + * SA_MCLK_DIV = 0x10 = 256/384 * AUX_PLL post dvivider + */ + cx25840_write(client, 0x127, 0x50); if (is_cx2583x(state)) break; - /* src1_ctl = 0x08010000 */ + /* src1_ctl */ + /* 0x1.60cd = 44100/32000 */ cx25840_write4(client, 0x8f8, 0x080160cd); - /* src3/4/6_ctl = 0x08020000 */ + /* src3/4/6_ctl */ + /* 0x1.7385 = 2 * (32000/44100) */ cx25840_write4(client, 0x900, 0x08017385); cx25840_write4(client, 0x904, 0x08017385); cx25840_write4(client, 0x90c, 0x08017385); break; case 48000: - if (!is_cx2388x(state) && !is_cx231xx(state)) { - /* VID_PLL and AUX_PLL */ - cx25840_write4(client, 0x108, 0x180a040f); - - /* AUX_PLL_FRAC */ - cx25840_write4(client, 0x110, 0x0098d6e5); - } + /* + * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04 + * AUX_PLL Integer = 0x0a, AUX PLL Post Divider = 0x18 + */ + cx25840_write4(client, 0x108, 0x180a040f); + + /* + * VID_PLL Fraction (register 0x10c) = 0x2be2fe + * 28636360 * 0xf.15f17f0/4 = 108 MHz + * 432 MHz pre-postdivide + */ + + /* + * AUX_PLL Fraction = 0x098d6e5 + * 28636363 * 0xa.4c6b728/0x18 = 48000 * 256 + * 295 MHz pre-postdivide + * FIXME 28636363 ref_freq doesn't match VID PLL ref + */ + cx25840_write4(client, 0x110, 0x0098d6e5); + + /* + * SA_MCLK_SEL = 1 + * SA_MCLK_DIV = 0x10 = 256/384 * AUX_PLL post dvivider + */ + cx25840_write(client, 0x127, 0x50); if (is_cx2583x(state)) break; - if (!is_cx2388x(state) && !is_cx231xx(state)) { - /* src1_ctl */ - cx25840_write4(client, 0x8f8, 0x08018000); + /* src1_ctl */ + /* 0x1.8000 = 48000/32000 */ + cx25840_write4(client, 0x8f8, 0x08018000); - /* src3/4/6_ctl */ - cx25840_write4(client, 0x900, 0x08015555); - cx25840_write4(client, 0x904, 0x08015555); - cx25840_write4(client, 0x90c, 0x08015555); - } else { + /* src3/4/6_ctl */ + /* 0x1.5555 = 2 * (32000/48000) */ + cx25840_write4(client, 0x900, 0x08015555); + cx25840_write4(client, 0x904, 0x08015555); + cx25840_write4(client, 0x90c, 0x08015555); + break; + } + } + + state->audclk_freq = freq; + + return 0; +} + +static inline int cx25836_set_audclk_freq(struct i2c_client *client, u32 freq) +{ + return cx25840_set_audclk_freq(client, freq); +} + +static int cx23885_set_audclk_freq(struct i2c_client *client, u32 freq) +{ + struct cx25840_state *state = to_state(i2c_get_clientdata(client)); + + if (state->aud_input != CX25840_AUDIO_SERIAL) { + switch (freq) { + case 32000: + case 44100: + case 48000: + /* We don't have register values + * so avoid destroying registers. */ + /* FIXME return -EINVAL; */ + break; + } + } else { + switch (freq) { + case 32000: + case 44100: + /* We don't have register values + * so avoid destroying registers. */ + /* FIXME return -EINVAL; */ + break; - cx25840_write4(client, 0x8f8, 0x0801867c); + case 48000: + /* src1_ctl */ + /* 0x1.867c = 48000 / (2 * 28636360/8 * 2/455) */ + cx25840_write4(client, 0x8f8, 0x0801867c); - cx25840_write4(client, 0x900, 0x08014faa); - cx25840_write4(client, 0x904, 0x08014faa); - cx25840_write4(client, 0x90c, 0x08014faa); - } + /* src3/4/6_ctl */ + /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */ + cx25840_write4(client, 0x900, 0x08014faa); + cx25840_write4(client, 0x904, 0x08014faa); + cx25840_write4(client, 0x90c, 0x08014faa); break; } } @@ -206,6 +338,101 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) return 0; } +static int cx231xx_set_audclk_freq(struct i2c_client *client, u32 freq) +{ + struct cx25840_state *state = to_state(i2c_get_clientdata(client)); + + if (state->aud_input != CX25840_AUDIO_SERIAL) { + switch (freq) { + case 32000: + /* src3/4/6_ctl */ + /* 0x1.f77f = (4 * 28636360/8 * 2/455) / 32000 */ + cx25840_write4(client, 0x900, 0x0801f77f); + cx25840_write4(client, 0x904, 0x0801f77f); + cx25840_write4(client, 0x90c, 0x0801f77f); + break; + + case 44100: + /* src3/4/6_ctl */ + /* 0x1.6d59 = (4 * 28636360/8 * 2/455) / 44100 */ + cx25840_write4(client, 0x900, 0x08016d59); + cx25840_write4(client, 0x904, 0x08016d59); + cx25840_write4(client, 0x90c, 0x08016d59); + break; + + case 48000: + /* src3/4/6_ctl */ + /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */ + cx25840_write4(client, 0x900, 0x08014faa); + cx25840_write4(client, 0x904, 0x08014faa); + cx25840_write4(client, 0x90c, 0x08014faa); + break; + } + } else { + switch (freq) { + /* FIXME These cases make different assumptions about audclk */ + case 32000: + /* src1_ctl */ + /* 0x1.0000 = 32000/32000 */ + cx25840_write4(client, 0x8f8, 0x08010000); + + /* src3/4/6_ctl */ + /* 0x2.0000 = 2 * (32000/32000) */ + cx25840_write4(client, 0x900, 0x08020000); + cx25840_write4(client, 0x904, 0x08020000); + cx25840_write4(client, 0x90c, 0x08020000); + break; + + case 44100: + /* src1_ctl */ + /* 0x1.60cd = 44100/32000 */ + cx25840_write4(client, 0x8f8, 0x080160cd); + + /* src3/4/6_ctl */ + /* 0x1.7385 = 2 * (32000/44100) */ + cx25840_write4(client, 0x900, 0x08017385); + cx25840_write4(client, 0x904, 0x08017385); + cx25840_write4(client, 0x90c, 0x08017385); + break; + + case 48000: + /* src1_ctl */ + /* 0x1.867c = 48000 / (2 * 28636360/8 * 2/455) */ + cx25840_write4(client, 0x8f8, 0x0801867c); + + /* src3/4/6_ctl */ + /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */ + cx25840_write4(client, 0x900, 0x08014faa); + cx25840_write4(client, 0x904, 0x08014faa); + cx25840_write4(client, 0x90c, 0x08014faa); + break; + } + } + + state->audclk_freq = freq; + + return 0; +} + +static int set_audclk_freq(struct i2c_client *client, u32 freq) +{ + struct cx25840_state *state = to_state(i2c_get_clientdata(client)); + + if (freq != 32000 && freq != 44100 && freq != 48000) + return -EINVAL; + + if (is_cx231xx(state)) + return cx231xx_set_audclk_freq(client, freq); + + if (is_cx2388x(state)) + return cx23885_set_audclk_freq(client, freq); + + if (is_cx2583x(state)) + return cx25836_set_audclk_freq(client, freq); + + return cx25840_set_audclk_freq(client, freq); +} + void cx25840_audio_set_path(struct i2c_client *client) { struct cx25840_state *state = to_state(i2c_get_clientdata(client)); -- cgit v1.2.3-70-g09d2 From e283d78083271c9faf784daad6367dfb903d0f06 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 27 Sep 2009 00:00:48 -0300 Subject: V4L/DVB (13090): cx25840: Init PLLs properly for CX2388[578] A/V cores The SYS and AUX PLLs need to be initialized to different values based on the chip: CX23885, CX23887, CX23888, as each uses a different crystal frequency: 28.6363 MHz, 25.0 MHz, 50.0 MHz. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx25840/cx25840-core.c | 106 ++++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 18 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index a6446e637f1..56ead3d3792 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -259,6 +259,13 @@ static void cx23885_initialize(struct i2c_client *client) struct cx25840_state *state = to_state(i2c_get_clientdata(client)); struct workqueue_struct *q; + /* + * Come out of digital power down + * The CX23888, at least, needs this, otherwise registers aside from + * 0x0-0x2 can't be read or written. + */ + cx25840_write(client, 0x000, 0); + /* Internal Reset */ cx25840_and_or(client, 0x102, ~0x01, 0x01); cx25840_and_or(client, 0x102, ~0x01, 0x00); @@ -269,18 +276,45 @@ static void cx23885_initialize(struct i2c_client *client) /* DIF in reset? */ cx25840_write(client, 0x398, 0); - /* Trust the default xtal, no division */ - /* This changes for the cx23888 products */ + /* + * Trust the default xtal, no division + * '885: 28.636363... MHz + * '887: 25.000000 MHz + * '888: 50.000000 MHz + */ cx25840_write(client, 0x2, 0x76); - /* Bring down the regulator for AUX clk */ + /* Power up all the PLL's and DLL */ cx25840_write(client, 0x1, 0x40); - /* Sys PLL frac */ - cx25840_write4(client, 0x11c, 0x01d1744c); - - /* Sys PLL int */ - cx25840_write4(client, 0x118, 0x00000416); + /* Sys PLL */ + switch (state->id) { + case V4L2_IDENT_CX23888_AV: + /* + * 50.0 MHz * (0xb + 0xe8ba26/0x2000000)/4 = 5 * 28.636363 MHz + * 572.73 MHz before post divide + */ + cx25840_write4(client, 0x11c, 0x00e8ba26); + cx25840_write4(client, 0x118, 0x0000040b); + break; + case V4L2_IDENT_CX23887_AV: + /* + * 25.0 MHz * (0x16 + 0x1d1744c/0x2000000)/4 = 5 * 28.636363 MHz + * 572.73 MHz before post divide + */ + cx25840_write4(client, 0x11c, 0x01d1744c); + cx25840_write4(client, 0x118, 0x00000416); + break; + case V4L2_IDENT_CX23885_AV: + default: + /* + * 28.636363 MHz * (0x14 + 0x0/0x2000000)/4 = 5 * 28.636363 MHz + * 572.73 MHz before post divide + */ + cx25840_write4(client, 0x11c, 0x00000000); + cx25840_write4(client, 0x118, 0x00000414); + break; + } /* Disable DIF bypass */ cx25840_write4(client, 0x33c, 0x00000001); @@ -288,11 +322,15 @@ static void cx23885_initialize(struct i2c_client *client) /* DIF Src phase inc */ cx25840_write4(client, 0x340, 0x0df7df83); - /* Vid PLL frac */ - cx25840_write4(client, 0x10c, 0x01b6db7b); - - /* Vid PLL int */ - cx25840_write4(client, 0x108, 0x00000512); + /* + * Vid PLL + * Setup for a BT.656 pixel clock of 13.5 Mpixels/second + * + * 28.636363 MHz * (0xf + 0x02be2c9/0x2000000)/4 = 8 * 13.5 MHz + * 432.0 MHz before post divide + */ + cx25840_write4(client, 0x10c, 0x002be2c9); + cx25840_write4(client, 0x108, 0x0000040f); /* Luma */ cx25840_write4(client, 0x414, 0x00107d12); @@ -300,11 +338,43 @@ static void cx23885_initialize(struct i2c_client *client) /* Chroma */ cx25840_write4(client, 0x420, 0x3d008282); - /* Aux PLL frac */ - cx25840_write4(client, 0x114, 0x017dbf48); - - /* Aux PLL int */ - cx25840_write4(client, 0x110, 0x000a030e); + /* + * Aux PLL + * Initial setup for audio sample clock: + * 48 ksps, 16 bits/sample, x160 multiplier = 122.88 MHz + * Intial I2S output/master clock(?): + * 48 ksps, 16 bits/sample, x16 multiplier = 12.288 MHz + */ + switch (state->id) { + case V4L2_IDENT_CX23888_AV: + /* + * 50.0 MHz * (0x7 + 0x0bedfa4/0x2000000)/3 = 122.88 MHz + * 368.64 MHz before post divide + * 122.88 MHz / 0xa = 12.288 MHz + */ + cx25840_write4(client, 0x114, 0x00bedfa4); + cx25840_write4(client, 0x110, 0x000a0307); + break; + case V4L2_IDENT_CX23887_AV: + /* + * 25.0 MHz * (0xe + 0x17dbf48/0x2000000)/3 = 122.88 MHz + * 368.64 MHz before post divide + * 122.88 MHz / 0xa = 12.288 MHz + */ + cx25840_write4(client, 0x114, 0x017dbf48); + cx25840_write4(client, 0x110, 0x000a030e); + break; + case V4L2_IDENT_CX23885_AV: + default: + /* + * 28.636363 MHz * (0xc + 0x1bf0c9e/0x2000000)/3 = 122.88 MHz + * 368.64 MHz before post divide + * 122.88 MHz / 0xa = 12.288 MHz + */ + cx25840_write4(client, 0x114, 0x01bf0c9e); + cx25840_write4(client, 0x110, 0x000a030c); + break; + }; /* ADC2 input select */ cx25840_write(client, 0x102, 0x10); -- cgit v1.2.3-70-g09d2 From c6b7053bbc3b1ec556780327cef0d0463e1537ea Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 27 Sep 2009 00:14:33 -0300 Subject: V4L/DVB (13091): cx23885: Enable HVR-1850 CX23888 A/V core to get VID_CLK running for IR For the IR controller on the CX23888 to work for the HVR-1850 and in general, the A/V core must be initialized to get the VID_CLK going. The VID_CLK is the timing reference for the CX23888's integrated IR controller. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-cards.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 4b5aa08036f..7c5d13ac538 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -946,6 +946,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: case CX23885_BOARD_COMPRO_VIDEOMATE_E800: + case CX23885_BOARD_HAUPPAUGE_HVR1850: dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_bus[2].i2c_adap, "cx25840", "cx25840", 0x88 >> 1, NULL); -- cgit v1.2.3-70-g09d2 From 8c2d7821d4e3827c29e4e4e345ee25390a141e55 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sun, 27 Sep 2009 15:54:47 -0300 Subject: V4L/DVB (13092): cx25840: Improvements to the cx23885/7/8 chip detection mechanism. The prior mechanism wasn't reliable with the cx23887. This new mechanism tests correctly against cx23885, 7 and 8 based products. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx25840/cx25840-core.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 56ead3d3792..904e9a5a906 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -1598,14 +1598,29 @@ static u32 get_cx2388x_ident(struct i2c_client *client) /* Come out of digital power down */ cx25840_write(client, 0x000, 0); + /* Detecting whether the part is cx23885/7/8 is more + * difficult than it needs to be. No ID register. Instead we + * probe certain registers indicated in the datasheets to look + * for specific defaults that differ between the silicon designs. */ + + /* It's either 885/7 if the IR Tx Clk Divider register exists */ if (cx25840_read4(client, 0x204) & 0xffff) { - /* IR Tx Clk Divider register exists; chip must be a CX23885 */ - ret = V4L2_IDENT_CX23885_AV; + /* CX23885 returns bogus repetitive byte values for the DIF, + * which doesn't exist for it. (Ex. 8a8a8a8a or 31313131) */ + ret = cx25840_read4(client, 0x300); + if (((ret & 0xffff0000) >> 16) == (ret & 0xffff)) { + /* No DIF */ + ret = V4L2_IDENT_CX23885_AV; + } else { + /* CX23887 has a broken DIF, but the registers + * appear valid (but unsed), good enough to detect. */ + ret = V4L2_IDENT_CX23887_AV; + } } else if (cx25840_read4(client, 0x300) & 0x0fffffff) { /* DIF PLL Freq Word reg exists; chip must be a CX23888 */ ret = V4L2_IDENT_CX23888_AV; } else { - /* A CX23887 A/V core has neither IR nor DIF */ + v4l_err(client, "Unable to detect h/w, assuming cx23887\n"); ret = V4L2_IDENT_CX23887_AV; } -- cgit v1.2.3-70-g09d2 From 1a0b9d89c62ddf0aed12798686fe452e7e97de42 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 27 Sep 2009 18:31:37 -0300 Subject: V4L/DVB (13097): cx23885: Complete CX23888 IR subdev implementation for Rx & almost for Tx This change completes the v4l2_subdev implementation for IR receive for the IR controller built into the CX23888. This changes almost completes the IR transmit side also, but doesn't. Instead notes in the comments describe what needs to be done for IR Tx to work in the subdevice implementation. The current Tx behavior is skeletal and benign. If left alone, it does nothing. It will only ever generate a Tx interrupt on Tx init by a caller or when the tx_write() method is called. The ISR, when called, will then disable the Tx FIFO service interrupt. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23888-ir.c | 1063 +++++++++++++++++++++++++++++- 1 file changed, 1034 insertions(+), 29 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c index 12df0e3a235..e8d949ae06b 100644 --- a/drivers/media/video/cx23885/cx23888-ir.c +++ b/drivers/media/video/cx23885/cx23888-ir.c @@ -21,25 +21,79 @@ * 02110-1301, USA. */ +#include + #include #include #include "cx23885.h" +static unsigned int ir_888_debug; +module_param(ir_888_debug, int, 0644); +MODULE_PARM_DESC(ir_888_debug, "enable debug messages [CX23888 IR controller]"); + #define CX23888_IR_REG_BASE 0x170000 /* * These CX23888 register offsets have a straightforward one to one mapping * to the CX23885 register offsets of 0x200 through 0x218 */ #define CX23888_IR_CNTRL_REG 0x170000 +#define CNTRL_WIN_3_3 0x00000000 +#define CNTRL_WIN_4_3 0x00000001 +#define CNTRL_WIN_3_4 0x00000002 +#define CNTRL_WIN_4_4 0x00000003 +#define CNTRL_WIN 0x00000003 +#define CNTRL_EDG_NONE 0x00000000 +#define CNTRL_EDG_FALL 0x00000004 +#define CNTRL_EDG_RISE 0x00000008 +#define CNTRL_EDG_BOTH 0x0000000C +#define CNTRL_EDG 0x0000000C +#define CNTRL_DMD 0x00000010 +#define CNTRL_MOD 0x00000020 +#define CNTRL_RFE 0x00000040 +#define CNTRL_TFE 0x00000080 +#define CNTRL_RXE 0x00000100 +#define CNTRL_TXE 0x00000200 +#define CNTRL_RIC 0x00000400 +#define CNTRL_TIC 0x00000800 +#define CNTRL_CPL 0x00001000 +#define CNTRL_LBM 0x00002000 +#define CNTRL_R 0x00004000 + #define CX23888_IR_TXCLK_REG 0x170004 +#define TXCLK_TCD 0x0000FFFF + #define CX23888_IR_RXCLK_REG 0x170008 +#define RXCLK_RCD 0x0000FFFF + #define CX23888_IR_CDUTY_REG 0x17000C +#define CDUTY_CDC 0x0000000F + #define CX23888_IR_STATS_REG 0x170010 +#define STATS_RTO 0x00000001 +#define STATS_ROR 0x00000002 +#define STATS_RBY 0x00000004 +#define STATS_TBY 0x00000008 +#define STATS_RSR 0x00000010 +#define STATS_TSR 0x00000020 + #define CX23888_IR_IRQEN_REG 0x170014 +#define IRQEN_RTE 0x00000001 +#define IRQEN_ROE 0x00000002 +#define IRQEN_RSE 0x00000010 +#define IRQEN_TSE 0x00000020 + #define CX23888_IR_FILTR_REG 0x170018 +#define FILTR_LPF 0x0000FFFF + /* This register doesn't follow the pattern; it's 0x23C on a CX23885 */ #define CX23888_IR_FIFO_REG 0x170040 +#define FIFO_RXTX 0x0000FFFF +#define FIFO_RXTX_LVL 0x00010000 +#define FIFO_RXTX_RTO 0x0001FFFF +#define FIFO_RX_NDV 0x00020000 +#define FIFO_RX_DEPTH 8 +#define FIFO_TX_DEPTH 8 /* CX23888 unique registers */ #define CX23888_IR_SEEDP_REG 0x17001C @@ -53,12 +107,32 @@ #define CX23888_IR_DPIPG_REG 0x17003C #define CX23888_IR_LEARN_REG 0x170044 +#define CX23888_VIDCLK_FREQ 108000000 /* 108 MHz, BT.656 */ +#define CX23888_IR_REFCLK_FREQ (CX23888_VIDCLK_FREQ/2) + +#define CX23888_IR_RX_KFIFO_SIZE (512 * sizeof(u32)) +#define CX23888_IR_TX_KFIFO_SIZE (512 * sizeof(u32)) struct cx23888_ir_state { struct v4l2_subdev sd; struct cx23885_dev *dev; u32 id; u32 rev; + + struct v4l2_subdev_ir_parameters rx_params; + struct mutex rx_params_lock; + atomic_t rxclk_divider; + atomic_t rx_invert; + + struct kfifo *rx_kfifo; + spinlock_t rx_kfifo_lock; + + struct v4l2_subdev_ir_parameters tx_params; + struct mutex tx_params_lock; + atomic_t txclk_divider; + + struct kfifo *tx_kfifo; + spinlock_t tx_kfifo_lock; }; static inline struct cx23888_ir_state *to_state(struct v4l2_subdev *sd) @@ -66,59 +140,903 @@ static inline struct cx23888_ir_state *to_state(struct v4l2_subdev *sd) return v4l2_get_subdevdata(sd); } -static int cx23888_ir_write(struct cx23885_dev *dev, u32 addr, u8 value) +/* + * IR register block read and write functions + */ +static +inline int cx23888_ir_write4(struct cx23885_dev *dev, u32 addr, u32 value) { - u32 reg = (addr & ~3); - int shift = (addr & 3) * 8; - u32 x = cx_read(reg); + cx_write(addr, value); + return 0; +} + +static inline u32 cx23888_ir_read4(struct cx23885_dev *dev, u32 addr) +{ + return cx_read(addr); +} - x = (x & ~(0xff << shift)) | ((u32)value << shift); - cx_write(reg, x); +static inline int cx23888_ir_and_or4(struct cx23885_dev *dev, u32 addr, + u32 and_mask, u32 or_value) +{ + cx_andor(addr, ~and_mask, or_value); return 0; } -static -inline int cx23888_ir_write4(struct cx23885_dev *dev, u32 addr, u32 value) +/* + * Rx and Tx Clock Divider register computations + * + * Note the largest clock divider value of 0xffff corresponds to: + * (0xffff + 1) * 1000 / 108/2 MHz = 1,213,629.629... ns + * which fits in 21 bits, so we'll use unsigned int for time arguments. + */ +static inline u16 count_to_clock_divider(unsigned int d) { - cx_write(addr, value); + if (d > RXCLK_RCD+1) + d = RXCLK_RCD; + else if (d < 2) + d = 1; + else + d--; + return (u16) d; +} + +static inline u16 ns_to_clock_divider(unsigned int ns) +{ + return count_to_clock_divider( + DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ/1000000 * ns, 1000)); +} + +static inline unsigned int clock_divider_to_ns(unsigned int divider) +{ + /* Period of the Rx or Tx clock in ns */ + return DIV_ROUND_CLOSEST((divider + 1) * 1000, + CX23888_IR_REFCLK_FREQ/1000000); +} + +static inline u16 carrier_freq_to_clock_divider(unsigned int freq) +{ + return count_to_clock_divider( + DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, freq * 16)); +} + +static inline unsigned int clock_divider_to_carrier_freq(unsigned int divider) +{ + return DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, (divider + 1) * 16); +} + +static inline u16 freq_to_clock_divider(unsigned int freq, + unsigned int rollovers) +{ + return count_to_clock_divider( + DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, freq * rollovers)); +} + +static inline unsigned int clock_divider_to_freq(unsigned int divider, + unsigned int rollovers) +{ + return DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, + (divider + 1) * rollovers); +} + +/* + * Low Pass Filter register calculations + * + * Note the largest count value of 0xffff corresponds to: + * 0xffff * 1000 / 108/2 MHz = 1,213,611.11... ns + * which fits in 21 bits, so we'll use unsigned int for time arguments. + */ +static inline u16 count_to_lpf_count(unsigned int d) +{ + if (d > FILTR_LPF) + d = FILTR_LPF; + else if (d < 4) + d = 0; + return (u16) d; +} + +static inline u16 ns_to_lpf_count(unsigned int ns) +{ + return count_to_lpf_count( + DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ/1000000 * ns, 1000)); +} + +static inline unsigned int lpf_count_to_ns(unsigned int count) +{ + /* Duration of the Low Pass Filter rejection window in ns */ + return DIV_ROUND_CLOSEST(count * 1000, CX23888_IR_REFCLK_FREQ/1000000); +} + +static inline unsigned int lpf_count_to_us(unsigned int count) +{ + /* Duration of the Low Pass Filter rejection window in us */ + return DIV_ROUND_CLOSEST(count, CX23888_IR_REFCLK_FREQ/1000000); +} + +/* + * FIFO register pulse width count compuations + */ +static u32 clock_divider_to_resolution(u16 divider) +{ + /* + * Resolution is the duration of 1 tick of the readable portion of + * of the pulse width counter as read from the FIFO. The two lsb's are + * not readable, hence the << 2. This function returns ns. + */ + return DIV_ROUND_CLOSEST((1 << 2) * ((u32) divider + 1) * 1000, + CX23888_IR_REFCLK_FREQ/1000000); +} + +static u64 pulse_width_count_to_ns(u16 count, u16 divider) +{ + u64 n; + u32 rem; + + /* + * The 2 lsb's of the pulse width timer count are not readable, hence + * the (count << 2) | 0x3 + */ + n = (((u64) count << 2) | 0x3) * (divider + 1) * 1000; /* millicycles */ + rem = do_div(n, CX23888_IR_REFCLK_FREQ/1000000); /* / MHz => ns */ + if (rem >= CX23888_IR_REFCLK_FREQ/1000000/2) + n++; + return n; +} + +static unsigned int pulse_width_count_to_us(u16 count, u16 divider) +{ + u64 n; + u32 rem; + + /* + * The 2 lsb's of the pulse width timer count are not readable, hence + * the (count << 2) | 0x3 + */ + n = (((u64) count << 2) | 0x3) * (divider + 1); /* cycles */ + rem = do_div(n, CX23888_IR_REFCLK_FREQ/1000000); /* / MHz => us */ + if (rem >= CX23888_IR_REFCLK_FREQ/1000000/2) + n++; + return (unsigned int) n; +} + +/* + * Pulse Clocks computations: Combined Pulse Width Count & Rx Clock Counts + * + * The total pulse clock count is an 18 bit pulse width timer count as the most + * significant part and (up to) 16 bit clock divider count as a modulus. + * When the Rx clock divider ticks down to 0, it increments the 18 bit pulse + * width timer count's least significant bit. + */ +static u64 ns_to_pulse_clocks(u32 ns) +{ + u64 clocks; + u32 rem; + clocks = CX23888_IR_REFCLK_FREQ/1000000 * (u64) ns; /* millicycles */ + rem = do_div(clocks, 1000); /* /1000 = cycles */ + if (rem >= 1000/2) + clocks++; + return clocks; +} + +static u16 pulse_clocks_to_clock_divider(u64 count) +{ + u32 rem; + + rem = do_div(count, (FIFO_RXTX << 2) | 0x3); + + /* net result needs to be rounded down and decremented by 1 */ + if (count > RXCLK_RCD+1) + count = RXCLK_RCD; + else if (count < 2) + count = 1; + else + count--; + return (u16) count; +} + +/* + * IR Control Register helpers + */ +enum tx_fifo_watermark { + TX_FIFO_HALF_EMPTY = 0, + TX_FIFO_EMPTY = CNTRL_TIC, +}; + +enum rx_fifo_watermark { + RX_FIFO_HALF_FULL = 0, + RX_FIFO_NOT_EMPTY = CNTRL_RIC, +}; + +static inline void control_tx_irq_watermark(struct cx23885_dev *dev, + enum tx_fifo_watermark level) +{ + cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_TIC, level); +} + +static inline void control_rx_irq_watermark(struct cx23885_dev *dev, + enum rx_fifo_watermark level) +{ + cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_RIC, level); +} + +static inline void control_tx_enable(struct cx23885_dev *dev, bool enable) +{ + cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~(CNTRL_TXE | CNTRL_TFE), + enable ? (CNTRL_TXE | CNTRL_TFE) : 0); +} + +static inline void control_rx_enable(struct cx23885_dev *dev, bool enable) +{ + cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~(CNTRL_RXE | CNTRL_RFE), + enable ? (CNTRL_RXE | CNTRL_RFE) : 0); +} + +static inline void control_tx_modulation_enable(struct cx23885_dev *dev, + bool enable) +{ + cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_MOD, + enable ? CNTRL_MOD : 0); +} + +static inline void control_rx_demodulation_enable(struct cx23885_dev *dev, + bool enable) +{ + cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_DMD, + enable ? CNTRL_DMD : 0); +} + +static inline void control_rx_s_edge_detection(struct cx23885_dev *dev, + u32 edge_types) +{ + cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_EDG_BOTH, + edge_types & CNTRL_EDG_BOTH); +} + +static void control_rx_s_carrier_window(struct cx23885_dev *dev, + unsigned int carrier, + unsigned int *carrier_range_low, + unsigned int *carrier_range_high) +{ + u32 v; + unsigned int c16 = carrier * 16; + + if (*carrier_range_low < DIV_ROUND_CLOSEST(c16, 16 + 3)) { + v = CNTRL_WIN_3_4; + *carrier_range_low = DIV_ROUND_CLOSEST(c16, 16 + 4); + } else { + v = CNTRL_WIN_3_3; + *carrier_range_low = DIV_ROUND_CLOSEST(c16, 16 + 3); + } + + if (*carrier_range_high > DIV_ROUND_CLOSEST(c16, 16 - 3)) { + v |= CNTRL_WIN_4_3; + *carrier_range_high = DIV_ROUND_CLOSEST(c16, 16 - 4); + } else { + v |= CNTRL_WIN_3_3; + *carrier_range_high = DIV_ROUND_CLOSEST(c16, 16 - 3); + } + cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_WIN, v); +} + +static inline void control_tx_polarity_invert(struct cx23885_dev *dev, + bool invert) +{ + cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_CPL, + invert ? CNTRL_CPL : 0); +} + +/* + * IR Rx & Tx Clock Register helpers + */ +static unsigned int txclk_tx_s_carrier(struct cx23885_dev *dev, + unsigned int freq, + u16 *divider) +{ + *divider = carrier_freq_to_clock_divider(freq); + cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, *divider); + return clock_divider_to_carrier_freq(*divider); +} + +static unsigned int rxclk_rx_s_carrier(struct cx23885_dev *dev, + unsigned int freq, + u16 *divider) +{ + *divider = carrier_freq_to_clock_divider(freq); + cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, *divider); + return clock_divider_to_carrier_freq(*divider); +} + +static u32 txclk_tx_s_max_pulse_width(struct cx23885_dev *dev, u32 ns, + u16 *divider) +{ + u64 pulse_clocks; + + if (ns > V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS) + ns = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS; + pulse_clocks = ns_to_pulse_clocks(ns); + *divider = pulse_clocks_to_clock_divider(pulse_clocks); + cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, *divider); + return (u32) pulse_width_count_to_ns(FIFO_RXTX, *divider); +} + +static u32 rxclk_rx_s_max_pulse_width(struct cx23885_dev *dev, u32 ns, + u16 *divider) +{ + u64 pulse_clocks; + + if (ns > V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS) + ns = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS; + pulse_clocks = ns_to_pulse_clocks(ns); + *divider = pulse_clocks_to_clock_divider(pulse_clocks); + cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, *divider); + return (u32) pulse_width_count_to_ns(FIFO_RXTX, *divider); +} + +/* + * IR Tx Carrier Duty Cycle register helpers + */ +static unsigned int cduty_tx_s_duty_cycle(struct cx23885_dev *dev, + unsigned int duty_cycle) +{ + u32 n; + n = DIV_ROUND_CLOSEST(duty_cycle * 100, 625); /* 16ths of 100% */ + if (n != 0) + n--; + if (n > 15) + n = 15; + cx23888_ir_write4(dev, CX23888_IR_CDUTY_REG, n); + return DIV_ROUND_CLOSEST((n+1) * 100, 16); +} + +/* + * IR Filter Register helpers + */ +static u32 filter_rx_s_min_width(struct cx23885_dev *dev, u32 min_width_ns) +{ + u32 count = ns_to_lpf_count(min_width_ns); + cx23888_ir_write4(dev, CX23888_IR_FILTR_REG, count); + return lpf_count_to_ns(count); +} + +/* + * IR IRQ Enable Register helpers + */ +static inline void irqenable_rx(struct cx23885_dev *dev, u32 mask) +{ + mask &= (IRQEN_RTE | IRQEN_ROE | IRQEN_RSE); + cx23888_ir_and_or4(dev, CX23888_IR_IRQEN_REG, + ~(IRQEN_RTE | IRQEN_ROE | IRQEN_RSE), mask); +} + +static inline void irqenable_tx(struct cx23885_dev *dev, u32 mask) +{ + mask &= IRQEN_TSE; + cx23888_ir_and_or4(dev, CX23888_IR_IRQEN_REG, ~IRQEN_TSE, mask); +} + +/* + * V4L2 Subdevice IR Ops + */ +static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status, + bool *handled) +{ + struct cx23888_ir_state *state = to_state(sd); + struct cx23885_dev *dev = state->dev; + + u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG); + u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG); + u32 stats = cx23888_ir_read4(dev, CX23888_IR_STATS_REG); + + u32 rx_data[FIFO_RX_DEPTH]; + int i, j, k; + u32 events, v; + int tsr, rsr, rto, ror, tse, rse, rte, roe, kror; + + tsr = stats & STATS_TSR; /* Tx FIFO Service Request */ + rsr = stats & STATS_RSR; /* Rx FIFO Service Request */ + rto = stats & STATS_RTO; /* Rx Pulse Width Timer Time Out */ + ror = stats & STATS_ROR; /* Rx FIFO Over Run */ + + tse = irqen & IRQEN_TSE; /* Tx FIFO Service Request IRQ Enable */ + rse = irqen & IRQEN_RSE; /* Rx FIFO Service Reuqest IRQ Enable */ + rte = irqen & IRQEN_RTE; /* Rx Pulse Width Timer Time Out IRQ Enable */ + roe = irqen & IRQEN_ROE; /* Rx FIFO Over Run IRQ Enable */ + + *handled = false; + v4l2_dbg(2, ir_888_debug, sd, "IRQ Status: %s %s %s %s %s %s\n", + tsr ? "tsr" : " ", rsr ? "rsr" : " ", + rto ? "rto" : " ", ror ? "ror" : " ", + stats & STATS_TBY ? "tby" : " ", + stats & STATS_RBY ? "rby" : " "); + + v4l2_dbg(2, ir_888_debug, sd, "IRQ Enables: %s %s %s %s\n", + tse ? "tse" : " ", rse ? "rse" : " ", + rte ? "rte" : " ", roe ? "roe" : " "); + + /* + * Transmitter interrupt service + */ + if (tse && tsr) { + /* + * TODO: + * Check the watermark threshold setting + * Pull FIFO_TX_DEPTH or FIFO_TX_DEPTH/2 entries from tx_kfifo + * Push the data to the hardware FIFO. + * If there was nothing more to send in the tx_kfifo, disable + * the TSR IRQ and notify the v4l2_device. + * If there was something in the tx_kfifo, check the tx_kfifo + * level and notify the v4l2_device, if it is low. + */ + /* For now, inhibit TSR interrupt until Tx is implemented */ + irqenable_tx(dev, 0); + events = V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ; + v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_TX_NOTIFY, &events); + *handled = true; + } + + /* + * Receiver interrupt service + */ + kror = 0; + if ((rse && rsr) || (rte && rto)) { + /* + * Receive data on RSR to clear the STATS_RSR. + * Receive data on RTO, since we may not have yet hit the RSR + * watermark when we receive the RTO. + */ + for (i = 0, v = FIFO_RX_NDV; + (v & FIFO_RX_NDV) && !kror; i = 0) { + for (j = 0; + (v & FIFO_RX_NDV) && j < FIFO_RX_DEPTH; j++) { + v = cx23888_ir_read4(dev, CX23888_IR_FIFO_REG); + rx_data[i++] = v & ~FIFO_RX_NDV; + } + if (i == 0) + break; + j = i * sizeof(u32); + k = kfifo_put(state->rx_kfifo, + (unsigned char *) rx_data, j); + if (k != j) + kror++; /* rx_kfifo over run */ + } + *handled = true; + } + + events = 0; + v = 0; + if (kror) { + events |= V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN; + v4l2_err(sd, "IR receiver software FIFO overrun\n"); + } + if (roe && ror) { + /* + * The RX FIFO Enable (CNTRL_RFE) must be toggled to clear + * the Rx FIFO Over Run status (STATS_ROR) + */ + v |= CNTRL_RFE; + events |= V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN; + v4l2_err(sd, "IR receiver hardware FIFO overrun\n"); + } + if (rte && rto) { + /* + * The IR Receiver Enable (CNTRL_RXE) must be toggled to clear + * the Rx Pulse Width Timer Time Out (STATS_RTO) + */ + v |= CNTRL_RXE; + events |= V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED; + } + if (v) { + /* Clear STATS_ROR & STATS_RTO as needed by reseting hardware */ + cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl & ~v); + cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl); + *handled = true; + } + if (kfifo_len(state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE/2) + events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ; + + if (events) + v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_RX_NOTIFY, &events); return 0; } -static u8 cx23888_ir_read(struct cx23885_dev *dev, u32 addr) +/* Receiver */ +static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count, + ssize_t *num) { - u32 x = cx_read((addr & ~3)); - int shift = (addr & 3) * 8; + struct cx23888_ir_state *state = to_state(sd); + bool invert = (bool) atomic_read(&state->rx_invert); + u16 divider = (u16) atomic_read(&state->rxclk_divider); + + unsigned int i, n; + u32 *p; + u32 u, v; + + n = count / sizeof(u32) * sizeof(u32); + if (n == 0) { + *num = 0; + return 0; + } + + n = kfifo_get(state->rx_kfifo, buf, n); + + n /= sizeof(u32); + *num = n * sizeof(u32); + + for (p = (u32 *) buf, i = 0; i < n; p++, i++) { + if ((*p & FIFO_RXTX_RTO) == FIFO_RXTX_RTO) { + *p = V4L2_SUBDEV_IR_PULSE_RX_SEQ_END; + v4l2_dbg(2, ir_888_debug, sd, "rx read: end of rx\n"); + continue; + } + + u = (*p & FIFO_RXTX_LVL) ? V4L2_SUBDEV_IR_PULSE_LEVEL_MASK : 0; + if (invert) + u = u ? 0 : V4L2_SUBDEV_IR_PULSE_LEVEL_MASK; - return (x >> shift) & 0xff; + v = (u32) pulse_width_count_to_ns((u16) (*p & FIFO_RXTX), + divider); + if (v >= V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS) + v = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS - 1; + + *p = u | v; + + v4l2_dbg(2, ir_888_debug, sd, "rx read: %10u ns %s\n", + v, u ? "mark" : "space"); + } + return 0; } -static inline u32 cx23888_ir_read4(struct cx23885_dev *dev, u32 addr) +static int cx23888_ir_rx_g_parameters(struct v4l2_subdev *sd, + struct v4l2_subdev_ir_parameters *p) { - return cx_read(addr); + struct cx23888_ir_state *state = to_state(sd); + mutex_lock(&state->rx_params_lock); + memcpy(p, &state->rx_params, sizeof(struct v4l2_subdev_ir_parameters)); + mutex_unlock(&state->rx_params_lock); + return 0; } -static int cx23888_ir_and_or(struct cx23885_dev *dev, u32 addr, - unsigned and_mask, u8 or_value) +static int cx23888_ir_rx_shutdown(struct v4l2_subdev *sd) { - return cx23888_ir_write(dev, addr, - (cx23888_ir_read(dev, addr) & and_mask) | - or_value); + struct cx23888_ir_state *state = to_state(sd); + struct cx23885_dev *dev = state->dev; + + mutex_lock(&state->rx_params_lock); + + /* Disable or slow down all IR Rx circuits and counters */ + irqenable_rx(dev, 0); + control_rx_enable(dev, false); + control_rx_demodulation_enable(dev, false); + control_rx_s_edge_detection(dev, CNTRL_EDG_NONE); + filter_rx_s_min_width(dev, 0); + cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, RXCLK_RCD); + + state->rx_params.shutdown = true; + + mutex_unlock(&state->rx_params_lock); + return 0; } -static inline int cx23888_ir_and_or4(struct cx23885_dev *dev, u32 addr, - u32 and_mask, u32 or_value) +static int cx23888_ir_rx_s_parameters(struct v4l2_subdev *sd, + struct v4l2_subdev_ir_parameters *p) { - cx_andor(addr, and_mask, or_value); + struct cx23888_ir_state *state = to_state(sd); + struct cx23885_dev *dev = state->dev; + struct v4l2_subdev_ir_parameters *o = &state->rx_params; + u16 rxclk_divider; + + if (p->shutdown) + return cx23888_ir_rx_shutdown(sd); + + if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH) + return -ENOSYS; + + mutex_lock(&state->rx_params_lock); + + o->shutdown = p->shutdown; + + o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH; + + o->bytes_per_data_element = p->bytes_per_data_element = sizeof(u32); + + /* Before we tweak the hardware, we have to disable the receiver */ + irqenable_rx(dev, 0); + control_rx_enable(dev, false); + + control_rx_demodulation_enable(dev, p->modulation); + o->modulation = p->modulation; + + if (p->modulation) { + p->carrier_freq = rxclk_rx_s_carrier(dev, p->carrier_freq, + &rxclk_divider); + + o->carrier_freq = p->carrier_freq; + + o->duty_cycle = p->duty_cycle = 50; + + control_rx_s_carrier_window(dev, p->carrier_freq, + &p->carrier_range_lower, + &p->carrier_range_upper); + o->carrier_range_lower = p->carrier_range_lower; + o->carrier_range_upper = p->carrier_range_upper; + } else { + p->max_pulse_width = + rxclk_rx_s_max_pulse_width(dev, p->max_pulse_width, + &rxclk_divider); + o->max_pulse_width = p->max_pulse_width; + } + atomic_set(&state->rxclk_divider, rxclk_divider); + + p->noise_filter_min_width = + filter_rx_s_min_width(dev, p->noise_filter_min_width); + o->noise_filter_min_width = p->noise_filter_min_width; + + p->resolution = clock_divider_to_resolution(rxclk_divider); + o->resolution = p->resolution; + + /* FIXME - make this dependent on resolution for better performance */ + control_rx_irq_watermark(dev, RX_FIFO_HALF_FULL); + + control_rx_s_edge_detection(dev, CNTRL_EDG_BOTH); + + o->invert = p->invert; + atomic_set(&state->rx_invert, p->invert); + + o->interrupt_enable = p->interrupt_enable; + o->enable = p->enable; + if (p->enable) { + kfifo_reset(state->rx_kfifo); + if (p->interrupt_enable) + irqenable_rx(dev, IRQEN_RSE | IRQEN_RTE | IRQEN_ROE); + control_rx_enable(dev, p->enable); + } + + mutex_unlock(&state->rx_params_lock); + return 0; +} + +/* Transmitter */ +static int cx23888_ir_tx_write(struct v4l2_subdev *sd, u8 *buf, size_t count, + ssize_t *num) +{ + struct cx23888_ir_state *state = to_state(sd); + struct cx23885_dev *dev = state->dev; + /* For now enable the Tx FIFO Service interrupt & pretend we did work */ + irqenable_tx(dev, IRQEN_TSE); + *num = count; + return 0; +} + +static int cx23888_ir_tx_g_parameters(struct v4l2_subdev *sd, + struct v4l2_subdev_ir_parameters *p) +{ + struct cx23888_ir_state *state = to_state(sd); + mutex_lock(&state->tx_params_lock); + memcpy(p, &state->tx_params, sizeof(struct v4l2_subdev_ir_parameters)); + mutex_unlock(&state->tx_params_lock); return 0; } +static int cx23888_ir_tx_shutdown(struct v4l2_subdev *sd) +{ + struct cx23888_ir_state *state = to_state(sd); + struct cx23885_dev *dev = state->dev; + + mutex_lock(&state->tx_params_lock); + + /* Disable or slow down all IR Tx circuits and counters */ + irqenable_tx(dev, 0); + control_tx_enable(dev, false); + control_tx_modulation_enable(dev, false); + cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, TXCLK_TCD); + + state->tx_params.shutdown = true; + + mutex_unlock(&state->tx_params_lock); + return 0; +} + +static int cx23888_ir_tx_s_parameters(struct v4l2_subdev *sd, + struct v4l2_subdev_ir_parameters *p) +{ + struct cx23888_ir_state *state = to_state(sd); + struct cx23885_dev *dev = state->dev; + struct v4l2_subdev_ir_parameters *o = &state->tx_params; + u16 txclk_divider; + + if (p->shutdown) + return cx23888_ir_tx_shutdown(sd); + + if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH) + return -ENOSYS; + + mutex_lock(&state->tx_params_lock); + + o->shutdown = p->shutdown; + + o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH; + + o->bytes_per_data_element = p->bytes_per_data_element = sizeof(u32); + + /* Before we tweak the hardware, we have to disable the transmitter */ + irqenable_tx(dev, 0); + control_tx_enable(dev, false); + + control_tx_modulation_enable(dev, p->modulation); + o->modulation = p->modulation; + + if (p->modulation) { + p->carrier_freq = txclk_tx_s_carrier(dev, p->carrier_freq, + &txclk_divider); + o->carrier_freq = p->carrier_freq; + + p->duty_cycle = cduty_tx_s_duty_cycle(dev, p->duty_cycle); + o->duty_cycle = p->duty_cycle; + } else { + p->max_pulse_width = + txclk_tx_s_max_pulse_width(dev, p->max_pulse_width, + &txclk_divider); + o->max_pulse_width = p->max_pulse_width; + } + atomic_set(&state->txclk_divider, txclk_divider); + + p->resolution = clock_divider_to_resolution(txclk_divider); + o->resolution = p->resolution; + + /* FIXME - make this dependent on resolution for better performance */ + control_tx_irq_watermark(dev, TX_FIFO_HALF_EMPTY); + + control_tx_polarity_invert(dev, p->invert); + o->invert = p->invert; + + o->interrupt_enable = p->interrupt_enable; + o->enable = p->enable; + if (p->enable) { + kfifo_reset(state->tx_kfifo); + if (p->interrupt_enable) + irqenable_tx(dev, IRQEN_TSE); + control_tx_enable(dev, p->enable); + } + + mutex_unlock(&state->tx_params_lock); + return 0; +} + + +/* + * V4L2 Subdevice Core Ops + */ static int cx23888_ir_log_status(struct v4l2_subdev *sd) { struct cx23888_ir_state *state = to_state(sd); struct cx23885_dev *dev = state->dev; - u8 cntrl = cx23888_ir_read(dev, CX23888_IR_CNTRL_REG+1); - v4l2_info(sd, "receiver %sabled\n", cntrl & 0x1 ? "en" : "dis"); - v4l2_info(sd, "transmitter %sabled\n", cntrl & 0x2 ? "en" : "dis"); + char *s; + int i, j; + + u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG); + u32 txclk = cx23888_ir_read4(dev, CX23888_IR_TXCLK_REG) & TXCLK_TCD; + u32 rxclk = cx23888_ir_read4(dev, CX23888_IR_RXCLK_REG) & RXCLK_RCD; + u32 cduty = cx23888_ir_read4(dev, CX23888_IR_CDUTY_REG) & CDUTY_CDC; + u32 stats = cx23888_ir_read4(dev, CX23888_IR_STATS_REG); + u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG); + u32 filtr = cx23888_ir_read4(dev, CX23888_IR_FILTR_REG) & FILTR_LPF; + + v4l2_info(sd, "IR Receiver:\n"); + v4l2_info(sd, "\tEnabled: %s\n", + cntrl & CNTRL_RXE ? "yes" : "no"); + v4l2_info(sd, "\tDemodulation from a carrier: %s\n", + cntrl & CNTRL_DMD ? "enabled" : "disabled"); + v4l2_info(sd, "\tFIFO: %s\n", + cntrl & CNTRL_RFE ? "enabled" : "disabled"); + switch (cntrl & CNTRL_EDG) { + case CNTRL_EDG_NONE: + s = "disabled"; + break; + case CNTRL_EDG_FALL: + s = "falling edge"; + break; + case CNTRL_EDG_RISE: + s = "rising edge"; + break; + case CNTRL_EDG_BOTH: + s = "rising & falling edges"; + break; + default: + s = "??? edge"; + break; + } + v4l2_info(sd, "\tPulse timers' start/stop trigger: %s\n", s); + v4l2_info(sd, "\tFIFO data on pulse timer overflow: %s\n", + cntrl & CNTRL_R ? "not loaded" : "overflow marker"); + v4l2_info(sd, "\tFIFO interrupt watermark: %s\n", + cntrl & CNTRL_RIC ? "not empty" : "half full or greater"); + v4l2_info(sd, "\tLoopback mode: %s\n", + cntrl & CNTRL_LBM ? "loopback active" : "normal receive"); + if (cntrl & CNTRL_DMD) { + v4l2_info(sd, "\tExpected carrier (16 clocks): %u Hz\n", + clock_divider_to_carrier_freq(rxclk)); + switch (cntrl & CNTRL_WIN) { + case CNTRL_WIN_3_3: + i = 3; + j = 3; + break; + case CNTRL_WIN_4_3: + i = 4; + j = 3; + break; + case CNTRL_WIN_3_4: + i = 3; + j = 4; + break; + case CNTRL_WIN_4_4: + i = 4; + j = 4; + break; + default: + i = 0; + j = 0; + break; + } + v4l2_info(sd, "\tNext carrier edge window: 16 clocks " + "-%1d/+%1d, %u to %u Hz\n", i, j, + clock_divider_to_freq(rxclk, 16 + j), + clock_divider_to_freq(rxclk, 16 - i)); + } else { + v4l2_info(sd, "\tMax measurable pulse width: %u us, " + "%llu ns\n", + pulse_width_count_to_us(FIFO_RXTX, rxclk), + pulse_width_count_to_ns(FIFO_RXTX, rxclk)); + } + v4l2_info(sd, "\tLow pass filter: %s\n", + filtr ? "enabled" : "disabled"); + if (filtr) + v4l2_info(sd, "\tMin acceptable pulse width (LPF): %u us, " + "%u ns\n", + lpf_count_to_us(filtr), + lpf_count_to_ns(filtr)); + v4l2_info(sd, "\tPulse width timer timed-out: %s\n", + stats & STATS_RTO ? "yes" : "no"); + v4l2_info(sd, "\tPulse width timer time-out intr: %s\n", + irqen & IRQEN_RTE ? "enabled" : "disabled"); + v4l2_info(sd, "\tFIFO overrun: %s\n", + stats & STATS_ROR ? "yes" : "no"); + v4l2_info(sd, "\tFIFO overrun interrupt: %s\n", + irqen & IRQEN_ROE ? "enabled" : "disabled"); + v4l2_info(sd, "\tBusy: %s\n", + stats & STATS_RBY ? "yes" : "no"); + v4l2_info(sd, "\tFIFO service requested: %s\n", + stats & STATS_RSR ? "yes" : "no"); + v4l2_info(sd, "\tFIFO service request interrupt: %s\n", + irqen & IRQEN_RSE ? "enabled" : "disabled"); + + v4l2_info(sd, "IR Transmitter:\n"); + v4l2_info(sd, "\tEnabled: %s\n", + cntrl & CNTRL_TXE ? "yes" : "no"); + v4l2_info(sd, "\tModulation onto a carrier: %s\n", + cntrl & CNTRL_MOD ? "enabled" : "disabled"); + v4l2_info(sd, "\tFIFO: %s\n", + cntrl & CNTRL_TFE ? "enabled" : "disabled"); + v4l2_info(sd, "\tFIFO interrupt watermark: %s\n", + cntrl & CNTRL_TIC ? "not empty" : "half full or less"); + v4l2_info(sd, "\tSignal polarity: %s\n", + cntrl & CNTRL_CPL ? "0:mark 1:space" : "0:space 1:mark"); + if (cntrl & CNTRL_MOD) { + v4l2_info(sd, "\tCarrier (16 clocks): %u Hz\n", + clock_divider_to_carrier_freq(txclk)); + v4l2_info(sd, "\tCarrier duty cycle: %2u/16\n", + cduty + 1); + } else { + v4l2_info(sd, "\tMax pulse width: %u us, " + "%llu ns\n", + pulse_width_count_to_us(FIFO_RXTX, txclk), + pulse_width_count_to_ns(FIFO_RXTX, txclk)); + } + v4l2_info(sd, "\tBusy: %s\n", + stats & STATS_TBY ? "yes" : "no"); + v4l2_info(sd, "\tFIFO service requested: %s\n", + stats & STATS_TSR ? "yes" : "no"); + v4l2_info(sd, "\tFIFO service request interrupt: %s\n", + irqen & IRQEN_TSE ? "enabled" : "disabled"); + return 0; } @@ -187,19 +1105,81 @@ static const struct v4l2_subdev_core_ops cx23888_ir_core_ops = { #endif }; +static const struct v4l2_subdev_ir_ops cx23888_ir_ir_ops = { + .interrupt_service_routine = cx23888_ir_irq_handler, + + .rx_read = cx23888_ir_rx_read, + .rx_g_parameters = cx23888_ir_rx_g_parameters, + .rx_s_parameters = cx23888_ir_rx_s_parameters, + + .tx_write = cx23888_ir_tx_write, + .tx_g_parameters = cx23888_ir_tx_g_parameters, + .tx_s_parameters = cx23888_ir_tx_s_parameters, +}; + static const struct v4l2_subdev_ops cx23888_ir_controller_ops = { .core = &cx23888_ir_core_ops, + .ir = &cx23888_ir_ir_ops, +}; + +static const struct v4l2_subdev_ir_parameters default_rx_params = { + .bytes_per_data_element = sizeof(u32), + .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH, + + .enable = false, + .interrupt_enable = false, + .shutdown = true, + + .modulation = true, + .carrier_freq = 36000, /* 36 kHz - RC-5, RC-6, and RC-6A carrier */ + + /* RC-5: 666,667 ns = 1/36 kHz * 32 cycles * 1 mark * 0.75 */ + /* RC-6A: 333,333 ns = 1/36 kHz * 16 cycles * 1 mark * 0.75 */ + .noise_filter_min_width = 333333, /* ns */ + .carrier_range_lower = 35000, + .carrier_range_upper = 37000, + .invert = false, +}; + +static const struct v4l2_subdev_ir_parameters default_tx_params = { + .bytes_per_data_element = sizeof(u32), + .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH, + + .enable = false, + .interrupt_enable = false, + .shutdown = true, + + .modulation = true, + .carrier_freq = 36000, /* 36 kHz - RC-5 carrier */ + .duty_cycle = 25, /* 25 % - RC-5 carrier */ + .invert = false, }; int cx23888_ir_probe(struct cx23885_dev *dev) { struct cx23888_ir_state *state; struct v4l2_subdev *sd; + struct v4l2_subdev_ir_parameters default_params; + int ret; state = kzalloc(sizeof(struct cx23888_ir_state), GFP_KERNEL); if (state == NULL) return -ENOMEM; + spin_lock_init(&state->rx_kfifo_lock); + state->rx_kfifo = kfifo_alloc(CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL, + &state->rx_kfifo_lock); + if (state->rx_kfifo == NULL) + return -ENOMEM; + + spin_lock_init(&state->tx_kfifo_lock); + state->tx_kfifo = kfifo_alloc(CX23888_IR_TX_KFIFO_SIZE, GFP_KERNEL, + &state->tx_kfifo_lock); + if (state->tx_kfifo == NULL) { + kfifo_free(state->rx_kfifo); + return -ENOMEM; + } + state->dev = dev; state->id = V4L2_IDENT_CX23888_IR; state->rev = 0; @@ -210,7 +1190,30 @@ int cx23888_ir_probe(struct cx23885_dev *dev) /* FIXME - fix the formatting of dev->v4l2_dev.name and use it */ snprintf(sd->name, sizeof(sd->name), "%s/888-ir", dev->name); sd->grp_id = CX23885_HW_888_IR; - return v4l2_device_register_subdev(&dev->v4l2_dev, sd); + + ret = v4l2_device_register_subdev(&dev->v4l2_dev, sd); + if (ret == 0) { + /* + * Ensure no interrupts arrive from '888 specific conditions, + * since we ignore them in this driver to have commonality with + * similar IR controller cores. + */ + cx23888_ir_write4(dev, CX23888_IR_IRQEN_REG, 0); + + mutex_init(&state->rx_params_lock); + memcpy(&default_params, &default_rx_params, + sizeof(struct v4l2_subdev_ir_parameters)); + v4l2_subdev_call(sd, ir, rx_s_parameters, &default_params); + + mutex_init(&state->tx_params_lock); + memcpy(&default_params, &default_tx_params, + sizeof(struct v4l2_subdev_ir_parameters)); + v4l2_subdev_call(sd, ir, tx_s_parameters, &default_params); + } else { + kfifo_free(state->rx_kfifo); + kfifo_free(state->tx_kfifo); + } + return ret; } int cx23888_ir_remove(struct cx23885_dev *dev) @@ -222,11 +1225,13 @@ int cx23888_ir_remove(struct cx23885_dev *dev) if (sd == NULL) return -ENODEV; - /* Disable receiver and transmitter */ - cx23888_ir_and_or(dev, CX23888_IR_CNTRL_REG+1, 0xfc, 0); + cx23888_ir_rx_shutdown(sd); + cx23888_ir_tx_shutdown(sd); state = to_state(sd); v4l2_device_unregister_subdev(sd); + kfifo_free(state->rx_kfifo); + kfifo_free(state->tx_kfifo); kfree(state); /* Nothing more to free() as state held the actual v4l2_subdev object */ return 0; -- cgit v1.2.3-70-g09d2 From f59ad611acccd4057b8e685c7fd5532ab1a17f66 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 27 Sep 2009 19:51:50 -0300 Subject: V4L/DVB (13098): cx23885: Add integrated IR subdevice interrupt and notification handling Add integrated IR subdevice interrupt and notification handling. This is in preparation of input keypress handling changes for the cx23885 module. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/Makefile | 2 +- drivers/media/video/cx23885/cx23885-cards.c | 23 +++++++ drivers/media/video/cx23885/cx23885-core.c | 74 +++++++++++++++++----- drivers/media/video/cx23885/cx23885-ir.c | 97 +++++++++++++++++++++++++++++ drivers/media/video/cx23885/cx23885-ir.h | 31 +++++++++ drivers/media/video/cx23885/cx23885-reg.h | 5 +- drivers/media/video/cx23885/cx23885.h | 10 ++- 7 files changed, 224 insertions(+), 18 deletions(-) create mode 100644 drivers/media/video/cx23885/cx23885-ir.c create mode 100644 drivers/media/video/cx23885/cx23885-ir.h (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile index 3832a1cb768..330cff3f77a 100644 --- a/drivers/media/video/cx23885/Makefile +++ b/drivers/media/video/cx23885/Makefile @@ -1,6 +1,6 @@ cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \ cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \ - cx23885-ioctl.o cx23888-ir.o \ + cx23885-ioctl.o cx23885-ir.o cx23888-ir.o \ netup-init.o cimax2.o netup-eeprom.o obj-$(CONFIG_VIDEO_CX23885) += cx23885.o diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 7c5d13ac538..c0e2409f3cb 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -821,6 +821,7 @@ int cx23885_ir_init(struct cx23885_dev *dev) if (ret) break; dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_888_IR); + dev->pci_irqmask |= PCI_MSK_IR; break; case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: request_module("ir-kbd-i2c"); @@ -830,6 +831,28 @@ int cx23885_ir_init(struct cx23885_dev *dev) return ret; } +void cx23885_ir_fini(struct cx23885_dev *dev) +{ + switch (dev->board) { + case CX23885_BOARD_HAUPPAUGE_HVR1850: + dev->pci_irqmask &= ~PCI_MSK_IR; + cx_clear(PCI_INT_MSK, PCI_MSK_IR); + cx23888_ir_remove(dev); + dev->sd_ir = NULL; + break; + } +} + +void cx23885_ir_pci_int_enable(struct cx23885_dev *dev) +{ + switch (dev->board) { + case CX23885_BOARD_HAUPPAUGE_HVR1850: + if (dev->sd_ir && (dev->pci_irqmask & PCI_MSK_IR)) + cx_set(PCI_INT_MSK, PCI_MSK_IR); + break; + } +} + void cx23885_card_setup(struct cx23885_dev *dev) { struct cx23885_tsport *ts1 = &dev->ts1; diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index 73be16b0d2a..c879211a704 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -33,6 +33,7 @@ #include "cx23885.h" #include "cimax2.h" #include "cx23888-ir.h" +#include "cx23885-ir.h" MODULE_DESCRIPTION("Driver for cx23885 based TV cards"); MODULE_AUTHOR("Steven Toth "); @@ -1655,6 +1656,7 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) u32 ts1_status, ts1_mask; u32 ts2_status, ts2_mask; int vida_count = 0, ts1_count = 0, ts2_count = 0, handled = 0; + bool ir_handled = false; pci_status = cx_read(PCI_INT_STAT); pci_mask = cx_read(PCI_INT_MSK); @@ -1680,18 +1682,12 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n", ts2_status, ts2_mask, ts2_count); - if ((pci_status & PCI_MSK_RISC_RD) || - (pci_status & PCI_MSK_RISC_WR) || - (pci_status & PCI_MSK_AL_RD) || - (pci_status & PCI_MSK_AL_WR) || - (pci_status & PCI_MSK_APB_DMA) || - (pci_status & PCI_MSK_VID_C) || - (pci_status & PCI_MSK_VID_B) || - (pci_status & PCI_MSK_VID_A) || - (pci_status & PCI_MSK_AUD_INT) || - (pci_status & PCI_MSK_AUD_EXT) || - (pci_status & PCI_MSK_GPIO0) || - (pci_status & PCI_MSK_GPIO1)) { + if (pci_status & (PCI_MSK_RISC_RD | PCI_MSK_RISC_WR | + PCI_MSK_AL_RD | PCI_MSK_AL_WR | PCI_MSK_APB_DMA | + PCI_MSK_VID_C | PCI_MSK_VID_B | PCI_MSK_VID_A | + PCI_MSK_AUD_INT | PCI_MSK_AUD_EXT | + PCI_MSK_GPIO0 | PCI_MSK_GPIO1 | + PCI_MSK_IR)) { if (pci_status & PCI_MSK_RISC_RD) dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n", @@ -1740,6 +1736,10 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) if (pci_status & PCI_MSK_GPIO1) dprintk(7, " (PCI_MSK_GPIO1 0x%08x)\n", PCI_MSK_GPIO1); + + if (pci_status & PCI_MSK_IR) + dprintk(7, " (PCI_MSK_IR 0x%08x)\n", + PCI_MSK_IR); } if (cx23885_boards[dev->board].cimax > 0 && @@ -1770,12 +1770,48 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) if (vida_status) handled += cx23885_video_irq(dev, vida_status); + if (pci_status & PCI_MSK_IR) { + v4l2_subdev_call(dev->sd_ir, ir, interrupt_service_routine, + pci_status, &ir_handled); + if (ir_handled) + handled++; + } + if (handled) cx_write(PCI_INT_STAT, pci_status); out: return IRQ_RETVAL(handled); } +static void cx23885_v4l2_dev_notify(struct v4l2_subdev *sd, + unsigned int notification, void *arg) +{ + struct cx23885_dev *dev; + + if (sd == NULL) + return; + + dev = to_cx23885(sd->v4l2_dev); + + switch (notification) { + case V4L2_SUBDEV_IR_RX_NOTIFY: /* Called in an IRQ context */ + if (sd == dev->sd_ir) + cx23885_ir_rx_v4l2_dev_notify(sd, *(u32 *)arg); + break; + case V4L2_SUBDEV_IR_TX_NOTIFY: /* Called in an IRQ context */ + if (sd == dev->sd_ir) + cx23885_ir_tx_v4l2_dev_notify(sd, *(u32 *)arg); + break; + } +} + +static void cx23885_v4l2_dev_notify_init(struct cx23885_dev *dev) +{ + INIT_WORK(&dev->ir_rx_work, cx23885_ir_rx_work_handler); + INIT_WORK(&dev->ir_tx_work, cx23885_ir_tx_work_handler); + dev->v4l2_dev.notify = cx23885_v4l2_dev_notify; +} + static inline int encoder_on_portb(struct cx23885_dev *dev) { return cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER; @@ -1872,6 +1908,9 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev, if (err < 0) goto fail_free; + /* Prepare to handle notifications from subdevices */ + cx23885_v4l2_dev_notify_init(dev); + /* pci init */ dev->pci = pci_dev; if (pci_enable_device(pci_dev)) { @@ -1914,6 +1953,13 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev, break; } + /* + * The CX2388[58] IR controller can start firing interrupts when + * enabled, so these have to take place after the cx23885_irq() handler + * is hooked up by the call to request_irq() above. + */ + cx23885_ir_pci_int_enable(dev); + return 0; fail_irq: @@ -1930,9 +1976,9 @@ static void __devexit cx23885_finidev(struct pci_dev *pci_dev) struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); struct cx23885_dev *dev = to_cx23885(v4l2_dev); - cx23885_shutdown(dev); + cx23885_ir_fini(dev); - cx23888_ir_remove(dev); + cx23885_shutdown(dev); pci_disable_device(pci_dev); diff --git a/drivers/media/video/cx23885/cx23885-ir.c b/drivers/media/video/cx23885/cx23885-ir.c new file mode 100644 index 00000000000..e84f90c75bf --- /dev/null +++ b/drivers/media/video/cx23885/cx23885-ir.c @@ -0,0 +1,97 @@ +/* + * Driver for the Conexant CX23885/7/8 PCIe bridge + * + * Infrared device support routines - non-input, non-vl42_subdev routines + * + * Copyright (C) 2009 Andy Walls + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#include + +#include "cx23885.h" + +#define CX23885_IR_RX_FIFO_SERVICE_REQ 0 +#define CX23885_IR_RX_END_OF_RX_DETECTED 1 +#define CX23885_IR_RX_HW_FIFO_OVERRUN 2 +#define CX23885_IR_RX_SW_FIFO_OVERRUN 3 + +#define CX23885_IR_TX_FIFO_SERVICE_REQ 0 + + +void cx23885_ir_rx_work_handler(struct work_struct *work) +{ + struct cx23885_dev *dev = + container_of(work, struct cx23885_dev, ir_rx_work); + u32 events = 0; + unsigned long *notifications = &dev->ir_rx_notifications; + + if (test_and_clear_bit(CX23885_IR_RX_SW_FIFO_OVERRUN, notifications)) + events |= V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN; + if (test_and_clear_bit(CX23885_IR_RX_HW_FIFO_OVERRUN, notifications)) + events |= V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN; + if (test_and_clear_bit(CX23885_IR_RX_END_OF_RX_DETECTED, notifications)) + events |= V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED; + if (test_and_clear_bit(CX23885_IR_RX_FIFO_SERVICE_REQ, notifications)) + events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ; + + if (events == 0) + return; +} + +void cx23885_ir_tx_work_handler(struct work_struct *work) +{ + struct cx23885_dev *dev = + container_of(work, struct cx23885_dev, ir_tx_work); + u32 events = 0; + unsigned long *notifications = &dev->ir_tx_notifications; + + if (test_and_clear_bit(CX23885_IR_TX_FIFO_SERVICE_REQ, notifications)) + events |= V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ; + + if (events == 0) + return; + +} + +/* Called in an IRQ context */ +void cx23885_ir_rx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events) +{ + struct cx23885_dev *dev = to_cx23885(sd->v4l2_dev); + unsigned long *notifications = &dev->ir_rx_notifications; + + if (events & V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ) + set_bit(CX23885_IR_RX_FIFO_SERVICE_REQ, notifications); + if (events & V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED) + set_bit(CX23885_IR_RX_END_OF_RX_DETECTED, notifications); + if (events & V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN) + set_bit(CX23885_IR_RX_HW_FIFO_OVERRUN, notifications); + if (events & V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN) + set_bit(CX23885_IR_RX_SW_FIFO_OVERRUN, notifications); + schedule_work(&dev->ir_rx_work); +} + +/* Called in an IRQ context */ +void cx23885_ir_tx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events) +{ + struct cx23885_dev *dev = to_cx23885(sd->v4l2_dev); + unsigned long *notifications = &dev->ir_tx_notifications; + + if (events & V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ) + set_bit(CX23885_IR_TX_FIFO_SERVICE_REQ, notifications); + schedule_work(&dev->ir_tx_work); +} diff --git a/drivers/media/video/cx23885/cx23885-ir.h b/drivers/media/video/cx23885/cx23885-ir.h new file mode 100644 index 00000000000..9b8a6d5d1ef --- /dev/null +++ b/drivers/media/video/cx23885/cx23885-ir.h @@ -0,0 +1,31 @@ +/* + * Driver for the Conexant CX23885/7/8 PCIe bridge + * + * Infrared device support routines - non-input, non-vl42_subdev routines + * + * Copyright (C) 2009 Andy Walls + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#ifndef _CX23885_IR_H_ +#define _CX23885_IR_H_ +void cx23885_ir_rx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events); +void cx23885_ir_tx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events); + +void cx23885_ir_rx_work_handler(struct work_struct *work); +void cx23885_ir_tx_work_handler(struct work_struct *work); +#endif diff --git a/drivers/media/video/cx23885/cx23885-reg.h b/drivers/media/video/cx23885/cx23885-reg.h index eafbe5226ba..c0bc9a06895 100644 --- a/drivers/media/video/cx23885/cx23885-reg.h +++ b/drivers/media/video/cx23885/cx23885-reg.h @@ -212,8 +212,9 @@ Channel manager Data Structure entry = 20 DWORD #define DEV_CNTRL2 0x00040000 -#define PCI_MSK_GPIO1 (1 << 24) -#define PCI_MSK_GPIO0 (1 << 23) +#define PCI_MSK_IR (1 << 28) +#define PCI_MSK_GPIO1 (1 << 24) +#define PCI_MSK_GPIO0 (1 << 23) #define PCI_MSK_APB_DMA (1 << 12) #define PCI_MSK_AL_WR (1 << 11) #define PCI_MSK_AL_RD (1 << 10) diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index f7ed146566d..ce82698db5f 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h @@ -355,7 +355,13 @@ struct cx23885_dev { unsigned char radio_addr; unsigned int has_radio; struct v4l2_subdev *sd_cx25840; - struct v4l2_subdev *sd_ir; + + /* Infrared */ + struct v4l2_subdev *sd_ir; + struct work_struct ir_rx_work; + unsigned long ir_rx_notifications; + struct work_struct ir_tx_work; + unsigned long ir_tx_notifications; /* V4l */ u32 freq; @@ -479,6 +485,8 @@ extern int cx23885_tuner_callback(void *priv, int component, int command, int arg); extern void cx23885_card_list(struct cx23885_dev *dev); extern int cx23885_ir_init(struct cx23885_dev *dev); +extern void cx23885_ir_pci_int_enable(struct cx23885_dev *dev); +extern void cx23885_ir_fini(struct cx23885_dev *dev); extern void cx23885_gpio_setup(struct cx23885_dev *dev); extern void cx23885_card_setup(struct cx23885_dev *dev); extern void cx23885_card_setup_pre_i2c(struct cx23885_dev *dev); -- cgit v1.2.3-70-g09d2 From 1d23a002434802078d806ddc2937bd69bbbd6dc8 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 27 Sep 2009 20:05:23 -0300 Subject: V4L/DVB (13099): ir-functions: Export ir_rc5_decode() for use by the cx23885 module Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-functions.c | 3 ++- include/media/ir-common.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c index abd4791acb0..fc2d8941459 100644 --- a/drivers/media/common/ir-functions.c +++ b/drivers/media/common/ir-functions.c @@ -275,7 +275,7 @@ EXPORT_SYMBOL_GPL(ir_decode_biphase); * saa7134 */ /* decode raw bit pattern to RC5 code */ -static u32 ir_rc5_decode(unsigned int code) +u32 ir_rc5_decode(unsigned int code) { unsigned int org_code = code; unsigned int pair; @@ -304,6 +304,7 @@ static u32 ir_rc5_decode(unsigned int code) RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); return rc5; } +EXPORT_SYMBOL_GPL(ir_rc5_decode); void ir_rc5_timer_end(unsigned long data) { diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 29f0e53cff9..af3257e6b80 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -111,6 +111,7 @@ u32 ir_extract_bits(u32 data, u32 mask); int ir_dump_samples(u32 *samples, int count); int ir_decode_biphase(u32 *samples, int count, int low, int high); int ir_decode_pulsedistance(u32 *samples, int count, int low, int high); +u32 ir_rc5_decode(unsigned int code); void ir_rc5_timer_end(unsigned long data); void ir_rc5_timer_keyup(unsigned long data); -- cgit v1.2.3-70-g09d2 From dbda8f701abb0e4693a30e9bef4a2301d1c8ea80 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 27 Sep 2009 20:55:41 -0300 Subject: V4L/DVB (13100): cx23885: Add IR input keypress handling and enable for the HVR-1850 This changes adds IR Rx keypress input event handling to the CX23885 module. This change specifically only adds input handling for IR devices implemented as v4l2_subdevices, using only the pulse width mode (for now), and only with RC-5 remotes. The V4L-DVB infrastructure is missing too much to support RC-6 mode 6A as used in many media center remotes. The grey Hauppauge RC-5 remote and HVR-1850 IR receiver work now. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/Makefile | 2 +- drivers/media/video/cx23885/cx23885-core.c | 3 + drivers/media/video/cx23885/cx23885-input.c | 418 ++++++++++++++++++++++++++++ drivers/media/video/cx23885/cx23885-input.h | 30 ++ drivers/media/video/cx23885/cx23885-ir.c | 4 + drivers/media/video/cx23885/cx23885.h | 3 + 6 files changed, 459 insertions(+), 1 deletion(-) create mode 100644 drivers/media/video/cx23885/cx23885-input.c create mode 100644 drivers/media/video/cx23885/cx23885-input.h (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile index 330cff3f77a..bb462589b53 100644 --- a/drivers/media/video/cx23885/Makefile +++ b/drivers/media/video/cx23885/Makefile @@ -1,6 +1,6 @@ cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \ cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \ - cx23885-ioctl.o cx23885-ir.o cx23888-ir.o \ + cx23885-ioctl.o cx23885-ir.o cx23885-input.o cx23888-ir.o \ netup-init.o cimax2.o netup-eeprom.o obj-$(CONFIG_VIDEO_CX23885) += cx23885.o diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index c879211a704..d6e41db500e 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -34,6 +34,7 @@ #include "cimax2.h" #include "cx23888-ir.h" #include "cx23885-ir.h" +#include "cx23885-input.h" MODULE_DESCRIPTION("Driver for cx23885 based TV cards"); MODULE_AUTHOR("Steven Toth "); @@ -1959,6 +1960,7 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev, * is hooked up by the call to request_irq() above. */ cx23885_ir_pci_int_enable(dev); + cx23885_input_init(dev); return 0; @@ -1976,6 +1978,7 @@ static void __devexit cx23885_finidev(struct pci_dev *pci_dev) struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); struct cx23885_dev *dev = to_cx23885(v4l2_dev); + cx23885_input_fini(dev); cx23885_ir_fini(dev); cx23885_shutdown(dev); diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c new file mode 100644 index 00000000000..c208079f4e9 --- /dev/null +++ b/drivers/media/video/cx23885/cx23885-input.c @@ -0,0 +1,418 @@ +/* + * Driver for the Conexant CX23885/7/8 PCIe bridge + * + * Infrared remote control input device + * + * Most of this file is + * + * Copyright (C) 2009 Andy Walls + * + * However, the cx23885_input_{init,fini} functions contained herein are + * derived from Linux kernel files linux/media/video/.../...-input.c marked as: + * + * Copyright (C) 2008 + * Copyright (C) 2005 Ludovico Cavedon + * Markus Rechberger + * Mauro Carvalho Chehab + * Sascha Sommer + * Copyright (C) 2004, 2005 Chris Pascoe + * Copyright (C) 2003, 2004 Gerd Knorr + * Copyright (C) 2003 Pavel Machek + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#include +#include +#include + +#include "cx23885.h" + +#define RC5_BITS 14 +#define RC5_HALF_BITS (2*RC5_BITS) +#define RC5_HALF_BITS_MASK ((1 << RC5_HALF_BITS) - 1) + +#define RC5_START_BITS_NORMAL 0x3 /* Command range 0 - 63 */ +#define RC5_START_BITS_EXTENDED 0x2 /* Command range 64 - 127 */ + +#define RC5_EXTENDED_COMMAND_OFFSET 64 + +static inline unsigned int rc5_command(u32 rc5_baseband) +{ + return RC5_INSTR(rc5_baseband) + + ((RC5_START(rc5_baseband) == RC5_START_BITS_EXTENDED) + ? RC5_EXTENDED_COMMAND_OFFSET : 0); +} + +static void cx23885_input_process_raw_rc5(struct cx23885_dev *dev) +{ + struct card_ir *ir_input = dev->ir_input; + unsigned int code, command; + u32 rc5; + + /* Ignore codes that are too short to be valid RC-5 */ + if (ir_input->last_bit < (RC5_HALF_BITS - 1)) + return; + + /* The library has the manchester coding backwards; XOR to adapt. */ + code = (ir_input->code & RC5_HALF_BITS_MASK) ^ RC5_HALF_BITS_MASK; + rc5 = ir_rc5_decode(code); + + switch (RC5_START(rc5)) { + case RC5_START_BITS_NORMAL: + break; + case RC5_START_BITS_EXTENDED: + /* Don't allow if the remote only emits standard commands */ + if (ir_input->start == RC5_START_BITS_NORMAL) + return; + break; + default: + return; + } + + if (ir_input->addr != RC5_ADDR(rc5)) + return; + + /* Don't generate a keypress for RC-5 auto-repeated keypresses */ + command = rc5_command(rc5); + if (RC5_TOGGLE(rc5) != RC5_TOGGLE(ir_input->last_rc5) || + command != rc5_command(ir_input->last_rc5) || + /* Catch T == 0, CMD == 0 (e.g. '0') as first keypress after init */ + RC5_START(ir_input->last_rc5) == 0) { + /* This keypress is differnet: not an auto repeat */ + ir_input_nokey(ir_input->dev, &ir_input->ir); + ir_input_keydown(ir_input->dev, &ir_input->ir, + command, ir_input->code); + } + ir_input->last_rc5 = rc5; + + /* Schedule when we should do the key up event: ir_input_nokey() */ + mod_timer(&ir_input->timer_keyup, + jiffies + msecs_to_jiffies(ir_input->rc5_key_timeout)); +} + +static void cx23885_input_next_pulse_width_rc5(struct cx23885_dev *dev, + u32 ns_pulse) +{ + const int rc5_quarterbit_ns = 444444; /* 32 cycles/36 kHz/2 = 444 us */ + struct card_ir *ir_input = dev->ir_input; + int i, level, quarterbits, halfbits; + + if (!ir_input->active) { + ir_input->active = 1; + /* assume an initial space that we may not detect or measure */ + ir_input->code = 0; + ir_input->last_bit = 0; + } + + if (ns_pulse == V4L2_SUBDEV_IR_PULSE_RX_SEQ_END) { + ir_input->last_bit++; /* Account for the final space */ + ir_input->active = 0; + cx23885_input_process_raw_rc5(dev); + return; + } + + level = (ns_pulse & V4L2_SUBDEV_IR_PULSE_LEVEL_MASK) ? 1 : 0; + + /* Skip any leading space to sync to the start bit */ + if (ir_input->last_bit == 0 && level == 0) + return; + + /* + * With valid RC-5 we can get up to two consecutive half-bits in a + * single pulse measurment. Experiments have shown that the duration + * of a half-bit can vary. Make sure we always end up with an even + * number of quarter bits at the same level (mark or space). + */ + ns_pulse &= V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS; + quarterbits = ns_pulse / rc5_quarterbit_ns; + if (quarterbits & 1) + quarterbits++; + halfbits = quarterbits / 2; + + for (i = 0; i < halfbits; i++) { + ir_input->last_bit++; + ir_input->code |= (level << ir_input->last_bit); + + if (ir_input->last_bit >= RC5_HALF_BITS-1) { + ir_input->active = 0; + cx23885_input_process_raw_rc5(dev); + /* + * If level is 1, a leading mark is invalid for RC5. + * If level is 0, we scan past extra intial space. + * Either way we don't want to reactivate collecting + * marks or spaces here with any left over half-bits. + */ + break; + } + } +} + +static void cx23885_input_process_pulse_widths_rc5(struct cx23885_dev *dev, + bool add_eom) +{ + struct card_ir *ir_input = dev->ir_input; + struct ir_input_state *ir_input_state = &ir_input->ir; + + u32 ns_pulse[RC5_HALF_BITS+1]; + ssize_t num = 0; + int count, i; + + do { + v4l2_subdev_call(dev->sd_ir, ir, rx_read, (u8 *) ns_pulse, + sizeof(ns_pulse), &num); + + count = num / sizeof(u32); + + /* Append an end of Rx seq, if the caller requested */ + if (add_eom && count < ARRAY_SIZE(ns_pulse)) { + ns_pulse[count] = V4L2_SUBDEV_IR_PULSE_RX_SEQ_END; + count++; + } + + /* Just drain the Rx FIFO, if we're called, but not RC-5 */ + if (ir_input_state->ir_type != IR_TYPE_RC5) + continue; + + for (i = 0; i < count; i++) + cx23885_input_next_pulse_width_rc5(dev, ns_pulse[i]); + } while (num != 0); +} + +void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events) +{ + struct v4l2_subdev_ir_parameters params; + int overrun, data_available; + + if (dev->sd_ir == NULL || events == 0) + return; + + switch (dev->board) { + case CX23885_BOARD_HAUPPAUGE_HVR1850: + /* + * The only board we handle right now. However other boards + * using the CX2388x integrated IR controller should be similar + */ + break; + default: + return; + } + + overrun = events & (V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN | + V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN); + + data_available = events & (V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED | + V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ); + + if (overrun) { + /* If there was a FIFO overrun, stop the device */ + v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, ¶ms); + params.enable = false; + /* Mitigate race with cx23885_input_ir_stop() */ + params.shutdown = atomic_read(&dev->ir_input_stopping); + v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, ¶ms); + } + + if (data_available) + cx23885_input_process_pulse_widths_rc5(dev, overrun); + + if (overrun) { + /* If there was a FIFO overrun, clear & restart the device */ + params.enable = true; + /* Mitigate race with cx23885_input_ir_stop() */ + params.shutdown = atomic_read(&dev->ir_input_stopping); + v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, ¶ms); + } +} + +static void cx23885_input_ir_start(struct cx23885_dev *dev) +{ + struct card_ir *ir_input = dev->ir_input; + struct ir_input_state *ir_input_state = &ir_input->ir; + struct v4l2_subdev_ir_parameters params; + + if (dev->sd_ir == NULL) + return; + + atomic_set(&dev->ir_input_stopping, 0); + + /* keyup timer set up, if needed */ + switch (dev->board) { + case CX23885_BOARD_HAUPPAUGE_HVR1850: + setup_timer(&ir_input->timer_keyup, + ir_rc5_timer_keyup, /* Not actually RC-5 specific */ + (unsigned long) ir_input); + if (ir_input_state->ir_type == IR_TYPE_RC5) { + /* + * RC-5 repeats a held key every + * 64 bits * (2 * 32/36000) sec/bit = 113.778 ms + */ + ir_input->rc5_key_timeout = 115; + } + break; + } + + v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, ¶ms); + switch (dev->board) { + case CX23885_BOARD_HAUPPAUGE_HVR1850: + /* + * The IR controller on this board only returns pulse widths. + * Any other mode setting will fail to set up the device. + */ + params.mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH; + params.enable = true; + params.interrupt_enable = true; + params.shutdown = false; + + /* Setup for baseband compatible with both RC-5 and RC-6A */ + params.modulation = false; + /* RC-5: 2,222,222 ns = 1/36 kHz * 32 cycles * 2 marks * 1.25*/ + /* RC-6A: 3,333,333 ns = 1/36 kHz * 16 cycles * 6 marks * 1.25*/ + params.max_pulse_width = 3333333; /* ns */ + /* RC-5: 666,667 ns = 1/36 kHz * 32 cycles * 1 mark * 0.75 */ + /* RC-6A: 333,333 ns = 1/36 kHz * 16 cycles * 1 mark * 0.75 */ + params.noise_filter_min_width = 333333; /* ns */ + /* + * This board has inverted receive sense: + * mark is received as low logic level; + * falling edges are detected as rising edges; etc. + */ + params.invert = true; + break; + } + v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, ¶ms); +} + +static void cx23885_input_ir_stop(struct cx23885_dev *dev) +{ + struct card_ir *ir_input = dev->ir_input; + struct v4l2_subdev_ir_parameters params; + + if (dev->sd_ir == NULL) + return; + + /* + * Stop the sd_ir subdevice from generating notifications and + * scheduling work. + * It is shutdown this way in order to mitigate a race with + * cx23885_input_rx_work_handler() in the overrun case, which could + * re-enable the subdevice. + */ + atomic_set(&dev->ir_input_stopping, 1); + v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, ¶ms); + while (params.shutdown == false) { + params.enable = false; + params.interrupt_enable = false; + params.shutdown = true; + v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, ¶ms); + v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, ¶ms); + } + + flush_scheduled_work(); + + switch (dev->board) { + case CX23885_BOARD_HAUPPAUGE_HVR1850: + del_timer_sync(&ir_input->timer_keyup); + break; + } +} + +int cx23885_input_init(struct cx23885_dev *dev) +{ + struct card_ir *ir; + struct input_dev *input_dev; + struct ir_scancode_table *ir_codes = NULL; + int ir_type, ir_addr, ir_start; + int ret; + + /* + * If the IR device (hardware registers, chip, GPIO lines, etc.) isn't + * encapsulated in a v4l2_subdev, then I'm not going to deal with it. + */ + if (dev->sd_ir == NULL) + return -ENODEV; + + switch (dev->board) { + case CX23885_BOARD_HAUPPAUGE_HVR1850: + /* Parameters for the grey Hauppauge remote for the HVR-1850 */ + ir_codes = &ir_codes_hauppauge_new_table; + ir_type = IR_TYPE_RC5; + ir_addr = 0x1e; /* RC-5 system bits emitted by the remote */ + ir_start = RC5_START_BITS_NORMAL; /* A basic RC-5 remote */ + break; + } + if (ir_codes == NULL) + return -ENODEV; + + ir = kzalloc(sizeof(*ir), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!ir || !input_dev) { + ret = -ENOMEM; + goto err_out_free; + } + + ir->dev = input_dev; + ir->addr = ir_addr; + ir->start = ir_start; + + /* init input device */ + snprintf(ir->name, sizeof(ir->name), "cx23885 IR (%s)", + cx23885_boards[dev->board].name); + snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(dev->pci)); + + ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); + input_dev->name = ir->name; + input_dev->phys = ir->phys; + input_dev->id.bustype = BUS_PCI; + input_dev->id.version = 1; + if (dev->pci->subsystem_vendor) { + input_dev->id.vendor = dev->pci->subsystem_vendor; + input_dev->id.product = dev->pci->subsystem_device; + } else { + input_dev->id.vendor = dev->pci->vendor; + input_dev->id.product = dev->pci->device; + } + input_dev->dev.parent = &dev->pci->dev; + + dev->ir_input = ir; + cx23885_input_ir_start(dev); + + ret = input_register_device(ir->dev); + if (ret) + goto err_out_stop; + + return 0; + +err_out_stop: + cx23885_input_ir_stop(dev); + dev->ir_input = NULL; +err_out_free: + input_free_device(input_dev); + kfree(ir); + return ret; +} + +void cx23885_input_fini(struct cx23885_dev *dev) +{ + /* Always stop the IR hardware from generating interrupts */ + cx23885_input_ir_stop(dev); + + if (dev->ir_input == NULL) + return; + input_unregister_device(dev->ir_input->dev); + kfree(dev->ir_input); + dev->ir_input = NULL; +} diff --git a/drivers/media/video/cx23885/cx23885-input.h b/drivers/media/video/cx23885/cx23885-input.h new file mode 100644 index 00000000000..3572cb1ecfc --- /dev/null +++ b/drivers/media/video/cx23885/cx23885-input.h @@ -0,0 +1,30 @@ +/* + * Driver for the Conexant CX23885/7/8 PCIe bridge + * + * Infrared remote control input device + * + * Copyright (C) 2009 Andy Walls + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#ifndef _CX23885_INPUT_H_ +#define _CX23885_INPUT_H_ +int cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events); + +int cx23885_input_init(struct cx23885_dev *dev); +void cx23885_input_fini(struct cx23885_dev *dev); +#endif diff --git a/drivers/media/video/cx23885/cx23885-ir.c b/drivers/media/video/cx23885/cx23885-ir.c index e84f90c75bf..6ae982cc985 100644 --- a/drivers/media/video/cx23885/cx23885-ir.c +++ b/drivers/media/video/cx23885/cx23885-ir.c @@ -24,6 +24,7 @@ #include #include "cx23885.h" +#include "cx23885-input.h" #define CX23885_IR_RX_FIFO_SERVICE_REQ 0 #define CX23885_IR_RX_END_OF_RX_DETECTED 1 @@ -51,6 +52,9 @@ void cx23885_ir_rx_work_handler(struct work_struct *work) if (events == 0) return; + + if (dev->ir_input) + cx23885_input_rx_work_handler(dev, events); } void cx23885_ir_tx_work_handler(struct work_struct *work) diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index ce82698db5f..1e0e9354806 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h @@ -363,6 +363,9 @@ struct cx23885_dev { struct work_struct ir_tx_work; unsigned long ir_tx_notifications; + struct card_ir *ir_input; + atomic_t ir_input_stopping; + /* V4l */ u32 freq; struct video_device *video_dev; -- cgit v1.2.3-70-g09d2 From 9133aee09e3689c116c526fa9011c33b872e65c1 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 23 May 2009 18:00:59 -0300 Subject: V4L/DVB (13103): create a standard method for dvb adapter drivers to override frontend ioctls Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-core/dvb_frontend.c | 20 +++++++++++++++++++- drivers/media/dvb/dvb-core/dvbdev.h | 28 ++++++++++++++++++++++++++++ drivers/media/video/cx23885/cx23885-dvb.c | 2 +- drivers/media/video/cx88/cx88-dvb.c | 2 +- drivers/media/video/saa7134/saa7134-dvb.c | 2 +- drivers/media/video/videobuf-dvb.c | 11 ++++++++--- include/media/videobuf-dvb.h | 4 +++- 7 files changed, 61 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 98082416aa5..e9ec8e91105 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1712,7 +1712,18 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, struct dvb_device *dvbdev = file->private_data; struct dvb_frontend *fe = dvbdev->priv; struct dvb_frontend_private *fepriv = fe->frontend_priv; - int err = -EOPNOTSUPP; + int cb_err, err = -EOPNOTSUPP; + + if (fe->dvb->fe_ioctl_override) { + cb_err = fe->dvb->fe_ioctl_override(fe, cmd, parg, + DVB_FE_IOCTL_PRE); + if (cb_err < 0) + return cb_err; + if (cb_err > 0) + return 0; + /* fe_ioctl_override returning 0 allows + * dvb-core to continue handling the ioctl */ + } switch (cmd) { case FE_GET_INFO: { @@ -1978,6 +1989,13 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, break; }; + if (fe->dvb->fe_ioctl_override) { + cb_err = fe->dvb->fe_ioctl_override(fe, cmd, parg, + DVB_FE_IOCTL_POST); + if (cb_err < 0) + return cb_err; + } + return err; } diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h index 01fc7048474..f7b499d4a3c 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.h +++ b/drivers/media/dvb/dvb-core/dvbdev.h @@ -54,6 +54,8 @@ module_param_array(adapter_nr, short, NULL, 0444); \ MODULE_PARM_DESC(adapter_nr, "DVB adapter numbers") +struct dvb_frontend; + struct dvb_adapter { int num; struct list_head list_head; @@ -69,6 +71,32 @@ struct dvb_adapter { int mfe_shared; /* indicates mutually exclusive frontends */ struct dvb_device *mfe_dvbdev; /* frontend device in use */ struct mutex mfe_lock; /* access lock for thread creation */ + + /* Allow the adapter/bridge driver to perform an action before and/or + * after the core handles an ioctl: + * + * DVB_FE_IOCTL_PRE indicates that the ioctl has not yet been handled. + * DVB_FE_IOCTL_POST indicates that the ioctl has been handled. + * + * When DVB_FE_IOCTL_PRE is passed to the callback as the stage arg: + * + * return 0 to allow dvb-core to handle the ioctl. + * return a positive int to prevent dvb-core from handling the ioctl, + * and exit without error. + * return a negative int to prevent dvb-core from handling the ioctl, + * and return that value as an error. + * + * When DVB_FE_IOCTL_POST is passed to the callback as the stage arg: + * + * return 0 to allow the dvb_frontend ioctl handler to exit normally. + * return a negative int to cause the dvb_frontend ioctl handler to + * return that value as an error. + */ +#define DVB_FE_IOCTL_PRE 0 +#define DVB_FE_IOCTL_POST 1 + int (*fe_ioctl_override)(struct dvb_frontend *fe, + unsigned int cmd, void *parg, + unsigned int stage); }; diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 45e13ee66dc..0a03e02b119 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -904,7 +904,7 @@ static int dvb_register(struct cx23885_tsport *port) /* register everything */ ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, - &dev->pci->dev, adapter_nr, 0); + &dev->pci->dev, adapter_nr, 0, NULL); /* init CI & MAC */ switch (dev->board) { diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index 518bcfe18bc..d9e402b25b5 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c @@ -1174,7 +1174,7 @@ static int dvb_register(struct cx8802_dev *dev) /* register everything */ return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, - &dev->pci->dev, adapter_nr, mfe_shared); + &dev->pci->dev, adapter_nr, mfe_shared, NULL); frontend_detach: core->gate_ctrl = NULL; diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 058b56bf671..96d3668f469 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -1574,7 +1574,7 @@ static int dvb_init(struct saa7134_dev *dev) /* register everything else */ ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, - &dev->pci->dev, adapter_nr, 0); + &dev->pci->dev, adapter_nr, 0, NULL); /* this sequence is necessary to make the tda1004x load its firmware * and to enter analog mode of hybrid boards diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c index 0e7dcba8e4a..a56cf0d3a6d 100644 --- a/drivers/media/video/videobuf-dvb.c +++ b/drivers/media/video/videobuf-dvb.c @@ -139,7 +139,9 @@ static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe, struct device *device, char *adapter_name, short *adapter_nr, - int mfe_shared) + int mfe_shared, + int (*fe_ioctl_override)(struct dvb_frontend *, + unsigned int, void *, unsigned int)) { int result; @@ -154,6 +156,7 @@ static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe, } fe->adapter.priv = adapter_priv; fe->adapter.mfe_shared = mfe_shared; + fe->adapter.fe_ioctl_override = fe_ioctl_override; return result; } @@ -253,7 +256,9 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f, void *adapter_priv, struct device *device, short *adapter_nr, - int mfe_shared) + int mfe_shared, + int (*fe_ioctl_override)(struct dvb_frontend *, + unsigned int, void *, unsigned int)) { struct list_head *list, *q; struct videobuf_dvb_frontend *fe; @@ -267,7 +272,7 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f, /* Bring up the adapter */ res = videobuf_dvb_register_adapter(f, module, adapter_priv, device, - fe->dvb.name, adapter_nr, mfe_shared); + fe->dvb.name, adapter_nr, mfe_shared, fe_ioctl_override); if (res < 0) { printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res); return res; diff --git a/include/media/videobuf-dvb.h b/include/media/videobuf-dvb.h index 6ba4f1271d2..07cf4b9d0a6 100644 --- a/include/media/videobuf-dvb.h +++ b/include/media/videobuf-dvb.h @@ -42,7 +42,9 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f, void *adapter_priv, struct device *device, short *adapter_nr, - int mfe_shared); + int mfe_shared, + int (*fe_ioctl_override)(struct dvb_frontend *, + unsigned int, void *, unsigned int)); void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f); -- cgit v1.2.3-70-g09d2 From 5bdd39621eb139630683b52c8e71202a2cc08291 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Fri, 8 May 2009 22:39:24 -0300 Subject: V4L/DVB (13104): cx23885: define a dvb frontend ioctl override function override set_frontend to allow rf input path switching on the HVR1275 Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-dvb.c | 37 +++++++++++++++++++++++-------- drivers/media/video/cx23885/cx23885.h | 4 ---- 2 files changed, 28 insertions(+), 13 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 0a03e02b119..875597640d7 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -487,10 +487,34 @@ static int cx23885_dvb_set_frontend(struct dvb_frontend *fe, } break; } - return (port->set_frontend_save) ? - port->set_frontend_save(fe, param) : -ENODEV; + return 0; } +static int cx23885_dvb_fe_ioctl_override(struct dvb_frontend *fe, + unsigned int cmd, void *parg, + unsigned int stage) +{ + int err = 0; + + switch (stage) { + case DVB_FE_IOCTL_PRE: + + switch (cmd) { + case FE_SET_FRONTEND: + err = cx23885_dvb_set_frontend(fe, + (struct dvb_frontend_parameters *) parg); + break; + } + break; + + case DVB_FE_IOCTL_POST: + /* no post-ioctl handling required */ + break; + } + return err; +}; + + static struct lgs8gxx_config magicpro_prohdtve2_lgs8g75_config = { .prod = LGS8GXX_PROD_LGS8G75, .demod_address = 0x19, @@ -550,12 +574,6 @@ static int dvb_register(struct cx23885_tsport *port) 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_hvr127x_config); } - - /* FIXME: temporary hack */ - /* define bridge override to set_frontend */ - port->set_frontend_save = fe0->dvb.frontend->ops.set_frontend; - fe0->dvb.frontend->ops.set_frontend = cx23885_dvb_set_frontend; - break; case CX23885_BOARD_HAUPPAUGE_HVR1255: i2c_bus = &dev->i2c_bus[0]; @@ -904,7 +922,8 @@ static int dvb_register(struct cx23885_tsport *port) /* register everything */ ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, - &dev->pci->dev, adapter_nr, 0, NULL); + &dev->pci->dev, adapter_nr, 0, + cx23885_dvb_fe_ioctl_override); /* init CI & MAC */ switch (dev->board) { diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index 1e0e9354806..d2fbc6807ce 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h @@ -297,10 +297,6 @@ struct cx23885_tsport { /* Allow a single tsport to have multiple frontends */ u32 num_frontends; void *port_priv; - - /* FIXME: temporary hack */ - int (*set_frontend_save) (struct dvb_frontend *, - struct dvb_frontend_parameters *); }; struct cx23885_dev { -- cgit v1.2.3-70-g09d2 From 94d983143e981c389c3849d8baecb41b71c134b3 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 7 Sep 2009 13:32:29 -0300 Subject: V4L/DVB (13105): dvb-usb: add fe_ioctl_override callback to dvb_usb_adapter_properties Allow dvb-usb adapter drivers to specify a fe_ioctl_override callback to enable device-specific handling of DVB frontend operations. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dvb-usb-dvb.c | 1 + drivers/media/dvb/dvb-usb/dvb-usb.h | 3 +++ 2 files changed, 4 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c index 8a7d87bcd1d..df1ec3e69f4 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c @@ -88,6 +88,7 @@ int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums) goto err; } adap->dvb_adap.priv = adap; + adap->dvb_adap.fe_ioctl_override = adap->props.fe_ioctl_override; if (adap->dev->props.read_mac_address) { if (adap->dev->props.read_mac_address(adap->dev,adap->dvb_adap.proposed_mac) == 0) diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index fe2b87efb3f..0143aef19ec 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -162,6 +162,9 @@ struct dvb_usb_adapter_properties { struct usb_data_stream_properties stream; int size_of_priv; + + int (*fe_ioctl_override) (struct dvb_frontend *, + unsigned int, void *, unsigned int); }; /** -- cgit v1.2.3-70-g09d2 From b450b92e162a454b82fea6373c83e447e28ce4d6 Mon Sep 17 00:00:00 2001 From: Henk Vergonet Date: Sun, 27 Sep 2009 18:19:58 -0300 Subject: V4L/DVB (13108): tda8290: enable deemphasis_50 module parameter This adds a forgotten module_param macro needed to set a deemphasis of 50us. It is the standard setting for commercial FM radio broadcasts outside the US. Signed-off-by: Henk Vergonet Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda8290.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c index 064d14c8d7b..c190b0dedee 100644 --- a/drivers/media/common/tuners/tda8290.c +++ b/drivers/media/common/tuners/tda8290.c @@ -33,6 +33,7 @@ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable verbose debug messages"); static int deemphasis_50; +module_param(deemphasis_50, int, 0644); MODULE_PARM_DESC(deemphasis_50, "0 - 75us deemphasis; 1 - 50us deemphasis"); /* ---------------------------------------------------------------------- */ -- cgit v1.2.3-70-g09d2 From 3986bd116f3c53d695aef1781e14b6c5670d4cdd Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 27 Sep 2009 17:00:13 -0300 Subject: V4L/DVB (13110): tda18271: use temporary variables in tda18271_rf_tracking_filters_init Use temporary variables for signed calulations between unsigned values Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda18271-fe.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index 3a50ce96fcb..8b515a7d93f 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c @@ -572,6 +572,7 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq) struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state; unsigned char *regs = priv->tda18271_regs; int bcal, rf, i; + s32 divisor, dividend; #define RF1 0 #define RF2 1 #define RF3 2 @@ -614,15 +615,17 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq) map[i].rf1 = rf_freq[RF1] / 1000; break; case RF2: - map[i].rf_a1 = (prog_cal[RF2] - prog_tab[RF2] - - prog_cal[RF1] + prog_tab[RF1]) / - (s32)((rf_freq[RF2] - rf_freq[RF1]) / 1000); + dividend = (s32)(prog_cal[RF2] - prog_tab[RF2]) - + (s32)(prog_cal[RF1] + prog_tab[RF1]); + divisor = (s32)(rf_freq[RF2] - rf_freq[RF1]) / 1000; + map[i].rf_a1 = (dividend / divisor); map[i].rf2 = rf_freq[RF2] / 1000; break; case RF3: - map[i].rf_a2 = (prog_cal[RF3] - prog_tab[RF3] - - prog_cal[RF2] + prog_tab[RF2]) / - (s32)((rf_freq[RF3] - rf_freq[RF2]) / 1000); + dividend = (s32)(prog_cal[RF3] - prog_tab[RF3]) - + (s32)(prog_cal[RF2] + prog_tab[RF2]); + divisor = (s32)(rf_freq[RF3] - rf_freq[RF2]) / 1000; + map[i].rf_a2 = (dividend / divisor); map[i].rf_b2 = prog_cal[RF2] - prog_tab[RF2]; map[i].rf3 = rf_freq[RF3] / 1000; break; -- cgit v1.2.3-70-g09d2 From 3a6b49fef6cd18ce3de9de3db12bfbeacf39f9e9 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 27 Sep 2009 23:10:20 -0300 Subject: V4L/DVB (13111): tda18271: more signedness fixes Convert tda18271_rf_tracking_filter_cal.rf_[ab][12] from int to s32. Convert tda18271_priv.tm_rfcal from unsigned int to u8. Cast subtractions between u32 values as s32. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda18271-fe.c | 21 +++++++++++---------- drivers/media/common/tuners/tda18271-priv.h | 11 ++++++----- 2 files changed, 17 insertions(+), 15 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index 8b515a7d93f..e0fd9f5d594 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c @@ -256,8 +256,9 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe, struct tda18271_priv *priv = fe->tuner_priv; struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state; unsigned char *regs = priv->tda18271_regs; - int tm_current, rfcal_comp, approx, i, ret; - u8 dc_over_dt, rf_tab; + int i, ret; + u8 tm_current, dc_over_dt, rf_tab; + s32 rfcal_comp, approx; /* power up */ ret = tda18271_set_standby_mode(fe, 0, 0, 0); @@ -277,11 +278,11 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe, return i; if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) { - approx = map[i].rf_a1 * - (freq / 1000 - map[i].rf1) + map[i].rf_b1 + rf_tab; + approx = map[i].rf_a1 * (s32)(freq / 1000 - map[i].rf1) + + map[i].rf_b1 + rf_tab; } else { - approx = map[i].rf_a2 * - (freq / 1000 - map[i].rf2) + map[i].rf_b2 + rf_tab; + approx = map[i].rf_a2 * (s32)(freq / 1000 - map[i].rf2) + + map[i].rf_b2 + rf_tab; } if (approx < 0) @@ -292,9 +293,9 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe, tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt); /* calculate temperature compensation */ - rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal) / 1000; + rfcal_comp = dc_over_dt * (s32)(tm_current - priv->tm_rfcal) / 1000; - regs[R_EB14] = approx + rfcal_comp; + regs[R_EB14] = (unsigned char)(approx + rfcal_comp); ret = tda18271_write_regs(fe, R_EB14, 1); fail: return ret; @@ -611,7 +612,7 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq) switch (rf) { case RF1: map[i].rf_a1 = 0; - map[i].rf_b1 = prog_cal[RF1] - prog_tab[RF1]; + map[i].rf_b1 = (s32)(prog_cal[RF1] - prog_tab[RF1]); map[i].rf1 = rf_freq[RF1] / 1000; break; case RF2: @@ -626,7 +627,7 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq) (s32)(prog_cal[RF2] + prog_tab[RF2]); divisor = (s32)(rf_freq[RF3] - rf_freq[RF2]) / 1000; map[i].rf_a2 = (dividend / divisor); - map[i].rf_b2 = prog_cal[RF2] - prog_tab[RF2]; + map[i].rf_b2 = (s32)(prog_cal[RF2] - prog_tab[RF2]); map[i].rf3 = rf_freq[RF3] / 1000; break; default: diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h index 2bee229acd9..74075be4dea 100644 --- a/drivers/media/common/tuners/tda18271-priv.h +++ b/drivers/media/common/tuners/tda18271-priv.h @@ -80,10 +80,10 @@ struct tda18271_rf_tracking_filter_cal { u32 rf1; u32 rf2; u32 rf3; - int rf_a1; - int rf_b1; - int rf_a2; - int rf_b2; + s32 rf_a1; + s32 rf_b1; + s32 rf_a2; + s32 rf_b2; }; enum tda18271_pll { @@ -111,10 +111,11 @@ struct tda18271_priv { enum tda18271_output_options output_opt; unsigned int config; /* interface to saa713x / tda829x */ - unsigned int tm_rfcal; unsigned int cal_initialized:1; unsigned int small_i2c:1; + u8 tm_rfcal; + struct tda18271_map_layout *maps; struct tda18271_std_map std; struct tda18271_rf_tracking_filter_cal rf_cal_state[8]; -- cgit v1.2.3-70-g09d2 From c0faeee5a3b70c894a27fa81a0d98a3ab223aff0 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 28 Sep 2009 03:13:49 -0300 Subject: V4L/DVB (13112): tda18271: display some state information in debug output Display i2c adapter id, address and master / slave role in debug output. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda18271-maps.c | 1 + drivers/media/common/tuners/tda18271-priv.h | 34 +++++++++++++++++++---------- 2 files changed, 23 insertions(+), 12 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/tda18271-maps.c b/drivers/media/common/tuners/tda18271-maps.c index e21fdeff3dd..e7f84c705da 100644 --- a/drivers/media/common/tuners/tda18271-maps.c +++ b/drivers/media/common/tuners/tda18271-maps.c @@ -978,6 +978,7 @@ static struct tda18271_cid_target_map tda18271_cid_target[] = { int tda18271_lookup_cid_target(struct dvb_frontend *fe, u32 *freq, u8 *cid_target, u16 *count_limit) { + struct tda18271_priv *priv = fe->tuner_priv; int i = 0; while ((tda18271_cid_target[i].rfmax * 1000) < *freq) { diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h index 74075be4dea..7047680cdbd 100644 --- a/drivers/media/common/tuners/tda18271-priv.h +++ b/drivers/media/common/tuners/tda18271-priv.h @@ -136,27 +136,37 @@ extern int tda18271_debug; #define DBG_ADV 8 #define DBG_CAL 16 -#define tda_printk(kern, fmt, arg...) \ - printk(kern "%s: " fmt, __func__, ##arg) - -#define tda_dprintk(lvl, fmt, arg...) do {\ +#define tda_printk(st, kern, fmt, arg...) do {\ + if (st) { \ + struct tda18271_priv *state = st; \ + printk(kern "%s: [%d-%04x|%s] " fmt, __func__, \ + i2c_adapter_id(state->i2c_props.adap), \ + state->i2c_props.addr, \ + (state->role == TDA18271_MASTER) \ + ? "M" : "S", ##arg); \ + } else \ + printk(kern "%s: " fmt, __func__, ##arg); \ +} while (0) + +#define tda_dprintk(st, lvl, fmt, arg...) do {\ if (tda18271_debug & lvl) \ - tda_printk(KERN_DEBUG, fmt, ##arg); } while (0) + tda_printk(st, KERN_DEBUG, fmt, ##arg); } while (0) #define tda_info(fmt, arg...) printk(KERN_INFO fmt, ##arg) -#define tda_warn(fmt, arg...) tda_printk(KERN_WARNING, fmt, ##arg) -#define tda_err(fmt, arg...) tda_printk(KERN_ERR, fmt, ##arg) -#define tda_dbg(fmt, arg...) tda_dprintk(DBG_INFO, fmt, ##arg) -#define tda_map(fmt, arg...) tda_dprintk(DBG_MAP, fmt, ##arg) -#define tda_reg(fmt, arg...) tda_dprintk(DBG_REG, fmt, ##arg) -#define tda_cal(fmt, arg...) tda_dprintk(DBG_CAL, fmt, ##arg) +#define tda_warn(fmt, arg...) tda_printk(priv, KERN_WARNING, fmt, ##arg) +#define tda_err(fmt, arg...) tda_printk(priv, KERN_ERR, fmt, ##arg) +#define tda_dbg(fmt, arg...) tda_dprintk(priv, DBG_INFO, fmt, ##arg) +#define tda_map(fmt, arg...) tda_dprintk(priv, DBG_MAP, fmt, ##arg) +#define tda_reg(fmt, arg...) tda_dprintk(priv, DBG_REG, fmt, ##arg) +#define tda_cal(fmt, arg...) tda_dprintk(priv, DBG_CAL, fmt, ##arg) #define tda_fail(ret) \ ({ \ int __ret; \ __ret = (ret < 0); \ if (__ret) \ - tda_printk(KERN_ERR, "error %d on line %d\n", ret, __LINE__);\ + tda_printk(priv, KERN_ERR, \ + "error %d on line %d\n", ret, __LINE__); \ __ret; \ }) -- cgit v1.2.3-70-g09d2 From 1d76331ddbb43c04d4d62bf5b9cc93efc05149c7 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 18 Sep 2009 05:36:24 -0300 Subject: V4L/DVB (13114): gspca - zc3xx.c: Bad init sequences of sensor cs2102. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/zc3xx.c | 399 +++++++++++--------------------------- 1 file changed, 112 insertions(+), 287 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index cdf3357b4c9..e544630757c 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -420,9 +420,7 @@ static const struct usb_action adcm2700_NoFliker[] = { {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ {} }; -static const struct usb_action cs2102_Initial[] = { - {0xa1, 0x01, 0x0008}, - {0xa1, 0x01, 0x0008}, +static const struct usb_action cs2102_Initial[] = { /* 320x240 */ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, @@ -471,88 +469,10 @@ static const struct usb_action cs2102_Initial[] = { {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xa0, 0x68, ZC3XX_R18D_YTARGET}, {0xa0, 0x00, 0x01ad}, - {0xa1, 0x01, 0x0002}, - {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {0xa1, 0x01, 0x01c8}, - {0xa1, 0x01, 0x01c9}, - {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ - {0xa0, 0x24, ZC3XX_R120_GAMMA00}, /* gamma 5 */ - {0xa0, 0x44, ZC3XX_R121_GAMMA01}, - {0xa0, 0x64, ZC3XX_R122_GAMMA02}, - {0xa0, 0x84, ZC3XX_R123_GAMMA03}, - {0xa0, 0x9d, ZC3XX_R124_GAMMA04}, - {0xa0, 0xb2, ZC3XX_R125_GAMMA05}, - {0xa0, 0xc4, ZC3XX_R126_GAMMA06}, - {0xa0, 0xd3, ZC3XX_R127_GAMMA07}, - {0xa0, 0xe0, ZC3XX_R128_GAMMA08}, - {0xa0, 0xeb, ZC3XX_R129_GAMMA09}, - {0xa0, 0xf4, ZC3XX_R12A_GAMMA0A}, - {0xa0, 0xfb, ZC3XX_R12B_GAMMA0B}, - {0xa0, 0xff, ZC3XX_R12C_GAMMA0C}, - {0xa0, 0xff, ZC3XX_R12D_GAMMA0D}, - {0xa0, 0xff, ZC3XX_R12E_GAMMA0E}, - {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, - {0xa0, 0x18, ZC3XX_R130_GAMMA10}, - {0xa0, 0x20, ZC3XX_R131_GAMMA11}, - {0xa0, 0x20, ZC3XX_R132_GAMMA12}, - {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, - {0xa0, 0x16, ZC3XX_R134_GAMMA14}, - {0xa0, 0x13, ZC3XX_R135_GAMMA15}, - {0xa0, 0x10, ZC3XX_R136_GAMMA16}, - {0xa0, 0x0e, ZC3XX_R137_GAMMA17}, - {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, - {0xa0, 0x09, ZC3XX_R139_GAMMA19}, - {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, - {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, - {0xa0, 0x00, ZC3XX_R13C_GAMMA1C}, - {0xa0, 0x00, ZC3XX_R13D_GAMMA1D}, - {0xa0, 0x00, ZC3XX_R13E_GAMMA1E}, - {0xa0, 0x01, ZC3XX_R13F_GAMMA1F}, - {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xf4, ZC3XX_R10B_RGB01}, - {0xa0, 0xf4, ZC3XX_R10C_RGB02}, - {0xa0, 0xf4, ZC3XX_R10D_RGB10}, - {0xa0, 0x58, ZC3XX_R10E_RGB11}, - {0xa0, 0xf4, ZC3XX_R10F_RGB12}, - {0xa0, 0xf4, ZC3XX_R110_RGB20}, - {0xa0, 0xf4, ZC3XX_R111_RGB21}, - {0xa0, 0x58, ZC3XX_R112_RGB22}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x23, 0x0001}, - {0xaa, 0x24, 0x0055}, - {0xaa, 0x25, 0x00cc}, - {0xaa, 0x21, 0x003f}, - {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0xab, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x98, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x30, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0xd4, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x39, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x70, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xb0, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x40, ZC3XX_R116_RGAIN}, - {0xa0, 0x40, ZC3XX_R117_GGAIN}, - {0xa0, 0x40, ZC3XX_R118_BGAIN}, {} }; -static const struct usb_action cs2102_InitialScale[] = { - {0xa1, 0x01, 0x0008}, - {0xa1, 0x01, 0x0008}, +static const struct usb_action cs2102_InitialScale[] = { /* 640x480 */ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, @@ -601,57 +521,75 @@ static const struct usb_action cs2102_InitialScale[] = { {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xa0, 0x68, ZC3XX_R18D_YTARGET}, {0xa0, 0x00, 0x01ad}, - {0xa1, 0x01, 0x0002}, - {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {0xa1, 0x01, 0x01c8}, - {0xa1, 0x01, 0x01c9}, - {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ - {0xa0, 0x24, ZC3XX_R120_GAMMA00}, /* gamma 5 */ - {0xa0, 0x44, ZC3XX_R121_GAMMA01}, - {0xa0, 0x64, ZC3XX_R122_GAMMA02}, - {0xa0, 0x84, ZC3XX_R123_GAMMA03}, - {0xa0, 0x9d, ZC3XX_R124_GAMMA04}, - {0xa0, 0xb2, ZC3XX_R125_GAMMA05}, - {0xa0, 0xc4, ZC3XX_R126_GAMMA06}, - {0xa0, 0xd3, ZC3XX_R127_GAMMA07}, - {0xa0, 0xe0, ZC3XX_R128_GAMMA08}, - {0xa0, 0xeb, ZC3XX_R129_GAMMA09}, - {0xa0, 0xf4, ZC3XX_R12A_GAMMA0A}, - {0xa0, 0xfb, ZC3XX_R12B_GAMMA0B}, - {0xa0, 0xff, ZC3XX_R12C_GAMMA0C}, - {0xa0, 0xff, ZC3XX_R12D_GAMMA0D}, - {0xa0, 0xff, ZC3XX_R12E_GAMMA0E}, - {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, - {0xa0, 0x18, ZC3XX_R130_GAMMA10}, - {0xa0, 0x20, ZC3XX_R131_GAMMA11}, - {0xa0, 0x20, ZC3XX_R132_GAMMA12}, - {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, - {0xa0, 0x16, ZC3XX_R134_GAMMA14}, - {0xa0, 0x13, ZC3XX_R135_GAMMA15}, - {0xa0, 0x10, ZC3XX_R136_GAMMA16}, - {0xa0, 0x0e, ZC3XX_R137_GAMMA17}, - {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, - {0xa0, 0x09, ZC3XX_R139_GAMMA19}, - {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, - {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, - {0xa0, 0x00, ZC3XX_R13C_GAMMA1C}, - {0xa0, 0x00, ZC3XX_R13D_GAMMA1D}, - {0xa0, 0x00, ZC3XX_R13E_GAMMA1E}, - {0xa0, 0x01, ZC3XX_R13F_GAMMA1F}, - {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xf4, ZC3XX_R10B_RGB01}, - {0xa0, 0xf4, ZC3XX_R10C_RGB02}, - {0xa0, 0xf4, ZC3XX_R10D_RGB10}, - {0xa0, 0x58, ZC3XX_R10E_RGB11}, - {0xa0, 0xf4, ZC3XX_R10F_RGB12}, - {0xa0, 0xf4, ZC3XX_R110_RGB20}, - {0xa0, 0xf4, ZC3XX_R111_RGB21}, - {0xa0, 0x58, ZC3XX_R112_RGB22}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {} +}; +static const struct usb_action cs2102_50HZ[] = { + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xaa, 0x23, 0x0001}, + {0xaa, 0x24, 0x005f}, + {0xaa, 0x25, 0x0090}, + {0xaa, 0x21, 0x00dd}, + {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0xbf, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x3a, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x98, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0xdd, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0xe4, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, + {} +}; +static const struct usb_action cs2102_50HZScale[] = { + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xaa, 0x23, 0x0000}, + {0xaa, 0x24, 0x00af}, + {0xaa, 0x25, 0x00c8}, + {0xaa, 0x21, 0x0068}, + {0xa0, 0x01, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x5f, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x90, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x1d, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x4c, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x68, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0xe3, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, + {} +}; +static const struct usb_action cs2102_60HZ[] = { + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xaa, 0x23, 0x0001}, + {0xaa, 0x24, 0x0055}, + {0xaa, 0x25, 0x00cc}, + {0xaa, 0x21, 0x003f}, + {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0xab, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x98, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x30, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0xd4, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x39, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x70, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xb0, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, + {} +}; +static const struct usb_action cs2102_60HZScale[] = { {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, {0xaa, 0x23, 0x0000}, {0xaa, 0x24, 0x00aa}, @@ -671,162 +609,50 @@ static const struct usb_action cs2102_InitialScale[] = { {0xa0, 0xa5, ZC3XX_R01E_HSYNC_1}, {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2}, {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x40, ZC3XX_R116_RGAIN}, - {0xa0, 0x40, ZC3XX_R117_GGAIN}, - {0xa0, 0x40, ZC3XX_R118_BGAIN}, - {} -}; -static const struct usb_action cs2102_50HZ[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x0f, 0x008c}, /* 00,0f,8c,aa */ - {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ - {0xaa, 0x04, 0x00ac}, /* 00,04,ac,aa */ - {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ - {0xaa, 0x11, 0x00ac}, /* 00,11,ac,aa */ - {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ - {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ - {0xaa, 0x1d, 0x00ac}, /* 00,1d,ac,aa */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ - {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x42, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,42,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ - {0xa0, 0x8c, ZC3XX_R01D_HSYNC_0}, /* 00,1d,8c,cc */ - {0xa0, 0xb0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,b0,cc */ - {0xa0, 0xd0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,d0,cc */ - {} -}; -static const struct usb_action cs2102_50HZScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x0f, 0x0093}, /* 00,0f,93,aa */ - {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ - {0xaa, 0x04, 0x00a1}, /* 00,04,a1,aa */ - {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ - {0xaa, 0x11, 0x00a1}, /* 00,11,a1,aa */ - {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ - {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ - {0xaa, 0x1d, 0x00a1}, /* 00,1d,a1,aa */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ - {0xa0, 0xf7, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f7,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x83, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,83,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ - {0xa0, 0x93, ZC3XX_R01D_HSYNC_0}, /* 00,1d,93,cc */ - {0xa0, 0xb0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,b0,cc */ - {0xa0, 0xd0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,d0,cc */ - {} -}; -static const struct usb_action cs2102_60HZ[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x0f, 0x005d}, /* 00,0f,5d,aa */ - {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ - {0xaa, 0x04, 0x00aa}, /* 00,04,aa,aa */ - {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ - {0xaa, 0x11, 0x00aa}, /* 00,11,aa,aa */ - {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ - {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ - {0xaa, 0x1d, 0x00aa}, /* 00,1d,aa,aa */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ - {0xa0, 0xe4, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e4,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3a,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ - {0xa0, 0x5d, ZC3XX_R01D_HSYNC_0}, /* 00,1d,5d,cc */ - {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ - {0xa0, 0xd0, 0x00c8}, /* 00,c8,d0,cc */ - {} -}; -static const struct usb_action cs2102_60HZScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x0f, 0x00b7}, /* 00,0f,b7,aa */ - {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ - {0xaa, 0x04, 0x00be}, /* 00,04,be,aa */ - {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ - {0xaa, 0x11, 0x00be}, /* 00,11,be,aa */ - {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ - {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ - {0xaa, 0x1d, 0x00be}, /* 00,1d,be,aa */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ - {0xa0, 0xfc, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,fc,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x69, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,69,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ - {0xa0, 0xb7, ZC3XX_R01D_HSYNC_0}, /* 00,1d,b7,cc */ - {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ - {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */ {} }; static const struct usb_action cs2102_NoFliker[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */ - {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ - {0xaa, 0x04, 0x0080}, /* 00,04,80,aa */ - {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ - {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */ - {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ - {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ - {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ - {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ - {0xa0, 0x59, ZC3XX_R01D_HSYNC_0}, /* 00,1d,59,cc */ - {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ - {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xaa, 0x23, 0x0001}, + {0xaa, 0x24, 0x005f}, + {0xaa, 0x25, 0x0000}, + {0xaa, 0x21, 0x0001}, + {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0xbf, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x80, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x01, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xa0, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, {} }; static const struct usb_action cs2102_NoFlikerScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */ - {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ - {0xaa, 0x04, 0x0080}, /* 00,04,80,aa */ - {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ - {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */ - {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ - {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ - {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ - {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ - {0xa0, 0x59, ZC3XX_R01D_HSYNC_0}, /* 00,1d,59,cc */ - {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ - {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xaa, 0x23, 0x0000}, + {0xaa, 0x24, 0x00af}, + {0xaa, 0x25, 0x0080}, + {0xaa, 0x21, 0x0001}, + {0xa0, 0x01, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x5f, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x80, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x01, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xa0, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, {} }; @@ -6384,7 +6210,7 @@ static void setmatrix(struct gspca_dev *gspca_dev) {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b}; static const __u8 *matrix_tb[SENSOR_MAX] = { adcm2700_matrix, /* SENSOR_ADCM2700 0 */ - NULL, /* SENSOR_CS2102 1 */ + ov7620_matrix, /* SENSOR_CS2102 1 */ NULL, /* SENSOR_CS2102K 2 */ gc0305_matrix, /* SENSOR_GC0305 3 */ NULL, /* SENSOR_HDCS2020b 4 */ @@ -7025,7 +6851,7 @@ static int sd_config(struct gspca_dev *gspca_dev, int vga = 1; /* 1: vga, 0: sif */ static const __u8 gamma[SENSOR_MAX] = { 4, /* SENSOR_ADCM2700 0 */ - 5, /* SENSOR_CS2102 1 */ + 4, /* SENSOR_CS2102 1 */ 5, /* SENSOR_CS2102K 2 */ 4, /* SENSOR_GC0305 3 */ 4, /* SENSOR_HDCS2020b 4 */ @@ -7310,8 +7136,7 @@ static int sd_start(struct gspca_dev *gspca_dev) /* set the gamma tables when not set */ switch (sd->sensor) { - case SENSOR_CS2102: /* gamma set in xxx_Initial */ - case SENSOR_CS2102K: + case SENSOR_CS2102K: /* gamma set in xxx_Initial */ case SENSOR_HDCS2020b: case SENSOR_PB0330: /* pb with chip_revision - see above */ case SENSOR_OV7630C: -- cgit v1.2.3-70-g09d2 From 0d07e240c5da04db7c26dd4e337b3845be99d5f8 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 1 Oct 2009 13:44:49 -0300 Subject: V4L/DVB (13115): gspca - main: More information messages. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 23d3fb77691..179cbc14ee5 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -980,7 +980,7 @@ static void gspca_release(struct video_device *vfd) { struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev); - PDEBUG(D_STREAM, "device released"); + PDEBUG(D_PROBE, "/dev/video%d released", gspca_dev->vdev.num); kfree(gspca_dev->usb_buf); kfree(gspca_dev); @@ -991,7 +991,7 @@ static int dev_open(struct file *file) struct gspca_dev *gspca_dev; int ret; - PDEBUG(D_STREAM, "%s open", current->comm); + PDEBUG(D_STREAM, "[%s] open", current->comm); gspca_dev = (struct gspca_dev *) video_devdata(file); if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; @@ -1037,7 +1037,7 @@ static int dev_close(struct file *file) { struct gspca_dev *gspca_dev = file->private_data; - PDEBUG(D_STREAM, "%s close", current->comm); + PDEBUG(D_STREAM, "[%s] close", current->comm); if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; gspca_dev->users--; @@ -2001,11 +2001,15 @@ int gspca_dev_probe(struct usb_interface *intf, PDEBUG(D_PROBE, "probing %04x:%04x", id->idVendor, id->idProduct); /* we don't handle multi-config cameras */ - if (dev->descriptor.bNumConfigurations != 1) + if (dev->descriptor.bNumConfigurations != 1) { + PDEBUG(D_ERR, "Too many config"); return -ENODEV; + } interface = &intf->cur_altsetting->desc; - if (interface->bInterfaceNumber > 0) + if (interface->bInterfaceNumber > 0) { + PDEBUG(D_ERR, "intf != 0"); return -ENODEV; + } /* create the device */ if (dev_size < sizeof *gspca_dev) @@ -2059,7 +2063,7 @@ int gspca_dev_probe(struct usb_interface *intf, } usb_set_intfdata(intf, gspca_dev); - PDEBUG(D_PROBE, "probe ok"); + PDEBUG(D_PROBE, "/dev/video%d created", gspca_dev->vdev.num); return 0; out: kfree(gspca_dev->usb_buf); @@ -2078,6 +2082,7 @@ void gspca_disconnect(struct usb_interface *intf) { struct gspca_dev *gspca_dev = usb_get_intfdata(intf); + PDEBUG(D_PROBE, "/dev/video%d disconnect", gspca_dev->vdev.num); mutex_lock(&gspca_dev->usb_lock); gspca_dev->present = 0; @@ -2096,7 +2101,7 @@ void gspca_disconnect(struct usb_interface *intf) /* (this will call gspca_release() immediatly or on last close) */ video_unregister_device(&gspca_dev->vdev); - PDEBUG(D_PROBE, "disconnect complete"); +/* PDEBUG(D_PROBE, "disconnect complete"); */ } EXPORT_SYMBOL(gspca_disconnect); -- cgit v1.2.3-70-g09d2 From 518c8df77c21b7d1690dd8b96eb0e54c4ec1c9c1 Mon Sep 17 00:00:00 2001 From: Rafal Milecki Date: Fri, 2 Oct 2009 03:54:44 -0300 Subject: V4L/DVB (13116): gspca - ov519: Webcam 041e:4067 added. Signed-off-by: Rafal Milecki Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/gspca.txt | 1 + drivers/media/video/gspca/ov519.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt index 3f61825be49..90e85a8a881 100644 --- a/Documentation/video4linux/gspca.txt +++ b/Documentation/video4linux/gspca.txt @@ -37,6 +37,7 @@ ov519 041e:405f Creative Live! VISTA VF0330 ov519 041e:4060 Creative Live! VISTA VF0350 ov519 041e:4061 Creative Live! VISTA VF0400 ov519 041e:4064 Creative Live! VISTA VF0420 +ov519 041e:4067 Creative Live! Cam Video IM (VF0350) ov519 041e:4068 Creative Live! VISTA VF0470 spca561 0458:7004 Genius VideoCAM Express V2 sunplus 0458:7006 Genius Dsc 1.3 Smart diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index a5c190e9379..e1655781978 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -3364,6 +3364,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 }, {USB_DEVICE(0x041e, 0x4064), .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, + {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 }, {USB_DEVICE(0x041e, 0x4068), .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 }, -- cgit v1.2.3-70-g09d2 From ff75e99c62bcef8ccd6fb70151ad2b87aa52a165 Mon Sep 17 00:00:00 2001 From: Marton Nemeth Date: Sun, 4 Oct 2009 13:51:26 -0300 Subject: V4L/DVB (13117): gspca - pac7311: remove magic value for SKIP. Change the magic value 0xaa to SKIP for better understandability. Signed-off-by: Marton Nemeth Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac7311.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 052714484e8..f05bc800a7c 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -316,7 +316,8 @@ static const __u8 start_7302[] = { 0, 0 /* end of sequence */ }; -/* page 3 - the value 0xaa says skip the index - see reg_w_page() */ +#define SKIP 0xaa +/* page 3 - the value SKIP says skip the index - see reg_w_page() */ static const __u8 page3_7302[] = { 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16, 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, @@ -383,13 +384,13 @@ static const __u8 start_7311[] = { 0, 0 /* end of sequence */ }; -/* page 4 - the value 0xaa says skip the index - see reg_w_page() */ +/* page 4 - the value SKIP says skip the index - see reg_w_page() */ static const __u8 page4_7311[] = { - 0xaa, 0xaa, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f, - 0x09, 0x00, 0xaa, 0xaa, 0x07, 0x00, 0x00, 0x62, - 0x08, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, 0xaa, - 0xaa, 0x00, 0x08, 0xaa, 0x03, 0xaa, 0x00, 0x68, + SKIP, SKIP, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f, + 0x09, 0x00, SKIP, SKIP, 0x07, 0x00, 0x00, 0x62, + 0x08, SKIP, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, SKIP, + SKIP, 0x00, 0x08, SKIP, 0x03, SKIP, 0x00, 0x68, 0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00, 0x23, 0x28, 0x04, 0x11, 0x00, 0x00 }; @@ -438,7 +439,7 @@ static void reg_w_page(struct gspca_dev *gspca_dev, int index; for (index = 0; index < len; index++) { - if (page[index] == 0xaa) /* skip this index */ + if (page[index] == SKIP) /* skip this index */ continue; gspca_dev->usb_buf[0] = page[index]; usb_control_msg(gspca_dev->dev, -- cgit v1.2.3-70-g09d2 From 5a2e8d9fc15901d6ee4ec177b3845a84b6b960bd Mon Sep 17 00:00:00 2001 From: Marton Nemeth Date: Sun, 4 Oct 2009 13:53:22 -0300 Subject: V4L/DVB (13118): gspca - pac7311: remove magic values for END_OF_SEQUENCE and LOAD_PAGE. Change the magic values 0, 254 and 255 to END_OF_SEQUENCE, LOAD_PAGE4 and LOAD_PAGE3 respectively for better source code readability. Signed-off-by: Marton Nemeth Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac7311.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index f05bc800a7c..418d1a36beb 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -244,6 +244,10 @@ static const struct v4l2_pix_format vga_mode[] = { .priv = 0}, }; +#define LOAD_PAGE3 255 +#define LOAD_PAGE4 254 +#define END_OF_SEQUENCE 0 + /* pac 7302 */ static const __u8 init_7302[] = { /* index,value */ @@ -302,7 +306,7 @@ static const __u8 start_7302[] = { 0xff, 1, 0x02, /* page 2 */ 0x22, 1, 0x00, 0xff, 1, 0x03, /* page 3 */ - 0x00, 255, /* load the page 3 */ + 0, LOAD_PAGE3, /* load the page 3 */ 0x11, 1, 0x01, 0xff, 1, 0x02, /* page 2 */ 0x13, 1, 0x00, @@ -313,7 +317,7 @@ static const __u8 start_7302[] = { 0x6e, 1, 0x08, 0xff, 1, 0x01, /* page 1 */ 0x78, 1, 0x00, - 0, 0 /* end of sequence */ + 0, END_OF_SEQUENCE /* end of sequence */ }; #define SKIP 0xaa @@ -379,9 +383,9 @@ static const __u8 start_7311[] = { 0xf0, 13, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00, 0x3f, 0x00, 0x0a, 0x01, 0x00, 0xff, 1, 0x04, /* page 4 */ - 0x00, 254, /* load the page 4 */ + 0, LOAD_PAGE4, /* load the page 4 */ 0x11, 1, 0x01, - 0, 0 /* end of sequence */ + 0, END_OF_SEQUENCE /* end of sequence */ }; /* page 4 - the value SKIP says skip the index - see reg_w_page() */ @@ -461,12 +465,12 @@ static void reg_w_var(struct gspca_dev *gspca_dev, index = *seq++; len = *seq++; switch (len) { - case 0: + case END_OF_SEQUENCE: return; - case 254: + case LOAD_PAGE4: reg_w_page(gspca_dev, page4_7311, sizeof page4_7311); break; - case 255: + case LOAD_PAGE3: reg_w_page(gspca_dev, page3_7302, sizeof page3_7302); break; default: -- cgit v1.2.3-70-g09d2 From 24067bb552ae8be647372359d6a3ea6ce7de1525 Mon Sep 17 00:00:00 2001 From: Marton Nemeth Date: Sun, 4 Oct 2009 13:54:48 -0300 Subject: V4L/DVB (13119): gspca - pac7311: remove magic value for USB_BUF_SZ The length check in reg_w_var() function is because the buffer contents is copied to gspca_dev->usb_buf which has the size of USB_BUF_SZ bytes as defined in drivers/media/video/gspca/gspca.h. Replace the number with symbol for better readability and maintainability. Signed-off-by: Marton Nemeth Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac7311.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 418d1a36beb..26514285a84 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -474,7 +474,7 @@ static void reg_w_var(struct gspca_dev *gspca_dev, reg_w_page(gspca_dev, page3_7302, sizeof page3_7302); break; default: - if (len > 64) { + if (len > USB_BUF_SZ) { PDEBUG(D_ERR|D_STREAM, "Incorrect variable sequence"); return; -- cgit v1.2.3-70-g09d2 From 4fc8b64823ef0c42213a89af6c4c13066f210981 Mon Sep 17 00:00:00 2001 From: Marton Nemeth Date: Sun, 4 Oct 2009 13:56:50 -0300 Subject: V4L/DVB (13120): gspca - pac7311: remove redundant register page switching Remove redundant register page switching to page 0 when changing the color control. Signed-off-by: Marton Nemeth Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac7311.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 26514285a84..b21c5e155f4 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -579,7 +579,6 @@ static void setcolors(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ reg_w(gspca_dev, 0x11, 0x01); reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ - reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ for (i = 0; i < 9; i++) { v = a[i] * sd->colors / COLOR_MAX + b[i]; reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07); -- cgit v1.2.3-70-g09d2 From 56f6f5582f7f422f142035dd92b521e72ffdb348 Mon Sep 17 00:00:00 2001 From: Marton Nemeth Date: Sun, 4 Oct 2009 13:58:19 -0300 Subject: V4L/DVB (13121): gspca - pac7311: add comment about JPEG header Add comment about the meaning of the fixed JPEG header bytes used to create each image. Signed-off-by: Marton Nemeth Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac7311.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index b21c5e155f4..f954900c451 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -801,13 +801,32 @@ static void do_autogain(struct gspca_dev *gspca_dev) sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; } +/* JPEG header, part 1 */ static const unsigned char pac7311_jpeg_header1[] = { - 0xff, 0xd8, 0xff, 0xc0, 0x00, 0x11, 0x08 + 0xff, 0xd8, /* SOI: Start of Image */ + + 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */ + 0x00, 0x11, /* length = 17 bytes (including this length field) */ + 0x08 /* Precision: 8 */ + /* 2 bytes is placed here: number of image lines */ + /* 2 bytes is placed here: samples per line */ }; +/* JPEG header, continued */ static const unsigned char pac7311_jpeg_header2[] = { - 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, - 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00 + 0x03, /* Number of image components: 3 */ + 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */ + 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */ + 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */ + + 0xff, 0xda, /* SOS: Start Of Scan */ + 0x00, 0x0c, /* length = 12 bytes (including this length field) */ + 0x03, /* number of components: 3 */ + 0x01, 0x00, /* selector 1, table 0x00 */ + 0x02, 0x11, /* selector 2, table 0x11 */ + 0x03, 0x11, /* selector 3, table 0x11 */ + 0x00, 0x3f, /* Spectral selection: 0 .. 63 */ + 0x00 /* Successive approximation: 0 */ }; /* this function is run at interrupt level */ -- cgit v1.2.3-70-g09d2 From b1de7aeba1d7592b97507c21ea986ec6243a4165 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 5 Oct 2009 12:48:20 -0300 Subject: V4L/DVB (13127): sh_mobile_ceu: add soft reset function Signed-off-by: Kuninori Morimoto Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/sh_mobile_ceu_camera.c | 42 +++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 9c8b7c7b89e..edb6ec3d2bc 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -153,6 +153,40 @@ static u32 ceu_read(struct sh_mobile_ceu_dev *priv, unsigned long reg_offs) return ioread32(priv->base + reg_offs); } +static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev) +{ + int i, success = 0; + struct soc_camera_device *icd = pcdev->icd; + + ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ + + /* wait CSTSR.CPTON bit */ + for (i = 0; i < 1000; i++) { + if (!(ceu_read(pcdev, CSTSR) & 1)) { + success++; + break; + } + udelay(1); + } + + /* wait CAPSR.CPKIL bit */ + for (i = 0; i < 1000; i++) { + if (!(ceu_read(pcdev, CAPSR) & (1 << 16))) { + success++; + break; + } + udelay(1); + } + + + if (2 != success) { + dev_warn(&icd->dev, "soft reset time out\n"); + return -EIO; + } + + return 0; +} + /* * Videobuf operations */ @@ -407,13 +441,9 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) pm_runtime_get_sync(ici->v4l2_dev.dev); - ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ - while (ceu_read(pcdev, CSTSR) & 1) - msleep(1); - pcdev->icd = icd; - return 0; + return sh_mobile_ceu_soft_reset(pcdev); } /* Called with .video_lock held */ @@ -427,7 +457,7 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) /* disable capture, disable interrupts */ ceu_write(pcdev, CEIER, 0); - ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ + sh_mobile_ceu_soft_reset(pcdev); /* make sure active buffer is canceled */ spin_lock_irqsave(&pcdev->lock, flags); -- cgit v1.2.3-70-g09d2 From 5cf93f1dcaff4960bdfea22196963556778b22b3 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 5 Oct 2009 12:48:59 -0300 Subject: V4L/DVB (13128): sh_mobile_ceu_camera: add VBP error support If CEU driver can not receive data from camera, CETCR has VBP error state. Then, CEU is stopped and cure operation is needed. This patch add VBP error cure operation. Signed-off-by: Kuninori Morimoto Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/sh_mobile_ceu_camera.c | 41 ++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index edb6ec3d2bc..a4f3472d4db 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -236,26 +236,45 @@ static void free_buffer(struct videobuf_queue *vq, #define CEU_CETCR_MAGIC 0x0317f313 /* acknowledge magical interrupt sources */ #define CEU_CETCR_IGRW (1 << 4) /* prohibited register access interrupt bit */ #define CEU_CEIER_CPEIE (1 << 0) /* one-frame capture end interrupt */ +#define CEU_CEIER_VBP (1 << 20) /* vbp error */ #define CEU_CAPCR_CTNCP (1 << 16) /* continuous capture mode (if set) */ +#define CEU_CEIER_MASK (CEU_CEIER_CPEIE | CEU_CEIER_VBP) -static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) +/* + * return value doesn't reflex the success/failure to queue the new buffer, + * but rather the status of the previous buffer. + */ +static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) { struct soc_camera_device *icd = pcdev->icd; dma_addr_t phys_addr_top, phys_addr_bottom; + u32 status; + int ret = 0; /* The hardware is _very_ picky about this sequence. Especially * the CEU_CETCR_MAGIC value. It seems like we need to acknowledge * several not-so-well documented interrupt sources in CETCR. */ - ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_CPEIE); - ceu_write(pcdev, CETCR, ~ceu_read(pcdev, CETCR) & CEU_CETCR_MAGIC); - ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_CPEIE); + ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_MASK); + status = ceu_read(pcdev, CETCR); + ceu_write(pcdev, CETCR, ~status & CEU_CETCR_MAGIC); + ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_MASK); ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP); ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW); + /* + * When a VBP interrupt occurs, a capture end interrupt does not occur + * and the image of that frame is not captured correctly. So, soft reset + * is needed here. + */ + if (status & CEU_CEIER_VBP) { + sh_mobile_ceu_soft_reset(pcdev); + ret = -EIO; + } + if (!pcdev->active) - return; + return ret; phys_addr_top = videobuf_to_dma_contig(pcdev->active); ceu_write(pcdev, CDAYR, phys_addr_top); @@ -281,6 +300,8 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) pcdev->active->state = VIDEOBUF_ACTIVE; ceu_write(pcdev, CAPSR, 0x1); /* start capture */ + + return ret; } static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq, @@ -353,6 +374,11 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq, list_add_tail(&vb->queue, &pcdev->capture); if (!pcdev->active) { + /* + * Because there were no active buffer at this moment, + * we are not interested in the return value of + * sh_mobile_ceu_capture here. + */ pcdev->active = vb; sh_mobile_ceu_capture(pcdev); } @@ -413,9 +439,8 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data) else pcdev->active = NULL; - sh_mobile_ceu_capture(pcdev); - - vb->state = VIDEOBUF_DONE; + vb->state = (sh_mobile_ceu_capture(pcdev) < 0) ? + VIDEOBUF_ERROR : VIDEOBUF_DONE; do_gettimeofday(&vb->ts); vb->field_count++; wake_up(&vb->done); -- cgit v1.2.3-70-g09d2 From 8f37cf25badd0ba9de7cd05c3f1d5362607c1bf9 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 5 Oct 2009 12:54:04 -0300 Subject: V4L/DVB (13130): soc-camera: add a new driver for the RJ54N1CB0C camera sensor from Sharp This adds an soc-camera / v4l2-subdev driver for the RJ54N1CB0C CMOS camera sensor from Sharp. The sensor is very picky about initialisation and configuration sequences. The driver limits artificially maximum window size by 800x600, although the sensor supports 1600x1200. Sizes above 800x600 don't seem to work correctly, besides, examples from the system integrator use sizes above 640x480 only for still photography. Unfortunately, I had to use "magic" register-value pairs for undocumented and "reserved" registers. This version of the driver also omits some functionality, like cropping, which hasn't been sufficiently tested yet and will be added later. create mode 100644 drivers/media/video/rj54n1cb0c.c Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 6 + drivers/media/video/Makefile | 1 + drivers/media/video/rj54n1cb0c.c | 1219 ++++++++++++++++++++++++++++++++++++++ include/media/v4l2-chip-ident.h | 3 + 4 files changed, 1229 insertions(+) create mode 100644 drivers/media/video/rj54n1cb0c.c (limited to 'drivers/media') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index c318676f2d2..0ab7ccd8729 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -847,6 +847,12 @@ config SOC_CAMERA_MT9V022 help This driver supports MT9V022 cameras from Micron +config SOC_CAMERA_RJ54N1 + tristate "rj54n1cb0c support" + depends on SOC_CAMERA && I2C + help + This is a rj54n1cb0c video driver + config SOC_CAMERA_TW9910 tristate "tw9910 support" depends on SOC_CAMERA && I2C diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index e706ceecef8..7a2dcc34111 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -78,6 +78,7 @@ obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o +obj-$(CONFIG_SOC_CAMERA_RJ54N1) += rj54n1cb0c.o obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o # And now the v4l2 drivers: diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c new file mode 100644 index 00000000000..373f2a30a67 --- /dev/null +++ b/drivers/media/video/rj54n1cb0c.c @@ -0,0 +1,1219 @@ +/* + * Driver for RJ54N1CB0C CMOS Image Sensor from Micron + * + * Copyright (C) 2009, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#define RJ54N1_DEV_CODE 0x0400 +#define RJ54N1_DEV_CODE2 0x0401 +#define RJ54N1_OUT_SEL 0x0403 +#define RJ54N1_XY_OUTPUT_SIZE_S_H 0x0404 +#define RJ54N1_X_OUTPUT_SIZE_S_L 0x0405 +#define RJ54N1_Y_OUTPUT_SIZE_S_L 0x0406 +#define RJ54N1_XY_OUTPUT_SIZE_P_H 0x0407 +#define RJ54N1_X_OUTPUT_SIZE_P_L 0x0408 +#define RJ54N1_Y_OUTPUT_SIZE_P_L 0x0409 +#define RJ54N1_LINE_LENGTH_PCK_S_H 0x040a +#define RJ54N1_LINE_LENGTH_PCK_S_L 0x040b +#define RJ54N1_LINE_LENGTH_PCK_P_H 0x040c +#define RJ54N1_LINE_LENGTH_PCK_P_L 0x040d +#define RJ54N1_RESIZE_N 0x040e +#define RJ54N1_RESIZE_N_STEP 0x040f +#define RJ54N1_RESIZE_STEP 0x0410 +#define RJ54N1_RESIZE_HOLD_H 0x0411 +#define RJ54N1_RESIZE_HOLD_L 0x0412 +#define RJ54N1_H_OBEN_OFS 0x0413 +#define RJ54N1_V_OBEN_OFS 0x0414 +#define RJ54N1_RESIZE_CONTROL 0x0415 +#define RJ54N1_INC_USE_SEL_H 0x0425 +#define RJ54N1_INC_USE_SEL_L 0x0426 +#define RJ54N1_MIRROR_STILL_MODE 0x0427 +#define RJ54N1_INIT_START 0x0428 +#define RJ54N1_SCALE_1_2_LEV 0x0429 +#define RJ54N1_SCALE_4_LEV 0x042a +#define RJ54N1_Y_GAIN 0x04d8 +#define RJ54N1_APT_GAIN_UP 0x04fa +#define RJ54N1_RA_SEL_UL 0x0530 +#define RJ54N1_BYTE_SWAP 0x0531 +#define RJ54N1_OUT_SIGPO 0x053b +#define RJ54N1_FRAME_LENGTH_S_H 0x0595 +#define RJ54N1_FRAME_LENGTH_S_L 0x0596 +#define RJ54N1_FRAME_LENGTH_P_H 0x0597 +#define RJ54N1_FRAME_LENGTH_P_L 0x0598 +#define RJ54N1_IOC 0x05ef +#define RJ54N1_TG_BYPASS 0x0700 +#define RJ54N1_PLL_L 0x0701 +#define RJ54N1_PLL_N 0x0702 +#define RJ54N1_PLL_EN 0x0704 +#define RJ54N1_RATIO_TG 0x0706 +#define RJ54N1_RATIO_T 0x0707 +#define RJ54N1_RATIO_R 0x0708 +#define RJ54N1_RAMP_TGCLK_EN 0x0709 +#define RJ54N1_OCLK_DSP 0x0710 +#define RJ54N1_RATIO_OP 0x0711 +#define RJ54N1_RATIO_O 0x0712 +#define RJ54N1_OCLK_SEL_EN 0x0713 +#define RJ54N1_CLK_RST 0x0717 +#define RJ54N1_RESET_STANDBY 0x0718 + +#define E_EXCLK (1 << 7) +#define SOFT_STDBY (1 << 4) +#define SEN_RSTX (1 << 2) +#define TG_RSTX (1 << 1) +#define DSP_RSTX (1 << 0) + +#define RESIZE_HOLD_SEL (1 << 2) +#define RESIZE_GO (1 << 1) + +#define RJ54N1_COLUMN_SKIP 0 +#define RJ54N1_ROW_SKIP 0 +#define RJ54N1_MAX_WIDTH 1600 +#define RJ54N1_MAX_HEIGHT 1200 + +/* I2C addresses: 0x50, 0x51, 0x60, 0x61 */ + +static const struct soc_camera_data_format rj54n1_colour_formats[] = { + { + .name = "YUYV", + .depth = 16, + .fourcc = V4L2_PIX_FMT_YUYV, + .colorspace = V4L2_COLORSPACE_JPEG, + }, { + .name = "RGB565", + .depth = 16, + .fourcc = V4L2_PIX_FMT_RGB565, + .colorspace = V4L2_COLORSPACE_SRGB, + } +}; + +struct rj54n1_clock_div { + u8 ratio_tg; + u8 ratio_t; + u8 ratio_r; + u8 ratio_op; + u8 ratio_o; +}; + +struct rj54n1 { + struct v4l2_subdev subdev; + struct v4l2_rect rect; /* Sensor window */ + unsigned short width; /* Output window */ + unsigned short height; + unsigned short resize; /* Sensor * 1024 / resize = Output */ + struct rj54n1_clock_div clk_div; + u32 fourcc; + unsigned short scale; + u8 bank; +}; + +struct rj54n1_reg_val { + u16 reg; + u8 val; +}; + +const static struct rj54n1_reg_val bank_4[] = { + {0x417, 0}, + {0x42c, 0}, + {0x42d, 0xf0}, + {0x42e, 0}, + {0x42f, 0x50}, + {0x430, 0xf5}, + {0x431, 0x16}, + {0x432, 0x20}, + {0x433, 0}, + {0x434, 0xc8}, + {0x43c, 8}, + {0x43e, 0x90}, + {0x445, 0x83}, + {0x4ba, 0x58}, + {0x4bb, 4}, + {0x4bc, 0x20}, + {0x4db, 4}, + {0x4fe, 2}, +}; + +const static struct rj54n1_reg_val bank_5[] = { + {0x514, 0}, + {0x516, 0}, + {0x518, 0}, + {0x51a, 0}, + {0x51d, 0xff}, + {0x56f, 0x28}, + {0x575, 0x40}, + {0x5bc, 0x48}, + {0x5c1, 6}, + {0x5e5, 0x11}, + {0x5e6, 0x43}, + {0x5e7, 0x33}, + {0x5e8, 0x21}, + {0x5e9, 0x30}, + {0x5ea, 0x0}, + {0x5eb, 0xa5}, + {0x5ec, 0xff}, + {0x5fe, 2}, +}; + +const static struct rj54n1_reg_val bank_7[] = { + {0x70a, 0}, + {0x714, 0xff}, + {0x715, 0xff}, + {0x716, 0x1f}, + {0x7FE, 0x02}, +}; + +const static struct rj54n1_reg_val bank_8[] = { + {0x800, 0x00}, + {0x801, 0x01}, + {0x802, 0x61}, + {0x805, 0x00}, + {0x806, 0x00}, + {0x807, 0x00}, + {0x808, 0x00}, + {0x809, 0x01}, + {0x80A, 0x61}, + {0x80B, 0x00}, + {0x80C, 0x01}, + {0x80D, 0x00}, + {0x80E, 0x00}, + {0x80F, 0x00}, + {0x810, 0x00}, + {0x811, 0x01}, + {0x812, 0x61}, + {0x813, 0x00}, + {0x814, 0x11}, + {0x815, 0x00}, + {0x816, 0x41}, + {0x817, 0x00}, + {0x818, 0x51}, + {0x819, 0x01}, + {0x81A, 0x1F}, + {0x81B, 0x00}, + {0x81C, 0x01}, + {0x81D, 0x00}, + {0x81E, 0x11}, + {0x81F, 0x00}, + {0x820, 0x41}, + {0x821, 0x00}, + {0x822, 0x51}, + {0x823, 0x00}, + {0x824, 0x00}, + {0x825, 0x00}, + {0x826, 0x47}, + {0x827, 0x01}, + {0x828, 0x4F}, + {0x829, 0x00}, + {0x82A, 0x00}, + {0x82B, 0x00}, + {0x82C, 0x30}, + {0x82D, 0x00}, + {0x82E, 0x40}, + {0x82F, 0x00}, + {0x830, 0xB3}, + {0x831, 0x00}, + {0x832, 0xE3}, + {0x833, 0x00}, + {0x834, 0x00}, + {0x835, 0x00}, + {0x836, 0x00}, + {0x837, 0x00}, + {0x838, 0x00}, + {0x839, 0x01}, + {0x83A, 0x61}, + {0x83B, 0x00}, + {0x83C, 0x01}, + {0x83D, 0x00}, + {0x83E, 0x00}, + {0x83F, 0x00}, + {0x840, 0x00}, + {0x841, 0x01}, + {0x842, 0x61}, + {0x843, 0x00}, + {0x844, 0x1D}, + {0x845, 0x00}, + {0x846, 0x00}, + {0x847, 0x00}, + {0x848, 0x00}, + {0x849, 0x01}, + {0x84A, 0x1F}, + {0x84B, 0x00}, + {0x84C, 0x05}, + {0x84D, 0x00}, + {0x84E, 0x19}, + {0x84F, 0x01}, + {0x850, 0x21}, + {0x851, 0x01}, + {0x852, 0x5D}, + {0x853, 0x00}, + {0x854, 0x00}, + {0x855, 0x00}, + {0x856, 0x19}, + {0x857, 0x01}, + {0x858, 0x21}, + {0x859, 0x00}, + {0x85A, 0x00}, + {0x85B, 0x00}, + {0x85C, 0x00}, + {0x85D, 0x00}, + {0x85E, 0x00}, + {0x85F, 0x00}, + {0x860, 0xB3}, + {0x861, 0x00}, + {0x862, 0xE3}, + {0x863, 0x00}, + {0x864, 0x00}, + {0x865, 0x00}, + {0x866, 0x00}, + {0x867, 0x00}, + {0x868, 0x00}, + {0x869, 0xE2}, + {0x86A, 0x00}, + {0x86B, 0x01}, + {0x86C, 0x06}, + {0x86D, 0x00}, + {0x86E, 0x00}, + {0x86F, 0x00}, + {0x870, 0x60}, + {0x871, 0x8C}, + {0x872, 0x10}, + {0x873, 0x00}, + {0x874, 0xE0}, + {0x875, 0x00}, + {0x876, 0x27}, + {0x877, 0x01}, + {0x878, 0x00}, + {0x879, 0x00}, + {0x87A, 0x00}, + {0x87B, 0x03}, + {0x87C, 0x00}, + {0x87D, 0x00}, + {0x87E, 0x00}, + {0x87F, 0x00}, + {0x880, 0x00}, + {0x881, 0x00}, + {0x882, 0x00}, + {0x883, 0x00}, + {0x884, 0x00}, + {0x885, 0x00}, + {0x886, 0xF8}, + {0x887, 0x00}, + {0x888, 0x03}, + {0x889, 0x00}, + {0x88A, 0x64}, + {0x88B, 0x00}, + {0x88C, 0x03}, + {0x88D, 0x00}, + {0x88E, 0xB1}, + {0x88F, 0x00}, + {0x890, 0x03}, + {0x891, 0x01}, + {0x892, 0x1D}, + {0x893, 0x00}, + {0x894, 0x03}, + {0x895, 0x01}, + {0x896, 0x4B}, + {0x897, 0x00}, + {0x898, 0xE5}, + {0x899, 0x00}, + {0x89A, 0x01}, + {0x89B, 0x00}, + {0x89C, 0x01}, + {0x89D, 0x04}, + {0x89E, 0xC8}, + {0x89F, 0x00}, + {0x8A0, 0x01}, + {0x8A1, 0x01}, + {0x8A2, 0x61}, + {0x8A3, 0x00}, + {0x8A4, 0x01}, + {0x8A5, 0x00}, + {0x8A6, 0x00}, + {0x8A7, 0x00}, + {0x8A8, 0x00}, + {0x8A9, 0x00}, + {0x8AA, 0x7F}, + {0x8AB, 0x03}, + {0x8AC, 0x00}, + {0x8AD, 0x00}, + {0x8AE, 0x00}, + {0x8AF, 0x00}, + {0x8B0, 0x00}, + {0x8B1, 0x00}, + {0x8B6, 0x00}, + {0x8B7, 0x01}, + {0x8B8, 0x00}, + {0x8B9, 0x00}, + {0x8BA, 0x02}, + {0x8BB, 0x00}, + {0x8BC, 0xFF}, + {0x8BD, 0x00}, + {0x8FE, 0x02}, +}; + +const static struct rj54n1_reg_val bank_10[] = { + {0x10bf, 0x69} +}; + +/* Clock dividers - these are default register values, divider = register + 1 */ +const static struct rj54n1_clock_div clk_div = { + .ratio_tg = 3 /* default: 5 */, + .ratio_t = 4 /* default: 1 */, + .ratio_r = 4 /* default: 0 */, + .ratio_op = 1 /* default: 5 */, + .ratio_o = 9 /* default: 0 */, +}; + +static struct rj54n1 *to_rj54n1(const struct i2c_client *client) +{ + return container_of(i2c_get_clientdata(client), struct rj54n1, subdev); +} + +static int reg_read(struct i2c_client *client, const u16 reg) +{ + struct rj54n1 *rj54n1 = to_rj54n1(client); + int ret; + + /* set bank */ + if (rj54n1->bank != reg >> 8) { + dev_dbg(&client->dev, "[0x%x] = 0x%x\n", 0xff, reg >> 8); + ret = i2c_smbus_write_byte_data(client, 0xff, reg >> 8); + if (ret < 0) + return ret; + rj54n1->bank = reg >> 8; + } + return i2c_smbus_read_byte_data(client, reg & 0xff); +} + +static int reg_write(struct i2c_client *client, const u16 reg, + const u8 data) +{ + struct rj54n1 *rj54n1 = to_rj54n1(client); + int ret; + + /* set bank */ + if (rj54n1->bank != reg >> 8) { + dev_dbg(&client->dev, "[0x%x] = 0x%x\n", 0xff, reg >> 8); + ret = i2c_smbus_write_byte_data(client, 0xff, reg >> 8); + if (ret < 0) + return ret; + rj54n1->bank = reg >> 8; + } + dev_dbg(&client->dev, "[0x%x] = 0x%x\n", reg & 0xff, data); + return i2c_smbus_write_byte_data(client, reg & 0xff, data); +} + +static int reg_set(struct i2c_client *client, const u16 reg, + const u8 data, const u8 mask) +{ + int ret; + + ret = reg_read(client, reg); + if (ret < 0) + return ret; + return reg_write(client, reg, (ret & ~mask) | (data & mask)); +} + +static int reg_write_multiple(struct i2c_client *client, + const struct rj54n1_reg_val *rv, const int n) +{ + int i, ret; + + for (i = 0; i < n; i++) { + ret = reg_write(client, rv->reg, rv->val); + if (ret < 0) + return ret; + rv++; + } + + return 0; +} + +static int rj54n1_s_stream(struct v4l2_subdev *sd, int enable) +{ + /* TODO: start / stop streaming */ + return 0; +} + +static int rj54n1_set_bus_param(struct soc_camera_device *icd, + unsigned long flags) +{ + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + struct i2c_client *client = sd->priv; + /* Figures 2.5-1 to 2.5-3 - default falling pixclk edge */ + + if (flags & SOCAM_PCLK_SAMPLE_RISING) + return reg_write(client, RJ54N1_OUT_SIGPO, 1 << 4); + else + return reg_write(client, RJ54N1_OUT_SIGPO, 0); +} + +static unsigned long rj54n1_query_bus_param(struct soc_camera_device *icd) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + const unsigned long flags = + SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING | + SOCAM_MASTER | SOCAM_DATAWIDTH_8 | + SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | + SOCAM_DATA_ACTIVE_HIGH; + + return soc_camera_apply_sensor_flags(icl, flags); +} + +static int rj54n1_set_rect(struct i2c_client *client, + u16 reg_x, u16 reg_y, u16 reg_xy, + u32 width, u32 height) +{ + int ret; + + ret = reg_write(client, reg_xy, + ((width >> 4) & 0x70) | + ((height >> 8) & 7)); + + if (!ret) + ret = reg_write(client, reg_x, width & 0xff); + if (!ret) + ret = reg_write(client, reg_y, height & 0xff); + + return ret; +} + +/* + * Some commands, specifically certain initialisation sequences, require + * a commit operation. + */ +static int rj54n1_commit(struct i2c_client *client) +{ + int ret = reg_write(client, RJ54N1_INIT_START, 1); + msleep(10); + if (!ret) + ret = reg_write(client, RJ54N1_INIT_START, 0); + return ret; +} + +static int rj54n1_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) +{ + struct i2c_client *client = sd->priv; + struct rj54n1 *rj54n1 = to_rj54n1(client); + + a->c = rj54n1->rect; + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + return 0; +} + +static int rj54n1_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) +{ + a->bounds.left = RJ54N1_COLUMN_SKIP; + a->bounds.top = RJ54N1_ROW_SKIP; + a->bounds.width = RJ54N1_MAX_WIDTH; + a->bounds.height = RJ54N1_MAX_HEIGHT; + a->defrect = a->bounds; + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + a->pixelaspect.numerator = 1; + a->pixelaspect.denominator = 1; + + return 0; +} + +static int rj54n1_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +{ + struct i2c_client *client = sd->priv; + struct rj54n1 *rj54n1 = to_rj54n1(client); + struct v4l2_pix_format *pix = &f->fmt.pix; + + pix->pixelformat = rj54n1->fourcc; + pix->field = V4L2_FIELD_NONE; + pix->width = rj54n1->width; + pix->height = rj54n1->height; + + return 0; +} + +/* + * The actual geometry configuration routine. It scales the input window into + * the output one, updates the window sizes and returns an error or the resize + * coefficient on success. Note: we only use the "Fixed Scaling" on this camera. + */ +static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h, + u32 *out_w, u32 *out_h) +{ + struct i2c_client *client = sd->priv; + unsigned int skip, resize, input_w = *in_w, input_h = *in_h, + output_w = *out_w, output_h = *out_h; + u16 inc_sel; + int ret; + + ret = rj54n1_set_rect(client, RJ54N1_X_OUTPUT_SIZE_S_L, + RJ54N1_Y_OUTPUT_SIZE_S_L, + RJ54N1_XY_OUTPUT_SIZE_S_H, output_w, output_h); + if (!ret) + ret = rj54n1_set_rect(client, RJ54N1_X_OUTPUT_SIZE_P_L, + RJ54N1_Y_OUTPUT_SIZE_P_L, + RJ54N1_XY_OUTPUT_SIZE_P_H, output_w, output_h); + + if (ret < 0) + return ret; + + if (output_w > input_w || output_h > input_h) { + input_w = output_w; + input_h = output_h; + + resize = 1024; + } else { + unsigned int resize_x, resize_y; + resize_x = input_w * 1024 / output_w; + resize_y = input_h * 1024 / output_h; + + resize = min(resize_x, resize_y); + + /* Prohibited value ranges */ + switch (resize) { + case 2040 ... 2047: + resize = 2039; + break; + case 4080 ... 4095: + resize = 4079; + break; + case 8160 ... 8191: + resize = 8159; + break; + case 16320 ... 16383: + resize = 16319; + } + + input_w = output_w * resize / 1024; + input_h = output_h * resize / 1024; + } + + /* Set scaling */ + ret = reg_write(client, RJ54N1_RESIZE_HOLD_L, resize & 0xff); + if (!ret) + ret = reg_write(client, RJ54N1_RESIZE_HOLD_H, resize >> 8); + + if (ret < 0) + return ret; + + /* + * Configure a skipping bitmask. The sensor will select a skipping value + * among set bits automatically. + */ + skip = min(resize / 1024, (unsigned)15); + inc_sel = 1 << skip; + + if (inc_sel <= 2) + inc_sel = 0xc; + else if (resize & 1023 && skip < 15) + inc_sel |= 1 << (skip + 1); + + ret = reg_write(client, RJ54N1_INC_USE_SEL_L, inc_sel & 0xfc); + if (!ret) + ret = reg_write(client, RJ54N1_INC_USE_SEL_H, inc_sel >> 8); + + /* Start resizing */ + if (!ret) + ret = reg_write(client, RJ54N1_RESIZE_CONTROL, + RESIZE_HOLD_SEL | RESIZE_GO | 1); + + if (ret < 0) + return ret; + + dev_dbg(&client->dev, "resize %u, skip %u\n", resize, skip); + + /* Constant taken from manufacturer's example */ + msleep(230); + + ret = reg_write(client, RJ54N1_RESIZE_CONTROL, RESIZE_HOLD_SEL | 1); + if (ret < 0) + return ret; + + *in_w = input_w; + *in_h = input_h; + *out_w = output_w; + *out_h = output_h; + + return resize; +} + +static int rj54n1_set_clock(struct i2c_client *client) +{ + struct rj54n1 *rj54n1 = to_rj54n1(client); + int ret; + + /* Enable external clock */ + ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK | SOFT_STDBY); + /* Leave stand-by */ + if (!ret) + ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK); + + if (!ret) + ret = reg_write(client, RJ54N1_PLL_L, 2); + if (!ret) + ret = reg_write(client, RJ54N1_PLL_N, 0x31); + + /* TGCLK dividers */ + if (!ret) + ret = reg_write(client, RJ54N1_RATIO_TG, + rj54n1->clk_div.ratio_tg); + if (!ret) + ret = reg_write(client, RJ54N1_RATIO_T, + rj54n1->clk_div.ratio_t); + if (!ret) + ret = reg_write(client, RJ54N1_RATIO_R, + rj54n1->clk_div.ratio_r); + + /* Enable TGCLK & RAMP */ + if (!ret) + ret = reg_write(client, RJ54N1_RAMP_TGCLK_EN, 3); + + /* Disable clock output */ + if (!ret) + ret = reg_write(client, RJ54N1_OCLK_DSP, 0); + + /* Set divisors */ + if (!ret) + ret = reg_write(client, RJ54N1_RATIO_OP, + rj54n1->clk_div.ratio_op); + if (!ret) + ret = reg_write(client, RJ54N1_RATIO_O, + rj54n1->clk_div.ratio_o); + + /* Enable OCLK */ + if (!ret) + ret = reg_write(client, RJ54N1_OCLK_SEL_EN, 1); + + /* Use PLL for Timing Generator, write 2 to reserved bits */ + if (!ret) + ret = reg_write(client, RJ54N1_TG_BYPASS, 2); + + /* Take sensor out of reset */ + if (!ret) + ret = reg_write(client, RJ54N1_RESET_STANDBY, + E_EXCLK | SEN_RSTX); + /* Enable PLL */ + if (!ret) + ret = reg_write(client, RJ54N1_PLL_EN, 1); + + /* Wait for PLL to stabilise */ + msleep(10); + + /* Enable clock to frequency divider */ + if (!ret) + ret = reg_write(client, RJ54N1_CLK_RST, 1); + + if (!ret) + ret = reg_read(client, RJ54N1_CLK_RST); + if (ret != 1) { + dev_err(&client->dev, + "Resetting RJ54N1CB0C clock failed: %d!\n", ret); + return -EIO; + } + /* Start the PLL */ + ret = reg_set(client, RJ54N1_OCLK_DSP, 1, 1); + + /* Enable OCLK */ + if (!ret) + ret = reg_write(client, RJ54N1_OCLK_SEL_EN, 1); + + return ret; +} + +static int rj54n1_reg_init(struct i2c_client *client) +{ + int ret = rj54n1_set_clock(client); + + if (!ret) + ret = reg_write_multiple(client, bank_7, ARRAY_SIZE(bank_7)); + if (!ret) + ret = reg_write_multiple(client, bank_10, ARRAY_SIZE(bank_10)); + + /* Set binning divisors */ + if (!ret) + ret = reg_write(client, RJ54N1_SCALE_1_2_LEV, 3 | (7 << 4)); + if (!ret) + ret = reg_write(client, RJ54N1_SCALE_4_LEV, 0xf); + + /* Switch to fixed resize mode */ + if (!ret) + ret = reg_write(client, RJ54N1_RESIZE_CONTROL, + RESIZE_HOLD_SEL | 1); + + /* Set gain */ + if (!ret) + ret = reg_write(client, RJ54N1_Y_GAIN, 0x84); + + /* Mirror the image back: default is upside down and left-to-right... */ + if (!ret) + ret = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 3, 3); + + if (!ret) + ret = reg_write_multiple(client, bank_4, ARRAY_SIZE(bank_4)); + if (!ret) + ret = reg_write_multiple(client, bank_5, ARRAY_SIZE(bank_5)); + if (!ret) + ret = reg_write_multiple(client, bank_8, ARRAY_SIZE(bank_8)); + + if (!ret) + ret = reg_write(client, RJ54N1_RESET_STANDBY, + E_EXCLK | DSP_RSTX | SEN_RSTX); + + /* Commit init */ + if (!ret) + ret = rj54n1_commit(client); + + /* Take DSP, TG, sensor out of reset */ + if (!ret) + ret = reg_write(client, RJ54N1_RESET_STANDBY, + E_EXCLK | DSP_RSTX | TG_RSTX | SEN_RSTX); + + if (!ret) + ret = reg_write(client, 0x7fe, 2); + + /* Constant taken from manufacturer's example */ + msleep(700); + + return ret; +} + +/* FIXME: streaming output only up to 800x600 is functional */ +static int rj54n1_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +{ + struct v4l2_pix_format *pix = &f->fmt.pix; + + pix->field = V4L2_FIELD_NONE; + + if (pix->width > 800) + pix->width = 800; + if (pix->height > 600) + pix->height = 600; + + return 0; +} + +static int rj54n1_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +{ + struct i2c_client *client = sd->priv; + struct rj54n1 *rj54n1 = to_rj54n1(client); + struct v4l2_pix_format *pix = &f->fmt.pix; + unsigned int output_w, output_h, + input_w = rj54n1->rect.width, input_h = rj54n1->rect.height; + int ret; + + /* + * The host driver can call us without .try_fmt(), so, we have to take + * care ourseleves + */ + ret = rj54n1_try_fmt(sd, f); + + /* + * Verify if the sensor has just been powered on. TODO: replace this + * with proper PM, when a suitable API is available. + */ + if (!ret) + ret = reg_read(client, RJ54N1_RESET_STANDBY); + if (ret < 0) + return ret; + + if (!(ret & E_EXCLK)) { + ret = rj54n1_reg_init(client); + if (ret < 0) + return ret; + } + + /* RA_SEL_UL is only relevant for raw modes, ignored otherwise. */ + switch (pix->pixelformat) { + case V4L2_PIX_FMT_YUYV: + ret = reg_write(client, RJ54N1_OUT_SEL, 0); + if (!ret) + ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); + break; + case V4L2_PIX_FMT_RGB565: + ret = reg_write(client, RJ54N1_OUT_SEL, 0x11); + if (!ret) + ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); + break; + default: + ret = -EINVAL; + } + + if (ret < 0) + return ret; + + /* Supported scales 1:1 - 1:16 */ + if (pix->width < input_w / 16) + pix->width = input_w / 16; + if (pix->height < input_h / 16) + pix->height = input_h / 16; + + output_w = pix->width; + output_h = pix->height; + + ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h); + if (ret < 0) + return ret; + + rj54n1->fourcc = pix->pixelformat; + rj54n1->resize = ret; + rj54n1->rect.width = input_w; + rj54n1->rect.height = input_h; + rj54n1->width = output_w; + rj54n1->height = output_h; + + pix->width = output_w; + pix->height = output_h; + pix->field = V4L2_FIELD_NONE; + + return ret; +} + +static int rj54n1_g_chip_ident(struct v4l2_subdev *sd, + struct v4l2_dbg_chip_ident *id) +{ + struct i2c_client *client = sd->priv; + + if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) + return -EINVAL; + + if (id->match.addr != client->addr) + return -ENODEV; + + id->ident = V4L2_IDENT_RJ54N1CB0C; + id->revision = 0; + + return 0; +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int rj54n1_g_register(struct v4l2_subdev *sd, + struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = sd->priv; + + if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || + reg->reg < 0x400 || reg->reg > 0x1fff) + /* Registers > 0x0800 are only available from Sharp support */ + return -EINVAL; + + if (reg->match.addr != client->addr) + return -ENODEV; + + reg->size = 1; + reg->val = reg_read(client, reg->reg); + + if (reg->val > 0xff) + return -EIO; + + return 0; +} + +static int rj54n1_s_register(struct v4l2_subdev *sd, + struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = sd->priv; + + if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || + reg->reg < 0x400 || reg->reg > 0x1fff) + /* Registers >= 0x0800 are only available from Sharp support */ + return -EINVAL; + + if (reg->match.addr != client->addr) + return -ENODEV; + + if (reg_write(client, reg->reg, reg->val) < 0) + return -EIO; + + return 0; +} +#endif + +static const struct v4l2_queryctrl rj54n1_controls[] = { + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Vertically", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Horizontally", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gain", + .minimum = 0, + .maximum = 127, + .step = 1, + .default_value = 66, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, +}; + +static struct soc_camera_ops rj54n1_ops = { + .set_bus_param = rj54n1_set_bus_param, + .query_bus_param = rj54n1_query_bus_param, + .controls = rj54n1_controls, + .num_controls = ARRAY_SIZE(rj54n1_controls), +}; + +static int rj54n1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = sd->priv; + int data; + + switch (ctrl->id) { + case V4L2_CID_VFLIP: + data = reg_read(client, RJ54N1_MIRROR_STILL_MODE); + if (data < 0) + return -EIO; + ctrl->value = !(data & 1); + break; + case V4L2_CID_HFLIP: + data = reg_read(client, RJ54N1_MIRROR_STILL_MODE); + if (data < 0) + return -EIO; + ctrl->value = !(data & 2); + break; + case V4L2_CID_GAIN: + data = reg_read(client, RJ54N1_Y_GAIN); + if (data < 0) + return -EIO; + + ctrl->value = data / 2; + break; + } + + return 0; +} + +static int rj54n1_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + int data; + struct i2c_client *client = sd->priv; + const struct v4l2_queryctrl *qctrl; + + qctrl = soc_camera_find_qctrl(&rj54n1_ops, ctrl->id); + if (!qctrl) + return -EINVAL; + + switch (ctrl->id) { + case V4L2_CID_VFLIP: + if (ctrl->value) + data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 1); + else + data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 1, 1); + if (data < 0) + return -EIO; + break; + case V4L2_CID_HFLIP: + if (ctrl->value) + data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 2); + else + data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 2, 2); + if (data < 0) + return -EIO; + break; + case V4L2_CID_GAIN: + if (ctrl->value > qctrl->maximum || + ctrl->value < qctrl->minimum) + return -EINVAL; + else if (reg_write(client, RJ54N1_Y_GAIN, ctrl->value * 2) < 0) + return -EIO; + break; + } + + return 0; +} + +static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = { + .g_ctrl = rj54n1_g_ctrl, + .s_ctrl = rj54n1_s_ctrl, + .g_chip_ident = rj54n1_g_chip_ident, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .g_register = rj54n1_g_register, + .s_register = rj54n1_s_register, +#endif +}; + +static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = { + .s_stream = rj54n1_s_stream, + .s_fmt = rj54n1_s_fmt, + .g_fmt = rj54n1_g_fmt, + .try_fmt = rj54n1_try_fmt, + .g_crop = rj54n1_g_crop, + .cropcap = rj54n1_cropcap, +}; + +static struct v4l2_subdev_ops rj54n1_subdev_ops = { + .core = &rj54n1_subdev_core_ops, + .video = &rj54n1_subdev_video_ops, +}; + +static int rj54n1_pin_config(struct i2c_client *client) +{ + /* + * Experimentally found out IOCTRL wired to 0. TODO: add to platform + * data: 0 or 1 << 7. + */ + return reg_write(client, RJ54N1_IOC, 0); +} + +/* + * Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one + */ +static int rj54n1_video_probe(struct soc_camera_device *icd, + struct i2c_client *client) +{ + int data1, data2; + int ret; + + /* This could be a BUG_ON() or a WARN_ON(), or remove it completely */ + if (!icd->dev.parent || + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) + return -ENODEV; + + /* Read out the chip version register */ + data1 = reg_read(client, RJ54N1_DEV_CODE); + data2 = reg_read(client, RJ54N1_DEV_CODE2); + + if (data1 != 0x51 || data2 != 0x10) { + ret = -ENODEV; + dev_info(&client->dev, "No RJ54N1CB0C found, read 0x%x:0x%x\n", + data1, data2); + goto ei2c; + } + + ret = rj54n1_pin_config(client); + if (ret < 0) + goto ei2c; + + dev_info(&client->dev, "Detected a RJ54N1CB0C chip ID 0x%x:0x%x\n", + data1, data2); + +ei2c: + return ret; +} + +static int rj54n1_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct rj54n1 *rj54n1; + struct soc_camera_device *icd = client->dev.platform_data; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct soc_camera_link *icl; + int ret; + + if (!icd) { + dev_err(&client->dev, "RJ54N1CB0C: missing soc-camera data!\n"); + return -EINVAL; + } + + icl = to_soc_camera_link(icd); + if (!icl) { + dev_err(&client->dev, "RJ54N1CB0C: missing platform data!\n"); + return -EINVAL; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE\n"); + return -EIO; + } + + rj54n1 = kzalloc(sizeof(struct rj54n1), GFP_KERNEL); + if (!rj54n1) + return -ENOMEM; + + v4l2_i2c_subdev_init(&rj54n1->subdev, client, &rj54n1_subdev_ops); + + icd->ops = &rj54n1_ops; + + rj54n1->clk_div = clk_div; + rj54n1->rect.left = RJ54N1_COLUMN_SKIP; + rj54n1->rect.top = RJ54N1_ROW_SKIP; + rj54n1->rect.width = RJ54N1_MAX_WIDTH; + rj54n1->rect.height = RJ54N1_MAX_HEIGHT; + rj54n1->width = RJ54N1_MAX_WIDTH; + rj54n1->height = RJ54N1_MAX_HEIGHT; + rj54n1->fourcc = V4L2_PIX_FMT_YUYV; + rj54n1->resize = 1024; + + ret = rj54n1_video_probe(icd, client); + if (ret < 0) { + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + kfree(rj54n1); + return ret; + } + + icd->formats = rj54n1_colour_formats; + icd->num_formats = ARRAY_SIZE(rj54n1_colour_formats); + + return ret; +} + +static int rj54n1_remove(struct i2c_client *client) +{ + struct rj54n1 *rj54n1 = to_rj54n1(client); + struct soc_camera_device *icd = client->dev.platform_data; + struct soc_camera_link *icl = to_soc_camera_link(icd); + + icd->ops = NULL; + if (icl->free_bus) + icl->free_bus(icl); + i2c_set_clientdata(client, NULL); + client->driver = NULL; + kfree(rj54n1); + + return 0; +} + +static const struct i2c_device_id rj54n1_id[] = { + { "rj54n1cb0c", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, rj54n1_id); + +static struct i2c_driver rj54n1_i2c_driver = { + .driver = { + .name = "rj54n1cb0c", + }, + .probe = rj54n1_probe, + .remove = rj54n1_remove, + .id_table = rj54n1_id, +}; + +static int __init rj54n1_mod_init(void) +{ + return i2c_add_driver(&rj54n1_i2c_driver); +} + +static void __exit rj54n1_mod_exit(void) +{ + i2c_del_driver(&rj54n1_i2c_driver); +} + +module_init(rj54n1_mod_init); +module_exit(rj54n1_mod_exit); + +MODULE_DESCRIPTION("Sharp RJ54N1CB0C Camera driver"); +MODULE_AUTHOR("Guennadi Liakhovetski "); +MODULE_LICENSE("GPL v2"); diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index a2d93da3845..43cf26ea673 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h @@ -281,6 +281,9 @@ enum { /* module m52790: just ident 52790 */ V4L2_IDENT_M52790 = 52790, + + /* Sharp RJ54N1CB0C, 0xCB0C = 51980 */ + V4L2_IDENT_RJ54N1CB0C = 51980, }; #endif -- cgit v1.2.3-70-g09d2 From d8d8622552088ca94fab4e4997f948514d0bdc27 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Sat, 19 Sep 2009 09:51:12 -0300 Subject: V4L/DVB (13134): Add support for TBS-likes remotes The patch brings infrared remote support for some cx88 based cards. Such as: TeVii S460,S420; Omicom SS4; SatTrade ST4200; TBS 8920,8910; Prof 7300,6200. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-keymaps.c | 40 +++++++++++++++++++++++++++++++++++ drivers/media/video/cx88/cx88-input.c | 24 +++++++++++++++++++++ include/media/ir-common.h | 1 + 3 files changed, 65 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c index f6790172736..a2c80a7a3ae 100644 --- a/drivers/media/common/ir-keymaps.c +++ b/drivers/media/common/ir-keymaps.c @@ -2964,6 +2964,46 @@ struct ir_scancode_table ir_codes_dm1105_nec_table = { }; EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec_table); +static struct ir_scancode ir_codes_tbs_nec[] = { + { 0x04, KEY_POWER2}, /*power*/ + { 0x14, KEY_MUTE}, /*mute*/ + { 0x07, KEY_1}, + { 0x06, KEY_2}, + { 0x05, KEY_3}, + { 0x0b, KEY_4}, + { 0x0a, KEY_5}, + { 0x09, KEY_6}, + { 0x0f, KEY_7}, + { 0x0e, KEY_8}, + { 0x0d, KEY_9}, + { 0x12, KEY_0}, + { 0x16, KEY_CHANNELUP}, /*ch+*/ + { 0x11, KEY_CHANNELDOWN},/*ch-*/ + { 0x13, KEY_VOLUMEUP}, /*vol+*/ + { 0x0c, KEY_VOLUMEDOWN},/*vol-*/ + { 0x03, KEY_RECORD}, /*rec*/ + { 0x18, KEY_PAUSE}, /*pause*/ + { 0x19, KEY_OK}, /*ok*/ + { 0x1a, KEY_CAMERA}, /* snapshot */ + { 0x01, KEY_UP}, + { 0x10, KEY_LEFT}, + { 0x02, KEY_RIGHT}, + { 0x08, KEY_DOWN}, + { 0x15, KEY_FAVORITES}, + { 0x17, KEY_SUBTITLE}, + { 0x1d, KEY_ZOOM}, + { 0x1f, KEY_EXIT}, + { 0x1e, KEY_MENU}, + { 0x1c, KEY_EPG}, + { 0x00, KEY_PREVIOUS}, + { 0x1b, KEY_MODE}, +}; +struct ir_scancode_table ir_codes_tbs_nec_table = { + .scan = ir_codes_tbs_nec, + .size = ARRAY_SIZE(ir_codes_tbs_nec), +}; +EXPORT_SYMBOL_GPL(ir_codes_tbs_nec_table); + /* Terratec Cinergy Hybrid T USB XS Devin Heitmueller */ diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index 78b3635178a..33437e40314 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c @@ -303,6 +303,22 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) ir->mask_keydown = 0x02; ir->polling = 50; /* ms */ break; + case CX88_BOARD_OMICOM_SS4_PCI: + case CX88_BOARD_SATTRADE_ST4200: + case CX88_BOARD_TBS_8920: + case CX88_BOARD_TBS_8910: + case CX88_BOARD_PROF_7300: + case CX88_BOARD_PROF_6200: + ir_codes = &ir_codes_tbs_nec_table; + ir_type = IR_TYPE_PD; + ir->sampling = 0xff00; /* address */ + break; + case CX88_BOARD_TEVII_S460: + case CX88_BOARD_TEVII_S420: + ir_codes = &ir_codes_dm1105_nec_table; + ir_type = IR_TYPE_PD; + ir->sampling = 0xff00; /* address */ + break; case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: ir_codes = &ir_codes_dntv_live_dvbt_pro_table; ir_type = IR_TYPE_PD; @@ -432,8 +448,16 @@ void cx88_ir_irq(struct cx88_core *core) /* decode it */ switch (core->boardnr) { + case CX88_BOARD_TEVII_S460: + case CX88_BOARD_TEVII_S420: case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: + case CX88_BOARD_OMICOM_SS4_PCI: + case CX88_BOARD_SATTRADE_ST4200: + case CX88_BOARD_TBS_8920: + case CX88_BOARD_TBS_8910: + case CX88_BOARD_PROF_7300: + case CX88_BOARD_PROF_6200: ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4); if (ircode == 0xffffffff) { /* decoding error */ diff --git a/include/media/ir-common.h b/include/media/ir-common.h index af3257e6b80..c2d515dd94d 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -173,6 +173,7 @@ extern struct ir_scancode_table ir_codes_ati_tv_wonder_hd_600_table; extern struct ir_scancode_table ir_codes_kworld_plus_tv_analog_table; extern struct ir_scancode_table ir_codes_kaiomy_table; extern struct ir_scancode_table ir_codes_dm1105_nec_table; +extern struct ir_scancode_table ir_codes_tbs_nec_table; extern struct ir_scancode_table ir_codes_evga_indtube_table; extern struct ir_scancode_table ir_codes_terratec_cinergy_xs_table; extern struct ir_scancode_table ir_codes_videomate_s350_table; -- cgit v1.2.3-70-g09d2 From 9d2ba7ad802300d6a1830df9268d8ba478c66a18 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Wed, 23 Sep 2009 14:44:12 -0300 Subject: V4L/DVB (13135): Add support for TeVii remotes The patch brings infrared remote support for some cx88 based cards. Such as TeVii S460,S420. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-keymaps.c | 55 +++++++++++++++++++++++++++++++++++ drivers/media/video/cx88/cx88-input.c | 2 +- include/media/ir-common.h | 1 + 3 files changed, 57 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c index a2c80a7a3ae..32f765e6e5f 100644 --- a/drivers/media/common/ir-keymaps.c +++ b/drivers/media/common/ir-keymaps.c @@ -2964,6 +2964,61 @@ struct ir_scancode_table ir_codes_dm1105_nec_table = { }; EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec_table); +static struct ir_scancode ir_codes_tevii_nec[] = { + { 0x0a, KEY_POWER2}, + { 0x0c, KEY_MUTE}, + { 0x11, KEY_1}, + { 0x12, KEY_2}, + { 0x13, KEY_3}, + { 0x14, KEY_4}, + { 0x15, KEY_5}, + { 0x16, KEY_6}, + { 0x17, KEY_7}, + { 0x18, KEY_8}, + { 0x19, KEY_9}, + { 0x10, KEY_0}, + { 0x1c, KEY_MENU}, + { 0x0f, KEY_VOLUMEDOWN}, + { 0x1a, KEY_LAST}, + { 0x0e, KEY_OPEN}, + { 0x04, KEY_RECORD}, + { 0x09, KEY_VOLUMEUP}, + { 0x08, KEY_CHANNELUP}, + { 0x07, KEY_PVR}, + { 0x0b, KEY_TIME}, + { 0x02, KEY_RIGHT}, + { 0x03, KEY_LEFT}, + { 0x00, KEY_UP}, + { 0x1f, KEY_OK}, + { 0x01, KEY_DOWN}, + { 0x05, KEY_TUNER}, + { 0x06, KEY_CHANNELDOWN}, + { 0x40, KEY_PLAYPAUSE}, + { 0x1e, KEY_REWIND}, + { 0x1b, KEY_FAVORITES}, + { 0x1d, KEY_BACK}, + { 0x4d, KEY_FASTFORWARD}, + { 0x44, KEY_EPG}, + { 0x4c, KEY_INFO}, + { 0x41, KEY_AB}, + { 0x43, KEY_AUDIO}, + { 0x45, KEY_SUBTITLE}, + { 0x4a, KEY_LIST}, + { 0x46, KEY_F1}, + { 0x47, KEY_F2}, + { 0x5e, KEY_F3}, + { 0x5c, KEY_F4}, + { 0x52, KEY_F5}, + { 0x5a, KEY_F6}, + { 0x56, KEY_MODE}, + { 0x58, KEY_SWITCHVIDEOMODE}, +}; +struct ir_scancode_table ir_codes_tevii_nec_table = { + .scan = ir_codes_tevii_nec, + .size = ARRAY_SIZE(ir_codes_tevii_nec), +}; +EXPORT_SYMBOL_GPL(ir_codes_tevii_nec_table); + static struct ir_scancode ir_codes_tbs_nec[] = { { 0x04, KEY_POWER2}, /*power*/ { 0x14, KEY_MUTE}, /*mute*/ diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index 33437e40314..c0047c1960c 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c @@ -315,7 +315,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) break; case CX88_BOARD_TEVII_S460: case CX88_BOARD_TEVII_S420: - ir_codes = &ir_codes_dm1105_nec_table; + ir_codes = &ir_codes_tevii_nec_table; ir_type = IR_TYPE_PD; ir->sampling = 0xff00; /* address */ break; diff --git a/include/media/ir-common.h b/include/media/ir-common.h index c2d515dd94d..5921776929e 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -173,6 +173,7 @@ extern struct ir_scancode_table ir_codes_ati_tv_wonder_hd_600_table; extern struct ir_scancode_table ir_codes_kworld_plus_tv_analog_table; extern struct ir_scancode_table ir_codes_kaiomy_table; extern struct ir_scancode_table ir_codes_dm1105_nec_table; +extern struct ir_scancode_table ir_codes_tevii_nec_table; extern struct ir_scancode_table ir_codes_tbs_nec_table; extern struct ir_scancode_table ir_codes_evga_indtube_table; extern struct ir_scancode_table ir_codes_terratec_cinergy_xs_table; -- cgit v1.2.3-70-g09d2 From 930bf78c20187f3cbbf0775cd317616c6b681a8a Mon Sep 17 00:00:00 2001 From: Theodore Kilgore Date: Mon, 5 Oct 2009 05:11:35 -0300 Subject: V4L/DVB (13137): gspca_mr97310a: Add controls for vga cams with sensor type 0 This patch adds controls for vga cams with sensor type 0, in order to correctly report the present controls, the probing of the sensor type has been moved from sd_start to sd_config, since this made the sensor type probing unreliable the detection method was changed. Note this requires the camera to enter streaming mode, so sd_config now briefly makes the camera stream. Signed-off-by: Theodore Kilgore Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/mr97310a.c | 506 ++++++++++++++++++++--------------- 1 file changed, 291 insertions(+), 215 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index f8328b9efae..f4c83b36790 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c @@ -1,23 +1,28 @@ /* * Mars MR97310A library * + * The original mr97310a driver, which supported the Aiptek Pencam VGA+, is * Copyright (C) 2009 Kyle Guinn * * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+ * and for the routines for detecting and classifying these various cameras, + * is Copyright (C) 2009 Theodore Kilgore * + * Support for the control settings for the CIF cameras is + * Copyright (C) 2009 Hans de Goede and + * Thomas Kaiser + * + * Support for the control settings for the VGA cameras is * Copyright (C) 2009 Theodore Kilgore * - * Acknowledgements: + * Several previously unsupported cameras are owned and have been tested by + * Hans de Goede and + * Thomas Kaiser and + * Theodore Kilgore * * The MR97311A support in gspca/mars.c has been helpful in understanding some * of the registers in these cameras. * - * Hans de Goede and - * Thomas Kaiser - * have assisted with their experience. Each of them has also helped by - * testing a previously unsupported camera. - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -40,11 +45,9 @@ #define CAM_TYPE_CIF 0 #define CAM_TYPE_VGA 1 -#define MR97310A_BRIGHTNESS_MIN -254 -#define MR97310A_BRIGHTNESS_MAX 255 #define MR97310A_BRIGHTNESS_DEFAULT 0 -#define MR97310A_EXPOSURE_MIN 300 +#define MR97310A_EXPOSURE_MIN 0 #define MR97310A_EXPOSURE_MAX 4095 #define MR97310A_EXPOSURE_DEFAULT 1000 @@ -82,6 +85,7 @@ struct sensor_w_data { int len; }; +static void sd_stopN(struct gspca_dev *gspca_dev); static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); @@ -94,14 +98,16 @@ static void setgain(struct gspca_dev *gspca_dev); /* V4L2 controls supported by the driver */ static struct ctrl sd_ctrls[] = { +/* Seprate brightness control description for Argus QuickClix as it has + different limits from to other mr97310a camera's */ { -#define BRIGHTNESS_IDX 0 +#define NORM_BRIGHTNESS_IDX 0 { .id = V4L2_CID_BRIGHTNESS, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Brightness", - .minimum = MR97310A_BRIGHTNESS_MIN, - .maximum = MR97310A_BRIGHTNESS_MAX, + .minimum = -254, + .maximum = 255, .step = 1, .default_value = MR97310A_BRIGHTNESS_DEFAULT, .flags = 0, @@ -110,7 +116,22 @@ static struct ctrl sd_ctrls[] = { .get = sd_getbrightness, }, { -#define EXPOSURE_IDX 1 +#define ARGUS_QC_BRIGHTNESS_IDX 1 + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 15, + .step = 1, + .default_value = MR97310A_BRIGHTNESS_DEFAULT, + .flags = 0, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, + { +#define EXPOSURE_IDX 2 { .id = V4L2_CID_EXPOSURE, .type = V4L2_CTRL_TYPE_INTEGER, @@ -125,7 +146,7 @@ static struct ctrl sd_ctrls[] = { .get = sd_getexposure, }, { -#define GAIN_IDX 2 +#define GAIN_IDX 3 { .id = V4L2_CID_GAIN, .type = V4L2_CTRL_TYPE_INTEGER, @@ -230,12 +251,17 @@ static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data) int rc; buf = data; - rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1); + if (sd->cam_type == CAM_TYPE_CIF) { + rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1); + confirm_reg = sd->sensor_type ? 0x13 : 0x11; + } else { + rc = sensor_write_reg(gspca_dev, reg, 0x00, &buf, 1); + confirm_reg = 0x11; + } if (rc < 0) return rc; buf = 0x01; - confirm_reg = sd->sensor_type ? 0x13 : 0x11; rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1); if (rc < 0) return rc; @@ -243,18 +269,26 @@ static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data) return 0; } -static int cam_get_response16(struct gspca_dev *gspca_dev) +static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose) { - __u8 *data = gspca_dev->usb_buf; int err_code; - data[0] = 0x21; + gspca_dev->usb_buf[0] = reg; err_code = mr_write(gspca_dev, 1); if (err_code < 0) return err_code; err_code = mr_read(gspca_dev, 16); - return err_code; + if (err_code < 0) + return err_code; + + if (verbose) + PDEBUG(D_PROBE, "Register: %02x reads %02x%02x%02x", reg, + gspca_dev->usb_buf[0], + gspca_dev->usb_buf[1], + gspca_dev->usb_buf[2]); + + return 0; } static int zero_the_pointer(struct gspca_dev *gspca_dev) @@ -264,7 +298,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) u8 status = 0; int tries = 0; - err_code = cam_get_response16(gspca_dev); + err_code = cam_get_response16(gspca_dev, 0x21, 0); if (err_code < 0) return err_code; @@ -275,7 +309,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) if (err_code < 0) return err_code; - err_code = cam_get_response16(gspca_dev); + err_code = cam_get_response16(gspca_dev, 0x21, 0); if (err_code < 0) return err_code; @@ -285,7 +319,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) if (err_code < 0) return err_code; - err_code = cam_get_response16(gspca_dev); + err_code = cam_get_response16(gspca_dev, 0x21, 0); if (err_code < 0) return err_code; @@ -295,7 +329,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) if (err_code < 0) return err_code; - err_code = cam_get_response16(gspca_dev); + err_code = cam_get_response16(gspca_dev, 0x21, 0); if (err_code < 0) return err_code; @@ -306,7 +340,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) return err_code; while (status != 0x0a && tries < 256) { - err_code = cam_get_response16(gspca_dev); + err_code = cam_get_response16(gspca_dev, 0x21, 0); status = data[0]; tries++; if (err_code < 0) @@ -323,7 +357,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) if (err_code < 0) return err_code; - err_code = cam_get_response16(gspca_dev); + err_code = cam_get_response16(gspca_dev, 0x21, 0); status = data[0]; tries++; if (err_code < 0) @@ -342,22 +376,34 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) return 0; } -static u8 get_sensor_id(struct gspca_dev *gspca_dev) +static int stream_start(struct gspca_dev *gspca_dev) { - int err_code; - - gspca_dev->usb_buf[0] = 0x1e; - err_code = mr_write(gspca_dev, 1); - if (err_code < 0) - return err_code; + gspca_dev->usb_buf[0] = 0x01; + gspca_dev->usb_buf[1] = 0x01; + return mr_write(gspca_dev, 2); +} - err_code = mr_read(gspca_dev, 16); - if (err_code < 0) - return err_code; +static void stream_stop(struct gspca_dev *gspca_dev) +{ + gspca_dev->usb_buf[0] = 0x01; + gspca_dev->usb_buf[1] = 0x00; + if (mr_write(gspca_dev, 2) < 0) + PDEBUG(D_ERR, "Stream Stop failed"); +} - PDEBUG(D_PROBE, "Byte zero reported is %01x", gspca_dev->usb_buf[0]); +static void lcd_stop(struct gspca_dev *gspca_dev) +{ + gspca_dev->usb_buf[0] = 0x19; + gspca_dev->usb_buf[1] = 0x54; + if (mr_write(gspca_dev, 2) < 0) + PDEBUG(D_ERR, "LCD Stop failed"); +} - return gspca_dev->usb_buf[0]; +static int isoc_enable(struct gspca_dev *gspca_dev) +{ + gspca_dev->usb_buf[0] = 0x00; + gspca_dev->usb_buf[1] = 0x4d; /* ISOC transfering enable... */ + return mr_write(gspca_dev, 2); } /* this function is called at probe time */ @@ -366,60 +412,172 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - __u8 *data = gspca_dev->usb_buf; int err_code; cam = &gspca_dev->cam; cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); + sd->do_lcd_stop = 0; + + /* Now, logical layout of the driver must fall sacrifice to the + * realities of the hardware supported. We have to sort out several + * cameras which share the USB ID but are in fact different inside. + * We need to start the initialization process for the cameras in + * order to classify them. Some of the supported cameras require the + * memory pointer to be set to 0 as the very first item of business + * or else they will not stream. So we do that immediately. + */ + err_code = zero_the_pointer(gspca_dev); + if (err_code < 0) + return err_code; if (id->idProduct == 0x010e) { sd->cam_type = CAM_TYPE_CIF; cam->nmodes--; - - data[0] = 0x01; - data[1] = 0x01; - err_code = mr_write(gspca_dev, 2); + err_code = stream_start(gspca_dev); + if (err_code < 0) + return err_code; + err_code = cam_get_response16(gspca_dev, 0x06, 1); if (err_code < 0) return err_code; - - msleep(200); - data[0] = get_sensor_id(gspca_dev); /* - * Known CIF cameras. If you have another to report, please do + * The various CIF cameras share the same USB ID but use + * different init routines and different controls. We need to + * detect which one is connected! * - * Name byte just read sd->sensor_type - * reported by - * Sakar Spy-shot 0x28 T. Kilgore 0 - * Innovage 0xf5 (unstable) T. Kilgore 0 - * Vivitar Mini 0x53 H. De Goede 0 - * Vivitar Mini 0x04 / 0x24 E. Rodriguez 0 - * Vivitar Mini 0x08 T. Kilgore 1 - * Elta-Media 8212dc 0x23 T. Kaiser 1 - * Philips dig. keych. 0x37 T. Kilgore 1 + * A list of known CIF cameras follows. They all report either + * 0002 for type 0 or 0003 for type 1. + * If you have another to report, please do + * + * Name sd->sensor_type reported by + * + * Sakar Spy-shot 0 T. Kilgore + * Innovage 0 T. Kilgore + * Vivitar Mini 0 H. De Goede + * Vivitar Mini 0 E. Rodriguez + * Vivitar Mini 1 T. Kilgore + * Elta-Media 8212dc 1 T. Kaiser + * Philips dig. keych. 1 T. Kilgore */ - if ((data[0] & 0x78) == 8 || - ((data[0] & 0x2) == 0x2 && data[0] != 0x53)) - sd->sensor_type = 1; - else + switch (gspca_dev->usb_buf[1]) { + case 2: sd->sensor_type = 0; - + break; + case 3: + sd->sensor_type = 1; + break; + default: + PDEBUG(D_ERR, "Unknown CIF Sensor id : %02x", + gspca_dev->usb_buf[1]); + return -ENODEV; + } PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d", sd->sensor_type); + } else { + sd->cam_type = CAM_TYPE_VGA; - if (force_sensor_type != -1) { - sd->sensor_type = !! force_sensor_type; - PDEBUG(D_PROBE, "Forcing sensor type to: %d", - sd->sensor_type); + /* + * VGA cams also have two different sensor types. Detection + * requires a two-step process. + * + * Here is a report on the result of the first test for the + * known MR97310a VGA cameras. If you have another to report, + * please do. + * + * Name byte just read sd->sensor_type + * sd->do_lcd_stop + * Aiptek Pencam VGA+ 0x31 0 1 + * ION digital 0x31 0 1 + * Sakar Digital 77379 0x31 0 1 + * Argus DC-1620 0x30 1 0 + * Argus QuickClix 0x30 1 1 (see note) + * Note that this test fails to distinguish sd->sensor_type + * for the two cameras which have reported 0x30. + * Another test will be run on them. + * But the sd->do_lcd_stop setting is needed, too. + */ + + err_code = cam_get_response16(gspca_dev, 0x20, 1); + if (err_code < 0) + return err_code; + sd->sensor_type = gspca_dev->usb_buf[0] & 1; + sd->do_lcd_stop = (~gspca_dev->usb_buf[0]) & 1; + err_code = stream_start(gspca_dev); + if (err_code < 0) + return err_code; + + /* + * A second test can now resolve any remaining ambiguity in the + * identification of the camera's sensor type. Specifically, + * it now gives the correct sensor_type for the Argus DC-1620 + * and the Argus QuickClix. + * + * This second test is only run if needed, + * but additional results from testing some other cameras + * are recorded here, too: + * + * Name gspca_dev->usb_buf[] sd->sensor_type + * + * Aiptek Pencam VGA+ 0300 (test not needed) 1 + * ION digital 0350 (test not needed) 1 + * Argus DC-1620 0450 (remains as type 0) 0 + * Argus QuickClix 0420 (corrected to type 1) 1 + * + * This test even seems able to distinguish one VGA cam from + * another which may be useful. However, the CIF type 1 cameras + * do not like it. + */ + + if (!sd->sensor_type) { + err_code = cam_get_response16(gspca_dev, 0x07, 1); + if (err_code < 0) + return err_code; + + switch (gspca_dev->usb_buf[1]) { + case 0x50: + break; + case 0x20: + sd->sensor_type = 1; + PDEBUG(D_PROBE, "sensor_type corrected to 1"); + break; + default: + PDEBUG(D_ERR, "Unknown VGA Sensor id : %02x", + gspca_dev->usb_buf[1]); + return -ENODEV; + } } + PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d", + sd->sensor_type); + } + /* Stop streaming as we've started it to probe the sensor type. */ + sd_stopN(gspca_dev); + if (force_sensor_type != -1) { + sd->sensor_type = !!force_sensor_type; + PDEBUG(D_PROBE, "Forcing sensor type to: %d", + sd->sensor_type); + } + + /* Setup controls depending on camera type */ + if (sd->cam_type == CAM_TYPE_CIF) { + /* No brightness for sensor_type 0 */ if (sd->sensor_type == 0) - gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX); + gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) | + (1 << ARGUS_QC_BRIGHTNESS_IDX); + else + gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX); } else { - sd->cam_type = CAM_TYPE_VGA; - PDEBUG(D_PROBE, "MR97310A VGA camera detected"); - gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) | - (1 << EXPOSURE_IDX) | (1 << GAIN_IDX); + /* All controls need to be disabled if VGA sensor_type is 0 */ + if (sd->sensor_type == 0) + gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) | + (1 << ARGUS_QC_BRIGHTNESS_IDX) | + (1 << EXPOSURE_IDX) | + (1 << GAIN_IDX); + else if (sd->do_lcd_stop) + /* Argus QuickClix has different brightness limits */ + gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX); + else + gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX); } sd->brightness = MR97310A_BRIGHTNESS_DEFAULT; @@ -455,11 +613,6 @@ static int start_cif_cam(struct gspca_dev *gspca_dev) }; /* Note: Some of the above descriptions guessed from MR97113A driver */ - data[0] = 0x01; - data[1] = 0x01; - err_code = mr_write(gspca_dev, 2); - if (err_code < 0) - return err_code; memcpy(data, startup_string, 11); if (sd->sensor_type) @@ -533,22 +686,7 @@ static int start_cif_cam(struct gspca_dev *gspca_dev) err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data, ARRAY_SIZE(cif_sensor1_init_data)); } - if (err_code < 0) - return err_code; - - setbrightness(gspca_dev); - setexposure(gspca_dev); - setgain(gspca_dev); - - msleep(200); - - data[0] = 0x00; - data[1] = 0x4d; /* ISOC transfering enable... */ - err_code = mr_write(gspca_dev, 2); - if (err_code < 0) - return err_code; - - return 0; + return err_code; } static int start_vga_cam(struct gspca_dev *gspca_dev) @@ -558,84 +696,8 @@ static int start_vga_cam(struct gspca_dev *gspca_dev) int err_code; const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x50, 0xc0}; - /* What some of these mean is explained in start_cif_cam(), above */ - sd->sof_read = 0; - - /* - * We have to know which camera we have, because the register writes - * depend upon the camera. This test, run before we actually enter - * the initialization routine, distinguishes most of the cameras, If - * needed, another routine is done later, too. - */ - memset(data, 0, 16); - data[0] = 0x20; - err_code = mr_write(gspca_dev, 1); - if (err_code < 0) - return err_code; - - err_code = mr_read(gspca_dev, 16); - if (err_code < 0) - return err_code; - - PDEBUG(D_PROBE, "Byte reported is %02x", data[0]); - - msleep(200); - /* - * Known VGA cameras. If you have another to report, please do - * - * Name byte just read sd->sensor_type - * sd->do_lcd_stop - * Aiptek Pencam VGA+ 0x31 0 1 - * ION digital 0x31 0 1 - * Argus DC-1620 0x30 1 0 - * Argus QuickClix 0x30 1 1 (not caught here) - */ - sd->sensor_type = data[0] & 1; - sd->do_lcd_stop = (~data[0]) & 1; - - - - /* Streaming setup begins here. */ - - - data[0] = 0x01; - data[1] = 0x01; - err_code = mr_write(gspca_dev, 2); - if (err_code < 0) - return err_code; - - /* - * A second test can now resolve any remaining ambiguity in the - * identification of the camera type, - */ - if (!sd->sensor_type) { - data[0] = get_sensor_id(gspca_dev); - if (data[0] == 0x7f) { - sd->sensor_type = 1; - PDEBUG(D_PROBE, "sensor_type corrected to 1"); - } - msleep(200); - } - - if (force_sensor_type != -1) { - sd->sensor_type = !! force_sensor_type; - PDEBUG(D_PROBE, "Forcing sensor type to: %d", - sd->sensor_type); - } - /* - * Known VGA cameras. - * This test is only run if the previous test returned 0x30, but - * here is the information for all others, too, just for reference. - * - * Name byte just read sd->sensor_type - * - * Aiptek Pencam VGA+ 0xfb (this test not run) 1 - * ION digital 0xbd (this test not run) 1 - * Argus DC-1620 0xe5 (no change) 0 - * Argus QuickClix 0x7f (reclassified) 1 - */ memcpy(data, startup_string, 11); if (!sd->sensor_type) { data[5] = 0x00; @@ -704,14 +766,6 @@ static int start_vga_cam(struct gspca_dev *gspca_dev) err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data, ARRAY_SIZE(vga_sensor1_init_data)); } - if (err_code < 0) - return err_code; - - msleep(200); - data[0] = 0x00; - data[1] = 0x4d; /* ISOC transfering enable... */ - err_code = mr_write(gspca_dev, 2); - return err_code; } @@ -719,82 +773,101 @@ static int sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int err_code; - struct cam *cam; - cam = &gspca_dev->cam; sd->sof_read = 0; - /* - * Some of the supported cameras require the memory pointer to be - * set to 0, or else they will not stream. - */ - zero_the_pointer(gspca_dev); - msleep(200); + + /* Some of the VGA cameras require the memory pointer + * to be set to 0 again. We have been forced to start the + * stream somewhere else to detect the hardware, and closed it, + * and now since we are restarting the stream we need to do a + * completely fresh and clean start. */ + err_code = zero_the_pointer(gspca_dev); + if (err_code < 0) + return err_code; + + err_code = stream_start(gspca_dev); + if (err_code < 0) + return err_code; + if (sd->cam_type == CAM_TYPE_CIF) { err_code = start_cif_cam(gspca_dev); } else { err_code = start_vga_cam(gspca_dev); } - return err_code; + if (err_code < 0) + return err_code; + + setbrightness(gspca_dev); + setexposure(gspca_dev); + setgain(gspca_dev); + + return isoc_enable(gspca_dev); } static void sd_stopN(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - int result; - - gspca_dev->usb_buf[0] = 1; - gspca_dev->usb_buf[1] = 0; - result = mr_write(gspca_dev, 2); - if (result < 0) - PDEBUG(D_ERR, "Camera Stop failed"); + stream_stop(gspca_dev); /* Not all the cams need this, but even if not, probably a good idea */ zero_the_pointer(gspca_dev); - if (sd->do_lcd_stop) { - gspca_dev->usb_buf[0] = 0x19; - gspca_dev->usb_buf[1] = 0x54; - result = mr_write(gspca_dev, 2); - if (result < 0) - PDEBUG(D_ERR, "Camera Stop failed"); - } + if (sd->do_lcd_stop) + lcd_stop(gspca_dev); } static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; u8 val; - - if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX)) + u8 sign_reg = 7; /* This reg and the next one used on CIF cams. */ + u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */ + const u8 quick_clix_table[] = + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ + { 0, 4, 8, 12, 1, 2, 3, 5, 6, 9, 7, 10, 13, 11, 14, 15}; + /* + * This control is disabled for CIF type 1 and VGA type 0 cameras. + * It does not quite act linearly for the Argus QuickClix camera, + * but it does control brightness. The values are 0 - 15 only, and + * the table above makes them act consecutively. + */ + if ((gspca_dev->ctrl_dis & (1 << NORM_BRIGHTNESS_IDX)) && + (gspca_dev->ctrl_dis & (1 << ARGUS_QC_BRIGHTNESS_IDX))) return; + if (sd->cam_type == CAM_TYPE_VGA) { + sign_reg += 4; + value_reg += 4; + } + /* Note register 7 is also seen as 0x8x or 0xCx in dumps */ if (sd->brightness > 0) { - sensor_write1(gspca_dev, 7, 0x00); + sensor_write1(gspca_dev, sign_reg, 0x00); val = sd->brightness; } else { - sensor_write1(gspca_dev, 7, 0x01); - val = 257 - sd->brightness; + sensor_write1(gspca_dev, sign_reg, 0x01); + val = (257 - sd->brightness); } - sensor_write1(gspca_dev, 8, val); + /* Use lookup table for funky Argus QuickClix brightness */ + if (sd->do_lcd_stop) + val = quick_clix_table[val]; + + sensor_write1(gspca_dev, value_reg, val); } static void setexposure(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - u8 val; + int exposure; if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX)) return; - if (sd->sensor_type) { - val = sd->exposure >> 4; - sensor_write1(gspca_dev, 3, val); - val = sd->exposure & 0xf; - sensor_write1(gspca_dev, 4, val); + if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) { + /* This cam does not like very low exposure settings */ + exposure = (sd->exposure < 300) ? 300 : sd->exposure; + sensor_write1(gspca_dev, 3, exposure >> 4); + sensor_write1(gspca_dev, 4, exposure & 0x0f); } else { - u8 clockdiv; - int exposure; - /* We have both a clock divider and an exposure register. We first calculate the clock divider, as that determines the maximum exposure and then we calculayte the exposure @@ -802,7 +875,7 @@ static void setexposure(struct gspca_dev *gspca_dev) Note our 0 - 4095 exposure is mapped to 0 - 511 milliseconds exposure time */ - clockdiv = (60 * sd->exposure + 7999) / 8000; + u8 clockdiv = (60 * sd->exposure + 7999) / 8000; /* Limit framerate to not exceed usb bandwidth */ if (clockdiv < 3 && gspca_dev->width >= 320) @@ -810,6 +883,9 @@ static void setexposure(struct gspca_dev *gspca_dev) else if (clockdiv < 2) clockdiv = 2; + if (sd->cam_type == CAM_TYPE_VGA && clockdiv < 4) + clockdiv = 4; + /* Frame exposure time in ms = 1000 * clockdiv / 60 -> exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */ exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv); @@ -832,7 +908,7 @@ static void setgain(struct gspca_dev *gspca_dev) if (gspca_dev->ctrl_dis & (1 << GAIN_IDX)) return; - if (sd->sensor_type) { + if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) { sensor_write1(gspca_dev, 0x0e, sd->gain); } else { sensor_write1(gspca_dev, 0x10, sd->gain); -- cgit v1.2.3-70-g09d2 From 8519110040ca98dfbc89c473921cca390c81460c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 5 Oct 2009 05:58:18 -0300 Subject: V4L/DVB (13138): gspca_sq905: cleanup sq905_dostream -Remove use of unneeded discarding variable -Cleanup locking to only take usb_lock around access to the control endpoint, by no longer taking the lock around the bulk transfer (which takes most of the time) we can remove the msleep(1) which was needed to give the gspca core a chance to grab the usb_lock to signal us to stop. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sq905.c | 56 ++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 30 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c index 715a68f0156..547d1fd5191 100644 --- a/drivers/media/video/gspca/sq905.c +++ b/drivers/media/video/gspca/sq905.c @@ -168,18 +168,22 @@ static int sq905_ack_frame(struct gspca_dev *gspca_dev) * request and read a block of data - see warning on sq905_command. */ static int -sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size) +sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size, int need_lock) { int ret; int act_len; gspca_dev->usb_buf[0] = '\0'; + if (need_lock) + mutex_lock(&gspca_dev->usb_lock); ret = usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), USB_REQ_SYNCH_FRAME, /* request */ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, SQ905_BULK_READ, size, gspca_dev->usb_buf, 1, SQ905_CMD_TIMEOUT); + if (need_lock) + mutex_unlock(&gspca_dev->usb_lock); if (ret < 0) { PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret); return ret; @@ -214,7 +218,6 @@ static void sq905_dostream(struct work_struct *work) int bytes_left; /* bytes remaining in current frame. */ int data_len; /* size to use for the next read. */ int header_read; /* true if we have already read the frame header. */ - int discarding; /* true if we failed to get space for frame. */ int packet_type; int frame_sz; int ret; @@ -222,7 +225,6 @@ static void sq905_dostream(struct work_struct *work) u8 *buffer; buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); - mutex_lock(&gspca_dev->usb_lock); if (!buffer) { PDEBUG(D_ERR, "Couldn't allocate USB buffer"); goto quit_stream; @@ -232,28 +234,22 @@ static void sq905_dostream(struct work_struct *work) + FRAME_HEADER_LEN; while (gspca_dev->present && gspca_dev->streaming) { - /* Need a short delay to ensure streaming flag was set by - * gspca and to make sure gspca can grab the mutex. */ - mutex_unlock(&gspca_dev->usb_lock); - msleep(1); - /* request some data and then read it until we have * a complete frame. */ bytes_left = frame_sz; header_read = 0; - discarding = 0; - while (bytes_left > 0) { + /* Note we do not check for gspca_dev->streaming here, as + we must finish reading an entire frame, otherwise the + next time we stream we start reading in the middle of a + frame. */ + while (bytes_left > 0 && gspca_dev->present) { data_len = bytes_left > SQ905_MAX_TRANSFER ? SQ905_MAX_TRANSFER : bytes_left; - mutex_lock(&gspca_dev->usb_lock); - if (!gspca_dev->present) - goto quit_stream; - ret = sq905_read_data(gspca_dev, buffer, data_len); + ret = sq905_read_data(gspca_dev, buffer, data_len, 1); if (ret < 0) goto quit_stream; - mutex_unlock(&gspca_dev->usb_lock); - PDEBUG(D_STREAM, + PDEBUG(D_PACK, "Got %d bytes out of %d for frame", data_len, bytes_left); bytes_left -= data_len; @@ -271,7 +267,7 @@ static void sq905_dostream(struct work_struct *work) packet_type = INTER_PACKET; } frame = gspca_get_i_frame(gspca_dev); - if (frame && !discarding) { + if (frame) { frame = gspca_frame_add(gspca_dev, packet_type, frame, data, data_len); /* If entire frame fits in one packet we still @@ -281,23 +277,23 @@ static void sq905_dostream(struct work_struct *work) frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); - } else { - discarding = 1; } } - /* acknowledge the frame */ - mutex_lock(&gspca_dev->usb_lock); - if (!gspca_dev->present) - goto quit_stream; - ret = sq905_ack_frame(gspca_dev); - if (ret < 0) - goto quit_stream; + if (gspca_dev->present) { + /* acknowledge the frame */ + mutex_lock(&gspca_dev->usb_lock); + ret = sq905_ack_frame(gspca_dev); + mutex_unlock(&gspca_dev->usb_lock); + if (ret < 0) + goto quit_stream; + } } quit_stream: - /* the usb_lock is already acquired */ - if (gspca_dev->present) + if (gspca_dev->present) { + mutex_lock(&gspca_dev->usb_lock); sq905_command(gspca_dev, SQ905_CLEAR); - mutex_unlock(&gspca_dev->usb_lock); + mutex_unlock(&gspca_dev->usb_lock); + } kfree(buffer); } @@ -346,7 +342,7 @@ static int sd_init(struct gspca_dev *gspca_dev) ret = sq905_command(gspca_dev, SQ905_ID); if (ret < 0) return ret; - ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4); + ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4, 0); if (ret < 0) return ret; /* usb_buf is allocated with kmalloc so is aligned. -- cgit v1.2.3-70-g09d2 From b3e440eef8a842736d63cc6a6594d80dfbb75fd9 Mon Sep 17 00:00:00 2001 From: Theodore Kilgore Date: Fri, 9 Oct 2009 03:54:49 -0300 Subject: V4L/DVB (13139): gspca_mr97310a: Improve VGA sensor type detection Improve (and also simplify :) gspca_mr97310a: VGA sensor type detection. As it was still failing on some machines (not with some cams, but on some machines interesting enough). Signed-off-by: Theodore Kilgore Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/mr97310a.c | 89 ++++++++++++++---------------------- 1 file changed, 34 insertions(+), 55 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index f4c83b36790..abc56e37efc 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c @@ -431,12 +431,13 @@ static int sd_config(struct gspca_dev *gspca_dev, if (err_code < 0) return err_code; + err_code = stream_start(gspca_dev); + if (err_code < 0) + return err_code; + if (id->idProduct == 0x010e) { sd->cam_type = CAM_TYPE_CIF; cam->nmodes--; - err_code = stream_start(gspca_dev); - if (err_code < 0) - return err_code; err_code = cam_get_response16(gspca_dev, 0x06, 1); if (err_code < 0) return err_code; @@ -476,74 +477,52 @@ static int sd_config(struct gspca_dev *gspca_dev, } else { sd->cam_type = CAM_TYPE_VGA; - /* - * VGA cams also have two different sensor types. Detection - * requires a two-step process. - * - * Here is a report on the result of the first test for the - * known MR97310a VGA cameras. If you have another to report, - * please do. - * - * Name byte just read sd->sensor_type - * sd->do_lcd_stop - * Aiptek Pencam VGA+ 0x31 0 1 - * ION digital 0x31 0 1 - * Sakar Digital 77379 0x31 0 1 - * Argus DC-1620 0x30 1 0 - * Argus QuickClix 0x30 1 1 (see note) - * Note that this test fails to distinguish sd->sensor_type - * for the two cameras which have reported 0x30. - * Another test will be run on them. - * But the sd->do_lcd_stop setting is needed, too. - */ - - err_code = cam_get_response16(gspca_dev, 0x20, 1); - if (err_code < 0) - return err_code; - sd->sensor_type = gspca_dev->usb_buf[0] & 1; - sd->do_lcd_stop = (~gspca_dev->usb_buf[0]) & 1; - err_code = stream_start(gspca_dev); + err_code = cam_get_response16(gspca_dev, 0x07, 1); if (err_code < 0) return err_code; /* - * A second test can now resolve any remaining ambiguity in the - * identification of the camera's sensor type. Specifically, - * it now gives the correct sensor_type for the Argus DC-1620 - * and the Argus QuickClix. - * - * This second test is only run if needed, - * but additional results from testing some other cameras - * are recorded here, too: + * Here is a table of the responses to the previous command + * from the known MR97310A VGA cameras. * * Name gspca_dev->usb_buf[] sd->sensor_type + * sd->do_lcd_stop + * Aiptek Pencam VGA+ 0300 0 1 + * ION digital 0350 0 1 + * Argus DC-1620 0450 1 0 + * Argus QuickClix 0420 1 1 * - * Aiptek Pencam VGA+ 0300 (test not needed) 1 - * ION digital 0350 (test not needed) 1 - * Argus DC-1620 0450 (remains as type 0) 0 - * Argus QuickClix 0420 (corrected to type 1) 1 + * Based upon these results, we assume default settings + * and then correct as necessary, as follows. * - * This test even seems able to distinguish one VGA cam from - * another which may be useful. However, the CIF type 1 cameras - * do not like it. */ - if (!sd->sensor_type) { - err_code = cam_get_response16(gspca_dev, 0x07, 1); - if (err_code < 0) - return err_code; - + sd->sensor_type = 1; + sd->do_lcd_stop = 0; + if ((gspca_dev->usb_buf[0] != 0x03) && + (gspca_dev->usb_buf[0] != 0x04)) { + PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x", + gspca_dev->usb_buf[1]); + PDEBUG(D_ERR, "Defaults assumed, may not work"); + PDEBUG(D_ERR, "Please report this"); + } + if (gspca_dev->usb_buf[0] == 0x04) { + sd->do_lcd_stop = 1; switch (gspca_dev->usb_buf[1]) { case 0x50: + sd->sensor_type = 0; + PDEBUG(D_PROBE, "sensor_type corrected to 0"); break; case 0x20: - sd->sensor_type = 1; - PDEBUG(D_PROBE, "sensor_type corrected to 1"); + /* Nothing to do here. */ break; default: - PDEBUG(D_ERR, "Unknown VGA Sensor id : %02x", - gspca_dev->usb_buf[1]); - return -ENODEV; + PDEBUG(D_ERR, + "Unknown VGA Sensor id Byte 1: %02x", + gspca_dev->usb_buf[1]); + PDEBUG(D_ERR, + "Defaults assumed, may not work"); + PDEBUG(D_ERR, "Please report this"); } } PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d", -- cgit v1.2.3-70-g09d2 From 6ca3f255f790764f9cfc41d3ac02823d83dfa5ac Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 9 Oct 2009 03:58:35 -0300 Subject: V4L/DVB (13140): gspca_jeilinj: once one frame is discarded it keeps discarding all frames While checking all gspca sub drivers pkt_scan functions for a bug I found in 1 of them (and after checking also in another), I noticed a bug in the gspca_jeilinj work queue function, once it has decided to start discard a frame because the application is not reading fast enough (and thus returning buffers to fill fast enough), it never stops discarding. This patch fixes this by simply completely removing the "discarding" variable, if we need to discard the current frame because there is no buffer to store it, the "frame" pointer will be NULL, so that is all we need to check. I've also moved the gspca_get_i_frame() call and the writing of the jpg header to the buffer to after the first usb_bulk_msg() call, as we don't need it before that, and that will give the app slightly more time to queue a buffer for us to fill. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/jeilinj.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c index a11c97ebeb0..d679970d5b3 100644 --- a/drivers/media/video/gspca/jeilinj.c +++ b/drivers/media/video/gspca/jeilinj.c @@ -185,7 +185,6 @@ static void jlj_dostream(struct work_struct *work) int blocks_left; /* 0x200-sized blocks remaining in current frame. */ int size_in_blocks; int act_len; - int discarding = 0; /* true if we failed to get space for frame. */ int packet_type; int ret; u8 *buffer; @@ -196,15 +195,6 @@ static void jlj_dostream(struct work_struct *work) goto quit_stream; } while (gspca_dev->present && gspca_dev->streaming) { - if (!gspca_dev->present) - goto quit_stream; - /* Start a new frame, and add the JPEG header, first thing */ - frame = gspca_get_i_frame(gspca_dev); - if (frame && !discarding) - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - dev->jpeg_hdr, JPEG_HDR_SZ); - else - discarding = 1; /* * Now request data block 0. Line 0 reports the size * to download, in blocks of size 0x200, and also tells the @@ -222,14 +212,17 @@ static void jlj_dostream(struct work_struct *work) size_in_blocks = buffer[0x0a]; blocks_left = buffer[0x0a] - 1; PDEBUG(D_STREAM, "blocks_left = 0x%x", blocks_left); - packet_type = INTER_PACKET; - if (frame && !discarding) + + /* Start a new frame, and add the JPEG header, first thing */ + frame = gspca_get_i_frame(gspca_dev); + if (frame) { + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + dev->jpeg_hdr, JPEG_HDR_SZ); /* Toss line 0 of data block 0, keep the rest. */ - gspca_frame_add(gspca_dev, packet_type, + gspca_frame_add(gspca_dev, INTER_PACKET, frame, buffer + FRAME_HEADER_LEN, JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN); - else - discarding = 1; + } while (blocks_left > 0) { if (!gspca_dev->present) goto quit_stream; @@ -246,12 +239,10 @@ static void jlj_dostream(struct work_struct *work) packet_type = LAST_PACKET; else packet_type = INTER_PACKET; - if (frame && !discarding) + if (frame) gspca_frame_add(gspca_dev, packet_type, frame, buffer, JEILINJ_MAX_TRANSFER); - else - discarding = 1; } } quit_stream: -- cgit v1.2.3-70-g09d2 From 205260102c5cef4180982eec88aaeb6934faf214 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 9 Oct 2009 04:17:42 -0300 Subject: V4L/DVB (13141): gspca_sq905c: once one frame is discarded it keeps discarding all frames While checking all gspca sub drivers pkt_scan functions for a bug I found in 1 of them (and after checking also in another), I noticed a bug in the gspca_sq905c work queue function, once it has decided to start discarding a frame because the application is not reading fast enough (and thus returning buffers to fill fast enough), it never stops discarding. This patch fixes this by simply completely removing the "discarding" variable, if we need to discard the current frame because there is no buffer to store it, the "frame" pointer will be NULL, so that is all we need to check. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sq905c.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c index 91689250543..81020f6f739 100644 --- a/drivers/media/video/gspca/sq905c.c +++ b/drivers/media/video/gspca/sq905c.c @@ -119,7 +119,6 @@ static void sq905c_dostream(struct work_struct *work) int bytes_left; /* bytes remaining in current frame. */ int data_len; /* size to use for the next read. */ int act_len; - int discarding = 0; /* true if we failed to get space for frame. */ int packet_type; int ret; u8 *buffer; @@ -131,8 +130,6 @@ static void sq905c_dostream(struct work_struct *work) } while (gspca_dev->present && gspca_dev->streaming) { - if (!gspca_dev->present) - goto quit_stream; /* Request the header, which tells the size to download */ ret = usb_bulk_msg(gspca_dev->dev, usb_rcvbulkpipe(gspca_dev->dev, 0x81), @@ -150,16 +147,12 @@ static void sq905c_dostream(struct work_struct *work) /* We keep the header. It has other information, too. */ packet_type = FIRST_PACKET; frame = gspca_get_i_frame(gspca_dev); - if (frame && !discarding) { + if (frame) gspca_frame_add(gspca_dev, packet_type, frame, buffer, FRAME_HEADER_LEN); - } else - discarding = 1; - while (bytes_left > 0) { + while (bytes_left > 0 && gspca_dev->present) { data_len = bytes_left > SQ905C_MAX_TRANSFER ? SQ905C_MAX_TRANSFER : bytes_left; - if (!gspca_dev->present) - goto quit_stream; ret = usb_bulk_msg(gspca_dev->dev, usb_rcvbulkpipe(gspca_dev->dev, 0x81), buffer, data_len, &act_len, @@ -174,19 +167,17 @@ static void sq905c_dostream(struct work_struct *work) packet_type = LAST_PACKET; else packet_type = INTER_PACKET; - frame = gspca_get_i_frame(gspca_dev); - if (frame && !discarding) + if (frame) gspca_frame_add(gspca_dev, packet_type, frame, buffer, data_len); - else - discarding = 1; } } quit_stream: - mutex_lock(&gspca_dev->usb_lock); - if (gspca_dev->present) + if (gspca_dev->present) { + mutex_lock(&gspca_dev->usb_lock); sq905c_command(gspca_dev, SQ905C_CLEAR, 0); - mutex_unlock(&gspca_dev->usb_lock); + mutex_unlock(&gspca_dev->usb_lock); + } kfree(buffer); } -- cgit v1.2.3-70-g09d2 From d76f975c574230fb00d07848d330e04d97e51475 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 11 Oct 2009 05:22:29 -0300 Subject: V4L/DVB (13142): gspca_mr97310a: small tweak to CIF sensor type 1 exposure setting The CIF sensor type 1 exposure setting got clamped at 300, as settings below 300 do not work well (and do work for the other sensors). This patch scales the 0-4095 range to 300-4095 instead of ignoring changes between 300, avoiding have a part of the control range where nothing happens. This is esp. important for software autogain as done by libv4l. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/mr97310a.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index abc56e37efc..f282f800070 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c @@ -842,8 +842,9 @@ static void setexposure(struct gspca_dev *gspca_dev) return; if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) { - /* This cam does not like very low exposure settings */ - exposure = (sd->exposure < 300) ? 300 : sd->exposure; + /* This cam does not like exposure settings > 300, + so scale 0 - 4095 to 300 - 4095 */ + exposure = (sd->exposure * 9267) / 10000 + 300; sensor_write1(gspca_dev, 3, exposure >> 4); sensor_write1(gspca_dev, 4, exposure & 0x0f); } else { -- cgit v1.2.3-70-g09d2 From 229bb7dc5181b3264550532a26a9c698be56fcb8 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 11 Oct 2009 07:41:46 -0300 Subject: V4L/DVB (13143): gspca_ov519 cleanup sensor detection gspca_ov519 cleanup sensor detection Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov519.c | 55 ++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 32 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index e1655781978..bb9976dc1e2 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -416,6 +416,7 @@ static const struct v4l2_pix_format ov511_sif_mode[] = { /* I2C ADDRESSES */ #define OV7xx0_SID 0x42 +#define OV_HIRES_SID 0x60 /* OV9xxx / OV2xxx / OV3xxx */ #define OV8xx0_SID 0xa0 #define OV6xx0_SID 0xc0 @@ -1423,13 +1424,18 @@ static inline int ov51x_restart(struct sd *sd) return 0; } +static int ov51x_set_slave_ids(struct sd *sd, __u8 slave); + /* This does an initial reset of an OmniVision sensor and ensures that I2C * is synchronized. Returns <0 on failure. */ -static int init_ov_sensor(struct sd *sd) +static int init_ov_sensor(struct sd *sd, __u8 slave) { int i; + if (ov51x_set_slave_ids(sd, slave) < 0) + return -EIO; + /* Reset the sensor */ if (i2c_w(sd, 0x12, 0x80) < 0) return -EIO; @@ -1996,46 +2002,31 @@ static int sd_config(struct gspca_dev *gspca_dev, ov51x_led_control(sd, 0); /* turn LED off */ - /* Test for 76xx */ - if (ov51x_set_slave_ids(sd, OV7xx0_SID) < 0) - goto error; - /* The OV519 must be more aggressive about sensor detection since * I2C write will never fail if the sensor is not present. We have * to try to initialize the sensor to detect its presence */ - if (init_ov_sensor(sd) >= 0) { + + /* Test for 76xx */ + if (init_ov_sensor(sd, OV7xx0_SID) >= 0) { if (ov7xx0_configure(sd) < 0) { PDEBUG(D_ERR, "Failed to configure OV7xx0"); goto error; } - } else { - - /* Test for 6xx0 */ - if (ov51x_set_slave_ids(sd, OV6xx0_SID) < 0) + /* Test for 6xx0 */ + } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) { + if (ov6xx0_configure(sd) < 0) { + PDEBUG(D_ERR, "Failed to configure OV6xx0"); + goto error; + } + /* Test for 8xx0 */ + } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) { + if (ov8xx0_configure(sd) < 0) { + PDEBUG(D_ERR, "Failed to configure OV8xx0"); goto error; - - if (init_ov_sensor(sd) >= 0) { - if (ov6xx0_configure(sd) < 0) { - PDEBUG(D_ERR, "Failed to configure OV6xx0"); - goto error; - } - } else { - - /* Test for 8xx0 */ - if (ov51x_set_slave_ids(sd, OV8xx0_SID) < 0) - goto error; - - if (init_ov_sensor(sd) < 0) { - PDEBUG(D_ERR, - "Can't determine sensor slave IDs"); - goto error; - } - if (ov8xx0_configure(sd) < 0) { - PDEBUG(D_ERR, - "Failed to configure OV8xx0 sensor"); - goto error; - } } + } else { + PDEBUG(D_ERR, "Can't determine sensor slave IDs"); + goto error; } cam = &gspca_dev->cam; -- cgit v1.2.3-70-g09d2 From 635118d5b19c4ad562d425a3f3491c721d6a8293 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 11 Oct 2009 09:49:03 -0300 Subject: V4L/DVB (13144): gspca_ov519: Add support for OV2610 and OV3610 sensors This patch adds support for the OV2610 and OV3610 sensors to the gspca ov519 subdriver. This is a preparation patch for adding ovfx2 bridge support. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov519.c | 892 +++++++++++++++++++++++++++++++++++++- 1 file changed, 882 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index bb9976dc1e2..bfc88360132 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -58,6 +58,7 @@ struct sd { #define BRIDGE_OV518 2 #define BRIDGE_OV518PLUS 3 #define BRIDGE_OV519 4 +#define BRIDGE_OVFX2 5 #define BRIDGE_MASK 7 char invert_led; @@ -81,15 +82,17 @@ struct sd { char sensor; /* Type of image sensor chip (SEN_*) */ #define SEN_UNKNOWN 0 -#define SEN_OV6620 1 -#define SEN_OV6630 2 -#define SEN_OV66308AF 3 -#define SEN_OV7610 4 -#define SEN_OV7620 5 -#define SEN_OV7640 6 -#define SEN_OV7670 7 -#define SEN_OV76BE 8 -#define SEN_OV8610 9 +#define SEN_OV2610 1 +#define SEN_OV3610 2 +#define SEN_OV6620 3 +#define SEN_OV6630 4 +#define SEN_OV66308AF 5 +#define SEN_OV7610 6 +#define SEN_OV7620 7 +#define SEN_OV7640 8 +#define SEN_OV7670 9 +#define SEN_OV76BE 10 +#define SEN_OV8610 11 }; /* V4L2 controls supported by the driver */ @@ -345,6 +348,70 @@ static const struct v4l2_pix_format ov511_sif_mode[] = { .priv = 0}, }; +static const struct v4l2_pix_format ovfx2_vga_mode[] = { + {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1}, + {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, +}; +static const struct v4l2_pix_format ovfx2_cif_mode[] = { + {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 160, + .sizeimage = 160 * 120, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 3}, + {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 176, + .sizeimage = 176 * 144, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1}, + {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 2}, + {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 352, + .sizeimage = 352 * 288, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, +}; +static const struct v4l2_pix_format ovfx2_ov2610_mode[] = { + {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 1600, + .sizeimage = 1600 * 1200, + .colorspace = V4L2_COLORSPACE_SRGB}, +}; +static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { + {2080, 1544, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 2080, + .sizeimage = 2080 * 1544, + .colorspace = V4L2_COLORSPACE_SRGB}, + {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 1600, + .sizeimage = 1600 * 1200, + .colorspace = V4L2_COLORSPACE_SRGB}, + {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 1024, + .sizeimage = 1024 * 768, + .colorspace = V4L2_COLORSPACE_SRGB}, + {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 800, + .sizeimage = 800 * 600, + .colorspace = V4L2_COLORSPACE_SRGB}, + {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480, + .colorspace = V4L2_COLORSPACE_SRGB}, +}; + + /* Registers common to OV511 / OV518 */ #define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */ #define R51x_SYS_RESET 0x50 @@ -509,6 +576,696 @@ struct ov_i2c_regvals { __u8 val; }; +/* Settings for OV2610 camera chip */ +static const struct ov_i2c_regvals norm_2610[] = +{ + { 0x10, 0x80 }, /* reset */ +}; + +static const struct ov_i2c_regvals norm_3620b[] = +{ + /* + * From the datasheet: "Note that after writing to register COMH + * (0x12) to change the sensor mode, registers related to the + * sensor’s cropping window will be reset back to their default + * values." + * + * "wait 4096 external clock ... to make sure the sensor is + * stable and ready to access registers" i.e. 160us at 24MHz + */ + + { 0x12, 0x80 }, /* COMH reset */ + { 0x12, 0x00 }, /* QXGA, master */ + + /* + * 11 CLKRC "Clock Rate Control" + * [7] internal frequency doublers: on + * [6] video port mode: master + * [5:0] clock divider: 1 + */ + { 0x11, 0x80 }, + + /* + * 13 COMI "Common Control I" + * = 192 (0xC0) 11000000 + * COMI[7] "AEC speed selection" + * = 1 (0x01) 1....... "Faster AEC correction" + * COMI[6] "AEC speed step selection" + * = 1 (0x01) .1...... "Big steps, fast" + * COMI[5] "Banding filter on off" + * = 0 (0x00) ..0..... "Off" + * COMI[4] "Banding filter option" + * = 0 (0x00) ...0.... "Main clock is 48 MHz and + * the PLL is ON" + * COMI[3] "Reserved" + * = 0 (0x00) ....0... + * COMI[2] "AGC auto manual control selection" + * = 0 (0x00) .....0.. "Manual" + * COMI[1] "AWB auto manual control selection" + * = 0 (0x00) ......0. "Manual" + * COMI[0] "Exposure control" + * = 0 (0x00) .......0 "Manual" + */ + { 0x13, 0xC0 }, + + /* + * 09 COMC "Common Control C" + * = 8 (0x08) 00001000 + * COMC[7:5] "Reserved" + * = 0 (0x00) 000..... + * COMC[4] "Sleep Mode Enable" + * = 0 (0x00) ...0.... "Normal mode" + * COMC[3:2] "Sensor sampling reset timing selection" + * = 2 (0x02) ....10.. "Longer reset time" + * COMC[1:0] "Output drive current select" + * = 0 (0x00) ......00 "Weakest" + */ + { 0x09, 0x08 }, + + /* + * 0C COMD "Common Control D" + * = 8 (0x08) 00001000 + * COMD[7] "Reserved" + * = 0 (0x00) 0....... + * COMD[6] "Swap MSB and LSB at the output port" + * = 0 (0x00) .0...... "False" + * COMD[5:3] "Reserved" + * = 1 (0x01) ..001... + * COMD[2] "Output Average On Off" + * = 0 (0x00) .....0.. "Output Normal" + * COMD[1] "Sensor precharge voltage selection" + * = 0 (0x00) ......0. "Selects internal + * reference precharge + * voltage" + * COMD[0] "Snapshot option" + * = 0 (0x00) .......0 "Enable live video output + * after snapshot sequence" + */ + { 0x0c, 0x08 }, + + /* + * 0D COME "Common Control E" + * = 161 (0xA1) 10100001 + * COME[7] "Output average option" + * = 1 (0x01) 1....... "Output average of 4 pixels" + * COME[6] "Anti-blooming control" + * = 0 (0x00) .0...... "Off" + * COME[5:3] "Reserved" + * = 4 (0x04) ..100... + * COME[2] "Clock output power down pin status" + * = 0 (0x00) .....0.. "Tri-state data output pin + * on power down" + * COME[1] "Data output pin status selection at power down" + * = 0 (0x00) ......0. "Tri-state VSYNC, PCLK, + * HREF, and CHSYNC pins on + * power down" + * COME[0] "Auto zero circuit select" + * = 1 (0x01) .......1 "On" + */ + { 0x0d, 0xA1 }, + + /* + * 0E COMF "Common Control F" + * = 112 (0x70) 01110000 + * COMF[7] "System clock selection" + * = 0 (0x00) 0....... "Use 24 MHz system clock" + * COMF[6:4] "Reserved" + * = 7 (0x07) .111.... + * COMF[3] "Manual auto negative offset canceling selection" + * = 0 (0x00) ....0... "Auto detect negative + * offset and cancel it" + * COMF[2:0] "Reserved" + * = 0 (0x00) .....000 + */ + { 0x0e, 0x70 }, + + /* + * 0F COMG "Common Control G" + * = 66 (0x42) 01000010 + * COMG[7] "Optical black output selection" + * = 0 (0x00) 0....... "Disable" + * COMG[6] "Black level calibrate selection" + * = 1 (0x01) .1...... "Use optical black pixels + * to calibrate" + * COMG[5:4] "Reserved" + * = 0 (0x00) ..00.... + * COMG[3] "Channel offset adjustment" + * = 0 (0x00) ....0... "Disable offset adjustment" + * COMG[2] "ADC black level calibration option" + * = 0 (0x00) .....0.. "Use B/G line and G/R + * line to calibrate each + * channel's black level" + * COMG[1] "Reserved" + * = 1 (0x01) ......1. + * COMG[0] "ADC black level calibration enable" + * = 0 (0x00) .......0 "Disable" + */ + { 0x0f, 0x42 }, + + /* + * 14 COMJ "Common Control J" + * = 198 (0xC6) 11000110 + * COMJ[7:6] "AGC gain ceiling" + * = 3 (0x03) 11...... "8x" + * COMJ[5:4] "Reserved" + * = 0 (0x00) ..00.... + * COMJ[3] "Auto banding filter" + * = 0 (0x00) ....0... "Banding filter is always + * on off depending on + * COMI[5] setting" + * COMJ[2] "VSYNC drop option" + * = 1 (0x01) .....1.. "SYNC is dropped if frame + * data is dropped" + * COMJ[1] "Frame data drop" + * = 1 (0x01) ......1. "Drop frame data if + * exposure is not within + * tolerance. In AEC mode, + * data is normally dropped + * when data is out of + * range." + * COMJ[0] "Reserved" + * = 0 (0x00) .......0 + */ + { 0x14, 0xC6 }, + + /* + * 15 COMK "Common Control K" + * = 2 (0x02) 00000010 + * COMK[7] "CHSYNC pin output swap" + * = 0 (0x00) 0....... "CHSYNC" + * COMK[6] "HREF pin output swap" + * = 0 (0x00) .0...... "HREF" + * COMK[5] "PCLK output selection" + * = 0 (0x00) ..0..... "PCLK always output" + * COMK[4] "PCLK edge selection" + * = 0 (0x00) ...0.... "Data valid on falling edge" + * COMK[3] "HREF output polarity" + * = 0 (0x00) ....0... "positive" + * COMK[2] "Reserved" + * = 0 (0x00) .....0.. + * COMK[1] "VSYNC polarity" + * = 1 (0x01) ......1. "negative" + * COMK[0] "HSYNC polarity" + * = 0 (0x00) .......0 "positive" + */ + { 0x15, 0x02 }, + + /* + * 33 CHLF "Current Control" + * = 9 (0x09) 00001001 + * CHLF[7:6] "Sensor current control" + * = 0 (0x00) 00...... + * CHLF[5] "Sensor current range control" + * = 0 (0x00) ..0..... "normal range" + * CHLF[4] "Sensor current" + * = 0 (0x00) ...0.... "normal current" + * CHLF[3] "Sensor buffer current control" + * = 1 (0x01) ....1... "half current" + * CHLF[2] "Column buffer current control" + * = 0 (0x00) .....0.. "normal current" + * CHLF[1] "Analog DSP current control" + * = 0 (0x00) ......0. "normal current" + * CHLF[1] "ADC current control" + * = 0 (0x00) ......0. "normal current" + */ + { 0x33, 0x09 }, + + /* + * 34 VBLM "Blooming Control" + * = 80 (0x50) 01010000 + * VBLM[7] "Hard soft reset switch" + * = 0 (0x00) 0....... "Hard reset" + * VBLM[6:4] "Blooming voltage selection" + * = 5 (0x05) .101.... + * VBLM[3:0] "Sensor current control" + * = 0 (0x00) ....0000 + */ + { 0x34, 0x50 }, + + /* + * 36 VCHG "Sensor Precharge Voltage Control" + * = 0 (0x00) 00000000 + * VCHG[7] "Reserved" + * = 0 (0x00) 0....... + * VCHG[6:4] "Sensor precharge voltage control" + * = 0 (0x00) .000.... + * VCHG[3:0] "Sensor array common reference" + * = 0 (0x00) ....0000 + */ + { 0x36, 0x00 }, + + /* + * 37 ADC "ADC Reference Control" + * = 4 (0x04) 00000100 + * ADC[7:4] "Reserved" + * = 0 (0x00) 0000.... + * ADC[3] "ADC input signal range" + * = 0 (0x00) ....0... "Input signal 1.0x" + * ADC[2:0] "ADC range control" + * = 4 (0x04) .....100 + */ + { 0x37, 0x04 }, + + /* + * 38 ACOM "Analog Common Ground" + * = 82 (0x52) 01010010 + * ACOM[7] "Analog gain control" + * = 0 (0x00) 0....... "Gain 1x" + * ACOM[6] "Analog black level calibration" + * = 1 (0x01) .1...... "On" + * ACOM[5:0] "Reserved" + * = 18 (0x12) ..010010 + */ + { 0x38, 0x52 }, + + /* + * 3A FREFA "Internal Reference Adjustment" + * = 0 (0x00) 00000000 + * FREFA[7:0] "Range" + * = 0 (0x00) 00000000 + */ + { 0x3a, 0x00 }, + + /* + * 3C FVOPT "Internal Reference Adjustment" + * = 31 (0x1F) 00011111 + * FVOPT[7:0] "Range" + * = 31 (0x1F) 00011111 + */ + { 0x3c, 0x1F }, + + /* + * 44 Undocumented = 0 (0x00) 00000000 + * 44[7:0] "It's a secret" + * = 0 (0x00) 00000000 + */ + { 0x44, 0x00 }, + + /* + * 40 Undocumented = 0 (0x00) 00000000 + * 40[7:0] "It's a secret" + * = 0 (0x00) 00000000 + */ + { 0x40, 0x00 }, + + /* + * 41 Undocumented = 0 (0x00) 00000000 + * 41[7:0] "It's a secret" + * = 0 (0x00) 00000000 + */ + { 0x41, 0x00 }, + + /* + * 42 Undocumented = 0 (0x00) 00000000 + * 42[7:0] "It's a secret" + * = 0 (0x00) 00000000 + */ + { 0x42, 0x00 }, + + /* + * 43 Undocumented = 0 (0x00) 00000000 + * 43[7:0] "It's a secret" + * = 0 (0x00) 00000000 + */ + { 0x43, 0x00 }, + + /* + * 45 Undocumented = 128 (0x80) 10000000 + * 45[7:0] "It's a secret" + * = 128 (0x80) 10000000 + */ + { 0x45, 0x80 }, + + /* + * 48 Undocumented = 192 (0xC0) 11000000 + * 48[7:0] "It's a secret" + * = 192 (0xC0) 11000000 + */ + { 0x48, 0xC0 }, + + /* + * 49 Undocumented = 25 (0x19) 00011001 + * 49[7:0] "It's a secret" + * = 25 (0x19) 00011001 + */ + { 0x49, 0x19 }, + + /* + * 4B Undocumented = 128 (0x80) 10000000 + * 4B[7:0] "It's a secret" + * = 128 (0x80) 10000000 + */ + { 0x4B, 0x80 }, + + /* + * 4D Undocumented = 196 (0xC4) 11000100 + * 4D[7:0] "It's a secret" + * = 196 (0xC4) 11000100 + */ + { 0x4D, 0xC4 }, + + /* + * 35 VREF "Reference Voltage Control" + * = 76 (0x4C) 01001100 + * VREF[7:5] "Column high reference control" + * = 2 (0x02) 010..... "higher voltage" + * VREF[4:2] "Column low reference control" + * = 3 (0x03) ...011.. "Highest voltage" + * VREF[1:0] "Reserved" + * = 0 (0x00) ......00 + */ + { 0x35, 0x4C }, + + /* + * 3D Undocumented = 0 (0x00) 00000000 + * 3D[7:0] "It's a secret" + * = 0 (0x00) 00000000 + */ + { 0x3D, 0x00 }, + + /* + * 3E Undocumented = 0 (0x00) 00000000 + * 3E[7:0] "It's a secret" + * = 0 (0x00) 00000000 + */ + { 0x3E, 0x00 }, + + /* + * 3B FREFB "Internal Reference Adjustment" + * = 24 (0x18) 00011000 + * FREFB[7:0] "Range" + * = 24 (0x18) 00011000 + */ + { 0x3b, 0x18 }, + + /* + * 33 CHLF "Current Control" + * = 25 (0x19) 00011001 + * CHLF[7:6] "Sensor current control" + * = 0 (0x00) 00...... + * CHLF[5] "Sensor current range control" + * = 0 (0x00) ..0..... "normal range" + * CHLF[4] "Sensor current" + * = 1 (0x01) ...1.... "double current" + * CHLF[3] "Sensor buffer current control" + * = 1 (0x01) ....1... "half current" + * CHLF[2] "Column buffer current control" + * = 0 (0x00) .....0.. "normal current" + * CHLF[1] "Analog DSP current control" + * = 0 (0x00) ......0. "normal current" + * CHLF[1] "ADC current control" + * = 0 (0x00) ......0. "normal current" + */ + { 0x33, 0x19 }, + + /* + * 34 VBLM "Blooming Control" + * = 90 (0x5A) 01011010 + * VBLM[7] "Hard soft reset switch" + * = 0 (0x00) 0....... "Hard reset" + * VBLM[6:4] "Blooming voltage selection" + * = 5 (0x05) .101.... + * VBLM[3:0] "Sensor current control" + * = 10 (0x0A) ....1010 + */ + { 0x34, 0x5A }, + + /* + * 3B FREFB "Internal Reference Adjustment" + * = 0 (0x00) 00000000 + * FREFB[7:0] "Range" + * = 0 (0x00) 00000000 + */ + { 0x3b, 0x00 }, + + /* + * 33 CHLF "Current Control" + * = 9 (0x09) 00001001 + * CHLF[7:6] "Sensor current control" + * = 0 (0x00) 00...... + * CHLF[5] "Sensor current range control" + * = 0 (0x00) ..0..... "normal range" + * CHLF[4] "Sensor current" + * = 0 (0x00) ...0.... "normal current" + * CHLF[3] "Sensor buffer current control" + * = 1 (0x01) ....1... "half current" + * CHLF[2] "Column buffer current control" + * = 0 (0x00) .....0.. "normal current" + * CHLF[1] "Analog DSP current control" + * = 0 (0x00) ......0. "normal current" + * CHLF[1] "ADC current control" + * = 0 (0x00) ......0. "normal current" + */ + { 0x33, 0x09 }, + + /* + * 34 VBLM "Blooming Control" + * = 80 (0x50) 01010000 + * VBLM[7] "Hard soft reset switch" + * = 0 (0x00) 0....... "Hard reset" + * VBLM[6:4] "Blooming voltage selection" + * = 5 (0x05) .101.... + * VBLM[3:0] "Sensor current control" + * = 0 (0x00) ....0000 + */ + { 0x34, 0x50 }, + + /* + * 12 COMH "Common Control H" + * = 64 (0x40) 01000000 + * COMH[7] "SRST" + * = 0 (0x00) 0....... "No-op" + * COMH[6:4] "Resolution selection" + * = 4 (0x04) .100.... "XGA" + * COMH[3] "Master slave selection" + * = 0 (0x00) ....0... "Master mode" + * COMH[2] "Internal B/R channel option" + * = 0 (0x00) .....0.. "B/R use same channel" + * COMH[1] "Color bar test pattern" + * = 0 (0x00) ......0. "Off" + * COMH[0] "Reserved" + * = 0 (0x00) .......0 + */ + { 0x12, 0x40 }, + + /* + * 17 HREFST "Horizontal window start" + * = 31 (0x1F) 00011111 + * HREFST[7:0] "Horizontal window start, 8 MSBs" + * = 31 (0x1F) 00011111 + */ + { 0x17, 0x1F }, + + /* + * 18 HREFEND "Horizontal window end" + * = 95 (0x5F) 01011111 + * HREFEND[7:0] "Horizontal Window End, 8 MSBs" + * = 95 (0x5F) 01011111 + */ + { 0x18, 0x5F }, + + /* + * 19 VSTRT "Vertical window start" + * = 0 (0x00) 00000000 + * VSTRT[7:0] "Vertical Window Start, 8 MSBs" + * = 0 (0x00) 00000000 + */ + { 0x19, 0x00 }, + + /* + * 1A VEND "Vertical window end" + * = 96 (0x60) 01100000 + * VEND[7:0] "Vertical Window End, 8 MSBs" + * = 96 (0x60) 01100000 + */ + { 0x1a, 0x60 }, + + /* + * 32 COMM "Common Control M" + * = 18 (0x12) 00010010 + * COMM[7:6] "Pixel clock divide option" + * = 0 (0x00) 00...... "/1" + * COMM[5:3] "Horizontal window end position, 3 LSBs" + * = 2 (0x02) ..010... + * COMM[2:0] "Horizontal window start position, 3 LSBs" + * = 2 (0x02) .....010 + */ + { 0x32, 0x12 }, + + /* + * 03 COMA "Common Control A" + * = 74 (0x4A) 01001010 + * COMA[7:4] "AWB Update Threshold" + * = 4 (0x04) 0100.... + * COMA[3:2] "Vertical window end line control 2 LSBs" + * = 2 (0x02) ....10.. + * COMA[1:0] "Vertical window start line control 2 LSBs" + * = 2 (0x02) ......10 + */ + { 0x03, 0x4A }, + + /* + * 11 CLKRC "Clock Rate Control" + * = 128 (0x80) 10000000 + * CLKRC[7] "Internal frequency doublers on off seclection" + * = 1 (0x01) 1....... "On" + * CLKRC[6] "Digital video master slave selection" + * = 0 (0x00) .0...... "Master mode, sensor + * provides PCLK" + * CLKRC[5:0] "Clock divider { CLK = PCLK/(1+CLKRC[5:0]) }" + * = 0 (0x00) ..000000 + */ + { 0x11, 0x80 }, + + /* + * 12 COMH "Common Control H" + * = 0 (0x00) 00000000 + * COMH[7] "SRST" + * = 0 (0x00) 0....... "No-op" + * COMH[6:4] "Resolution selection" + * = 0 (0x00) .000.... "QXGA" + * COMH[3] "Master slave selection" + * = 0 (0x00) ....0... "Master mode" + * COMH[2] "Internal B/R channel option" + * = 0 (0x00) .....0.. "B/R use same channel" + * COMH[1] "Color bar test pattern" + * = 0 (0x00) ......0. "Off" + * COMH[0] "Reserved" + * = 0 (0x00) .......0 + */ + { 0x12, 0x00 }, + + /* + * 12 COMH "Common Control H" + * = 64 (0x40) 01000000 + * COMH[7] "SRST" + * = 0 (0x00) 0....... "No-op" + * COMH[6:4] "Resolution selection" + * = 4 (0x04) .100.... "XGA" + * COMH[3] "Master slave selection" + * = 0 (0x00) ....0... "Master mode" + * COMH[2] "Internal B/R channel option" + * = 0 (0x00) .....0.. "B/R use same channel" + * COMH[1] "Color bar test pattern" + * = 0 (0x00) ......0. "Off" + * COMH[0] "Reserved" + * = 0 (0x00) .......0 + */ + { 0x12, 0x40 }, + + /* + * 17 HREFST "Horizontal window start" + * = 31 (0x1F) 00011111 + * HREFST[7:0] "Horizontal window start, 8 MSBs" + * = 31 (0x1F) 00011111 + */ + { 0x17, 0x1F }, + + /* + * 18 HREFEND "Horizontal window end" + * = 95 (0x5F) 01011111 + * HREFEND[7:0] "Horizontal Window End, 8 MSBs" + * = 95 (0x5F) 01011111 + */ + { 0x18, 0x5F }, + + /* + * 19 VSTRT "Vertical window start" + * = 0 (0x00) 00000000 + * VSTRT[7:0] "Vertical Window Start, 8 MSBs" + * = 0 (0x00) 00000000 + */ + { 0x19, 0x00 }, + + /* + * 1A VEND "Vertical window end" + * = 96 (0x60) 01100000 + * VEND[7:0] "Vertical Window End, 8 MSBs" + * = 96 (0x60) 01100000 + */ + { 0x1a, 0x60 }, + + /* + * 32 COMM "Common Control M" + * = 18 (0x12) 00010010 + * COMM[7:6] "Pixel clock divide option" + * = 0 (0x00) 00...... "/1" + * COMM[5:3] "Horizontal window end position, 3 LSBs" + * = 2 (0x02) ..010... + * COMM[2:0] "Horizontal window start position, 3 LSBs" + * = 2 (0x02) .....010 + */ + { 0x32, 0x12 }, + + /* + * 03 COMA "Common Control A" + * = 74 (0x4A) 01001010 + * COMA[7:4] "AWB Update Threshold" + * = 4 (0x04) 0100.... + * COMA[3:2] "Vertical window end line control 2 LSBs" + * = 2 (0x02) ....10.. + * COMA[1:0] "Vertical window start line control 2 LSBs" + * = 2 (0x02) ......10 + */ + { 0x03, 0x4A }, + + /* + * 02 RED "Red Gain Control" + * = 175 (0xAF) 10101111 + * RED[7] "Action" + * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))" + * RED[6:0] "Value" + * = 47 (0x2F) .0101111 + */ + { 0x02, 0xAF }, + + /* + * 2D ADDVSL "VSYNC Pulse Width" + * = 210 (0xD2) 11010010 + * ADDVSL[7:0] "VSYNC pulse width, LSB" + * = 210 (0xD2) 11010010 + */ + { 0x2d, 0xD2 }, + + /* + * 00 GAIN = 24 (0x18) 00011000 + * GAIN[7:6] "Reserved" + * = 0 (0x00) 00...... + * GAIN[5] "Double" + * = 0 (0x00) ..0..... "False" + * GAIN[4] "Double" + * = 1 (0x01) ...1.... "True" + * GAIN[3:0] "Range" + * = 8 (0x08) ....1000 + */ + { 0x00, 0x18 }, + + /* + * 01 BLUE "Blue Gain Control" + * = 240 (0xF0) 11110000 + * BLUE[7] "Action" + * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))" + * BLUE[6:0] "Value" + * = 112 (0x70) .1110000 + */ + { 0x01, 0xF0 }, + + /* + * 10 AEC "Automatic Exposure Control" + * = 10 (0x0A) 00001010 + * AEC[7:0] "Automatic Exposure Control, 8 MSBs" + * = 10 (0x0A) 00001010 + */ + { 0x10, 0x0A }, + + { 0xE1, 0x67 }, + { 0xE3, 0x03 }, + { 0xE4, 0x26 }, + { 0xE5, 0x3E }, + { 0xF8, 0x01 }, + { 0xFF, 0x01 }, +}; + static const struct ov_i2c_regvals norm_6x20[] = { { 0x12, 0x80 }, /* reset */ { 0x11, 0x01 }, @@ -1514,6 +2271,39 @@ static int write_i2c_regvals(struct sd *sd, * ***************************************************************************/ +/* This initializes the OV2x10 / OV3610 / OV3620 */ +static int ov_hires_configure(struct sd *sd) +{ + int high, low; + + if (sd->bridge != BRIDGE_OVFX2) { + PDEBUG(D_ERR, "error hires sensors only supported with ovfx2"); + return -1; + } + + PDEBUG(D_PROBE, "starting ov hires configuration"); + + /* Detect sensor (sub)type */ + high = i2c_r(sd, 0x0a); + low = i2c_r(sd, 0x0b); + /* info("%x, %x", high, low); */ + if (high == 0x96 && low == 0x40) { + PDEBUG(D_PROBE, "Sensor is an OV2610"); + sd->sensor = SEN_OV2610; + } else if (high == 0x36 && (low & 0x0f) == 0x00) { + PDEBUG(D_PROBE, "Sensor is an OV3610"); + sd->sensor = SEN_OV3610; + } else { + PDEBUG(D_ERR, "Error unknown sensor type: 0x%02x%02x", + high, low); + return -1; + } + + /* Set sensor-specific vars */ + return 0; +} + + /* This initializes the OV8110, OV8610 sensor. The OV8110 uses * the same register settings as the OV8610, since they are very similar. */ @@ -2024,6 +2814,12 @@ static int sd_config(struct gspca_dev *gspca_dev, PDEBUG(D_ERR, "Failed to configure OV8xx0"); goto error; } + /* Test for 3xxx / 2xxx */ + } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) { + if (ov_hires_configure(sd) < 0) { + PDEBUG(D_ERR, "Failed to configure high res OV"); + goto error; + } } else { PDEBUG(D_ERR, "Can't determine sensor slave IDs"); goto error; @@ -2060,6 +2856,21 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->nmodes = ARRAY_SIZE(ov519_sif_mode); } break; + case BRIDGE_OVFX2: + if (sd->sensor == SEN_OV2610) { + cam->cam_mode = ovfx2_ov2610_mode; + cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode); + } else if (sd->sensor == SEN_OV3610) { + cam->cam_mode = ovfx2_ov3610_mode; + cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode); + } else if (!sd->sif) { + cam->cam_mode = ov519_vga_mode; + cam->nmodes = ARRAY_SIZE(ov519_vga_mode); + } else { + cam->cam_mode = ov519_sif_mode; + cam->nmodes = ARRAY_SIZE(ov519_sif_mode); + } + break; } sd->brightness = BRIGHTNESS_DEF; if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF) @@ -2083,6 +2894,9 @@ static int sd_config(struct gspca_dev *gspca_dev, /* OV8610 Frequency filter control should work but needs testing */ if (sd->sensor == SEN_OV8610) gspca_dev->ctrl_dis |= 1 << FREQ_IDX; + /* No controls for the OV2610/OV3610 */ + if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) + gspca_dev->ctrl_dis |= 0xFF; return 0; error: @@ -2097,6 +2911,20 @@ static int sd_init(struct gspca_dev *gspca_dev) /* initialize the sensor */ switch (sd->sensor) { + case SEN_OV2610: + if (write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610))) + return -EIO; + /* Enable autogain, autoexpo, awb, bandfilter */ + if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0) + return -EIO; + break; + case SEN_OV3610: + if (write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b))) + return -EIO; + /* Enable autogain, autoexpo, awb, bandfilter */ + if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0) + return -EIO; + break; case SEN_OV6620: if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20))) return -EIO; @@ -2546,6 +3374,42 @@ static int mode_init_ov_sensor_regs(struct sd *sd) /******** Mode (VGA/QVGA) and sensor specific regs ********/ switch (sd->sensor) { + case SEN_OV2610: + i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); + i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); + i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); + i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); + i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); + i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); + i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); + return 0; + case SEN_OV3610: { + int xstart, xend, ystart, yend; + + if (qvga) { + xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4); + ystart = (772 - gspca_dev->height) / 2; + } else { + xstart = (2080 - gspca_dev->width) / 2 + (0x10 << 4); + ystart = (1544 - gspca_dev->height) / 2; + } + xend = xstart + gspca_dev->width; + yend = ystart + gspca_dev->height; + /* Writing to the COMH register resets the other windowing regs + to their default values, so we must do this first. */ + i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0); + i2c_w_mask(sd, 0x32, + (((xend >> 1) & 7) << 3) | ((xstart >> 1) & 7), + 0x3f); + i2c_w_mask(sd, 0x03, + (((yend >> 1) & 3) << 2) | ((ystart >> 1) & 3), + 0x0f); + i2c_w(sd, 0x17, xstart >> 4); + i2c_w(sd, 0x18, xend >> 4); + i2c_w(sd, 0x19, ystart >> 3); + i2c_w(sd, 0x1a, yend >> 3); + return 0; + } case SEN_OV8610: /* For OV8610 qvga means qsvga */ i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5); @@ -2653,6 +3517,10 @@ static int set_ov_sensor_window(struct sd *sd) int ret, hstart, hstop, vstop, vstart; __u8 v; + /* mode setup is fully handled in mode_init_ov_sensor_regs for these */ + if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) + return mode_init_ov_sensor_regs(sd); + gspca_dev = &sd->gspca_dev; qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1; crop = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 2; @@ -3115,7 +3983,8 @@ static void setcolors(struct gspca_dev *gspca_dev) static void setautobrightness(struct sd *sd) { - if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670) + if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670 || + sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) return; i2c_w_mask(sd, 0x2d, sd->autobrightness ? 0x10 : 0x00, 0x10); @@ -3123,6 +3992,9 @@ static void setautobrightness(struct sd *sd) static void setfreq(struct sd *sd) { + if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) + return; + if (sd->sensor == SEN_OV7670) { switch (sd->freq) { case 0: /* Banding filter disabled */ -- cgit v1.2.3-70-g09d2 From b46aaa02648cd8c1ebc20191304e2f6a2382d04c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 12 Oct 2009 10:07:57 -0300 Subject: V4L/DVB (13145): gscpa_ov519: add support for the ovfx2 bridge gscpa_ov519: add support for the ovfx2 bridge Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov519.c | 206 +++++++++++++++++++++++++++++++++----- 1 file changed, 181 insertions(+), 25 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index bfc88360132..30e91c365ea 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -2,14 +2,19 @@ * OV519 driver * * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr) + * Copyright (C) 2009 Hans de Goede * * This module is adapted from the ov51x-jpeg package, which itself * was adapted from the ov511 driver. * * Original copyright for the ov511 driver is: * - * Copyright (c) 1999-2004 Mark W. McClelland + * Copyright (c) 1999-2006 Mark W. McClelland * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach + * Many improvements by Bret Wallach + * Color fixes by by Orion Sky Lawlor (2/26/2000) + * OV7620 fixes by Charl P. Botha + * Changes by Claudio Matsuoka * * ov51x-jpeg original copyright is: * @@ -389,26 +394,31 @@ static const struct v4l2_pix_format ovfx2_ov2610_mode[] = { .colorspace = V4L2_COLORSPACE_SRGB}, }; static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { - {2080, 1544, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 2080, - .sizeimage = 2080 * 1544, - .colorspace = V4L2_COLORSPACE_SRGB}, - {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 1600, - .sizeimage = 1600 * 1200, - .colorspace = V4L2_COLORSPACE_SRGB}, - {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 1024, - .sizeimage = 1024 * 768, - .colorspace = V4L2_COLORSPACE_SRGB}, - {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 800, - .sizeimage = 800 * 600, - .colorspace = V4L2_COLORSPACE_SRGB}, {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, .bytesperline = 640, .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB}, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1}, + {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 800, + .sizeimage = 800 * 600, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1}, + {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 1024, + .sizeimage = 1024 * 768, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1}, + {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 1600, + .sizeimage = 1600 * 1200, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, + {2048, 1536, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 2048, + .sizeimage = 2048 * 1536, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, }; @@ -473,6 +483,30 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { #define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */ +/* + * The FX2 chip does not give us a zero length read at end of frame. + * It does, however, give a short read at the end of a frame, if + * neccessary, rather than run two frames together. + * + * By choosing the right bulk transfer size, we are guaranteed to always + * get a short read for the last read of each frame. Frame sizes are + * always a composite number (width * height, or a multiple) so if we + * choose a prime number, we are guaranteed that the last read of a + * frame will be short. + * + * But it isn't that easy: the 2.6 kernel requires a multiple of 4KB, + * otherwise EOVERFLOW "babbling" errors occur. I have not been able + * to figure out why. [PMiller] + * + * The constant (13 * 4096) is the largest "prime enough" number less than 64KB. + * + * It isn't enough to know the number of bytes per frame, in case we + * have data dropouts or buffer overruns (even though the FX2 double + * buffers, there are some pretty strict real time constraints for + * isochronous transfer for larger frame sizes). + */ +#define OVFX2_BULK_SIZE (13 * 4096) + /* I2C registers */ #define R51x_I2C_W_SID 0x41 #define R51x_I2C_SADDR_3 0x42 @@ -480,6 +514,7 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { #define R51x_I2C_R_SID 0x44 #define R51x_I2C_DATA 0x45 #define R518_I2C_CTL 0x47 /* OV518(+) only */ +#define OVFX2_I2C_ADDR 0x00 /* I2C ADDRESSES */ #define OV7xx0_SID 0x42 @@ -579,7 +614,7 @@ struct ov_i2c_regvals { /* Settings for OV2610 camera chip */ static const struct ov_i2c_regvals norm_2610[] = { - { 0x10, 0x80 }, /* reset */ + { 0x12, 0x80 }, /* reset */ }; static const struct ov_i2c_regvals norm_3620b[] = @@ -1803,7 +1838,23 @@ static unsigned char ov7670_abs_to_sm(unsigned char v) static int reg_w(struct sd *sd, __u16 index, __u8 value) { int ret; - int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 2 : 1; + int req; + + switch (sd->bridge) { + case BRIDGE_OV511: + case BRIDGE_OV511PLUS: + req = 2; + break; + case BRIDGE_OVFX2: + ret = usb_control_msg(sd->gspca_dev.dev, + usb_sndctrlpipe(sd->gspca_dev.dev, 0), + 0x0a, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + (__u16)value, index, NULL, 0, 500); + goto leave; + default: + req = 1; + } sd->gspca_dev.usb_buf[0] = value; ret = usb_control_msg(sd->gspca_dev.dev, @@ -1812,6 +1863,7 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, index, sd->gspca_dev.usb_buf, 1, 500); +leave: if (ret < 0) PDEBUG(D_ERR, "Write reg [%02x] %02x failed", index, value); return ret; @@ -1822,7 +1874,19 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value) static int reg_r(struct sd *sd, __u16 index) { int ret; - int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 3 : 1; + int req; + + switch (sd->bridge) { + case BRIDGE_OV511: + case BRIDGE_OV511PLUS: + req = 3; + break; + case BRIDGE_OVFX2: + req = 0x0b; + break; + default: + req = 1; + } ret = usb_control_msg(sd->gspca_dev.dev, usb_rcvctrlpipe(sd->gspca_dev.dev, 0), @@ -2082,6 +2146,43 @@ static int ov518_i2c_r(struct sd *sd, __u8 reg) return value; } +static int ovfx2_i2c_w(struct sd *sd, __u8 reg, __u8 value) +{ + int ret; + + ret = usb_control_msg(sd->gspca_dev.dev, + usb_sndctrlpipe(sd->gspca_dev.dev, 0), + 0x02, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + (__u16)value, (__u16)reg, NULL, 0, 500); + + if (ret >= 0) + PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg); + else + PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg); + + return ret; +} + +static int ovfx2_i2c_r(struct sd *sd, __u8 reg) +{ + int ret; + + ret = usb_control_msg(sd->gspca_dev.dev, + usb_rcvctrlpipe(sd->gspca_dev.dev, 0), + 0x03, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, (__u16)reg, sd->gspca_dev.usb_buf, 1, 500); + + if (ret >= 0) { + ret = sd->gspca_dev.usb_buf[0]; + PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, ret); + } else + PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg); + + return ret; +} + static int i2c_w(struct sd *sd, __u8 reg, __u8 value) { switch (sd->bridge) { @@ -2092,6 +2193,8 @@ static int i2c_w(struct sd *sd, __u8 reg, __u8 value) case BRIDGE_OV518PLUS: case BRIDGE_OV519: return ov518_i2c_w(sd, reg, value); + case BRIDGE_OVFX2: + return ovfx2_i2c_w(sd, reg, value); } return -1; /* Should never happen */ } @@ -2106,6 +2209,8 @@ static int i2c_r(struct sd *sd, __u8 reg) case BRIDGE_OV518PLUS: case BRIDGE_OV519: return ov518_i2c_r(sd, reg); + case BRIDGE_OVFX2: + return ovfx2_i2c_r(sd, reg); } return -1; /* Should never happen */ } @@ -2147,6 +2252,8 @@ static inline int ov51x_stop(struct sd *sd) return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a); case BRIDGE_OV519: return reg_w(sd, OV519_SYS_RESET1, 0x0f); + case BRIDGE_OVFX2: + return reg_w_mask(sd, 0x0f, 0x00, 0x02); } return 0; @@ -2176,6 +2283,8 @@ static inline int ov51x_restart(struct sd *sd) return reg_w(sd, R51x_SYS_RESET, 0x00); case BRIDGE_OV519: return reg_w(sd, OV519_SYS_RESET1, 0x00); + case BRIDGE_OVFX2: + return reg_w_mask(sd, 0x0f, 0x02, 0x02); } return 0; @@ -2229,6 +2338,9 @@ static int ov51x_set_slave_ids(struct sd *sd, { int rc; + if (sd->bridge == BRIDGE_OVFX2) + return reg_w(sd, OVFX2_I2C_ADDR, slave); + rc = reg_w(sd, R51x_I2C_W_SID, slave); if (rc < 0) return rc; @@ -2762,12 +2874,29 @@ static int ov519_configure(struct sd *sd) return write_regvals(sd, init_519, ARRAY_SIZE(init_519)); } +static int ovfx2_configure(struct sd *sd) +{ + static const struct ov_regvals init_fx2[] = { + { 0x00, 0x60 }, + { 0x02, 0x01 }, + { 0x0f, 0x1d }, + { 0xe9, 0x82 }, + { 0xea, 0xc7 }, + { 0xeb, 0x10 }, + { 0xec, 0xf6 }, + }; + + sd->stopped = 1; + + return write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2)); +} + /* this function is called at probe time */ static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id) { struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; + struct cam *cam = &gspca_dev->cam; int ret = 0; sd->bridge = id->driver_info & BRIDGE_MASK; @@ -2785,6 +2914,12 @@ static int sd_config(struct gspca_dev *gspca_dev, case BRIDGE_OV519: ret = ov519_configure(sd); break; + case BRIDGE_OVFX2: + ret = ovfx2_configure(sd); + cam->bulk_size = OVFX2_BULK_SIZE; + cam->bulk_nurbs = MAX_NURBS; + cam->bulk = 1; + break; } if (ret) @@ -2825,7 +2960,6 @@ static int sd_config(struct gspca_dev *gspca_dev, goto error; } - cam = &gspca_dev->cam; switch (sd->bridge) { case BRIDGE_OV511: case BRIDGE_OV511PLUS: @@ -3388,9 +3522,9 @@ static int mode_init_ov_sensor_regs(struct sd *sd) if (qvga) { xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4); - ystart = (772 - gspca_dev->height) / 2; + ystart = (776 - gspca_dev->height) / 2; } else { - xstart = (2080 - gspca_dev->width) / 2 + (0x10 << 4); + xstart = (2076 - gspca_dev->width) / 2 + (0x10 << 4); ystart = (1544 - gspca_dev->height) / 2; } xend = xstart + gspca_dev->width; @@ -3685,6 +3819,7 @@ static int sd_start(struct gspca_dev *gspca_dev) case BRIDGE_OV519: ret = ov519_mode_init_regs(sd); break; + /* case BRIDGE_OVFX2: nothing to do */ } if (ret < 0) goto out; @@ -3850,6 +3985,20 @@ static void ov519_pkt_scan(struct gspca_dev *gspca_dev, data, len); } +static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + __u8 *data, /* isoc packet */ + int len) /* iso packet length */ +{ + /* A short read signals EOF */ + if (len < OVFX2_BULK_SIZE) { + gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0); + return; + } + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); +} + static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ __u8 *data, /* isoc packet */ @@ -3869,6 +4018,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, case BRIDGE_OV519: ov519_pkt_scan(gspca_dev, frame, data, len); break; + case BRIDGE_OVFX2: + ovfx2_pkt_scan(gspca_dev, frame, data, len); + break; } } @@ -4237,11 +4389,15 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 }, {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 }, {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 }, + {USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 }, {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 }, {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 }, {USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS }, {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS }, {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS }, + {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 }, + {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 }, + {USB_DEVICE(0x8020, 0xEF04), .driver_info = BRIDGE_OVFX2 }, {} }; -- cgit v1.2.3-70-g09d2 From ebbb5c3e0eb73db4da5bee57cd0344a74cf73319 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 12 Oct 2009 11:32:44 -0300 Subject: V4L/DVB (13146): gspca_ov519: cleanup sensor handling There were various "if (sensor == foo)" pieces of code inside ov519.c, move these bits to the sensor specific init functions, where they belong. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov519.c | 159 ++++++++++++++------------------------ 1 file changed, 59 insertions(+), 100 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 30e91c365ea..4d6a762a6f3 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -3501,7 +3501,8 @@ static int ov519_mode_init_regs(struct sd *sd) static int mode_init_ov_sensor_regs(struct sd *sd) { struct gspca_dev *gspca_dev; - int qvga; + int qvga, xstart, xend, ystart, yend; + __u8 v; gspca_dev = &sd->gspca_dev; qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1; @@ -3517,9 +3518,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd) i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); return 0; - case SEN_OV3610: { - int xstart, xend, ystart, yend; - + case SEN_OV3610: if (qvga) { xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4); ystart = (776 - gspca_dev->height) / 2; @@ -3543,13 +3542,19 @@ static int mode_init_ov_sensor_regs(struct sd *sd) i2c_w(sd, 0x19, ystart >> 3); i2c_w(sd, 0x1a, yend >> 3); return 0; - } case SEN_OV8610: /* For OV8610 qvga means qsvga */ i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5); + i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ + i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ + i2c_w_mask(sd, 0x2d, 0x00, 0x40); /* from windrv 090403 */ + i2c_w_mask(sd, 0x28, 0x20, 0x20); /* progressive mode on */ break; case SEN_OV7610: i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); + i2c_w(sd, 0x35, qvga?0x1e:0x9e); + i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ + i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ break; case SEN_OV7620: case SEN_OV76BE: @@ -3560,6 +3565,10 @@ static int mode_init_ov_sensor_regs(struct sd *sd) i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0); i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); + i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ + i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ + if (sd->sensor == SEN_OV76BE) + i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e); break; case SEN_OV7640: i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); @@ -3569,6 +3578,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd) /* i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */ /* i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */ /* i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */ + i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */ break; case SEN_OV7670: /* set COM7_FMT_VGA or COM7_FMT_QVGA @@ -3577,55 +3587,56 @@ static int mode_init_ov_sensor_regs(struct sd *sd) i2c_w_mask(sd, OV7670_REG_COM7, qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA, OV7670_COM7_FMT_MASK); + i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ + i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB, + OV7670_COM8_AWB); + if (qvga) { /* QVGA from ov7670.c by + * Jonathan Corbet */ + xstart = 164; + xend = 28; + ystart = 14; + yend = 494; + } else { /* VGA */ + xstart = 158; + xend = 14; + ystart = 10; + yend = 490; + } + /* OV7670 hardware window registers are split across + * multiple locations */ + i2c_w(sd, OV7670_REG_HSTART, xstart >> 3); + i2c_w(sd, OV7670_REG_HSTOP, xend >> 3); + v = i2c_r(sd, OV7670_REG_HREF); + v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07); + msleep(10); /* need to sleep between read and write to + * same reg! */ + i2c_w(sd, OV7670_REG_HREF, v); + + i2c_w(sd, OV7670_REG_VSTART, ystart >> 2); + i2c_w(sd, OV7670_REG_VSTOP, yend >> 2); + v = i2c_r(sd, OV7670_REG_VREF); + v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03); + msleep(10); /* need to sleep between read and write to + * same reg! */ + i2c_w(sd, OV7670_REG_VREF, v); break; case SEN_OV6620: + i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); + i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ + i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ + break; case SEN_OV6630: case SEN_OV66308AF: i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); + i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ break; default: return -EINVAL; } - /******** Palette-specific regs ********/ - - /* The OV518 needs special treatment. Although both the OV518 - * and the OV6630 support a 16-bit video bus, only the 8 bit Y - * bus is actually used. The UV bus is tied to ground. - * Therefore, the OV6630 needs to be in 8-bit multiplexed - * output mode */ - - /* OV7640 is 8-bit only */ - - if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV66308AF && - sd->sensor != SEN_OV7640) - i2c_w_mask(sd, 0x13, 0x00, 0x20); - /******** Clock programming ********/ i2c_w(sd, 0x11, sd->clockdiv); - /******** Special Features ********/ -/* no evidence this is possible with OV7670, either */ - /* Test Pattern */ - if (sd->sensor != SEN_OV7640 && sd->sensor != SEN_OV7670) - i2c_w_mask(sd, 0x12, 0x00, 0x02); - - /* Enable auto white balance */ - if (sd->sensor == SEN_OV7670) - i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB, - OV7670_COM8_AWB); - else - i2c_w_mask(sd, 0x12, 0x04, 0x04); - - /* This will go away as soon as ov51x_mode_init_sensor_regs() */ - /* is fully tested. */ - /* 7620/6620/6630? don't have register 0x35, so play it safe */ - if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { - if (!qvga) - i2c_w(sd, 0x35, 0x9e); - else - i2c_w(sd, 0x35, 0x1e); - } return 0; } @@ -3648,11 +3659,11 @@ static int set_ov_sensor_window(struct sd *sd) struct gspca_dev *gspca_dev; int qvga, crop; int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; - int ret, hstart, hstop, vstop, vstart; - __u8 v; + int ret; /* mode setup is fully handled in mode_init_ov_sensor_regs for these */ - if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) + if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610 || + sd->sensor == SEN_OV7670) return mode_init_ov_sensor_regs(sd); gspca_dev = &sd->gspca_dev; @@ -3701,11 +3712,6 @@ static int set_ov_sensor_window(struct sd *sd) hwebase = 0x1a; vwsbase = vwebase = 0x03; break; - case SEN_OV7670: - /*handling of OV7670 hardware sensor start and stop values - * is very odd, compared to the other OV sensors */ - vwsbase = vwebase = hwebase = hwsbase = 0x00; - break; default: return -EINVAL; } @@ -3746,58 +3752,11 @@ static int set_ov_sensor_window(struct sd *sd) if (ret < 0) return ret; - if (sd->sensor == SEN_OV8610) { - i2c_w_mask(sd, 0x2d, 0x05, 0x40); - /* old 0x95, new 0x05 from windrv 090403 */ - /* bits 5-7: reserved */ - i2c_w_mask(sd, 0x28, 0x20, 0x20); - /* bit 5: progressive mode on */ - } - - /* The below is wrong for OV7670s because their window registers - * only store the high bits in 0x17 to 0x1a */ - - /* SRH Use sd->max values instead of requested win values */ - /* SCS Since we're sticking with only the max hardware widths - * for a given mode */ - /* I can hard code this for OV7670s */ - /* Yes, these numbers do look odd, but they're tested and work! */ - if (sd->sensor == SEN_OV7670) { - if (qvga) { /* QVGA from ov7670.c by - * Jonathan Corbet */ - hstart = 164; - hstop = 28; - vstart = 14; - vstop = 494; - } else { /* VGA */ - hstart = 158; - hstop = 14; - vstart = 10; - vstop = 490; - } - /* OV7670 hardware window registers are split across - * multiple locations */ - i2c_w(sd, OV7670_REG_HSTART, hstart >> 3); - i2c_w(sd, OV7670_REG_HSTOP, hstop >> 3); - v = i2c_r(sd, OV7670_REG_HREF); - v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07); - msleep(10); /* need to sleep between read and write to - * same reg! */ - i2c_w(sd, OV7670_REG_HREF, v); + i2c_w(sd, 0x17, hwsbase); + i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale)); + i2c_w(sd, 0x19, vwsbase); + i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale)); - i2c_w(sd, OV7670_REG_VSTART, vstart >> 2); - i2c_w(sd, OV7670_REG_VSTOP, vstop >> 2); - v = i2c_r(sd, OV7670_REG_VREF); - v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03); - msleep(10); /* need to sleep between read and write to - * same reg! */ - i2c_w(sd, OV7670_REG_VREF, v); - } else { - i2c_w(sd, 0x17, hwsbase); - i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale)); - i2c_w(sd, 0x19, vwsbase); - i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale)); - } return 0; } -- cgit v1.2.3-70-g09d2 From f4eabafeb3ea41801260fba624cbf2da971d19f8 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 6 Aug 2009 06:05:40 -0300 Subject: V4L/DVB (13148): uvcvideo: Handle V4L2_CTRL_TYPE_BUTTON control type in VIDIOC_QUERYCTRL Return minimum, maximum and step set to 0 without querying the hardware. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_ctrl.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index 1b89735e62f..6f1487fc3d7 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c @@ -826,6 +826,13 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, ret = 0; goto out; + case V4L2_CTRL_TYPE_BUTTON: + v4l2_ctrl->minimum = 0; + v4l2_ctrl->maximum = 0; + v4l2_ctrl->step = 0; + ret = 0; + goto out; + default: break; } -- cgit v1.2.3-70-g09d2 From 663a419203cc9690d16502be509ffb8acc40552a Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 6 Aug 2009 11:41:17 -0300 Subject: V4L/DVB (13149): uvcvideo: Add a new UVC_TRACE_VIDEO trace level Use the trace level for messages related to video URB buffers allocation and alternate setting selection. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_video.c | 18 ++++++++++++++---- drivers/media/video/uvc/uvcvideo.h | 1 + 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index a6e41d12b22..bb9fed66936 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -781,10 +781,15 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming *stream, if (i == UVC_URBS) { stream->urb_size = psize * npackets; + uvc_trace(UVC_TRACE_VIDEO, "Allocated %u URB buffers " + "of %ux%u bytes each.\n", UVC_URBS, npackets, + psize); return npackets; } } + uvc_trace(UVC_TRACE_VIDEO, "Failed to allocate URB buffers (%u bytes " + "per packet).\n", psize); return 0; } @@ -935,10 +940,12 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) bandwidth = stream->ctrl.dwMaxPayloadTransferSize; if (bandwidth == 0) { - uvc_printk(KERN_WARNING, "device %s requested null " - "bandwidth, defaulting to lowest.\n", - stream->dev->name); + uvc_trace(UVC_TRACE_VIDEO, "Device requested null " + "bandwidth, defaulting to lowest.\n"); bandwidth = 1; + } else { + uvc_trace(UVC_TRACE_VIDEO, "Device requested %u " + "B/frame bandwidth.\n", bandwidth); } for (i = 0; i < intf->num_altsetting; ++i) { @@ -955,8 +962,11 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) break; } - if (i >= intf->num_altsetting) + if (i >= intf->num_altsetting) { + uvc_trace(UVC_TRACE_VIDEO, "No fast enough alt setting " + "for requested bandwidth.\n"); return -EIO; + } ret = usb_set_interface(stream->dev->udev, intfnum, i); if (ret < 0) diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index e7958aa454c..f5c40c0f0b4 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -533,6 +533,7 @@ struct uvc_driver { #define UVC_TRACE_FRAME (1 << 7) #define UVC_TRACE_SUSPEND (1 << 8) #define UVC_TRACE_STATUS (1 << 9) +#define UVC_TRACE_VIDEO (1 << 10) #define UVC_WARN_MINMAX 0 #define UVC_WARN_PROBE_DEF 1 -- cgit v1.2.3-70-g09d2 From 4e7387858f35eace117493e4ad69d3b7ccc84a41 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 2 Sep 2009 03:09:02 -0300 Subject: V4L/DVB (13150): uvcvideo: Don't acquire privileges in VIDIOC_TRY_FMT The VIDIOC_TRY_FMT ioctl doesn't interfere with video streaming and thus should succeed on an unprivileged file handle. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_v4l2.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index a2bdd806efa..7c555712411 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c @@ -371,7 +371,6 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, * - VIDIOC_S_INPUT * - VIDIOC_S_PARM * - VIDIOC_S_FMT - * - VIDIOC_TRY_FMT * - VIDIOC_REQBUFS */ static int uvc_acquire_privileges(struct uvc_fh *handle) @@ -731,9 +730,6 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct uvc_streaming_control probe; - if ((ret = uvc_acquire_privileges(handle)) < 0) - return ret; - return uvc_v4l2_try_format(stream, arg, &probe, NULL, NULL); } -- cgit v1.2.3-70-g09d2 From 1a969d9863a0c8890eb799ec710dda9701f10483 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 2 Sep 2009 03:12:26 -0300 Subject: V4L/DVB (13151): uvcvideo: Dismiss privileges when freeing video buffers Dismiss privileges on the file handle when calling VIDIOC_REQBUFS with a buffer count of 0. This allows applications to release the streaming permissions on the file handle without closing it. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_v4l2.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 7c555712411..94c1d6696af 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c @@ -364,7 +364,8 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, * unprivileged state. Only a single instance can be in a privileged state at * a given time. Trying to perform an operation that requires privileges will * automatically acquire the required privileges if possible, or return -EBUSY - * otherwise. Privileges are dismissed when closing the instance. + * otherwise. Privileges are dismissed when closing the instance or when + * freeing the video buffers using VIDIOC_REQBUFS. * * Operations that require privileges are: * @@ -884,6 +885,9 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) if (ret < 0) return ret; + if (ret == 0) + uvc_dismiss_privileges(handle); + rb->count = ret; ret = 0; break; -- cgit v1.2.3-70-g09d2 From 716fdee110ceb816cca8c46c0890d08c5a1addb9 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 29 Sep 2009 21:07:19 -0300 Subject: V4L/DVB (13152): uvcvideo: Rely on videodev to reference-count the device The uvcvideo driver has a driver-wide lock and a reference count to protect against a disconnect/open race. Now that videodev handles the race itself, reference-counting in the driver can be removed. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_driver.c | 155 ++++++++++++++++++----------------- drivers/media/video/uvc/uvc_v4l2.c | 32 ++------ drivers/media/video/uvc/uvcvideo.h | 5 +- 3 files changed, 88 insertions(+), 104 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 8756be56915..ebddf006a4f 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -1530,6 +1530,66 @@ static int uvc_scan_device(struct uvc_device *dev) * Video device registration and unregistration */ +/* + * Delete the UVC device. + * + * Called by the kernel when the last reference to the uvc_device structure + * is released. + * + * As this function is called after or during disconnect(), all URBs have + * already been canceled by the USB core. There is no need to kill the + * interrupt URB manually. + */ +static void uvc_delete(struct uvc_device *dev) +{ + struct list_head *p, *n; + + usb_put_intf(dev->intf); + usb_put_dev(dev->udev); + + uvc_status_cleanup(dev); + uvc_ctrl_cleanup_device(dev); + + list_for_each_safe(p, n, &dev->chains) { + struct uvc_video_chain *chain; + chain = list_entry(p, struct uvc_video_chain, list); + kfree(chain); + } + + list_for_each_safe(p, n, &dev->entities) { + struct uvc_entity *entity; + entity = list_entry(p, struct uvc_entity, list); + kfree(entity); + } + + list_for_each_safe(p, n, &dev->streams) { + struct uvc_streaming *streaming; + streaming = list_entry(p, struct uvc_streaming, list); + usb_driver_release_interface(&uvc_driver.driver, + streaming->intf); + usb_put_intf(streaming->intf); + kfree(streaming->format); + kfree(streaming->header.bmaControls); + kfree(streaming); + } + + kfree(dev); +} + +static void uvc_release(struct video_device *vdev) +{ + struct uvc_streaming *stream = video_get_drvdata(vdev); + struct uvc_device *dev = stream->dev; + + video_device_release(vdev); + + /* Decrement the registered streams count and delete the device when it + * reaches zero. + */ + if (atomic_dec_and_test(&dev->nstreams)) + uvc_delete(dev); +} + /* * Unregister the video devices. */ @@ -1537,16 +1597,26 @@ static void uvc_unregister_video(struct uvc_device *dev) { struct uvc_streaming *stream; + /* Unregistering all video devices might result in uvc_delete() being + * called from inside the loop if there's no open file handle. To avoid + * that, increment the stream count before iterating over the streams + * and decrement it when done. + */ + atomic_inc(&dev->nstreams); + list_for_each_entry(stream, &dev->streams, list) { if (stream->vdev == NULL) continue; - if (stream->vdev->minor == -1) - video_device_release(stream->vdev); - else - video_unregister_device(stream->vdev); + video_unregister_device(stream->vdev); stream->vdev = NULL; } + + /* Decrement the stream count and call uvc_delete explicitly if there + * are no stream left. + */ + if (atomic_dec_and_test(&dev->nstreams)) + uvc_delete(dev); } static int uvc_register_video(struct uvc_device *dev, @@ -1580,7 +1650,7 @@ static int uvc_register_video(struct uvc_device *dev, vdev->parent = &dev->intf->dev; vdev->minor = -1; vdev->fops = &uvc_fops; - vdev->release = video_device_release; + vdev->release = uvc_release; strlcpy(vdev->name, dev->name, sizeof vdev->name); /* Set the driver data before calling video_register_device, otherwise @@ -1598,6 +1668,7 @@ static int uvc_register_video(struct uvc_device *dev, return ret; } + atomic_inc(&dev->nstreams); return 0; } @@ -1653,61 +1724,6 @@ static int uvc_register_chains(struct uvc_device *dev) * USB probe, disconnect, suspend and resume */ -/* - * Delete the UVC device. - * - * Called by the kernel when the last reference to the uvc_device structure - * is released. - * - * Unregistering the video devices is done here because every opened instance - * must be closed before the device can be unregistered. An alternative would - * have been to use another reference count for uvc_v4l2_open/uvc_release, and - * unregister the video devices on disconnect when that reference count drops - * to zero. - * - * As this function is called after or during disconnect(), all URBs have - * already been canceled by the USB core. There is no need to kill the - * interrupt URB manually. - */ -void uvc_delete(struct kref *kref) -{ - struct uvc_device *dev = container_of(kref, struct uvc_device, kref); - struct list_head *p, *n; - - /* Unregister the video devices. */ - uvc_unregister_video(dev); - usb_put_intf(dev->intf); - usb_put_dev(dev->udev); - - uvc_status_cleanup(dev); - uvc_ctrl_cleanup_device(dev); - - list_for_each_safe(p, n, &dev->chains) { - struct uvc_video_chain *chain; - chain = list_entry(p, struct uvc_video_chain, list); - kfree(chain); - } - - list_for_each_safe(p, n, &dev->entities) { - struct uvc_entity *entity; - entity = list_entry(p, struct uvc_entity, list); - kfree(entity); - } - - list_for_each_safe(p, n, &dev->streams) { - struct uvc_streaming *streaming; - streaming = list_entry(p, struct uvc_streaming, list); - usb_driver_release_interface(&uvc_driver.driver, - streaming->intf); - usb_put_intf(streaming->intf); - kfree(streaming->format); - kfree(streaming->header.bmaControls); - kfree(streaming); - } - - kfree(dev); -} - static int uvc_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -1730,7 +1746,7 @@ static int uvc_probe(struct usb_interface *intf, INIT_LIST_HEAD(&dev->entities); INIT_LIST_HEAD(&dev->chains); INIT_LIST_HEAD(&dev->streams); - kref_init(&dev->kref); + atomic_set(&dev->nstreams, 0); atomic_set(&dev->users, 0); dev->udev = usb_get_dev(udev); @@ -1792,7 +1808,7 @@ static int uvc_probe(struct usb_interface *intf, return 0; error: - kref_put(&dev->kref, uvc_delete); + uvc_unregister_video(dev); return -ENODEV; } @@ -1809,21 +1825,9 @@ static void uvc_disconnect(struct usb_interface *intf) UVC_SC_VIDEOSTREAMING) return; - /* uvc_v4l2_open() might race uvc_disconnect(). A static driver-wide - * lock is needed to prevent uvc_disconnect from releasing its - * reference to the uvc_device instance after uvc_v4l2_open() received - * the pointer to the device (video_devdata) but before it got the - * chance to increase the reference count (kref_get). - * - * Note that the reference can't be released with the lock held, - * otherwise a AB-BA deadlock can occur with videodev_lock that - * videodev acquires in videodev_open() and video_unregister_device(). - */ - mutex_lock(&uvc_driver.open_mutex); dev->state |= UVC_DEV_DISCONNECTED; - mutex_unlock(&uvc_driver.open_mutex); - kref_put(&dev->kref, uvc_delete); + uvc_unregister_video(dev); } static int uvc_suspend(struct usb_interface *intf, pm_message_t message) @@ -2159,7 +2163,6 @@ static int __init uvc_init(void) INIT_LIST_HEAD(&uvc_driver.devices); INIT_LIST_HEAD(&uvc_driver.controls); - mutex_init(&uvc_driver.open_mutex); mutex_init(&uvc_driver.ctrl_mutex); uvc_ctrl_init(); diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 94c1d6696af..b3478d0eaf4 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c @@ -376,25 +376,18 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, */ static int uvc_acquire_privileges(struct uvc_fh *handle) { - int ret = 0; - /* Always succeed if the handle is already privileged. */ if (handle->state == UVC_HANDLE_ACTIVE) return 0; /* Check if the device already has a privileged handle. */ - mutex_lock(&uvc_driver.open_mutex); if (atomic_inc_return(&handle->stream->active) != 1) { atomic_dec(&handle->stream->active); - ret = -EBUSY; - goto done; + return -EBUSY; } handle->state = UVC_HANDLE_ACTIVE; - -done: - mutex_unlock(&uvc_driver.open_mutex); - return ret; + return 0; } static void uvc_dismiss_privileges(struct uvc_fh *handle) @@ -421,24 +414,20 @@ static int uvc_v4l2_open(struct file *file) int ret = 0; uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n"); - mutex_lock(&uvc_driver.open_mutex); stream = video_drvdata(file); - if (stream->dev->state & UVC_DEV_DISCONNECTED) { - ret = -ENODEV; - goto done; - } + if (stream->dev->state & UVC_DEV_DISCONNECTED) + return -ENODEV; ret = usb_autopm_get_interface(stream->dev->intf); if (ret < 0) - goto done; + return ret; /* Create the device handle. */ handle = kzalloc(sizeof *handle, GFP_KERNEL); if (handle == NULL) { usb_autopm_put_interface(stream->dev->intf); - ret = -ENOMEM; - goto done; + return -ENOMEM; } if (atomic_inc_return(&stream->dev->users) == 1) { @@ -447,7 +436,7 @@ static int uvc_v4l2_open(struct file *file) usb_autopm_put_interface(stream->dev->intf); atomic_dec(&stream->dev->users); kfree(handle); - goto done; + return ret; } } @@ -456,11 +445,7 @@ static int uvc_v4l2_open(struct file *file) handle->state = UVC_HANDLE_PASSIVE; file->private_data = handle; - kref_get(&stream->dev->kref); - -done: - mutex_unlock(&uvc_driver.open_mutex); - return ret; + return 0; } static int uvc_v4l2_release(struct file *file) @@ -490,7 +475,6 @@ static int uvc_v4l2_release(struct file *file) uvc_status_stop(stream->dev); usb_autopm_put_interface(stream->dev->intf); - kref_put(&stream->dev->kref, uvc_delete); return 0; } diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index f5c40c0f0b4..dae5f57523d 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -475,7 +475,6 @@ struct uvc_device { char name[32]; enum uvc_device_state state; - struct kref kref; struct list_head list; atomic_t users; @@ -488,6 +487,7 @@ struct uvc_device { /* Video Streaming interfaces */ struct list_head streams; + atomic_t nstreams; /* Status Interrupt Endpoint */ struct usb_host_endpoint *int_ep; @@ -511,8 +511,6 @@ struct uvc_fh { struct uvc_driver { struct usb_driver driver; - struct mutex open_mutex; /* protects from open/disconnect race */ - struct list_head devices; /* struct uvc_device list */ struct list_head controls; /* struct uvc_control_info list */ struct mutex ctrl_mutex; /* protects controls and devices @@ -572,7 +570,6 @@ extern unsigned int uvc_trace_param; /* Core driver */ extern struct uvc_driver uvc_driver; -extern void uvc_delete(struct kref *kref); /* Video buffers queue management. */ extern void uvc_queue_init(struct uvc_video_queue *queue, -- cgit v1.2.3-70-g09d2 From fd1b6bbb4a54a232ae6a1e5e4a6fbe3507ed5142 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Sun, 27 Sep 2009 05:30:34 -0300 Subject: V4L/DVB (13153): uvcvideo: Fix uvc_alloc_urb_buffers() This patch sets stream->urb_size as psize*npackets before calling uvc_alloc_urb_buffers, which may fix a possible failure of usb_buffer_free in case usb_buffer_alloc returns NULL. The patch is based on the ideas below: 1,If usb_buffer_alloc can't allocate a buffer sucessfully, uvc_free_urb_buffers will be called to free the allocated buffers, and stream->urb_size is required to be passed to usb_buffer_free; 2,uvc_free_urb_buffers can reset stream->urb_size. This patch is against linux-v2.6.31-next-20090926. Signed-off-by: Ming Lei Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index bb9fed66936..3369200a91d 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -770,8 +770,9 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming *stream, /* Retry allocations until one succeed. */ for (; npackets > 1; npackets /= 2) { for (i = 0; i < UVC_URBS; ++i) { + stream->urb_size = psize * npackets; stream->urb_buffer[i] = usb_buffer_alloc( - stream->dev->udev, psize * npackets, + stream->dev->udev, stream->urb_size, gfp_flags | __GFP_NOWARN, &stream->urb_dma[i]); if (!stream->urb_buffer[i]) { uvc_free_urb_buffers(stream); @@ -780,7 +781,6 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming *stream, } if (i == UVC_URBS) { - stream->urb_size = psize * npackets; uvc_trace(UVC_TRACE_VIDEO, "Allocated %u URB buffers " "of %ux%u bytes each.\n", UVC_URBS, npackets, psize); -- cgit v1.2.3-70-g09d2 From c4ed8c66d79d707d89fe732ff5b97739edf1ba62 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 8 Oct 2009 19:38:10 -0300 Subject: V4L/DVB (13154): uvcvideo: Handle garbage at the end of streaming interface descriptors At least one 5986:0241 webcam model includes vendor-specific descriptors at the end of its streaming interface descriptors. Print an information UVC_TRACE_DESCR message and try to continue parsing the descriptors rather than bailing out with an error. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_driver.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index ebddf006a4f..307d3a6b739 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -426,7 +426,8 @@ static int uvc_parse_format(struct uvc_device *dev, /* Parse the frame descriptors. Only uncompressed, MJPEG and frame * based formats have frame descriptors. */ - while (buflen > 2 && buffer[2] == ftype) { + while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && + buffer[2] == ftype) { frame = &format->frame[format->nframes]; if (ftype != UVC_VS_FRAME_FRAME_BASED) n = buflen > 25 ? buffer[25] : 0; @@ -503,12 +504,14 @@ static int uvc_parse_format(struct uvc_device *dev, buffer += buffer[0]; } - if (buflen > 2 && buffer[2] == UVC_VS_STILL_IMAGE_FRAME) { + if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && + buffer[2] == UVC_VS_STILL_IMAGE_FRAME) { buflen -= buffer[0]; buffer += buffer[0]; } - if (buflen > 2 && buffer[2] == UVC_VS_COLORFORMAT) { + if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && + buffer[2] == UVC_VS_COLORFORMAT) { if (buflen < 6) { uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " "interface %d COLORFORMAT error\n", @@ -749,6 +752,11 @@ static int uvc_parse_streaming(struct uvc_device *dev, buffer += buffer[0]; } + if (buflen) + uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface " + "%d has %u bytes of trailing descriptor garbage.\n", + dev->udev->devnum, alts->desc.bInterfaceNumber, buflen); + /* Parse the alternate settings to find the maximum bandwidth. */ for (i = 0; i < intf->num_altsetting; ++i) { struct usb_host_endpoint *ep; -- cgit v1.2.3-70-g09d2 From b232a012adfea9f535702e8296ea6b76e691f436 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 9 Oct 2009 20:55:23 -0300 Subject: V4L/DVB (13155): uvcvideo: Add a module parameter to set the streaming control timeout The default streaming control timeout was found by Ondrej Zary to be too low for some Logitech webcams. With kernel 2.6.22 and newer they would timeout during initialization unles the audio function was initialized before the video function. Add a module parameter to set the streaming control timeout and increase the default value from 1000ms to 3000ms to fix the above problem. Thanks to Ondrej Zary for investigating the issue and providing an initial patch. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_driver.c | 3 +++ drivers/media/video/uvc/uvc_video.c | 4 ++-- drivers/media/video/uvc/uvcvideo.h | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 307d3a6b739..ab4a60102d0 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -46,6 +46,7 @@ unsigned int uvc_no_drop_param; static unsigned int uvc_quirks_param; unsigned int uvc_trace_param; +unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT; /* ------------------------------------------------------------------------ * Video formats @@ -2195,6 +2196,8 @@ module_param_named(quirks, uvc_quirks_param, uint, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(quirks, "Forced device quirks"); module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(trace, "Trace level bitmask"); +module_param_named(timeout, uvc_timeout_param, uint, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(timeout, "Streaming control requests timeout"); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 3369200a91d..05139a4f14f 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -135,7 +135,7 @@ static int uvc_get_video_ctrl(struct uvc_streaming *stream, ret = __uvc_query_ctrl(stream->dev, query, 0, stream->intfnum, probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data, - size, UVC_CTRL_STREAMING_TIMEOUT); + size, uvc_timeout_param); if ((query == UVC_GET_MIN || query == UVC_GET_MAX) && ret == 2) { /* Some cameras, mostly based on Bison Electronics chipsets, @@ -239,7 +239,7 @@ static int uvc_set_video_ctrl(struct uvc_streaming *stream, ret = __uvc_query_ctrl(stream->dev, UVC_SET_CUR, 0, stream->intfnum, probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data, - size, UVC_CTRL_STREAMING_TIMEOUT); + size, uvc_timeout_param); if (ret != size) { uvc_printk(KERN_ERR, "Failed to set UVC %s control : " "%d (exp. %u).\n", probe ? "probe" : "commit", diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index dae5f57523d..fb3342ae6d7 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -148,7 +148,7 @@ struct uvc_xu_control { #define UVC_MAX_STATUS_SIZE 16 #define UVC_CTRL_CONTROL_TIMEOUT 300 -#define UVC_CTRL_STREAMING_TIMEOUT 1000 +#define UVC_CTRL_STREAMING_TIMEOUT 3000 /* Devices quirks */ #define UVC_QUIRK_STATUS_INTERVAL 0x00000001 @@ -538,6 +538,7 @@ struct uvc_driver { extern unsigned int uvc_no_drop_param; extern unsigned int uvc_trace_param; +extern unsigned int uvc_timeout_param; #define uvc_trace(flag, msg...) \ do { \ -- cgit v1.2.3-70-g09d2 From 06d3a396b26e48012ce0f2ee21b1fdff092d8d4a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Oct 2009 20:09:42 -0300 Subject: V4L/DVB (13157): dvb_frontend: represent all DVBS2API commands via macro Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-core/dvb_frontend.c | 159 +++++------------------------- 1 file changed, 26 insertions(+), 133 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index e9ec8e91105..07461222a7f 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -895,104 +895,27 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe) } static struct dtv_cmds_h dtv_cmds[] = { - [DTV_TUNE] = { - .name = "DTV_TUNE", - .cmd = DTV_TUNE, - .set = 1, - }, - [DTV_CLEAR] = { - .name = "DTV_CLEAR", - .cmd = DTV_CLEAR, - .set = 1, - }, + _DTV_CMD(DTV_TUNE, 1, 0), + _DTV_CMD(DTV_CLEAR, 1, 0), /* Set */ - [DTV_FREQUENCY] = { - .name = "DTV_FREQUENCY", - .cmd = DTV_FREQUENCY, - .set = 1, - }, - [DTV_BANDWIDTH_HZ] = { - .name = "DTV_BANDWIDTH_HZ", - .cmd = DTV_BANDWIDTH_HZ, - .set = 1, - }, - [DTV_MODULATION] = { - .name = "DTV_MODULATION", - .cmd = DTV_MODULATION, - .set = 1, - }, - [DTV_INVERSION] = { - .name = "DTV_INVERSION", - .cmd = DTV_INVERSION, - .set = 1, - }, - [DTV_DISEQC_MASTER] = { - .name = "DTV_DISEQC_MASTER", - .cmd = DTV_DISEQC_MASTER, - .set = 1, - .buffer = 1, - }, - [DTV_SYMBOL_RATE] = { - .name = "DTV_SYMBOL_RATE", - .cmd = DTV_SYMBOL_RATE, - .set = 1, - }, - [DTV_INNER_FEC] = { - .name = "DTV_INNER_FEC", - .cmd = DTV_INNER_FEC, - .set = 1, - }, - [DTV_VOLTAGE] = { - .name = "DTV_VOLTAGE", - .cmd = DTV_VOLTAGE, - .set = 1, - }, - [DTV_TONE] = { - .name = "DTV_TONE", - .cmd = DTV_TONE, - .set = 1, - }, - [DTV_PILOT] = { - .name = "DTV_PILOT", - .cmd = DTV_PILOT, - .set = 1, - }, - [DTV_ROLLOFF] = { - .name = "DTV_ROLLOFF", - .cmd = DTV_ROLLOFF, - .set = 1, - }, - [DTV_DELIVERY_SYSTEM] = { - .name = "DTV_DELIVERY_SYSTEM", - .cmd = DTV_DELIVERY_SYSTEM, - .set = 1, - }, - [DTV_HIERARCHY] = { - .name = "DTV_HIERARCHY", - .cmd = DTV_HIERARCHY, - .set = 1, - }, - [DTV_CODE_RATE_HP] = { - .name = "DTV_CODE_RATE_HP", - .cmd = DTV_CODE_RATE_HP, - .set = 1, - }, - [DTV_CODE_RATE_LP] = { - .name = "DTV_CODE_RATE_LP", - .cmd = DTV_CODE_RATE_LP, - .set = 1, - }, - [DTV_GUARD_INTERVAL] = { - .name = "DTV_GUARD_INTERVAL", - .cmd = DTV_GUARD_INTERVAL, - .set = 1, - }, - [DTV_TRANSMISSION_MODE] = { - .name = "DTV_TRANSMISSION_MODE", - .cmd = DTV_TRANSMISSION_MODE, - .set = 1, - }, + _DTV_CMD(DTV_FREQUENCY, 1, 0), + _DTV_CMD(DTV_BANDWIDTH_HZ, 1, 0), + _DTV_CMD(DTV_MODULATION, 1, 0), + _DTV_CMD(DTV_INVERSION, 1, 0), + _DTV_CMD(DTV_DISEQC_MASTER, 1, 1), + _DTV_CMD(DTV_SYMBOL_RATE, 1, 0), + _DTV_CMD(DTV_INNER_FEC, 1, 0), + _DTV_CMD(DTV_VOLTAGE, 1, 0), + _DTV_CMD(DTV_TONE, 1, 0), + _DTV_CMD(DTV_PILOT, 1, 0), + _DTV_CMD(DTV_ROLLOFF, 1, 0), + _DTV_CMD(DTV_DELIVERY_SYSTEM, 1, 0), + _DTV_CMD(DTV_HIERARCHY, 1, 0), + _DTV_CMD(DTV_CODE_RATE_HP, 1, 0), + _DTV_CMD(DTV_CODE_RATE_LP, 1, 0), + _DTV_CMD(DTV_GUARD_INTERVAL, 1, 0), + _DTV_CMD(DTV_TRANSMISSION_MODE, 1, 0), _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1, 0), _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 1, 0), @@ -1035,43 +958,13 @@ static struct dtv_cmds_h dtv_cmds[] = { _DTV_CMD(DTV_ISDBS_TS_ID, 1, 0), /* Get */ - [DTV_DISEQC_SLAVE_REPLY] = { - .name = "DTV_DISEQC_SLAVE_REPLY", - .cmd = DTV_DISEQC_SLAVE_REPLY, - .set = 0, - .buffer = 1, - }, - - [DTV_API_VERSION] = { - .name = "DTV_API_VERSION", - .cmd = DTV_API_VERSION, - .set = 0, - }, - [DTV_CODE_RATE_HP] = { - .name = "DTV_CODE_RATE_HP", - .cmd = DTV_CODE_RATE_HP, - .set = 0, - }, - [DTV_CODE_RATE_LP] = { - .name = "DTV_CODE_RATE_LP", - .cmd = DTV_CODE_RATE_LP, - .set = 0, - }, - [DTV_GUARD_INTERVAL] = { - .name = "DTV_GUARD_INTERVAL", - .cmd = DTV_GUARD_INTERVAL, - .set = 0, - }, - [DTV_TRANSMISSION_MODE] = { - .name = "DTV_TRANSMISSION_MODE", - .cmd = DTV_TRANSMISSION_MODE, - .set = 0, - }, - [DTV_HIERARCHY] = { - .name = "DTV_HIERARCHY", - .cmd = DTV_HIERARCHY, - .set = 0, - }, + _DTV_CMD(DTV_DISEQC_SLAVE_REPLY, 0, 1), + _DTV_CMD(DTV_API_VERSION, 0, 0), + _DTV_CMD(DTV_CODE_RATE_HP, 0, 0), + _DTV_CMD(DTV_CODE_RATE_LP, 0, 0), + _DTV_CMD(DTV_GUARD_INTERVAL, 0, 0), + _DTV_CMD(DTV_TRANSMISSION_MODE, 0, 0), + _DTV_CMD(DTV_HIERARCHY, 0, 0), }; static void dtv_property_dump(struct dtv_property *tvp) -- cgit v1.2.3-70-g09d2 From 7cbefad085c9112d0b1814db18423e5da072f5c8 Mon Sep 17 00:00:00 2001 From: Tuukka Toivonen Date: Thu, 23 Jul 2009 10:56:25 -0300 Subject: V4L/DVB (13165): videobuf do not force buffer size to be multiple of PAGE_SIZE When the image size (bytesperline*height) is not multiple of PAGE_SIZE, v4l2 rounded the required buffer size to be multiple of PAGE_SIZE. This prevented user space to store images directly into userptr buffers which were not multiple of PAGE_SIZE. This constraint is removed. The start address is still assumed to be required page-aligned, ie., when v4l2 allocates mmap buffers, the offset between different buffers is page-aligned. Signed-off-by: Tuukka Toivonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videobuf-core.c | 7 +++---- drivers/media/video/videobuf-dma-sg.c | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index 8e93c6f25c8..a96b08d3df5 100644 --- a/drivers/media/video/videobuf-core.c +++ b/drivers/media/video/videobuf-core.c @@ -360,7 +360,7 @@ int __videobuf_mmap_setup(struct videobuf_queue *q, q->bufs[i]->bsize = bsize; switch (memory) { case V4L2_MEMORY_MMAP: - q->bufs[i]->boff = bsize * i; + q->bufs[i]->boff = PAGE_ALIGN(bsize) * i; break; case V4L2_MEMORY_USERPTR: case V4L2_MEMORY_OVERLAY: @@ -430,9 +430,8 @@ int videobuf_reqbufs(struct videobuf_queue *q, count = VIDEO_MAX_FRAME; size = 0; q->ops->buf_setup(q, &count, &size); - size = PAGE_ALIGN(size); dprintk(1, "reqbufs: bufs=%d, size=0x%x [%d pages total]\n", - count, size, (count*size)>>PAGE_SHIFT); + count, size, (count*PAGE_ALIGN(size))>>PAGE_SHIFT); retval = __videobuf_mmap_setup(q, count, size, req->memory); if (retval < 0) { @@ -1099,7 +1098,7 @@ int videobuf_cgmbuf(struct videobuf_queue *q, mbuf->size = 0; for (i = 0; i < mbuf->frames; i++) { mbuf->offsets[i] = q->bufs[i]->boff; - mbuf->size += q->bufs[i]->bsize; + mbuf->size += PAGE_ALIGN(q->bufs[i]->bsize); } return 0; diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index 032ebae0134..a583d394696 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c @@ -588,7 +588,7 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q, retval = -EBUSY; goto done; } - size += q->bufs[last]->bsize; + size += PAGE_ALIGN(q->bufs[last]->bsize); if (size == (vma->vm_end - vma->vm_start)) break; } @@ -610,7 +610,7 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q, continue; q->bufs[i]->map = map; q->bufs[i]->baddr = vma->vm_start + size; - size += q->bufs[i]->bsize; + size += PAGE_ALIGN(q->bufs[i]->bsize); } map->count = 1; -- cgit v1.2.3-70-g09d2 From e6a1a08f00689b0006bef2376ac30daa467901e9 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 19 Sep 2009 16:48:17 -0300 Subject: V4L/DVB (13166): remove duplicate structure field initialization The definition of tvaudio_tuner_ops initializes the s_tuner field twice. It appears that the second case should initialize the g_tuner field. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r@ identifier I, s, fld; position p0,p; expression E; @@ struct I s =@p0 { ... .fld@p = E, ...}; @s@ identifier I, s, r.fld; position r.p0,p; expression E; @@ struct I s =@p0 { ... .fld@p = E, ...}; @script:python@ p0 << r.p0; fld << r.fld; ps << s.p; pr << r.p; @@ if int(ps[0].line)!=int(pr[0].line) or int(ps[0].column)!=int(pr[0].column): cocci.print_main(fld,p0) // Signed-off-by: Julia Lawall Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tvaudio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 0869bafc2b5..800fc1b111e 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -1919,7 +1919,7 @@ static const struct v4l2_subdev_tuner_ops tvaudio_tuner_ops = { .s_radio = tvaudio_s_radio, .s_frequency = tvaudio_s_frequency, .s_tuner = tvaudio_s_tuner, - .s_tuner = tvaudio_g_tuner, + .g_tuner = tvaudio_g_tuner, }; static const struct v4l2_subdev_audio_ops tvaudio_audio_ops = { -- cgit v1.2.3-70-g09d2 From e3c6e1aaa5db7822524f5b1355960fd732910068 Mon Sep 17 00:00:00 2001 From: Danny Wood Date: Sun, 20 Sep 2009 12:14:21 -0300 Subject: V4L/DVB (13168): Add support for Asus Europa Hybrid DVB-T card (SAA7134 SubVendor ID: 0x1043 Device ID: 0x4847) Adds the device IDs and driver linking to allow the Asus Europa DVB-T card to operate with these drivers. The device has a SAA7134 chipset with a TD1316 Hybrid Tuner. All inputs work on the card including switching between DVB-T and Analogue TV, there is also no IR with this card. [mchehab@redhat.com: CodingStyle fixes] Signed-off-by: Danny Wood Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.saa7134 | 1 + drivers/media/video/saa7134/saa7134-cards.c | 31 +++++++++++++++++++++++++++++ drivers/media/video/saa7134/saa7134-dvb.c | 1 + drivers/media/video/saa7134/saa7134.h | 1 + 4 files changed, 34 insertions(+) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index 2620d60341e..94e255a76f7 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -172,3 +172,4 @@ 171 -> Beholder BeholdTV X7 [5ace:7595] 172 -> RoverMedia TV Link Pro FM [19d1:0138] 173 -> Zolid Hybrid TV Tuner PCI [1131:2004] +174 -> Asus Europa Hybrid OEM [1043:4847] diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 7de7f1f0add..bdb61385136 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -5280,6 +5280,30 @@ struct saa7134_board saa7134_boards[] = { .amux = TV, }, }, + [SAA7134_BOARD_ASUS_EUROPA_HYBRID] = { + .name = "Asus Europa Hybrid OEM", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_TD1316, + .radio_type = UNSET, + .tuner_addr = 0x61, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE, + .mpeg = SAA7134_MPEG_DVB, + .inputs = { { + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + }, { + .name = name_comp1, + .vmux = 4, + .amux = LINE2, + }, { + .name = name_svideo, + .vmux = 8, + .amux = LINE2, + } }, + }, }; @@ -6418,6 +6442,12 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = PCI_VENDOR_ID_PHILIPS, .subdevice = 0x2004, .driver_data = SAA7134_BOARD_ZOLID_HYBRID_PCI, + }, { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x1043, + .subdevice = 0x4847, + .driver_data = SAA7134_BOARD_ASUS_EUROPA_HYBRID, }, { /* --- boards without eeprom + subsystem ID --- */ .vendor = PCI_VENDOR_ID_PHILIPS, @@ -7080,6 +7110,7 @@ int saa7134_board_init2(struct saa7134_dev *dev) /* break intentionally omitted */ case SAA7134_BOARD_VIDEOMATE_DVBT_300: case SAA7134_BOARD_ASUS_EUROPA2_HYBRID: + case SAA7134_BOARD_ASUS_EUROPA_HYBRID: { /* The Philips EUROPA based hybrid boards have the tuner diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 96d3668f469..cd31284faf7 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -1131,6 +1131,7 @@ static int dvb_init(struct saa7134_dev *dev) break; case SAA7134_BOARD_PHILIPS_EUROPA: case SAA7134_BOARD_VIDEOMATE_DVBT_300: + case SAA7134_BOARD_ASUS_EUROPA_HYBRID: fe0->dvb.frontend = dvb_attach(tda10046_attach, &philips_europa_config, &dev->i2c_adap); diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index f8697d46ff5..94e1a3be331 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -297,6 +297,7 @@ struct saa7134_format { #define SAA7134_BOARD_BEHOLD_X7 171 #define SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM 172 #define SAA7134_BOARD_ZOLID_HYBRID_PCI 173 +#define SAA7134_BOARD_ASUS_EUROPA_HYBRID 174 #define SAA7134_MAXBOARDS 32 #define SAA7134_INPUT_MAX 8 -- cgit v1.2.3-70-g09d2 From d31242943a73aba0e5cfd0ea674b5e694b4a39e6 Mon Sep 17 00:00:00 2001 From: Richard Röjfors Date: Tue, 22 Sep 2009 06:05:42 -0300 Subject: V4L/DVB (13173): adv7180: Support for getting input status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds support to the ADV7180 driver to check the input status. Since the status is held in the same register as the input standard a small restructuring of the code is done to reuse the code for reading the register Signed-off-by: Richard Röjfors Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/adv7180.c | 66 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 12 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/adv7180.c b/drivers/media/video/adv7180.c index 1b3cbd02a7f..f3fce398020 100644 --- a/drivers/media/video/adv7180.c +++ b/drivers/media/video/adv7180.c @@ -30,14 +30,31 @@ #define DRIVER_NAME "adv7180" -#define ADV7180_INPUT_CONTROL_REG 0x00 -#define ADV7180_INPUT_CONTROL_PAL_BG_NTSC_J_SECAM 0x00 +#define ADV7180_INPUT_CONTROL_REG 0x00 +#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM 0x00 +#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM_PED 0x10 +#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_J_SECAM 0x20 +#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_M_SECAM 0x30 +#define ADV7180_INPUT_CONTROL_NTSC_J 0x40 +#define ADV7180_INPUT_CONTROL_NTSC_M 0x50 +#define ADV7180_INPUT_CONTROL_PAL60 0x60 +#define ADV7180_INPUT_CONTROL_NTSC_443 0x70 +#define ADV7180_INPUT_CONTROL_PAL_BG 0x80 +#define ADV7180_INPUT_CONTROL_PAL_N 0x90 +#define ADV7180_INPUT_CONTROL_PAL_M 0xa0 +#define ADV7180_INPUT_CONTROL_PAL_M_PED 0xb0 +#define ADV7180_INPUT_CONTROL_PAL_COMB_N 0xc0 +#define ADV7180_INPUT_CONTROL_PAL_COMB_N_PED 0xd0 +#define ADV7180_INPUT_CONTROL_PAL_SECAM 0xe0 +#define ADV7180_INPUT_CONTROL_PAL_SECAM_PED 0xf0 + #define ADV7180_AUTODETECT_ENABLE_REG 0x07 #define ADV7180_AUTODETECT_DEFAULT 0x7f -#define ADV7180_STATUS1_REG 0x10 -#define ADV7180_STATUS1_AUTOD_MASK 0x70 +#define ADV7180_STATUS1_REG 0x10 +#define ADV7180_STATUS1_IN_LOCK 0x01 +#define ADV7180_STATUS1_AUTOD_MASK 0x70 #define ADV7180_STATUS1_AUTOD_NTSM_M_J 0x00 #define ADV7180_STATUS1_AUTOD_NTSC_4_43 0x10 #define ADV7180_STATUS1_AUTOD_PAL_M 0x20 @@ -55,13 +72,11 @@ struct adv7180_state { struct v4l2_subdev sd; }; -static v4l2_std_id determine_norm(struct i2c_client *client) +static v4l2_std_id adv7180_std_to_v4l2(u8 status1) { - u8 status1 = i2c_smbus_read_byte_data(client, ADV7180_STATUS1_REG); - switch (status1 & ADV7180_STATUS1_AUTOD_MASK) { case ADV7180_STATUS1_AUTOD_NTSM_M_J: - return V4L2_STD_NTSC_M_JP; + return V4L2_STD_NTSC; case ADV7180_STATUS1_AUTOD_NTSC_4_43: return V4L2_STD_NTSC_443; case ADV7180_STATUS1_AUTOD_PAL_M: @@ -81,6 +96,30 @@ static v4l2_std_id determine_norm(struct i2c_client *client) } } +static u32 adv7180_status_to_v4l2(u8 status1) +{ + if (!(status1 & ADV7180_STATUS1_IN_LOCK)) + return V4L2_IN_ST_NO_SIGNAL; + + return 0; +} + +static int __adv7180_status(struct i2c_client *client, u32 *status, + v4l2_std_id *std) +{ + int status1 = i2c_smbus_read_byte_data(client, ADV7180_STATUS1_REG); + + if (status1 < 0) + return status1; + + if (status) + *status = adv7180_status_to_v4l2(status1); + if (std) + *std = adv7180_std_to_v4l2(status1); + + return 0; +} + static inline struct adv7180_state *to_state(struct v4l2_subdev *sd) { return container_of(sd, struct adv7180_state, sd); @@ -88,10 +127,12 @@ static inline struct adv7180_state *to_state(struct v4l2_subdev *sd) static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) { - struct i2c_client *client = v4l2_get_subdevdata(sd); + return __adv7180_status(v4l2_get_subdevdata(sd), NULL, std); +} - *std = determine_norm(client); - return 0; +static int adv7180_g_input_status(struct v4l2_subdev *sd, u32 *status) +{ + return __adv7180_status(v4l2_get_subdevdata(sd), status, NULL); } static int adv7180_g_chip_ident(struct v4l2_subdev *sd, @@ -104,6 +145,7 @@ static int adv7180_g_chip_ident(struct v4l2_subdev *sd, static const struct v4l2_subdev_video_ops adv7180_video_ops = { .querystd = adv7180_querystd, + .g_input_status = adv7180_g_input_status, }; static const struct v4l2_subdev_core_ops adv7180_core_ops = { @@ -143,7 +185,7 @@ static int adv7180_probe(struct i2c_client *client, /* Initialize adv7180 */ /* enable autodetection */ ret = i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG, - ADV7180_INPUT_CONTROL_PAL_BG_NTSC_J_SECAM); + ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM); if (ret > 0) ret = i2c_smbus_write_byte_data(client, ADV7180_AUTODETECT_ENABLE_REG, -- cgit v1.2.3-70-g09d2 From c277b60a08fe9e201656528b3f5cd35b554e24af Mon Sep 17 00:00:00 2001 From: Richard Röjfors Date: Tue, 22 Sep 2009 06:06:34 -0300 Subject: V4L/DVB (13174): adv7180: Support for setting input status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support for settings the input standard of the ADV7180. When the input standard is set there is no use to ask the chip for standard, therefore it is cached in the driver. Signed-off-by: Richard Röjfors Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/adv7180.c | 72 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/adv7180.c b/drivers/media/video/adv7180.c index f3fce398020..8b199a86a3a 100644 --- a/drivers/media/video/adv7180.c +++ b/drivers/media/video/adv7180.c @@ -69,7 +69,9 @@ struct adv7180_state { - struct v4l2_subdev sd; + struct v4l2_subdev sd; + v4l2_std_id curr_norm; + bool autodetect; }; static v4l2_std_id adv7180_std_to_v4l2(u8 status1) @@ -96,6 +98,29 @@ static v4l2_std_id adv7180_std_to_v4l2(u8 status1) } } +static int v4l2_std_to_adv7180(v4l2_std_id std) +{ + if (std == V4L2_STD_PAL_60) + return ADV7180_INPUT_CONTROL_PAL60; + if (std == V4L2_STD_NTSC_443) + return ADV7180_INPUT_CONTROL_NTSC_443; + if (std == V4L2_STD_PAL_N) + return ADV7180_INPUT_CONTROL_PAL_N; + if (std == V4L2_STD_PAL_M) + return ADV7180_INPUT_CONTROL_PAL_M; + if (std == V4L2_STD_PAL_Nc) + return ADV7180_INPUT_CONTROL_PAL_COMB_N; + + if (std & V4L2_STD_PAL) + return ADV7180_INPUT_CONTROL_PAL_BG; + if (std & V4L2_STD_NTSC) + return ADV7180_INPUT_CONTROL_NTSC_M; + if (std & V4L2_STD_SECAM) + return ADV7180_INPUT_CONTROL_PAL_SECAM; + + return -EINVAL; +} + static u32 adv7180_status_to_v4l2(u8 status1) { if (!(status1 & ADV7180_STATUS1_IN_LOCK)) @@ -127,7 +152,15 @@ static inline struct adv7180_state *to_state(struct v4l2_subdev *sd) static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) { - return __adv7180_status(v4l2_get_subdevdata(sd), NULL, std); + struct adv7180_state *state = to_state(sd); + int err = 0; + + if (!state->autodetect) + *std = state->curr_norm; + else + err = __adv7180_status(v4l2_get_subdevdata(sd), NULL, std); + + return err; } static int adv7180_g_input_status(struct v4l2_subdev *sd, u32 *status) @@ -143,6 +176,39 @@ static int adv7180_g_chip_ident(struct v4l2_subdev *sd, return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7180, 0); } +static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std) +{ + struct adv7180_state *state = to_state(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret; + + /* all standards -> autodetect */ + if (std == V4L2_STD_ALL) { + ret = i2c_smbus_write_byte_data(client, + ADV7180_INPUT_CONTROL_REG, + ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM); + if (ret < 0) + goto out; + + state->autodetect = true; + } else { + ret = v4l2_std_to_adv7180(std); + if (ret < 0) + goto out; + + ret = i2c_smbus_write_byte_data(client, + ADV7180_INPUT_CONTROL_REG, ret); + if (ret < 0) + goto out; + + state->curr_norm = std; + state->autodetect = false; + } + ret = 0; +out: + return ret; +} + static const struct v4l2_subdev_video_ops adv7180_video_ops = { .querystd = adv7180_querystd, .g_input_status = adv7180_g_input_status, @@ -150,6 +216,7 @@ static const struct v4l2_subdev_video_ops adv7180_video_ops = { static const struct v4l2_subdev_core_ops adv7180_core_ops = { .g_chip_ident = adv7180_g_chip_ident, + .s_std = adv7180_s_std, }; static const struct v4l2_subdev_ops adv7180_ops = { @@ -179,6 +246,7 @@ static int adv7180_probe(struct i2c_client *client, state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL); if (state == NULL) return -ENOMEM; + state->autodetect = true; sd = &state->sd; v4l2_i2c_subdev_init(sd, client, &adv7180_ops); -- cgit v1.2.3-70-g09d2 From 527aebf29c64a56557f9b44d2852ccb99f91ac3e Mon Sep 17 00:00:00 2001 From: Richard Röjfors Date: Tue, 22 Sep 2009 06:07:34 -0300 Subject: V4L/DVB (13175): adv7180: Use __devinit and __devexit macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch defines the probe and remove function as __devinit and __devexit. Signed-off-by: Richard Röjfors Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/adv7180.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/adv7180.c b/drivers/media/video/adv7180.c index 8b199a86a3a..77eada64cf7 100644 --- a/drivers/media/video/adv7180.c +++ b/drivers/media/video/adv7180.c @@ -229,7 +229,7 @@ static const struct v4l2_subdev_ops adv7180_ops = { * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' */ -static int adv7180_probe(struct i2c_client *client, +static __devinit int adv7180_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct adv7180_state *state; @@ -267,7 +267,7 @@ static int adv7180_probe(struct i2c_client *client, return 0; } -static int adv7180_remove(struct i2c_client *client) +static __devexit int adv7180_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); @@ -289,7 +289,7 @@ static struct i2c_driver adv7180_driver = { .name = DRIVER_NAME, }, .probe = adv7180_probe, - .remove = adv7180_remove, + .remove = __devexit_p(adv7180_remove), .id_table = adv7180_id, }; -- cgit v1.2.3-70-g09d2 From 42752f7a3f4afbabb513d5769c590e9abe2d0cd6 Mon Sep 17 00:00:00 2001 From: Richard Röjfors Date: Tue, 22 Sep 2009 06:07:06 -0300 Subject: V4L/DVB (13176): adv7180: Support checking standard via interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the I2C device provides an interrupt it is registered and the standard is updated via interrupts rather than polling. Since I2C communication is needed, the interrupt handler fires off a work which will check the new standard, and store it in the internal structure. To handle mutual exclusion a mutex is introduced. Signed-off-by: Richard Röjfors Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/adv7180.c | 185 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 168 insertions(+), 17 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/adv7180.c b/drivers/media/video/adv7180.c index 77eada64cf7..0826f0dabc1 100644 --- a/drivers/media/video/adv7180.c +++ b/drivers/media/video/adv7180.c @@ -27,6 +27,7 @@ #include #include #include +#include #define DRIVER_NAME "adv7180" @@ -48,9 +49,14 @@ #define ADV7180_INPUT_CONTROL_PAL_SECAM 0xe0 #define ADV7180_INPUT_CONTROL_PAL_SECAM_PED 0xf0 -#define ADV7180_AUTODETECT_ENABLE_REG 0x07 -#define ADV7180_AUTODETECT_DEFAULT 0x7f +#define ADV7180_EXTENDED_OUTPUT_CONTROL_REG 0x04 +#define ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS 0xC5 +#define ADV7180_AUTODETECT_ENABLE_REG 0x07 +#define ADV7180_AUTODETECT_DEFAULT 0x7f + +#define ADV7180_ADI_CTRL_REG 0x0e +#define ADV7180_ADI_CTRL_IRQ_SPACE 0x20 #define ADV7180_STATUS1_REG 0x10 #define ADV7180_STATUS1_IN_LOCK 0x01 @@ -67,9 +73,28 @@ #define ADV7180_IDENT_REG 0x11 #define ADV7180_ID_7180 0x18 +#define ADV7180_ICONF1_ADI 0x40 +#define ADV7180_ICONF1_ACTIVE_LOW 0x01 +#define ADV7180_ICONF1_PSYNC_ONLY 0x10 +#define ADV7180_ICONF1_ACTIVE_TO_CLR 0xC0 + +#define ADV7180_IRQ1_LOCK 0x01 +#define ADV7180_IRQ1_UNLOCK 0x02 +#define ADV7180_ISR1_ADI 0x42 +#define ADV7180_ICR1_ADI 0x43 +#define ADV7180_IMR1_ADI 0x44 +#define ADV7180_IMR2_ADI 0x48 +#define ADV7180_IRQ3_AD_CHANGE 0x08 +#define ADV7180_ISR3_ADI 0x4A +#define ADV7180_ICR3_ADI 0x4B +#define ADV7180_IMR3_ADI 0x4C +#define ADV7180_IMR4_ADI 0x50 struct adv7180_state { struct v4l2_subdev sd; + struct work_struct work; + struct mutex mutex; /* mutual excl. when accessing chip */ + int irq; v4l2_std_id curr_norm; bool autodetect; }; @@ -153,19 +178,30 @@ static inline struct adv7180_state *to_state(struct v4l2_subdev *sd) static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) { struct adv7180_state *state = to_state(sd); - int err = 0; + int err = mutex_lock_interruptible(&state->mutex); + if (err) + return err; - if (!state->autodetect) + /* when we are interrupt driven we know the state */ + if (!state->autodetect || state->irq > 0) *std = state->curr_norm; else err = __adv7180_status(v4l2_get_subdevdata(sd), NULL, std); + mutex_unlock(&state->mutex); return err; } static int adv7180_g_input_status(struct v4l2_subdev *sd, u32 *status) { - return __adv7180_status(v4l2_get_subdevdata(sd), status, NULL); + struct adv7180_state *state = to_state(sd); + int ret = mutex_lock_interruptible(&state->mutex); + if (ret) + return ret; + + ret = __adv7180_status(v4l2_get_subdevdata(sd), status, NULL); + mutex_unlock(&state->mutex); + return ret; } static int adv7180_g_chip_ident(struct v4l2_subdev *sd, @@ -180,7 +216,9 @@ static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std) { struct adv7180_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; + int ret = mutex_lock_interruptible(&state->mutex); + if (ret) + return ret; /* all standards -> autodetect */ if (std == V4L2_STD_ALL) { @@ -190,6 +228,7 @@ static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std) if (ret < 0) goto out; + __adv7180_status(client, NULL, &state->curr_norm); state->autodetect = true; } else { ret = v4l2_std_to_adv7180(std); @@ -206,6 +245,7 @@ static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std) } ret = 0; out: + mutex_unlock(&state->mutex); return ret; } @@ -224,6 +264,39 @@ static const struct v4l2_subdev_ops adv7180_ops = { .video = &adv7180_video_ops, }; +static void adv7180_work(struct work_struct *work) +{ + struct adv7180_state *state = container_of(work, struct adv7180_state, + work); + struct i2c_client *client = v4l2_get_subdevdata(&state->sd); + u8 isr3; + + mutex_lock(&state->mutex); + i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG, + ADV7180_ADI_CTRL_IRQ_SPACE); + isr3 = i2c_smbus_read_byte_data(client, ADV7180_ISR3_ADI); + /* clear */ + i2c_smbus_write_byte_data(client, ADV7180_ICR3_ADI, isr3); + i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG, 0); + + if (isr3 & ADV7180_IRQ3_AD_CHANGE && state->autodetect) + __adv7180_status(client, NULL, &state->curr_norm); + mutex_unlock(&state->mutex); + + enable_irq(state->irq); +} + +static irqreturn_t adv7180_irq(int irq, void *devid) +{ + struct adv7180_state *state = devid; + + schedule_work(&state->work); + + disable_irq_nosync(state->irq); + + return IRQ_HANDLED; +} + /* * Generic i2c probe * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' @@ -244,33 +317,111 @@ static __devinit int adv7180_probe(struct i2c_client *client, client->addr << 1, client->adapter->name); state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL); - if (state == NULL) - return -ENOMEM; + if (state == NULL) { + ret = -ENOMEM; + goto err; + } + + state->irq = client->irq; + INIT_WORK(&state->work, adv7180_work); + mutex_init(&state->mutex); state->autodetect = true; sd = &state->sd; v4l2_i2c_subdev_init(sd, client, &adv7180_ops); /* Initialize adv7180 */ - /* enable autodetection */ + /* Enable autodetection */ ret = i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG, ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM); - if (ret > 0) - ret = i2c_smbus_write_byte_data(client, - ADV7180_AUTODETECT_ENABLE_REG, - ADV7180_AUTODETECT_DEFAULT); - if (ret < 0) { - printk(KERN_ERR DRIVER_NAME - ": Failed to communicate to chip: %d\n", ret); - return ret; + if (ret < 0) + goto err_unreg_subdev; + + ret = i2c_smbus_write_byte_data(client, ADV7180_AUTODETECT_ENABLE_REG, + ADV7180_AUTODETECT_DEFAULT); + if (ret < 0) + goto err_unreg_subdev; + + /* ITU-R BT.656-4 compatible */ + ret = i2c_smbus_write_byte_data(client, + ADV7180_EXTENDED_OUTPUT_CONTROL_REG, + ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS); + if (ret < 0) + goto err_unreg_subdev; + + /* read current norm */ + __adv7180_status(client, NULL, &state->curr_norm); + + /* register for interrupts */ + if (state->irq > 0) { + ret = request_irq(state->irq, adv7180_irq, 0, DRIVER_NAME, + state); + if (ret) + goto err_unreg_subdev; + + ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG, + ADV7180_ADI_CTRL_IRQ_SPACE); + if (ret < 0) + goto err_unreg_subdev; + + /* config the Interrupt pin to be active low */ + ret = i2c_smbus_write_byte_data(client, ADV7180_ICONF1_ADI, + ADV7180_ICONF1_ACTIVE_LOW | ADV7180_ICONF1_PSYNC_ONLY); + if (ret < 0) + goto err_unreg_subdev; + + ret = i2c_smbus_write_byte_data(client, ADV7180_IMR1_ADI, 0); + if (ret < 0) + goto err_unreg_subdev; + + ret = i2c_smbus_write_byte_data(client, ADV7180_IMR2_ADI, 0); + if (ret < 0) + goto err_unreg_subdev; + + /* enable AD change interrupts interrupts */ + ret = i2c_smbus_write_byte_data(client, ADV7180_IMR3_ADI, + ADV7180_IRQ3_AD_CHANGE); + if (ret < 0) + goto err_unreg_subdev; + + ret = i2c_smbus_write_byte_data(client, ADV7180_IMR4_ADI, 0); + if (ret < 0) + goto err_unreg_subdev; + + ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG, + 0); + if (ret < 0) + goto err_unreg_subdev; } return 0; + +err_unreg_subdev: + mutex_destroy(&state->mutex); + v4l2_device_unregister_subdev(sd); + kfree(state); +err: + printk(KERN_ERR DRIVER_NAME ": Failed to probe: %d\n", ret); + return ret; } static __devexit int adv7180_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct adv7180_state *state = to_state(sd); + + if (state->irq > 0) { + free_irq(client->irq, state); + if (cancel_work_sync(&state->work)) { + /* + * Work was pending, therefore we need to enable + * IRQ here to balance the disable_irq() done in the + * interrupt handler. + */ + enable_irq(state->irq); + } + } + mutex_destroy(&state->mutex); v4l2_device_unregister_subdev(sd); kfree(to_state(sd)); return 0; -- cgit v1.2.3-70-g09d2 From eea85b0a629970d462481a80e1d45f4d71fe797f Mon Sep 17 00:00:00 2001 From: Richard Röjfors Date: Tue, 22 Sep 2009 10:14:39 -0300 Subject: V4L/DVB (13177): radio: Add support for TEF6862 tuner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds support for TEF6862 Car Radio Enhanced Selectivity Tuner. It's implemented as a subdev, supporting checking signal strength and setting and getting frequency. Signed-off-by: Richard Röjfors Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/Kconfig | 12 +++ drivers/media/radio/Makefile | 1 + drivers/media/radio/tef6862.c | 232 ++++++++++++++++++++++++++++++++++++++++ include/media/v4l2-chip-ident.h | 3 + 4 files changed, 248 insertions(+) create mode 100644 drivers/media/radio/tef6862.c (limited to 'drivers/media') diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index a87a477c87f..931b8b370b5 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -401,4 +401,16 @@ config RADIO_TEA5764_XTAL Say Y here if TEA5764 have a 32768 Hz crystal in circuit, say N here if TEA5764 reference frequency is connected in FREQIN. +config RADIO_TEF6862 + tristate "TEF6862 Car Radio Enhanced Selectivity Tuner" + depends on I2C && VIDEO_V4L2 + ---help--- + Say Y here if you want to use the TEF6862 Car Radio Enhanced + Selectivity Tuner, found for instance on the Russellville development + board. On the russellville the device is connected to internal + timberdale I2C bus. + + To compile this driver as a module, choose M here: the + module will be called TEF6862. + endif # RADIO_ADAPTERS diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile index 2a1be3bf4f7..a4bdca08a94 100644 --- a/drivers/media/radio/Makefile +++ b/drivers/media/radio/Makefile @@ -22,5 +22,6 @@ obj-$(CONFIG_USB_DSBR) += dsbr100.o obj-$(CONFIG_RADIO_SI470X) += si470x/ obj-$(CONFIG_USB_MR800) += radio-mr800.o obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o +obj-$(CONFIG_RADIO_TEF6862) += tef6862.o EXTRA_CFLAGS += -Isound diff --git a/drivers/media/radio/tef6862.c b/drivers/media/radio/tef6862.c new file mode 100644 index 00000000000..6e607ff0c16 --- /dev/null +++ b/drivers/media/radio/tef6862.c @@ -0,0 +1,232 @@ +/* + * tef6862.c Philips TEF6862 Car Radio Enhanced Selectivity Tuner + * Copyright (c) 2009 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "tef6862" + +#define FREQ_MUL 16000 + +#define TEF6862_LO_FREQ (875 * FREQ_MUL / 10) +#define TEF6862_HI_FREQ (108 * FREQ_MUL) + +/* Write mode sub addresses */ +#define WM_SUB_BANDWIDTH 0x0 +#define WM_SUB_PLLM 0x1 +#define WM_SUB_PLLL 0x2 +#define WM_SUB_DAA 0x3 +#define WM_SUB_AGC 0x4 +#define WM_SUB_BAND 0x5 +#define WM_SUB_CONTROL 0x6 +#define WM_SUB_LEVEL 0x7 +#define WM_SUB_IFCF 0x8 +#define WM_SUB_IFCAP 0x9 +#define WM_SUB_ACD 0xA +#define WM_SUB_TEST 0xF + +/* Different modes of the MSA register */ +#define MODE_BUFFER 0x0 +#define MODE_PRESET 0x1 +#define MODE_SEARCH 0x2 +#define MODE_AF_UPDATE 0x3 +#define MODE_JUMP 0x4 +#define MODE_CHECK 0x5 +#define MODE_LOAD 0x6 +#define MODE_END 0x7 +#define MODE_SHIFT 5 + +struct tef6862_state { + struct v4l2_subdev sd; + unsigned long freq; +}; + +static inline struct tef6862_state *to_state(struct v4l2_subdev *sd) +{ + return container_of(sd, struct tef6862_state, sd); +} + +static u16 tef6862_sigstr(struct i2c_client *client) +{ + u8 buf[4]; + int err = i2c_master_recv(client, buf, sizeof(buf)); + if (err == sizeof(buf)) + return buf[3] << 8; + return 0; +} + +static int tef6862_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v) +{ + if (v->index > 0) + return -EINVAL; + + /* only support FM for now */ + strlcpy(v->name, "FM", sizeof(v->name)); + v->type = V4L2_TUNER_RADIO; + v->rangelow = TEF6862_LO_FREQ; + v->rangehigh = TEF6862_HI_FREQ; + v->rxsubchans = V4L2_TUNER_SUB_MONO; + v->capability = V4L2_TUNER_CAP_LOW; + v->audmode = V4L2_TUNER_MODE_STEREO; + v->signal = tef6862_sigstr(v4l2_get_subdevdata(sd)); + + return 0; +} + +static int tef6862_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v) +{ + return v->index ? -EINVAL : 0; +} + +static int tef6862_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) +{ + struct tef6862_state *state = to_state(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); + u16 pll; + u8 i2cmsg[3]; + int err; + + if (f->tuner != 0) + return -EINVAL; + + pll = 1964 + ((f->frequency - TEF6862_LO_FREQ) * 20) / FREQ_MUL; + i2cmsg[0] = (MODE_PRESET << MODE_SHIFT) | WM_SUB_PLLM; + i2cmsg[1] = (pll >> 8) & 0xff; + i2cmsg[2] = pll & 0xff; + + err = i2c_master_send(client, i2cmsg, sizeof(i2cmsg)); + if (!err) + state->freq = f->frequency; + return err; +} + +static int tef6862_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) +{ + struct tef6862_state *state = to_state(sd); + + if (f->tuner != 0) + return -EINVAL; + f->type = V4L2_TUNER_RADIO; + f->frequency = state->freq; + return 0; +} + +static int tef6862_g_chip_ident(struct v4l2_subdev *sd, + struct v4l2_dbg_chip_ident *chip) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEF6862, 0); +} + +static const struct v4l2_subdev_tuner_ops tef6862_tuner_ops = { + .g_tuner = tef6862_g_tuner, + .s_tuner = tef6862_s_tuner, + .s_frequency = tef6862_s_frequency, + .g_frequency = tef6862_g_frequency, +}; + +static const struct v4l2_subdev_core_ops tef6862_core_ops = { + .g_chip_ident = tef6862_g_chip_ident, +}; + +static const struct v4l2_subdev_ops tef6862_ops = { + .core = &tef6862_core_ops, + .tuner = &tef6862_tuner_ops, +}; + +/* + * Generic i2c probe + * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' + */ + +static int __devinit tef6862_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct tef6862_state *state; + struct v4l2_subdev *sd; + + /* Check if the adapter supports the needed features */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -EIO; + + v4l_info(client, "chip found @ 0x%02x (%s)\n", + client->addr << 1, client->adapter->name); + + state = kmalloc(sizeof(struct tef6862_state), GFP_KERNEL); + if (state == NULL) + return -ENOMEM; + state->freq = TEF6862_LO_FREQ; + + sd = &state->sd; + v4l2_i2c_subdev_init(sd, client, &tef6862_ops); + + return 0; +} + +static int __devexit tef6862_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + + v4l2_device_unregister_subdev(sd); + kfree(to_state(sd)); + return 0; +} + +static const struct i2c_device_id tef6862_id[] = { + {DRIVER_NAME, 0}, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, tef6862_id); + +static struct i2c_driver tef6862_driver = { + .driver = { + .owner = THIS_MODULE, + .name = DRIVER_NAME, + }, + .probe = tef6862_probe, + .remove = tef6862_remove, + .id_table = tef6862_id, +}; + +static __init int tef6862_init(void) +{ + return i2c_add_driver(&tef6862_driver); +} + +static __exit void tef6862_exit(void) +{ + i2c_del_driver(&tef6862_driver); +} + +module_init(tef6862_init); +module_exit(tef6862_exit); + +MODULE_DESCRIPTION("TEF6862 Car Radio Enhanced Selectivity Tuner"); +MODULE_AUTHOR("Mocean Laboratories"); +MODULE_LICENSE("GPL v2"); + diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index 43cf26ea673..91942dbe64e 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h @@ -131,6 +131,9 @@ enum { V4L2_IDENT_SAA6752HS = 6752, V4L2_IDENT_SAA6752HS_AC3 = 6753, + /* modules tef6862: just ident 6862 */ + V4L2_IDENT_TEF6862 = 6862, + /* module adv7170: just ident 7170 */ V4L2_IDENT_ADV7170 = 7170, -- cgit v1.2.3-70-g09d2 From a511ba947600ae263f8c29c86020ba66a901d3e5 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 16 Oct 2009 07:13:07 -0300 Subject: V4L/DVB (13178): gspca: Add support for Winbond W9967CF and W9968CF camera's This patch adds support to gspca for the Winbond W9967CF and W9968CF camera's. This is mostly a port of the existing v4l1 driver to gspca (making it v4l2). But this also features fixes to the bitbanging i2c code (send a nack not an ack after reading the last byte of a transfer), which gets rid of the weird errors which were being seen there, and of the smbus_refresh() hack to get around these errors. Also the vstart settings have been tweaked to work with different frequency filter settings. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 11 +- drivers/media/video/gspca/Kconfig | 5 +- drivers/media/video/gspca/gspca.c | 22 +- drivers/media/video/gspca/gspca.h | 1 + drivers/media/video/gspca/ov519.c | 115 +++++-- drivers/media/video/gspca/w996Xcf.c | 589 ++++++++++++++++++++++++++++++++++++ 6 files changed, 713 insertions(+), 30 deletions(-) create mode 100644 drivers/media/video/gspca/w996Xcf.c (limited to 'drivers/media') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 0ab7ccd8729..c69f858c927 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -951,9 +951,13 @@ source "drivers/media/video/usbvideo/Kconfig" source "drivers/media/video/et61x251/Kconfig" config VIDEO_OVCAMCHIP - tristate "OmniVision Camera Chip support" + tristate "OmniVision Camera Chip support (DEPRECATED)" depends on I2C && VIDEO_V4L1 ---help--- + This driver is DEPRECATED please use the gspca ov519 module + instead. Note that for the ov511 / ov518 support of the gspca module + you need atleast version 0.6.0 of libv4l. + Support for the OmniVision OV6xxx and OV7xxx series of camera chips. This driver is intended to be used with the ov511 and w9968cf USB camera drivers. @@ -962,9 +966,12 @@ config VIDEO_OVCAMCHIP module will be called ovcamchip. config USB_W9968CF - tristate "USB W996[87]CF JPEG Dual Mode Camera support" + tristate "USB W996[87]CF JPEG Dual Mode Camera support (DEPRECATED)" depends on VIDEO_V4L1 && I2C && VIDEO_OVCAMCHIP ---help--- + This driver is DEPRECATED please use the gspca ov519 module + instead. + Say Y here if you want support for cameras based on OV681 or Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips. diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig index fe2e490ebc5..cbc2367719f 100644 --- a/drivers/media/video/gspca/Kconfig +++ b/drivers/media/video/gspca/Kconfig @@ -76,10 +76,11 @@ config USB_GSPCA_MR97310A module will be called gspca_mr97310a. config USB_GSPCA_OV519 - tristate "OV519 USB Camera Driver" + tristate "OV51x / OVFX2 / W996xCF USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the OV519 chip. + Say Y here if you want support for cameras based on one of these: + OV511(+), OV518(+), OV519, OVFX2, W9967CF, W9968CF To compile this driver as a module, choose M here: the module will be called gspca_ov519. diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 179cbc14ee5..ebaa2425fb5 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -475,10 +475,18 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev) xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK : USB_ENDPOINT_XFER_ISOC; i = gspca_dev->alt; /* previous alt setting */ - while (--i >= 0) { - ep = alt_xfer(&intf->altsetting[i], xfer); - if (ep) - break; + if (gspca_dev->cam.reverse_alts) { + while (++i < gspca_dev->nbalt) { + ep = alt_xfer(&intf->altsetting[i], xfer); + if (ep) + break; + } + } else { + while (--i >= 0) { + ep = alt_xfer(&intf->altsetting[i], xfer); + if (ep) + break; + } } if (ep == NULL) { err("no transfer endpoint found"); @@ -599,7 +607,11 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) /* set the higher alternate setting and * loop until urb submit succeeds */ - gspca_dev->alt = gspca_dev->nbalt; + if (gspca_dev->cam.reverse_alts) + gspca_dev->alt = 0; + else + gspca_dev->alt = gspca_dev->nbalt; + if (gspca_dev->sd_desc->isoc_init) { ret = gspca_dev->sd_desc->isoc_init(gspca_dev); if (ret < 0) diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 70b1fd83087..1d761d7cefc 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -58,6 +58,7 @@ struct cam { u8 npkt; /* number of packets in an ISOC message * 0 is the default value: 32 packets */ u32 input_flags; /* value for ENUM_INPUT status flags */ + char reverse_alts; /* Alt settings are in high to low order */ }; struct gspca_dev; diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 4d6a762a6f3..994a5e927d2 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -64,6 +64,7 @@ struct sd { #define BRIDGE_OV518PLUS 3 #define BRIDGE_OV519 4 #define BRIDGE_OVFX2 5 +#define BRIDGE_W9968CF 6 #define BRIDGE_MASK 7 char invert_led; @@ -98,8 +99,17 @@ struct sd { #define SEN_OV7670 9 #define SEN_OV76BE 10 #define SEN_OV8610 11 + + u8 sensor_addr; + int sensor_width; + int sensor_height; }; +/* Note this is a bit of a hack, but the w9968cf driver needs the code for all + the ov sensors which is already present here. When we have the time we + really should move the sensor drivers to v4l2 sub drivers. */ +#include "w996Xcf.c" + /* V4L2 controls supported by the driver */ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); @@ -1471,6 +1481,7 @@ static const struct ov_i2c_regvals norm_7610[] = { }; static const struct ov_i2c_regvals norm_7620[] = { + { 0x12, 0x80 }, /* reset */ { 0x00, 0x00 }, /* gain */ { 0x01, 0x80 }, /* blue gain */ { 0x02, 0x80 }, /* red gain */ @@ -1835,10 +1846,9 @@ static unsigned char ov7670_abs_to_sm(unsigned char v) } /* Write a OV519 register */ -static int reg_w(struct sd *sd, __u16 index, __u8 value) +static int reg_w(struct sd *sd, __u16 index, __u16 value) { - int ret; - int req; + int ret, req = 0; switch (sd->bridge) { case BRIDGE_OV511: @@ -1846,11 +1856,14 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value) req = 2; break; case BRIDGE_OVFX2: + req = 0x0a; + /* fall through */ + case BRIDGE_W9968CF: ret = usb_control_msg(sd->gspca_dev.dev, usb_sndctrlpipe(sd->gspca_dev.dev, 0), - 0x0a, + req, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - (__u16)value, index, NULL, 0, 500); + value, index, NULL, 0, 500); goto leave; default: req = 1; @@ -1864,12 +1877,17 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value) 0, index, sd->gspca_dev.usb_buf, 1, 500); leave: - if (ret < 0) - PDEBUG(D_ERR, "Write reg [%02x] %02x failed", index, value); - return ret; + if (ret < 0) { + PDEBUG(D_ERR, "Write reg 0x%04x -> [0x%02x] failed", + value, index); + return ret; + } + + PDEBUG(D_USBO, "Write reg 0x%04x -> [0x%02x]", value, index); + return 0; } -/* Read from a OV519 register */ +/* Read from a OV519 register, note not valid for the w9968cf!! */ /* returns: negative is error, pos or zero is data */ static int reg_r(struct sd *sd, __u16 index) { @@ -1894,10 +1912,12 @@ static int reg_r(struct sd *sd, __u16 index) USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, index, sd->gspca_dev.usb_buf, 1, 500); - if (ret >= 0) + if (ret >= 0) { ret = sd->gspca_dev.usb_buf[0]; - else + PDEBUG(D_USBI, "Read reg [0x%02X] -> 0x%04X", index, ret); + } else PDEBUG(D_ERR, "Read reg [0x%02x] failed", index); + return ret; } @@ -1917,6 +1937,7 @@ static int reg_r8(struct sd *sd, ret = sd->gspca_dev.usb_buf[0]; else PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index); + return ret; } @@ -1962,9 +1983,12 @@ static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, index, sd->gspca_dev.usb_buf, n, 500); - if (ret < 0) + if (ret < 0) { PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value); - return ret; + return ret; + } + + return 0; } static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value) @@ -2156,12 +2180,13 @@ static int ovfx2_i2c_w(struct sd *sd, __u8 reg, __u8 value) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, (__u16)value, (__u16)reg, NULL, 0, 500); - if (ret >= 0) - PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg); - else + if (ret < 0) { PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg); + return ret; + } - return ret; + PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg); + return 0; } static int ovfx2_i2c_r(struct sd *sd, __u8 reg) @@ -2195,6 +2220,8 @@ static int i2c_w(struct sd *sd, __u8 reg, __u8 value) return ov518_i2c_w(sd, reg, value); case BRIDGE_OVFX2: return ovfx2_i2c_w(sd, reg, value); + case BRIDGE_W9968CF: + return w9968cf_i2c_w(sd, reg, value); } return -1; /* Should never happen */ } @@ -2211,6 +2238,8 @@ static int i2c_r(struct sd *sd, __u8 reg) return ov518_i2c_r(sd, reg); case BRIDGE_OVFX2: return ovfx2_i2c_r(sd, reg); + case BRIDGE_W9968CF: + return w9968cf_i2c_r(sd, reg); } return -1; /* Should never happen */ } @@ -2241,6 +2270,8 @@ static int i2c_w_mask(struct sd *sd, * registers while the camera is streaming */ static inline int ov51x_stop(struct sd *sd) { + int ret; + PDEBUG(D_STREAM, "stopping"); sd->stopped = 1; switch (sd->bridge) { @@ -2254,6 +2285,11 @@ static inline int ov51x_stop(struct sd *sd) return reg_w(sd, OV519_SYS_RESET1, 0x0f); case BRIDGE_OVFX2: return reg_w_mask(sd, 0x0f, 0x00, 0x02); + case BRIDGE_W9968CF: + ret = reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */ + ret += reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */ + ret += reg_w(sd, 0x16, 0x0000); /* stop video capture */ + return ret; } return 0; @@ -2285,6 +2321,8 @@ static inline int ov51x_restart(struct sd *sd) return reg_w(sd, OV519_SYS_RESET1, 0x00); case BRIDGE_OVFX2: return reg_w_mask(sd, 0x0f, 0x02, 0x02); + case BRIDGE_W9968CF: + return reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */ } return 0; @@ -2338,8 +2376,13 @@ static int ov51x_set_slave_ids(struct sd *sd, { int rc; - if (sd->bridge == BRIDGE_OVFX2) + switch (sd->bridge) { + case BRIDGE_OVFX2: return reg_w(sd, OVFX2_I2C_ADDR, slave); + case BRIDGE_W9968CF: + sd->sensor_addr = slave; + return 0; + } rc = reg_w(sd, R51x_I2C_W_SID, slave); if (rc < 0) @@ -2920,6 +2963,10 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->bulk_nurbs = MAX_NURBS; cam->bulk = 1; break; + case BRIDGE_W9968CF: + ret = w9968cf_configure(sd); + cam->reverse_alts = 1; + break; } if (ret) @@ -3005,6 +3052,16 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->nmodes = ARRAY_SIZE(ov519_sif_mode); } break; + case BRIDGE_W9968CF: + cam->cam_mode = w9968cf_vga_mode; + cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode); + /* if (sd->sif) + cam->nmodes--; */ + + /* w9968cf needs initialisation once the sensor is known */ + if (w9968cf_init(sd) < 0) + goto error; + break; } sd->brightness = BRIGHTNESS_DEF; if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF) @@ -3753,9 +3810,9 @@ static int set_ov_sensor_window(struct sd *sd) return ret; i2c_w(sd, 0x17, hwsbase); - i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale)); + i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale)); i2c_w(sd, 0x19, vwsbase); - i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale)); + i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale)); return 0; } @@ -3766,6 +3823,10 @@ static int sd_start(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int ret = 0; + /* Default for most bridges, allow bridge_mode_init_regs to override */ + sd->sensor_width = sd->gspca_dev.width; + sd->sensor_height = sd->gspca_dev.height; + switch (sd->bridge) { case BRIDGE_OV511: case BRIDGE_OV511PLUS: @@ -3779,6 +3840,9 @@ static int sd_start(struct gspca_dev *gspca_dev) ret = ov519_mode_init_regs(sd); break; /* case BRIDGE_OVFX2: nothing to do */ + case BRIDGE_W9968CF: + ret = w9968cf_mode_init_regs(sd); + break; } if (ret < 0) goto out; @@ -3980,6 +4044,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, case BRIDGE_OVFX2: ovfx2_pkt_scan(gspca_dev, frame, data, len); break; + case BRIDGE_W9968CF: + w9968cf_pkt_scan(gspca_dev, frame, data, len); + break; } } @@ -4275,8 +4342,12 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) struct sd *sd = (struct sd *) gspca_dev; sd->freq = val; - if (gspca_dev->streaming) + if (gspca_dev->streaming) { setfreq(sd); + /* Ugly but necessary */ + if (sd->bridge == BRIDGE_W9968CF) + w9968cf_set_crop_window(sd); + } return 0; } @@ -4332,6 +4403,7 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF }, {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 }, {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 }, {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 }, @@ -4356,6 +4428,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS }, {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 }, {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 }, + {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF }, {USB_DEVICE(0x8020, 0xEF04), .driver_info = BRIDGE_OVFX2 }, {} }; diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c new file mode 100644 index 00000000000..ba3a28d4f87 --- /dev/null +++ b/drivers/media/video/gspca/w996Xcf.c @@ -0,0 +1,589 @@ +/** + * + * GSPCA sub driver for W996[78]CF JPEG USB Dual Mode Camera Chip. + * + * Copyright (C) 2009 Hans de Goede + * + * This module is adapted from the in kernel v4l1 w9968cf driver: + * + * Copyright (C) 2002-2004 by Luca Risolia + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* Note this is not a stand alone driver, it gets included in ov519.c, this + is a bit of a hack, but it needs the driver code for a lot of different + ov sensors which is already present in ov519.c (the old v4l1 driver used + the ovchipcam framework). When we have the time we really should move + the sensor drivers to v4l2 sub drivers, and properly split of this + driver from ov519.c */ + +#define W9968CF_I2C_BUS_DELAY 4 /* delay in us for I2C bit r/w operations */ + +/* FIXME make this runtime configurable */ +/* Comment/uncomment this for high/low quality of compressed video */ +#define W9968CF_DEC_FAST_LOWQUALITY_VIDEO + +#ifdef W9968CF_DEC_FAST_LOWQUALITY_VIDEO +static const unsigned char Y_QUANTABLE[64] = { + 16, 11, 10, 16, 24, 40, 51, 61, + 12, 12, 14, 19, 26, 58, 60, 55, + 14, 13, 16, 24, 40, 57, 69, 56, + 14, 17, 22, 29, 51, 87, 80, 62, + 18, 22, 37, 56, 68, 109, 103, 77, + 24, 35, 55, 64, 81, 104, 113, 92, + 49, 64, 78, 87, 103, 121, 120, 101, + 72, 92, 95, 98, 112, 100, 103, 99 +}; + +static const unsigned char UV_QUANTABLE[64] = { + 17, 18, 24, 47, 99, 99, 99, 99, + 18, 21, 26, 66, 99, 99, 99, 99, + 24, 26, 56, 99, 99, 99, 99, 99, + 47, 66, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99 +}; +#else +static const unsigned char Y_QUANTABLE[64] = { + 8, 5, 5, 8, 12, 20, 25, 30, + 6, 6, 7, 9, 13, 29, 30, 27, + 7, 6, 8, 12, 20, 28, 34, 28, + 7, 8, 11, 14, 25, 43, 40, 31, + 9, 11, 18, 28, 34, 54, 51, 38, + 12, 17, 27, 32, 40, 52, 56, 46, + 24, 32, 39, 43, 51, 60, 60, 50, + 36, 46, 47, 49, 56, 50, 51, 49 +}; + +static const unsigned char UV_QUANTABLE[64] = { + 8, 9, 12, 23, 49, 49, 49, 49, + 9, 10, 13, 33, 49, 49, 49, 49, + 12, 13, 28, 49, 49, 49, 49, 49, + 23, 33, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49 +}; +#endif + +static const struct v4l2_pix_format w9968cf_vga_mode[] = { + {160, 120, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, + .bytesperline = 160 * 2, + .sizeimage = 160 * 120 * 2, + .colorspace = V4L2_COLORSPACE_JPEG}, + {176, 144, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, + .bytesperline = 176 * 2, + .sizeimage = 176 * 144 * 2, + .colorspace = V4L2_COLORSPACE_JPEG}, + {320, 240, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, + .bytesperline = 320 * 2, + .sizeimage = 320 * 240 * 2, + .colorspace = V4L2_COLORSPACE_JPEG}, + {352, 288, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, + .bytesperline = 352 * 2, + .sizeimage = 352 * 288 * 2, + .colorspace = V4L2_COLORSPACE_JPEG}, +/* {640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, + .bytesperline = 640 * 2, + .sizeimage = 640 * 480 * 2, + .colorspace = V4L2_COLORSPACE_JPEG}, */ +}; + +static int reg_w(struct sd *sd, __u16 index, __u16 value); + +/*-------------------------------------------------------------------------- + Write 64-bit data to the fast serial bus registers. + Return 0 on success, -1 otherwise. + --------------------------------------------------------------------------*/ +static int w9968cf_write_fsb(struct sd *sd, u16* data) +{ + struct usb_device* udev = sd->gspca_dev.dev; + u16 value; + int ret; + + value = *data++; + memcpy(sd->gspca_dev.usb_buf, data, 6); + + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0, + USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, + value, 0x06, sd->gspca_dev.usb_buf, 6, 500); + if (ret < 0) { + PDEBUG(D_ERR, "Write FSB registers failed (%d)", ret); + return ret; + } + + return 0; +} + +/*-------------------------------------------------------------------------- + Write data to the serial bus control register. + Return 0 on success, a negative number otherwise. + --------------------------------------------------------------------------*/ +static int w9968cf_write_sb(struct sd *sd, u16 value) +{ + int ret; + + /* We don't use reg_w here, as that would cause all writes when + bitbanging i2c to be logged, making the logs impossible to read */ + ret = usb_control_msg(sd->gspca_dev.dev, + usb_sndctrlpipe(sd->gspca_dev.dev, 0), + 0, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, 0x01, NULL, 0, 500); + + udelay(W9968CF_I2C_BUS_DELAY); + + if (ret < 0) { + PDEBUG(D_ERR, "Write SB reg [01] %04x failed", value); + return ret; + } + + return 0; +} + +/*-------------------------------------------------------------------------- + Read data from the serial bus control register. + Return 0 on success, a negative number otherwise. + --------------------------------------------------------------------------*/ +static int w9968cf_read_sb(struct sd *sd) +{ + int ret; + + /* We don't use reg_r here, as the w9968cf is special and has 16 + bit registers instead of 8 bit */ + ret = usb_control_msg(sd->gspca_dev.dev, + usb_rcvctrlpipe(sd->gspca_dev.dev, 0), + 1, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, 0x01, sd->gspca_dev.usb_buf, 2, 500); + if (ret >= 0) + ret = sd->gspca_dev.usb_buf[0] | + (sd->gspca_dev.usb_buf[1] << 8); + else + PDEBUG(D_ERR, "Read SB reg [01] failed"); + + udelay(W9968CF_I2C_BUS_DELAY); + + return ret; +} + +/*-------------------------------------------------------------------------- + Upload quantization tables for the JPEG compression. + This function is called by w9968cf_start_transfer(). + Return 0 on success, a negative number otherwise. + --------------------------------------------------------------------------*/ +static int w9968cf_upload_quantizationtables(struct sd *sd) +{ + u16 a, b; + int ret = 0, i, j; + + ret += reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */ + + for (i = 0, j = 0; i < 32; i++, j += 2) { + a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8); + b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8); + ret += reg_w(sd, 0x40+i, a); + ret += reg_w(sd, 0x60+i, b); + } + ret += reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */ + + return ret; +} + +/**************************************************************************** + * Low-level I2C I/O functions. * + * The adapter supports the following I2C transfer functions: * + * i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only) * + * i2c_adap_read_byte_data() * + * i2c_adap_read_byte() * + ****************************************************************************/ + +static int w9968cf_smbus_start(struct sd *sd) +{ + int ret = 0; + + ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */ + ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */ + + return ret; +} + +static int w9968cf_smbus_stop(struct sd *sd) +{ + int ret = 0; + + ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */ + ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */ + ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */ + + return ret; +} + +static int w9968cf_smbus_write_byte(struct sd *sd, u8 v) +{ + u8 bit; + int ret = 0, sda; + + for (bit = 0 ; bit < 8 ; bit++) { + sda = (v & 0x80) ? 2 : 0; + v <<= 1; + /* SDE=1, SDA=sda, SCL=0 */ + ret += w9968cf_write_sb(sd, 0x10 | sda); + /* SDE=1, SDA=sda, SCL=1 */ + ret += w9968cf_write_sb(sd, 0x11 | sda); + /* SDE=1, SDA=sda, SCL=0 */ + ret += w9968cf_write_sb(sd, 0x10 | sda); + } + + return ret; +} + +static int w9968cf_smbus_read_byte(struct sd *sd, u8* v) +{ + u8 bit; + int ret = 0; + + /* No need to ensure SDA is high as we are always called after + read_ack which ends with SDA high */ + *v = 0; + for (bit = 0 ; bit < 8 ; bit++) { + *v <<= 1; + /* SDE=1, SDA=1, SCL=1 */ + ret += w9968cf_write_sb(sd, 0x0013); + *v |= (w9968cf_read_sb(sd) & 0x0008) ? 1 : 0; + /* SDE=1, SDA=1, SCL=0 */ + ret += w9968cf_write_sb(sd, 0x0012); + } + + return ret; +} + +static int w9968cf_smbus_write_nack(struct sd *sd) +{ + int ret = 0; + + /* No need to ensure SDA is high as we are always called after + read_byte which ends with SDA high */ + ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */ + ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */ + + return ret; +} + +static int w9968cf_smbus_read_ack(struct sd *sd) +{ + int ret = 0, sda; + + /* Ensure SDA is high before raising clock to avoid a spurious stop */ + ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */ + ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */ + sda = w9968cf_read_sb(sd); + ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */ + if (sda < 0) + ret += sda; + else if (sda & 0x08) { + PDEBUG(D_USBI, "Did not receive i2c ACK"); + ret += -1; + } + + return ret; +} + +/* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */ +static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value) +{ + u16* data = (u16 *)sd->gspca_dev.usb_buf; + int ret = 0; + + data[0] = 0x082f | ((sd->sensor_addr & 0x80) ? 0x1500 : 0x0); + data[0] |= (sd->sensor_addr & 0x40) ? 0x4000 : 0x0; + data[1] = 0x2082 | ((sd->sensor_addr & 0x40) ? 0x0005 : 0x0); + data[1] |= (sd->sensor_addr & 0x20) ? 0x0150 : 0x0; + data[1] |= (sd->sensor_addr & 0x10) ? 0x5400 : 0x0; + data[2] = 0x8208 | ((sd->sensor_addr & 0x08) ? 0x0015 : 0x0); + data[2] |= (sd->sensor_addr & 0x04) ? 0x0540 : 0x0; + data[2] |= (sd->sensor_addr & 0x02) ? 0x5000 : 0x0; + data[3] = 0x1d20 | ((sd->sensor_addr & 0x02) ? 0x0001 : 0x0); + data[3] |= (sd->sensor_addr & 0x01) ? 0x0054 : 0x0; + + ret += w9968cf_write_fsb(sd, data); + + data[0] = 0x8208 | ((reg & 0x80) ? 0x0015 : 0x0); + data[0] |= (reg & 0x40) ? 0x0540 : 0x0; + data[0] |= (reg & 0x20) ? 0x5000 : 0x0; + data[1] = 0x0820 | ((reg & 0x20) ? 0x0001 : 0x0); + data[1] |= (reg & 0x10) ? 0x0054 : 0x0; + data[1] |= (reg & 0x08) ? 0x1500 : 0x0; + data[1] |= (reg & 0x04) ? 0x4000 : 0x0; + data[2] = 0x2082 | ((reg & 0x04) ? 0x0005 : 0x0); + data[2] |= (reg & 0x02) ? 0x0150 : 0x0; + data[2] |= (reg & 0x01) ? 0x5400 : 0x0; + data[3] = 0x001d; + + ret += w9968cf_write_fsb(sd, data); + + data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0); + data[0] |= (value & 0x40) ? 0x0540 : 0x0; + data[0] |= (value & 0x20) ? 0x5000 : 0x0; + data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0); + data[1] |= (value & 0x10) ? 0x0054 : 0x0; + data[1] |= (value & 0x08) ? 0x1500 : 0x0; + data[1] |= (value & 0x04) ? 0x4000 : 0x0; + data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0); + data[2] |= (value & 0x02) ? 0x0150 : 0x0; + data[2] |= (value & 0x01) ? 0x5400 : 0x0; + data[3] = 0xfe1d; + + ret += w9968cf_write_fsb(sd, data); + + if (!ret) + PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg); + else + PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg); + + return ret; +} + +/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */ +static int w9968cf_i2c_r(struct sd *sd, u8 reg) +{ + int ret = 0; + u8 value; + + /* Fast serial bus data control disable */ + ret += w9968cf_write_sb(sd, 0x0013); /* don't change ! */ + + ret += w9968cf_smbus_start(sd); + ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr); + ret += w9968cf_smbus_read_ack(sd); + ret += w9968cf_smbus_write_byte(sd, reg); + ret += w9968cf_smbus_read_ack(sd); + ret += w9968cf_smbus_stop(sd); + ret += w9968cf_smbus_start(sd); + ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1); + ret += w9968cf_smbus_read_ack(sd); + ret += w9968cf_smbus_read_byte(sd, &value); + /* signal we don't want to read anymore, the v4l1 driver used to + send an ack here which is very wrong! (and then fixed + the issues this gave by retrying reads) */ + ret += w9968cf_smbus_write_nack(sd); + ret += w9968cf_smbus_stop(sd); + + /* Fast serial bus data control re-enable */ + ret += w9968cf_write_sb(sd, 0x0030); + + if (!ret) { + ret = value; + PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value); + } else + PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg); + + return ret; +} + + +/*-------------------------------------------------------------------------- + Turn on the LED on some webcams. A beep should be heard too. + Return 0 on success, a negative number otherwise. + --------------------------------------------------------------------------*/ +static int w9968cf_configure(struct sd *sd) +{ + int ret = 0; + + ret += reg_w(sd, 0x00, 0xff00); /* power-down */ + ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */ + ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */ + ret += reg_w(sd, 0x01, 0x0010); /* serial bus, SDS high */ + ret += reg_w(sd, 0x01, 0x0000); /* serial bus, SDS low */ + ret += reg_w(sd, 0x01, 0x0010); /* ..high 'beep-beep' */ + ret += reg_w(sd, 0x01, 0x0030); /* Set sda scl to FSB mode */ + + if (ret) + PDEBUG(D_ERR, "Couldn't turn on the LED"); + + sd->stopped = 1; + + return ret; +} + +static int w9968cf_init(struct sd *sd) +{ + int ret = 0; + unsigned long hw_bufsize = sd->sif ? (352 * 288 * 2) : (640 * 480 * 2), + y0 = 0x0000, + u0 = y0 + hw_bufsize/2, + v0 = u0 + hw_bufsize/4, + y1 = v0 + hw_bufsize/4, + u1 = y1 + hw_bufsize/2, + v1 = u1 + hw_bufsize/4; + + ret += reg_w(sd, 0x00, 0xff00); /* power off */ + ret += reg_w(sd, 0x00, 0xbf10); /* power on */ + + ret += reg_w(sd, 0x03, 0x405d); /* DRAM timings */ + ret += reg_w(sd, 0x04, 0x0030); /* SDRAM timings */ + + ret += reg_w(sd, 0x20, y0 & 0xffff); /* Y buf.0, low */ + ret += reg_w(sd, 0x21, y0 >> 16); /* Y buf.0, high */ + ret += reg_w(sd, 0x24, u0 & 0xffff); /* U buf.0, low */ + ret += reg_w(sd, 0x25, u0 >> 16); /* U buf.0, high */ + ret += reg_w(sd, 0x28, v0 & 0xffff); /* V buf.0, low */ + ret += reg_w(sd, 0x29, v0 >> 16); /* V buf.0, high */ + + ret += reg_w(sd, 0x22, y1 & 0xffff); /* Y buf.1, low */ + ret += reg_w(sd, 0x23, y1 >> 16); /* Y buf.1, high */ + ret += reg_w(sd, 0x26, u1 & 0xffff); /* U buf.1, low */ + ret += reg_w(sd, 0x27, u1 >> 16); /* U buf.1, high */ + ret += reg_w(sd, 0x2a, v1 & 0xffff); /* V buf.1, low */ + ret += reg_w(sd, 0x2b, v1 >> 16); /* V buf.1, high */ + + ret += reg_w(sd, 0x32, y1 & 0xffff); /* JPEG buf 0 low */ + ret += reg_w(sd, 0x33, y1 >> 16); /* JPEG buf 0 high */ + + ret += reg_w(sd, 0x34, y1 & 0xffff); /* JPEG buf 1 low */ + ret += reg_w(sd, 0x35, y1 >> 16); /* JPEG bug 1 high */ + + ret += reg_w(sd, 0x36, 0x0000);/* JPEG restart interval */ + ret += reg_w(sd, 0x37, 0x0804);/*JPEG VLE FIFO threshold*/ + ret += reg_w(sd, 0x38, 0x0000);/* disable hw up-scaling */ + ret += reg_w(sd, 0x3f, 0x0000); /* JPEG/MCTL test data */ + + return ret; +} + +static int w9968cf_set_crop_window(struct sd *sd) +{ + int ret = 0, start_cropx, start_cropy, x, y, fw, fh, cw, ch, + max_width, max_height; + + if (sd->sif) { + max_width = 352; + max_height = 288; + } else { + max_width = 640; + max_height = 480; + } + + if (sd->sensor == SEN_OV7620) { + /* Sigh, this is dependend on the clock / framerate changes + made by the frequency control, sick. */ + if (sd->freq == 1) { + start_cropx = 279; + start_cropy = 35; + } else { + start_cropx = 103; + start_cropy = 35; + } + } else { + start_cropx = 320; + start_cropy = 35; + } + + /* Work around to avoid FP arithmetics */ + #define SC(x) ((x) << 10) + + /* Scaling factors */ + fw = SC(sd->gspca_dev.width) / max_width; + fh = SC(sd->gspca_dev.height) / max_height; + + cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.width)/fh; + ch = (fw >= fh) ? SC(sd->gspca_dev.height)/fw : max_height; + + sd->sensor_width = max_width; + sd->sensor_height = max_height; + + x = (max_width - cw) / 2; + y = (max_height - ch) / 2; + + ret += reg_w(sd, 0x10, start_cropx + x); + ret += reg_w(sd, 0x11, start_cropy + y); + ret += reg_w(sd, 0x12, start_cropx + x + cw); + ret += reg_w(sd, 0x13, start_cropy + y + ch); + + return ret; +} + +static int w9968cf_mode_init_regs(struct sd *sd) +{ + int ret = 0, val, vs_polarity, hs_polarity; + + ret += w9968cf_set_crop_window(sd); + + ret += reg_w(sd, 0x14, sd->gspca_dev.width); + ret += reg_w(sd, 0x15, sd->gspca_dev.height); + + /* JPEG width & height */ + ret += reg_w(sd, 0x30, sd->gspca_dev.width); + ret += reg_w(sd, 0x31, sd->gspca_dev.height); + + /* Y & UV frame buffer strides (in WORD) */ + ret += reg_w(sd, 0x2c, sd->gspca_dev.width); + + ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */ + ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */ + + /* Transfer size */ + /* FIXME JPEG * 4 ?? */ + val = sd->gspca_dev.width * sd->gspca_dev.height; + ret += reg_w(sd, 0x3d, val & 0xffff); /* low bits */ + ret += reg_w(sd, 0x3e, val >> 16); /* high bits */ + + /* Video Capture Control Register */ + if (sd->sensor == SEN_OV7620) { + /* Seems to work around a bug in the image sensor */ + vs_polarity = 1; + hs_polarity = 1; + } else { + vs_polarity = 1; + hs_polarity = 0; + } + + val = (vs_polarity << 12) | (hs_polarity << 11); + + val |= 0x0080; /* Enable HW double buffering */ + + /* val |= 0x0020; enable clamping */ + /* val |= 0x0008; enable (1-2-1) filter */ + /* val |= 0x000c; enable (2-3-6-3-2) filter */ + + val |= 0x8000; /* capt. enable */ + + ret += reg_w(sd, 0x16, val); + + sd->gspca_dev.empty_packet = 0; + + return ret; +} + +static void w9968cf_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + __u8 *data, /* isoc packet */ + int len) /* iso packet length */ +{ + /* An empty packet signals EOF */ + if (gspca_dev->empty_packet) { + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + data, len); + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + NULL, 0); + gspca_dev->empty_packet = 0; + } + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); +} -- cgit v1.2.3-70-g09d2 From fb1f9020609ead93fcec4b0dd02511a46294c147 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 16 Oct 2009 07:42:53 -0300 Subject: V4L/DVB (13179): gspca_ov519: cache sensor regs to avoid unnecessary slow i2c reads / writes Cache sensor regs to avoid unnecessary slow i2c reads / writes, this speeds up sd_start a bit with most bridges and a lot (from 5 seconds down to 0.3 seconds) with W996xCF cams, as this avoids very slow bit bang IO over USB i2c reads. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov519.c | 53 +++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 994a5e927d2..91e9b23a3a0 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -103,6 +103,7 @@ struct sd { u8 sensor_addr; int sensor_width; int sensor_height; + int sensor_reg_cache[256]; }; /* Note this is a bit of a hack, but the w9968cf driver needs the code for all @@ -2210,38 +2211,70 @@ static int ovfx2_i2c_r(struct sd *sd, __u8 reg) static int i2c_w(struct sd *sd, __u8 reg, __u8 value) { + int ret = -1; + + if (sd->sensor_reg_cache[reg] == value) + return 0; + switch (sd->bridge) { case BRIDGE_OV511: case BRIDGE_OV511PLUS: - return ov511_i2c_w(sd, reg, value); + ret = ov511_i2c_w(sd, reg, value); + break; case BRIDGE_OV518: case BRIDGE_OV518PLUS: case BRIDGE_OV519: - return ov518_i2c_w(sd, reg, value); + ret = ov518_i2c_w(sd, reg, value); + break; case BRIDGE_OVFX2: - return ovfx2_i2c_w(sd, reg, value); + ret = ovfx2_i2c_w(sd, reg, value); + break; case BRIDGE_W9968CF: - return w9968cf_i2c_w(sd, reg, value); + ret = w9968cf_i2c_w(sd, reg, value); + break; + } + + if (ret >= 0) { + /* Up on sensor reset empty the register cache */ + if (reg == 0x12 && (value & 0x80)) + memset(sd->sensor_reg_cache, -1, + sizeof(sd->sensor_reg_cache)); + else + sd->sensor_reg_cache[reg] = value; } - return -1; /* Should never happen */ + + return ret; } static int i2c_r(struct sd *sd, __u8 reg) { + int ret; + + if (sd->sensor_reg_cache[reg] != -1) + return sd->sensor_reg_cache[reg]; + switch (sd->bridge) { case BRIDGE_OV511: case BRIDGE_OV511PLUS: - return ov511_i2c_r(sd, reg); + ret = ov511_i2c_r(sd, reg); + break; case BRIDGE_OV518: case BRIDGE_OV518PLUS: case BRIDGE_OV519: - return ov518_i2c_r(sd, reg); + ret = ov518_i2c_r(sd, reg); + break; case BRIDGE_OVFX2: - return ovfx2_i2c_r(sd, reg); + ret = ovfx2_i2c_r(sd, reg); + break; case BRIDGE_W9968CF: - return w9968cf_i2c_r(sd, reg); + ret = w9968cf_i2c_r(sd, reg); + break; } - return -1; /* Should never happen */ + + if (ret >= 0) + sd->sensor_reg_cache[reg] = ret; + + return ret; } /* Writes bits at positions specified by mask to an I2C reg. Bits that are in -- cgit v1.2.3-70-g09d2 From 8394bcf3fc0293aa5cd07e2a1a3c6bf4e1a5b835 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 16 Oct 2009 11:26:22 -0300 Subject: V4L/DVB (13180): gspca-w9968cf: Don't add an extra packet to the buffer after the EOF gspca-w9968cf: Don't add an extra packet to the buffer after the EOF, this makes the frame data size bigger then it should be which makes gstreamer discard it. This patch also fixes an unrelated compiler warning. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov519.c | 2 +- drivers/media/video/gspca/w996Xcf.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 91e9b23a3a0..ef88e244df1 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -2248,7 +2248,7 @@ static int i2c_w(struct sd *sd, __u8 reg, __u8 value) static int i2c_r(struct sd *sd, __u8 reg) { - int ret; + int ret = -1; if (sd->sensor_reg_cache[reg] != -1) return sd->sensor_reg_cache[reg]; diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c index ba3a28d4f87..3bdc6b405e2 100644 --- a/drivers/media/video/gspca/w996Xcf.c +++ b/drivers/media/video/gspca/w996Xcf.c @@ -580,7 +580,7 @@ static void w9968cf_pkt_scan(struct gspca_dev *gspca_dev, /* An empty packet signals EOF */ if (gspca_dev->empty_packet) { frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, - data, len); + NULL, 0); gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0); gspca_dev->empty_packet = 0; -- cgit v1.2.3-70-g09d2 From 79b359025d57969decb465973f7c0ea195009007 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 19 Oct 2009 06:08:01 -0300 Subject: V4L/DVB (13181): gspca w9968cf: Add support for JPEG compression gspca w9968cf: Add support for JPEG compression, this enables much higher framerates at 320x240 / 352x288 and also allows for 640x480 mode for cams which can do this. The w9968cf uses planar JPEG, which libv4l until now did not support, so this requires atleast version 0.6.3 of libv4l. And something important I forgot to mention in my earlier w9968cf commits: Many thanks to Hans Verkuil for giving me a w9968cf based cam, which has allowed me to develop the gspca w9968cf support. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 6 +- drivers/media/video/gspca/ov519.c | 68 +++++++++++++++-- drivers/media/video/gspca/w996Xcf.c | 143 +++++++++++++++++++++--------------- 3 files changed, 146 insertions(+), 71 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index c69f858c927..7ecae636e6a 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -956,7 +956,8 @@ config VIDEO_OVCAMCHIP ---help--- This driver is DEPRECATED please use the gspca ov519 module instead. Note that for the ov511 / ov518 support of the gspca module - you need atleast version 0.6.0 of libv4l. + you need atleast version 0.6.0 of libv4l and for the w9968cf + atleast version 0.6.3 of libv4l. Support for the OmniVision OV6xxx and OV7xxx series of camera chips. This driver is intended to be used with the ov511 and w9968cf USB @@ -970,7 +971,8 @@ config USB_W9968CF depends on VIDEO_V4L1 && I2C && VIDEO_OVCAMCHIP ---help--- This driver is DEPRECATED please use the gspca ov519 module - instead. + instead. Note that for the w9968cf support of the gspca module + you need atleast version 0.6.3 of libv4l. Say Y here if you want support for cameras based on OV681 or Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips. diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index ef88e244df1..a63cb75aa7f 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -80,6 +80,10 @@ struct sd { __u8 vflip; __u8 autobrightness; __u8 freq; + __u8 quality; +#define QUALITY_MIN 50 +#define QUALITY_MAX 70 +#define QUALITY_DEF 50 __u8 stopped; /* Streaming is temporarily paused */ @@ -104,6 +108,8 @@ struct sd { int sensor_width; int sensor_height; int sensor_reg_cache[256]; + + u8 *jpeg_hdr; }; /* Note this is a bit of a hack, but the w9968cf driver needs the code for all @@ -2303,8 +2309,6 @@ static int i2c_w_mask(struct sd *sd, * registers while the camera is streaming */ static inline int ov51x_stop(struct sd *sd) { - int ret; - PDEBUG(D_STREAM, "stopping"); sd->stopped = 1; switch (sd->bridge) { @@ -2319,10 +2323,7 @@ static inline int ov51x_stop(struct sd *sd) case BRIDGE_OVFX2: return reg_w_mask(sd, 0x0f, 0x00, 0x02); case BRIDGE_W9968CF: - ret = reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */ - ret += reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */ - ret += reg_w(sd, 0x16, 0x0000); /* stop video capture */ - return ret; + return reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */ } return 0; @@ -3088,8 +3089,8 @@ static int sd_config(struct gspca_dev *gspca_dev, case BRIDGE_W9968CF: cam->cam_mode = w9968cf_vga_mode; cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode); - /* if (sd->sif) - cam->nmodes--; */ + if (sd->sif) + cam->nmodes--; /* w9968cf needs initialisation once the sensor is known */ if (w9968cf_init(sd) < 0) @@ -3113,6 +3114,7 @@ static int sd_config(struct gspca_dev *gspca_dev, gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << OV7670_FREQ_IDX); } + sd->quality = QUALITY_DEF; if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670) gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX; /* OV8610 Frequency filter control should work but needs testing */ @@ -3909,6 +3911,14 @@ static void sd_stopN(struct gspca_dev *gspca_dev) ov51x_led_control(sd, 0); } +static void sd_stop0(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + if (sd->bridge == BRIDGE_W9968CF) + w9968cf_stop0(sd); +} + static void ov511_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ __u8 *in, /* isoc packet */ @@ -4421,6 +4431,45 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, return -EINVAL; } +static int sd_get_jcomp(struct gspca_dev *gspca_dev, + struct v4l2_jpegcompression *jcomp) +{ + struct sd *sd = (struct sd *) gspca_dev; + + if (sd->bridge != BRIDGE_W9968CF) + return -EINVAL; + + memset(jcomp, 0, sizeof *jcomp); + jcomp->quality = sd->quality; + jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT | + V4L2_JPEG_MARKER_DRI; + return 0; +} + +static int sd_set_jcomp(struct gspca_dev *gspca_dev, + struct v4l2_jpegcompression *jcomp) +{ + struct sd *sd = (struct sd *) gspca_dev; + + if (sd->bridge != BRIDGE_W9968CF) + return -EINVAL; + + if (gspca_dev->streaming) + return -EBUSY; + + if (jcomp->quality < QUALITY_MIN) + sd->quality = QUALITY_MIN; + else if (jcomp->quality > QUALITY_MAX) + sd->quality = QUALITY_MAX; + else + sd->quality = jcomp->quality; + + /* Return resulting jcomp params to app */ + sd_get_jcomp(gspca_dev, jcomp); + + return 0; +} + /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, @@ -4430,8 +4479,11 @@ static const struct sd_desc sd_desc = { .init = sd_init, .start = sd_start, .stopN = sd_stopN, + .stop0 = sd_stop0, .pkt_scan = sd_pkt_scan, .querymenu = sd_querymenu, + .get_jcomp = sd_get_jcomp, + .set_jcomp = sd_set_jcomp, }; /* -- module initialisation -- */ diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c index 3bdc6b405e2..7378f049508 100644 --- a/drivers/media/video/gspca/w996Xcf.c +++ b/drivers/media/video/gspca/w996Xcf.c @@ -31,57 +31,14 @@ the sensor drivers to v4l2 sub drivers, and properly split of this driver from ov519.c */ -#define W9968CF_I2C_BUS_DELAY 4 /* delay in us for I2C bit r/w operations */ +/* The CONEX_CAM define for jpeg.h needs renaming, now its used here too */ +#define CONEX_CAM +#include "jpeg.h" -/* FIXME make this runtime configurable */ -/* Comment/uncomment this for high/low quality of compressed video */ -#define W9968CF_DEC_FAST_LOWQUALITY_VIDEO - -#ifdef W9968CF_DEC_FAST_LOWQUALITY_VIDEO -static const unsigned char Y_QUANTABLE[64] = { - 16, 11, 10, 16, 24, 40, 51, 61, - 12, 12, 14, 19, 26, 58, 60, 55, - 14, 13, 16, 24, 40, 57, 69, 56, - 14, 17, 22, 29, 51, 87, 80, 62, - 18, 22, 37, 56, 68, 109, 103, 77, - 24, 35, 55, 64, 81, 104, 113, 92, - 49, 64, 78, 87, 103, 121, 120, 101, - 72, 92, 95, 98, 112, 100, 103, 99 -}; +#define W9968CF_I2C_BUS_DELAY 4 /* delay in us for I2C bit r/w operations */ -static const unsigned char UV_QUANTABLE[64] = { - 17, 18, 24, 47, 99, 99, 99, 99, - 18, 21, 26, 66, 99, 99, 99, 99, - 24, 26, 56, 99, 99, 99, 99, 99, - 47, 66, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99 -}; -#else -static const unsigned char Y_QUANTABLE[64] = { - 8, 5, 5, 8, 12, 20, 25, 30, - 6, 6, 7, 9, 13, 29, 30, 27, - 7, 6, 8, 12, 20, 28, 34, 28, - 7, 8, 11, 14, 25, 43, 40, 31, - 9, 11, 18, 28, 34, 54, 51, 38, - 12, 17, 27, 32, 40, 52, 56, 46, - 24, 32, 39, 43, 51, 60, 60, 50, - 36, 46, 47, 49, 56, 50, 51, 49 -}; - -static const unsigned char UV_QUANTABLE[64] = { - 8, 9, 12, 23, 49, 49, 49, 49, - 9, 10, 13, 33, 49, 49, 49, 49, - 12, 13, 28, 49, 49, 49, 49, 49, - 23, 33, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49 -}; -#endif +#define Y_QUANTABLE (sd->jpeg_hdr + JPEG_QT0_OFFSET) +#define UV_QUANTABLE (sd->jpeg_hdr + JPEG_QT1_OFFSET) static const struct v4l2_pix_format w9968cf_vga_mode[] = { {160, 120, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, @@ -92,18 +49,18 @@ static const struct v4l2_pix_format w9968cf_vga_mode[] = { .bytesperline = 176 * 2, .sizeimage = 176 * 144 * 2, .colorspace = V4L2_COLORSPACE_JPEG}, - {320, 240, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, + {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 320 * 2, .sizeimage = 320 * 240 * 2, .colorspace = V4L2_COLORSPACE_JPEG}, - {352, 288, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, + {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 352 * 2, .sizeimage = 352 * 288 * 2, .colorspace = V4L2_COLORSPACE_JPEG}, -/* {640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, + {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 640 * 2, .sizeimage = 640 * 480 * 2, - .colorspace = V4L2_COLORSPACE_JPEG}, */ + .colorspace = V4L2_COLORSPACE_JPEG}, }; static int reg_w(struct sd *sd, __u16 index, __u16 value); @@ -534,17 +491,35 @@ static int w9968cf_mode_init_regs(struct sd *sd) ret += reg_w(sd, 0x31, sd->gspca_dev.height); /* Y & UV frame buffer strides (in WORD) */ + if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat == + V4L2_PIX_FMT_JPEG) { + ret += reg_w(sd, 0x2c, sd->gspca_dev.width/2); + ret += reg_w(sd, 0x2d, sd->gspca_dev.width/4); + } else ret += reg_w(sd, 0x2c, sd->gspca_dev.width); ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */ ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */ - /* Transfer size */ - /* FIXME JPEG * 4 ?? */ + /* Transfer size in WORDS (for UYVY format only) */ val = sd->gspca_dev.width * sd->gspca_dev.height; ret += reg_w(sd, 0x3d, val & 0xffff); /* low bits */ ret += reg_w(sd, 0x3e, val >> 16); /* high bits */ + if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat == + V4L2_PIX_FMT_JPEG) { + /* We may get called multiple times (usb isoc bw negotiat.) */ + if (!sd->jpeg_hdr) + sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); + if (!sd->jpeg_hdr) + return -ENOMEM; + + jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height, + sd->gspca_dev.width, 0x22); /* JPEG 420 */ + jpeg_set_qual(sd->jpeg_hdr, sd->quality); + ret += w9968cf_upload_quantizationtables(sd); + } + /* Video Capture Control Register */ if (sd->sensor == SEN_OV7620) { /* Seems to work around a bug in the image sensor */ @@ -557,6 +532,15 @@ static int w9968cf_mode_init_regs(struct sd *sd) val = (vs_polarity << 12) | (hs_polarity << 11); + /* NOTE: We may not have enough memory to do double buffering while + doing compression (amount of memory differs per model cam). + So we use the second image buffer also as jpeg stream buffer + (see w9968cf_init), and disable double buffering. */ + if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat == + V4L2_PIX_FMT_JPEG) { + /* val |= 0x0002; YUV422P */ + val |= 0x0003; /* YUV420P */ + } else val |= 0x0080; /* Enable HW double buffering */ /* val |= 0x0020; enable clamping */ @@ -572,18 +556,55 @@ static int w9968cf_mode_init_regs(struct sd *sd) return ret; } +static void w9968cf_stop0(struct sd *sd) +{ + if (sd->gspca_dev.present) { + reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */ + reg_w(sd, 0x16, 0x0000); /* stop video capture */ + } + + kfree(sd->jpeg_hdr); + sd->jpeg_hdr = NULL; +} + +/* The w9968cf docs say that a 0 sized packet means EOF (and also SOF + for the next frame). This seems to simply not be true when operating + in JPEG mode, in this case there may be empty packets within the + frame. So in JPEG mode use the JPEG SOI marker to detect SOF. + + Note to make things even more interesting the w9968cf sends *PLANAR* jpeg, + to be precise it sends: SOI, SOF, DRI, SOS, Y-data, SOS, U-data, SOS, + V-data, EOI. */ static void w9968cf_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ __u8 *data, /* isoc packet */ int len) /* iso packet length */ { - /* An empty packet signals EOF */ - if (gspca_dev->empty_packet) { - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + struct sd *sd = (struct sd *) gspca_dev; + + if (w9968cf_vga_mode[gspca_dev->curr_mode].pixelformat == + V4L2_PIX_FMT_JPEG) { + if (len >= 2 && + data[0] == 0xff && + data[1] == 0xd8) { + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, NULL, 0); - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - NULL, 0); - gspca_dev->empty_packet = 0; + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + sd->jpeg_hdr, JPEG_HDR_SZ); + /* Strip the ff d8, our own header (which adds + huffman and quantization tables) already has this */ + len -= 2; + data += 2; + } + } else { + /* In UYVY mode an empty packet signals EOF */ + if (gspca_dev->empty_packet) { + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + NULL, 0); + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + NULL, 0); + gspca_dev->empty_packet = 0; + } } gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); } -- cgit v1.2.3-70-g09d2 From 73997870c64d604f521e85a57511f36a2dc22ed0 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 19 Oct 2009 06:47:03 -0300 Subject: V4L/DVB (13182): gspca w9968cf: slight tweak to vstart and hstart gspca w9968cf: slight tweak to vstart and hstart to get rid of black borders in 640x480 mode. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/w996Xcf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c index 7378f049508..4f9add79ce1 100644 --- a/drivers/media/video/gspca/w996Xcf.c +++ b/drivers/media/video/gspca/w996Xcf.c @@ -442,11 +442,11 @@ static int w9968cf_set_crop_window(struct sd *sd) /* Sigh, this is dependend on the clock / framerate changes made by the frequency control, sick. */ if (sd->freq == 1) { - start_cropx = 279; - start_cropy = 35; + start_cropx = 277; + start_cropy = 37; } else { - start_cropx = 103; - start_cropy = 35; + start_cropx = 105; + start_cropy = 37; } } else { start_cropx = 320; -- cgit v1.2.3-70-g09d2 From 21f1b932dbcc5ed18444e6995aeb856e583804ae Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 23 Oct 2009 06:50:12 -0300 Subject: V4L/DVB (13183): gspca: add stv0680 subdriver This patch adds a new subdriver to gspca supporting cams with the stv0680 bridge (replacing the old in kernel v4l1 driver). Many thanks to Hans Verkuil for providing me with one of the 2 cams used in testing this new sub driver. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 6 +- drivers/media/video/gspca/Kconfig | 9 + drivers/media/video/gspca/Makefile | 2 + drivers/media/video/gspca/stv0680.c | 365 ++++++++++++++++++++++++++++++++++++ include/linux/videodev2.h | 1 + 5 files changed, 382 insertions(+), 1 deletion(-) create mode 100644 drivers/media/video/gspca/stv0680.c (limited to 'drivers/media') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 7ecae636e6a..82ae85c975f 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -1016,9 +1016,13 @@ config USB_SE401 source "drivers/media/video/sn9c102/Kconfig" config USB_STV680 - tristate "USB STV680 (Pencam) Camera support" + tristate "USB STV680 (Pencam) Camera support (DEPRECATED)" depends on VIDEO_V4L1 ---help--- + This driver is DEPRECATED please use the gspca stv0680 module + instead. Note that for the gspca stv0680 module you need + atleast version 0.6.3 of libv4l. + Say Y here if you want to connect this type of camera to your computer's USB port. This includes the Pencam line of cameras. See for more information diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig index cbc2367719f..568edbbb894 100644 --- a/drivers/media/video/gspca/Kconfig +++ b/drivers/media/video/gspca/Kconfig @@ -230,6 +230,15 @@ config USB_GSPCA_STK014 To compile this driver as a module, choose M here: the module will be called gspca_stk014. +config USB_GSPCA_STV0680 + tristate "STV0680 USB Camera Driver" + depends on VIDEO_V4L2 && USB_GSPCA + help + Say Y here if you want support for cameras based on the STV0680 chip. + + To compile this driver as a module, choose M here: the + module will be called gspca_stv0680. + config USB_GSPCA_SUNPLUS tristate "SUNPLUS USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile index b7420818037..770b01387e9 100644 --- a/drivers/media/video/gspca/Makefile +++ b/drivers/media/video/gspca/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_USB_GSPCA_SQ905) += gspca_sq905.o obj-$(CONFIG_USB_GSPCA_SQ905C) += gspca_sq905c.o obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o +obj-$(CONFIG_USB_GSPCA_STV0680) += gspca_stv0680.o obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o @@ -50,6 +51,7 @@ gspca_spca561-objs := spca561.o gspca_sq905-objs := sq905.o gspca_sq905c-objs := sq905c.o gspca_stk014-objs := stk014.o +gspca_stv0680-objs := stv0680.o gspca_sunplus-objs := sunplus.o gspca_t613-objs := t613.o gspca_tv8532-objs := tv8532.o diff --git a/drivers/media/video/gspca/stv0680.c b/drivers/media/video/gspca/stv0680.c new file mode 100644 index 00000000000..0981ce14235 --- /dev/null +++ b/drivers/media/video/gspca/stv0680.c @@ -0,0 +1,365 @@ +/* + * STV0680 USB Camera Driver + * + * Copyright (C) 2009 Hans de Goede + * + * This module is adapted from the in kernel v4l1 stv680 driver: + * + * STV0680 USB Camera Driver, by Kevin Sisson (kjsisson@bellsouth.net) + * + * Thanks to STMicroelectronics for information on the usb commands, and + * to Steve Miller at STM for his help and encouragement while I was + * writing this driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define MODULE_NAME "stv0680" + +#include "gspca.h" + +MODULE_AUTHOR("Hans de Goede "); +MODULE_DESCRIPTION("STV0680 USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + struct v4l2_pix_format mode; + u8 orig_mode; + u8 video_mode; + u8 current_mode; +}; + +/* V4L2 controls supported by the driver */ +static struct ctrl sd_ctrls[] = { +}; + +static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val, + int size) +{ + int ret = -1; + u8 req_type = 0; + + switch (set) { + case 0: /* 0xc1 */ + req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT; + break; + case 1: /* 0x41 */ + req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT; + break; + case 2: /* 0x80 */ + req_type = USB_DIR_IN | USB_RECIP_DEVICE; + break; + case 3: /* 0x40 */ + req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; + break; + } + + ret = usb_control_msg(gspca_dev->dev, + usb_rcvctrlpipe(gspca_dev->dev, 0), + req, req_type, + val, 0, gspca_dev->usb_buf, size, 500); + + if ((ret < 0) && (req != 0x0a)) + PDEBUG(D_ERR, + "usb_control_msg error %i, request = 0x%x, error = %i", + set, req, ret); + + return ret; +} + +static int stv0680_handle_error(struct gspca_dev *gspca_dev, int ret) +{ + stv_sndctrl(gspca_dev, 0, 0x80, 0, 0x02); /* Get Last Error */ + PDEBUG(D_ERR, "last error: %i, command = 0x%x", + gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); + return ret; +} + +static int stv0680_get_video_mode(struct gspca_dev *gspca_dev) +{ + /* Note not sure if this init of usb_buf is really necessary */ + memset(gspca_dev->usb_buf, 0, 8); + gspca_dev->usb_buf[0] = 0x0f; + + if (stv_sndctrl(gspca_dev, 0, 0x87, 0, 0x08) != 0x08) { + PDEBUG(D_ERR, "Get_Camera_Mode failed"); + return stv0680_handle_error(gspca_dev, -EIO); + } + + return gspca_dev->usb_buf[0]; /* 01 = VGA, 03 = QVGA, 00 = CIF */ +} + +static int stv0680_set_video_mode(struct gspca_dev *gspca_dev, u8 mode) +{ + struct sd *sd = (struct sd *) gspca_dev; + + if (sd->current_mode == mode) + return 0; + + memset(gspca_dev->usb_buf, 0, 8); + gspca_dev->usb_buf[0] = mode; + + if (stv_sndctrl(gspca_dev, 3, 0x07, 0x0100, 0x08) != 0x08) { + PDEBUG(D_ERR, "Set_Camera_Mode failed"); + return stv0680_handle_error(gspca_dev, -EIO); + } + + /* Verify we got what we've asked for */ + if (stv0680_get_video_mode(gspca_dev) != mode) { + PDEBUG(D_ERR, "Error setting camera video mode!"); + return -EIO; + } + + sd->current_mode = mode; + + return 0; +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + int ret; + struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam = &gspca_dev->cam; + + /* ping camera to be sure STV0680 is present */ + if (stv_sndctrl(gspca_dev, 0, 0x88, 0x5678, 0x02) != 0x02 || + gspca_dev->usb_buf[0] != 0x56 || gspca_dev->usb_buf[1] != 0x78) { + PDEBUG(D_ERR, "STV(e): camera ping failed!!"); + return stv0680_handle_error(gspca_dev, -ENODEV); + } + + /* get camera descriptor */ + if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x09) != 0x09) + return stv0680_handle_error(gspca_dev, -ENODEV); + + if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x22) != 0x22 || + gspca_dev->usb_buf[7] != 0xa0 || gspca_dev->usb_buf[8] != 0x23) { + PDEBUG(D_ERR, "Could not get descriptor 0200."); + return stv0680_handle_error(gspca_dev, -ENODEV); + } + if (stv_sndctrl(gspca_dev, 0, 0x8a, 0, 0x02) != 0x02) + return stv0680_handle_error(gspca_dev, -ENODEV); + if (stv_sndctrl(gspca_dev, 0, 0x8b, 0, 0x24) != 0x24) + return stv0680_handle_error(gspca_dev, -ENODEV); + if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10) + return stv0680_handle_error(gspca_dev, -ENODEV); + + if (!(gspca_dev->usb_buf[7] & 0x09)) { + PDEBUG(D_ERR, "Camera supports neither CIF nor QVGA mode"); + return -ENODEV; + } + if (gspca_dev->usb_buf[7] & 0x01) + PDEBUG(D_PROBE, "Camera supports CIF mode"); + if (gspca_dev->usb_buf[7] & 0x02) + PDEBUG(D_PROBE, "Camera supports VGA mode"); + if (gspca_dev->usb_buf[7] & 0x08) + PDEBUG(D_PROBE, "Camera supports QVGA mode"); + + if (gspca_dev->usb_buf[7] & 0x01) + sd->video_mode = 0x00; /* CIF */ + else + sd->video_mode = 0x03; /* QVGA */ + + /* FW rev, ASIC rev, sensor ID */ + PDEBUG(D_PROBE, "Firmware rev is %i.%i", + gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); + PDEBUG(D_PROBE, "ASIC rev is %i.%i", + gspca_dev->usb_buf[2], gspca_dev->usb_buf[3]); + PDEBUG(D_PROBE, "Sensor ID is %i", + (gspca_dev->usb_buf[4]*16) + (gspca_dev->usb_buf[5]>>4)); + + + ret = stv0680_get_video_mode(gspca_dev); + if (ret < 0) + return ret; + sd->current_mode = sd->orig_mode = ret; + + ret = stv0680_set_video_mode(gspca_dev, sd->video_mode); + if (ret < 0) + return ret; + + /* Get mode details */ + if (stv_sndctrl(gspca_dev, 0, 0x8f, 0, 0x10) != 0x10) + return stv0680_handle_error(gspca_dev, -EIO); + + cam->bulk = 1; + cam->bulk_nurbs = 1; /* The cam cannot handle more */ + cam->bulk_size = (gspca_dev->usb_buf[0] << 24) | + (gspca_dev->usb_buf[1] << 16) | + (gspca_dev->usb_buf[2] << 8) | + (gspca_dev->usb_buf[3]); + sd->mode.width = (gspca_dev->usb_buf[4] << 8) | + (gspca_dev->usb_buf[5]); /* 322, 356, 644 */ + sd->mode.height = (gspca_dev->usb_buf[6] << 8) | + (gspca_dev->usb_buf[7]); /* 242, 292, 484 */ + sd->mode.pixelformat = V4L2_PIX_FMT_STV0680; + sd->mode.field = V4L2_FIELD_NONE; + sd->mode.bytesperline = sd->mode.width; + sd->mode.sizeimage = cam->bulk_size; + sd->mode.colorspace = V4L2_COLORSPACE_SRGB; + + /* origGain = gspca_dev->usb_buf[12]; */ + + cam->cam_mode = &sd->mode; + cam->nmodes = 1; + + + ret = stv0680_set_video_mode(gspca_dev, sd->orig_mode); + if (ret < 0) + return ret; + + if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0100, 0x12) != 0x12 || + gspca_dev->usb_buf[8] != 0x53 || gspca_dev->usb_buf[9] != 0x05) { + PDEBUG(D_ERR, "Could not get descriptor 0100."); + return stv0680_handle_error(gspca_dev, -EIO); + } + + return 0; +} + +/* this function is called at probe and resume time */ +static int sd_init(struct gspca_dev *gspca_dev) +{ + return 0; +} + +/* -- start the camera -- */ +static int sd_start(struct gspca_dev *gspca_dev) +{ + int ret; + struct sd *sd = (struct sd *) gspca_dev; + + ret = stv0680_set_video_mode(gspca_dev, sd->video_mode); + if (ret < 0) + return ret; + + if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10) + return stv0680_handle_error(gspca_dev, -EIO); + + /* Start stream at: + 0x0000 = CIF (352x288) + 0x0100 = VGA (640x480) + 0x0300 = QVGA (320x240) */ + if (stv_sndctrl(gspca_dev, 1, 0x09, sd->video_mode << 8, 0x0) != 0x0) + return stv0680_handle_error(gspca_dev, -EIO); + + return 0; +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + /* This is a high priority command; it stops all lower order cmds */ + if (stv_sndctrl(gspca_dev, 1, 0x04, 0x0000, 0x0) != 0x0) + stv0680_handle_error(gspca_dev, -EIO); +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + if (!sd->gspca_dev.present) + return; + + stv0680_set_video_mode(gspca_dev, sd->orig_mode); +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, + __u8 *data, + int len) +{ + struct sd *sd = (struct sd *) gspca_dev; + + /* Every now and then the camera sends a 16 byte packet, no idea + what it contains, but it is not image data, when this + happens the frame received before this packet is corrupt, + so discard it. */ + if (len != sd->mode.sizeimage) { + gspca_dev->last_packet_type = DISCARD_PACKET; + return; + } + + /* Finish the previous frame, we do this upon reception of the next + packet, even though it is already complete so that the strange 16 + byte packets send after a corrupt frame can discard it. */ + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, NULL, 0); + + /* Store the just received frame */ + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); +} + +/* sub-driver description */ +static const struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .init = sd_init, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +static const __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x0553, 0x0202)}, + {USB_DEVICE(0x041e, 0x4007)}, + {} +}; +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) + return ret; + PDEBUG(D_PROBE, "registered"); + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index b59e78c5716..b9a799a3576 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -361,6 +361,7 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */ #define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */ #define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */ +#define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */ /* * F O R M A T E N U M E R A T I O N -- cgit v1.2.3-70-g09d2 From bf926adfbbb36876396511f1bdc78f73dc596e21 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 23 Oct 2009 06:56:06 -0300 Subject: V4L/DVB (13184): gspca: Don't forget to resubmit URB's in case of an error The gscpa core was not resubmitting URB's when the URB status was an error, this means we will loose URB's (potentially all stopping the stream) in case of sporadic USB issues. I've seen this with an Aiptek stv0680 based PenCam connected through an USB 2.0 hub. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index ebaa2425fb5..3298e33c782 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -138,7 +138,7 @@ static void fill_frame(struct gspca_dev *gspca_dev, if (!gspca_dev->frozen) #endif PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); - return; + goto resubmit; } pkt_scan = gspca_dev->sd_desc->pkt_scan; for (i = 0; i < urb->number_of_packets; i++) { @@ -174,6 +174,7 @@ static void fill_frame(struct gspca_dev *gspca_dev, pkt_scan(gspca_dev, frame, data, len); } +resubmit: /* resubmit the URB */ st = usb_submit_urb(urb, GFP_ATOMIC); if (st < 0) @@ -220,7 +221,7 @@ static void bulk_irq(struct urb *urb) if (!gspca_dev->frozen) #endif PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); - return; + goto resubmit; } /* check the availability of the frame buffer */ @@ -235,6 +236,7 @@ static void bulk_irq(struct urb *urb) urb->actual_length); } +resubmit: /* resubmit the URB */ if (gspca_dev->cam.bulk_nurbs != 0) { st = usb_submit_urb(urb, GFP_ATOMIC); -- cgit v1.2.3-70-g09d2 From 6a540bdf0134fc7198dd053a352b4c414a5e7e19 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 24 Oct 2009 15:02:14 -0300 Subject: V4L/DVB (13185): gspca: Don't resubmit error status URB's when suspending gspca: Don't resubmit error status URB's when suspending Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 3298e33c782..eb166048540 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -135,9 +135,10 @@ static void fill_frame(struct gspca_dev *gspca_dev, if (urb->status == -ESHUTDOWN) return; /* disconnection */ #ifdef CONFIG_PM - if (!gspca_dev->frozen) + if (gspca_dev->frozen) + return; #endif - PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); + PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); goto resubmit; } pkt_scan = gspca_dev->sd_desc->pkt_scan; @@ -218,9 +219,10 @@ static void bulk_irq(struct urb *urb) break; default: #ifdef CONFIG_PM - if (!gspca_dev->frozen) + if (gspca_dev->frozen) + return; #endif - PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); + PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); goto resubmit; } -- cgit v1.2.3-70-g09d2 From 36a91879d85396ea6470d3a5bde8287e40b5a0e9 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Tue, 13 Oct 2009 23:32:29 -0300 Subject: V4L/DVB (13187): au8522: add support for saturation and hue controls Add support for saturation/hue controls, prompted by errors showing up in the mythbackend log. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/au8522_decoder.c | 22 ++++++++++++++++++++-- drivers/media/dvb/frontends/au8522_priv.h | 2 ++ 2 files changed, 22 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c index 74981ee923c..dee609cdd77 100644 --- a/drivers/media/dvb/frontends/au8522_decoder.c +++ b/drivers/media/dvb/frontends/au8522_decoder.c @@ -23,7 +23,6 @@ /* Developer notes: * * VBI support is not yet working - * Saturation and hue setting are not yet working * Enough is implemented here for CVBS and S-Video inputs, but the actual * analog demodulator code isn't implemented (not needed for xc5000 since it * has its own demodulator and outputs CVBS) @@ -236,8 +235,10 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode) state->contrast = 0x79; au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80); au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80); + state->saturation = 0x80; au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00); au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00); + state->hue = 0x00; /* Other decoder registers */ au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00); @@ -504,7 +505,19 @@ static int au8522_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) ctrl->value); break; case V4L2_CID_SATURATION: + state->saturation = ctrl->value; + au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, + ctrl->value); + au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, + ctrl->value); + break; case V4L2_CID_HUE: + state->hue = ctrl->value; + au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, + ctrl->value >> 8); + au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, + ctrl->value & 0xFF); + break; case V4L2_CID_AUDIO_VOLUME: case V4L2_CID_AUDIO_BASS: case V4L2_CID_AUDIO_TREBLE: @@ -534,7 +547,11 @@ static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) ctrl->value = state->contrast; break; case V4L2_CID_SATURATION: + ctrl->value = state->saturation; + break; case V4L2_CID_HUE: + ctrl->value = state->hue; + break; case V4L2_CID_AUDIO_VOLUME: case V4L2_CID_AUDIO_BASS: case V4L2_CID_AUDIO_TREBLE: @@ -632,8 +649,9 @@ static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) case V4L2_CID_BRIGHTNESS: return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128); case V4L2_CID_SATURATION: + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128); case V4L2_CID_HUE: - /* Not yet implemented */ + return v4l2_ctrl_query_fill(qc, -32768, 32768, 1, 0); default: break; } diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb/frontends/au8522_priv.h index f328f2b3ad3..c74c4e72fe9 100644 --- a/drivers/media/dvb/frontends/au8522_priv.h +++ b/drivers/media/dvb/frontends/au8522_priv.h @@ -62,6 +62,8 @@ struct au8522_state { u32 rev; u8 brightness; u8 contrast; + u8 saturation; + s16 hue; }; /* These are routines shared by both the VSB/QAM demodulator and the analog -- cgit v1.2.3-70-g09d2 From 760c466c66db40cde5953e93b94ae20c7610fb20 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Tue, 13 Oct 2009 23:44:14 -0300 Subject: V4L/DVB (13188): xc5000: return an error on tuning attempts if firmware not loaded Xc5000 tuning attempts shouldn't return zero in the case where the firmware did not load successfully. Thanks to Michael Krufky for pointing out this issue. Cc: Michael Krufky Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/xc5000.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index d33bf831e76..432003dded7 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c @@ -633,8 +633,12 @@ static int xc5000_set_params(struct dvb_frontend *fe, struct xc5000_priv *priv = fe->tuner_priv; int ret; - if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) - xc_load_fw_and_init_tuner(fe); + if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) { + if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) { + dprintk(1, "Unable to load firmware and init tuner\n"); + return -EINVAL; + } + } dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency); @@ -884,8 +888,12 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe, if (priv->i2c_props.adap == NULL) return -EINVAL; - if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) - xc_load_fw_and_init_tuner(fe); + if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) { + if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) { + dprintk(1, "Unable to load firmware and init tuner\n"); + return -EINVAL; + } + } switch (params->mode) { case V4L2_TUNER_RADIO: -- cgit v1.2.3-70-g09d2 From e0d49e2d3ae3cd887b7999c4227c04008d2a02c4 Mon Sep 17 00:00:00 2001 From: Marton Nemeth Date: Mon, 5 Oct 2009 05:41:30 -0300 Subject: V4L/DVB (13192): gspca - pac_common: redesign function for finding Start Of Frame The original implementation of pac_find_sof() does not always find the Start Of Frame (SOF) marker. Replace it with a state machine based design. Acked-by: Hans de Goede Signed-off-by: Marton Nemeth Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac_common.h | 84 ++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac_common.h b/drivers/media/video/gspca/pac_common.h index 34d4b1494cd..d3006539fb8 100644 --- a/drivers/media/video/gspca/pac_common.h +++ b/drivers/media/video/gspca/pac_common.h @@ -33,6 +33,45 @@ static const unsigned char pac_sof_marker[5] = { 0xff, 0xff, 0x00, 0xff, 0x96 }; +/* + The following state machine finds the SOF marker sequence + 0xff, 0xff, 0x00, 0xff, 0x96 in a byte stream. + + +----------+ + | 0: START |<---------------\ + +----------+<-\ | + | \---/otherwise | + v 0xff | + +----------+ otherwise | + | 1 |--------------->* + | | ^ + +----------+ | + | | + v 0xff | + +----------+<-\0xff | + /->| |--/ | + | | 2 |--------------->* + | | | otherwise ^ + | +----------+ | + | | | + | v 0x00 | + | +----------+ | + | | 3 | | + | | |--------------->* + | +----------+ otherwise ^ + | | | + 0xff | v 0xff | + | +----------+ | + \--| 4 | | + | |----------------/ + +----------+ otherwise + | + v 0x96 + +----------+ + | FOUND | + +----------+ +*/ + static unsigned char *pac_find_sof(struct gspca_dev *gspca_dev, unsigned char *m, int len) { @@ -41,17 +80,54 @@ static unsigned char *pac_find_sof(struct gspca_dev *gspca_dev, /* Search for the SOF marker (fixed part) in the header */ for (i = 0; i < len; i++) { - if (m[i] == pac_sof_marker[sd->sof_read]) { - sd->sof_read++; - if (sd->sof_read == sizeof(pac_sof_marker)) { + switch (sd->sof_read) { + case 0: + if (m[i] == 0xff) + sd->sof_read = 1; + break; + case 1: + if (m[i] == 0xff) + sd->sof_read = 2; + else + sd->sof_read = 0; + break; + case 2: + switch (m[i]) { + case 0x00: + sd->sof_read = 3; + break; + case 0xff: + /* stay in this state */ + break; + default: + sd->sof_read = 0; + } + break; + case 3: + if (m[i] == 0xff) + sd->sof_read = 4; + else + sd->sof_read = 0; + break; + case 4: + switch (m[i]) { + case 0x96: + /* Pattern found */ PDEBUG(D_FRAM, "SOF found, bytes to analyze: %u." " Frame starts at byte #%u", len, i + 1); sd->sof_read = 0; return m + i + 1; + break; + case 0xff: + sd->sof_read = 2; + break; + default: + sd->sof_read = 0; } - } else { + break; + default: sd->sof_read = 0; } } -- cgit v1.2.3-70-g09d2 From 013db7575bdfb57d295e9a27186f52c7547ef2d2 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 7 Oct 2009 05:24:19 -0300 Subject: V4L/DVB (13193): gspca - zc3xx.c: Change init sequences of sensor tas5130c. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/zc3xx.c | 228 ++++++++++++-------------------------- 1 file changed, 69 insertions(+), 159 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index e544630757c..0aa87d2958a 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -5481,7 +5481,7 @@ static const struct usb_action tas5130CK_InitialScale[] = { {} }; -static const struct usb_action tas5130cxx_Initial[] = { +static const struct usb_action tas5130cxx_InitialScale[] = { /* 320x240 */ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, {0xa0, 0x50, ZC3XX_R002_CLOCKSELECT}, {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, @@ -5510,74 +5510,19 @@ static const struct usb_action tas5130cxx_Initial[] = { {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x68, ZC3XX_R18D_YTARGET}, - {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, + {0xa0, 0x95, ZC3XX_R18D_YTARGET}, + {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, {0xa0, 0x00, 0x01ad}, {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xa1, 0x01, 0x0002}, - {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {0xa1, 0x01, 0x01c8}, - {0xa1, 0x01, 0x01c9}, - {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ - - {0xa0, 0x68, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xec, ZC3XX_R10B_RGB01}, - {0xa0, 0xec, ZC3XX_R10C_RGB02}, - {0xa0, 0xec, ZC3XX_R10D_RGB10}, - {0xa0, 0x68, ZC3XX_R10E_RGB11}, - {0xa0, 0xec, ZC3XX_R10F_RGB12}, - {0xa0, 0xec, ZC3XX_R110_RGB20}, - {0xa0, 0xec, ZC3XX_R111_RGB21}, - {0xa0, 0x68, ZC3XX_R112_RGB22}, - - {0xa1, 0x01, 0x018d}, - {0xa0, 0x90, ZC3XX_R18D_YTARGET}, /* 90 */ - {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - - {0xaa, 0xa3, 0x0001}, - {0xaa, 0xa4, 0x0077}, - {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, - {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, - - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 00 */ - {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 03 */ - {0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* e8 */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 0 */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 0 */ - {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 7d */ - - {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 08 */ - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 24 */ - {0xa0, 0xf0, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, - {0xa0, 0xc0, ZC3XX_R0A0_MAXXLOW}, - {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, /* 50 */ - {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {} }; -static const struct usb_action tas5130cxx_InitialScale[] = { -/*?? {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, */ +static const struct usb_action tas5130cxx_Initial[] = { /* 640x480 */ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa1, 0x01, 0x0008}, - {0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT}, {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, {0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING}, @@ -5601,63 +5546,13 @@ static const struct usb_action tas5130cxx_InitialScale[] = { {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x68, ZC3XX_R18D_YTARGET}, - {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, + {0xa0, 0x95, ZC3XX_R18D_YTARGET}, + {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, {0xa0, 0x00, 0x01ad}, {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xa1, 0x01, 0x0002}, - {0xa1, 0x01, 0x0008}, - - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa1, 0x01, 0x0008}, /* clock ? */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {0xa1, 0x01, 0x01c8}, - {0xa1, 0x01, 0x01c9}, - {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ - - {0xa0, 0x68, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xec, ZC3XX_R10B_RGB01}, - {0xa0, 0xec, ZC3XX_R10C_RGB02}, - {0xa0, 0xec, ZC3XX_R10D_RGB10}, - {0xa0, 0x68, ZC3XX_R10E_RGB11}, - {0xa0, 0xec, ZC3XX_R10F_RGB12}, - {0xa0, 0xec, ZC3XX_R110_RGB20}, - {0xa0, 0xec, ZC3XX_R111_RGB21}, - {0xa0, 0x68, ZC3XX_R112_RGB22}, - - {0xa1, 0x01, 0x018d}, - {0xa0, 0x90, ZC3XX_R18D_YTARGET}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0xa3, 0x0001}, - {0xaa, 0xa4, 0x0063}, - {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, - {0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x38, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0xd3, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xda, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, - {0xa0, 0x4c, ZC3XX_R0A0_MAXXLOW}, - {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {} }; static const struct usb_action tas5130cxx_50HZ[] = { @@ -5667,20 +5562,22 @@ static const struct usb_action tas5130cxx_50HZ[] = { {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ {0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,63,cc */ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */ - {0xa0, 0x38, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,38,cc */ + {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xfe, ZC3XX_R192_EXPOSURELIMITLOW}, {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ - {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ + {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, {0xa0, 0xd3, ZC3XX_R01D_HSYNC_0}, /* 00,1d,d3,cc */ {0xa0, 0xda, ZC3XX_R01E_HSYNC_1}, /* 00,1e,da,cc */ {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ + {0xa0, 0x4c, ZC3XX_R0A0_MAXXLOW}, + {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, {} }; static const struct usb_action tas5130cxx_50HZScale[] = { @@ -5690,20 +5587,22 @@ static const struct usb_action tas5130cxx_50HZScale[] = { {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */ - {0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e8,cc */ + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xd0, ZC3XX_R192_EXPOSURELIMITLOW}, {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */ - {0xa0, 0x14, ZC3XX_R18C_AEFREEZE}, /* 01,8c,14,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ - {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ + {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, {0xa0, 0xf0, ZC3XX_R01D_HSYNC_0}, /* 00,1d,f0,cc */ {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f4,cc */ {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ + {0xa0, 0xc0, ZC3XX_R0A0_MAXXLOW}, + {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, {} }; static const struct usb_action tas5130cxx_60HZ[] = { @@ -5713,20 +5612,22 @@ static const struct usb_action tas5130cxx_60HZ[] = { {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ {0xa0, 0x36, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,36,cc */ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,01,cc */ - {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ + {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x54, ZC3XX_R192_EXPOSURELIMITLOW}, {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ {0xa0, 0x3e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3e,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ - {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ + {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, {0xa0, 0xca, ZC3XX_R01D_HSYNC_0}, /* 00,1d,ca,cc */ {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ + {0xa0, 0x28, ZC3XX_R0A0_MAXXLOW}, + {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, {} }; static const struct usb_action tas5130cxx_60HZScale[] = { @@ -5736,20 +5637,22 @@ static const struct usb_action tas5130cxx_60HZScale[] = { {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */ - {0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e8,cc */ + {0xa0, 0x09, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x47, ZC3XX_R192_EXPOSURELIMITLOW}, {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */ - {0xa0, 0x14, ZC3XX_R18C_AEFREEZE}, /* 01,8c,14,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ - {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ + {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c8,cc */ {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ + {0xa0, 0x20, ZC3XX_R0A0_MAXXLOW}, + {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, {} }; static const struct usb_action tas5130cxx_NoFliker[] = { @@ -5759,13 +5662,13 @@ static const struct usb_action tas5130cxx_NoFliker[] = { {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ {0xa0, 0x40, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,40,cc */ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,01,cc */ - {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */ @@ -5773,6 +5676,8 @@ static const struct usb_action tas5130cxx_NoFliker[] = { {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */ + {0xa0, 0xf0, ZC3XX_R0A0_MAXXLOW}, + {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, {} }; @@ -5783,13 +5688,13 @@ static const struct usb_action tas5130cxx_NoFlikerScale[] = { {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ {0xa0, 0x90, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,90,cc */ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */ - {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x0a, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */ @@ -5797,6 +5702,8 @@ static const struct usb_action tas5130cxx_NoFlikerScale[] = { {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */ + {0xa0, 0xf0, ZC3XX_R0A0_MAXXLOW}, + {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, {} }; @@ -6206,6 +6113,8 @@ static void setmatrix(struct gspca_dev *gspca_dev) {0x4c, 0xf5, 0xff, 0xf9, 0x51, 0xf5, 0xfb, 0xed, 0x5f}; static const __u8 po2030_matrix[9] = {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60}; + static const u8 tas5130c_matrix[9] = + {0x68, 0xec, 0xec, 0xec, 0x68, 0xec, 0xec, 0xec, 0x68}; static const __u8 vf0250_matrix[9] = {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b}; static const __u8 *matrix_tb[SENSOR_MAX] = { @@ -6225,7 +6134,7 @@ static void setmatrix(struct gspca_dev *gspca_dev) NULL, /* SENSOR_PB0330 13 */ po2030_matrix, /* SENSOR_PO2030 14 */ NULL, /* SENSOR_TAS5130CK 15 */ - NULL, /* SENSOR_TAS5130CXX 16 */ + tas5130c_matrix, /* SENSOR_TAS5130CXX 16 */ vf0250_matrix, /* SENSOR_TAS5130C_VF0250 17 */ }; @@ -6491,13 +6400,13 @@ static int setlightfreq(struct gspca_dev *gspca_dev) PO2030_50HZ, PO2030_50HZ, PO2030_60HZ, PO2030_60HZ}, /* SENSOR_TAS5130CK 15 */ - {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale, - tas5130cxx_50HZ, tas5130cxx_50HZScale, - tas5130cxx_60HZ, tas5130cxx_60HZScale}, + {tas5130cxx_NoFlikerScale, tas5130cxx_NoFliker, + tas5130cxx_50HZScale, tas5130cxx_50HZ, + tas5130cxx_60HZScale, tas5130cxx_60HZ}, /* SENSOR_TAS5130CXX 16 */ - {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale, - tas5130cxx_50HZ, tas5130cxx_50HZScale, - tas5130cxx_60HZ, tas5130cxx_60HZScale}, + {tas5130cxx_NoFlikerScale, tas5130cxx_NoFliker, + tas5130cxx_50HZScale, tas5130cxx_50HZ, + tas5130cxx_60HZScale, tas5130cxx_60HZ}, /* SENSOR_TAS5130C_VF0250 17 */ {tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale, tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale, @@ -6689,6 +6598,7 @@ struct sensor_by_chipset_revision { __u8 internal_sensor_id; }; static const struct sensor_by_chipset_revision chipset_revision_sensor[] = { + {0xc000, 0x12}, /* TAS5130C */ {0xc001, 0x13}, /* MI0360 */ {0xe001, 0x13}, {0x8001, 0x13}, @@ -6866,7 +6776,7 @@ static int sd_config(struct gspca_dev *gspca_dev, 4, /* SENSOR_PB0330 13 */ 4, /* SENSOR_PO2030 14 */ 4, /* SENSOR_TAS5130CK 15 */ - 4, /* SENSOR_TAS5130CXX 16 */ + 3, /* SENSOR_TAS5130CXX 16 */ 3, /* SENSOR_TAS5130C_VF0250 17 */ }; @@ -6929,7 +6839,7 @@ static int sd_config(struct gspca_dev *gspca_dev, break; case 0x10: case 0x12: - PDEBUG(D_PROBE, "Find Sensor TAS5130"); + PDEBUG(D_PROBE, "Find Sensor TAS5130C"); sd->sensor = SENSOR_TAS5130CXX; break; case 0x11: @@ -7062,7 +6972,7 @@ static int sd_start(struct gspca_dev *gspca_dev) /* or {pb03303x_InitialScale, pb03303x_Initial}, */ {PO2030_mode0, PO2030_mode1}, /* 14 */ {tas5130CK_InitialScale, tas5130CK_Initial}, /* 15 */ - {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 16 */ + {tas5130cxx_Initial, tas5130cxx_InitialScale}, /* 16 */ {tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial}, /* 17 */ }; -- cgit v1.2.3-70-g09d2 From 216f05aa2a704ab8dfbfb3ca36da1e04d2a9ee67 Mon Sep 17 00:00:00 2001 From: Olivier Lorin Date: Thu, 15 Oct 2009 04:12:46 -0300 Subject: V4L/DVB (13194): gspca - gl860: improvement of the main driver part - fix for warning compilation about sd_ctrls - trace improvement while probing the sensor Signed-off-by: Olivier Lorin Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gl860/gl860.c | 43 ++++++++++++++++----------------- 1 file changed, 21 insertions(+), 22 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c index 6ef59ac7f50..1c3ec0242c3 100644 --- a/drivers/media/video/gspca/gl860/gl860.c +++ b/drivers/media/video/gspca/gl860/gl860.c @@ -23,8 +23,8 @@ #include "gspca.h" #include "gl860.h" -MODULE_AUTHOR("Olivier Lorin "); -MODULE_DESCRIPTION("GSPCA/Genesys Logic GL860 USB Camera Driver"); +MODULE_AUTHOR("Olivier Lorin "); +MODULE_DESCRIPTION("Genesys Logic USB PC Camera Driver"); MODULE_LICENSE("GPL"); /*======================== static function declarations ====================*/ @@ -53,7 +53,7 @@ MODULE_PARM_DESC(AC50Hz, " Does AC power frequency is 50Hz? (0/1)"); static char sensor[7]; module_param_string(sensor, sensor, sizeof(sensor), 0644); MODULE_PARM_DESC(sensor, - " Driver sensor ('MI1320'/'MI2020'/'OV9655'/'OV2640'/'')"); + " Driver sensor ('MI1320'/'MI2020'/'OV9655'/'OV2640')"); /*============================ webcam controls =============================*/ @@ -156,7 +156,7 @@ static int gl860_build_control_table(struct gspca_dev *gspca_dev) SET_MY_CTRL(V4L2_CID_VFLIP, V4L2_CTRL_TYPE_BOOLEAN, "Flip", flip) SET_MY_CTRL(V4L2_CID_POWER_LINE_FREQUENCY, - V4L2_CTRL_TYPE_BOOLEAN, "50Hz", AC50Hz) + V4L2_CTRL_TYPE_BOOLEAN, "AC power 50Hz", AC50Hz) return nCtrls; } @@ -702,6 +702,7 @@ static int gl860_guess_sensor(struct gspca_dev *gspca_dev, ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL); msleep(56); + PDEBUG(D_PROBE, "probing for sensor MI2020 or OVXXXX"); nOV = 0; for (ntry = 0; ntry < 4; ntry++) { ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL); @@ -711,14 +712,14 @@ static int gl860_guess_sensor(struct gspca_dev *gspca_dev, ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL); msleep(10); ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &probe); - PDEBUG(D_PROBE, "1st probe=%02x", probe); + PDEBUG(D_PROBE, "probe=0x%02x", probe); if (probe == 0xff) nOV++; } if (nOV) { - PDEBUG(D_PROBE, "0xff -> sensor OVXXXX"); - PDEBUG(D_PROBE, "Probing for sensor OV2640 or OV9655"); + PDEBUG(D_PROBE, "0xff -> OVXXXX"); + PDEBUG(D_PROBE, "probing for sensor OV2640 or OV9655"); nb26 = nb96 = 0; for (ntry = 0; ntry < 4; ntry++) { @@ -728,40 +729,38 @@ static int gl860_guess_sensor(struct gspca_dev *gspca_dev, ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x800a, 0, NULL); msleep(10); + /* Wait for 26(OV2640) or 96(OV9655) */ ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x800a, 1, &probe); - PDEBUG(D_PROBE, "2nd probe=%02x", probe); - if (probe == 0x00) - nb26++; if (probe == 0x26 || probe == 0x40) { + PDEBUG(D_PROBE, + "probe=0x%02x -> OV2640", + probe); sd->sensor = ID_OV2640; nb26 += 4; break; } if (probe == 0x96 || probe == 0x55) { + PDEBUG(D_PROBE, + "probe=0x%02x -> OV9655", + probe); sd->sensor = ID_OV9655; nb96 += 4; break; } + PDEBUG(D_PROBE, "probe=0x%02x", probe); + if (probe == 0x00) + nb26++; if (probe == 0xff) nb96++; msleep(3); } - if (nb26 < 4 && nb96 < 4) { - PDEBUG(D_PROBE, "No relevant answer "); - PDEBUG(D_PROBE, "* 1.3Mpixels -> use OV9655"); - PDEBUG(D_PROBE, "* 2.0Mpixels -> use OV2640"); - PDEBUG(D_PROBE, - "To force a sensor, add that line to " - "/etc/modprobe.d/options.conf:"); - PDEBUG(D_PROBE, "options gspca_gl860 " - "sensor=\"OV2640\" or \"OV9655\""); + if (nb26 < 4 && nb96 < 4) return -1; - } - } else { /* probe = 0 */ - PDEBUG(D_PROBE, "No 0xff -> sensor MI2020"); + } else { + PDEBUG(D_PROBE, "Not any 0xff -> MI2020"); sd->sensor = ID_MI2020; } } -- cgit v1.2.3-70-g09d2 From be9904bdde05137085af1df98de98a49ddce9ad8 Mon Sep 17 00:00:00 2001 From: Olivier Lorin Date: Thu, 15 Oct 2009 04:13:45 -0300 Subject: V4L/DVB (13195): gspca - gl860: comment changes and naming scheme egalization - small changes in comments - unified naming scheme for subdriver variables Signed-off-by: Olivier Lorin Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gl860/gl860-mi1320.c | 55 ++++++++++---------- drivers/media/video/gspca/gl860/gl860-mi2020.c | 69 +++++++++++++------------- drivers/media/video/gspca/gl860/gl860-ov2640.c | 57 ++++++++++----------- drivers/media/video/gspca/gl860/gl860-ov9655.c | 43 ++++++++-------- drivers/media/video/gspca/gl860/gl860.c | 8 ++- drivers/media/video/gspca/gl860/gl860.h | 7 +-- 6 files changed, 118 insertions(+), 121 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gl860/gl860-mi1320.c b/drivers/media/video/gspca/gl860/gl860-mi1320.c index 39f6261c1a0..1355e526ee8 100644 --- a/drivers/media/video/gspca/gl860/gl860-mi1320.c +++ b/drivers/media/video/gspca/gl860/gl860-mi1320.c @@ -1,6 +1,5 @@ -/* @file gl860-mi1320.c - * @author Olivier LORIN from my logs - * @date 2009-08-27 +/* Subdriver for the GL860 chip with the MI1320 sensor + * Author Olivier LORIN from own logs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -127,49 +126,49 @@ static u8 dat_wbalBL[] = static u8 dat_hvflip1[] = {0xf0, 0x00, 0xf1, 0x00}; -static u8 s000[] = +static u8 dat_common00[] = "\x00\x01\x07\x6a\x06\x63\x0d\x6a" "\xc0\x00\x10\x10\xc1\x03\xc2\x42" "\xd8\x04\x58\x00\x04\x02"; -static u8 s001[] = +static u8 dat_common01[] = "\x0d\x00\xf1\x0b\x0d\x00\xf1\x08" "\x35\x00\xf1\x22\x68\x00\xf1\x5d" "\xf0\x00\xf1\x01\x06\x70\xf1\x0e" "\xf0\x00\xf1\x02\xdd\x18\xf1\xe0"; -static u8 s002[] = +static u8 dat_common02[] = "\x05\x01\xf1\x84\x06\x00\xf1\x44" "\x07\x00\xf1\xbe\x08\x00\xf1\x1e" "\x20\x01\xf1\x03\x21\x84\xf1\x00" "\x22\x0d\xf1\x0f\x24\x80\xf1\x00" "\x34\x18\xf1\x2d\x35\x00\xf1\x22" "\x43\x83\xf1\x83\x59\x00\xf1\xff"; -static u8 s003[] = +static u8 dat_common03[] = "\xf0\x00\xf1\x02\x39\x06\xf1\x8c" "\x3a\x06\xf1\x8c\x3b\x03\xf1\xda" "\x3c\x05\xf1\x30\x57\x01\xf1\x0c" "\x58\x01\xf1\x42\x59\x01\xf1\x0c" "\x5a\x01\xf1\x42\x5c\x13\xf1\x0e" "\x5d\x17\xf1\x12\x64\x1e\xf1\x1c"; -static u8 s004[] = +static u8 dat_common04[] = "\xf0\x00\xf1\x02\x24\x5f\xf1\x20" "\x28\xea\xf1\x02\x5f\x41\xf1\x43"; -static u8 s005[] = +static u8 dat_common05[] = "\x02\x00\xf1\xee\x03\x29\xf1\x1a" "\x04\x02\xf1\xa4\x09\x00\xf1\x68" "\x0a\x00\xf1\x2a\x0b\x00\xf1\x04" "\x0c\x00\xf1\x93\x0d\x00\xf1\x82" "\x0e\x00\xf1\x40\x0f\x00\xf1\x5f" "\x10\x00\xf1\x4e\x11\x00\xf1\x5b"; -static u8 s006[] = +static u8 dat_common06[] = "\x15\x00\xf1\xc9\x16\x00\xf1\x5e" "\x17\x00\xf1\x9d\x18\x00\xf1\x06" "\x19\x00\xf1\x89\x1a\x00\xf1\x12" "\x1b\x00\xf1\xa1\x1c\x00\xf1\xe4" "\x1d\x00\xf1\x7a\x1e\x00\xf1\x64" "\xf6\x00\xf1\x5f"; -static u8 s007[] = +static u8 dat_common07[] = "\xf0\x00\xf1\x01\x53\x09\xf1\x03" "\x54\x3d\xf1\x1c\x55\x99\xf1\x72" "\x56\xc1\xf1\xb1\x57\xd8\xf1\xce" "\x58\xe0\xf1\x00\xdc\x0a\xf1\x03" "\xdd\x45\xf1\x20\xde\xae\xf1\x82" "\xdf\xdc\xf1\xc9\xe0\xf6\xf1\xea" "\xe1\xff\xf1\x00"; -static u8 s008[] = +static u8 dat_common08[] = "\xf0\x00\xf1\x01\x80\x00\xf1\x06" "\x81\xf6\xf1\x08\x82\xfb\xf1\xf7" "\x83\x00\xf1\xfe\xb6\x07\xf1\x03" "\xb7\x18\xf1\x0c\x84\xfb\xf1\x06" "\x85\xfb\xf1\xf9\x86\x00\xf1\xff" "\xb8\x07\xf1\x04\xb9\x16\xf1\x0a"; -static u8 s009[] = +static u8 dat_common09[] = "\x87\xfa\xf1\x05\x88\xfc\xf1\xf9" "\x89\x00\xf1\xff\xba\x06\xf1\x03" "\xbb\x17\xf1\x09\x8a\xe8\xf1\x14" "\x8b\xf7\xf1\xf0\x8c\xfd\xf1\xfa" "\x8d\x00\xf1\x00\xbc\x05\xf1\x01" "\xbd\x0c\xf1\x08\xbe\x00\xf1\x14"; -static u8 s010[] = +static u8 dat_common10[] = "\x8e\xea\xf1\x13\x8f\xf7\xf1\xf2" "\x90\xfd\xf1\xfa\x91\x00\xf1\x00" "\xbf\x05\xf1\x01\xc0\x0a\xf1\x08" "\xc1\x00\xf1\x0c\x92\xed\xf1\x0f" "\x93\xf9\xf1\xf4\x94\xfe\xf1\xfb" "\x95\x00\xf1\x00\xc2\x04\xf1\x01" "\xc3\x0a\xf1\x07\xc4\x00\xf1\x10"; -static u8 s011[] = +static u8 dat_common11[] = "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x25\x00\xf1\x55\x34\x10\xf1\x10" "\x35\xf0\xf1\x10\x3a\x02\xf1\x03" "\x3b\x04\xf1\x2a\x9b\x43\xf1\x00" "\xa4\x03\xf1\xc0\xa7\x02\xf1\x81"; @@ -222,26 +221,26 @@ void mi1320_init_settings(struct gspca_dev *gspca_dev) static void common(struct gspca_dev *gspca_dev) { - s32 n; /* reserved for FETCH macros */ + s32 n; /* reserved for FETCH functions */ - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 22, s000); + ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 22, dat_common00); ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 32, s001); + ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 32, dat_common01); n = fetch_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common)); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s002); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s003); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 16, s004); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s005); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 44, s006); + ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common02); + ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common03); + ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 16, dat_common04); + ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common05); + ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 44, dat_common06); keep_on_fetching_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common), n); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 52, s007); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s008); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s009); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 56, s010); + ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 52, dat_common07); + ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common08); + ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common09); + ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 56, dat_common10); keep_on_fetching_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common), n); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, s011); + ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, dat_common11); keep_on_fetching_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common), n); } diff --git a/drivers/media/video/gspca/gl860/gl860-mi2020.c b/drivers/media/video/gspca/gl860/gl860-mi2020.c index ffb09fed3e8..80cb3f1b36f 100644 --- a/drivers/media/video/gspca/gl860/gl860-mi2020.c +++ b/drivers/media/video/gspca/gl860/gl860-mi2020.c @@ -1,7 +1,6 @@ -/* @file gl860-mi2020.c - * @author Olivier LORIN, from Ice/Soro2005's logs(A), Fret_saw/Hulkie's +/* Subdriver for the GL860 chip with the MI2020 sensor + * Author Olivier LORIN, from Ice/Soro2005's logs(A), Fret_saw/Hulkie's * logs(B) and Tricid"s logs(C). With the help of Kytrix/BUGabundo/Blazercist. - * @date 2009-08-27 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,7 +40,7 @@ static u8 dat_freq1[] = { 0x8c, 0xa4, 0x04 }; static u8 dat_multi5[] = { 0x8c, 0xa1, 0x03 }; static u8 dat_multi6[] = { 0x90, 0x00, 0x05 }; -static struct validx tbl_common_a[] = { +static struct validx tbl_common1[] = { {0x0000, 0x0000}, {1, 0xffff}, /* msleep(35); */ {0x006a, 0x0007}, {0x0063, 0x0006}, {0x006a, 0x000d}, {0x0000, 0x00c0}, @@ -49,7 +48,7 @@ static struct validx tbl_common_a[] = { {0x0000, 0x0058}, {0x0002, 0x0004}, {0x0041, 0x0000}, }; -static struct validx tbl_common_b[] = { +static struct validx tbl_common2[] = { {0x006a, 0x0007}, {35, 0xffff}, {0x00ef, 0x0006}, @@ -60,7 +59,7 @@ static struct validx tbl_common_b[] = { {0x0004, 0x00d8}, {0x0000, 0x0058}, {0x0041, 0x0000}, }; -static struct idxdata tbl_common_c[] = { +static struct idxdata tbl_common3[] = { {0x32, "\x02\x00\x08"}, {0x33, "\xf4\x03\x1d"}, {6, "\xff\xff\xff"}, /* 12 */ {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"}, @@ -109,7 +108,7 @@ static struct idxdata tbl_common_c[] = { {0x33, "\x8c\xa2\x03"}, {0x33, "\x90\x00\xbb"}, }; -static struct idxdata tbl_common_d[] = { +static struct idxdata tbl_common4[] = { {0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x21"}, {0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\xa4\x0b"}, @@ -118,7 +117,7 @@ static struct idxdata tbl_common_d[] = { {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\x24\x17"}, {0x33, "\x90\x00\xc0"}, }; -static struct idxdata tbl_common_e[] = { +static struct idxdata tbl_common5[] = { {0x33, "\x8c\xa4\x04"}, {0x33, "\x90\x00\x80"}, {0x33, "\x8c\xa7\x9d"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa7\x9e"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa2\x0c"}, {0x33, "\x90\x00\x17"}, {0x33, "\x8c\xa2\x15"}, @@ -180,7 +179,7 @@ static struct validx tbl_init_at_startup[] = { {53, 0xffff}, }; -static struct idxdata tbl_init_post_alt_low_a[] = { +static struct idxdata tbl_init_post_alt_low1[] = { {0x33, "\x8c\x27\x15"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\x81"}, {0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x17"}, {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x1a"}, {0x33, "\x8c\xa4\x0a"}, @@ -189,7 +188,7 @@ static struct idxdata tbl_init_post_alt_low_a[] = { {0x33, "\x90\x00\x9b"}, }; -static struct idxdata tbl_init_post_alt_low_b[] = { +static struct idxdata tbl_init_post_alt_low2[] = { {0x33, "\x8c\x27\x03"}, {0x33, "\x90\x03\x24"}, {0x33, "\x8c\x27\x05"}, {0x33, "\x90\x02\x58"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"}, {2, "\xff\xff\xff"}, @@ -197,7 +196,7 @@ static struct idxdata tbl_init_post_alt_low_b[] = { {2, "\xff\xff\xff"}, }; -static struct idxdata tbl_init_post_alt_low_c[] = { +static struct idxdata tbl_init_post_alt_low3[] = { {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"}, {2, "\xff\xff\xff"}, {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x20"}, @@ -221,7 +220,7 @@ static struct idxdata tbl_init_post_alt_low_c[] = { {1, "\xff\xff\xff"}, }; -static struct idxdata tbl_init_post_alt_low_d[] = { +static struct idxdata tbl_init_post_alt_low4[] = { {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"}, {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"}, {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"}, @@ -267,7 +266,7 @@ static struct idxdata tbl_init_post_alt_low_d[] = { {0x32, "\x6c\x14\x08"}, }; -static struct idxdata tbl_init_post_alt_big_a[] = { +static struct idxdata tbl_init_post_alt_big1[] = { {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"}, {2, "\xff\xff\xff"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, @@ -288,7 +287,7 @@ static struct idxdata tbl_init_post_alt_big_a[] = { {0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"}, }; -static struct idxdata tbl_init_post_alt_big_b[] = { +static struct idxdata tbl_init_post_alt_big2[] = { {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"}, {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"}, {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"}, @@ -317,7 +316,7 @@ static struct idxdata tbl_init_post_alt_big_b[] = { {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"}, }; -static struct idxdata tbl_init_post_alt_big_c[] = { +static struct idxdata tbl_init_post_alt_big3[] = { {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa1\x02"}, @@ -388,14 +387,14 @@ static void common(struct gspca_dev *gspca_dev) s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; if (_MI2020b_) { - fetch_validx(gspca_dev, tbl_common_a, ARRAY_SIZE(tbl_common_a)); + fetch_validx(gspca_dev, tbl_common1, ARRAY_SIZE(tbl_common1)); } else { if (_MI2020_) ctrl_out(gspca_dev, 0x40, 1, 0x0008, 0x0004, 0, NULL); else ctrl_out(gspca_dev, 0x40, 1, 0x0002, 0x0004, 0, NULL); msleep(35); - fetch_validx(gspca_dev, tbl_common_b, ARRAY_SIZE(tbl_common_b)); + fetch_validx(gspca_dev, tbl_common2, ARRAY_SIZE(tbl_common2)); } ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x86\x25\x01"); ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x86\x25\x00"); @@ -403,13 +402,13 @@ static void common(struct gspca_dev *gspca_dev) ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0030, 3, "\x1a\x0a\xcc"); if (reso == IMAGE_1600) msleep(2); /* 1600 */ - fetch_idxdata(gspca_dev, tbl_common_c, ARRAY_SIZE(tbl_common_c)); + fetch_idxdata(gspca_dev, tbl_common3, ARRAY_SIZE(tbl_common3)); if (_MI2020b_ || _MI2020_) - fetch_idxdata(gspca_dev, tbl_common_d, - ARRAY_SIZE(tbl_common_d)); + fetch_idxdata(gspca_dev, tbl_common4, + ARRAY_SIZE(tbl_common4)); - fetch_idxdata(gspca_dev, tbl_common_e, ARRAY_SIZE(tbl_common_e)); + fetch_idxdata(gspca_dev, tbl_common5, ARRAY_SIZE(tbl_common5)); if (_MI2020b_ || _MI2020_) { /* Different from fret */ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x78"); @@ -525,15 +524,15 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev) 12, dat_800); if (_MI2020c_) - fetch_idxdata(gspca_dev, tbl_init_post_alt_low_a, - ARRAY_SIZE(tbl_init_post_alt_low_a)); + fetch_idxdata(gspca_dev, tbl_init_post_alt_low1, + ARRAY_SIZE(tbl_init_post_alt_low1)); if (reso == IMAGE_800) - fetch_idxdata(gspca_dev, tbl_init_post_alt_low_b, - ARRAY_SIZE(tbl_init_post_alt_low_b)); + fetch_idxdata(gspca_dev, tbl_init_post_alt_low2, + ARRAY_SIZE(tbl_init_post_alt_low2)); - fetch_idxdata(gspca_dev, tbl_init_post_alt_low_c, - ARRAY_SIZE(tbl_init_post_alt_low_c)); + fetch_idxdata(gspca_dev, tbl_init_post_alt_low3, + ARRAY_SIZE(tbl_init_post_alt_low3)); if (_MI2020b_) { ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL); @@ -574,8 +573,8 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev) msleep(5);/* " */ if (_MI2020c_) { - fetch_idxdata(gspca_dev, tbl_init_post_alt_low_d, - ARRAY_SIZE(tbl_init_post_alt_low_d)); + fetch_idxdata(gspca_dev, tbl_init_post_alt_low4, + ARRAY_SIZE(tbl_init_post_alt_low4)); } else { ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c); msleep(14); /* 0xd8 */ @@ -644,8 +643,8 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev) 3, "\x90\x04\xb0"); } - fetch_idxdata(gspca_dev, tbl_init_post_alt_big_a, - ARRAY_SIZE(tbl_init_post_alt_big_a)); + fetch_idxdata(gspca_dev, tbl_init_post_alt_big1, + ARRAY_SIZE(tbl_init_post_alt_big1)); if (reso == IMAGE_1600) msleep(13); /* 1600 */ @@ -708,8 +707,8 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev) msleep(14); if (_MI2020c_) - fetch_idxdata(gspca_dev, tbl_init_post_alt_big_b, - ARRAY_SIZE(tbl_init_post_alt_big_b)); + fetch_idxdata(gspca_dev, tbl_init_post_alt_big2, + ARRAY_SIZE(tbl_init_post_alt_big2)); /* flip/mirror */ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1); @@ -738,8 +737,8 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev) sd->nbIm = 0; if (_MI2020c_) - fetch_idxdata(gspca_dev, tbl_init_post_alt_big_c, - ARRAY_SIZE(tbl_init_post_alt_big_c)); + fetch_idxdata(gspca_dev, tbl_init_post_alt_big3, + ARRAY_SIZE(tbl_init_post_alt_big3)); } sd->vold.mirror = mirror; diff --git a/drivers/media/video/gspca/gl860/gl860-ov2640.c b/drivers/media/video/gspca/gl860/gl860-ov2640.c index 14b9c373f9f..e0837432d39 100644 --- a/drivers/media/video/gspca/gl860/gl860-ov2640.c +++ b/drivers/media/video/gspca/gl860/gl860-ov2640.c @@ -1,6 +1,5 @@ -/* @file gl860-ov2640.c - * @author Olivier LORIN, from Malmostoso's logs - * @date 2009-08-27 +/* Subdriver for the GL860 chip with the OV2640 sensor + * Author Olivier LORIN, from Malmostoso's logs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -92,7 +91,7 @@ static struct validx tbl_common[] = { {0x6000, 0x0010}, }; -static struct validx tbl_sensor_settings_common_a[] = { +static struct validx tbl_sensor_settings_common1[] = { {0x0041, 0x0000}, {0x006a, 0x0007}, {0x00ef, 0x0006}, {0x006a, 0x000d}, {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, {0x0041, 0x00c2}, {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, {0x0041, 0x0000}, @@ -104,7 +103,7 @@ static struct validx tbl_sensor_settings_common_a[] = { {0x0040, 0x0000}, }; -static struct validx tbl_sensor_settings_common_b[] = { +static struct validx tbl_sensor_settings_common2[] = { {0x6001, 0x00ff}, {0x6038, 0x000c}, {10, 0xffff}, {0x6000, 0x0011}, @@ -166,7 +165,7 @@ static struct validx tbl_800[] = { {0x60ff, 0x00dd}, {0x6020, 0x008c}, {0x6001, 0x00ff}, {0x6044, 0x0018}, }; -static struct validx tbl_big_a[] = { +static struct validx tbl_big1[] = { {0x0002, 0x00c1}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, {0x6001, 0x00ff}, {0x6000, 0x0012}, {0x6000, 0x0000}, {0x6000, 0x0045}, {0x6000, 0x0010}, {0x6000, 0x0011}, {0x6011, 0x0017}, {0x6075, 0x0018}, @@ -176,14 +175,14 @@ static struct validx tbl_big_a[] = { {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x6000, 0x008c}, }; -static struct validx tbl_big_b[] = { +static struct validx tbl_big2[] = { {0x603d, 0x0086}, {0x6000, 0x0050}, {0x6090, 0x0051}, {0x602c, 0x0052}, {0x6000, 0x0053}, {0x6000, 0x0054}, {0x6088, 0x0055}, {0x6000, 0x0057}, {0x6040, 0x005a}, {0x60f0, 0x005b}, {0x6001, 0x005c}, {0x6082, 0x00d3}, {0x6000, 0x008e}, }; -static struct validx tbl_big_c[] = { +static struct validx tbl_big3[] = { {0x6004, 0x00da}, {0x6000, 0x00e0}, {0x6067, 0x00e1}, {0x60ff, 0x00dd}, {0x6001, 0x00ff}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, {0x6001, 0x00ff}, {0x6000, 0x0011}, {0x6000, 0x00ff}, {0x6010, 0x00c7}, @@ -275,6 +274,8 @@ static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + sd->mirrorMask = 0; + sd->vold.backlight = -1; sd->vold.brightness = -1; sd->vold.sharpness = -1; @@ -292,16 +293,16 @@ static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev) static int ov2640_init_post_alt(struct gspca_dev *gspca_dev) { s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; - s32 n; /* reserved for FETCH macros */ + s32 n; /* reserved for FETCH functions */ ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL); - n = fetch_validx(gspca_dev, tbl_sensor_settings_common_a, - ARRAY_SIZE(tbl_sensor_settings_common_a)); + n = fetch_validx(gspca_dev, tbl_sensor_settings_common1, + ARRAY_SIZE(tbl_sensor_settings_common1)); ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_post); common(gspca_dev); - keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_a, - ARRAY_SIZE(tbl_sensor_settings_common_a), n); + keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common1, + ARRAY_SIZE(tbl_sensor_settings_common1), n); switch (reso) { case IMAGE_640: @@ -316,18 +317,18 @@ static int ov2640_init_post_alt(struct gspca_dev *gspca_dev) case IMAGE_1600: case IMAGE_1280: - n = fetch_validx(gspca_dev, tbl_big_a, ARRAY_SIZE(tbl_big_a)); + n = fetch_validx(gspca_dev, tbl_big1, ARRAY_SIZE(tbl_big1)); if (reso == IMAGE_1280) { - n = fetch_validx(gspca_dev, tbl_big_b, - ARRAY_SIZE(tbl_big_b)); + n = fetch_validx(gspca_dev, tbl_big2, + ARRAY_SIZE(tbl_big2)); } else { ctrl_out(gspca_dev, 0x40, 1, 0x601d, 0x0086, 0, NULL); ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00d7, 0, NULL); ctrl_out(gspca_dev, 0x40, 1, 0x6082, 0x00d3, 0, NULL); } - n = fetch_validx(gspca_dev, tbl_big_c, ARRAY_SIZE(tbl_big_c)); + n = fetch_validx(gspca_dev, tbl_big3, ARRAY_SIZE(tbl_big3)); if (reso == IMAGE_1280) { ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL); @@ -343,20 +344,20 @@ static int ov2640_init_post_alt(struct gspca_dev *gspca_dev) break; } - n = fetch_validx(gspca_dev, tbl_sensor_settings_common_b, - ARRAY_SIZE(tbl_sensor_settings_common_b)); + n = fetch_validx(gspca_dev, tbl_sensor_settings_common2, + ARRAY_SIZE(tbl_sensor_settings_common2)); ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50); - keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b, - ARRAY_SIZE(tbl_sensor_settings_common_b), n); + keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common2, + ARRAY_SIZE(tbl_sensor_settings_common2), n); ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, c28); - keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b, - ARRAY_SIZE(tbl_sensor_settings_common_b), n); + keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common2, + ARRAY_SIZE(tbl_sensor_settings_common2), n); ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, ca8); - keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b, - ARRAY_SIZE(tbl_sensor_settings_common_b), n); + keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common2, + ARRAY_SIZE(tbl_sensor_settings_common2), n); ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50); - keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b, - ARRAY_SIZE(tbl_sensor_settings_common_b), n); + keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common2, + ARRAY_SIZE(tbl_sensor_settings_common2), n); ov2640_camera_settings(gspca_dev); @@ -395,6 +396,7 @@ static int ov2640_camera_settings(struct gspca_dev *gspca_dev) s32 wbal = sd->vcur.whitebal; if (backlight != sd->vold.backlight) { + /* No sd->vold.backlight=backlight; (to be done again later) */ if (backlight < 0 || backlight > sd->vmax.backlight) backlight = 0; @@ -404,7 +406,6 @@ static int ov2640_camera_settings(struct gspca_dev *gspca_dev) 0, NULL); ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025, 0, NULL); - /* No sd->vold.backlight=backlight; (to be done again later) */ } if (bright != sd->vold.brightness) { diff --git a/drivers/media/video/gspca/gl860/gl860-ov9655.c b/drivers/media/video/gspca/gl860/gl860-ov9655.c index eda3346f939..d412694c50a 100644 --- a/drivers/media/video/gspca/gl860/gl860-ov9655.c +++ b/drivers/media/video/gspca/gl860/gl860-ov9655.c @@ -1,7 +1,6 @@ -/* @file gl860-ov9655.c - * @author Olivier LORIN, from logs done by Simon (Sur3) and Almighurt +/* Subdriver for the GL860 chip with the OV9655 sensor + * Author Olivier LORIN, from logs done by Simon (Sur3) and Almighurt * on dsd's weblog - * @date 2009-08-27 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -104,14 +103,14 @@ static u8 *tbl_800[] = { }; static u8 c04[] = {0x04}; -static u8 dat_post_1[] = "\x04\x00\x10\x20\xa1\x00\x00\x02"; -static u8 dat_post_2[] = "\x10\x10\xc1\x02"; -static u8 dat_post_3[] = "\x04\x00\x10\x7c\xa1\x00\x00\x04"; -static u8 dat_post_4[] = "\x10\x02\xc1\x06"; -static u8 dat_post_5[] = "\x04\x00\x10\x7b\xa1\x00\x00\x08"; -static u8 dat_post_6[] = "\x10\x10\xc1\x05"; -static u8 dat_post_7[] = "\x04\x00\x10\x7c\xa1\x00\x00\x08"; -static u8 dat_post_8[] = "\x04\x00\x10\x7c\xa1\x00\x00\x09"; +static u8 dat_post1[] = "\x04\x00\x10\x20\xa1\x00\x00\x02"; +static u8 dat_post2[] = "\x10\x10\xc1\x02"; +static u8 dat_post3[] = "\x04\x00\x10\x7c\xa1\x00\x00\x04"; +static u8 dat_post4[] = "\x10\x02\xc1\x06"; +static u8 dat_post5[] = "\x04\x00\x10\x7b\xa1\x00\x00\x08"; +static u8 dat_post6[] = "\x10\x10\xc1\x05"; +static u8 dat_post7[] = "\x04\x00\x10\x7c\xa1\x00\x00\x08"; +static u8 dat_post8[] = "\x04\x00\x10\x7c\xa1\x00\x00\x09"; static struct validx tbl_init_post_alt[] = { {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x603c, 0x00ff}, @@ -212,7 +211,7 @@ static int ov9655_init_pre_alt(struct gspca_dev *gspca_dev) static int ov9655_init_post_alt(struct gspca_dev *gspca_dev) { s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; - s32 n; /* reserved for FETCH macros */ + s32 n; /* reserved for FETCH functions */ s32 i; u8 **tbl; @@ -243,7 +242,7 @@ static int ov9655_init_post_alt(struct gspca_dev *gspca_dev) ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04); keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, ARRAY_SIZE(tbl_init_post_alt), n); - ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1); + ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1); keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, ARRAY_SIZE(tbl_init_post_alt), n); @@ -259,7 +258,7 @@ static int ov9655_init_post_alt(struct gspca_dev *gspca_dev) ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04); keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, ARRAY_SIZE(tbl_init_post_alt), n); - ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1); + ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1); keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, ARRAY_SIZE(tbl_init_post_alt), n); @@ -270,18 +269,18 @@ static int ov9655_init_post_alt(struct gspca_dev *gspca_dev) keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, ARRAY_SIZE(tbl_init_post_alt), n); - ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1); + ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1); - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_2); - ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_3); + ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post2); + ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post3); - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_4); - ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_5); + ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post4); + ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post5); - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_6); - ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_7); + ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post6); + ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post7); - ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_8); + ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post8); ov9655_camera_settings(gspca_dev); diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c index 1c3ec0242c3..a2108dd7105 100644 --- a/drivers/media/video/gspca/gl860/gl860.c +++ b/drivers/media/video/gspca/gl860/gl860.c @@ -1,9 +1,7 @@ -/* @file gl860.c - * @date 2009-08-27 +/* GSPCA subdrivers for Genesys Logic webcams with the GL860 chip + * Subdriver core * - * Genesys Logic webcam with gl860 subdrivers - * - * Driver by Olivier Lorin + * 2009/09/24 Olivier Lorin * GSPCA by Jean-Francois Moine * Thanks BUGabundo and Malmostoso for your amazing help! * diff --git a/drivers/media/video/gspca/gl860/gl860.h b/drivers/media/video/gspca/gl860/gl860.h index cef4e24c1e6..305061ff838 100644 --- a/drivers/media/video/gspca/gl860/gl860.h +++ b/drivers/media/video/gspca/gl860/gl860.h @@ -1,6 +1,7 @@ -/* @file gl860.h - * @author Olivier LORIN, tiré du pilote Syntek par Nicolas VIVIEN - * @date 2009-08-27 +/* GSPCA subdrivers for Genesys Logic webcams with the GL860 chip + * Subdriver declarations + * + * 2009/10/14 Olivier LORIN * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -- cgit v1.2.3-70-g09d2 From fdd1dd1d246e14dacd8fb0bf842828b03bed2481 Mon Sep 17 00:00:00 2001 From: Olivier Lorin Date: Thu, 15 Oct 2009 04:20:54 -0300 Subject: V4L/DVB (13196): gspca - gl860: add flip/mirror for OV2640 - add flip/mirror support for OV2640 - fix for backlight value range - fix for red-blue inversion hue mode with V4L1 applications Signed-off-by: Olivier Lorin Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gl860/gl860-ov2640.c | 99 +++++++++++--------------- 1 file changed, 41 insertions(+), 58 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gl860/gl860-ov2640.c b/drivers/media/video/gspca/gl860/gl860-ov2640.c index e0837432d39..768cac5cd72 100644 --- a/drivers/media/video/gspca/gl860/gl860-ov2640.c +++ b/drivers/media/video/gspca/gl860/gl860-ov2640.c @@ -20,8 +20,12 @@ #include "gl860.h" static u8 dat_init1[] = "\x00\x41\x07\x6a\x06\x61\x0d\x6a" "\x10\x10\xc1\x01"; -static u8 dat_init2[] = {0x61}; /* expected */ -static u8 dat_init3[] = {0x51}; /* expected */ + +static u8 c61[] = {0x61}; /* expected */ +static u8 c51[] = {0x51}; /* expected */ +static u8 c50[] = {0x50}; /* expected */ +static u8 c28[] = {0x28}; /* expected */ +static u8 ca8[] = {0xa8}; /* expected */ static u8 dat_post[] = "\x00\x41\x07\x6a\x06\xef\x0d\x6a" "\x10\x10\xc1\x01"; @@ -31,10 +35,6 @@ static u8 dat_800[] = "\xd0\x01\xd1\x10\xd2\x58\xd3\x02\xd4\x18\xd5\x21"; static u8 dat_1280[] = "\xd0\x01\xd1\x18\xd2\xc0\xd3\x02\xd4\x28\xd5\x01"; static u8 dat_1600[] = "\xd0\x01\xd1\x20\xd2\xb0\xd3\x02\xd4\x30\xd5\x41"; -static u8 c50[] = {0x50}; /* expected */ -static u8 c28[] = {0x28}; /* expected */ -static u8 ca8[] = {0xa8}; /* expected */ - static struct validx tbl_init_at_startup[] = { {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1}, {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d}, @@ -107,36 +107,6 @@ static struct validx tbl_sensor_settings_common2[] = { {0x6001, 0x00ff}, {0x6038, 0x000c}, {10, 0xffff}, {0x6000, 0x0011}, - /* backlight=31/64 */ - {0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025}, - /* bright=0/256 */ - {0x6000, 0x00ff}, {0x6009, 0x007c}, {0x6000, 0x007d}, - /* wbal=64/128 */ - {0x6000, 0x00ff}, {0x6003, 0x007c}, {0x6040, 0x007d}, - /* cntr=0/256 */ - {0x6000, 0x00ff}, {0x6007, 0x007c}, {0x6000, 0x007d}, - /* sat=128/256 */ - {0x6000, 0x00ff}, {0x6001, 0x007c}, {0x6080, 0x007d}, - /* sharpness=0/32 */ - {0x6000, 0x00ff}, {0x6001, 0x0092}, {0x60c0, 0x0093}, - /* hue=0/256 */ - {0x6000, 0x00ff}, {0x6002, 0x007c}, {0x6000, 0x007d}, - /* gam=32/64 */ - {0x6000, 0x00ff}, {0x6008, 0x007c}, {0x6020, 0x007d}, - /* image right up */ - {0xffff, 0xffff}, - {15, 0xffff}, - {0x6001, 0x00ff}, {0x6000, 0x8004}, - {0xffff, 0xffff}, - {0x60a8, 0x0004}, - {15, 0xffff}, - {0x6001, 0x00ff}, {0x6000, 0x8004}, - {0xffff, 0xffff}, - {0x60f8, 0x0004}, - /* image right up */ - {0xffff, 0xffff}, - /* backlight=31/64 */ - {0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025}, }; static struct validx tbl_640[] = { @@ -222,17 +192,19 @@ void ov2640_init_settings(struct gspca_dev *gspca_dev) sd->vcur.hue = 0; sd->vcur.saturation = 128; sd->vcur.whitebal = 64; + sd->vcur.mirror = 0; + sd->vcur.flip = 0; sd->vmax.backlight = 64; sd->vmax.brightness = 255; sd->vmax.sharpness = 31; sd->vmax.contrast = 255; sd->vmax.gamma = 64; - sd->vmax.hue = 255 + 1; + sd->vmax.hue = 254 + 2; sd->vmax.saturation = 255; sd->vmax.whitebal = 128; - sd->vmax.mirror = 0; - sd->vmax.flip = 0; + sd->vmax.mirror = 1; + sd->vmax.flip = 1; sd->vmax.AC50Hz = 0; sd->dev_camera_settings = ov2640_camera_settings; @@ -258,11 +230,11 @@ static int ov2640_init_at_startup(struct gspca_dev *gspca_dev) common(gspca_dev); - ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0006, 1, dat_init2); + ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0006, 1, c61); ctrl_out(gspca_dev, 0x40, 1, 0x00ef, 0x0006, 0, NULL); - ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, dat_init3); + ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c51); ctrl_out(gspca_dev, 0x40, 1, 0x0051, 0x0000, 0, NULL); /* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */ @@ -284,6 +256,8 @@ static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev) sd->vold.gamma = -1; sd->vold.hue = -1; sd->vold.whitebal = -1; + sd->vold.mirror = -1; + sd->vold.flip = -1; ov2640_init_post_alt(gspca_dev); @@ -346,18 +320,6 @@ static int ov2640_init_post_alt(struct gspca_dev *gspca_dev) n = fetch_validx(gspca_dev, tbl_sensor_settings_common2, ARRAY_SIZE(tbl_sensor_settings_common2)); - ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50); - keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common2, - ARRAY_SIZE(tbl_sensor_settings_common2), n); - ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, c28); - keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common2, - ARRAY_SIZE(tbl_sensor_settings_common2), n); - ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, ca8); - keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common2, - ARRAY_SIZE(tbl_sensor_settings_common2), n); - ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50); - keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common2, - ARRAY_SIZE(tbl_sensor_settings_common2), n); ov2640_camera_settings(gspca_dev); @@ -394,6 +356,8 @@ static int ov2640_camera_settings(struct gspca_dev *gspca_dev) s32 sat = sd->vcur.saturation; s32 hue = sd->vcur.hue; s32 wbal = sd->vcur.whitebal; + s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) == 0); + s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) == 0); if (backlight != sd->vold.backlight) { /* No sd->vold.backlight=backlight; (to be done again later) */ @@ -402,9 +366,9 @@ static int ov2640_camera_settings(struct gspca_dev *gspca_dev) ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight , 0x0024, + ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight , 0x0024, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025, + ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight - 10, 0x0025, 0, NULL); } @@ -467,7 +431,7 @@ static int ov2640_camera_settings(struct gspca_dev *gspca_dev) ctrl_out(gspca_dev, 0x40, 1, 0x6002 , 0x007c, 0, NULL); ctrl_out(gspca_dev, 0x40, 1, 0x6000 + hue * (hue < 255), 0x007d, 0, NULL); - if (hue >= sd->vmax.hue) + if (hue >= 255) sd->swapRB = 1; else sd->swapRB = 0; @@ -483,14 +447,33 @@ static int ov2640_camera_settings(struct gspca_dev *gspca_dev) ctrl_out(gspca_dev, 0x40, 1, 0x6000 + gam, 0x007d, 0, NULL); } + if (mirror != sd->vold.mirror || flip != sd->vold.flip) { + sd->vold.mirror = mirror; + sd->vold.flip = flip; + + mirror = 0x80 * mirror; + ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL); + ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x8004, 0, NULL); + ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, c28); + ctrl_out(gspca_dev, 0x40, 1, 0x6028 + mirror, 0x0004, 0, NULL); + + flip = 0x50 * flip + mirror; + ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL); + ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x8004, 0, NULL); + ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, ca8); + ctrl_out(gspca_dev, 0x40, 1, 0x6028 + flip, 0x0004, 0, NULL); + + ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50); + } + if (backlight != sd->vold.backlight) { sd->vold.backlight = backlight; ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight , 0x0024, + ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight , 0x0024, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025, + ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight - 10, 0x0025, 0, NULL); } -- cgit v1.2.3-70-g09d2 From 46b4f2ab5858de905a20389c32105fcee833e0d3 Mon Sep 17 00:00:00 2001 From: Amauri Magagna Date: Sat, 17 Oct 2009 07:21:29 -0300 Subject: V4L/DVB (13197): gspca - sonixj: Adjust colors and autogain for sensor om6802. - set correct colors at startup time - autogain was too slow (4-5 mn - now 15-30 s)) Signed-off-by: Amauri Magagna Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 33f4d0a1f6f..82604f328dc 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -346,7 +346,7 @@ static const u8 sn_mt9v111[0x1c] = { static const u8 sn_om6802[0x1c] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20, + 0x00, 0x23, 0x72, 0x00, 0x1a, 0x20, 0x20, 0x19, /* reg8 reg9 rega regb regc regd rege regf */ 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ @@ -1987,11 +1987,19 @@ static void do_autogain(struct gspca_dev *gspca_dev) sd->exposure = setexposure(gspca_dev, (unsigned int) (expotimes << 8)); break; + case SENSOR_OM6802: + expotimes = sd->exposure; + expotimes += (luma_mean - delta) >> 2; + if (expotimes < 0) + expotimes = 0; + sd->exposure = setexposure(gspca_dev, + (unsigned int) expotimes); + setredblue(gspca_dev); + break; default: /* case SENSOR_MO4000: */ /* case SENSOR_MI0360: */ /* case SENSOR_MT9V111: */ -/* case SENSOR_OM6802: */ expotimes = sd->exposure; expotimes += (luma_mean - delta) >> 6; if (expotimes < 0) -- cgit v1.2.3-70-g09d2 From 5f78a9f96bc1954e9bd51458af8658b1eda603be Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 19 Oct 2009 07:40:33 -0300 Subject: V4L/DVB (13198): gspca - ov519: Bad frame pointer in ovfx2 packet scan. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov519.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index a63cb75aa7f..f88a526e216 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -4058,7 +4058,7 @@ static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev, { /* A short read signals EOF */ if (len < OVFX2_BULK_SIZE) { - gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, len); + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, len); gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0); return; } -- cgit v1.2.3-70-g09d2 From bc809ab37e4a8f6eeea0afae76bb1bc6cc52fe98 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 28 Sep 2009 16:44:52 -0300 Subject: V4L/DVB (13201): saa7164: disable tda18271 slave tuner output on slave in standby mode Enable the standby mode optimization to disable the tda18271 slave tuner output / loop thru options when in low power mode on the slave tuner, only. The master tuner must always leave slave tuner output / loop thru enabled. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7164/saa7164-dvb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7164/saa7164-dvb.c b/drivers/media/video/saa7164/saa7164-dvb.c index 6a2d847d6a8..cf099c59b38 100644 --- a/drivers/media/video/saa7164/saa7164-dvb.c +++ b/drivers/media/video/saa7164/saa7164-dvb.c @@ -68,6 +68,7 @@ static struct tda18271_config hauppauge_hvr22x0s_tuner_config = { .std_map = &hauppauge_tda18271_std_map, .gate = TDA18271_GATE_ANALOG, .role = TDA18271_SLAVE, + .output_opt = TDA18271_OUTPUT_LT_OFF, .rf_cal_on_startup = 1 }; -- cgit v1.2.3-70-g09d2 From 184e769f93e734ced24c948ea02e3d541c45c766 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Fri, 5 Jun 2009 04:28:28 -0300 Subject: V4L/DVB (13204): saa7134: add support for the Leadtek DTV1000S Thanks to Terry Wu for finding the GPIOs required for svideo / composite input Cc: Terry Wu Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.saa7134 | 1 + drivers/media/video/saa7134/saa7134-cards.c | 6 +++++ drivers/media/video/saa7134/saa7134-dvb.c | 39 +++++++++++++++++++++++++++++ drivers/media/video/saa7134/saa7134.h | 1 + 4 files changed, 47 insertions(+) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index 94e255a76f7..fce1e7eb047 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -173,3 +173,4 @@ 172 -> RoverMedia TV Link Pro FM [19d1:0138] 173 -> Zolid Hybrid TV Tuner PCI [1131:2004] 174 -> Asus Europa Hybrid OEM [1043:4847] +175 -> Leadtek Winfast DTV1000S [107d:6655] diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index bdb61385136..9481379edec 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -6448,6 +6448,12 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = 0x1043, .subdevice = 0x4847, .driver_data = SAA7134_BOARD_ASUS_EUROPA_HYBRID, + }, { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7130, + .subvendor = 0x107d, + .subdevice = 0x6655, + .driver_data = SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S, }, { /* --- boards without eeprom + subsystem ID --- */ .vendor = PCI_VENDOR_ID_PHILIPS, diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index cd31284faf7..73739d2a63d 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -1045,6 +1045,32 @@ static struct tda18271_config zolid_tda18271_config = { .gate = TDA18271_GATE_ANALOG, }; +static struct tda10048_config dtv1000s_tda10048_config = { + .demod_address = 0x10 >> 1, + .output_mode = TDA10048_PARALLEL_OUTPUT, + .fwbulkwritelen = TDA10048_BULKWRITE_200, + .inversion = TDA10048_INVERSION_ON, + .dtv6_if_freq_khz = TDA10048_IF_3300, + .dtv7_if_freq_khz = TDA10048_IF_3800, + .dtv8_if_freq_khz = TDA10048_IF_4300, + .clk_freq_khz = TDA10048_CLK_16000, + .disable_gate_access = 1, +}; + +static struct tda18271_std_map dtv1000s_tda18271_std_map = { + .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4, + .if_lvl = 1, .rfagc_top = 0x37, }, + .dvbt_7 = { .if_freq = 3800, .agc_mode = 3, .std = 5, + .if_lvl = 1, .rfagc_top = 0x37, }, + .dvbt_8 = { .if_freq = 4300, .agc_mode = 3, .std = 6, + .if_lvl = 1, .rfagc_top = 0x37, }, +}; + +static struct tda18271_config dtv1000s_tda18271_config = { + .std_map = &dtv1000s_tda18271_std_map, + .gate = TDA18271_GATE_ANALOG, +}; + /* ================================================================== * Core code */ @@ -1543,6 +1569,19 @@ static int dvb_init(struct saa7134_dev *dev) &zolid_tda18271_config); } break; + case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S: + fe0->dvb.frontend = dvb_attach(tda10048_attach, + &dtv1000s_tda10048_config, + &dev->i2c_adap); + if (fe0->dvb.frontend != NULL) { + dvb_attach(tda829x_attach, fe0->dvb.frontend, + &dev->i2c_adap, 0x4b, + &tda829x_no_probe); + dvb_attach(tda18271_attach, fe0->dvb.frontend, + 0x60, &dev->i2c_adap, + &dtv1000s_tda18271_config); + } + break; default: wprintk("Huh? unknown DVB card?\n"); break; diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 94e1a3be331..13a861bedc3 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -298,6 +298,7 @@ struct saa7134_format { #define SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM 172 #define SAA7134_BOARD_ZOLID_HYBRID_PCI 173 #define SAA7134_BOARD_ASUS_EUROPA_HYBRID 174 +#define SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S 175 #define SAA7134_MAXBOARDS 32 #define SAA7134_INPUT_MAX 8 -- cgit v1.2.3-70-g09d2 From fb29ab96982baba57b03636e2a894c0d0acd197e Mon Sep 17 00:00:00 2001 From: "David T.L. Wong" Date: Tue, 20 Oct 2009 12:13:39 -0300 Subject: V4L/DVB (13206): cx25840: add component support Signed-off-by: David T.L. Wong Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx25840/cx25840-core.c | 36 ++++++++++++++++++++---------- include/media/cx25840.h | 1 + 2 files changed, 25 insertions(+), 12 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 904e9a5a906..9702a9334b4 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -703,6 +703,10 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp struct cx25840_state *state = to_state(i2c_get_clientdata(client)); u8 is_composite = (vid_input >= CX25840_COMPOSITE1 && vid_input <= CX25840_COMPOSITE8); + u8 is_component = (vid_input & CX25840_COMPONENT_ON) == + CX25840_COMPONENT_ON; + int luma = vid_input & 0xf0; + int chroma = vid_input & 0xf00; u8 reg; v4l_dbg(1, cx25840_debug, client, @@ -715,18 +719,14 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp reg = vid_input & 0xff; if ((vid_input & CX25840_SVIDEO_ON) == CX25840_SVIDEO_ON) is_composite = 0; - else + else if ((vid_input & CX25840_COMPONENT_ON) == 0) is_composite = 1; v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n", reg, is_composite); - } else - if (is_composite) { + } else if (is_composite) { reg = 0xf0 + (vid_input - CX25840_COMPOSITE1); } else { - int luma = vid_input & 0xf0; - int chroma = vid_input & 0xf00; - if ((vid_input & ~0xff0) || luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA8 || chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) { @@ -768,8 +768,11 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp cx25840_write(client, 0x103, reg); - /* Set INPUT_MODE to Composite (0) or S-Video (1) */ - cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02); + /* Set INPUT_MODE to Composite, S-Video or Component */ + if (is_component) + cx25840_and_or(client, 0x401, ~0x6, 0x6); + else + cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02); if (!is_cx2388x(state) && !is_cx231xx(state)) { /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ @@ -780,12 +783,21 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp else cx25840_and_or(client, 0x102, ~0x4, 0); } else { - if (is_composite) + /* Set DUAL_MODE_ADC2 to 1 if component*/ + cx25840_and_or(client, 0x102, ~0x4, is_component ? 0x4 : 0x0); + if (is_composite) { /* ADC2 input select channel 2 */ cx25840_and_or(client, 0x102, ~0x2, 0); - else - /* ADC2 input select channel 3 */ - cx25840_and_or(client, 0x102, ~0x2, 2); + } else if (!is_component) { + /* S-Video */ + if (chroma >= CX25840_SVIDEO_CHROMA7) { + /* ADC2 input select channel 3 */ + cx25840_and_or(client, 0x102, ~0x2, 2); + } else { + /* ADC2 input select channel 2 */ + cx25840_and_or(client, 0x102, ~0x2, 0); + } + } } state->vid_input = vid_input; diff --git a/include/media/cx25840.h b/include/media/cx25840.h index 2c3fbaa33f7..0b0cb177679 100644 --- a/include/media/cx25840.h +++ b/include/media/cx25840.h @@ -84,6 +84,7 @@ enum cx25840_video_input { CX25840_NONE0_CH3 = 0x80000080, CX25840_NONE1_CH3 = 0x800000c0, CX25840_SVIDEO_ON = 0x80000100, + CX25840_COMPONENT_ON = 0x80000200, }; enum cx25840_audio_input { -- cgit v1.2.3-70-g09d2 From dac65fa169ebf9fb1bd488385c62b5dd0c71771c Mon Sep 17 00:00:00 2001 From: "David T.L. Wong" Date: Wed, 21 Oct 2009 11:07:24 -0300 Subject: V4L/DVB (13207): cx23885: add component input type Signed-off-by: David T. L. Wong Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-video.c | 1 + drivers/media/video/cx23885/cx23885.h | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 3f1d07e6490..eebd52eb3dc 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -1145,6 +1145,7 @@ static int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i) [CX23885_VMUX_COMPOSITE3] = "Composite3", [CX23885_VMUX_COMPOSITE4] = "Composite4", [CX23885_VMUX_SVIDEO] = "S-Video", + [CX23885_VMUX_COMPONENT] = "Component", [CX23885_VMUX_TELEVISION] = "Television", [CX23885_VMUX_CABLE] = "Cable TV", [CX23885_VMUX_DVB] = "DVB", diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index d2fbc6807ce..813eaf7c5e9 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h @@ -157,6 +157,7 @@ enum cx23885_itype { CX23885_VMUX_COMPOSITE3, CX23885_VMUX_COMPOSITE4, CX23885_VMUX_SVIDEO, + CX23885_VMUX_COMPONENT, CX23885_VMUX_TELEVISION, CX23885_VMUX_CABLE, CX23885_VMUX_DVB, -- cgit v1.2.3-70-g09d2 From fd705e7cd8ef61efc443b90f94afed42beabeacd Mon Sep 17 00:00:00 2001 From: "David T.L. Wong" Date: Wed, 21 Oct 2009 11:08:30 -0300 Subject: V4L/DVB (13208): cx23885: fix uninitialized member bug Signed-off-by: David T. L. Wong Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-video.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index eebd52eb3dc..e14cb39d841 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -1504,6 +1504,7 @@ int cx23885_video_register(struct cx23885_dev *dev) if (sd) { struct tuner_setup tun_setup; + memset(&tun_setup, 0, sizeof(tun_setup)); tun_setup.mode_mask = T_ANALOG_TV; tun_setup.type = dev->tuner_type; tun_setup.addr = v4l2_i2c_subdev_addr(sd); -- cgit v1.2.3-70-g09d2 From bc1548adbee02899c7db5cd045bb0d799b220dce Mon Sep 17 00:00:00 2001 From: "David T.L. Wong" Date: Wed, 21 Oct 2009 11:09:28 -0300 Subject: V4L/DVB (13209): cx23885: card mygica x8506 add analog video input support Signed-off-by: David T. L. Wong Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-cards.c | 42 +++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index c0e2409f3cb..7438e79a8ef 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -200,11 +200,51 @@ struct cx23885_board cx23885_boards[] = { }, [CX23885_BOARD_MYGICA_X8506] = { .name = "Mygica X8506 DMB-TH", + .tuner_type = TUNER_ABSENT, + .porta = CX23885_ANALOG_VIDEO, .portb = CX23885_MPEG_DVB, + .input = { + { + .type = CX23885_VMUX_COMPOSITE1, + .vmux = CX25840_COMPOSITE8, + }, + { + .type = CX23885_VMUX_SVIDEO, + .vmux = CX25840_SVIDEO_LUMA3 | + CX25840_SVIDEO_CHROMA4, + }, + { + .type = CX23885_VMUX_COMPONENT, + .vmux = CX25840_COMPONENT_ON | + CX25840_VIN1_CH1 | + CX25840_VIN6_CH2 | + CX25840_VIN7_CH3, + }, + }, }, [CX23885_BOARD_MAGICPRO_PROHDTVE2] = { .name = "Magic-Pro ProHDTV Extreme 2", + .tuner_type = TUNER_ABSENT, + .porta = CX23885_ANALOG_VIDEO, .portb = CX23885_MPEG_DVB, + .input = { + { + .type = CX23885_VMUX_COMPOSITE1, + .vmux = CX25840_COMPOSITE8, + }, + { + .type = CX23885_VMUX_SVIDEO, + .vmux = CX25840_SVIDEO_LUMA3 | + CX25840_SVIDEO_CHROMA4, + }, + { + .type = CX23885_VMUX_COMPONENT, + .vmux = CX25840_COMPONENT_ON | + CX25840_VIN1_CH1 | + CX25840_VIN6_CH2 | + CX25840_VIN7_CH3, + }, + }, }, [CX23885_BOARD_HAUPPAUGE_HVR1850] = { .name = "Hauppauge WinTV-HVR1850", @@ -970,6 +1010,8 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: case CX23885_BOARD_COMPRO_VIDEOMATE_E800: case CX23885_BOARD_HAUPPAUGE_HVR1850: + case CX23885_BOARD_MYGICA_X8506: + case CX23885_BOARD_MAGICPRO_PROHDTVE2: dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_bus[2].i2c_adap, "cx25840", "cx25840", 0x88 >> 1, NULL); -- cgit v1.2.3-70-g09d2 From 8e069bb9aeb4250dd062bb136f4b3db5c4c530ff Mon Sep 17 00:00:00 2001 From: "David T.L. Wong" Date: Wed, 21 Oct 2009 12:29:11 -0300 Subject: V4L/DVB (13210): cx23885: card Mygica X8506 better GPIO setup Signed-off-by: David T.L. Wong Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-cards.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 7438e79a8ef..a2ba09e0aef 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -799,12 +799,13 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) break; case CX23885_BOARD_MYGICA_X8506: case CX23885_BOARD_MAGICPRO_PROHDTVE2: + /* GPIO-0 (0)Analog / (1)Digital TV */ /* GPIO-1 reset XC5000 */ /* GPIO-2 reset LGS8GL5 / LGS8G75 */ - cx_set(GP0_IO, 0x00060000); - cx_clear(GP0_IO, 0x00000006); + cx23885_gpio_enable(dev, GPIO_0 | GPIO_1 | GPIO_2, 1); + cx23885_gpio_clear(dev, GPIO_1 | GPIO_2); mdelay(100); - cx_set(GP0_IO, 0x00060006); + cx23885_gpio_set(dev, GPIO_0 | GPIO_1 | GPIO_2); mdelay(100); break; case CX23885_BOARD_HAUPPAUGE_HVR1850: -- cgit v1.2.3-70-g09d2 From 6f0d8c020ecff4acb959627109d3b81ded211b70 Mon Sep 17 00:00:00 2001 From: "David T.L. Wong" Date: Wed, 21 Oct 2009 13:15:30 -0300 Subject: V4L/DVB (13211): cx23885: card Mygica X8506 analog TV support Signed-off-by: David T.L. Wong Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-cards.c | 14 ++++++++++++-- drivers/media/video/cx23885/cx23885-dvb.c | 5 +++++ drivers/media/video/cx23885/cx23885-video.c | 8 ++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index a2ba09e0aef..2cbac93866b 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -200,10 +200,15 @@ struct cx23885_board cx23885_boards[] = { }, [CX23885_BOARD_MYGICA_X8506] = { .name = "Mygica X8506 DMB-TH", - .tuner_type = TUNER_ABSENT, + .tuner_type = TUNER_XC5000, + .tuner_addr = 0x61, .porta = CX23885_ANALOG_VIDEO, .portb = CX23885_MPEG_DVB, .input = { + { + .type = CX23885_VMUX_TELEVISION, + .vmux = CX25840_COMPOSITE2, + }, { .type = CX23885_VMUX_COMPOSITE1, .vmux = CX25840_COMPOSITE8, @@ -224,10 +229,15 @@ struct cx23885_board cx23885_boards[] = { }, [CX23885_BOARD_MAGICPRO_PROHDTVE2] = { .name = "Magic-Pro ProHDTV Extreme 2", - .tuner_type = TUNER_ABSENT, + .tuner_type = TUNER_XC5000, + .tuner_addr = 0x61, .porta = CX23885_ANALOG_VIDEO, .portb = CX23885_MPEG_DVB, .input = { + { + .type = CX23885_VMUX_TELEVISION, + .vmux = CX25840_COMPOSITE2, + }, { .type = CX23885_VMUX_COMPOSITE1, .vmux = CX25840_COMPOSITE8, diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 875597640d7..4d439f2c4ab 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -486,6 +486,11 @@ static int cx23885_dvb_set_frontend(struct dvb_frontend *fe, break; } break; + case CX23885_BOARD_MYGICA_X8506: + case CX23885_BOARD_MAGICPRO_PROHDTVE2: + /* Select Digital TV */ + cx23885_gpio_set(dev, GPIO_0); + break; } return 0; } diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index e14cb39d841..8b372b4f0de 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -402,6 +402,13 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) INPUT(input)->gpio2, INPUT(input)->gpio3); dev->input = input; + if (dev->board == CX23885_BOARD_MYGICA_X8506 || + dev->board == CX23885_BOARD_MAGICPRO_PROHDTVE2) { + /* Select Analog TV */ + if (INPUT(input)->type == CX23885_VMUX_TELEVISION) + cx23885_gpio_clear(dev, GPIO_0); + } + /* Tell the internal A/V decoder */ v4l2_subdev_call(dev->sd_cx25840, video, s_routing, INPUT(input)->vmux, 0, 0); @@ -1508,6 +1515,7 @@ int cx23885_video_register(struct cx23885_dev *dev) tun_setup.mode_mask = T_ANALOG_TV; tun_setup.type = dev->tuner_type; tun_setup.addr = v4l2_i2c_subdev_addr(sd); + tun_setup.tuner_callback = cx23885_tuner_callback; v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup); } -- cgit v1.2.3-70-g09d2 From e29cd96715ab8b9315fb50096df4677a23d7d6a7 Mon Sep 17 00:00:00 2001 From: "David T.L. Wong" Date: Mon, 26 Oct 2009 08:25:52 -0300 Subject: V4L/DVB (13212): fix gcc-4.3.3 compilation error at dib7000p_pid_filter(): missing parameter name Signed-off-by: David T.L. Wong Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/dib7000p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h index 3a769df3c86..805dd13a97e 100644 --- a/drivers/media/dvb/frontends/dib7000p.h +++ b/drivers/media/dvb/frontends/dib7000p.h @@ -97,7 +97,7 @@ static inline int dib7000pc_detection(struct i2c_adapter *i2c_adap) printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; } -static inline int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff) +static inline int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; -- cgit v1.2.3-70-g09d2 From 1724c8fa7eb33d68898e060a08a8e6a88348b62f Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Fri, 23 Oct 2009 02:47:49 -0300 Subject: V4L/DVB (13214): tda18271: allow for i2c buses that cant send 16 bytes at once There is already an option for sending 16 byte chunks rather that writing 39 bytes all at once during the tuner's initialization. Some i2c buses can't send 16 bytes at once, so create an option for sending 8 byte chunks. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda18271-common.c | 16 ++++++++++++++-- drivers/media/common/tuners/tda18271-fe.c | 3 ++- drivers/media/common/tuners/tda18271-priv.h | 2 +- drivers/media/common/tuners/tda18271.h | 12 +++++++++--- 4 files changed, 26 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c index 155c93eb75d..e1f678281a5 100644 --- a/drivers/media/common/tuners/tda18271-common.c +++ b/drivers/media/common/tuners/tda18271-common.c @@ -326,12 +326,24 @@ int tda18271_init_regs(struct dvb_frontend *fe) regs[R_EB22] = 0x48; regs[R_EB23] = 0xb0; - if (priv->small_i2c) { + switch (priv->small_i2c) { + case TDA18271_08_BYTE_CHUNK_INIT: + tda18271_write_regs(fe, 0x00, 0x08); + tda18271_write_regs(fe, 0x08, 0x08); + tda18271_write_regs(fe, 0x10, 0x08); + tda18271_write_regs(fe, 0x18, 0x08); + tda18271_write_regs(fe, 0x20, 0x07); + break; + case TDA18271_16_BYTE_CHUNK_INIT: tda18271_write_regs(fe, 0x00, 0x10); tda18271_write_regs(fe, 0x10, 0x10); tda18271_write_regs(fe, 0x20, 0x07); - } else + break; + case TDA18271_39_BYTE_CHUNK_INIT: + default: tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS); + break; + } /* setup agc1 gain */ regs[R_EB17] = 0x00; diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index e0fd9f5d594..eb772415886 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c @@ -1224,7 +1224,8 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; priv->role = (cfg) ? cfg->role : TDA18271_MASTER; priv->config = (cfg) ? cfg->config : 0; - priv->small_i2c = (cfg) ? cfg->small_i2c : 0; + priv->small_i2c = (cfg) ? + cfg->small_i2c : TDA18271_39_BYTE_CHUNK_INIT; priv->output_opt = (cfg) ? cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON; diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h index 7047680cdbd..9589ab0576d 100644 --- a/drivers/media/common/tuners/tda18271-priv.h +++ b/drivers/media/common/tuners/tda18271-priv.h @@ -109,10 +109,10 @@ struct tda18271_priv { enum tda18271_i2c_gate gate; enum tda18271_ver id; enum tda18271_output_options output_opt; + enum tda18271_small_i2c small_i2c; unsigned int config; /* interface to saa713x / tda829x */ unsigned int cal_initialized:1; - unsigned int small_i2c:1; u8 tm_rfcal; diff --git a/drivers/media/common/tuners/tda18271.h b/drivers/media/common/tuners/tda18271.h index 323f2912128..d7fcc36dc6e 100644 --- a/drivers/media/common/tuners/tda18271.h +++ b/drivers/media/common/tuners/tda18271.h @@ -78,6 +78,12 @@ enum tda18271_output_options { TDA18271_OUTPUT_XT_OFF = 2, }; +enum tda18271_small_i2c { + TDA18271_39_BYTE_CHUNK_INIT = 0, + TDA18271_16_BYTE_CHUNK_INIT = 1, + TDA18271_08_BYTE_CHUNK_INIT = 2, +}; + struct tda18271_config { /* override default if freq / std settings (optional) */ struct tda18271_std_map *std_map; @@ -91,12 +97,12 @@ struct tda18271_config { /* output options that can be disabled */ enum tda18271_output_options output_opt; + /* some i2c providers cant write all 39 registers at once */ + enum tda18271_small_i2c small_i2c; + /* force rf tracking filter calibration on startup */ unsigned int rf_cal_on_startup:1; - /* some i2c providers cant write all 39 registers at once */ - unsigned int small_i2c:1; - /* interface to saa713x / tda829x */ unsigned int config; }; -- cgit v1.2.3-70-g09d2 From 42f9a03ed3ddcccc5372bf4774afc8c4273c6c3a Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Fri, 23 Oct 2009 03:20:45 -0300 Subject: V4L/DVB (13215): tda18271: add support for the set_config method Add the set_config method to allow drivers to configure the tda18271 driver options after attach. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda18271-fe.c | 39 ++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 13 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index eb772415886..ecb65802725 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c @@ -1185,6 +1185,26 @@ static int tda18271_get_id(struct dvb_frontend *fe) return ret; } +static int tda18271_set_config(struct dvb_frontend *fe, void *priv_cfg) +{ + struct tda18271_priv *priv = fe->tuner_priv; + struct tda18271_config *cfg = (struct tda18271_config *) priv_cfg; + + priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; + priv->role = (cfg) ? cfg->role : TDA18271_MASTER; + priv->config = (cfg) ? cfg->config : 0; + priv->small_i2c = (cfg) ? + cfg->small_i2c : TDA18271_39_BYTE_CHUNK_INIT; + priv->output_opt = (cfg) ? + cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON; + + /* override default std map with values in config struct */ + if ((cfg) && (cfg->std_map)) + tda18271_update_std_map(fe, cfg->std_map); + + return 0; +} + static struct dvb_tuner_ops tda18271_tuner_ops = { .info = { .name = "NXP TDA18271HD", @@ -1197,6 +1217,7 @@ static struct dvb_tuner_ops tda18271_tuner_ops = { .set_params = tda18271_set_params, .set_analog_params = tda18271_set_analog_params, .release = tda18271_release, + .set_config = tda18271_set_config, .get_frequency = tda18271_get_frequency, .get_bandwidth = tda18271_get_bandwidth, }; @@ -1221,13 +1242,9 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, /* new tuner instance */ int rf_cal_on_startup; - priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; - priv->role = (cfg) ? cfg->role : TDA18271_MASTER; - priv->config = (cfg) ? cfg->config : 0; - priv->small_i2c = (cfg) ? - cfg->small_i2c : TDA18271_39_BYTE_CHUNK_INIT; - priv->output_opt = (cfg) ? - cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON; + fe->tuner_priv = priv; + + tda18271_set_config(fe, cfg); /* tda18271_cal_on_startup == -1 when cal * module option is unset */ @@ -1243,8 +1260,6 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, priv->cal_initialized = false; mutex_init(&priv->lock); - fe->tuner_priv = priv; - if (tda_fail(tda18271_get_id(fe))) goto fail; @@ -1276,14 +1291,12 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, priv->small_i2c = cfg->small_i2c; if (cfg->output_opt) priv->output_opt = cfg->output_opt; + if (cfg->std_map) + tda18271_update_std_map(fe, cfg->std_map); } break; } - /* override default std map with values in config struct */ - if ((cfg) && (cfg->std_map)) - tda18271_update_std_map(fe, cfg->std_map); - mutex_unlock(&tda18271_list_mutex); memcpy(&fe->ops.tuner_ops, &tda18271_tuner_ops, -- cgit v1.2.3-70-g09d2 From c54e1dde586ea0e930d6c443ca60a9b9d0310de3 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 24 Oct 2009 17:47:49 -0300 Subject: V4L/DVB (13216): tda18271: initialize tuner during set_config if rf_cal_on_startup is set If rf_cal_on_startup is enabled in the structure passed into tda18271_set_config, and the cal module option isn't disabled, then we should run the initialization and calibration procedures during the tda18271_set_config function call. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda18271-fe.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index ecb65802725..24f1d38081e 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c @@ -1185,10 +1185,10 @@ static int tda18271_get_id(struct dvb_frontend *fe) return ret; } -static int tda18271_set_config(struct dvb_frontend *fe, void *priv_cfg) +static int tda18271_setup_configuration(struct dvb_frontend *fe, + struct tda18271_config *cfg) { struct tda18271_priv *priv = fe->tuner_priv; - struct tda18271_config *cfg = (struct tda18271_config *) priv_cfg; priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; priv->role = (cfg) ? cfg->role : TDA18271_MASTER; @@ -1205,6 +1205,28 @@ static int tda18271_set_config(struct dvb_frontend *fe, void *priv_cfg) return 0; } +static int tda18271_set_config(struct dvb_frontend *fe, void *priv_cfg) +{ + struct tda18271_config *cfg = (struct tda18271_config *) priv_cfg; + int rf_cal_on_startup; + + tda18271_setup_configuration(fe, cfg); + + /* tda18271_cal_on_startup == -1 when cal module option is unset */ + if (tda18271_cal_on_startup == -1) { + /* honor configuration setting */ + rf_cal_on_startup = + ((cfg) && (cfg->rf_cal_on_startup)) ? 1 : 0; + } else { + /* module option overrides configuration setting */ + rf_cal_on_startup = tda18271_cal_on_startup; + } + if (rf_cal_on_startup) + tda18271_init(fe); + + return 0; +} + static struct dvb_tuner_ops tda18271_tuner_ops = { .info = { .name = "NXP TDA18271HD", @@ -1244,7 +1266,7 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, fe->tuner_priv = priv; - tda18271_set_config(fe, cfg); + tda18271_setup_configuration(fe, cfg); /* tda18271_cal_on_startup == -1 when cal * module option is unset */ -- cgit v1.2.3-70-g09d2 From 188ea058ff2e671270273a1f5d13f46ca75b8a35 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 24 Oct 2009 18:18:03 -0300 Subject: V4L/DVB (13217): tda18271: handle rf_cal_on_startup properly during attach If rf_cal_on_startup is enabled in the structure passed into tda18271_attach, and the cal module option isn't disabled, then we should run the initialization and calibration procedures during the tda18271_attach function call, regardless of how many instances of the driver have been attached. If the device is already calibrated, the driver will detect that and will only calibrate again if necessary. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda18271-fe.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index 24f1d38081e..8b934f48b6f 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c @@ -1249,7 +1249,7 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, struct tda18271_config *cfg) { struct tda18271_priv *priv = NULL; - int instance; + int instance, rf_cal_on_startup = 0; mutex_lock(&tda18271_list_mutex); @@ -1262,8 +1262,6 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, case 1: { /* new tuner instance */ - int rf_cal_on_startup; - fe->tuner_priv = priv; tda18271_setup_configuration(fe, cfg); @@ -1315,7 +1313,20 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, priv->output_opt = cfg->output_opt; if (cfg->std_map) tda18271_update_std_map(fe, cfg->std_map); + + /* tda18271_cal_on_startup == -1 when cal + * module option is unset */ + if (tda18271_cal_on_startup == -1) { + /* honor attach-time configuration */ + rf_cal_on_startup = + (cfg->rf_cal_on_startup) ? 1 : 0; + } else { + /* module option overrides attach config */ + rf_cal_on_startup = tda18271_cal_on_startup; + } } + if (rf_cal_on_startup) + tda18271_init(fe); break; } -- cgit v1.2.3-70-g09d2 From 5881ecfca058d731758c76018205b5b3dff9291f Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 24 Oct 2009 18:37:22 -0300 Subject: V4L/DVB (13218): tda18271: consolidate common code for calibration on startup determination consolidate common code used to determine if calibration on startup is needed Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda18271-fe.c | 51 +++++++++---------------------- 1 file changed, 15 insertions(+), 36 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index 8b934f48b6f..cae0df1748f 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c @@ -1205,23 +1205,23 @@ static int tda18271_setup_configuration(struct dvb_frontend *fe, return 0; } +static inline int tda18271_need_cal_on_startup(struct tda18271_config *cfg) +{ + /* tda18271_cal_on_startup == -1 when cal module option is unset */ + return ((tda18271_cal_on_startup == -1) ? + /* honor configuration setting */ + ((cfg) && (cfg->rf_cal_on_startup)) : + /* module option overrides configuration setting */ + (tda18271_cal_on_startup)) ? 1 : 0; +} + static int tda18271_set_config(struct dvb_frontend *fe, void *priv_cfg) { struct tda18271_config *cfg = (struct tda18271_config *) priv_cfg; - int rf_cal_on_startup; tda18271_setup_configuration(fe, cfg); - /* tda18271_cal_on_startup == -1 when cal module option is unset */ - if (tda18271_cal_on_startup == -1) { - /* honor configuration setting */ - rf_cal_on_startup = - ((cfg) && (cfg->rf_cal_on_startup)) ? 1 : 0; - } else { - /* module option overrides configuration setting */ - rf_cal_on_startup = tda18271_cal_on_startup; - } - if (rf_cal_on_startup) + if (tda18271_need_cal_on_startup(cfg)) tda18271_init(fe); return 0; @@ -1249,7 +1249,7 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, struct tda18271_config *cfg) { struct tda18271_priv *priv = NULL; - int instance, rf_cal_on_startup = 0; + int instance; mutex_lock(&tda18271_list_mutex); @@ -1266,17 +1266,6 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, tda18271_setup_configuration(fe, cfg); - /* tda18271_cal_on_startup == -1 when cal - * module option is unset */ - if (tda18271_cal_on_startup == -1) { - /* honor attach-time configuration */ - rf_cal_on_startup = - ((cfg) && (cfg->rf_cal_on_startup)) ? 1 : 0; - } else { - /* module option overrides attach configuration */ - rf_cal_on_startup = tda18271_cal_on_startup; - } - priv->cal_initialized = false; mutex_init(&priv->lock); @@ -1289,7 +1278,8 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, mutex_lock(&priv->lock); tda18271_init_regs(fe); - if ((rf_cal_on_startup) && (priv->id == TDA18271HDC2)) + if ((tda18271_need_cal_on_startup(cfg)) && + (priv->id == TDA18271HDC2)) tda18271c2_rf_cal_init(fe); mutex_unlock(&priv->lock); @@ -1313,19 +1303,8 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, priv->output_opt = cfg->output_opt; if (cfg->std_map) tda18271_update_std_map(fe, cfg->std_map); - - /* tda18271_cal_on_startup == -1 when cal - * module option is unset */ - if (tda18271_cal_on_startup == -1) { - /* honor attach-time configuration */ - rf_cal_on_startup = - (cfg->rf_cal_on_startup) ? 1 : 0; - } else { - /* module option overrides attach config */ - rf_cal_on_startup = tda18271_cal_on_startup; - } } - if (rf_cal_on_startup) + if (tda18271_need_cal_on_startup(cfg)) tda18271_init(fe); break; } -- cgit v1.2.3-70-g09d2 From 712bc0b30fa72edd1b3910250dcaf52894871714 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 25 Oct 2009 12:36:26 -0300 Subject: V4L/DVB (13219): tda18271: remove unneeded braces in switch..case block Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda18271-fe.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index cae0df1748f..9199e362279 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c @@ -1260,7 +1260,6 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, case 0: goto fail; case 1: - { /* new tuner instance */ fe->tuner_priv = priv; @@ -1284,7 +1283,6 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, mutex_unlock(&priv->lock); break; - } default: /* existing tuner instance */ fe->tuner_priv = priv; -- cgit v1.2.3-70-g09d2 From 5abaa530bfe10e2a446679442b283f865a444a32 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 25 Oct 2009 10:43:30 -0300 Subject: V4L/DVB (13220): tda18271: increment module version minor Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda18271-fe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index 9199e362279..07d6e1c159c 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c @@ -1326,7 +1326,7 @@ EXPORT_SYMBOL_GPL(tda18271_attach); MODULE_DESCRIPTION("NXP TDA18271HD analog / digital tuner driver"); MODULE_AUTHOR("Michael Krufky "); MODULE_LICENSE("GPL"); -MODULE_VERSION("0.3"); +MODULE_VERSION("0.4"); /* * Overrides for Emacs so that we follow Linus's tabbing style. -- cgit v1.2.3-70-g09d2 From 4a89baa2e140fd4a12be55e03f8ebe1acabb1328 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Mon, 12 Oct 2009 00:13:28 -0300 Subject: V4L/DVB (13222): pvrusb2: Make more info available to udev pvrusb2: Associate V4L device node in sysfs with the underlying USB device. This opens the door to device information tracking in udev Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 2d8825e5b1b..6aa48e0ae73 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -913,6 +913,15 @@ static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) } +static void pvr2_v4l2_dev_disassociate_parent(struct pvr2_v4l2_dev *dip) +{ + if (!dip) return; + if (!dip->devbase.parent) return; + dip->devbase.parent = NULL; + device_move(&dip->devbase.dev, NULL, DPM_ORDER_NONE); +} + + static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp) { if (vp->dev_video) { @@ -943,6 +952,8 @@ static void pvr2_v4l2_internal_check(struct pvr2_channel *chp) struct pvr2_v4l2 *vp; vp = container_of(chp,struct pvr2_v4l2,channel); if (!vp->channel.mc_head->disconnect_flag) return; + pvr2_v4l2_dev_disassociate_parent(vp->dev_video); + pvr2_v4l2_dev_disassociate_parent(vp->dev_radio); if (vp->vfirst) return; pvr2_v4l2_destroy_no_lock(vp); } @@ -1250,12 +1261,13 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, struct pvr2_v4l2 *vp, int v4l_type) { + struct usb_device *usbdev; int mindevnum; int unit_number; int *nr_ptr = NULL; dip->v4lp = vp; - + usbdev = pvr2_hdw_get_dev(vp->channel.mc_head->hdw); dip->v4l_type = v4l_type; switch (v4l_type) { case VFL_TYPE_GRABBER: @@ -1296,6 +1308,7 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) { mindevnum = nr_ptr[unit_number]; } + dip->devbase.parent = &usbdev->dev; if ((video_register_device(&dip->devbase, dip->v4l_type, mindevnum) < 0) && (video_register_device(&dip->devbase, -- cgit v1.2.3-70-g09d2 From 1b33185f5d944092576fc6562a842c603a2570d6 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Mon, 12 Oct 2009 00:18:13 -0300 Subject: V4L/DVB (13223): pvrusb2: Soften encoder warning message pvrusb2: Encoder failures are mostly recoverable by the driver. While it would sure be nice not to have the failure happen in the first place, this has been going on for years and I doubt that a real solution will ever present itself. I think that part's firmware is just slightly flakey and we have to deal with it. The driver does deal with it just fine, but the warning message going into the kernel log is probably a little more alarming than it should be. So try to soften up the warning somewhat. Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-encoder.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c index 54ac5349dee..e046fdaec5a 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c @@ -294,7 +294,10 @@ static int pvr2_encoder_cmd(void *ctxt, pvr2_trace( PVR2_TRACE_ERROR_LEGS, "Giving up on command." - " This is normally recovered by the driver."); + " This is normally recovered via a firmware" + " reload and re-initialization; concern" + " is only warranted if this happens repeatedly" + " and rapidly."); break; } wrData[0] = 0x7; -- cgit v1.2.3-70-g09d2 From 271081475427f7d1acf5f8cdc51fc70afe662b17 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Mon, 12 Oct 2009 00:21:20 -0300 Subject: V4L/DVB (13224): pvrusb2: Improve diagnostic info on driver initialization failure It used to be that the only real detectable reason for the driver to fail during initialization would be that if the hardware is simply jammed. However with the advent of the sub-device mechanism in V4L it is possible now to detect if a sub-device module fails to load successfully. The pvrusb2 driver does in fact react to this by also (correctly) failing, however the original diagnostic message "hardware is jammed" was still being reported. This misleads the user because in fact it might not actually be a hardware failure. This change adds logic to tell the difference and then report a more appropriate message to the kernel log. Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | 1 + drivers/media/video/pvrusb2/pvrusb2-hdw.c | 28 ++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index 5b152ff20bd..9098494ae59 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h @@ -270,6 +270,7 @@ struct pvr2_hdw { int force_dirty; /* consider all controls dirty if true */ int flag_ok; /* device in known good state */ + int flag_modulefail; /* true if at least one module failed to load */ int flag_disconnected; /* flag_ok == 0 due to disconnect */ int flag_init_ok; /* true if structure is fully initialized */ int fw1_state; /* current situation with fw1 */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 13639b30270..33ea950abb4 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -2030,7 +2030,8 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw, fname = (mid < ARRAY_SIZE(module_names)) ? module_names[mid] : NULL; if (!fname) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Module ID %u for device %s has no name", + "Module ID %u for device %s has no name?" + " The driver might have a configuration problem.", mid, hdw->hdw_desc->description); return -EINVAL; @@ -2058,7 +2059,8 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw, if (!i2ccnt) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Module ID %u (%s) for device %s:" - " No i2c addresses", + " No i2c addresses." + " The driver might have a configuration problem.", mid, fname, hdw->hdw_desc->description); return -EINVAL; } @@ -2090,7 +2092,9 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw, if (!sd) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Module ID %u (%s) for device %s failed to load", + "Module ID %u (%s) for device %s failed to load." + " Possible missing sub-device kernel module or" + " initialization failure within module.", mid, fname, hdw->hdw_desc->description); return -EIO; } @@ -2132,7 +2136,10 @@ static void pvr2_hdw_load_modules(struct pvr2_hdw *hdw) for (idx = 0; idx < ct->cnt; idx++) { if (pvr2_hdw_load_subdev(hdw, &ct->lst[idx]) < 0) okFl = 0; } - if (!okFl) pvr2_hdw_render_useless(hdw); + if (!okFl) { + hdw->flag_modulefail = !0; + pvr2_hdw_render_useless(hdw); + } } @@ -2334,6 +2341,19 @@ static void pvr2_hdw_setup(struct pvr2_hdw *hdw) break; } } + if (hdw->flag_modulefail) { + pvr2_trace( + PVR2_TRACE_ERROR_LEGS, + "***WARNING*** pvrusb2 driver initialization" + " failed due to the failure of one or more" + " sub-device kernel modules."); + pvr2_trace( + PVR2_TRACE_ERROR_LEGS, + "You need to resolve the failing condition" + " before this driver can function. There" + " should be some earlier messages giving more" + " information about the problem."); + } if (procreload) { pvr2_trace( PVR2_TRACE_ERROR_LEGS, -- cgit v1.2.3-70-g09d2 From 00970beb9b51dd1b25c0d91a3f5fe11dd29e38e2 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Mon, 12 Oct 2009 00:23:37 -0300 Subject: V4L/DVB (13225): pvrusb2: Report hardware description to kernel log upon initialization The driver also contains a piece of configuration data that produces a one line description of the specific hardware being driver (e.g. "Hauppauge 24xxx", "OnAir", etc). This change generates an informational message to the kernel log reporting the hardware type being driven. This is a very useful thing to know when diagnosing problems. Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-hdw.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 33ea950abb4..1bfa9b9d7aa 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -2439,6 +2439,8 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, hdw = kzalloc(sizeof(*hdw),GFP_KERNEL); pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"", hdw,hdw_desc->description); + pvr2_trace(PVR2_TRACE_INFO, "Hardware description attached: %s", + hdw_desc->description); if (!hdw) goto fail; init_timer(&hdw->quiescent_timer); -- cgit v1.2.3-70-g09d2 From aa976ca1dfb2e5b3fb67eeaf1ca44182ef3efcdb Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Mon, 12 Oct 2009 00:25:09 -0300 Subject: V4L/DVB (13226): pvrusb2: Add hardware description to debuginfo output Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-debugifc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c index fbe3856bdca..010018bc838 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c +++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c @@ -142,6 +142,9 @@ int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt) { int bcnt = 0; int ccnt; + ccnt = scnprintf(buf, acnt, "Driver hardware description: %s\n", + pvr2_hdw_get_desc(hdw)); + bcnt += ccnt; acnt -= ccnt; buf += ccnt; ccnt = scnprintf(buf,acnt,"Driver state info:\n"); bcnt += ccnt; acnt -= ccnt; buf += ccnt; ccnt = pvr2_hdw_state_report(hdw,buf,acnt); -- cgit v1.2.3-70-g09d2 From 515ebf79e579d423d60aea4334d61007328c5114 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Mon, 12 Oct 2009 00:27:38 -0300 Subject: V4L/DVB (13227): pvrusb2: Fix redundant message on driver initialization failure (missing break) After detecting failure due to module initialization error, get out. Don't report jammed hardware. Problem due to a missing break statement. Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-hdw.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 1bfa9b9d7aa..4a464ff3bb0 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -2353,6 +2353,7 @@ static void pvr2_hdw_setup(struct pvr2_hdw *hdw) " before this driver can function. There" " should be some earlier messages giving more" " information about the problem."); + break; } if (procreload) { pvr2_trace( -- cgit v1.2.3-70-g09d2 From e67e376b1e50b60238410893971c5e6c4dd19ef1 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Mon, 12 Oct 2009 00:28:19 -0300 Subject: V4L/DVB (13228): pvrusb2: Cosmetic kernel log tweak Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-hdw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 4a464ff3bb0..4c1a2a53442 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -2440,7 +2440,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, hdw = kzalloc(sizeof(*hdw),GFP_KERNEL); pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"", hdw,hdw_desc->description); - pvr2_trace(PVR2_TRACE_INFO, "Hardware description attached: %s", + pvr2_trace(PVR2_TRACE_INFO, "Hardware description: %s", hdw_desc->description); if (!hdw) goto fail; -- cgit v1.2.3-70-g09d2 From 2d8d7762d75d36a08a4a5c3d3f1c301f76cb8f56 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 24 Sep 2009 07:58:09 -0300 Subject: V4L/DVB (13231): pwc: Use kernel's simple_strtol() Change own implementation of pwc_atoi() by simple_strtol(x, NULL, 10). Signed-off-by: Andy Shevchenko Acked-by: Pekka Enberg Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pwc/pwc-if.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index f976df452a3..89b620f6db7 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -68,6 +68,7 @@ #endif #include #include +#include /* simple_strtol() */ #include "pwc.h" #include "pwc-kiara.h" @@ -1916,19 +1917,6 @@ disconnect_out: unlock_kernel(); } -/* *grunt* We have to do atoi ourselves :-( */ -static int pwc_atoi(const char *s) -{ - int k = 0; - - k = 0; - while (*s != '\0' && *s >= '0' && *s <= '9') { - k = 10 * k + (*s - '0'); - s++; - } - return k; -} - /* * Initialization code & module stuff @@ -2078,13 +2066,16 @@ static int __init usb_pwc_init(void) } else { /* No type or serial number specified, just a number. */ - device_hint[i].device_node = pwc_atoi(s); + device_hint[i].device_node = + simple_strtol(s, NULL, 10); } } else { /* There's a colon, so we have at least a type and a device node */ - device_hint[i].type = pwc_atoi(s); - device_hint[i].device_node = pwc_atoi(colon + 1); + device_hint[i].type = + simple_strtol(s, NULL, 10); + device_hint[i].device_node = + simple_strtol(colon + 1, NULL, 10); if (*dot != '\0') { /* There's a serial number as well */ int k; -- cgit v1.2.3-70-g09d2 From 3c3099d5edd719aebfccf63b628b6f11afa59bfe Mon Sep 17 00:00:00 2001 From: "Aleksandr V. Piskunov" Date: Fri, 25 Sep 2009 18:16:21 -0300 Subject: V4L/DVB (13232): cx25840 6.5MHz carrier detection fixes cx25840: Disable 6.5MHz carrier autodetection for PAL, always assume its DK. Only try to autodetect 6.5MHz carrier for SECAM if user accepts both system DK and L. Signed-off-by: Aleksandr V. Piskunov Reviewed-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx25840/cx25840-core.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 9702a9334b4..385ecd58f1c 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -685,13 +685,30 @@ static void input_change(struct i2c_client *client) } cx25840_write(client, 0x80b, 0x00); } else if (std & V4L2_STD_PAL) { - /* Follow tuner change procedure for PAL */ + /* Autodetect audio standard and audio system */ cx25840_write(client, 0x808, 0xff); - cx25840_write(client, 0x80b, 0x10); + /* Since system PAL-L is pretty much non-existant and + not used by any public broadcast network, force + 6.5 MHz carrier to be interpreted as System DK, + this avoids DK audio detection instability */ + cx25840_write(client, 0x80b, 0x00); } else if (std & V4L2_STD_SECAM) { - /* Select autodetect for SECAM */ + /* Autodetect audio standard and audio system */ cx25840_write(client, 0x808, 0xff); - cx25840_write(client, 0x80b, 0x10); + /* If only one of SECAM-DK / SECAM-L is required, then force + 6.5MHz carrier, else autodetect it */ + if ((std & V4L2_STD_SECAM_DK) && + !(std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) { + /* 6.5 MHz carrier to be interpreted as System DK */ + cx25840_write(client, 0x80b, 0x00); + } else if (!(std & V4L2_STD_SECAM_DK) && + (std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) { + /* 6.5 MHz carrier to be interpreted as System L */ + cx25840_write(client, 0x80b, 0x08); + } else { + /* 6.5 MHz carrier to be autodetected */ + cx25840_write(client, 0x80b, 0x10); + } } cx25840_and_or(client, 0x810, ~0x01, 0); -- cgit v1.2.3-70-g09d2 From 43e16ea241cab1f4d4206307b2f6eacbaf4dc335 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 2 Oct 2009 05:47:08 -0300 Subject: V4L/DVB (13233): i2c_board_info can be local Recent fixes to the em28xx and saa7134 drivers have been overzealous. While the ir-kbd-i2c platform data indeed needs to be persistent, the struct i2c_board_info doesn't, as it is only used by i2c_new_device(). So revert a part of the original fixes, to save some memory. Signed-off-by: Jean Delvare Acked-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-cards.c | 9 +++++---- drivers/media/video/em28xx/em28xx.h | 1 - drivers/media/video/saa7134/saa7134-input.c | 21 +++++++++++---------- drivers/media/video/saa7134/saa7134.h | 1 - 4 files changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 7ccac2095b7..6c7cbbc59e1 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -2234,6 +2234,7 @@ static int em28xx_hint_board(struct em28xx *dev) /* ----------------------------------------------------------------------- */ void em28xx_register_i2c_ir(struct em28xx *dev) { + struct i2c_board_info info; const unsigned short addr_list[] = { 0x30, 0x47, I2C_CLIENT_END }; @@ -2241,9 +2242,9 @@ void em28xx_register_i2c_ir(struct em28xx *dev) if (disable_ir) return; - memset(&dev->info, 0, sizeof(&dev->info)); + memset(&info, 0, sizeof(struct i2c_board_info)); memset(&dev->init_data, 0, sizeof(dev->init_data)); - strlcpy(dev->info.type, "ir_video", I2C_NAME_SIZE); + strlcpy(info.type, "ir_video", I2C_NAME_SIZE); /* detect & configure */ switch (dev->model) { @@ -2266,8 +2267,8 @@ void em28xx_register_i2c_ir(struct em28xx *dev) } if (dev->init_data.name) - dev->info.platform_data = &dev->init_data; - i2c_new_probed_device(&dev->i2c_adap, &dev->info, addr_list); + info.platform_data = &dev->init_data; + i2c_new_probed_device(&dev->i2c_adap, &info, addr_list); } void em28xx_card_setup(struct em28xx *dev) diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 0a73e8bf0d6..a476f7bb7bf 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -615,7 +615,6 @@ struct em28xx { struct em28xx_dvb *dvb; /* I2C keyboard data */ - struct i2c_board_info info; struct IR_i2c_init_data init_data; }; diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index a0e8c62e6ae..bcb65e93edc 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -695,6 +695,7 @@ void saa7134_input_fini(struct saa7134_dev *dev) void saa7134_probe_i2c_ir(struct saa7134_dev *dev) { + struct i2c_board_info info; const unsigned short addr_list[] = { 0x7a, 0x47, 0x71, 0x2d, I2C_CLIENT_END @@ -714,9 +715,9 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) return; } - memset(&dev->info, 0, sizeof(dev->info)); + memset(&info, 0, sizeof(struct i2c_board_info)); memset(&dev->init_data, 0, sizeof(dev->init_data)); - strlcpy(dev->info.type, "ir_video", I2C_NAME_SIZE); + strlcpy(info.type, "ir_video", I2C_NAME_SIZE); switch (dev->board) { case SAA7134_BOARD_PINNACLE_PCTV_110i: @@ -725,11 +726,11 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) if (pinnacle_remote == 0) { dev->init_data.get_key = get_key_pinnacle_color; dev->init_data.ir_codes = &ir_codes_pinnacle_color_table; - dev->info.addr = 0x47; + info.addr = 0x47; } else { dev->init_data.get_key = get_key_pinnacle_grey; dev->init_data.ir_codes = &ir_codes_pinnacle_grey_table; - dev->info.addr = 0x47; + info.addr = 0x47; } break; case SAA7134_BOARD_UPMOST_PURPLE_TV: @@ -741,7 +742,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) dev->init_data.name = "MSI TV@nywhere Plus"; dev->init_data.get_key = get_key_msi_tvanywhere_plus; dev->init_data.ir_codes = &ir_codes_msi_tvanywhere_plus_table; - dev->info.addr = 0x30; + info.addr = 0x30; /* MSI TV@nywhere Plus controller doesn't seem to respond to probes unless we read something from an existing device. Weird... @@ -775,20 +776,20 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) break; case SAA7134_BOARD_AVERMEDIA_CARDBUS_501: case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: - dev->info.addr = 0x40; + info.addr = 0x40; break; } if (dev->init_data.name) - dev->info.platform_data = &dev->init_data; + info.platform_data = &dev->init_data; /* No need to probe if address is known */ - if (dev->info.addr) { - i2c_new_device(&dev->i2c_adap, &dev->info); + if (info.addr) { + i2c_new_device(&dev->i2c_adap, &info); return; } /* Address not known, fallback to probing */ - i2c_new_probed_device(&dev->i2c_adap, &dev->info, addr_list); + i2c_new_probed_device(&dev->i2c_adap, &info, addr_list); } static int saa7134_rc5_irq(struct saa7134_dev *dev) diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 13a861bedc3..53b7e0b8a2f 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -594,7 +594,6 @@ struct saa7134_dev { unsigned int insuspend; /* I2C keyboard data */ - struct i2c_board_info info; struct IR_i2c_init_data init_data; /* SAA7134_MPEG_* */ -- cgit v1.2.3-70-g09d2 From aef02aa1e2593b39f808b2b8ae928699087b96dc Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 2 Oct 2009 08:47:22 -0300 Subject: V4L/DVB (13234): IR device at I2C address 0x7a The i2c core prevents us from probing I2C address 0x7a because it's not a valid 7-bit address (reserved for 10-bit addressing.) So we must stop probing this address, and explicitly list all adapters which use it. Under the assumption that only the Upmost Purple TV adapter uses this invalid address, this fix should do the trick. Signed-off-by: Jean Delvare Acked-by: hermann pitton Acked-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-input.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index bcb65e93edc..c3b5cfa13b6 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -697,7 +697,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) { struct i2c_board_info info; const unsigned short addr_list[] = { - 0x7a, 0x47, 0x71, 0x2d, + 0x47, 0x71, 0x2d, I2C_CLIENT_END }; @@ -737,6 +737,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) dev->init_data.name = "Purple TV"; dev->init_data.get_key = get_key_purpletv; dev->init_data.ir_codes = &ir_codes_purpletv_table; + info.addr = 0x7a; break; case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: dev->init_data.name = "MSI TV@nywhere Plus"; -- cgit v1.2.3-70-g09d2 From 30093e8bf90217deef07299bae45d95ddc5fdb8a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 2 Oct 2009 09:48:04 -0300 Subject: V4L/DVB (13235): saa7134: Complete the IR address list Google is pretty clear that the HVR 1110 IR chip is always at address 0x71 and the BeholdTV IR chip is always at address 0x2d. This completes the list of IR device addresses for the SAA7134-based adapters, and we no longer need to probe any of them. Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-input.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index c3b5cfa13b6..8f9203e7d3b 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -696,10 +696,6 @@ void saa7134_input_fini(struct saa7134_dev *dev) void saa7134_probe_i2c_ir(struct saa7134_dev *dev) { struct i2c_board_info info; - const unsigned short addr_list[] = { - 0x47, 0x71, 0x2d, - I2C_CLIENT_END - }; struct i2c_msg msg_msi = { .addr = 0x50, @@ -757,6 +753,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) dev->init_data.name = "HVR 1110"; dev->init_data.get_key = get_key_hvr1110; dev->init_data.ir_codes = &ir_codes_hauppauge_new_table; + info.addr = 0x71; break; case SAA7134_BOARD_BEHOLD_607FM_MK3: case SAA7134_BOARD_BEHOLD_607FM_MK5: @@ -774,23 +771,20 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) dev->init_data.name = "BeholdTV"; dev->init_data.get_key = get_key_beholdm6xx; dev->init_data.ir_codes = &ir_codes_behold_table; + info.addr = 0x2d; break; case SAA7134_BOARD_AVERMEDIA_CARDBUS_501: case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: info.addr = 0x40; break; + default: + dprintk("No I2C IR support for board %x\n", dev->board); + return; } if (dev->init_data.name) info.platform_data = &dev->init_data; - /* No need to probe if address is known */ - if (info.addr) { - i2c_new_device(&dev->i2c_adap, &info); - return; - } - - /* Address not known, fallback to probing */ - i2c_new_probed_device(&dev->i2c_adap, &info, addr_list); + i2c_new_device(&dev->i2c_adap, &info); } static int saa7134_rc5_irq(struct saa7134_dev *dev) -- cgit v1.2.3-70-g09d2 From 7ef68e60d9435eb604a346babccb48000b94bc76 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 2 Oct 2009 10:27:42 -0300 Subject: V4L/DVB (13236): ir-kbd-i2c: Don't reject unknown I2C addresses I do not think it makes sense any longer for ir-kbd-i2c to reject devices at unknown I2C addresses. The caller can provide all the details about how the device should be handled. Having to add new addresses to ir-kbd-i2c so that they aren't rejected is a pain we don't need. Unsupported devices will be spotted a few lines later anyway. This already lets us unlist 2 addresses (0x7a and 0x2d) for which handling details are always provided by the caller (saa7134-input). Hopefully we can remove more in the future. Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ir-kbd-i2c.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 247d3115a9b..aec36660987 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -299,7 +299,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct ir_scancode_table *ir_codes = NULL; const char *name = NULL; - int ir_type; + int ir_type = 0; struct IR_i2c *ir; struct input_dev *input_dev; struct i2c_adapter *adap = client->adapter; @@ -353,10 +353,8 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) ir_type = IR_TYPE_RC5; ir_codes = &ir_codes_fusionhdtv_mce_table; break; - case 0x7a: case 0x47: case 0x71: - case 0x2d: if (adap->id == I2C_HW_B_CX2388x || adap->id == I2C_HW_B_CX2341X) { /* Handled by cx88-input */ @@ -381,10 +379,6 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) ir_type = IR_TYPE_OTHER; ir_codes = &ir_codes_avermedia_cardbus_table; break; - default: - dprintk(1, DEVNAME ": Unsupported i2c address 0x%02x\n", addr); - err = -ENODEV; - goto err_out_free; } /* Let the caller override settings */ @@ -427,7 +421,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) } /* Make sure we are all setup before going on */ - if (!name || !ir->get_key || !ir_codes) { + if (!name || !ir->get_key || !ir_type || !ir_codes) { dprintk(1, DEVNAME ": Unsupported device at address 0x%02x\n", addr); err = -ENODEV; -- cgit v1.2.3-70-g09d2 From 622b828ab795580903e79acb33fb44f5c9ce7b0f Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 5 Oct 2009 10:48:17 -0300 Subject: V4L/DVB (13238): v4l2_subdev: rename tuner s_standby operation to core s_power Upcoming I2C v4l2_subdev drivers need a way to control the subdevice power state from the core. This use case is already partially covered by the tuner s_standby operation, but no way to explicitly come back from the standby state is available. Rename the tuner s_standby operation to core s_power, and fix tuner drivers accordingly. The tuner core will call s_power(0) instead of s_standby(). No explicit call to s_power(1) is required for tuners as they are supposed to wake up from standby automatically. [mchehab@redhat.com: CodingStyle fix] Signed-off-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/au0828/au0828-video.c | 2 +- drivers/media/video/cx231xx/cx231xx-video.c | 2 +- drivers/media/video/cx23885/cx23885-core.c | 2 +- drivers/media/video/cx23885/cx23885-dvb.c | 2 +- drivers/media/video/cx88/cx88-cards.c | 2 +- drivers/media/video/cx88/cx88-dvb.c | 2 +- drivers/media/video/cx88/cx88-video.c | 2 +- drivers/media/video/em28xx/em28xx-cards.c | 2 +- drivers/media/video/em28xx/em28xx-video.c | 2 +- drivers/media/video/saa7134/saa7134-core.c | 2 +- drivers/media/video/saa7134/saa7134-video.c | 2 +- drivers/media/video/tuner-core.c | 9 ++++++--- include/media/v4l2-subdev.h | 7 ++++--- 13 files changed, 21 insertions(+), 17 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c index 51527d7b55a..1485aee18d5 100644 --- a/drivers/media/video/au0828/au0828-video.c +++ b/drivers/media/video/au0828/au0828-video.c @@ -830,7 +830,7 @@ static int au0828_v4l2_close(struct file *filp) au0828_uninit_isoc(dev); /* Save some power by putting tuner to sleep */ - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby); + v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0); /* When close the device, set the usb intf0 into alt0 to free USB bandwidth */ diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c index 36503725d97..d095aa0d6d1 100644 --- a/drivers/media/video/cx231xx/cx231xx-video.c +++ b/drivers/media/video/cx231xx/cx231xx-video.c @@ -2106,7 +2106,7 @@ static int cx231xx_v4l2_close(struct file *filp) } /* Save some power by putting tuner to sleep */ - call_all(dev, tuner, s_standby); + call_all(dev, core, s_power, 0); /* do this before setting alternate! */ cx231xx_uninit_isoc(dev); diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index d6e41db500e..e34a4ec4a2c 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -919,7 +919,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) cx23885_i2c_register(&dev->i2c_bus[1]); cx23885_i2c_register(&dev->i2c_bus[2]); cx23885_card_setup(dev); - call_all(dev, tuner, s_standby); + call_all(dev, core, s_power, 0); cx23885_ir_init(dev); if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) { diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 4d439f2c4ab..f4f046cd81a 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -920,7 +920,7 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend->callback = cx23885_tuner_callback; /* Put the analog decoder in standby to keep it quiet */ - call_all(dev, tuner, s_standby); + call_all(dev, core, s_power, 0); if (fe0->dvb.frontend->ops.analog_ops.standby) fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend); diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 33be6369871..7330a2d7043 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c @@ -3267,7 +3267,7 @@ static void cx88_card_setup(struct cx88_core *core) ctl.fname); call_all(core, tuner, s_config, &xc2028_cfg); } - call_all(core, tuner, s_standby); + call_all(core, core, s_power, 0); } /* ------------------------------------------------------------------ */ diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index d9e402b25b5..9df71d0244a 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c @@ -1170,7 +1170,7 @@ static int dvb_register(struct cx8802_dev *dev) fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; /* Put the analog decoder in standby to keep it quiet */ - call_all(core, tuner, s_standby); + call_all(core, core, s_power, 0); /* register everything */ return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 57e6b124109..d7e8fcee559 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -935,7 +935,7 @@ static int video_release(struct file *file) mutex_lock(&dev->core->lock); if(atomic_dec_and_test(&dev->core->users)) - call_all(dev->core, tuner, s_standby); + call_all(dev->core, core, s_power, 0); mutex_unlock(&dev->core->lock); return 0; diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 6c7cbbc59e1..1e193707073 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -2658,7 +2658,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, em28xx_init_extension(dev); /* Save some power by putting tuner to sleep */ - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby); + v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0); return 0; diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 3a1dfb7726f..fbe536f092f 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -2225,7 +2225,7 @@ static int em28xx_v4l2_close(struct file *filp) } /* Save some power by putting tuner to sleep */ - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby); + v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0); /* do this before setting alternate! */ em28xx_uninit_isoc(dev); diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index f87757fccc7..9a5df930885 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -1032,7 +1032,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, saa7134_irq_video_signalchange(dev); if (TUNER_ABSENT != dev->tuner_type) - saa_call_all(dev, tuner, s_standby); + saa_call_all(dev, core, s_power, 0); /* register v4l devices */ if (saa7134_no_overlay > 0) diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index da26f476a30..35f8daa3a35 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -1499,7 +1499,7 @@ static int video_release(struct file *file) saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0); saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0); - saa_call_all(dev, tuner, s_standby); + saa_call_all(dev, core, s_power, 0); if (fh->radio) saa_call_all(dev, core, ioctl, RDS_CMD_CLOSE, &cmd); diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index aba92e2313d..50f6db5cd50 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -752,14 +752,17 @@ static int tuner_s_radio(struct v4l2_subdev *sd) return 0; } -static int tuner_s_standby(struct v4l2_subdev *sd) +static int tuner_s_power(struct v4l2_subdev *sd, int on) { struct tuner *t = to_tuner(sd); struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; + if (on) + return 0; + tuner_dbg("Putting tuner to sleep\n"); - if (check_mode(t, "s_standby") == -EINVAL) + if (check_mode(t, "s_power") == -EINVAL) return 0; t->mode = T_STANDBY; if (analog_ops->standby) @@ -961,6 +964,7 @@ static int tuner_command(struct i2c_client *client, unsigned cmd, void *arg) static const struct v4l2_subdev_core_ops tuner_core_ops = { .log_status = tuner_log_status, .s_std = tuner_s_std, + .s_power = tuner_s_power, }; static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = { @@ -971,7 +975,6 @@ static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = { .g_frequency = tuner_g_frequency, .s_type_addr = tuner_s_type_addr, .s_config = tuner_s_config, - .s_standby = tuner_s_standby, }; static const struct v4l2_subdev_ops tuner_ops = { diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index ecc2818938b..88c13d6f791 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -106,6 +106,9 @@ struct v4l2_decode_vbi_line { s_gpio: set GPIO pins. Very simple right now, might need to be extended with a direction argument if needed. + + s_power: puts subdevice in power saving mode (on == 0) or normal operation + mode (on == 1). */ struct v4l2_subdev_core_ops { int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip); @@ -128,6 +131,7 @@ struct v4l2_subdev_core_ops { int (*g_register)(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg); int (*s_register)(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg); #endif + int (*s_power)(struct v4l2_subdev *sd, int on); }; /* s_mode: switch the tuner to a specific tuner mode. Replacement of s_radio. @@ -137,8 +141,6 @@ struct v4l2_subdev_core_ops { s_type_addr: sets tuner type and its I2C addr. s_config: sets tda9887 specific stuff, like port1, port2 and qss - - s_standby: puts tuner on powersaving state, disabling it, except for i2c. */ struct v4l2_subdev_tuner_ops { int (*s_mode)(struct v4l2_subdev *sd, enum v4l2_tuner_type); @@ -151,7 +153,6 @@ struct v4l2_subdev_tuner_ops { int (*s_modulator)(struct v4l2_subdev *sd, struct v4l2_modulator *vm); int (*s_type_addr)(struct v4l2_subdev *sd, struct tuner_setup *type); int (*s_config)(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *config); - int (*s_standby)(struct v4l2_subdev *sd); }; /* s_clock_freq: set the frequency (in Hz) of the audio clock output. -- cgit v1.2.3-70-g09d2 From 311c70e1f906b7411b30f526ef15deb62cb37e7a Mon Sep 17 00:00:00 2001 From: Johann Friedrichs Date: Wed, 7 Oct 2009 04:41:37 -0300 Subject: V4L/DVB (13239): saa7146: fix memory leakage in pagetable-handling In buffer_release() the previously allocated pagetables are not freed, which might result in a memory leak in certain application use-cases, where the frame format is changed from planar format to non-planar format. The fix explicitely frees the page tables when a format change is done and when buffer_release() is called. Signed-off-by: Johann Friedrichs Signed-off-by: Michael Hunold Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/saa7146_video.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index 552dab442d7..becbaadb3b7 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c @@ -1205,6 +1205,13 @@ static int buffer_activate (struct saa7146_dev *dev, return 0; } +static void release_all_pagetables(struct saa7146_dev *dev, struct saa7146_buf *buf) +{ + saa7146_pgtable_free(dev->pci, &buf->pt[0]); + saa7146_pgtable_free(dev->pci, &buf->pt[1]); + saa7146_pgtable_free(dev->pci, &buf->pt[2]); +} + static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, enum v4l2_field field) { @@ -1257,16 +1264,12 @@ static int buffer_prepare(struct videobuf_queue *q, sfmt = format_by_fourcc(dev,buf->fmt->pixelformat); + release_all_pagetables(dev, buf); if( 0 != IS_PLANAR(sfmt->trans)) { - saa7146_pgtable_free(dev->pci, &buf->pt[0]); - saa7146_pgtable_free(dev->pci, &buf->pt[1]); - saa7146_pgtable_free(dev->pci, &buf->pt[2]); - saa7146_pgtable_alloc(dev->pci, &buf->pt[0]); saa7146_pgtable_alloc(dev->pci, &buf->pt[1]); saa7146_pgtable_alloc(dev->pci, &buf->pt[2]); } else { - saa7146_pgtable_free(dev->pci, &buf->pt[0]); saa7146_pgtable_alloc(dev->pci, &buf->pt[0]); } @@ -1329,6 +1332,9 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) struct saa7146_buf *buf = (struct saa7146_buf *)vb; DEB_CAP(("vbuf:%p\n",vb)); + + release_all_pagetables(dev, buf); + saa7146_dma_free(dev,q,buf); } -- cgit v1.2.3-70-g09d2 From f14a2972e40dbfbe7077ec7ab21cc2729f7e7d6d Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Fri, 23 Oct 2009 07:59:42 -0300 Subject: V4L/DVB (13241): Cleanup redundant tests on unsigned The variables are unsigned so the test `>= 0' is always true, the `< 0' test always fails. In these cases the other part of the test catches wrapped values. Signed-off-by: Roel Kluin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda9887.c | 2 +- drivers/media/dvb/siano/smscoreapi.c | 2 +- drivers/media/video/bt819.c | 2 +- drivers/media/video/hexium_gemini.c | 2 +- drivers/media/video/hexium_orion.c | 2 +- drivers/media/video/mxb.c | 2 +- drivers/media/video/s2255drv.c | 2 +- drivers/media/video/saa7110.c | 2 +- drivers/media/video/saa717x.c | 2 +- drivers/media/video/tuner-core.c | 2 +- drivers/media/video/usbvision/usbvision-video.c | 2 +- drivers/media/video/vpx3220.c | 2 +- drivers/media/video/zoran/zoran_driver.c | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/tda9887.c b/drivers/media/common/tuners/tda9887.c index 544cdbe88a6..a71c100c95d 100644 --- a/drivers/media/common/tuners/tda9887.c +++ b/drivers/media/common/tuners/tda9887.c @@ -463,7 +463,7 @@ static int tda9887_set_insmod(struct dvb_frontend *fe) buf[1] &= ~cQSS; } - if (adjust >= 0x00 && adjust < 0x20) { + if (adjust < 0x20) { buf[2] &= ~cTopMask; buf[2] |= adjust; } diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index fa6a62369a7..ca758bcb48c 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -1373,7 +1373,7 @@ static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum, *pGroupCfg = 1; - if (PinNum >= 0 && PinNum <= 1) { + if (PinNum <= 1) { *pTranslatedPinNum = 0; *pGroupNum = 9; *pGroupCfg = 2; diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c index f9330e3529c..5bb0f9e7158 100644 --- a/drivers/media/video/bt819.c +++ b/drivers/media/video/bt819.c @@ -299,7 +299,7 @@ static int bt819_s_routing(struct v4l2_subdev *sd, v4l2_dbg(1, debug, sd, "set input %x\n", input); - if (input < 0 || input > 7) + if (input > 7) return -EINVAL; if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL) diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c index 71c211402eb..60d992ee258 100644 --- a/drivers/media/video/hexium_gemini.c +++ b/drivers/media/video/hexium_gemini.c @@ -251,7 +251,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input) DEB_EE(("VIDIOC_S_INPUT %d.\n", input)); - if (input < 0 || input >= HEXIUM_INPUTS) + if (input >= HEXIUM_INPUTS) return -EINVAL; hexium->cur_input = input; diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c index 39d65ca41c6..938a1f8f880 100644 --- a/drivers/media/video/hexium_orion.c +++ b/drivers/media/video/hexium_orion.c @@ -350,7 +350,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input) struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; struct hexium *hexium = (struct hexium *) dev->ext_priv; - if (input < 0 || input >= HEXIUM_INPUTS) + if (input >= HEXIUM_INPUTS) return -EINVAL; hexium->cur_input = input; diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index 3454070e63f..c1fc6dc776f 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c @@ -478,7 +478,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input) DEB_EE(("VIDIOC_S_INPUT %d.\n", input)); - if (input < 0 || input >= MXB_INPUTS) + if (input >= MXB_INPUTS) return -EINVAL; mxb->cur_input = input; diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 2c0bb06cab3..d0824f3c734 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c @@ -1958,7 +1958,7 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) if (pdword[1] >= MAX_CHANNELS) break; cc = G_chnmap[pdword[1]]; - if (!(cc >= 0 && cc < MAX_CHANNELS)) + if (cc >= MAX_CHANNELS) break; switch (pdword[2]) { case S2255_RESPONSE_SETMODE: diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c index 5c24c993ac1..3bca744e43a 100644 --- a/drivers/media/video/saa7110.c +++ b/drivers/media/video/saa7110.c @@ -304,7 +304,7 @@ static int saa7110_s_routing(struct v4l2_subdev *sd, { struct saa7110 *decoder = to_saa7110(sd); - if (input < 0 || input >= SAA7110_MAX_INPUT) { + if (input >= SAA7110_MAX_INPUT) { v4l2_dbg(1, debug, sd, "input=%d not available\n", input); return -EINVAL; } diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c index b15c40908e8..ad6cd37311f 100644 --- a/drivers/media/video/saa717x.c +++ b/drivers/media/video/saa717x.c @@ -1115,7 +1115,7 @@ static int saa717x_s_video_routing(struct v4l2_subdev *sd, v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", input); /* inputs from 0-9 are available*/ /* saa717x have mode0-mode9 but mode5 is reserved. */ - if (input < 0 || input > 9 || input == 5) + if (input > 9 || input == 5) return -EINVAL; if (decoder->input != input) { diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 50f6db5cd50..a9c9703113c 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -328,7 +328,7 @@ static void set_type(struct i2c_client *c, unsigned int type, t->type = type; /* prevent invalid config values */ - t->config = ((new_config >= 0) && (new_config < 256)) ? new_config : 0; + t->config = new_config < 256 ? new_config : 0; if (tuner_callback != NULL) { tuner_dbg("defining GPIO callback\n"); t->fe.callback = tuner_callback; diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index a2a50d608a3..c07b0ac452a 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -601,7 +601,7 @@ static int vidioc_s_input (struct file *file, void *priv, unsigned int input) { struct usb_usbvision *usbvision = video_drvdata(file); - if ((input >= usbvision->video_inputs) || (input < 0) ) + if (input >= usbvision->video_inputs) return -EINVAL; mutex_lock(&usbvision->lock); diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c index 97e0ce28ff1..33205d7537d 100644 --- a/drivers/media/video/vpx3220.c +++ b/drivers/media/video/vpx3220.c @@ -391,7 +391,7 @@ static int vpx3220_s_routing(struct v4l2_subdev *sd, {0x0e, 1} }; - if (input < 0 || input > 2) + if (input > 2) return -EINVAL; v4l2_dbg(1, debug, sd, "input switched to %s\n", inputs[input]); diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index 47137deafcf..e9f72ca458f 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c @@ -2764,7 +2764,7 @@ static int zoran_enum_input(struct file *file, void *__fh, struct zoran_fh *fh = __fh; struct zoran *zr = fh->zr; - if (inp->index < 0 || inp->index >= zr->card.inputs) + if (inp->index >= zr->card.inputs) return -EINVAL; else { int id = inp->index; -- cgit v1.2.3-70-g09d2 From 065b6f7a34ec5628e0b1243bfc4214cb5f53d429 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 29 Oct 2009 07:42:30 -0300 Subject: V4L/DVB (13242): gspca_mr97310a: Add minimum clock divider control When "shooting" certain (quite rare) scenes, the mr97310's compression is not effective and it cannot keep up with the data stream. This patch adds a minimum clock divider control, which influences the maximum framerate, libv4l will automatically increase this minimum clockdiv control when it detect the cam cannot keep up. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/mr97310a.c | 57 ++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index f282f800070..63050f0ebfa 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c @@ -55,6 +55,10 @@ #define MR97310A_GAIN_MAX 31 #define MR97310A_GAIN_DEFAULT 25 +#define MR97310A_MIN_CLOCKDIV_MIN 3 +#define MR97310A_MIN_CLOCKDIV_MAX 8 +#define MR97310A_MIN_CLOCKDIV_DEFAULT 3 + MODULE_AUTHOR("Kyle Guinn ," "Theodore Kilgore "); MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver"); @@ -76,6 +80,7 @@ struct sd { int brightness; u16 exposure; u8 gain; + u8 min_clockdiv; }; struct sensor_w_data { @@ -92,6 +97,8 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val); static void setbrightness(struct gspca_dev *gspca_dev); static void setexposure(struct gspca_dev *gspca_dev); static void setgain(struct gspca_dev *gspca_dev); @@ -160,6 +167,21 @@ static struct ctrl sd_ctrls[] = { .set = sd_setgain, .get = sd_getgain, }, + { +#define MIN_CLOCKDIV_IDX 4 + { + .id = V4L2_CID_PRIVATE_BASE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Minimum Clock Divider", + .minimum = MR97310A_MIN_CLOCKDIV_MIN, + .maximum = MR97310A_MIN_CLOCKDIV_MAX, + .step = 1, + .default_value = MR97310A_MIN_CLOCKDIV_DEFAULT, + .flags = 0, + }, + .set = sd_setmin_clockdiv, + .get = sd_getmin_clockdiv, + }, }; static const struct v4l2_pix_format vga_mode[] = { @@ -544,14 +566,16 @@ static int sd_config(struct gspca_dev *gspca_dev, gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) | (1 << ARGUS_QC_BRIGHTNESS_IDX); else - gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX); + gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) | + (1 << MIN_CLOCKDIV_IDX); } else { /* All controls need to be disabled if VGA sensor_type is 0 */ if (sd->sensor_type == 0) gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) | (1 << ARGUS_QC_BRIGHTNESS_IDX) | (1 << EXPOSURE_IDX) | - (1 << GAIN_IDX); + (1 << GAIN_IDX) | + (1 << MIN_CLOCKDIV_IDX); else if (sd->do_lcd_stop) /* Argus QuickClix has different brightness limits */ gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX); @@ -562,6 +586,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->brightness = MR97310A_BRIGHTNESS_DEFAULT; sd->exposure = MR97310A_EXPOSURE_DEFAULT; sd->gain = MR97310A_GAIN_DEFAULT; + sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT; return 0; } @@ -837,6 +862,7 @@ static void setexposure(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int exposure; + u8 buf[2]; if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX)) return; @@ -858,8 +884,8 @@ static void setexposure(struct gspca_dev *gspca_dev) u8 clockdiv = (60 * sd->exposure + 7999) / 8000; /* Limit framerate to not exceed usb bandwidth */ - if (clockdiv < 3 && gspca_dev->width >= 320) - clockdiv = 3; + if (clockdiv < sd->min_clockdiv && gspca_dev->width >= 320) + clockdiv = sd->min_clockdiv; else if (clockdiv < 2) clockdiv = 2; @@ -875,9 +901,10 @@ static void setexposure(struct gspca_dev *gspca_dev) /* exposure register value is reversed! */ exposure = 511 - exposure; + buf[0] = exposure & 0xff; + buf[1] = exposure >> 8; + sensor_write_reg(gspca_dev, 0x0e, 0, buf, 2); sensor_write1(gspca_dev, 0x02, clockdiv); - sensor_write1(gspca_dev, 0x0e, exposure & 0xff); - sensor_write1(gspca_dev, 0x0f, exposure >> 8); } } @@ -949,6 +976,24 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->min_clockdiv = val; + if (gspca_dev->streaming) + setexposure(gspca_dev); + return 0; +} + +static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->min_clockdiv; + return 0; +} + /* Include pac common sof detection functions */ #include "pac_common.h" -- cgit v1.2.3-70-g09d2 From 8ac246cb8fc880cb8f438ab7ded454207cc8170d Mon Sep 17 00:00:00 2001 From: Aurelien Jacobs Date: Thu, 29 Oct 2009 07:45:24 -0300 Subject: V4L/DVB (13243): gscpa_mr97310a: Add Trust Spyc@m 100 USB ID gscpa_mr97310a: Add Trust Spyc@m 100 USB ID Signed-off-by: Aurelien Jacobs Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/gspca.txt | 1 + drivers/media/video/gspca/mr97310a.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt index 90e85a8a881..2bd1d165042 100644 --- a/Documentation/video4linux/gspca.txt +++ b/Documentation/video4linux/gspca.txt @@ -203,6 +203,7 @@ spca500 084d:0003 D-Link DSC-350 spca500 08ca:0103 Aiptek PocketDV sunplus 08ca:0104 Aiptek PocketDVII 1.3 sunplus 08ca:0106 Aiptek Pocket DV3100+ +mr97310a 08ca:0110 Trust Spyc@m 100 mr97310a 08ca:0111 Aiptek PenCam VGA+ sunplus 08ca:2008 Aiptek Mini PenCam 2 M sunplus 08ca:2010 Aiptek PocketCam 3M diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index 63050f0ebfa..d316b56e396 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c @@ -457,7 +457,7 @@ static int sd_config(struct gspca_dev *gspca_dev, if (err_code < 0) return err_code; - if (id->idProduct == 0x010e) { + if (id->idProduct == 0x0110 || id->idProduct == 0x010e) { sd->cam_type = CAM_TYPE_CIF; cam->nmodes--; err_code = cam_get_response16(gspca_dev, 0x06, 1); @@ -1039,6 +1039,7 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x08ca, 0x0110)}, /* Trust Spyc@m 100 */ {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */ {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */ {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */ -- cgit v1.2.3-70-g09d2 From 1160a3818ec387ddadfd173b3bceea654a474b74 Mon Sep 17 00:00:00 2001 From: Theodore Kilgore Date: Fri, 30 Oct 2009 04:29:56 -0300 Subject: V4L/DVB (13244): gspca_mr97310a: Fix / update some comments gspca_mr97310a: Fix / update some comments Signed-off-by: Theodore Kilgore Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/mr97310a.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index d316b56e396..b66169256dc 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c @@ -18,7 +18,9 @@ * Several previously unsupported cameras are owned and have been tested by * Hans de Goede and * Thomas Kaiser and - * Theodore Kilgore + * Theodore Kilgore and + * Edmond Rodriguez and + * Aurelien Jacobs * * The MR97311A support in gspca/mars.c has been helpful in understanding some * of the registers in these cameras. @@ -105,8 +107,8 @@ static void setgain(struct gspca_dev *gspca_dev); /* V4L2 controls supported by the driver */ static struct ctrl sd_ctrls[] = { -/* Seprate brightness control description for Argus QuickClix as it has - different limits from to other mr97310a camera's */ +/* Separate brightness control description for Argus QuickClix as it has + different limits from the other mr97310a cameras */ { #define NORM_BRIGHTNESS_IDX 0 { @@ -428,7 +430,7 @@ static int isoc_enable(struct gspca_dev *gspca_dev) return mr_write(gspca_dev, 2); } -/* this function is called at probe time */ +/* This function is called at probe time */ static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id) { @@ -441,11 +443,11 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->nmodes = ARRAY_SIZE(vga_mode); sd->do_lcd_stop = 0; - /* Now, logical layout of the driver must fall sacrifice to the - * realities of the hardware supported. We have to sort out several - * cameras which share the USB ID but are in fact different inside. - * We need to start the initialization process for the cameras in - * order to classify them. Some of the supported cameras require the + /* Several of the supported CIF cameras share the same USB ID but + * require different initializations and different control settings. + * The same is true of the VGA cameras. Therefore, we are forced + * to start the initialization process in order to determine which + * camera is present. Some of the supported cameras require the * memory pointer to be set to 0 as the very first item of business * or else they will not stream. So we do that immediately. */ @@ -464,9 +466,10 @@ static int sd_config(struct gspca_dev *gspca_dev, if (err_code < 0) return err_code; /* - * The various CIF cameras share the same USB ID but use - * different init routines and different controls. We need to - * detect which one is connected! + * All but one of the known CIF cameras share the same USB ID, + * but two different init routines are in use, and the control + * settings are different, too. We need to detect which camera + * of the two known varieties is connected! * * A list of known CIF cameras follows. They all report either * 0002 for type 0 or 0003 for type 1. @@ -481,6 +484,7 @@ static int sd_config(struct gspca_dev *gspca_dev, * Vivitar Mini 1 T. Kilgore * Elta-Media 8212dc 1 T. Kaiser * Philips dig. keych. 1 T. Kilgore + * Trust Spyc@m 100 1 A. Jacobs */ switch (gspca_dev->usb_buf[1]) { case 2: -- cgit v1.2.3-70-g09d2 From 64f4d9a367b4fe329ba78e3171d1abb1338a951f Mon Sep 17 00:00:00 2001 From: Theodore Kilgore Date: Fri, 30 Oct 2009 04:43:39 -0300 Subject: V4L/DVB (13245): gspca_mr97310a: Change blue gain setting for Sakar Digital VGA camera gspca_mr97310a: Change blue gain setting for Sakar Digital VGA camera Signed-off-by: Theodore Kilgore Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/mr97310a.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index b66169256dc..a97061a9e44 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c @@ -78,6 +78,7 @@ struct sd { u8 cam_type; /* 0 is CIF and 1 is VGA */ u8 sensor_type; /* We use 0 and 1 here, too. */ u8 do_lcd_stop; + u8 adj_colors; int brightness; u16 exposure; @@ -525,6 +526,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->sensor_type = 1; sd->do_lcd_stop = 0; + sd->adj_colors = 0; if ((gspca_dev->usb_buf[0] != 0x03) && (gspca_dev->usb_buf[0] != 0x04)) { PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x", @@ -532,6 +534,10 @@ static int sd_config(struct gspca_dev *gspca_dev, PDEBUG(D_ERR, "Defaults assumed, may not work"); PDEBUG(D_ERR, "Please report this"); } + /* Sakar Digital color needs to be adjusted. */ + if ((gspca_dev->usb_buf[0] == 0x03) && + (gspca_dev->usb_buf[1] == 0x50)) + sd->adj_colors = 1; if (gspca_dev->usb_buf[0] == 0x04) { sd->do_lcd_stop = 1; switch (gspca_dev->usb_buf[1]) { @@ -759,9 +765,20 @@ static int start_vga_cam(struct gspca_dev *gspca_dev) err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data, ARRAY_SIZE(vga_sensor0_init_data)); } else { /* sd->sensor_type = 1 */ - const struct sensor_w_data vga_sensor1_init_data[] = { + const struct sensor_w_data color_adj[] = { + {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, + /* adjusted blue, green, red gain correct + too much blue from the Sakar Digital */ + 0x05, 0x01, 0x05}, 8} + }; + + const struct sensor_w_data color_no_adj[] = { {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, - 0x07, 0x00, 0x01}, 8}, + /* default blue, green, red gain settings */ + 0x07, 0x00, 0x01}, 8} + }; + + const struct sensor_w_data vga_sensor1_init_data[] = { {0x11, 0x04, {0x01}, 1}, /*{0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, */ {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, @@ -771,6 +788,17 @@ static int start_vga_cam(struct gspca_dev *gspca_dev) {0x11, 0x04, {0x01}, 1}, {0, 0, {0}, 0} }; + + if (sd->adj_colors) + err_code = sensor_write_regs(gspca_dev, color_adj, + ARRAY_SIZE(color_adj)); + else + err_code = sensor_write_regs(gspca_dev, color_no_adj, + ARRAY_SIZE(color_no_adj)); + + if (err_code < 0) + return err_code; + err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data, ARRAY_SIZE(vga_sensor1_init_data)); } -- cgit v1.2.3-70-g09d2 From d6eef4947858ebebaf05d79bce7b8be0d4c036ba Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 24 Oct 2009 16:42:16 -0300 Subject: V4L/DVB (13247): tuner-core: dont force every tuner to set frequency at startup Setting the tuner frequency at the same time as initializing the other devices on the i2c bus can cause problems on devices that require firmware download or extensive calibration proceduces during initialization. This change allows us to prevent the tune at startup for devices that perform better without it. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tuner-core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index a9c9703113c..5b3eaa16afd 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -320,6 +320,7 @@ static void set_type(struct i2c_client *c, unsigned int type, struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; unsigned char buffer[4]; + int tune_now = 1; if (type == UNSET || type == TUNER_ABSENT) { tuner_dbg ("tuner 0x%02x: Tuner type absent\n",c->addr); @@ -404,6 +405,7 @@ static void set_type(struct i2c_client *c, unsigned int type, }; if (!dvb_attach(xc2028_attach, &t->fe, &cfg)) goto attach_failed; + tune_now = 0; break; } case TUNER_TDA9887: @@ -419,6 +421,7 @@ static void set_type(struct i2c_client *c, unsigned int type, if (!dvb_attach(xc5000_attach, &t->fe, t->i2c->adapter, &xc5000_cfg)) goto attach_failed; + tune_now = 0; break; } case TUNER_NXP_TDA18271: @@ -430,6 +433,7 @@ static void set_type(struct i2c_client *c, unsigned int type, if (!dvb_attach(tda18271_attach, &t->fe, t->i2c->addr, t->i2c->adapter, &cfg)) goto attach_failed; + tune_now = 0; break; } default: @@ -458,12 +462,13 @@ static void set_type(struct i2c_client *c, unsigned int type, if (t->mode_mask == T_UNINITIALIZED) t->mode_mask = new_mode_mask; - /* xc2028/3028 and xc5000 requires a firmware to be set-up later + /* Some tuners require more initialization setup before use, + such as firmware download or device calibration. trying to set a frequency here will just fail FIXME: better to move set_freq to the tuner code. This is needed on analog tuners for PLL to properly work */ - if (t->type != TUNER_XC2028 && t->type != TUNER_XC5000) + if (tune_now) set_freq(c, (V4L2_TUNER_RADIO == t->mode) ? t->radio_freq : t->tv_freq); -- cgit v1.2.3-70-g09d2 From 56e93ed9cff06e258cff8815fde31cd61d0a6d5a Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 20 Oct 2009 04:34:11 -0300 Subject: V4L/DVB (13249): gspca - pac7311: Webcam 093a:2628 added. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/gspca.txt | 1 + drivers/media/video/gspca/pac7311.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt index 2bd1d165042..a87a8ceb624 100644 --- a/Documentation/video4linux/gspca.txt +++ b/Documentation/video4linux/gspca.txt @@ -241,6 +241,7 @@ pac7311 093a:2621 PAC731x pac7311 093a:2622 Genius Eye 312 pac7311 093a:2624 PAC7302 pac7311 093a:2626 Labtec 2200 +pac7311 093a:2628 Genius iLook 300 pac7311 093a:2629 Genious iSlim 300 pac7311 093a:262a Webcam 300k pac7311 093a:262c Philips SPC 230 NC diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index f954900c451..a3fbd307bb7 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -1092,6 +1092,7 @@ static __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x093a, 0x2622), .driver_info = SENSOR_PAC7302}, {USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302}, {USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302}, + {USB_DEVICE(0x093a, 0x2628), .driver_info = SENSOR_PAC7302}, {USB_DEVICE(0x093a, 0x2629), .driver_info = SENSOR_PAC7302}, {USB_DEVICE(0x093a, 0x262a), .driver_info = SENSOR_PAC7302}, {USB_DEVICE(0x093a, 0x262c), .driver_info = SENSOR_PAC7302}, -- cgit v1.2.3-70-g09d2 From 721ecbcbea61df76490b3ba03c7dded7134e628c Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 20 Oct 2009 05:25:16 -0300 Subject: V4L/DVB (13250): gspca - zc3xx: Add some delays and warn on i2c errors. This patch fixes the kernel bug 14195 (random errors - bad images - with the webcam 10fd:8050 - sensor tas5130cxx). Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/zc3xx.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 0aa87d2958a..e57f9dd68a4 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -6036,8 +6036,10 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev, reg_w_i(gspca_dev->dev, reg, 0x0092); reg_w_i(gspca_dev->dev, 0x02, 0x0090); /* <- read command */ - msleep(25); + msleep(20); retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ + if (retbyte != 0x00) + err("i2c_r status error %02x", retbyte); retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */ PDEBUG(D_USBI, "i2c r [%02x] -> %04x (%02x)", @@ -6056,8 +6058,10 @@ static __u8 i2c_write(struct gspca_dev *gspca_dev, reg_w_i(gspca_dev->dev, valL, 0x93); reg_w_i(gspca_dev->dev, valH, 0x94); reg_w_i(gspca_dev->dev, 0x01, 0x90); /* <- write command */ - msleep(15); + msleep(1); retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ + if (retbyte != 0x00) + err("i2c_w status error %02x", retbyte); PDEBUG(D_USBO, "i2c w [%02x] = %02x%02x (%02x)", reg, valH, valL, retbyte); return retbyte; @@ -6092,7 +6096,7 @@ static void usb_exchange(struct gspca_dev *gspca_dev, break; } action++; -/* msleep(1); */ + msleep(1); } } @@ -6555,7 +6559,7 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev) start_2wr_probe(dev, 0x0e); /* PAS202BCB */ reg_w(dev, 0x08, 0x008d); i2c_write(gspca_dev, 0x03, 0xaa, 0x00); - msleep(500); + msleep(50); retword = i2c_read(gspca_dev, 0x03); if (retword != 0) return 0x0e; /* PAS202BCB */ @@ -6699,7 +6703,6 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) reg_w(dev, 0x01, 0x0001); reg_w(dev, 0xee, 0x008b); reg_w(dev, 0x03, 0x0012); -/* msleep(150); */ reg_w(dev, 0x01, 0x0012); reg_w(dev, 0x05, 0x0012); retword = i2c_read(gspca_dev, 0x00) << 8; /* ID 0 */ @@ -7100,7 +7103,7 @@ static int sd_start(struct gspca_dev *gspca_dev) setautogain(gspca_dev); switch (sd->sensor) { case SENSOR_PO2030: - msleep(500); + msleep(50); reg_r(gspca_dev, 0x0008); reg_r(gspca_dev, 0x0007); /*fall thru*/ -- cgit v1.2.3-70-g09d2 From 7fb101ae2525ea5e8bad43a3fc228e87c5f047c6 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 22 Oct 2009 06:27:14 -0300 Subject: V4L/DVB (13251): gspca - sonixj: Cleanup code and change some comments. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 82604f328dc..22209945698 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -455,7 +455,7 @@ static const u8 hv7131r_sensor_init[][8] = { {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10}, @@ -1014,7 +1014,7 @@ static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg) reg_r(gspca_dev, 0x0a, 5); } -static int hv7131r_probe(struct gspca_dev *gspca_dev) +static void hv7131r_probe(struct gspca_dev *gspca_dev) { i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */ msleep(10); @@ -1026,14 +1026,12 @@ static int hv7131r_probe(struct gspca_dev *gspca_dev) && gspca_dev->usb_buf[2] == 0x01 && gspca_dev->usb_buf[3] == 0x00 && gspca_dev->usb_buf[4] == 0x00) { - PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R"); - return 0; + PDEBUG(D_PROBE, "Sensor sn9c102P HV7131R found"); + return; } - PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x", + PDEBUG(D_PROBE, "Sensor 0x%02x 0x%02x 0x%02x - sn9c102P not found", gspca_dev->usb_buf[0], gspca_dev->usb_buf[1], gspca_dev->usb_buf[2]); - PDEBUG(D_PROBE, "Sensor sn9c102P Not found"); - return -ENODEV; } static void mi0360_probe(struct gspca_dev *gspca_dev) @@ -1086,7 +1084,7 @@ static void mi0360_probe(struct gspca_dev *gspca_dev) } } -static int configure_gpio(struct gspca_dev *gspca_dev, +static void configure_gpio(struct gspca_dev *gspca_dev, const u8 *sn9c1xx) { struct sd *sd = (struct sd *) gspca_dev; @@ -1160,13 +1158,10 @@ static int configure_gpio(struct gspca_dev *gspca_dev, reg_w1(gspca_dev, 0x01, 0x43); reg_w1(gspca_dev, 0x17, 0x61); reg_w1(gspca_dev, 0x01, 0x42); - if (sd->sensor == SENSOR_HV7131R) { - if (hv7131r_probe(gspca_dev) < 0) - return -ENODEV; - } + if (sd->sensor == SENSOR_HV7131R) + hv7131r_probe(gspca_dev); break; } - return 0; } static void hv7131R_InitSensor(struct gspca_dev *gspca_dev) @@ -2319,31 +2314,32 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)}, {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)}, {USB_DEVICE(0x06f8, 0x3008), BSI(SN9C105, OV7660, 0x21)}, +/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x21)}, */ {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)}, -/* bw600.inf: - {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */ -/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */ -/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */ +/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x21)}, */ +/* {USB_DEVICE(0x0c45, 0x607b), BSI(SN9C102P, OV7660, 0x21)}, */ {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)}, -/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */ +/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x21)}, */ {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)}, -/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6802, 0x??)}, */ +/* {USB_DEVICE(0x0c45, 0x60c2), BSI(SN9C105, P1030xC, 0x??)}, */ +/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6802, 0x21)}, */ /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */ {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)}, /* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */ -/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */ +/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x21)}, */ {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)}, #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)}, {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)}, #endif {USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/ -/* {USB_DEVICE(0x0c45, 0x6102), BSI(SN9C120, PO2030N, ??)}, */ +/* {USB_DEVICE(0x0c45, 0x6102), BSI(SN9C120, P1030xC, ??)}, */ /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6802, 0x21)}, */ {USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/ {USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/ {USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/ {USB_DEVICE(0x0c45, 0x610e), BSI(SN9C120, OV7630, 0x21)}, /*sn9c128*/ +/* {USB_DEVICE(0x0c45, 0x610f), BSI(SN9C120, S5K53BEB, 0x??)}, */ /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/ -- cgit v1.2.3-70-g09d2 From 928213aad76e0036290901d244d614c01cac7278 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Thu, 29 Oct 2009 22:24:34 -0300 Subject: V4L/DVB (13253): cx23885: CodingStyle fix Add whitespace around binary operators in cx23888-ir.c Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23888-ir.c | 37 ++++++++++++++++---------------- 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c index e8d949ae06b..3ccc8afeccf 100644 --- a/drivers/media/video/cx23885/cx23888-ir.c +++ b/drivers/media/video/cx23885/cx23888-ir.c @@ -108,7 +108,7 @@ MODULE_PARM_DESC(ir_888_debug, "enable debug messages [CX23888 IR controller]"); #define CX23888_IR_LEARN_REG 0x170044 #define CX23888_VIDCLK_FREQ 108000000 /* 108 MHz, BT.656 */ -#define CX23888_IR_REFCLK_FREQ (CX23888_VIDCLK_FREQ/2) +#define CX23888_IR_REFCLK_FREQ (CX23888_VIDCLK_FREQ / 2) #define CX23888_IR_RX_KFIFO_SIZE (512 * sizeof(u32)) #define CX23888_IR_TX_KFIFO_SIZE (512 * sizeof(u32)) @@ -171,7 +171,7 @@ static inline int cx23888_ir_and_or4(struct cx23885_dev *dev, u32 addr, */ static inline u16 count_to_clock_divider(unsigned int d) { - if (d > RXCLK_RCD+1) + if (d > RXCLK_RCD + 1) d = RXCLK_RCD; else if (d < 2) d = 1; @@ -183,14 +183,14 @@ static inline u16 count_to_clock_divider(unsigned int d) static inline u16 ns_to_clock_divider(unsigned int ns) { return count_to_clock_divider( - DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ/1000000 * ns, 1000)); + DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ / 1000000 * ns, 1000)); } static inline unsigned int clock_divider_to_ns(unsigned int divider) { /* Period of the Rx or Tx clock in ns */ return DIV_ROUND_CLOSEST((divider + 1) * 1000, - CX23888_IR_REFCLK_FREQ/1000000); + CX23888_IR_REFCLK_FREQ / 1000000); } static inline u16 carrier_freq_to_clock_divider(unsigned int freq) @@ -237,19 +237,20 @@ static inline u16 count_to_lpf_count(unsigned int d) static inline u16 ns_to_lpf_count(unsigned int ns) { return count_to_lpf_count( - DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ/1000000 * ns, 1000)); + DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ / 1000000 * ns, 1000)); } static inline unsigned int lpf_count_to_ns(unsigned int count) { /* Duration of the Low Pass Filter rejection window in ns */ - return DIV_ROUND_CLOSEST(count * 1000, CX23888_IR_REFCLK_FREQ/1000000); + return DIV_ROUND_CLOSEST(count * 1000, + CX23888_IR_REFCLK_FREQ / 1000000); } static inline unsigned int lpf_count_to_us(unsigned int count) { /* Duration of the Low Pass Filter rejection window in us */ - return DIV_ROUND_CLOSEST(count, CX23888_IR_REFCLK_FREQ/1000000); + return DIV_ROUND_CLOSEST(count, CX23888_IR_REFCLK_FREQ / 1000000); } /* @@ -263,7 +264,7 @@ static u32 clock_divider_to_resolution(u16 divider) * not readable, hence the << 2. This function returns ns. */ return DIV_ROUND_CLOSEST((1 << 2) * ((u32) divider + 1) * 1000, - CX23888_IR_REFCLK_FREQ/1000000); + CX23888_IR_REFCLK_FREQ / 1000000); } static u64 pulse_width_count_to_ns(u16 count, u16 divider) @@ -276,8 +277,8 @@ static u64 pulse_width_count_to_ns(u16 count, u16 divider) * the (count << 2) | 0x3 */ n = (((u64) count << 2) | 0x3) * (divider + 1) * 1000; /* millicycles */ - rem = do_div(n, CX23888_IR_REFCLK_FREQ/1000000); /* / MHz => ns */ - if (rem >= CX23888_IR_REFCLK_FREQ/1000000/2) + rem = do_div(n, CX23888_IR_REFCLK_FREQ / 1000000); /* / MHz => ns */ + if (rem >= CX23888_IR_REFCLK_FREQ / 1000000 / 2) n++; return n; } @@ -291,9 +292,9 @@ static unsigned int pulse_width_count_to_us(u16 count, u16 divider) * The 2 lsb's of the pulse width timer count are not readable, hence * the (count << 2) | 0x3 */ - n = (((u64) count << 2) | 0x3) * (divider + 1); /* cycles */ - rem = do_div(n, CX23888_IR_REFCLK_FREQ/1000000); /* / MHz => us */ - if (rem >= CX23888_IR_REFCLK_FREQ/1000000/2) + n = (((u64) count << 2) | 0x3) * (divider + 1); /* cycles */ + rem = do_div(n, CX23888_IR_REFCLK_FREQ / 1000000); /* / MHz => us */ + if (rem >= CX23888_IR_REFCLK_FREQ / 1000000 / 2) n++; return (unsigned int) n; } @@ -310,9 +311,9 @@ static u64 ns_to_pulse_clocks(u32 ns) { u64 clocks; u32 rem; - clocks = CX23888_IR_REFCLK_FREQ/1000000 * (u64) ns; /* millicycles */ + clocks = CX23888_IR_REFCLK_FREQ / 1000000 * (u64) ns; /* millicycles */ rem = do_div(clocks, 1000); /* /1000 = cycles */ - if (rem >= 1000/2) + if (rem >= 1000 / 2) clocks++; return clocks; } @@ -324,7 +325,7 @@ static u16 pulse_clocks_to_clock_divider(u64 count) rem = do_div(count, (FIFO_RXTX << 2) | 0x3); /* net result needs to be rounded down and decremented by 1 */ - if (count > RXCLK_RCD+1) + if (count > RXCLK_RCD + 1) count = RXCLK_RCD; else if (count < 2) count = 1; @@ -484,7 +485,7 @@ static unsigned int cduty_tx_s_duty_cycle(struct cx23885_dev *dev, if (n > 15) n = 15; cx23888_ir_write4(dev, CX23888_IR_CDUTY_REG, n); - return DIV_ROUND_CLOSEST((n+1) * 100, 16); + return DIV_ROUND_CLOSEST((n + 1) * 100, 16); } /* @@ -630,7 +631,7 @@ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status, cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl); *handled = true; } - if (kfifo_len(state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE/2) + if (kfifo_len(state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2) events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ; if (events) -- cgit v1.2.3-70-g09d2 From 53c8ec5e0e93f1ab600f91203ede43b83b3361ba Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 31 Oct 2009 13:46:08 -0300 Subject: V4L/DVB (13259): saa7134: fix badly merged DTV1000S patch As pointed out by Hermann Pitton, it turns out that the DTV1000S card's analog entry made it into the #if 0 flyvideo tweaks in saa7134-cards.c and is not valid there. This patch fixes the problem. Cc: hermann pitton Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-cards.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 9481379edec..e737ddf9414 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -5304,6 +5304,22 @@ struct saa7134_board saa7134_boards[] = { .amux = LINE2, } }, }, + [SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S] = { + .name = "Leadtek Winfast DTV1000S", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_TDA8290, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .mpeg = SAA7134_MPEG_DVB, + .inputs = { { + .name = name_comp1, + .vmux = 3, + }, { + .name = name_svideo, + .vmux = 8, + } }, + }, }; -- cgit v1.2.3-70-g09d2 From 0700adec9efec3136fa44d90f064c9227817f37b Mon Sep 17 00:00:00 2001 From: Michael Obst Date: Sat, 31 Oct 2009 14:05:42 -0300 Subject: V4L/DVB (13260): saa7134: add support for Leadtek Winfast DTV-1000S remote control Signed-off-by: Michael Obst Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-keymaps.c | 1 + drivers/media/video/saa7134/saa7134-cards.c | 1 + drivers/media/video/saa7134/saa7134-input.c | 6 ++++++ 3 files changed, 8 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c index 32f765e6e5f..e353dffe696 100644 --- a/drivers/media/common/ir-keymaps.c +++ b/drivers/media/common/ir-keymaps.c @@ -1705,6 +1705,7 @@ static struct ir_scancode ir_codes_winfast[] = { { 0x37, KEY_RADIO }, /* FM */ { 0x38, KEY_DVD }, + { 0x1a, KEY_MODE}, /* change to MCE mode on Y04G0051 */ { 0x3e, KEY_F21 }, /* MCE +VOL, on Y04G0033 */ { 0x3a, KEY_F22 }, /* MCE -VOL, on Y04G0033 */ { 0x3b, KEY_F23 }, /* MCE +CH, on Y04G0033 */ diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index e737ddf9414..7e40d6d99dd 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -6801,6 +6801,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG: case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS: case SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM: + case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S: dev->has_remote = SAA7134_REMOTE_GPIO; break; case SAA7134_BOARD_FLYDVBS_LR300: diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 8f9203e7d3b..83206cfb7b8 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -616,6 +616,12 @@ int saa7134_input_init1(struct saa7134_dev *dev) mask_keycode = 0x003f00; mask_keydown = 0x040000; break; + case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S: + ir_codes = &ir_codes_winfast_table; + mask_keycode = 0x5f00; + mask_keyup = 0x020000; + polling = 50; // ms + break; } if (NULL == ir_codes) { printk("%s: Oops: IR config error [card=%d]\n", -- cgit v1.2.3-70-g09d2 From 972aacc2989506d9c67f8b710021ff98041363d5 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 1 Nov 2009 02:52:01 -0300 Subject: V4L/DVB (13262): tda18271: fix regression preventing std map override from taking effect In the changeset entitled, "tda18271: add support for the set_config method", the initialization order was changed such that the standard map overrides were being applied before loading the default standard map, based on the stepping of the silicon. This changeset restores the proper order by processing the standard map overrides both within the tda18271_set_config() and the tda18271_attach() functions, after we read the id register of the tuner. Thanks to Michael Obst for his testing, helping me to identify the regression. Signed-off-by: Michael Krufky Signed-off-by: Michael Obst Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda18271-fe.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index 07d6e1c159c..b2e15456d5f 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c @@ -1198,10 +1198,6 @@ static int tda18271_setup_configuration(struct dvb_frontend *fe, priv->output_opt = (cfg) ? cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON; - /* override default std map with values in config struct */ - if ((cfg) && (cfg->std_map)) - tda18271_update_std_map(fe, cfg->std_map); - return 0; } @@ -1224,6 +1220,10 @@ static int tda18271_set_config(struct dvb_frontend *fe, void *priv_cfg) if (tda18271_need_cal_on_startup(cfg)) tda18271_init(fe); + /* override default std map with values in config struct */ + if ((cfg) && (cfg->std_map)) + tda18271_update_std_map(fe, cfg->std_map); + return 0; } @@ -1307,6 +1307,10 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, break; } + /* override default std map with values in config struct */ + if ((cfg) && (cfg->std_map)) + tda18271_update_std_map(fe, cfg->std_map); + mutex_unlock(&tda18271_list_mutex); memcpy(&fe->ops.tuner_ops, &tda18271_tuner_ops, -- cgit v1.2.3-70-g09d2 From b31210d737f383c14a02b20ab68e1a5770818f2d Mon Sep 17 00:00:00 2001 From: Theodore Kilgore Date: Sun, 1 Nov 2009 13:02:59 -0300 Subject: V4L/DVB (13265): gspca_mr97310a: Partly back off red gain change for Sakar Digital VGA camera gspca_mr97310a: Partly back off red gain change for Sakar Digital VGA camera Signed-off-by: Theodore Kilgore Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/mr97310a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index a97061a9e44..57ea1c77221 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c @@ -769,7 +769,7 @@ static int start_vga_cam(struct gspca_dev *gspca_dev) {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, /* adjusted blue, green, red gain correct too much blue from the Sakar Digital */ - 0x05, 0x01, 0x05}, 8} + 0x05, 0x01, 0x04}, 8} }; const struct sensor_w_data color_no_adj[] = { -- cgit v1.2.3-70-g09d2 From b4b84deede5edb1e5492533a04f24ea16d1fae0a Mon Sep 17 00:00:00 2001 From: Theodore Kilgore Date: Sun, 1 Nov 2009 13:07:08 -0300 Subject: V4L/DVB (13266): gspca_mr97310a: Fix / update some comments gspca_mr97310a: Fix / update some comments Signed-off-by: Theodore Kilgore Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/mr97310a.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index 57ea1c77221..d2bfdec1c90 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c @@ -814,9 +814,8 @@ static int sd_start(struct gspca_dev *gspca_dev) /* Some of the VGA cameras require the memory pointer * to be set to 0 again. We have been forced to start the - * stream somewhere else to detect the hardware, and closed it, - * and now since we are restarting the stream we need to do a - * completely fresh and clean start. */ + * stream in sd_config() to detect the hardware, and closed it. + * Thus, we need here to do a completely fresh and clean start. */ err_code = zero_the_pointer(gspca_dev); if (err_code < 0) return err_code; @@ -875,7 +874,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) value_reg += 4; } - /* Note register 7 is also seen as 0x8x or 0xCx in dumps */ + /* Note register 7 is also seen as 0x8x or 0xCx in some dumps */ if (sd->brightness > 0) { sensor_write1(gspca_dev, sign_reg, 0x00); val = sd->brightness; @@ -900,7 +899,7 @@ static void setexposure(struct gspca_dev *gspca_dev) return; if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) { - /* This cam does not like exposure settings > 300, + /* This cam does not like exposure settings < 300, so scale 0 - 4095 to 300 - 4095 */ exposure = (sd->exposure * 9267) / 10000 + 300; sensor_write1(gspca_dev, 3, exposure >> 4); @@ -908,7 +907,7 @@ static void setexposure(struct gspca_dev *gspca_dev) } else { /* We have both a clock divider and an exposure register. We first calculate the clock divider, as that determines - the maximum exposure and then we calculayte the exposure + the maximum exposure and then we calculate the exposure register setting (which goes from 0 - 511). Note our 0 - 4095 exposure is mapped to 0 - 511 -- cgit v1.2.3-70-g09d2 From 542821d8d064d04e898a3c473b742b4e512de09d Mon Sep 17 00:00:00 2001 From: Theodore Kilgore Date: Sun, 1 Nov 2009 13:09:15 -0300 Subject: V4L/DVB (13267): gspca_mr97310a: Change brightness for VGA type 1 cameras downward gspca_mr97310a: Change brightness for VGA type 1 cameras downward Signed-off-by: Theodore Kilgore Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/mr97310a.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index d2bfdec1c90..442bf1ec5ed 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c @@ -780,8 +780,9 @@ static int start_vga_cam(struct gspca_dev *gspca_dev) const struct sensor_w_data vga_sensor1_init_data[] = { {0x11, 0x04, {0x01}, 1}, - /*{0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, */ - {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, + {0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, + /* These settings may be better for some cameras */ + /* {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, */ 0x00, 0x0a}, 7}, {0x11, 0x04, {0x01}, 1}, {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6}, -- cgit v1.2.3-70-g09d2 From 117e1348f8b0cd91834873bb21faff827798bd8b Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 1 Nov 2009 11:16:10 -0300 Subject: V4L/DVB (13269): saa7134: codingstyle: use /* style comments */ instead of // Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 83206cfb7b8..f658f251399 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -620,7 +620,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) ir_codes = &ir_codes_winfast_table; mask_keycode = 0x5f00; mask_keyup = 0x020000; - polling = 50; // ms + polling = 50; /* ms */ break; } if (NULL == ir_codes) { -- cgit v1.2.3-70-g09d2 From 26b9d6c0b0e91c84b4713da5abd16baef3963d33 Mon Sep 17 00:00:00 2001 From: Abylay Ospan Date: Sun, 1 Nov 2009 18:46:53 -0300 Subject: V4L/DVB (13271): TS speed check. Logging transport stream speed in Kbits per second [mchehab@redhat.com: add asm/div64.h and allocate vars only if dvb_demux_speedcheck specified] Signed-off-by: Abylay Ospan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-core/dvb_demux.c | 39 ++++++++++++++++++++++++++++++++++ drivers/media/dvb/dvb-core/dvb_demux.h | 5 +++++ 2 files changed, 44 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c index 91c537bca8a..b78cfb7d189 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/drivers/media/dvb/dvb-core/dvb_demux.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "dvb_demux.h" @@ -44,6 +45,11 @@ module_param(dvb_demux_tscheck, int, 0644); MODULE_PARM_DESC(dvb_demux_tscheck, "enable transport stream continuity and TEI check"); +static int dvb_demux_speedcheck; +module_param(dvb_demux_speedcheck, int, 0644); +MODULE_PARM_DESC(dvb_demux_speedcheck, + "enable transport stream speed check"); + #define dprintk_tscheck(x...) do { \ if (dvb_demux_tscheck && printk_ratelimit()) \ printk(x); \ @@ -387,6 +393,39 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) u16 pid = ts_pid(buf); int dvr_done = 0; + if (dvb_demux_speedcheck) { + struct timespec cur_time, delta_time; + u64 speed_bytes, speed_timedelta; + + demux->speed_pkts_cnt++; + + /* show speed every SPEED_PKTS_INTERVAL packets */ + if (!(demux->speed_pkts_cnt % SPEED_PKTS_INTERVAL)) { + cur_time = current_kernel_time(); + + if (demux->speed_last_time.tv_sec != 0 && + demux->speed_last_time.tv_nsec != 0) { + delta_time = timespec_sub(cur_time, + demux->speed_last_time); + speed_bytes = (u64)demux->speed_pkts_cnt + * 188 * 8; + /* convert to 1024 basis */ + speed_bytes = 1000 * div64_u64(speed_bytes, + 1024); + speed_timedelta = + (u64)timespec_to_ns(&delta_time); + speed_timedelta = div64_u64(speed_timedelta, + 1000000); /* nsec -> usec */ + printk(KERN_INFO "TS speed %llu Kbits/sec \n", + div64_u64(speed_bytes, + speed_timedelta)); + }; + + demux->speed_last_time = cur_time; + demux->speed_pkts_cnt = 0; + }; + }; + if (dvb_demux_tscheck) { if (!demux->cnt_storage) demux->cnt_storage = vmalloc(MAX_PID + 1); diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h index 2fe05d03240..a7d876fd02d 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.h +++ b/drivers/media/dvb/dvb-core/dvb_demux.h @@ -44,6 +44,8 @@ #define MAX_PID 0x1fff +#define SPEED_PKTS_INTERVAL 50000 + struct dvb_demux_filter { struct dmx_section_filter filter; u8 maskandmode[DMX_MAX_FILTER_SIZE]; @@ -131,6 +133,9 @@ struct dvb_demux { spinlock_t lock; uint8_t *cnt_storage; /* for TS continuity check */ + + struct timespec speed_last_time; /* for TS speed check */ + uint32_t speed_pkts_cnt; /* for TS speed check */ }; int dvb_dmx_init(struct dvb_demux *dvbdemux); -- cgit v1.2.3-70-g09d2 From 648732fcefa73932ae8caa8bcfd262863904dd66 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 4 Nov 2009 12:11:43 -0200 Subject: V4L/DVB (13271a): Fix a badly solved merge conflict Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 1ec1a4cb047..c8034d5c817 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -2135,10 +2135,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { - .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, - .pid_filter_count = 32, - .pid_filter = stk70x0p_pid_filter, - .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, .pid_filter = stk70x0p_pid_filter, @@ -2210,6 +2206,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, .frontend_attach = stk7070p_frontend_attach, .tuner_attach = dib7070p_tuner_attach, -- cgit v1.2.3-70-g09d2 From 0b66cf90371dcd28c6eb98904adb694ae98eb20f Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Wed, 4 Nov 2009 14:16:25 -0300 Subject: V4L/DVB (13285): vpfe_capture: keep index within bound in vpfe_cropcap() If vpfe_dev->std_index equals ARRAY_SIZE(vpfe_standards), that is one too large. Signed-off-by: Roel Kluin Acked-by: Muralidharan Karicheri Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/davinci/vpfe_capture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c index 402ce43ef38..6b31e59f47f 100644 --- a/drivers/media/video/davinci/vpfe_capture.c +++ b/drivers/media/video/davinci/vpfe_capture.c @@ -1577,7 +1577,7 @@ static int vpfe_cropcap(struct file *file, void *priv, v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_cropcap\n"); - if (vpfe_dev->std_index > ARRAY_SIZE(vpfe_standards)) + if (vpfe_dev->std_index >= ARRAY_SIZE(vpfe_standards)) return -EINVAL; memset(crop, 0, sizeof(struct v4l2_cropcap)); -- cgit v1.2.3-70-g09d2 From 9710e7a77a0a0564a393250d86b8cb3d560bb69f Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Wed, 4 Nov 2009 15:28:33 -0300 Subject: V4L/DVB (13288): adding __init/__exit macros to various drivers Trivial patch which adds the __init/__exit macros to the module_init/ module_exit functions of the following drivers in media video: drivers/media/video/ivtv/ivtv-driver.c drivers/media/video/cx18/cx18-driver.c drivers/media/video/davinci/dm355_ccdc.c drivers/media/video/davinci/dm644x_ccdc.c drivers/media/video/saa7164/saa7164-core.c drivers/media/video/saa7134/saa7134-core.c drivers/media/video/cx23885/cx23885-core.c Cc: Hermann Pitton Acked-by: Steven Toth Signed-off-by: Peter Huewe Acked-by: Andy Walls Acked-by: Laurent Pinchart Acked-by: Muralidharan Karicheri Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-driver.c | 4 ++-- drivers/media/video/cx23885/cx23885-core.c | 4 ++-- drivers/media/video/davinci/dm355_ccdc.c | 4 ++-- drivers/media/video/davinci/dm644x_ccdc.c | 4 ++-- drivers/media/video/ivtv/ivtv-driver.c | 4 ++-- drivers/media/video/saa7134/saa7134-core.c | 4 ++-- drivers/media/video/saa7164/saa7164-core.c | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 6dd51e27582..e12082b8a08 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -1200,7 +1200,7 @@ static struct pci_driver cx18_pci_driver = { .remove = cx18_remove, }; -static int module_start(void) +static int __init module_start(void) { printk(KERN_INFO "cx18: Start initialization, version %s\n", CX18_VERSION); @@ -1224,7 +1224,7 @@ static int module_start(void) return 0; } -static void module_cleanup(void) +static void __exit module_cleanup(void) { pci_unregister_driver(&cx18_pci_driver); } diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index e34a4ec4a2c..e8eb4ec0c30 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -2026,7 +2026,7 @@ static struct pci_driver cx23885_pci_driver = { .resume = NULL, }; -static int cx23885_init(void) +static int __init cx23885_init(void) { printk(KERN_INFO "cx23885 driver version %d.%d.%d loaded\n", (CX23885_VERSION_CODE >> 16) & 0xff, @@ -2039,7 +2039,7 @@ static int cx23885_init(void) return pci_register_driver(&cx23885_pci_driver); } -static void cx23885_fini(void) +static void __exit cx23885_fini(void) { pci_unregister_driver(&cx23885_pci_driver); } diff --git a/drivers/media/video/davinci/dm355_ccdc.c b/drivers/media/video/davinci/dm355_ccdc.c index 4629cabe3f2..56fbefe036a 100644 --- a/drivers/media/video/davinci/dm355_ccdc.c +++ b/drivers/media/video/davinci/dm355_ccdc.c @@ -959,7 +959,7 @@ static struct ccdc_hw_device ccdc_hw_dev = { }, }; -static int dm355_ccdc_init(void) +static int __init dm355_ccdc_init(void) { printk(KERN_NOTICE "dm355_ccdc_init\n"); if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0) @@ -969,7 +969,7 @@ static int dm355_ccdc_init(void) return 0; } -static void dm355_ccdc_exit(void) +static void __exit dm355_ccdc_exit(void) { vpfe_unregister_ccdc_device(&ccdc_hw_dev); } diff --git a/drivers/media/video/davinci/dm644x_ccdc.c b/drivers/media/video/davinci/dm644x_ccdc.c index 2f19a919f47..d5fa193f32d 100644 --- a/drivers/media/video/davinci/dm644x_ccdc.c +++ b/drivers/media/video/davinci/dm644x_ccdc.c @@ -859,7 +859,7 @@ static struct ccdc_hw_device ccdc_hw_dev = { }, }; -static int dm644x_ccdc_init(void) +static int __init dm644x_ccdc_init(void) { printk(KERN_NOTICE "dm644x_ccdc_init\n"); if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0) @@ -869,7 +869,7 @@ static int dm644x_ccdc_init(void) return 0; } -static void dm644x_ccdc_exit(void) +static void __exit dm644x_ccdc_exit(void) { vpfe_unregister_ccdc_device(&ccdc_hw_dev); } diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 463ec3457d7..7cdbc1a8f21 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -1361,7 +1361,7 @@ static struct pci_driver ivtv_pci_driver = { .remove = ivtv_remove, }; -static int module_start(void) +static int __init module_start(void) { printk(KERN_INFO "ivtv: Start initialization, version %s\n", IVTV_VERSION); @@ -1385,7 +1385,7 @@ static int module_start(void) return 0; } -static void module_cleanup(void) +static void __exit module_cleanup(void) { pci_unregister_driver(&ivtv_pci_driver); } diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 9a5df930885..0ba7f5af0fc 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -1319,7 +1319,7 @@ static struct pci_driver saa7134_pci_driver = { #endif }; -static int saa7134_init(void) +static int __init saa7134_init(void) { INIT_LIST_HEAD(&saa7134_devlist); printk(KERN_INFO "saa7130/34: v4l2 driver version %d.%d.%d loaded\n", @@ -1333,7 +1333,7 @@ static int saa7134_init(void) return pci_register_driver(&saa7134_pci_driver); } -static void saa7134_fini(void) +static void __exit saa7134_fini(void) { pci_unregister_driver(&saa7134_pci_driver); } diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c index 709affc3104..e6aa0fbd1e9 100644 --- a/drivers/media/video/saa7164/saa7164-core.c +++ b/drivers/media/video/saa7164/saa7164-core.c @@ -724,13 +724,13 @@ static struct pci_driver saa7164_pci_driver = { .resume = NULL, }; -static int saa7164_init(void) +static int __init saa7164_init(void) { printk(KERN_INFO "saa7164 driver loaded\n"); return pci_register_driver(&saa7164_pci_driver); } -static void saa7164_fini(void) +static void __exit saa7164_fini(void) { pci_unregister_driver(&saa7164_pci_driver); } -- cgit v1.2.3-70-g09d2 From 0bc23083cfa0e4bee3a89254c0af7dc6a16513bb Mon Sep 17 00:00:00 2001 From: Filipe Rosset Date: Wed, 4 Nov 2009 15:31:25 -0300 Subject: V4L/DVB (13289): em28xx-audio: Convert printks to em28xx_err Convert printks to em28xx_err. Signed-off-by: Filipe Rosset Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-audio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index ac947aecb9c..bd783387b37 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c @@ -293,7 +293,7 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) dprintk("opening device and trying to acquire exclusive lock\n"); if (!dev) { - printk(KERN_ERR "BUG: em28xx can't find device struct." + em28xx_err("BUG: em28xx can't find device struct." " Can't proceed with open\n"); return -ENODEV; } @@ -325,7 +325,7 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) return 0; err: - printk(KERN_ERR "Error while configuring em28xx mixer\n"); + em28xx_err("Error while configuring em28xx mixer\n"); return ret; } -- cgit v1.2.3-70-g09d2 From 480be1851aebcb0b9c5b0fb9acefe5da97cc702a Mon Sep 17 00:00:00 2001 From: Filipe Rosset Date: Wed, 4 Nov 2009 15:32:37 -0300 Subject: V4L/DVB (13290): em28xx-dvb: Convert printks to em28xx_err and em28xx_info Convert printks to em28xx_err and em28xx_info Signed-off-by: Filipe Rosset Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-dvb.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index 19f5156f653..cc0505eb900 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c @@ -313,22 +313,20 @@ static int attach_xc3028(u8 addr, struct em28xx *dev) cfg.i2c_addr = addr; if (!dev->dvb->frontend) { - printk(KERN_ERR "%s/2: dvb frontend not attached. " - "Can't attach xc3028\n", - dev->name); + em28xx_errdev("/2: dvb frontend not attached. " + "Can't attach xc3028\n"); return -EINVAL; } fe = dvb_attach(xc2028_attach, dev->dvb->frontend, &cfg); if (!fe) { - printk(KERN_ERR "%s/2: xc3028 attach failed\n", - dev->name); + em28xx_errdev("/2: xc3028 attach failed\n"); dvb_frontend_detach(dev->dvb->frontend); dev->dvb->frontend = NULL; return -EINVAL; } - printk(KERN_INFO "%s/2: xc3028 attached\n", dev->name); + em28xx_info("%s/2: xc3028 attached\n", dev->name); return 0; } @@ -463,7 +461,7 @@ static int dvb_init(struct em28xx *dev) dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); if (dvb == NULL) { - printk(KERN_INFO "em28xx_dvb: memory allocation failed\n"); + em28xx_info("em28xx_dvb: memory allocation failed\n"); return -ENOMEM; } dev->dvb = dvb; @@ -570,15 +568,12 @@ static int dvb_init(struct em28xx *dev) } break; default: - printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" - " isn't supported yet\n", - dev->name); + em28xx_errdev("/2: The frontend of your DVB/ATSC card" + " isn't supported yet\n"); break; } if (NULL == dvb->frontend) { - printk(KERN_ERR - "%s/2: frontend initialization failed\n", - dev->name); + em28xx_errdev("/2: frontend initialization failed\n"); result = -EINVAL; goto out_free; } @@ -592,7 +587,7 @@ static int dvb_init(struct em28xx *dev) goto out_free; em28xx_set_mode(dev, EM28XX_SUSPEND); - printk(KERN_INFO "Successfully loaded em28xx-dvb\n"); + em28xx_info("Successfully loaded em28xx-dvb\n"); return 0; out_free: -- cgit v1.2.3-70-g09d2 From 6f901a991991fd3c9ac51bc7234a6706ef17ddfe Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 4 Nov 2009 15:35:09 -0300 Subject: V4L/DVB (13292): tvp514x: recognize the error case in tvp514x_read_reg() i2c_smbus_read_byte_data() returns a negative value on error. It is very likely to be != -1 (-EPERM). Signed-off-by: Sebastian Andrzej Siewior Acked-by: Vaibhav Hiremath Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tvp514x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c index 244372627df..26b4e718cd6 100644 --- a/drivers/media/video/tvp514x.c +++ b/drivers/media/video/tvp514x.c @@ -272,7 +272,7 @@ static int tvp514x_read_reg(struct v4l2_subdev *sd, u8 reg) read_again: err = i2c_smbus_read_byte_data(client, reg); - if (err == -1) { + if (err < 0) { if (retry <= I2C_RETRY_COUNT) { v4l2_warn(sd, "Read: retry ... %d\n", retry); retry++; -- cgit v1.2.3-70-g09d2 From ad12f07bf21e8d98e6042c8ed795d2d041e26934 Mon Sep 17 00:00:00 2001 From: Akihiro Tsukada Date: Wed, 4 Nov 2009 15:39:31 -0300 Subject: V4L/DVB (13293): dvb-usb-friio: return the correct DTV_DELIVERY_SYSTEM This patch makes the driver return the correct DTV_DELIVERY_SYSTEM. The driver previously returned SYS_UNDEFINED for DTV_DELIVERY_SYSTEM property, as it lacked any driver specific S2API support. Signed-off-by: Akihiro Tsukada Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/friio-fe.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/dvb/dvb-usb/friio-fe.c index c4dfe25cf60..8b489d11eb3 100644 --- a/drivers/media/dvb/dvb-usb/friio-fe.c +++ b/drivers/media/dvb/dvb-usb/friio-fe.c @@ -286,6 +286,27 @@ static int jdvbt90502_get_tune_settings(struct dvb_frontend *fe, return 0; } +/* filter out un-supported properties to notify users */ +static int jdvbt90502_set_property(struct dvb_frontend *fe, + struct dtv_property *tvp) +{ + int r = 0; + + switch (tvp->cmd) { + case DTV_DELIVERY_SYSTEM: + if (tvp->u.data != SYS_ISDBT) + r = -EINVAL; + break; + case DTV_CLEAR: + case DTV_TUNE: + case DTV_FREQUENCY: + break; + default: + r = -EINVAL; + } + return r; +} + static int jdvbt90502_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) { @@ -314,6 +335,9 @@ static int jdvbt90502_set_frontend(struct dvb_frontend *fe, deb_fe("%s: Freq:%d\n", __func__, p->frequency); + /* for recovery from DTV_CLEAN */ + fe->dtv_property_cache.delivery_system = SYS_ISDBT; + ret = jdvbt90502_pll_set_freq(state, p->frequency); if (ret) { deb_fe("%s:ret == %d\n", __func__, ret); @@ -394,6 +418,7 @@ static int jdvbt90502_init(struct dvb_frontend *fe) if (ret != 1) goto error; } + fe->dtv_property_cache.delivery_system = SYS_ISDBT; msleep(100); return 0; @@ -471,6 +496,8 @@ static struct dvb_frontend_ops jdvbt90502_ops = { .sleep = jdvbt90502_sleep, .write = _jdvbt90502_write, + .set_property = jdvbt90502_set_property, + .set_frontend = jdvbt90502_set_frontend, .get_frontend = jdvbt90502_get_frontend, .get_tune_settings = jdvbt90502_get_tune_settings, -- cgit v1.2.3-70-g09d2 From 9ebef973b4a3b9af5c71ef5c266efac8be3e17e0 Mon Sep 17 00:00:00 2001 From: Akihiro Tsukada Date: Wed, 4 Nov 2009 15:40:36 -0300 Subject: V4L/DVB (13294): dvb-usb-friio: cleaning up unnecessary functions This patch removes some fe->ops.X() functions which do nothing more useful than the default. Signed-off-by: Akihiro Tsukada Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/friio-fe.c | 38 ------------------------------------ 1 file changed, 38 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/dvb/dvb-usb/friio-fe.c index 8b489d11eb3..9cbbe42ca44 100644 --- a/drivers/media/dvb/dvb-usb/friio-fe.c +++ b/drivers/media/dvb/dvb-usb/friio-fe.c @@ -232,12 +232,6 @@ static int jdvbt90502_read_status(struct dvb_frontend *fe, fe_status_t *state) return 0; } -static int jdvbt90502_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - *ber = 0; - return 0; -} - static int jdvbt90502_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { @@ -264,27 +258,6 @@ static int jdvbt90502_read_signal_strength(struct dvb_frontend *fe, return 0; } -static int jdvbt90502_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - *snr = 0x0101; - return 0; -} - -static int jdvbt90502_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - *ucblocks = 0; - return 0; -} - -static int jdvbt90502_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *fs) -{ - fs->min_delay_ms = 500; - fs->step_size = 0; - fs->max_drift = 0; - - return 0; -} /* filter out un-supported properties to notify users */ static int jdvbt90502_set_property(struct dvb_frontend *fe, @@ -347,12 +320,6 @@ static int jdvbt90502_set_frontend(struct dvb_frontend *fe, return 0; } -static int jdvbt90502_sleep(struct dvb_frontend *fe) -{ - deb_fe("%s called.\n", __func__); - return 0; -} - /** * (reg, val) commad list to initialize this module. @@ -493,18 +460,13 @@ static struct dvb_frontend_ops jdvbt90502_ops = { .release = jdvbt90502_release, .init = jdvbt90502_init, - .sleep = jdvbt90502_sleep, .write = _jdvbt90502_write, .set_property = jdvbt90502_set_property, .set_frontend = jdvbt90502_set_frontend, .get_frontend = jdvbt90502_get_frontend, - .get_tune_settings = jdvbt90502_get_tune_settings, .read_status = jdvbt90502_read_status, - .read_ber = jdvbt90502_read_ber, .read_signal_strength = jdvbt90502_read_signal_strength, - .read_snr = jdvbt90502_read_snr, - .read_ucblocks = jdvbt90502_read_ucblocks, }; -- cgit v1.2.3-70-g09d2 From 7dee9d1c057a24f5b1cd97b0bf37d05766906222 Mon Sep 17 00:00:00 2001 From: Éric Piel Date: Wed, 4 Nov 2009 15:46:11 -0300 Subject: V4L/DVB (13295): sms1xxx: load smsdvb also for the hauppauge tiger cards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit load smsdvb also for the hauppauge tiger cards [dougsland@redhat.com: fixed rejects due changes in sms-cards.c] Signed-off-by: Éric Piel Acked-by: Michael Krufky Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/sms-cards.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index 0420e2885e7..e21638969cd 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c @@ -294,6 +294,8 @@ int sms_board_load_modules(int id) case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A: case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B: case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: request_module("smsdvb"); break; default: -- cgit v1.2.3-70-g09d2 From c86c82b74f800486ede57fdd5a4fa77d86368861 Mon Sep 17 00:00:00 2001 From: Sergio C Fortier Date: Wed, 4 Nov 2009 15:55:09 -0300 Subject: V4L/DVB (13297): dib0700_devices: EvolutePC TvWay+ USB ISDB-Tb remote control support Patch for EvolutePC TvWay+ USB ISDB-Tb remote control support. [dougsland@redhat.com: fixed malformed patch] Cc: Patrick Boettcher Signed-off-by: Sergio C Fortier Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index c8034d5c817..684146f98eb 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -917,6 +917,18 @@ static struct dvb_usb_rc_key dib0700_rc_keys[] = { { 0x8618, KEY_RECORD }, { 0x861a, KEY_STOP }, + + /* Key codes for the EvolutePC TVWay+ remote (proto NEC) */ + { 0x7a00, KEY_MENU }, + { 0x7a01, KEY_RECORD }, + { 0x7a02, KEY_PLAY }, + { 0x7a03, KEY_STOP }, + { 0x7a10, KEY_CHANNELUP }, + { 0x7a11, KEY_CHANNELDOWN }, + { 0x7a12, KEY_VOLUMEUP }, + { 0x7a13, KEY_VOLUMEDOWN }, + { 0x7a40, KEY_POWER }, + { 0x7a41, KEY_MUTE }, }; /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */ -- cgit v1.2.3-70-g09d2 From a6b69e409a41144c24dcbecdc174a5c847631de2 Mon Sep 17 00:00:00 2001 From: Marton Nemeth Date: Mon, 2 Nov 2009 08:05:51 -0300 Subject: V4L/DVB (13298): gspca - pac207/pac7311/mr97310a: Simplify pac_find_sof. Remove struct sd dependency from pac_find_sof() function implementation. This step prepares separation of pac7302 and pac7311 specific parts of struct sd. Signed-off-by: Marton Nemeth Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/mr97310a.c | 3 ++- drivers/media/video/gspca/pac207.c | 2 +- drivers/media/video/gspca/pac7311.c | 2 +- drivers/media/video/gspca/pac_common.h | 27 +++++++++++++-------------- 4 files changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index 442bf1ec5ed..ffb5e6d62c0 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c @@ -1034,9 +1034,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, __u8 *data, /* isoc packet */ int len) /* iso packet length */ { + struct sd *sd = (struct sd *) gspca_dev; unsigned char *sof; - sof = pac_find_sof(gspca_dev, data, len); + sof = pac_find_sof(&sd->sof_read, data, len); if (sof) { int n; diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index 96659433d24..57e13e2d550 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c @@ -344,7 +344,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct sd *sd = (struct sd *) gspca_dev; unsigned char *sof; - sof = pac_find_sof(gspca_dev, data, len); + sof = pac_find_sof(&sd->sof_read, data, len); if (sof) { int n; diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index a3fbd307bb7..329f867612d 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -838,7 +838,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct sd *sd = (struct sd *) gspca_dev; unsigned char *sof; - sof = pac_find_sof(gspca_dev, data, len); + sof = pac_find_sof(&sd->sof_read, data, len); if (sof) { unsigned char tmpbuf[4]; int n, lum_offset, footer_length; diff --git a/drivers/media/video/gspca/pac_common.h b/drivers/media/video/gspca/pac_common.h index d3006539fb8..20f67d9b8c0 100644 --- a/drivers/media/video/gspca/pac_common.h +++ b/drivers/media/video/gspca/pac_common.h @@ -72,42 +72,41 @@ static const unsigned char pac_sof_marker[5] = +----------+ */ -static unsigned char *pac_find_sof(struct gspca_dev *gspca_dev, +static unsigned char *pac_find_sof(u8 *sof_read, unsigned char *m, int len) { - struct sd *sd = (struct sd *) gspca_dev; int i; /* Search for the SOF marker (fixed part) in the header */ for (i = 0; i < len; i++) { - switch (sd->sof_read) { + switch (*sof_read) { case 0: if (m[i] == 0xff) - sd->sof_read = 1; + *sof_read = 1; break; case 1: if (m[i] == 0xff) - sd->sof_read = 2; + *sof_read = 2; else - sd->sof_read = 0; + *sof_read = 0; break; case 2: switch (m[i]) { case 0x00: - sd->sof_read = 3; + *sof_read = 3; break; case 0xff: /* stay in this state */ break; default: - sd->sof_read = 0; + *sof_read = 0; } break; case 3: if (m[i] == 0xff) - sd->sof_read = 4; + *sof_read = 4; else - sd->sof_read = 0; + *sof_read = 0; break; case 4: switch (m[i]) { @@ -117,18 +116,18 @@ static unsigned char *pac_find_sof(struct gspca_dev *gspca_dev, "SOF found, bytes to analyze: %u." " Frame starts at byte #%u", len, i + 1); - sd->sof_read = 0; + *sof_read = 0; return m + i + 1; break; case 0xff: - sd->sof_read = 2; + *sof_read = 2; break; default: - sd->sof_read = 0; + *sof_read = 0; } break; default: - sd->sof_read = 0; + *sof_read = 0; } } -- cgit v1.2.3-70-g09d2 From cc409c0efb40a4c99cf023ec12ba7d67c67f666b Mon Sep 17 00:00:00 2001 From: Marton Nemeth Date: Mon, 2 Nov 2009 08:09:34 -0300 Subject: V4L/DVB (13299): gspca - pac7311: Extract pac_start_frame. Creating the start of the frame is done in the same way for pac7302 and for pac7311. Extract this common part to the pac_start_frame() function. Signed-off-by: Marton Nemeth Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac7311.c | 42 +++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 16 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 329f867612d..8d3e4eb53d7 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -802,7 +802,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) } /* JPEG header, part 1 */ -static const unsigned char pac7311_jpeg_header1[] = { +static const unsigned char pac_jpeg_header1[] = { 0xff, 0xd8, /* SOI: Start of Image */ 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */ @@ -813,7 +813,7 @@ static const unsigned char pac7311_jpeg_header1[] = { }; /* JPEG header, continued */ -static const unsigned char pac7311_jpeg_header2[] = { +static const unsigned char pac_jpeg_header2[] = { 0x03, /* Number of image components: 3 */ 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */ 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */ @@ -829,6 +829,26 @@ static const unsigned char pac7311_jpeg_header2[] = { 0x00 /* Successive approximation: 0 */ }; +static void pac_start_frame(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, + __u16 lines, __u16 samples_per_line) +{ + unsigned char tmpbuf[4]; + + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + pac_jpeg_header1, sizeof(pac_jpeg_header1)); + + tmpbuf[0] = lines >> 8; + tmpbuf[1] = lines & 0xff; + tmpbuf[2] = samples_per_line >> 8; + tmpbuf[3] = samples_per_line & 0xff; + + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + tmpbuf, sizeof(tmpbuf)); + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + pac_jpeg_header2, sizeof(pac_jpeg_header2)); +} + /* this function is run at interrupt level */ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ @@ -840,7 +860,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, sof = pac_find_sof(&sd->sof_read, data, len); if (sof) { - unsigned char tmpbuf[4]; int n, lum_offset, footer_length; if (sd->sensor == SENSOR_PAC7302) { @@ -882,23 +901,14 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, atomic_set(&sd->avg_lum, -1); /* Start the new frame with the jpeg header */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - pac7311_jpeg_header1, sizeof(pac7311_jpeg_header1)); if (sd->sensor == SENSOR_PAC7302) { /* The PAC7302 has the image rotated 90 degrees */ - tmpbuf[0] = gspca_dev->width >> 8; - tmpbuf[1] = gspca_dev->width & 0xff; - tmpbuf[2] = gspca_dev->height >> 8; - tmpbuf[3] = gspca_dev->height & 0xff; + pac_start_frame(gspca_dev, frame, + gspca_dev->width, gspca_dev->height); } else { - tmpbuf[0] = gspca_dev->height >> 8; - tmpbuf[1] = gspca_dev->height & 0xff; - tmpbuf[2] = gspca_dev->width >> 8; - tmpbuf[3] = gspca_dev->width & 0xff; + pac_start_frame(gspca_dev, frame, + gspca_dev->height, gspca_dev->width); } - gspca_frame_add(gspca_dev, INTER_PACKET, frame, tmpbuf, 4); - gspca_frame_add(gspca_dev, INTER_PACKET, frame, - pac7311_jpeg_header2, sizeof(pac7311_jpeg_header2)); } gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); } -- cgit v1.2.3-70-g09d2 From 1408b8472910e894b290205b4baed5b14b8f45af Mon Sep 17 00:00:00 2001 From: Marton Nemeth Date: Mon, 2 Nov 2009 08:13:21 -0300 Subject: V4L/DVB (13300): gspca - pac7302/pac7311: Separate the two subdrivers. All PAC7311 specific functions remain in pac7311.c. All PAC7302 specific functions are moved to pac7302.c. The USB device table is also divided into two parts. This makes it possible to remove the sensor specific decisions from different functions and also remove sensor infromation from the USB device table. The common functions are just copied to both subdrivers. These common functions can be separated later to a common file or helper module. Signed-off-by: Marton Nemeth Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/Kconfig | 9 + drivers/media/video/gspca/Makefile | 2 + drivers/media/video/gspca/pac7302.c | 962 ++++++++++++++++++++++++++++++++++++ drivers/media/video/gspca/pac7311.c | 440 +++-------------- 4 files changed, 1033 insertions(+), 380 deletions(-) create mode 100644 drivers/media/video/gspca/pac7302.c (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig index 568edbbb894..609d65b0b10 100644 --- a/drivers/media/video/gspca/Kconfig +++ b/drivers/media/video/gspca/Kconfig @@ -104,6 +104,15 @@ config USB_GSPCA_PAC207 To compile this driver as a module, choose M here: the module will be called gspca_pac207. +config USB_GSPCA_PAC7302 + tristate "Pixart PAC7302 USB Camera Driver" + depends on VIDEO_V4L2 && USB_GSPCA + help + Say Y here if you want support for cameras based on the PAC7302 chip. + + To compile this driver as a module, choose M here: the + module will be called gspca_pac7302. + config USB_GSPCA_PAC7311 tristate "Pixart PAC7311 USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile index 770b01387e9..ff2c7279d82 100644 --- a/drivers/media/video/gspca/Makefile +++ b/drivers/media/video/gspca/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o +obj-$(CONFIG_USB_GSPCA_PAC7302) += gspca_pac7302.o obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o obj-$(CONFIG_USB_GSPCA_SN9C20X) += gspca_sn9c20x.o obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o @@ -38,6 +39,7 @@ gspca_mr97310a-objs := mr97310a.o gspca_ov519-objs := ov519.o gspca_ov534-objs := ov534.o gspca_pac207-objs := pac207.o +gspca_pac7302-objs := pac7302.o gspca_pac7311-objs := pac7311.o gspca_sn9c20x-objs := sn9c20x.o gspca_sonixb-objs := sonixb.o diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c new file mode 100644 index 00000000000..228b414709f --- /dev/null +++ b/drivers/media/video/gspca/pac7302.c @@ -0,0 +1,962 @@ +/* + * Pixart PAC7302 library + * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li + * + * V4L2 by Jean-Francois Moine + * + * Separated from Pixart PAC7311 library by Márton Németh + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* Some documentation about various registers as determined by trial and error. + When the register addresses differ between the 7202 and the 7311 the 2 + different addresses are written as 7302addr/7311addr, when one of the 2 + addresses is a - sign that register description is not valid for the + matching IC. + + Register page 1: + + Address Description + -/0x08 Unknown compressor related, must always be 8 except when not + in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 ! + -/0x1b Auto white balance related, bit 0 is AWB enable (inverted) + bits 345 seem to toggle per color gains on/off (inverted) + 0x78 Global control, bit 6 controls the LED (inverted) + -/0x80 JPEG compression ratio ? Best not touched + + Register page 3/4: + + Address Description + 0x02 Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on + the 7302, so one of 3, 6, 9, ..., except when between 6 and 12? + -/0x0f Master gain 1-245, low value = high gain + 0x10/- Master gain 0-31 + -/0x10 Another gain 0-15, limited influence (1-2x gain I guess) + 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused + -/0x27 Seems to toggle various gains on / off, Setting bit 7 seems to + completely disable the analog amplification block. Set to 0x68 + for max gain, 0x14 for minimal gain. +*/ + +#define MODULE_NAME "pac7302" + +#include "gspca.h" + +MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); +MODULE_DESCRIPTION("Pixart PAC7302"); +MODULE_LICENSE("GPL"); + +/* specific webcam descriptor for pac7302 */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + unsigned char brightness; + unsigned char contrast; + unsigned char colors; + unsigned char gain; + unsigned char exposure; + unsigned char autogain; + __u8 hflip; + __u8 vflip; + + u8 sof_read; + u8 autogain_ignore_frames; + + atomic_t avg_lum; +}; + +/* V4L2 controls supported by the driver */ +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); +static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls[] = { +/* This control is pac7302 only */ + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, +#define BRIGHTNESS_MAX 0x20 + .maximum = BRIGHTNESS_MAX, + .step = 1, +#define BRIGHTNESS_DEF 0x10 + .default_value = BRIGHTNESS_DEF, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, +/* This control is for both the 7302 and the 7311 */ + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, +#define CONTRAST_MAX 255 + .maximum = CONTRAST_MAX, + .step = 1, +#define CONTRAST_DEF 127 + .default_value = CONTRAST_DEF, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, +/* This control is pac7302 only */ + { + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation", + .minimum = 0, +#define COLOR_MAX 255 + .maximum = COLOR_MAX, + .step = 1, +#define COLOR_DEF 127 + .default_value = COLOR_DEF, + }, + .set = sd_setcolors, + .get = sd_getcolors, + }, +/* All controls below are for both the 7302 and the 7311 */ + { + { + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gain", + .minimum = 0, +#define GAIN_MAX 255 + .maximum = GAIN_MAX, + .step = 1, +#define GAIN_DEF 127 +#define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */ + .default_value = GAIN_DEF, + }, + .set = sd_setgain, + .get = sd_getgain, + }, + { + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure", + .minimum = 0, +#define EXPOSURE_MAX 255 + .maximum = EXPOSURE_MAX, + .step = 1, +#define EXPOSURE_DEF 16 /* 32 ms / 30 fps */ +#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */ + .default_value = EXPOSURE_DEF, + }, + .set = sd_setexposure, + .get = sd_getexposure, + }, + { + { + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Auto Gain", + .minimum = 0, + .maximum = 1, + .step = 1, +#define AUTOGAIN_DEF 1 + .default_value = AUTOGAIN_DEF, + }, + .set = sd_setautogain, + .get = sd_getautogain, + }, + { + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mirror", + .minimum = 0, + .maximum = 1, + .step = 1, +#define HFLIP_DEF 0 + .default_value = HFLIP_DEF, + }, + .set = sd_sethflip, + .get = sd_gethflip, + }, + { + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Vflip", + .minimum = 0, + .maximum = 1, + .step = 1, +#define VFLIP_DEF 0 + .default_value = VFLIP_DEF, + }, + .set = sd_setvflip, + .get = sd_getvflip, + }, +}; + +static const struct v4l2_pix_format vga_mode[] = { + {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 0}, +}; + +#define LOAD_PAGE3 255 +#define LOAD_PAGE4 254 +#define END_OF_SEQUENCE 0 + +/* pac 7302 */ +static const __u8 init_7302[] = { +/* index,value */ + 0xff, 0x01, /* page 1 */ + 0x78, 0x00, /* deactivate */ + 0xff, 0x01, + 0x78, 0x40, /* led off */ +}; +static const __u8 start_7302[] = { +/* index, len, [value]* */ + 0xff, 1, 0x00, /* page 0 */ + 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80, + 0x00, 0x00, 0x00, 0x00, + 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00, + 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7, + 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11, + 0x26, 2, 0xaa, 0xaa, + 0x2e, 1, 0x31, + 0x38, 1, 0x01, + 0x3a, 3, 0x14, 0xff, 0x5a, + 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11, + 0x00, 0x54, 0x11, + 0x55, 1, 0x00, + 0x62, 4, 0x10, 0x1e, 0x1e, 0x18, + 0x6b, 1, 0x00, + 0x6e, 3, 0x08, 0x06, 0x00, + 0x72, 3, 0x00, 0xff, 0x00, + 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c, + 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50, + 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00, + 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9, + 0xd2, 0xeb, + 0xaf, 1, 0x02, + 0xb5, 2, 0x08, 0x08, + 0xb8, 2, 0x08, 0x88, + 0xc4, 4, 0xae, 0x01, 0x04, 0x01, + 0xcc, 1, 0x00, + 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9, + 0xc1, 0xd7, 0xec, + 0xdc, 1, 0x01, + 0xff, 1, 0x01, /* page 1 */ + 0x12, 3, 0x02, 0x00, 0x01, + 0x3e, 2, 0x00, 0x00, + 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2, + 0x7c, 1, 0x00, + 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20, + 0x02, 0x00, + 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04, + 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, + 0x07, 0x00, 0x01, 0x07, 0x04, 0x01, + 0xd8, 1, 0x01, + 0xdb, 2, 0x00, 0x01, + 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00, + 0xe6, 4, 0x00, 0x00, 0x00, 0x01, + 0xeb, 1, 0x00, + 0xff, 1, 0x02, /* page 2 */ + 0x22, 1, 0x00, + 0xff, 1, 0x03, /* page 3 */ + 0, LOAD_PAGE3, /* load the page 3 */ + 0x11, 1, 0x01, + 0xff, 1, 0x02, /* page 2 */ + 0x13, 1, 0x00, + 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96, + 0x27, 2, 0x14, 0x0c, + 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22, + 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44, + 0x6e, 1, 0x08, + 0xff, 1, 0x01, /* page 1 */ + 0x78, 1, 0x00, + 0, END_OF_SEQUENCE /* end of sequence */ +}; + +#define SKIP 0xaa +/* page 3 - the value SKIP says skip the index - see reg_w_page() */ +static const __u8 page3_7302[] = { + 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16, + 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, + 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21, + 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54, + 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00, + 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8, + 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, + 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00, + 0x00 +}; + +static void reg_w_buf(struct gspca_dev *gspca_dev, + __u8 index, + const char *buffer, int len) +{ + memcpy(gspca_dev->usb_buf, buffer, len); + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), + 1, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, /* value */ + index, gspca_dev->usb_buf, len, + 500); +} + + +static void reg_w(struct gspca_dev *gspca_dev, + __u8 index, + __u8 value) +{ + gspca_dev->usb_buf[0] = value; + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), + 0, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, index, gspca_dev->usb_buf, 1, + 500); +} + +static void reg_w_seq(struct gspca_dev *gspca_dev, + const __u8 *seq, int len) +{ + while (--len >= 0) { + reg_w(gspca_dev, seq[0], seq[1]); + seq += 2; + } +} + +/* load the beginning of a page */ +static void reg_w_page(struct gspca_dev *gspca_dev, + const __u8 *page, int len) +{ + int index; + + for (index = 0; index < len; index++) { + if (page[index] == SKIP) /* skip this index */ + continue; + gspca_dev->usb_buf[0] = page[index]; + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), + 0, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, index, gspca_dev->usb_buf, 1, + 500); + } +} + +/* output a variable sequence */ +static void reg_w_var(struct gspca_dev *gspca_dev, + const __u8 *seq, + const __u8 *page3, unsigned int page3_len, + const __u8 *page4, unsigned int page4_len) +{ + int index, len; + + for (;;) { + index = *seq++; + len = *seq++; + switch (len) { + case END_OF_SEQUENCE: + return; + case LOAD_PAGE4: + reg_w_page(gspca_dev, page4, page4_len); + break; + case LOAD_PAGE3: + reg_w_page(gspca_dev, page3, page3_len); + break; + default: + if (len > USB_BUF_SZ) { + PDEBUG(D_ERR|D_STREAM, + "Incorrect variable sequence"); + return; + } + while (len > 0) { + if (len < 8) { + reg_w_buf(gspca_dev, index, seq, len); + seq += len; + break; + } + reg_w_buf(gspca_dev, index, seq, 8); + seq += 8; + index += 8; + len -= 8; + } + } + } + /* not reached */ +} + +/* this function is called at probe time for pac7302 */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam; + + cam = &gspca_dev->cam; + + PDEBUG(D_CONF, "Find Sensor PAC7302"); + cam->cam_mode = vga_mode; /* only 640x480 */ + cam->nmodes = ARRAY_SIZE(vga_mode); + + sd->brightness = BRIGHTNESS_DEF; + sd->contrast = CONTRAST_DEF; + sd->colors = COLOR_DEF; + sd->gain = GAIN_DEF; + sd->exposure = EXPOSURE_DEF; + sd->autogain = AUTOGAIN_DEF; + sd->hflip = HFLIP_DEF; + sd->vflip = VFLIP_DEF; + return 0; +} + +/* This function is used by pac7302 only */ +static void setbrightcont(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int i, v; + static const __u8 max[10] = + {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb, + 0xd4, 0xec}; + static const __u8 delta[10] = + {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17, + 0x11, 0x0b}; + + reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ + for (i = 0; i < 10; i++) { + v = max[i]; + v += (sd->brightness - BRIGHTNESS_MAX) + * 150 / BRIGHTNESS_MAX; /* 200 ? */ + v -= delta[i] * sd->contrast / CONTRAST_MAX; + if (v < 0) + v = 0; + else if (v > 0xff) + v = 0xff; + reg_w(gspca_dev, 0xa2 + i, v); + } + reg_w(gspca_dev, 0xdc, 0x01); +} + +/* This function is used by pac7302 only */ +static void setcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int i, v; + static const int a[9] = + {217, -212, 0, -101, 170, -67, -38, -315, 355}; + static const int b[9] = + {19, 106, 0, 19, 106, 1, 19, 106, 1}; + + reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ + reg_w(gspca_dev, 0x11, 0x01); + reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ + for (i = 0; i < 9; i++) { + v = a[i] * sd->colors / COLOR_MAX + b[i]; + reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07); + reg_w(gspca_dev, 0x0f + 2 * i + 1, v); + } + reg_w(gspca_dev, 0xdc, 0x01); + PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); +} + +static void setgain(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ + reg_w(gspca_dev, 0x10, sd->gain >> 3); + + /* load registers to sensor (Bit 0, auto clear) */ + reg_w(gspca_dev, 0x11, 0x01); +} + +static void setexposure(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 reg; + + /* register 2 of frame 3/4 contains the clock divider configuring the + no fps according to the formula: 60 / reg. sd->exposure is the + desired exposure time in ms. */ + reg = 120 * sd->exposure / 1000; + if (reg < 2) + reg = 2; + else if (reg > 63) + reg = 63; + + /* On the pac7302 reg2 MUST be a multiple of 3, so round it to + the nearest multiple of 3, except when between 6 and 12? */ + if (reg < 6 || reg > 12) + reg = ((reg + 1) / 3) * 3; + reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ + reg_w(gspca_dev, 0x02, reg); + + /* load registers to sensor (Bit 0, auto clear) */ + reg_w(gspca_dev, 0x11, 0x01); +} + +static void sethvflip(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 data; + + reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ + data = (sd->hflip ? 0x08 : 0x00) | (sd->vflip ? 0x04 : 0x00); + reg_w(gspca_dev, 0x21, data); + /* load registers to sensor (Bit 0, auto clear) */ + reg_w(gspca_dev, 0x11, 0x01); +} + +/* this function is called at probe and resume time for pac7302 */ +static int sd_init(struct gspca_dev *gspca_dev) +{ + reg_w_seq(gspca_dev, init_7302, sizeof init_7302); + + return 0; +} + +static int sd_start(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->sof_read = 0; + + reg_w_var(gspca_dev, start_7302, + page3_7302, sizeof(page3_7302), + NULL, 0); + setbrightcont(gspca_dev); + setcolors(gspca_dev); + setgain(gspca_dev); + setexposure(gspca_dev); + sethvflip(gspca_dev); + + /* only resolution 640x480 is supported for pac7302 */ + + sd->sof_read = 0; + sd->autogain_ignore_frames = 0; + atomic_set(&sd->avg_lum, -1); + + /* start stream */ + reg_w(gspca_dev, 0xff, 0x01); + reg_w(gspca_dev, 0x78, 0x01); + + return 0; +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + reg_w(gspca_dev, 0xff, 0x01); + reg_w(gspca_dev, 0x78, 0x00); + reg_w(gspca_dev, 0x78, 0x00); +} + +/* called on streamoff with alt 0 and on disconnect for pac7302 */ +static void sd_stop0(struct gspca_dev *gspca_dev) +{ + if (!gspca_dev->present) + return; + reg_w(gspca_dev, 0xff, 0x01); + reg_w(gspca_dev, 0x78, 0x40); +} + +/* Include pac common sof detection functions */ +#include "pac_common.h" + +static void do_autogain(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int avg_lum = atomic_read(&sd->avg_lum); + int desired_lum, deadzone; + + if (avg_lum == -1) + return; + + desired_lum = 270 + sd->brightness * 4; + /* Hack hack, with the 7202 the first exposure step is + pretty large, so if we're about to make the first + exposure increase make the deadzone large to avoid + oscilating */ + if (desired_lum > avg_lum && sd->gain == GAIN_DEF && + sd->exposure > EXPOSURE_DEF && + sd->exposure < 42) + deadzone = 90; + else + deadzone = 30; + + if (sd->autogain_ignore_frames > 0) + sd->autogain_ignore_frames--; + else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum, + deadzone, GAIN_KNEE, EXPOSURE_KNEE)) + sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; +} + +/* JPEG header, part 1 */ +static const unsigned char pac_jpeg_header1[] = { + 0xff, 0xd8, /* SOI: Start of Image */ + + 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */ + 0x00, 0x11, /* length = 17 bytes (including this length field) */ + 0x08 /* Precision: 8 */ + /* 2 bytes is placed here: number of image lines */ + /* 2 bytes is placed here: samples per line */ +}; + +/* JPEG header, continued */ +static const unsigned char pac_jpeg_header2[] = { + 0x03, /* Number of image components: 3 */ + 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */ + 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */ + 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */ + + 0xff, 0xda, /* SOS: Start Of Scan */ + 0x00, 0x0c, /* length = 12 bytes (including this length field) */ + 0x03, /* number of components: 3 */ + 0x01, 0x00, /* selector 1, table 0x00 */ + 0x02, 0x11, /* selector 2, table 0x11 */ + 0x03, 0x11, /* selector 3, table 0x11 */ + 0x00, 0x3f, /* Spectral selection: 0 .. 63 */ + 0x00 /* Successive approximation: 0 */ +}; + +static void pac_start_frame(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, + __u16 lines, __u16 samples_per_line) +{ + unsigned char tmpbuf[4]; + + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + pac_jpeg_header1, sizeof(pac_jpeg_header1)); + + tmpbuf[0] = lines >> 8; + tmpbuf[1] = lines & 0xff; + tmpbuf[2] = samples_per_line >> 8; + tmpbuf[3] = samples_per_line & 0xff; + + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + tmpbuf, sizeof(tmpbuf)); + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + pac_jpeg_header2, sizeof(pac_jpeg_header2)); +} + +/* this function is run at interrupt level */ +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + __u8 *data, /* isoc packet */ + int len) /* iso packet length */ +{ + struct sd *sd = (struct sd *) gspca_dev; + unsigned char *sof; + + sof = pac_find_sof(&sd->sof_read, data, len); + if (sof) { + int n, lum_offset, footer_length; + + /* 6 bytes after the FF D9 EOF marker a number of lumination + bytes are send corresponding to different parts of the + image, the 14th and 15th byte after the EOF seem to + correspond to the center of the image */ + lum_offset = 61 + sizeof pac_sof_marker; + footer_length = 74; + + /* Finish decoding current frame */ + n = (sof - data) - (footer_length + sizeof pac_sof_marker); + if (n < 0) { + frame->data_end += n; + n = 0; + } + frame = gspca_frame_add(gspca_dev, INTER_PACKET, frame, + data, n); + if (gspca_dev->last_packet_type != DISCARD_PACKET && + frame->data_end[-2] == 0xff && + frame->data_end[-1] == 0xd9) + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + NULL, 0); + + n = sof - data; + len -= n; + data = sof; + + /* Get average lumination */ + if (gspca_dev->last_packet_type == LAST_PACKET && + n >= lum_offset) + atomic_set(&sd->avg_lum, data[-lum_offset] + + data[-lum_offset + 1]); + else + atomic_set(&sd->avg_lum, -1); + + /* Start the new frame with the jpeg header */ + /* The PAC7302 has the image rotated 90 degrees */ + pac_start_frame(gspca_dev, frame, + gspca_dev->width, gspca_dev->height); + } + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); +} + +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + if (gspca_dev->streaming) + setbrightcont(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->brightness; + return 0; +} + +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = val; + if (gspca_dev->streaming) { + setbrightcont(gspca_dev); + } + return 0; +} + +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->contrast; + return 0; +} + +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->colors = val; + if (gspca_dev->streaming) + setcolors(gspca_dev); + return 0; +} + +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->colors; + return 0; +} + +static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->gain = val; + if (gspca_dev->streaming) + setgain(gspca_dev); + return 0; +} + +static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->gain; + return 0; +} + +static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->exposure = val; + if (gspca_dev->streaming) + setexposure(gspca_dev); + return 0; +} + +static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->exposure; + return 0; +} + +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->autogain = val; + /* when switching to autogain set defaults to make sure + we are on a valid point of the autogain gain / + exposure knee graph, and give this change time to + take effect before doing autogain. */ + if (sd->autogain) { + sd->exposure = EXPOSURE_DEF; + sd->gain = GAIN_DEF; + if (gspca_dev->streaming) { + sd->autogain_ignore_frames = + PAC_AUTOGAIN_IGNORE_FRAMES; + setexposure(gspca_dev); + setgain(gspca_dev); + } + } + + return 0; +} + +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->autogain; + return 0; +} + +static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->hflip = val; + if (gspca_dev->streaming) + sethvflip(gspca_dev); + return 0; +} + +static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->hflip; + return 0; +} + +static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->vflip = val; + if (gspca_dev->streaming) + sethvflip(gspca_dev); + return 0; +} + +static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->vflip; + return 0; +} + +/* sub-driver description for pac7302 */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .init = sd_init, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .pkt_scan = sd_pkt_scan, + .dq_callback = do_autogain, +}; + +/* -- module initialisation -- */ +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x06f8, 0x3009)}, + {USB_DEVICE(0x093a, 0x2620)}, + {USB_DEVICE(0x093a, 0x2621)}, + {USB_DEVICE(0x093a, 0x2622)}, + {USB_DEVICE(0x093a, 0x2624)}, + {USB_DEVICE(0x093a, 0x2626)}, + {USB_DEVICE(0x093a, 0x2628)}, + {USB_DEVICE(0x093a, 0x2629)}, + {USB_DEVICE(0x093a, 0x262a)}, + {USB_DEVICE(0x093a, 0x262c)}, + {} +}; +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) + return ret; + PDEBUG(D_PROBE, "registered"); + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 8d3e4eb53d7..a2f788468ec 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -57,23 +57,17 @@ MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); MODULE_DESCRIPTION("Pixart PAC7311"); MODULE_LICENSE("GPL"); -/* specific webcam descriptor */ +/* specific webcam descriptor for pac7311 */ struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - unsigned char brightness; unsigned char contrast; - unsigned char colors; unsigned char gain; unsigned char exposure; unsigned char autogain; __u8 hflip; __u8 vflip; - __u8 sensor; -#define SENSOR_PAC7302 0 -#define SENSOR_PAC7311 1 - u8 sof_read; u8 autogain_ignore_frames; @@ -81,12 +75,8 @@ struct sd { }; /* V4L2 controls supported by the driver */ -static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); -static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); @@ -99,23 +89,6 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { -/* This control is pac7302 only */ -#define BRIGHTNESS_IDX 0 - { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness", - .minimum = 0, -#define BRIGHTNESS_MAX 0x20 - .maximum = BRIGHTNESS_MAX, - .step = 1, -#define BRIGHTNESS_DEF 0x10 - .default_value = BRIGHTNESS_DEF, - }, - .set = sd_setbrightness, - .get = sd_getbrightness, - }, /* This control is for both the 7302 and the 7311 */ { { @@ -132,23 +105,6 @@ static struct ctrl sd_ctrls[] = { .set = sd_setcontrast, .get = sd_getcontrast, }, -/* This control is pac7302 only */ -#define SATURATION_IDX 2 - { - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation", - .minimum = 0, -#define COLOR_MAX 255 - .maximum = COLOR_MAX, - .step = 1, -#define COLOR_DEF 127 - .default_value = COLOR_DEF, - }, - .set = sd_setcolors, - .get = sd_getcolors, - }, /* All controls below are for both the 7302 and the 7311 */ { { @@ -248,103 +204,6 @@ static const struct v4l2_pix_format vga_mode[] = { #define LOAD_PAGE4 254 #define END_OF_SEQUENCE 0 -/* pac 7302 */ -static const __u8 init_7302[] = { -/* index,value */ - 0xff, 0x01, /* page 1 */ - 0x78, 0x00, /* deactivate */ - 0xff, 0x01, - 0x78, 0x40, /* led off */ -}; -static const __u8 start_7302[] = { -/* index, len, [value]* */ - 0xff, 1, 0x00, /* page 0 */ - 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80, - 0x00, 0x00, 0x00, 0x00, - 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00, - 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7, - 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11, - 0x26, 2, 0xaa, 0xaa, - 0x2e, 1, 0x31, - 0x38, 1, 0x01, - 0x3a, 3, 0x14, 0xff, 0x5a, - 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11, - 0x00, 0x54, 0x11, - 0x55, 1, 0x00, - 0x62, 4, 0x10, 0x1e, 0x1e, 0x18, - 0x6b, 1, 0x00, - 0x6e, 3, 0x08, 0x06, 0x00, - 0x72, 3, 0x00, 0xff, 0x00, - 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c, - 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50, - 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00, - 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9, - 0xd2, 0xeb, - 0xaf, 1, 0x02, - 0xb5, 2, 0x08, 0x08, - 0xb8, 2, 0x08, 0x88, - 0xc4, 4, 0xae, 0x01, 0x04, 0x01, - 0xcc, 1, 0x00, - 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9, - 0xc1, 0xd7, 0xec, - 0xdc, 1, 0x01, - 0xff, 1, 0x01, /* page 1 */ - 0x12, 3, 0x02, 0x00, 0x01, - 0x3e, 2, 0x00, 0x00, - 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2, - 0x7c, 1, 0x00, - 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20, - 0x02, 0x00, - 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04, - 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, - 0x07, 0x00, 0x01, 0x07, 0x04, 0x01, - 0xd8, 1, 0x01, - 0xdb, 2, 0x00, 0x01, - 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00, - 0xe6, 4, 0x00, 0x00, 0x00, 0x01, - 0xeb, 1, 0x00, - 0xff, 1, 0x02, /* page 2 */ - 0x22, 1, 0x00, - 0xff, 1, 0x03, /* page 3 */ - 0, LOAD_PAGE3, /* load the page 3 */ - 0x11, 1, 0x01, - 0xff, 1, 0x02, /* page 2 */ - 0x13, 1, 0x00, - 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96, - 0x27, 2, 0x14, 0x0c, - 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22, - 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44, - 0x6e, 1, 0x08, - 0xff, 1, 0x01, /* page 1 */ - 0x78, 1, 0x00, - 0, END_OF_SEQUENCE /* end of sequence */ -}; - -#define SKIP 0xaa -/* page 3 - the value SKIP says skip the index - see reg_w_page() */ -static const __u8 page3_7302[] = { - 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16, - 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, - 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00, - 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21, - 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54, - 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00, - 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8, - 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, - 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00, - 0x00 -}; - /* pac 7311 */ static const __u8 init_7311[] = { 0x78, 0x40, /* Bit_0=start stream, Bit_6=LED */ @@ -388,6 +247,7 @@ static const __u8 start_7311[] = { 0, END_OF_SEQUENCE /* end of sequence */ }; +#define SKIP 0xaa /* page 4 - the value SKIP says skip the index - see reg_w_page() */ static const __u8 page4_7311[] = { SKIP, SKIP, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f, @@ -457,7 +317,9 @@ static void reg_w_page(struct gspca_dev *gspca_dev, /* output a variable sequence */ static void reg_w_var(struct gspca_dev *gspca_dev, - const __u8 *seq) + const __u8 *seq, + const __u8 *page3, unsigned int page3_len, + const __u8 *page4, unsigned int page4_len) { int index, len; @@ -468,10 +330,10 @@ static void reg_w_var(struct gspca_dev *gspca_dev, case END_OF_SEQUENCE: return; case LOAD_PAGE4: - reg_w_page(gspca_dev, page4_7311, sizeof page4_7311); + reg_w_page(gspca_dev, page4, page4_len); break; case LOAD_PAGE3: - reg_w_page(gspca_dev, page3_7302, sizeof page3_7302); + reg_w_page(gspca_dev, page3, page3_len); break; default: if (len > USB_BUF_SZ) { @@ -495,7 +357,7 @@ static void reg_w_var(struct gspca_dev *gspca_dev, /* not reached */ } -/* this function is called at probe time */ +/* this function is called at probe time for pac7311 */ static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id) { @@ -504,22 +366,11 @@ static int sd_config(struct gspca_dev *gspca_dev, cam = &gspca_dev->cam; - sd->sensor = id->driver_info; - if (sd->sensor == SENSOR_PAC7302) { - PDEBUG(D_CONF, "Find Sensor PAC7302"); - cam->cam_mode = &vga_mode[2]; /* only 640x480 */ - cam->nmodes = 1; - } else { - PDEBUG(D_CONF, "Find Sensor PAC7311"); - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); - gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) - | (1 << SATURATION_IDX); - } + PDEBUG(D_CONF, "Find Sensor PAC7311"); + cam->cam_mode = vga_mode; + cam->nmodes = ARRAY_SIZE(vga_mode); - sd->brightness = BRIGHTNESS_DEF; sd->contrast = CONTRAST_DEF; - sd->colors = COLOR_DEF; sd->gain = GAIN_DEF; sd->exposure = EXPOSURE_DEF; sd->autogain = AUTOGAIN_DEF; @@ -528,33 +379,6 @@ static int sd_config(struct gspca_dev *gspca_dev, return 0; } -/* This function is used by pac7302 only */ -static void setbrightcont(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i, v; - static const __u8 max[10] = - {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb, - 0xd4, 0xec}; - static const __u8 delta[10] = - {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17, - 0x11, 0x0b}; - - reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ - for (i = 0; i < 10; i++) { - v = max[i]; - v += (sd->brightness - BRIGHTNESS_MAX) - * 150 / BRIGHTNESS_MAX; /* 200 ? */ - v -= delta[i] * sd->contrast / CONTRAST_MAX; - if (v < 0) - v = 0; - else if (v > 0xff) - v = 0xff; - reg_w(gspca_dev, 0xa2 + i, v); - } - reg_w(gspca_dev, 0xdc, 0x01); -} - /* This function is used by pac7311 only */ static void setcontrast(struct gspca_dev *gspca_dev) { @@ -566,45 +390,19 @@ static void setcontrast(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x11, 0x01); } -/* This function is used by pac7302 only */ -static void setcolors(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i, v; - static const int a[9] = - {217, -212, 0, -101, 170, -67, -38, -315, 355}; - static const int b[9] = - {19, 106, 0, 19, 106, 1, 19, 106, 1}; - - reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ - reg_w(gspca_dev, 0x11, 0x01); - reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ - for (i = 0; i < 9; i++) { - v = a[i] * sd->colors / COLOR_MAX + b[i]; - reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07); - reg_w(gspca_dev, 0x0f + 2 * i + 1, v); - } - reg_w(gspca_dev, 0xdc, 0x01); - PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); -} - static void setgain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + int gain = GAIN_MAX - sd->gain; + + if (gain < 1) + gain = 1; + else if (gain > 245) + gain = 245; + reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ + reg_w(gspca_dev, 0x0e, 0x00); + reg_w(gspca_dev, 0x0f, gain); - if (sd->sensor == SENSOR_PAC7302) { - reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ - reg_w(gspca_dev, 0x10, sd->gain >> 3); - } else { - int gain = GAIN_MAX - sd->gain; - if (gain < 1) - gain = 1; - else if (gain > 245) - gain = 245; - reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ - reg_w(gspca_dev, 0x0e, 0x00); - reg_w(gspca_dev, 0x0f, gain); - } /* load registers to sensor (Bit 0, auto clear) */ reg_w(gspca_dev, 0x11, 0x01); } @@ -623,25 +421,17 @@ static void setexposure(struct gspca_dev *gspca_dev) else if (reg > 63) reg = 63; - if (sd->sensor == SENSOR_PAC7302) { - /* On the pac7302 reg2 MUST be a multiple of 3, so round it to - the nearest multiple of 3, except when between 6 and 12? */ - if (reg < 6 || reg > 12) - reg = ((reg + 1) / 3) * 3; - reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ - reg_w(gspca_dev, 0x02, reg); - } else { - reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ - reg_w(gspca_dev, 0x02, reg); - /* Page 1 register 8 must always be 0x08 except when not in - 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */ - reg_w(gspca_dev, 0xff, 0x01); - if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv && - reg <= 3) - reg_w(gspca_dev, 0x08, 0x09); - else - reg_w(gspca_dev, 0x08, 0x08); - } + reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ + reg_w(gspca_dev, 0x02, reg); + /* Page 1 register 8 must always be 0x08 except when not in + 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */ + reg_w(gspca_dev, 0xff, 0x01); + if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv && + reg <= 3) + reg_w(gspca_dev, 0x08, 0x09); + else + reg_w(gspca_dev, 0x08, 0x08); + /* load registers to sensor (Bit 0, auto clear) */ reg_w(gspca_dev, 0x11, 0x01); } @@ -651,29 +441,17 @@ static void sethvflip(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; __u8 data; - if (sd->sensor == SENSOR_PAC7302) { - reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ - data = (sd->hflip ? 0x08 : 0x00) - | (sd->vflip ? 0x04 : 0x00); - } else { - reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ - data = (sd->hflip ? 0x04 : 0x00) - | (sd->vflip ? 0x08 : 0x00); - } + reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ + data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00); reg_w(gspca_dev, 0x21, data); /* load registers to sensor (Bit 0, auto clear) */ reg_w(gspca_dev, 0x11, 0x01); } -/* this function is called at probe and resume time */ +/* this function is called at probe and resume time for pac7311 */ static int sd_init(struct gspca_dev *gspca_dev) { - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_PAC7302) - reg_w_seq(gspca_dev, init_7302, sizeof init_7302); - else - reg_w_seq(gspca_dev, init_7311, sizeof init_7311); + reg_w_seq(gspca_dev, init_7311, sizeof init_7311); return 0; } @@ -684,14 +462,10 @@ static int sd_start(struct gspca_dev *gspca_dev) sd->sof_read = 0; - if (sd->sensor == SENSOR_PAC7302) { - reg_w_var(gspca_dev, start_7302); - setbrightcont(gspca_dev); - setcolors(gspca_dev); - } else { - reg_w_var(gspca_dev, start_7311); - setcontrast(gspca_dev); - } + reg_w_var(gspca_dev, start_7311, + NULL, 0, + page4_7311, sizeof(page4_7311)); + setcontrast(gspca_dev); setgain(gspca_dev); setexposure(gspca_dev); sethvflip(gspca_dev); @@ -709,8 +483,6 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x87, 0x11); break; case 0: /* 640x480 */ - if (sd->sensor == SENSOR_PAC7302) - break; reg_w(gspca_dev, 0xff, 0x01); reg_w(gspca_dev, 0x17, 0x00); reg_w(gspca_dev, 0x87, 0x12); @@ -723,23 +495,13 @@ static int sd_start(struct gspca_dev *gspca_dev) /* start stream */ reg_w(gspca_dev, 0xff, 0x01); - if (sd->sensor == SENSOR_PAC7302) - reg_w(gspca_dev, 0x78, 0x01); - else - reg_w(gspca_dev, 0x78, 0x05); + reg_w(gspca_dev, 0x78, 0x05); + return 0; } static void sd_stopN(struct gspca_dev *gspca_dev) { - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_PAC7302) { - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x78, 0x00); - reg_w(gspca_dev, 0x78, 0x00); - return; - } reg_w(gspca_dev, 0xff, 0x04); reg_w(gspca_dev, 0x27, 0x80); reg_w(gspca_dev, 0x28, 0xca); @@ -752,17 +514,9 @@ static void sd_stopN(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */ } -/* called on streamoff with alt 0 and on disconnect */ +/* called on streamoff with alt 0 and on disconnect for 7311 */ static void sd_stop0(struct gspca_dev *gspca_dev) { - struct sd *sd = (struct sd *) gspca_dev; - - if (!gspca_dev->present) - return; - if (sd->sensor == SENSOR_PAC7302) { - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x78, 0x40); - } } /* Include pac common sof detection functions */ @@ -777,22 +531,8 @@ static void do_autogain(struct gspca_dev *gspca_dev) if (avg_lum == -1) return; - if (sd->sensor == SENSOR_PAC7302) { - desired_lum = 270 + sd->brightness * 4; - /* Hack hack, with the 7202 the first exposure step is - pretty large, so if we're about to make the first - exposure increase make the deadzone large to avoid - oscilating */ - if (desired_lum > avg_lum && sd->gain == GAIN_DEF && - sd->exposure > EXPOSURE_DEF && - sd->exposure < 42) - deadzone = 90; - else - deadzone = 30; - } else { - desired_lum = 200; - deadzone = 20; - } + desired_lum = 200; + deadzone = 20; if (sd->autogain_ignore_frames > 0) sd->autogain_ignore_frames--; @@ -862,17 +602,12 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, if (sof) { int n, lum_offset, footer_length; - if (sd->sensor == SENSOR_PAC7302) { - /* 6 bytes after the FF D9 EOF marker a number of lumination - bytes are send corresponding to different parts of the - image, the 14th and 15th byte after the EOF seem to - correspond to the center of the image */ - lum_offset = 61 + sizeof pac_sof_marker; - footer_length = 74; - } else { - lum_offset = 24 + sizeof pac_sof_marker; - footer_length = 26; - } + /* 6 bytes after the FF D9 EOF marker a number of lumination + bytes are send corresponding to different parts of the + image, the 14th and 15th byte after the EOF seem to + correspond to the center of the image */ + lum_offset = 24 + sizeof pac_sof_marker; + footer_length = 26; /* Finish decoding current frame */ n = (sof - data) - (footer_length + sizeof pac_sof_marker); @@ -901,46 +636,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, atomic_set(&sd->avg_lum, -1); /* Start the new frame with the jpeg header */ - if (sd->sensor == SENSOR_PAC7302) { - /* The PAC7302 has the image rotated 90 degrees */ - pac_start_frame(gspca_dev, frame, - gspca_dev->width, gspca_dev->height); - } else { - pac_start_frame(gspca_dev, frame, - gspca_dev->height, gspca_dev->width); - } + pac_start_frame(gspca_dev, frame, + gspca_dev->height, gspca_dev->width); } gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); } -static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->brightness = val; - if (gspca_dev->streaming) - setbrightcont(gspca_dev); - return 0; -} - -static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - *val = sd->brightness; - return 0; -} - static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; sd->contrast = val; if (gspca_dev->streaming) { - if (sd->sensor == SENSOR_PAC7302) - setbrightcont(gspca_dev); - else - setcontrast(gspca_dev); + setcontrast(gspca_dev); } return 0; } @@ -953,24 +661,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) return 0; } -static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->colors = val; - if (gspca_dev->streaming) - setcolors(gspca_dev); - return 0; -} - -static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - *val = sd->colors; - return 0; -} - static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -1074,7 +764,7 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) return 0; } -/* sub-driver description */ +/* sub-driver description for pac7311 */ static struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, @@ -1090,22 +780,12 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ static __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x06f8, 0x3009), .driver_info = SENSOR_PAC7302}, - {USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311}, - {USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311}, - {USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311}, - {USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311}, - {USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311}, - {USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311}, - {USB_DEVICE(0x093a, 0x2620), .driver_info = SENSOR_PAC7302}, - {USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302}, - {USB_DEVICE(0x093a, 0x2622), .driver_info = SENSOR_PAC7302}, - {USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302}, - {USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302}, - {USB_DEVICE(0x093a, 0x2628), .driver_info = SENSOR_PAC7302}, - {USB_DEVICE(0x093a, 0x2629), .driver_info = SENSOR_PAC7302}, - {USB_DEVICE(0x093a, 0x262a), .driver_info = SENSOR_PAC7302}, - {USB_DEVICE(0x093a, 0x262c), .driver_info = SENSOR_PAC7302}, + {USB_DEVICE(0x093a, 0x2600)}, + {USB_DEVICE(0x093a, 0x2601)}, + {USB_DEVICE(0x093a, 0x2603)}, + {USB_DEVICE(0x093a, 0x2608)}, + {USB_DEVICE(0x093a, 0x260e)}, + {USB_DEVICE(0x093a, 0x260f)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); -- cgit v1.2.3-70-g09d2 From 23a98274cc348880ecb6803307c254448084953a Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 2 Nov 2009 09:10:25 -0300 Subject: V4L/DVB (13301): gspca - sonixj: Simplify the sensor init exchanges. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 174 ++++++++----------------------------- 1 file changed, 34 insertions(+), 140 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 22209945698..63371bbe3da 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -464,6 +464,8 @@ static const u8 hv7131r_sensor_init[][8] = { {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10}, + /* set sensor clock */ {} }; static const u8 mi0360_sensor_init[][8] = { @@ -545,7 +547,7 @@ static const u8 mo4000_sensor_init[][8] = { }; static const u8 mt9v111_sensor_init[][8] = { {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */ - /* delay 20 ms */ + {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */ {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */ @@ -622,10 +624,10 @@ static const u8 om6802_sensor_init[][8] = { static const u8 ov7630_sensor_init[][8] = { {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10}, -/* win: delay 20ms */ + {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10}, -/* win: delay 20ms */ + {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, /* win: i2c_r from 00 to 80 */ {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10}, @@ -677,6 +679,7 @@ static const u8 ov7630_sensor_init[][8] = { static const u8 ov7648_sensor_init[][8] = { {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */ + {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10}, {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10}, @@ -723,7 +726,7 @@ static const u8 ov7648_sensor_init[][8] = { static const u8 ov7660_sensor_init[][8] = { {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ -/* (delay 20ms) */ + {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, /* Outformat = rawRGB */ {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ @@ -894,6 +897,18 @@ static const u8 sp80708_sensor_init[][8] = { {} }; +static const u8 (*sensor_init[9])[8] = { + hv7131r_sensor_init, /* HV7131R 0 */ + mi0360_sensor_init, /* MI0360 1 */ + mo4000_sensor_init, /* MO4000 2 */ + mt9v111_sensor_init, /* MT9V111 3 */ + om6802_sensor_init, /* OM6802 4 */ + ov7630_sensor_init, /* OV7630 5 */ + ov7648_sensor_init, /* OV7648 6 */ + ov7660_sensor_init, /* OV7660 7 */ + sp80708_sensor_init, /* SP80708 8 */ +}; + /* read bytes to gspca_dev->usb_buf */ static void reg_r(struct gspca_dev *gspca_dev, u16 value, int len) @@ -1014,6 +1029,18 @@ static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg) reg_r(gspca_dev, 0x0a, 5); } +static void i2c_w_seq(struct gspca_dev *gspca_dev, + const u8 (*data)[8]) +{ + while ((*data)[0] != 0) { + if ((*data)[0] != 0xdd) + i2c_w8(gspca_dev, *data); + else + msleep((*data)[1]); + data++; + } +} + static void hv7131r_probe(struct gspca_dev *gspca_dev) { i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */ @@ -1164,129 +1191,6 @@ static void configure_gpio(struct gspca_dev *gspca_dev, } } -static void hv7131R_InitSensor(struct gspca_dev *gspca_dev) -{ - int i = 0; - static const u8 SetSensorClk[] = /* 0x08 Mclk */ - { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 }; - - while (hv7131r_sensor_init[i][0]) { - i2c_w8(gspca_dev, hv7131r_sensor_init[i]); - i++; - } - i2c_w8(gspca_dev, SetSensorClk); -} - -static void mi0360_InitSensor(struct gspca_dev *gspca_dev) -{ - int i = 0; - - while (mi0360_sensor_init[i][0]) { - i2c_w8(gspca_dev, mi0360_sensor_init[i]); - i++; - } -} - -static void mo4000_InitSensor(struct gspca_dev *gspca_dev) -{ - int i = 0; - - while (mo4000_sensor_init[i][0]) { - i2c_w8(gspca_dev, mo4000_sensor_init[i]); - i++; - } -} - -static void mt9v111_InitSensor(struct gspca_dev *gspca_dev) -{ - int i = 0; - - i2c_w8(gspca_dev, mt9v111_sensor_init[i]); - i++; - msleep(20); - while (mt9v111_sensor_init[i][0]) { - i2c_w8(gspca_dev, mt9v111_sensor_init[i]); - i++; - } -} - -static void om6802_InitSensor(struct gspca_dev *gspca_dev) -{ - int i = 0; - - while (om6802_sensor_init[i][0]) { - i2c_w8(gspca_dev, om6802_sensor_init[i]); - i++; - } -} - -static void ov7630_InitSensor(struct gspca_dev *gspca_dev) -{ - int i = 0; - - i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */ - i++; - i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */ - i++; - msleep(20); - i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */ - i++; - i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */ - i++; - msleep(20); - i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */ - i++; -/*jfm:win i2c_r from 00 to 80*/ - - while (ov7630_sensor_init[i][0]) { - i2c_w8(gspca_dev, ov7630_sensor_init[i]); - i++; - } -} - -static void ov7648_InitSensor(struct gspca_dev *gspca_dev) -{ - int i = 0; - - i2c_w8(gspca_dev, ov7648_sensor_init[i]); - i++; -/* win: dble reset */ - i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */ - i++; - msleep(20); -/* win: i2c reg read 00..7f */ - while (ov7648_sensor_init[i][0]) { - i2c_w8(gspca_dev, ov7648_sensor_init[i]); - i++; - } -} - -static void ov7660_InitSensor(struct gspca_dev *gspca_dev) -{ - int i = 0; - - i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */ - i++; - msleep(20); - while (ov7660_sensor_init[i][0]) { - i2c_w8(gspca_dev, ov7660_sensor_init[i]); - i++; - } -} - -static void sp80708_InitSensor(struct gspca_dev *gspca_dev) -{ - int i = 0; - - i2c_w8(gspca_dev, sp80708_sensor_init[i]); /* reset SCCB */ - i++; - msleep(20); - while (sp80708_sensor_init[i][0]) { - i2c_w8(gspca_dev, sp80708_sensor_init[i]); - i++; - } -} - /* this function is called at probe time */ static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id) @@ -1801,6 +1705,9 @@ static int sd_start(struct gspca_dev *gspca_dev) break; } + /* initialize the sensor */ + i2c_w_seq(gspca_dev, sensor_init[sd->sensor]); + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; if (mode) reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */ @@ -1808,14 +1715,7 @@ static int sd_start(struct gspca_dev *gspca_dev) reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */ reg17 = 0x61; /* 0x:20: enable sensor clock */ switch (sd->sensor) { - case SENSOR_HV7131R: - hv7131R_InitSensor(gspca_dev); - break; - case SENSOR_MI0360: - mi0360_InitSensor(gspca_dev); - break; case SENSOR_MO4000: - mo4000_InitSensor(gspca_dev); if (mode) { /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */ reg1 = 0x06; /* clk 24Mz */ @@ -1825,7 +1725,6 @@ static int sd_start(struct gspca_dev *gspca_dev) } break; case SENSOR_MT9V111: - mt9v111_InitSensor(gspca_dev); if (mode) { reg1 = 0x04; /* 320 clk 48Mhz */ } else { @@ -1834,22 +1733,18 @@ static int sd_start(struct gspca_dev *gspca_dev) } break; case SENSOR_OM6802: - om6802_InitSensor(gspca_dev); reg17 = 0x64; /* 640 MCKSIZE */ break; case SENSOR_OV7630: - ov7630_InitSensor(gspca_dev); setvflip(sd); reg17 = 0xe2; reg1 = 0x44; break; case SENSOR_OV7648: - ov7648_InitSensor(gspca_dev); reg17 = 0x21; /* reg1 = 0x42; * 42 - 46? */ break; case SENSOR_OV7660: - ov7660_InitSensor(gspca_dev); if (sd->bridge == BRIDGE_SN9C120) { if (mode) { /* 320x240 - 160x120 */ reg17 = 0xa2; @@ -1863,7 +1758,6 @@ static int sd_start(struct gspca_dev *gspca_dev) break; default: /* case SENSOR_SP80708: */ - sp80708_InitSensor(gspca_dev); if (mode) { /*?? reg1 = 0x04; * 320 clk 48Mhz */ } else { -- cgit v1.2.3-70-g09d2 From a782636c26b7468345d2c3b67952bf695a39cdfa Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 2 Nov 2009 09:21:06 -0300 Subject: V4L/DVB (13302): gspca - sonixj: Fix some bad values of sensor om6802. - sensor address is 0x34 - sensor i2c is 100 kHz Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 63371bbe3da..159f9f7be30 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -973,7 +973,14 @@ static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) struct sd *sd = (struct sd *) gspca_dev; PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val); - gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */ + switch (sd->sensor) { + case SENSOR_OM6802: /* i2c command = a0 (100 kHz) */ + gspca_dev->usb_buf[0] = 0x80 | (2 << 4); + break; + default: /* i2c command = a1 (400 kHz) */ + gspca_dev->usb_buf[0] = 0x81 | (2 << 4); + break; + } gspca_dev->usb_buf[1] = sd->i2c_base; gspca_dev->usb_buf[2] = reg; gspca_dev->usb_buf[3] = val; @@ -1012,7 +1019,14 @@ static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg) struct sd *sd = (struct sd *) gspca_dev; u8 mode[8]; - mode[0] = 0x81 | 0x10; + switch (sd->sensor) { + case SENSOR_OM6802: /* i2c command = 90 (100 kHz) */ + mode[0] = 0x80 | 0x10; + break; + default: /* i2c command = 91 (400 kHz) */ + mode[0] = 0x81 | 0x10; + break; + } mode[1] = sd->i2c_base; mode[2] = reg; mode[3] = 0; @@ -1022,7 +1036,7 @@ static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg) mode[7] = 0x10; i2c_w8(gspca_dev, mode); msleep(2); - mode[0] = 0x81 | (5 << 4) | 0x02; + mode[0] = (mode[0] & 0x81) | (5 << 4) | 0x02; mode[2] = 0; i2c_w8(gspca_dev, mode); msleep(2); @@ -2216,7 +2230,7 @@ static const __devinitdata struct usb_device_id device_table[] = { /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x21)}, */ {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)}, /* {USB_DEVICE(0x0c45, 0x60c2), BSI(SN9C105, P1030xC, 0x??)}, */ -/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6802, 0x21)}, */ +/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6802, 0x34)}, */ /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */ {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)}, /* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */ @@ -2228,7 +2242,7 @@ static const __devinitdata struct usb_device_id device_table[] = { #endif {USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/ /* {USB_DEVICE(0x0c45, 0x6102), BSI(SN9C120, P1030xC, ??)}, */ -/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6802, 0x21)}, */ +/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6802, 0x34)}, */ {USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/ {USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/ {USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/ @@ -2236,7 +2250,7 @@ static const __devinitdata struct usb_device_id device_table[] = { /* {USB_DEVICE(0x0c45, 0x610f), BSI(SN9C120, S5K53BEB, 0x??)}, */ /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ - {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/ + {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C120, OM6802, 0x34)}, /*sn9c325?*/ /*bw600.inf:*/ {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/ {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)}, @@ -2255,7 +2269,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x21)}, /* {USB_DEVICE(0x0c45, 0x6142), BSI(SN9C120, PO2030N, ??)}, *sn9c120b*/ {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)}, /*sn9c120b*/ - {USB_DEVICE(0x0c45, 0x6148), BSI(SN9C120, OM6802, 0x21)}, /*sn9c120b*/ + {USB_DEVICE(0x0c45, 0x6148), BSI(SN9C120, OM6802, 0x34)}, /*sn9c120b*/ {} }; MODULE_DEVICE_TABLE(usb, device_table); -- cgit v1.2.3-70-g09d2 From 3fccb774ef6e43c2d80d322a5b52564db3067ef8 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 2 Nov 2009 09:54:04 -0300 Subject: V4L/DVB (13303): gspca - sonixj: Change sensor and om6802 exchanges. - the sensors are now initialized sooner - om6802: . set some parameters in factory mode . lack of some parameters . gpio adjustments Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 110 ++++++++++++++++++++++++++++++------- 1 file changed, 90 insertions(+), 20 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 159f9f7be30..c1b6c956558 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -574,7 +574,9 @@ static const u8 mt9v111_sensor_init[][8] = { {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */ {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */ {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, - /*******/ + {} +}; +static const u8 mt9v111_sensor_param1[][8] = { {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10}, @@ -587,11 +589,16 @@ static const u8 mt9v111_sensor_init[][8] = { {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */ {} }; +static const u8 om6802_init0[2][8] = { +/*fixme: variable*/ + {0xa0, 0x34, 0x29, 0x0e, 0x00, 0x00, 0x00, 0x10}, + {0xa0, 0x34, 0x23, 0xb0, 0x00, 0x00, 0x00, 0x10}, +}; static const u8 om6802_sensor_init[][8] = { - {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10}, + {0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10}, + /* factory mode */ {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10}, + {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10}, /* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */ {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10}, /* white balance & auto-exposure */ @@ -614,11 +621,14 @@ static const u8 om6802_sensor_init[][8] = { /* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10}, * auto frame rate */ /* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */ - -/* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */ -/* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */ -/* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */ -/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */ + {0xa0, 0x34, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10}, + {} +}; +static const u8 om6802_sensor_param1[][8] = { + {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, + {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, + {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, + {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, {} }; static const u8 ov7630_sensor_init[][8] = { @@ -704,7 +714,9 @@ static const u8 ov7648_sensor_init[][8] = { /* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */ /* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */ /* {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */ -/*...*/ + {} +}; +static const u8 ov7648_sensor_param1[][8] = { /* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */ /* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN * set by setvflip */ @@ -786,8 +798,11 @@ static const u8 ov7660_sensor_init[][8] = { {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */ +/* not in all ms-win traces*/ {0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10}, -/****** (some exchanges in the win trace) ******/ + {} +}; +static const u8 ov7660_sensor_param1[][8] = { {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */ /* bits[3..0]reserved */ {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, @@ -800,6 +815,7 @@ static const u8 ov7660_sensor_init[][8] = { {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */ /* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */ /****** (some exchanges in the win trace) ******/ +/*fixme:param2*/ {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */ {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */ {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */ @@ -807,6 +823,7 @@ static const u8 ov7660_sensor_init[][8] = { /* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */ /****** (some exchanges in the win trace) ******/ /******!! startsensor KO if changed !!****/ +/*fixme: param3*/ {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, @@ -886,7 +903,9 @@ static const u8 sp80708_sensor_init[][8] = { {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10}, - /********/ + {} +}; +static const u8 sp80708_sensor_param1[][8] = { {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10}, @@ -1125,7 +1144,7 @@ static void mi0360_probe(struct gspca_dev *gspca_dev) } } -static void configure_gpio(struct gspca_dev *gspca_dev, +static void bridge_init(struct gspca_dev *gspca_dev, const u8 *sn9c1xx) { struct sd *sd = (struct sd *) gspca_dev; @@ -1166,10 +1185,22 @@ static void configure_gpio(struct gspca_dev *gspca_dev, reg_w1(gspca_dev, 0x01, 0x40); break; case SENSOR_OM6802: - reg_w1(gspca_dev, 0x02, 0x71); - reg_w1(gspca_dev, 0x01, 0x42); + msleep(10); + reg_w1(gspca_dev, 0x02, 0x73); + reg_w1(gspca_dev, 0x17, 0x60); + reg_w1(gspca_dev, 0x01, 0x22); + msleep(100); + reg_w1(gspca_dev, 0x01, 0x62); + reg_w1(gspca_dev, 0x17, 0x64); reg_w1(gspca_dev, 0x17, 0x64); reg_w1(gspca_dev, 0x01, 0x42); + msleep(10); + reg_w1(gspca_dev, 0x01, 0x42); + i2c_w8(gspca_dev, om6802_init0[0]); + i2c_w8(gspca_dev, om6802_init0[1]); + msleep(15); + reg_w1(gspca_dev, 0x02, 0x71); + msleep(150); break; case SENSOR_OV7630: reg_w1(gspca_dev, 0x01, 0x61); @@ -1639,8 +1670,9 @@ static int sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int i; - u8 reg1, reg17; + u8 reg1, reg2, reg17; const u8 *sn9c1xx; + const u8 (*init)[8]; int mode; static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; @@ -1656,8 +1688,25 @@ static int sd_start(struct gspca_dev *gspca_dev) 0x21); /* JPEG 422 */ jpeg_set_qual(sd->jpeg_hdr, sd->quality); - sn9c1xx = sn_tb[(int) sd->sensor]; - configure_gpio(gspca_dev, sn9c1xx); + /* initialize the bridge */ + sn9c1xx = sn_tb[sd->sensor]; + bridge_init(gspca_dev, sn9c1xx); + /* initialize the sensor */ + i2c_w_seq(gspca_dev, sensor_init[sd->sensor]); + + switch (sd->sensor) { + case SENSOR_OM6802: + reg2 = 0x71; + break; + case SENSOR_SP80708: + reg2 = 0x62; + break; + default: + reg2 = 0x40; + break; + } + reg_w1(gspca_dev, 0x02, reg2); + reg_w1(gspca_dev, 0x02, reg2); reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]); reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]); @@ -1704,6 +1753,10 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x9a, 0x07); reg_w1(gspca_dev, 0x99, 0x59); break; + case SENSOR_OM6802: + reg_w1(gspca_dev, 0x9a, 0x08); + reg_w1(gspca_dev, 0x99, 0x10); + break; case SENSOR_OV7648: reg_w1(gspca_dev, 0x9a, 0x0a); reg_w1(gspca_dev, 0x99, 0x60); @@ -1719,9 +1772,12 @@ static int sd_start(struct gspca_dev *gspca_dev) break; } - /* initialize the sensor */ - i2c_w_seq(gspca_dev, sensor_init[sd->sensor]); + reg_w(gspca_dev, 0x84, reg84, sizeof reg84); + reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */ + reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */ + reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */ + init = NULL; mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; if (mode) reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */ @@ -1739,6 +1795,7 @@ static int sd_start(struct gspca_dev *gspca_dev) } break; case SENSOR_MT9V111: + init = mt9v111_sensor_param1; if (mode) { reg1 = 0x04; /* 320 clk 48Mhz */ } else { @@ -1747,6 +1804,7 @@ static int sd_start(struct gspca_dev *gspca_dev) } break; case SENSOR_OM6802: + init = om6802_sensor_param1; reg17 = 0x64; /* 640 MCKSIZE */ break; case SENSOR_OV7630: @@ -1755,10 +1813,12 @@ static int sd_start(struct gspca_dev *gspca_dev) reg1 = 0x44; break; case SENSOR_OV7648: + init = ov7648_sensor_param1; reg17 = 0x21; /* reg1 = 0x42; * 42 - 46? */ break; case SENSOR_OV7660: + init = ov7660_sensor_param1; if (sd->bridge == BRIDGE_SN9C120) { if (mode) { /* 320x240 - 160x120 */ reg17 = 0xa2; @@ -1772,6 +1832,7 @@ static int sd_start(struct gspca_dev *gspca_dev) break; default: /* case SENSOR_SP80708: */ + init = sp80708_sensor_param1; if (mode) { /*?? reg1 = 0x04; * 320 clk 48Mhz */ } else { @@ -1780,6 +1841,13 @@ static int sd_start(struct gspca_dev *gspca_dev) } break; } + + /* more sensor initialization - param1 */ + if (init != NULL) { + i2c_w_seq(gspca_dev, init); +/* init = NULL; */ + } + reg_w(gspca_dev, 0xc0, C0, 6); reg_w(gspca_dev, 0xca, CA, 4); switch (sd->sensor) { @@ -1794,6 +1862,7 @@ static int sd_start(struct gspca_dev *gspca_dev) break; } + /* here change size mode 0 -> VGA; 1 -> CIF */ sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40; reg_w1(gspca_dev, 0x18, sd->reg18); @@ -1801,6 +1870,7 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x17, reg17); reg_w1(gspca_dev, 0x01, reg1); + switch (sd->sensor) { case SENSOR_OV7630: setvflip(sd); -- cgit v1.2.3-70-g09d2 From 98941e4dade35ab2e83c9bc796fdc76ed3636a75 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 2 Nov 2009 09:56:59 -0300 Subject: V4L/DVB (13304): gspca - sonixj: Don't access the sensor when setting the bridge. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index c1b6c956558..bd076605c4b 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -304,7 +304,7 @@ static const u8 sn_hv7131[0x1c] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20, /* reg8 reg9 rega regb regc regd rege regf */ - 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, + 0x81, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, /* reg18 reg19 reg1a reg1b */ @@ -315,7 +315,7 @@ static const u8 sn_mi0360[0x1c] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, /* reg8 reg9 rega regb regc regd rege regf */ - 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, /* reg18 reg19 reg1a reg1b */ @@ -337,7 +337,7 @@ static const u8 sn_mt9v111[0x1c] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, /* reg8 reg9 rega regb regc regd rege regf */ - 0x81, 0x5c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x81, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40, /* reg18 reg19 reg1a reg1b */ @@ -359,7 +359,7 @@ static const u8 sn_ov7630[0x1c] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20, /* reg8 reg9 rega regb regc regd rege regf */ - 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10, + 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2, /* reg18 reg19 reg1a reg1b */ @@ -370,7 +370,7 @@ static const u8 sn_ov7648[0x1c] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, /* reg8 reg9 rega regb regc regd rege regf */ - 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00, /* reg18 reg19 reg1a reg1b */ @@ -392,7 +392,7 @@ static const u8 sn_sp80708[0x1c] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20, /* reg8 reg9 rega regb regc regd rege regf */ - 0x81, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x81, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00, /* reg18 reg19 reg1a reg1b */ -- cgit v1.2.3-70-g09d2 From 0939e266697d516ba09cfaec6a97887600a4162d Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 2 Nov 2009 09:58:49 -0300 Subject: V4L/DVB (13305): gspca - sonixj: The V flip control does not exist for all sensors. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index bd076605c4b..e75e7e36e7d 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -1549,6 +1549,8 @@ static void setvflip(struct sd *sd) { u8 comn; + if (sd->gspca_dev.ctrl_dis & (1 << VFLIP_IDX)) + return; if (sd->sensor == SENSOR_OV7630) { comn = 0x02; if (!sd->vflip) -- cgit v1.2.3-70-g09d2 From 5b34e3e4eb993578c313f473ff60df62e0c24379 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 2 Nov 2009 10:00:48 -0300 Subject: V4L/DVB (13306): gspca - sonixj: Change the copyright. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index e75e7e36e7d..a9643a0f78d 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -1,8 +1,7 @@ /* - * Sonix sn9c102p sn9c105 sn9c120 (jpeg) library - * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr - * - * V4L2 by Jean-Francois Moine + * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver + * Copyright (C) 2009 Jean-Francois Moine + * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -- cgit v1.2.3-70-g09d2 From 3bc766ad374d04349ba09bd93f51980ad29d11c3 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 21 Oct 2009 18:36:18 -0300 Subject: V4L/DVB (13308): uvcvideo: Add support for MSI StarCam 370i webcams The MSI StarCam 370i (1b3b:2951) requires the MINMAX quirk. Add a corresponding entry in the device IDs list. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_driver.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index ab4a60102d0..782faf6970b 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -2136,6 +2136,15 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_STATUS_INTERVAL }, + /* MSI StarCam 370i */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x1b3b, + .idProduct = 0x2951, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_PROBE_MINMAX }, /* SiGma Micro USB Web Camera */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, -- cgit v1.2.3-70-g09d2 From 350d6407f84db58e2dfb5a5a5283982130746a41 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 4 Nov 2009 11:53:49 -0300 Subject: V4L/DVB (13310): uvcvideo: Return -EINVAL instead of -ENODEV in read() -EINVAL is required by the V4L2 specification. -ENODEV is simply wrong as the device exists. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_v4l2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index b3478d0eaf4..be3da56d4db 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c @@ -1035,7 +1035,7 @@ static ssize_t uvc_v4l2_read(struct file *file, char __user *data, size_t count, loff_t *ppos) { uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_read: not implemented.\n"); - return -ENODEV; + return -EINVAL; } /* -- cgit v1.2.3-70-g09d2 From 56205cc0dd703be70b4ea1138a7e774e058d79fa Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 4 Nov 2009 16:38:04 -0300 Subject: V4L/DVB (13323): gspca - zc3xx: Adjust the exchanges of sensors mi0360soc and pb0330. - the pb03303x exchanges were the mi0360soc ones - add the new sensor mi0360soc - the new exchanges are taken from the info file of the ms-win driver of the webcams 0ac8:301b and 0ac8:303b (vm30x.inf) Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/zc3xx.c | 823 ++++++++++++++++---------------------- 1 file changed, 335 insertions(+), 488 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index e57f9dd68a4..11305079224 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -61,17 +61,18 @@ struct sd { #define SENSOR_HV7131C 6 #define SENSOR_ICM105A 7 #define SENSOR_MC501CB 8 -#define SENSOR_OV7620 9 -/*#define SENSOR_OV7648 9 - same values */ -#define SENSOR_OV7630C 10 -#define SENSOR_PAS106 11 -#define SENSOR_PAS202B 12 -#define SENSOR_PB0330 13 -#define SENSOR_PO2030 14 -#define SENSOR_TAS5130CK 15 -#define SENSOR_TAS5130CXX 16 -#define SENSOR_TAS5130C_VF0250 17 -#define SENSOR_MAX 18 +#define SENSOR_MI0360SOC 9 +#define SENSOR_OV7620 10 +/*#define SENSOR_OV7648 10 - same values */ +#define SENSOR_OV7630C 11 +#define SENSOR_PAS106 12 +#define SENSOR_PAS202B 13 +#define SENSOR_PB0330 14 /* (MI0360) */ +#define SENSOR_PO2030 15 +#define SENSOR_TAS5130CK 16 +#define SENSOR_TAS5130CXX 17 +#define SENSOR_TAS5130C_VF0250 18 +#define SENSOR_MAX 19 unsigned short chip_revision; u8 *jpeg_hdr; @@ -4235,170 +4236,80 @@ static const struct usb_action pas202b_NoFlikerScale[] = { {} }; -static const struct usb_action pb03303x_Initial[] = { +/* mi0360soc and pb0330 from vm30x.inf for 0ac8:301b and 0ac8:303b 07/02/13 */ +static const struct usb_action mi0360soc_Initial[] = { /* 640x480 */ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, /* 8b -> dc */ + {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, /*jfm: was 03*/ +/* {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, */ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, + {0xdd, 0x00, 0x0200}, {0xaa, 0x01, 0x0001}, {0xaa, 0x06, 0x0000}, {0xaa, 0x08, 0x0483}, {0xaa, 0x01, 0x0004}, {0xaa, 0x08, 0x0006}, {0xaa, 0x02, 0x0011}, - {0xaa, 0x03, 0x01e7}, - {0xaa, 0x04, 0x0287}, + {0xaa, 0x03, 0x01e5}, /*jfm: was 01e7*/ + {0xaa, 0x04, 0x0285}, /*jfm: was 0287*/ {0xaa, 0x07, 0x3002}, - {0xaa, 0x20, 0x1100}, - {0xaa, 0x35, 0x0050}, + {0xaa, 0x20, 0x5100}, /*jfm: was 1100*/ + {0xaa, 0x35, 0x507f}, /*jfm: was 0050*/ {0xaa, 0x30, 0x0005}, {0xaa, 0x31, 0x0000}, {0xaa, 0x58, 0x0078}, {0xaa, 0x62, 0x0411}, {0xaa, 0x2b, 0x0028}, - {0xaa, 0x2c, 0x0030}, - {0xaa, 0x2d, 0x0030}, - {0xaa, 0x2e, 0x0028}, + {0xaa, 0x2c, 0x007f}, /*jfm: was 0030*/ + {0xaa, 0x2d, 0x007f}, /*jfm: was 0030*/ + {0xaa, 0x2e, 0x007f}, /*jfm: was 0030*/ {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, - {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /*jfm: was 37*/ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x00, 0x01ad}, + {0xa0, 0x09, 0x01ad}, /*jfm: was 00*/ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, - {0xa0, 0x78, ZC3XX_R18D_YTARGET}, + {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, /* jfm: was 78 */ {0xa0, 0x61, ZC3XX_R116_RGAIN}, {0xa0, 0x65, ZC3XX_R118_BGAIN}, - - {0xa1, 0x01, 0x0002}, - {0xa0, 0x09, 0x01ad}, - {0xa0, 0x15, 0x01ae}, - {0xa0, 0x0d, 0x003a}, - {0xa0, 0x02, 0x003b}, - {0xa0, 0x00, 0x0038}, - {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xf8, ZC3XX_R10B_RGB01}, - {0xa0, 0xf8, ZC3XX_R10C_RGB02}, - {0xa0, 0xf8, ZC3XX_R10D_RGB10}, - {0xa0, 0x50, ZC3XX_R10E_RGB11}, - {0xa0, 0xf8, ZC3XX_R10F_RGB12}, - {0xa0, 0xf8, ZC3XX_R110_RGB20}, - {0xa0, 0xf8, ZC3XX_R111_RGB21}, - {0xa0, 0x50, ZC3XX_R112_RGB22}, - - {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, - {0xa1, 0x01, 0x01c8}, - {0xa1, 0x01, 0x01c9}, - {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ - {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ - {0xa0, 0x38, ZC3XX_R121_GAMMA01}, - {0xa0, 0x59, ZC3XX_R122_GAMMA02}, - {0xa0, 0x79, ZC3XX_R123_GAMMA03}, - {0xa0, 0x92, ZC3XX_R124_GAMMA04}, - {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, - {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, - {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, - {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, - {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, - {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, - {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, - {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, - {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, - {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, - {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, - {0xa0, 0x26, ZC3XX_R130_GAMMA10}, - {0xa0, 0x22, ZC3XX_R131_GAMMA11}, - {0xa0, 0x20, ZC3XX_R132_GAMMA12}, - {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, - {0xa0, 0x16, ZC3XX_R134_GAMMA14}, - {0xa0, 0x13, ZC3XX_R135_GAMMA15}, - {0xa0, 0x10, ZC3XX_R136_GAMMA16}, - {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, - {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, - {0xa0, 0x09, ZC3XX_R139_GAMMA19}, - {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, - {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, - {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, - {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, - {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, - {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, - {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xf8, ZC3XX_R10B_RGB01}, - {0xa0, 0xf8, ZC3XX_R10C_RGB02}, - {0xa0, 0xf8, ZC3XX_R10D_RGB10}, - {0xa0, 0x50, ZC3XX_R10E_RGB11}, - {0xa0, 0xf8, ZC3XX_R10F_RGB12}, - {0xa0, 0xf8, ZC3XX_R110_RGB20}, - {0xa0, 0xf8, ZC3XX_R111_RGB21}, - {0xa0, 0x50, ZC3XX_R112_RGB22}, - - {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x05, 0x0009}, - {0xaa, 0x09, 0x0134}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xec, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x9c, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x09, 0x01ad}, - {0xa0, 0x15, 0x01ae}, - {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {} }; - -static const struct usb_action pb03303x_InitialScale[] = { +static const struct usb_action mi0360soc_InitialScale[] = { /* 320x240 */ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, /* 8b -> dc */ + {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, /*jfm: was 03*/ +/* {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, */ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, + {0xdd, 0x00, 0x0200}, {0xaa, 0x01, 0x0001}, {0xaa, 0x06, 0x0000}, {0xaa, 0x08, 0x0483}, @@ -4408,111 +4319,111 @@ static const struct usb_action pb03303x_InitialScale[] = { {0xaa, 0x03, 0x01e7}, {0xaa, 0x04, 0x0287}, {0xaa, 0x07, 0x3002}, - {0xaa, 0x20, 0x1100}, - {0xaa, 0x35, 0x0050}, + {0xaa, 0x20, 0x5100}, /*jfm: was 1100*/ + {0xaa, 0x35, 0x007f}, /*jfm: was 0050*/ {0xaa, 0x30, 0x0005}, {0xaa, 0x31, 0x0000}, {0xaa, 0x58, 0x0078}, {0xaa, 0x62, 0x0411}, - {0xaa, 0x2b, 0x0028}, - {0xaa, 0x2c, 0x0030}, - {0xaa, 0x2d, 0x0030}, - {0xaa, 0x2e, 0x0028}, + {0xaa, 0x2b, 0x007f}, /*jfm: was 28*/ + {0xaa, 0x2c, 0x007f}, /*jfm: was 30*/ + {0xaa, 0x2d, 0x007f}, /*jfm: was 30*/ + {0xaa, 0x2e, 0x007f}, /*jfm: was 28*/ {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, - {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /*jfm: was 37*/ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x00, 0x01ad}, + {0xa0, 0x09, 0x01ad}, /*jfm: was 00*/ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, - {0xa0, 0x78, ZC3XX_R18D_YTARGET}, + {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, /*jfm: was 78*/ {0xa0, 0x61, ZC3XX_R116_RGAIN}, {0xa0, 0x65, ZC3XX_R118_BGAIN}, - - {0xa1, 0x01, 0x0002}, - - {0xa0, 0x09, 0x01ad}, - {0xa0, 0x15, 0x01ae}, - - {0xa0, 0x0d, 0x003a}, - {0xa0, 0x02, 0x003b}, - {0xa0, 0x00, 0x0038}, - {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xf8, ZC3XX_R10B_RGB01}, - {0xa0, 0xf8, ZC3XX_R10C_RGB02}, - {0xa0, 0xf8, ZC3XX_R10D_RGB10}, - {0xa0, 0x50, ZC3XX_R10E_RGB11}, - {0xa0, 0xf8, ZC3XX_R10F_RGB12}, - {0xa0, 0xf8, ZC3XX_R110_RGB20}, - {0xa0, 0xf8, ZC3XX_R111_RGB21}, - {0xa0, 0x50, ZC3XX_R112_RGB22}, - - {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {0xa1, 0x01, 0x01c8}, - {0xa1, 0x01, 0x01c9}, - {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ - - {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ - {0xa0, 0x38, ZC3XX_R121_GAMMA01}, - {0xa0, 0x59, ZC3XX_R122_GAMMA02}, - {0xa0, 0x79, ZC3XX_R123_GAMMA03}, - {0xa0, 0x92, ZC3XX_R124_GAMMA04}, - {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, - {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, - {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, - {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, - {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, - {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, - {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, - {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, - {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, - {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, - {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, - {0xa0, 0x26, ZC3XX_R130_GAMMA10}, - {0xa0, 0x22, ZC3XX_R131_GAMMA11}, - {0xa0, 0x20, ZC3XX_R132_GAMMA12}, - {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, - {0xa0, 0x16, ZC3XX_R134_GAMMA14}, - {0xa0, 0x13, ZC3XX_R135_GAMMA15}, - {0xa0, 0x10, ZC3XX_R136_GAMMA16}, - {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, - {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, - {0xa0, 0x09, ZC3XX_R139_GAMMA19}, - {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, - {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, - {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, - {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, - {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, - {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, - {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xf8, ZC3XX_R10B_RGB01}, - {0xa0, 0xf8, ZC3XX_R10C_RGB02}, - {0xa0, 0xf8, ZC3XX_R10D_RGB10}, - {0xa0, 0x50, ZC3XX_R10E_RGB11}, - {0xa0, 0xf8, ZC3XX_R10F_RGB12}, - {0xa0, 0xf8, ZC3XX_R110_RGB20}, - {0xa0, 0xf8, ZC3XX_R111_RGB21}, - {0xa0, 0x50, ZC3XX_R112_RGB22}, - - {0xa1, 0x01, 0x0180}, + {} +}; +static const struct usb_action mi360soc_AE50HZ[] = { + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xbb, 0x00, 0x0562}, + {0xbb, 0x01, 0x09aa}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x9b, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {} +}; +static const struct usb_action mi360soc_AE50HZScale[] = { + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xbb, 0x00, 0x0509}, + {0xbb, 0x01, 0x0934}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xd2, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x9a, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {} +}; +static const struct usb_action mi360soc_AE60HZ[] = { {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xbb, 0x00, 0x053d}, + {0xbb, 0x01, 0x096e}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xdd, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {} +}; +static const struct usb_action mi360soc_AE60HZScale[] = { {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x05, 0x0009}, - {0xaa, 0x09, 0x0134}, + {0xbb, 0x00, 0x0509}, + {0xbb, 0x01, 0x0983}, {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xec, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x8f, ZC3XX_R192_EXPOSURELIMITLOW}, {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x9c, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW}, {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, @@ -4522,20 +4433,60 @@ static const struct usb_action pb03303x_InitialScale[] = { {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2}, {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x09, 0x01ad}, - {0xa0, 0x15, 0x01ae}, - {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa1, 0x01, 0x0180}, + {} +}; +static const struct usb_action mi360soc_AENoFliker[] = { + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xbb, 0x00, 0x0509}, + {0xbb, 0x01, 0x0960}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x09, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xe0, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {} }; -static const struct usb_action pb0330xx_Initial[] = { - {0xa1, 0x01, 0x0008}, - {0xa1, 0x01, 0x0008}, +static const struct usb_action mi360soc_AENoFlikerScale[] = { + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xbb, 0x00, 0x0534}, + {0xbb, 0x02, 0x0960}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x34, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xe0, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {} +}; + +static const struct usb_action pb0330_Initial[] = { /* 640x480 */ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, @@ -4547,11 +4498,12 @@ static const struct usb_action pb0330xx_Initial[] = { {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, + {0xdd, 0x00, 0x0200}, {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, {0xaa, 0x01, 0x0006}, {0xaa, 0x02, 0x0011}, - {0xaa, 0x03, 0x01e7}, - {0xaa, 0x04, 0x0287}, + {0xaa, 0x03, 0x01e5}, /*jfm: was 1e7*/ + {0xaa, 0x04, 0x0285}, /*jfm: was 0287*/ {0xaa, 0x06, 0x0003}, {0xaa, 0x07, 0x3002}, {0xaa, 0x20, 0x1100}, @@ -4569,88 +4521,21 @@ static const struct usb_action pb0330xx_Initial[] = { {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x00, 0x01ad}, + {0xa0, 0x09, 0x01ad}, /*jfm: was 00 */ + {0xa0, 0x15, 0x01ae}, {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, - {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, - {0xa1, 0x01, 0x0002}, - {0xa0, 0x09, 0x01ad}, - {0xa0, 0x15, 0x01ae}, - {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, - {0xa1, 0x01, 0x0091}, - {0xa1, 0x01, 0x0095}, - {0xa1, 0x01, 0x0096}, - {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xf8, ZC3XX_R10B_RGB01}, - {0xa0, 0xf8, ZC3XX_R10C_RGB02}, - {0xa0, 0xf8, ZC3XX_R10D_RGB10}, - {0xa0, 0x50, ZC3XX_R10E_RGB11}, - {0xa0, 0xf8, ZC3XX_R10F_RGB12}, - {0xa0, 0xf8, ZC3XX_R110_RGB20}, - {0xa0, 0xf8, ZC3XX_R111_RGB21}, - {0xa0, 0x50, ZC3XX_R112_RGB22}, - {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {0xa1, 0x01, 0x01c8}, - {0xa1, 0x01, 0x01c9}, - {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ - - {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xf8, ZC3XX_R10B_RGB01}, - {0xa0, 0xf8, ZC3XX_R10C_RGB02}, - {0xa0, 0xf8, ZC3XX_R10D_RGB10}, - {0xa0, 0x50, ZC3XX_R10E_RGB11}, - {0xa0, 0xf8, ZC3XX_R10F_RGB12}, - {0xa0, 0xf8, ZC3XX_R110_RGB20}, - {0xa0, 0xf8, ZC3XX_R111_RGB21}, - {0xa0, 0x50, ZC3XX_R112_RGB22}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x05, 0x0066}, - {0xaa, 0x09, 0x02b2}, - {0xaa, 0x10, 0x0002}, - - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x8c, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x09, 0x01ad}, - {0xa0, 0x15, 0x01ae}, - {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa1, 0x01, 0x0008}, - {0xa1, 0x01, 0x0007}, -/* {0xa0, 0x30, 0x0007}, */ -/* {0xa0, 0x00, 0x0007}, */ + {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /*jfm: was 6c*/ {} }; - -static const struct usb_action pb0330xx_InitialScale[] = { - {0xa1, 0x01, 0x0008}, - {0xa1, 0x01, 0x0008}, +static const struct usb_action pb0330_InitialScale[] = { /* 320x240 */ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 10 */ + {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, @@ -4662,6 +4547,7 @@ static const struct usb_action pb0330xx_InitialScale[] = { {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, + {0xdd, 0x00, 0x0200}, {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, {0xaa, 0x01, 0x0006}, {0xaa, 0x02, 0x0011}, @@ -4684,53 +4570,43 @@ static const struct usb_action pb0330xx_InitialScale[] = { {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x00, 0x01ad}, + {0xa0, 0x09, 0x01ad}, + {0xa0, 0x15, 0x01ae}, {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, - {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, - {0xa1, 0x01, 0x0002}, - {0xa0, 0x09, 0x01ad}, - {0xa0, 0x15, 0x01ae}, - {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, - {0xa1, 0x01, 0x0091}, - {0xa1, 0x01, 0x0095}, - {0xa1, 0x01, 0x0096}, - {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xf8, ZC3XX_R10B_RGB01}, - {0xa0, 0xf8, ZC3XX_R10C_RGB02}, - {0xa0, 0xf8, ZC3XX_R10D_RGB10}, - {0xa0, 0x50, ZC3XX_R10E_RGB11}, - {0xa0, 0xf8, ZC3XX_R10F_RGB12}, - {0xa0, 0xf8, ZC3XX_R110_RGB20}, - {0xa0, 0xf8, ZC3XX_R111_RGB21}, - {0xa0, 0x50, ZC3XX_R112_RGB22}, - {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {0xa1, 0x01, 0x01c8}, - {0xa1, 0x01, 0x01c9}, - {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ - - {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xf8, ZC3XX_R10B_RGB01}, - {0xa0, 0xf8, ZC3XX_R10C_RGB02}, - {0xa0, 0xf8, ZC3XX_R10D_RGB10}, - {0xa0, 0x50, ZC3XX_R10E_RGB11}, - {0xa0, 0xf8, ZC3XX_R10F_RGB12}, - {0xa0, 0xf8, ZC3XX_R110_RGB20}, - {0xa0, 0xf8, ZC3XX_R111_RGB21}, - {0xa0, 0x50, ZC3XX_R112_RGB22}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /*jfm: was 6c*/ + {} +}; +static const struct usb_action pb0330_50HZ[] = { + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xbb, 0x00, 0x055c}, + {0xbb, 0x01, 0x09aa}, + {0xbb, 0x00, 0x1001}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xc4, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x5c, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, + {} +}; +static const struct usb_action pb0330_50HZScale[] = { {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x05, 0x0066}, - {0xaa, 0x09, 0x02b2}, - {0xaa, 0x10, 0x0002}, + {0xbb, 0x00, 0x0566}, + {0xbb, 0x02, 0x09b2}, + {0xbb, 0x00, 0x1002}, {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, @@ -4738,124 +4614,102 @@ static const struct usb_action pb0330xx_InitialScale[] = { {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, {0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE}, {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1}, {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x09, 0x01ad}, - {0xa0, 0x15, 0x01ae}, - {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa1, 0x01, 0x0008}, - {0xa1, 0x01, 0x0007}, -/* {0xa0, 0x30, 0x0007}, */ -/* {0xa0, 0x00, 0x0007}, */ - {} -}; -static const struct usb_action pb0330_50HZ[] = { - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ - {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,ee,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x46, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,46,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ - {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ - {0xa0, 0x68, ZC3XX_R01D_HSYNC_0}, /* 00,1d,68,cc */ - {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ - {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */ - {} -}; -static const struct usb_action pb0330_50HZScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ - {0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,a0,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x7a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7a,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ - {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ - {0xa0, 0xe5, ZC3XX_R01D_HSYNC_0}, /* 00,1d,e5,cc */ - {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f0,cc */ - {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */ {} }; static const struct usb_action pb0330_60HZ[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ - {0xa0, 0xdd, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,dd,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3d,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ - {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ - {0xa0, 0x43, ZC3XX_R01D_HSYNC_0}, /* 00,1d,43,cc */ - {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */ - {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xbb, 0x00, 0x0535}, + {0xbb, 0x01, 0x0974}, + {0xbb, 0x00, 0x1001}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xfe, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x3e, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x35, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xd0, ZC3XX_R020_HSYNC_3}, {} }; static const struct usb_action pb0330_60HZScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ - {0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,a0,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x7a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7a,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ - {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ - {0xa0, 0x41, ZC3XX_R01D_HSYNC_0}, /* 00,1d,41,cc */ - {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */ - {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xbb, 0x00, 0x0535}, + {0xbb, 0x02, 0x096c}, + {0xbb, 0x00, 0x1002}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xc0, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x7c, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x35, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xd0, ZC3XX_R020_HSYNC_3}, {} }; static const struct usb_action pb0330_NoFliker[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ - {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ - {0xa0, 0x09, ZC3XX_R01D_HSYNC_0}, /* 00,1d,09,cc */ - {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */ - {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xbb, 0x00, 0x0509}, + {0xbb, 0x02, 0x0940}, + {0xbb, 0x00, 0x1002}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x09, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xe0, ZC3XX_R020_HSYNC_3}, {} }; static const struct usb_action pb0330_NoFlikerScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ - {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ - {0xa0, 0x09, ZC3XX_R01D_HSYNC_0}, /* 00,1d,09,cc */ - {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */ - {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xbb, 0x00, 0x0535}, + {0xbb, 0x01, 0x0980}, + {0xbb, 0x00, 0x1001}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x35, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xe0, ZC3XX_R020_HSYNC_3}, {} }; @@ -6131,15 +5985,16 @@ static void setmatrix(struct gspca_dev *gspca_dev) NULL, /* SENSOR_HV7131C 6 */ NULL, /* SENSOR_ICM105A 7 */ NULL, /* SENSOR_MC501CB 8 */ - ov7620_matrix, /* SENSOR_OV7620 9 */ - NULL, /* SENSOR_OV7630C 10 */ - NULL, /* SENSOR_PAS106 11 */ - pas202b_matrix, /* SENSOR_PAS202B 12 */ - NULL, /* SENSOR_PB0330 13 */ - po2030_matrix, /* SENSOR_PO2030 14 */ - NULL, /* SENSOR_TAS5130CK 15 */ - tas5130c_matrix, /* SENSOR_TAS5130CXX 16 */ - vf0250_matrix, /* SENSOR_TAS5130C_VF0250 17 */ + gc0305_matrix, /* SENSOR_MI0360SOC 9 */ + ov7620_matrix, /* SENSOR_OV7620 10 */ + NULL, /* SENSOR_OV7630C 11 */ + NULL, /* SENSOR_PAS106 12 */ + pas202b_matrix, /* SENSOR_PAS202B 13 */ + gc0305_matrix, /* SENSOR_PB0330 14 */ + po2030_matrix, /* SENSOR_PO2030 15 */ + NULL, /* SENSOR_TAS5130CK 16 */ + tas5130c_matrix, /* SENSOR_TAS5130CXX 17 */ + vf0250_matrix, /* SENSOR_TAS5130C_VF0250 18 */ }; matrix = matrix_tb[sd->sensor]; @@ -6379,39 +6234,43 @@ static int setlightfreq(struct gspca_dev *gspca_dev) {MC501CB_NoFliker, MC501CB_NoFlikerScale, MC501CB_50HZ, MC501CB_50HZScale, MC501CB_60HZ, MC501CB_60HZScale}, -/* SENSOR_OV7620 9 */ +/* SENSOR_MI0360SOC 9 */ + {mi360soc_AENoFlikerScale, mi360soc_AENoFliker, + mi360soc_AE50HZScale, mi360soc_AE50HZ, + mi360soc_AE60HZScale, mi360soc_AE60HZ}, +/* SENSOR_OV7620 10 */ {OV7620_NoFliker, OV7620_NoFliker, OV7620_50HZ, OV7620_50HZ, OV7620_60HZ, OV7620_60HZ}, -/* SENSOR_OV7630C 10 */ +/* SENSOR_OV7630C 11 */ {NULL, NULL, NULL, NULL, NULL, NULL}, -/* SENSOR_PAS106 11 */ +/* SENSOR_PAS106 12 */ {pas106b_NoFliker, pas106b_NoFliker, pas106b_50HZ, pas106b_50HZ, pas106b_60HZ, pas106b_60HZ}, -/* SENSOR_PAS202B 12 */ +/* SENSOR_PAS202B 13 */ {pas202b_NoFlikerScale, pas202b_NoFliker, pas202b_50HZScale, pas202b_50HZ, pas202b_60HZScale, pas202b_60HZ}, -/* SENSOR_PB0330 13 */ - {pb0330_NoFliker, pb0330_NoFlikerScale, - pb0330_50HZ, pb0330_50HZScale, - pb0330_60HZ, pb0330_60HZScale}, -/* SENSOR_PO2030 14 */ +/* SENSOR_PB0330 14 */ + {pb0330_NoFlikerScale, pb0330_NoFliker, + pb0330_50HZScale, pb0330_50HZ, + pb0330_60HZScale, pb0330_60HZ}, +/* SENSOR_PO2030 15 */ {PO2030_NoFliker, PO2030_NoFliker, PO2030_50HZ, PO2030_50HZ, PO2030_60HZ, PO2030_60HZ}, -/* SENSOR_TAS5130CK 15 */ +/* SENSOR_TAS5130CK 16 */ {tas5130cxx_NoFlikerScale, tas5130cxx_NoFliker, tas5130cxx_50HZScale, tas5130cxx_50HZ, tas5130cxx_60HZScale, tas5130cxx_60HZ}, -/* SENSOR_TAS5130CXX 16 */ +/* SENSOR_TAS5130CXX 17 */ {tas5130cxx_NoFlikerScale, tas5130cxx_NoFliker, tas5130cxx_50HZScale, tas5130cxx_50HZ, tas5130cxx_60HZScale, tas5130cxx_60HZ}, -/* SENSOR_TAS5130C_VF0250 17 */ +/* SENSOR_TAS5130C_VF0250 18 */ {tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale, tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale, tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale}, @@ -6468,6 +6327,7 @@ static void send_unknown(struct usb_device *dev, int sensor) case SENSOR_ADCM2700: case SENSOR_GC0305: case SENSOR_OV7620: + case SENSOR_MI0360SOC: case SENSOR_PB0330: case SENSOR_PO2030: reg_w(dev, 0x0d, 0x003a); @@ -6603,7 +6463,7 @@ struct sensor_by_chipset_revision { }; static const struct sensor_by_chipset_revision chipset_revision_sensor[] = { {0xc000, 0x12}, /* TAS5130C */ - {0xc001, 0x13}, /* MI0360 */ + {0xc001, 0x13}, /* MI0360SOC */ {0xe001, 0x13}, {0x8001, 0x13}, {0x8000, 0x14}, /* CS2102K */ @@ -6772,15 +6632,16 @@ static int sd_config(struct gspca_dev *gspca_dev, 4, /* SENSOR_HV7131C 6 */ 4, /* SENSOR_ICM105A 7 */ 4, /* SENSOR_MC501CB 8 */ - 3, /* SENSOR_OV7620 9 */ - 4, /* SENSOR_OV7630C 10 */ - 4, /* SENSOR_PAS106 11 */ - 4, /* SENSOR_PAS202B 12 */ - 4, /* SENSOR_PB0330 13 */ - 4, /* SENSOR_PO2030 14 */ - 4, /* SENSOR_TAS5130CK 15 */ - 3, /* SENSOR_TAS5130CXX 16 */ - 3, /* SENSOR_TAS5130C_VF0250 17 */ + 4, /* SENSOR_MI0360SOC 9 */ + 3, /* SENSOR_OV7620 10 */ + 4, /* SENSOR_OV7630C 11 */ + 4, /* SENSOR_PAS106 12 */ + 4, /* SENSOR_PAS202B 13 */ + 4, /* SENSOR_PB0330 14 */ + 4, /* SENSOR_PO2030 15 */ + 4, /* SENSOR_TAS5130CK 16 */ + 3, /* SENSOR_TAS5130CXX 17 */ + 3, /* SENSOR_TAS5130C_VF0250 18 */ }; /* define some sensors from the vendor/product */ @@ -6851,9 +6712,9 @@ static int sd_config(struct gspca_dev *gspca_dev, break; case 0x13: PDEBUG(D_PROBE, - "Find Sensor MI0360. Chip revision %x", + "Find Sensor MI0360SOC. Chip revision %x", sd->chip_revision); - sd->sensor = SENSOR_PB0330; + sd->sensor = SENSOR_MI0360SOC; break; case 0x14: PDEBUG(D_PROBE, @@ -6967,17 +6828,17 @@ static int sd_start(struct gspca_dev *gspca_dev) {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 6 */ {icm105axx_InitialScale, icm105axx_Initial}, /* 7 */ {MC501CB_InitialScale, MC501CB_Initial}, /* 8 */ - {OV7620_mode0, OV7620_mode1}, /* 9 */ - {ov7630c_InitialScale, ov7630c_Initial}, /* 10 */ - {pas106b_InitialScale, pas106b_Initial}, /* 11 */ - {pas202b_Initial, pas202b_InitialScale}, /* 12 */ - {pb0330xx_InitialScale, pb0330xx_Initial}, /* 13 */ -/* or {pb03303x_InitialScale, pb03303x_Initial}, */ - {PO2030_mode0, PO2030_mode1}, /* 14 */ - {tas5130CK_InitialScale, tas5130CK_Initial}, /* 15 */ - {tas5130cxx_Initial, tas5130cxx_InitialScale}, /* 16 */ + {mi0360soc_Initial, mi0360soc_InitialScale}, /* 9 */ + {OV7620_mode0, OV7620_mode1}, /* 10 */ + {ov7630c_InitialScale, ov7630c_Initial}, /* 11 */ + {pas106b_InitialScale, pas106b_Initial}, /* 12 */ + {pas202b_Initial, pas202b_InitialScale}, /* 13 */ + {pb0330_Initial, pb0330_InitialScale}, /* 14 */ + {PO2030_mode0, PO2030_mode1}, /* 15 */ + {tas5130CK_InitialScale, tas5130CK_Initial}, /* 16 */ + {tas5130cxx_Initial, tas5130cxx_InitialScale}, /* 17 */ {tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial}, - /* 17 */ + /* 18 */ }; /* create the JPEG header */ @@ -6997,19 +6858,6 @@ static int sd_start(struct gspca_dev *gspca_dev) case SENSOR_PAS106: usb_exchange(gspca_dev, pas106b_Initial_com); break; - case SENSOR_PB0330: - if (mode) { - if (sd->chip_revision == 0xc001 - || sd->chip_revision == 0xe001 - || sd->chip_revision == 0x8001) - zc3_init = pb03303x_Initial; - } else { - if (sd->chip_revision == 0xc001 - || sd->chip_revision == 0xe001 - || sd->chip_revision == 0x8001) - zc3_init = pb03303x_InitialScale; - } - break; } usb_exchange(gspca_dev, zc3_init); @@ -7051,7 +6899,6 @@ static int sd_start(struct gspca_dev *gspca_dev) switch (sd->sensor) { case SENSOR_CS2102K: /* gamma set in xxx_Initial */ case SENSOR_HDCS2020b: - case SENSOR_PB0330: /* pb with chip_revision - see above */ case SENSOR_OV7630C: case SENSOR_TAS5130CK: break; -- cgit v1.2.3-70-g09d2 From 4f7309e27865b88df7b0b0ad59e0376dba1806af Mon Sep 17 00:00:00 2001 From: Marton Nemeth Date: Thu, 5 Nov 2009 05:35:08 -0300 Subject: V4L/DVB (13324): gspca - pac7302/pac7311: Handle return value of usb_control_msg(). The function usb_control_msg() can return error any time so at least warn the user if an error happens. No message is printed in case of normal operation. Signed-off-by: Marton Nemeth Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac7302.c | 24 +++++++++++++++++++++--- drivers/media/video/gspca/pac7311.c | 24 +++++++++++++++++++++--- 2 files changed, 42 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index 228b414709f..60d1a31f530 100644 --- a/drivers/media/video/gspca/pac7302.c +++ b/drivers/media/video/gspca/pac7302.c @@ -335,14 +335,20 @@ static void reg_w_buf(struct gspca_dev *gspca_dev, __u8 index, const char *buffer, int len) { + int ret; + memcpy(gspca_dev->usb_buf, buffer, len); - usb_control_msg(gspca_dev->dev, + ret = usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), 1, /* request */ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ index, gspca_dev->usb_buf, len, 500); + if (ret < 0) + PDEBUG(D_ERR, "reg_w_buf(): " + "Failed to write registers to index 0x%x, error %i", + index, ret); } @@ -350,13 +356,19 @@ static void reg_w(struct gspca_dev *gspca_dev, __u8 index, __u8 value) { + int ret; + gspca_dev->usb_buf[0] = value; - usb_control_msg(gspca_dev->dev, + ret = usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), 0, /* request */ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, index, gspca_dev->usb_buf, 1, 500); + if (ret < 0) + PDEBUG(D_ERR, "reg_w(): " + "Failed to write register to index 0x%x, value 0x%x, error %i", + index, value, ret); } static void reg_w_seq(struct gspca_dev *gspca_dev, @@ -373,17 +385,23 @@ static void reg_w_page(struct gspca_dev *gspca_dev, const __u8 *page, int len) { int index; + int ret; for (index = 0; index < len; index++) { if (page[index] == SKIP) /* skip this index */ continue; gspca_dev->usb_buf[0] = page[index]; - usb_control_msg(gspca_dev->dev, + ret = usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), 0, /* request */ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, index, gspca_dev->usb_buf, 1, 500); + if (ret < 0) + PDEBUG(D_ERR, "reg_w_page(): " + "Failed to write register to index 0x%x, " + "value 0x%x, error %i", + index, page[index], ret); } } diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index a2f788468ec..82cdd43aada 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -263,14 +263,20 @@ static void reg_w_buf(struct gspca_dev *gspca_dev, __u8 index, const char *buffer, int len) { + int ret; + memcpy(gspca_dev->usb_buf, buffer, len); - usb_control_msg(gspca_dev->dev, + ret = usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), 1, /* request */ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ index, gspca_dev->usb_buf, len, 500); + if (ret < 0) + PDEBUG(D_ERR, "reg_w_buf(): " + "Failed to write registers to index 0x%x, error %i", + index, ret); } @@ -278,13 +284,19 @@ static void reg_w(struct gspca_dev *gspca_dev, __u8 index, __u8 value) { + int ret; + gspca_dev->usb_buf[0] = value; - usb_control_msg(gspca_dev->dev, + ret = usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), 0, /* request */ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, index, gspca_dev->usb_buf, 1, 500); + if (ret < 0) + PDEBUG(D_ERR, "reg_w(): " + "Failed to write register to index 0x%x, value 0x%x, error %i", + index, value, ret); } static void reg_w_seq(struct gspca_dev *gspca_dev, @@ -301,17 +313,23 @@ static void reg_w_page(struct gspca_dev *gspca_dev, const __u8 *page, int len) { int index; + int ret; for (index = 0; index < len; index++) { if (page[index] == SKIP) /* skip this index */ continue; gspca_dev->usb_buf[0] = page[index]; - usb_control_msg(gspca_dev->dev, + ret = usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), 0, /* request */ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, index, gspca_dev->usb_buf, 1, 500); + if (ret < 0) + PDEBUG(D_ERR, "reg_w_page(): " + "Failed to write register to index 0x%x, " + "value 0x%x, error %i", + index, page[index], ret); } } -- cgit v1.2.3-70-g09d2 From 8337fc3053f4189fb64d60495ed89df5befa2a6b Mon Sep 17 00:00:00 2001 From: Marton Nemeth Date: Thu, 5 Nov 2009 05:40:46 -0300 Subject: V4L/DVB (13325): gspca - pac7302/pac7311: Fix buffer overrun. The reg_w_seq() function expects the sequence length in entries and not in bytes. One entry in init_7302 and init_7311 is two bytes and not one. Signed-off-by: Marton Nemeth Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac7302.c | 2 +- drivers/media/video/gspca/pac7311.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index 60d1a31f530..09d3d191d94 100644 --- a/drivers/media/video/gspca/pac7302.c +++ b/drivers/media/video/gspca/pac7302.c @@ -571,7 +571,7 @@ static void sethvflip(struct gspca_dev *gspca_dev) /* this function is called at probe and resume time for pac7302 */ static int sd_init(struct gspca_dev *gspca_dev) { - reg_w_seq(gspca_dev, init_7302, sizeof init_7302); + reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2); return 0; } diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 82cdd43aada..b1127d94897 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -469,7 +469,7 @@ static void sethvflip(struct gspca_dev *gspca_dev) /* this function is called at probe and resume time for pac7311 */ static int sd_init(struct gspca_dev *gspca_dev) { - reg_w_seq(gspca_dev, init_7311, sizeof init_7311); + reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2); return 0; } -- cgit v1.2.3-70-g09d2 From fc099f0e0e52a349a3fe92bfb8d3fb6ec5378174 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 7 Nov 2009 14:51:01 -0300 Subject: V4L/DVB (13327): em28xx: fix alt modprobe parameter It seems that some patch broke alt modprobe parameter. Fix it to allow changing alternate interfaces during module load and at runtime. If changed during runtime, you'll need to stop a and restart stream for the parameter to be used. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-core.c | 13 ++++++++++++- drivers/media/video/em28xx/em28xx.h | 3 --- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index a88257a7d94..33586004eb4 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -50,7 +50,7 @@ MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]"); printk(KERN_INFO "%s %s :"fmt, \ dev->name, __func__ , ##arg); } while (0) -static int alt = EM28XX_PINOUT; +static int alt; module_param(alt, int, 0644); MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); @@ -778,6 +778,16 @@ int em28xx_set_alternate(struct em28xx *dev) int i; unsigned int min_pkt_size = dev->width * 2 + 4; + /* + * alt = 0 is used only for control messages, so, only values + * greater than 0 can be used for streaming. + */ + if (alt && alt < dev->num_alt) { + em28xx_coredbg("alternate forced to %d\n", dev->alt); + dev->alt = alt; + goto set_alt; + } + /* When image size is bigger than a certain value, the frame size should be increased, otherwise, only green screen will be received. @@ -798,6 +808,7 @@ int em28xx_set_alternate(struct em28xx *dev) dev->alt = i; } +set_alt: if (dev->alt != prev_alt) { em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n", min_pkt_size, dev->alt); diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index a476f7bb7bf..bca5cbb7931 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -143,9 +143,6 @@ */ #define EM28XX_NUM_PACKETS 40 -/* default alternate; 0 means choose the best */ -#define EM28XX_PINOUT 0 - #define EM28XX_INTERLACED_DEFAULT 1 /* -- cgit v1.2.3-70-g09d2 From f57b17c3956f2e1e70f63dd2ed8088b582f3915e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 12 Nov 2009 11:21:05 -0300 Subject: V4L/DVB (13328): em28xx: Add chip ID for em2800 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-cards.c | 3 +++ drivers/media/video/em28xx/em28xx-reg.h | 1 + 2 files changed, 4 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 1e193707073..00bceb865a7 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -2532,6 +2532,9 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, dev->chip_id = retval; switch (dev->chip_id) { + case CHIP_ID_EM2800: + em28xx_info("chip ID is em2800\n"); + break; case CHIP_ID_EM2710: em28xx_info("chip ID is em2710\n"); break; diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h index ed12e7ffcbd..058ac87639c 100644 --- a/drivers/media/video/em28xx/em28xx-reg.h +++ b/drivers/media/video/em28xx/em28xx-reg.h @@ -192,6 +192,7 @@ /* FIXME: Need to be populated with the other chip ID's */ enum em28xx_chip_id { + CHIP_ID_EM2800 = 7, CHIP_ID_EM2710 = 17, CHIP_ID_EM2820 = 18, /* Also used by some em2710 */ CHIP_ID_EM2840 = 20, -- cgit v1.2.3-70-g09d2 From af5c8e1523edf792f57ec938aef9423783af25e1 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Tue, 27 Oct 2009 23:33:21 -0300 Subject: V4L/DVB (13329): s5h1409: provide HVR-1600 specific optimizations Perform some optimization of the register configuration based on a trace of the HVR-1600 Windows i2c traffic (and consultation with Steven Toth). Note that some of these values may be able to be moved into the common driver, but I am holding off on that until they can be tested with other boards. This work was sponsored by ONELAN Limited. Cc: Steven Toth Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/s5h1409.c | 15 +++++++++++++++ drivers/media/dvb/frontends/s5h1409.h | 7 +++++++ drivers/media/video/cx18/cx18-dvb.c | 3 ++- 3 files changed, 24 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c index fb301151842..85fba581c5a 100644 --- a/drivers/media/dvb/frontends/s5h1409.c +++ b/drivers/media/dvb/frontends/s5h1409.c @@ -614,6 +614,21 @@ static int s5h1409_init(struct dvb_frontend *fe) /* The datasheet says that after initialisation, VSB is default */ state->current_modulation = VSB_8; + /* Optimize for the HVR-1600 if appropriate. Note that some of these + may get folded into the generic case after testing with other + devices */ + if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) { + /* VSB AGC REF */ + s5h1409_writereg(state, 0x09, 0x0050); + + /* Unknown but Windows driver does it... */ + s5h1409_writereg(state, 0x21, 0x0001); + s5h1409_writereg(state, 0x50, 0x030e); + + /* QAM AGC REF */ + s5h1409_writereg(state, 0x82, 0x0800); + } + if (state->config->output_mode == S5H1409_SERIAL_OUTPUT) s5h1409_writereg(state, 0xab, s5h1409_readreg(state, 0xab) | 0x100); /* Serial */ diff --git a/drivers/media/dvb/frontends/s5h1409.h b/drivers/media/dvb/frontends/s5h1409.h index 070d9743e33..91f2ebd1a53 100644 --- a/drivers/media/dvb/frontends/s5h1409.h +++ b/drivers/media/dvb/frontends/s5h1409.h @@ -57,6 +57,13 @@ struct s5h1409_config { #define S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2 #define S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3 u16 mpeg_timing; + + /* HVR-1600 optimizations (to better work with MXL5005s) + Note: some of these are likely to be folded into the generic driver + after being regression tested with other boards */ +#define S5H1409_HVR1600_NOOPTIMIZE 0 +#define S5H1409_HVR1600_OPTIMIZE 1 + u8 hvr1600_opt; }; #if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) \ diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c index 51a0c33b25b..f402e798e32 100644 --- a/drivers/media/video/cx18/cx18-dvb.c +++ b/drivers/media/video/cx18/cx18-dvb.c @@ -71,7 +71,8 @@ static struct s5h1409_config hauppauge_hvr1600_config = { .qam_if = 44000, .inversion = S5H1409_INVERSION_OFF, .status_mode = S5H1409_DEMODLOCKING, - .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK + .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, + .hvr1600_opt = S5H1409_HVR1600_OPTIMIZE }; /* -- cgit v1.2.3-70-g09d2 From f0cd44b4a1a7465230dfbe1e645d9dc73f83cb13 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 28 Oct 2009 01:26:05 -0300 Subject: V4L/DVB (13330): s5h1409: properly handle QAM optimization after lock achieved The sh51409 driver was only doing the QAM optimization a single time, and it would only occur if you received a lock instantaneously after the tuning request. Restructure the code so that the optimization occurs once you reach a signal lock. Note that this depends on the caller polling for status, but we don't have much choice at this point without an independent thread monitoring the lock status. Also, at this point pretty much every application polls for status lock after doing the tune, so the likelihood of the optimization not occurring in the real world is pretty low. The state machine has also been reworked such that setting the interleave mode is now a dependency of doing the QAM optimization. Before both were mutually exclusive, which was not consistent with the Windows driver. We now have a single state machine that controls both. The changes as-is are only enabled for the HVR-1600. Once the changes are tested with some of the other boards, this change should be made generic and the "_legacy" functions should be removed. This work was sponsored by ONELAN Limited. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/s5h1409.c | 136 ++++++++++++++++++++++++++++++++-- 1 file changed, 128 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c index 85fba581c5a..5507159a23b 100644 --- a/drivers/media/dvb/frontends/s5h1409.c +++ b/drivers/media/dvb/frontends/s5h1409.c @@ -44,7 +44,15 @@ struct s5h1409_state { int if_freq; u32 is_qam_locked; - u32 qam_state; + + /* QAM tuning state goes through the following state transitions */ +#define QAM_STATE_UNTUNED 0 +#define QAM_STATE_TUNING_STARTED 1 +#define QAM_STATE_INTERLEAVE_SET 2 +#define QAM_STATE_QAM_OPTIMIZED_L1 3 +#define QAM_STATE_QAM_OPTIMIZED_L2 4 +#define QAM_STATE_QAM_OPTIMIZED_L3 5 + u8 qam_state; }; static int debug; @@ -347,7 +355,7 @@ static int s5h1409_softreset(struct dvb_frontend *fe) s5h1409_writereg(state, 0xf5, 0); s5h1409_writereg(state, 0xf5, 1); state->is_qam_locked = 0; - state->qam_state = 0; + state->qam_state = QAM_STATE_UNTUNED; return 0; } @@ -474,6 +482,59 @@ static void s5h1409_set_qam_amhum_mode(struct dvb_frontend *fe) struct s5h1409_state *state = fe->demodulator_priv; u16 reg; + if (state->qam_state < QAM_STATE_INTERLEAVE_SET) { + /* We should not perform amhum optimization until + the interleave mode has been configured */ + return; + } + + if (state->qam_state == QAM_STATE_QAM_OPTIMIZED_L3) { + /* We've already reached the maximum optimization level, so + dont bother banging on the status registers */ + return; + } + + /* QAM EQ lock check */ + reg = s5h1409_readreg(state, 0xf0); + + if ((reg >> 13) & 0x1) { + reg &= 0xff; + + s5h1409_writereg(state, 0x96, 0x000c); + if (reg < 0x68) { + if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L3) { + dprintk("%s() setting QAM state to OPT_L3\n", + __func__); + s5h1409_writereg(state, 0x93, 0x3130); + s5h1409_writereg(state, 0x9e, 0x2836); + state->qam_state = QAM_STATE_QAM_OPTIMIZED_L3; + } + } else { + if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L2) { + dprintk("%s() setting QAM state to OPT_L2\n", + __func__); + s5h1409_writereg(state, 0x93, 0x3332); + s5h1409_writereg(state, 0x9e, 0x2c37); + state->qam_state = QAM_STATE_QAM_OPTIMIZED_L2; + } + } + + } else { + if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L1) { + dprintk("%s() setting QAM state to OPT_L1\n", __func__); + s5h1409_writereg(state, 0x96, 0x0008); + s5h1409_writereg(state, 0x93, 0x3332); + s5h1409_writereg(state, 0x9e, 0x2c37); + state->qam_state = QAM_STATE_QAM_OPTIMIZED_L1; + } + } +} + +static void s5h1409_set_qam_amhum_mode_legacy(struct dvb_frontend *fe) +{ + struct s5h1409_state *state = fe->demodulator_priv; + u16 reg; + if (state->is_qam_locked) return; @@ -506,6 +567,46 @@ static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe) struct s5h1409_state *state = fe->demodulator_priv; u16 reg, reg1, reg2; + if (state->qam_state >= QAM_STATE_INTERLEAVE_SET) { + /* We've done the optimization already */ + return; + } + + reg = s5h1409_readreg(state, 0xf1); + + /* Master lock */ + if ((reg >> 15) & 0x1) { + if (state->qam_state == QAM_STATE_UNTUNED || + state->qam_state == QAM_STATE_TUNING_STARTED) { + dprintk("%s() setting QAM state to INTERLEAVE_SET\n", + __func__); + reg1 = s5h1409_readreg(state, 0xb2); + reg2 = s5h1409_readreg(state, 0xad); + + s5h1409_writereg(state, 0x96, 0x0020); + s5h1409_writereg(state, 0xad, + (((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff))); + s5h1409_writereg(state, 0xab, + s5h1409_readreg(state, 0xab) & 0xeffe); + state->qam_state = QAM_STATE_INTERLEAVE_SET; + } + } else { + if (state->qam_state == QAM_STATE_UNTUNED) { + dprintk("%s() setting QAM state to TUNING_STARTED\n", + __func__); + s5h1409_writereg(state, 0x96, 0x08); + s5h1409_writereg(state, 0xab, + s5h1409_readreg(state, 0xab) | 0x1001); + state->qam_state = QAM_STATE_TUNING_STARTED; + } + } +} + +static void s5h1409_set_qam_interleave_mode_legacy(struct dvb_frontend *fe) +{ + struct s5h1409_state *state = fe->demodulator_priv; + u16 reg, reg1, reg2; + reg = s5h1409_readreg(state, 0xf1); /* Master lock */ @@ -553,16 +654,24 @@ static int s5h1409_set_frontend(struct dvb_frontend *fe, fe->ops.i2c_gate_ctrl(fe, 0); } - /* Optimize the demod for QAM */ - if (p->u.vsb.modulation != VSB_8) { - s5h1409_set_qam_amhum_mode(fe); - s5h1409_set_qam_interleave_mode(fe); - } - /* Issue a reset to the demod so it knows to resync against the newly tuned frequency */ s5h1409_softreset(fe); + /* Optimize the demod for QAM */ + if (state->current_modulation != VSB_8) { + /* This almost certainly applies to all boards, but for now + only do it for the HVR-1600. Once the other boards are + tested, the "legacy" versions can just go away */ + if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) { + s5h1409_set_qam_amhum_mode(fe); + s5h1409_set_qam_interleave_mode(fe); + } else { + s5h1409_set_qam_amhum_mode_legacy(fe); + s5h1409_set_qam_interleave_mode_legacy(fe); + } + } + return 0; } @@ -656,6 +765,17 @@ static int s5h1409_read_status(struct dvb_frontend *fe, fe_status_t *status) *status = 0; + /* Optimize the demod for QAM */ + if (state->current_modulation != VSB_8) { + /* This almost certainly applies to all boards, but for now + only do it for the HVR-1600. Once the other boards are + tested, the "legacy" versions can just go away */ + if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) { + s5h1409_set_qam_amhum_mode(fe); + s5h1409_set_qam_interleave_mode(fe); + } + } + /* Get the demodulator status */ reg = s5h1409_readreg(state, 0xf1); if (reg & 0x1000) -- cgit v1.2.3-70-g09d2 From 48c511ed675772bd08044d97756f7f7aae5168eb Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 28 Oct 2009 23:10:16 -0300 Subject: V4L/DVB (13331): mxl5005s: provide ability to override QAM gain for HVR-1600 The HVR-1600 doesn't use the standard mechanism for computing the gain when in QAM mode, instead always forcing it to be 0x02. Provide the ability to override the algorithm on a per-board basis. This change results in an improvement of 0.4-0.6 dB for QAM tuning. This work was sponsored by ONELAN Limited. Cc: Steven Toth Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/mxl5005s.c | 5 ++++- drivers/media/common/tuners/mxl5005s.h | 4 ++++ drivers/media/video/cx18/cx18-dvb.c | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c index 0803dab58ff..605e28b7326 100644 --- a/drivers/media/common/tuners/mxl5005s.c +++ b/drivers/media/common/tuners/mxl5005s.c @@ -2789,7 +2789,10 @@ static u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq) /* add for 2.6.5 Special setting for QAM */ if (state->Mod_Type == MXL_QAM) { - if (state->RF_IN < 680000000) + if (state->config->qam_gain != 0) + status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, + state->config->qam_gain); + else if (state->RF_IN < 680000000) status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3); else status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2); diff --git a/drivers/media/common/tuners/mxl5005s.h b/drivers/media/common/tuners/mxl5005s.h index 7ac6815b30a..fc8a1ffc53b 100644 --- a/drivers/media/common/tuners/mxl5005s.h +++ b/drivers/media/common/tuners/mxl5005s.h @@ -108,6 +108,10 @@ struct mxl5005s_config { #define MXL_LOW_IF 1 u8 if_mode; + /* Some boards need to override the built-in logic for determining + the gain when in QAM mode (the HVR-1600 is one such case) */ + u8 qam_gain; + /* Stuff I don't know what to do with */ u8 AgcMasterByte; }; diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c index f402e798e32..54a6fd3f7af 100644 --- a/drivers/media/video/cx18/cx18-dvb.c +++ b/drivers/media/video/cx18/cx18-dvb.c @@ -61,6 +61,7 @@ static struct mxl5005s_config hauppauge_hvr1600_tuner = { .top = MXL5005S_TOP_25P2, .mod_mode = MXL_DIGITAL_MODE, .if_mode = MXL_ZERO_IF, + .qam_gain = 0x02, .AgcMasterByte = 0x00, }; -- cgit v1.2.3-70-g09d2 From adcd8de6de36f67241a5c3562f2ef1d5998b30a9 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Mon, 2 Nov 2009 01:30:40 -0300 Subject: V4L/DVB (13332): s5h1409: remove a set register that would cause lock to be lost. On particularly weak signals, changing register 0xab after setting the interleave mode will cause the FEC lock to get lost (while still holding the EQ lock). So remove the write entirely, which seems to have had no adverse effect in either of my ClearQAM environments (and in particular resolves the customer's reported issue). Also flip around the order of the amhum optimization and the interleave setup to be consistent with the windows driver, which has the side-benefit of doing them both in the same call (since the amhum optimization can only be done once the interleave setup). This work was sponsored by ONELAN Limited. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/s5h1409.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c index 5507159a23b..0e2f61a8978 100644 --- a/drivers/media/dvb/frontends/s5h1409.c +++ b/drivers/media/dvb/frontends/s5h1409.c @@ -586,8 +586,6 @@ static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe) s5h1409_writereg(state, 0x96, 0x0020); s5h1409_writereg(state, 0xad, (((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff))); - s5h1409_writereg(state, 0xab, - s5h1409_readreg(state, 0xab) & 0xeffe); state->qam_state = QAM_STATE_INTERLEAVE_SET; } } else { @@ -664,8 +662,8 @@ static int s5h1409_set_frontend(struct dvb_frontend *fe, only do it for the HVR-1600. Once the other boards are tested, the "legacy" versions can just go away */ if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) { - s5h1409_set_qam_amhum_mode(fe); s5h1409_set_qam_interleave_mode(fe); + s5h1409_set_qam_amhum_mode(fe); } else { s5h1409_set_qam_amhum_mode_legacy(fe); s5h1409_set_qam_interleave_mode_legacy(fe); @@ -771,8 +769,8 @@ static int s5h1409_read_status(struct dvb_frontend *fe, fe_status_t *status) only do it for the HVR-1600. Once the other boards are tested, the "legacy" versions can just go away */ if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) { - s5h1409_set_qam_amhum_mode(fe); s5h1409_set_qam_interleave_mode(fe); + s5h1409_set_qam_amhum_mode(fe); } } -- cgit v1.2.3-70-g09d2 From 873688cd30294412e185ba39f8487e3eed0f692d Mon Sep 17 00:00:00 2001 From: Abylay Ospan Date: Sat, 17 Oct 2009 08:23:00 -0300 Subject: V4L/DVB (13334): stv6110: add configurable gain It has positive effect for NetUP Dual DVB-S2 CI card. Signed-off-by: Abylay Ospan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv6110.c | 13 ++++--------- drivers/media/dvb/frontends/stv6110.h | 1 + drivers/media/video/cx23885/cx23885-dvb.c | 2 ++ 3 files changed, 7 insertions(+), 9 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv6110.c b/drivers/media/dvb/frontends/stv6110.c index dcf1b21ea97..bef0cc83847 100644 --- a/drivers/media/dvb/frontends/stv6110.c +++ b/drivers/media/dvb/frontends/stv6110.c @@ -37,6 +37,7 @@ struct stv6110_priv { u32 mclk; u8 clk_div; + u8 gain; u8 regs[8]; }; @@ -255,7 +256,7 @@ static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency) u8 ret = 0x04; u32 divider, ref, p, presc, i, result_freq, vco_freq; s32 p_calc, p_calc_opt = 1000, r_div, r_div_opt = 0, p_val; - s32 srate; u8 gain; + s32 srate; dprintk("%s, freq=%d kHz, mclk=%d Hz\n", __func__, frequency, priv->mclk); @@ -273,15 +274,8 @@ static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency) } else srate = 15000000; - if (srate >= 15000000) - gain = 3; /* +6 dB */ - else if (srate >= 5000000) - gain = 3; /* +6 dB */ - else - gain = 3; /* +6 dB */ - priv->regs[RSTV6110_CTRL2] &= ~0x0f; - priv->regs[RSTV6110_CTRL2] |= (gain & 0x0f); + priv->regs[RSTV6110_CTRL2] |= (priv->gain & 0x0f); if (frequency <= 1023000) { p = 1; @@ -436,6 +430,7 @@ struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe, priv->i2c = i2c; priv->mclk = config->mclk; priv->clk_div = config->clk_div; + priv->gain = config->gain; memcpy(&priv->regs, ®0[1], 8); diff --git a/drivers/media/dvb/frontends/stv6110.h b/drivers/media/dvb/frontends/stv6110.h index 9db2402410f..fe71bba6a26 100644 --- a/drivers/media/dvb/frontends/stv6110.h +++ b/drivers/media/dvb/frontends/stv6110.h @@ -41,6 +41,7 @@ struct stv6110_config { u8 i2c_address; u32 mclk; + u8 gain; u8 clk_div; /* divisor value for the output clock */ }; diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index f4f046cd81a..0180b75d1f3 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -414,12 +414,14 @@ static struct stv6110_config netup_stv6110_tunerconfig_a = { .i2c_address = 0x60, .mclk = 16000000, .clk_div = 1, + .gain = 8, /* +16 dB - maximum gain */ }; static struct stv6110_config netup_stv6110_tunerconfig_b = { .i2c_address = 0x63, .mclk = 16000000, .clk_div = 1, + .gain = 8, /* +16 dB - maximum gain */ }; static int tbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -- cgit v1.2.3-70-g09d2 From 9329fb5b731cd535a7c7d0690d30e872f29a33d3 Mon Sep 17 00:00:00 2001 From: Abylay Ospan Date: Sat, 17 Oct 2009 08:38:45 -0300 Subject: V4L/DVB (13335): stv0900: fix diseqc support for NetUP card Signed-off-by: Abylay Ospan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0900_core.c | 31 +++++++++++++++++++----------- drivers/media/video/cx23885/cx23885-dvb.c | 8 ++++---- 2 files changed, 24 insertions(+), 15 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c index 768a1611e8c..4729be7fdf7 100644 --- a/drivers/media/dvb/frontends/stv0900_core.c +++ b/drivers/media/dvb/frontends/stv0900_core.c @@ -1771,7 +1771,6 @@ static int stv0900_diseqc_send(struct stv0900_internal *i_params , u8 *Data, msleep(10); i++; } - break; } @@ -1795,19 +1794,20 @@ static int stv0900_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) struct stv0900_internal *i_params = state->internal; enum fe_stv0900_demod_num demod = state->demod; s32 mode_field; - u32 diseqc_fifo; + u8 data; dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE); - dmd_reg(diseqc_fifo, R0900_P1_DISTXDATA, R0900_P2_DISTXDATA); switch (burst) { case SEC_MINI_A: stv0900_write_bits(i_params, mode_field, 3);/* Unmodulated */ - stv0900_write_reg(i_params, diseqc_fifo, 0x00); + data = 0x00; + stv0900_diseqc_send(state->internal, &data, 1, state->demod); break; case SEC_MINI_B: stv0900_write_bits(i_params, mode_field, 2);/* Modulated */ - stv0900_write_reg(i_params, diseqc_fifo, 0xff); + data = 0xff; + stv0900_diseqc_send(state->internal, &data, 1, state->demod); break; } @@ -1858,28 +1858,37 @@ static int stv0900_recv_slave_reply(struct dvb_frontend *fe, return 0; } -static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t toneoff) { struct stv0900_state *state = fe->demodulator_priv; struct stv0900_internal *i_params = state->internal; enum fe_stv0900_demod_num demod = state->demod; s32 mode_field, reset_field; - dprintk("%s: %s\n", __func__, ((tone == 0) ? "Off" : "On")); + dprintk("%s: %s\n", __func__, ((toneoff == 0) ? "On" : "Off")); dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE); dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET); - if (tone) { - /*Set the DiseqC mode to 22Khz continues tone*/ + switch (toneoff) { + case SEC_TONE_ON: + /*Set the DiseqC mode to 22Khz _continues_ tone*/ stv0900_write_bits(i_params, mode_field, 0); stv0900_write_bits(i_params, reset_field, 1); /*release DiseqC reset to enable the 22KHz tone*/ stv0900_write_bits(i_params, reset_field, 0); - } else { - stv0900_write_bits(i_params, mode_field, 0); + break; + case SEC_TONE_OFF: + /*return diseqc mode to config->diseqc_mode. + Usually it's without _continues_ tone */ + stv0900_write_bits(i_params, mode_field, + state->config->diseqc_mode); /*maintain the DiseqC reset to disable the 22KHz tone*/ stv0900_write_bits(i_params, reset_field, 1); + stv0900_write_bits(i_params, reset_field, 0); + break; + default: + return -EINVAL; } return 0; diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 0180b75d1f3..305f4710b5e 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -839,8 +839,8 @@ static int dvb_register(struct cx23885_tsport *port) if (!dvb_attach(lnbh24_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, - LNBH24_PCL, - LNBH24_TTX, 0x09)) + LNBH24_PCL | LNBH24_TTX, + LNBH24_TEN, 0x09)) printk(KERN_ERR "No LNBH24 found!\n"); @@ -860,8 +860,8 @@ static int dvb_register(struct cx23885_tsport *port) if (!dvb_attach(lnbh24_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, - LNBH24_PCL, - LNBH24_TTX, 0x0a)) + LNBH24_PCL | LNBH24_TTX, + LNBH24_TEN, 0x0a)) printk(KERN_ERR "No LNBH24 found!\n"); -- cgit v1.2.3-70-g09d2 From 29372a8daec4c1dca83e294006488b1d47dd965c Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Sat, 17 Oct 2009 08:58:26 -0300 Subject: V4L/DVB (13336): stv0900: config definition for single/dual mode Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0900.h | 1 + drivers/media/dvb/frontends/stv0900_core.c | 4 ++-- drivers/media/video/cx23885/cx23885-dvb.c | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv0900.h b/drivers/media/dvb/frontends/stv0900.h index bf4e9b63304..446bdfc8ad1 100644 --- a/drivers/media/dvb/frontends/stv0900.h +++ b/drivers/media/dvb/frontends/stv0900.h @@ -36,6 +36,7 @@ struct stv0900_reg { struct stv0900_config { u8 demod_address; + u8 demod_mode; u32 xtal; u8 clkmode;/* 0 for CLKI, 2 for XTALI */ diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c index 4729be7fdf7..c8c72f56fdd 100644 --- a/drivers/media/dvb/frontends/stv0900_core.c +++ b/drivers/media/dvb/frontends/stv0900_core.c @@ -1400,7 +1400,7 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe, dprintk("%s\n", __func__); - if (temp_int != NULL) { + if ((temp_int != NULL) && (p_init->demod_mode == STV0900_DUAL)) { state->internal = temp_int->internal; (state->internal->dmds_used)++; dprintk("%s: Find Internal Structure!\n", __func__); @@ -1972,7 +1972,7 @@ struct dvb_frontend *stv0900_attach(const struct stv0900_config *config, case 0: case 1: init_params.dmd_ref_clk = config->xtal; - init_params.demod_mode = STV0900_DUAL; + init_params.demod_mode = config->demod_mode; init_params.rolloff = STV0900_35; init_params.path1_ts_clock = config->path1_mode; init_params.tun1_maddress = config->tun1_maddress; diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 305f4710b5e..44e5fade048 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -400,6 +400,7 @@ static struct stv0900_reg stv0900_ts_regs[] = { static struct stv0900_config netup_stv0900_config = { .demod_address = 0x68, + .demod_mode = 1, /* dual */ .xtal = 8000000, .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */ .diseqc_mode = 2,/* 2/3 PWM */ -- cgit v1.2.3-70-g09d2 From 502cd96d5b0714e0ab022766014f58b0684699a8 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Tue, 27 Oct 2009 14:59:53 -0300 Subject: V4L/DVB (13337): Change str snr scale for stv0900/903 and Netup Dual DVB-S2 card. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0900_core.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c index c8c72f56fdd..11dbe942aa4 100644 --- a/drivers/media/dvb/frontends/stv0900_core.c +++ b/drivers/media/dvb/frontends/stv0900_core.c @@ -599,6 +599,8 @@ static s32 stv0900_get_rf_level(struct stv0900_internal *i_params, break; } + dprintk("%s: AGC Gain = 0x%x\n", __func__, agc_gain); + imin = 0; imax = lookup->size - 1; if (INRANGE(lookup->table[imin].regval, agc_gain, lookup->table[imax].regval)) { @@ -634,7 +636,14 @@ static int stv0900_read_signal_strength(struct dvb_frontend *fe, u16 *strength) s32 rflevel = stv0900_get_rf_level(internal, &stv0900_rf, state->demod); - *strength = (rflevel + 100) * (16383 / 105); + rflevel = (rflevel + 100) * (65535 / 70); + if (rflevel < 0) + rflevel = 0; + + if (rflevel > 65535) + rflevel = 65535; + + *strength = rflevel; return 0; } @@ -709,6 +718,8 @@ static s32 stv0900_carr_get_quality(struct dvb_frontend *fe, } } + dprintk("%s: Quality = %d\n", __func__, c_n); + return c_n; } @@ -752,10 +763,16 @@ static int stv0900_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks) static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr) { - *snr = stv0900_carr_get_quality(fe, + s32 snrlcl = stv0900_carr_get_quality(fe, (const struct stv0900_table *)&stv0900_s2_cn); - *snr += 30; - *snr *= (16383 / 1030); + snrlcl = (snrlcl + 30) * 384; + if (snrlcl < 0) + snrlcl = 0; + + if (snrlcl > 65535) + snrlcl = 65535; + + *snr = snrlcl; return 0; } -- cgit v1.2.3-70-g09d2 From 46960eea9c0f7abb3a0a65276939762b97eac337 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Fri, 6 Nov 2009 23:07:56 -0300 Subject: V4L/DVB (13338): stv0900: big rework to support cut 3.0. Patch 1 of 4. Also patch changes logic to prevent code repetitions and big indents. It makes checkpatch silent :) Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0900_init.h | 257 ++++++++++++++++++++++------- drivers/media/dvb/frontends/stv0900_priv.h | 81 +++------ 2 files changed, 224 insertions(+), 114 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv0900_init.h b/drivers/media/dvb/frontends/stv0900_init.h index ff388b47a4e..b684df9995d 100644 --- a/drivers/media/dvb/frontends/stv0900_init.h +++ b/drivers/media/dvb/frontends/stv0900_init.h @@ -141,85 +141,228 @@ struct stv0900_short_frames_car_loop_optim { }; +struct stv0900_short_frames_car_loop_optim_vs_mod { + enum fe_stv0900_modulation modulation; + u8 car_loop_2; /* SR<3msps */ + u8 car_loop_5; /* 3 Date: Fri, 6 Nov 2009 23:23:29 -0300 Subject: V4L/DVB (13339): stv0900: big rework to support cut 3.0. Patch 2 of 4. Also patch changes logic to prevent code repetitions and big indents. It makes checkpatch silent :) Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0900_reg.h | 5000 +++++++++++++++-------------- 1 file changed, 2594 insertions(+), 2406 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv0900_reg.h b/drivers/media/dvb/frontends/stv0900_reg.h index 264f9cf9a17..7b8edf192e9 100644 --- a/drivers/media/dvb/frontends/stv0900_reg.h +++ b/drivers/media/dvb/frontends/stv0900_reg.h @@ -14,7 +14,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * @@ -26,3762 +26,3950 @@ #ifndef STV0900_REG_H #define STV0900_REG_H +extern s32 shiftx(s32 x, int demod, s32 shift); + +#define REGx(x) shiftx(x, demod, 0x200) +#define FLDx(x) shiftx(x, demod, 0x2000000) + /*MID*/ -#define R0900_MID 0xf100 -#define F0900_MCHIP_IDENT 0xf10000f0 -#define F0900_MRELEASE 0xf100000f +#define R0900_MID 0xf100 +#define F0900_MCHIP_IDENT 0xf10000f0 +#define F0900_MRELEASE 0xf100000f /*DACR1*/ -#define R0900_DACR1 0xf113 -#define F0900_DAC_MODE 0xf11300e0 -#define F0900_DAC_VALUE1 0xf113000f +#define R0900_DACR1 0xf113 +#define F0900_DAC_MODE 0xf11300e0 +#define F0900_DAC_VALUE1 0xf113000f /*DACR2*/ -#define R0900_DACR2 0xf114 -#define F0900_DAC_VALUE0 0xf11400ff +#define R0900_DACR2 0xf114 +#define F0900_DAC_VALUE0 0xf11400ff /*OUTCFG*/ -#define R0900_OUTCFG 0xf11c -#define F0900_INV_DATA6 0xf11c0080 -#define F0900_OUTSERRS1_HZ 0xf11c0040 -#define F0900_OUTSERRS2_HZ 0xf11c0020 -#define F0900_OUTSERRS3_HZ 0xf11c0010 -#define F0900_OUTPARRS3_HZ 0xf11c0008 -#define F0900_OUTHZ3_CONTROL 0xf11c0007 - -/*MODECFG*/ -#define R0900_MODECFG 0xf11d -#define F0900_FECSPY_SEL_2 0xf11d0020 -#define F0900_HWARE_SEL_2 0xf11d0010 -#define F0900_PKTDEL_SEL_2 0xf11d0008 -#define F0900_DISEQC_SEL_2 0xf11d0004 -#define F0900_VIT_SEL_2 0xf11d0002 -#define F0900_DEMOD_SEL_2 0xf11d0001 +#define R0900_OUTCFG 0xf11c +#define F0900_OUTSERRS1_HZ 0xf11c0040 +#define F0900_OUTSERRS2_HZ 0xf11c0020 +#define F0900_OUTSERRS3_HZ 0xf11c0010 +#define F0900_OUTPARRS3_HZ 0xf11c0008 /*IRQSTATUS3*/ -#define R0900_IRQSTATUS3 0xf120 -#define F0900_SPLL_LOCK 0xf1200020 -#define F0900_SSTREAM_LCK_3 0xf1200010 -#define F0900_SSTREAM_LCK_2 0xf1200008 -#define F0900_SSTREAM_LCK_1 0xf1200004 -#define F0900_SDVBS1_PRF_2 0xf1200002 -#define F0900_SDVBS1_PRF_1 0xf1200001 +#define R0900_IRQSTATUS3 0xf120 +#define F0900_SPLL_LOCK 0xf1200020 +#define F0900_SSTREAM_LCK_3 0xf1200010 +#define F0900_SSTREAM_LCK_2 0xf1200008 +#define F0900_SSTREAM_LCK_1 0xf1200004 +#define F0900_SDVBS1_PRF_2 0xf1200002 +#define F0900_SDVBS1_PRF_1 0xf1200001 /*IRQSTATUS2*/ -#define R0900_IRQSTATUS2 0xf121 -#define F0900_SSPY_ENDSIM_3 0xf1210080 -#define F0900_SSPY_ENDSIM_2 0xf1210040 -#define F0900_SSPY_ENDSIM_1 0xf1210020 -#define F0900_SPKTDEL_ERROR_2 0xf1210010 -#define F0900_SPKTDEL_LOCKB_2 0xf1210008 -#define F0900_SPKTDEL_LOCK_2 0xf1210004 -#define F0900_SPKTDEL_ERROR_1 0xf1210002 -#define F0900_SPKTDEL_LOCKB_1 0xf1210001 +#define R0900_IRQSTATUS2 0xf121 +#define F0900_SSPY_ENDSIM_3 0xf1210080 +#define F0900_SSPY_ENDSIM_2 0xf1210040 +#define F0900_SSPY_ENDSIM_1 0xf1210020 +#define F0900_SPKTDEL_ERROR_2 0xf1210010 +#define F0900_SPKTDEL_LOCKB_2 0xf1210008 +#define F0900_SPKTDEL_LOCK_2 0xf1210004 +#define F0900_SPKTDEL_ERROR_1 0xf1210002 +#define F0900_SPKTDEL_LOCKB_1 0xf1210001 /*IRQSTATUS1*/ -#define R0900_IRQSTATUS1 0xf122 -#define F0900_SPKTDEL_LOCK_1 0xf1220080 -#define F0900_SEXTPINB2 0xf1220040 -#define F0900_SEXTPIN2 0xf1220020 -#define F0900_SEXTPINB1 0xf1220010 -#define F0900_SEXTPIN1 0xf1220008 -#define F0900_SDEMOD_LOCKB_2 0xf1220004 -#define F0900_SDEMOD_LOCK_2 0xf1220002 -#define F0900_SDEMOD_IRQ_2 0xf1220001 +#define R0900_IRQSTATUS1 0xf122 +#define F0900_SPKTDEL_LOCK_1 0xf1220080 +#define F0900_SDEMOD_LOCKB_2 0xf1220004 +#define F0900_SDEMOD_LOCK_2 0xf1220002 +#define F0900_SDEMOD_IRQ_2 0xf1220001 /*IRQSTATUS0*/ -#define R0900_IRQSTATUS0 0xf123 -#define F0900_SDEMOD_LOCKB_1 0xf1230080 -#define F0900_SDEMOD_LOCK_1 0xf1230040 -#define F0900_SDEMOD_IRQ_1 0xf1230020 -#define F0900_SBCH_ERRFLAG 0xf1230010 -#define F0900_SDISEQC2RX_IRQ 0xf1230008 -#define F0900_SDISEQC2TX_IRQ 0xf1230004 -#define F0900_SDISEQC1RX_IRQ 0xf1230002 -#define F0900_SDISEQC1TX_IRQ 0xf1230001 +#define R0900_IRQSTATUS0 0xf123 +#define F0900_SDEMOD_LOCKB_1 0xf1230080 +#define F0900_SDEMOD_LOCK_1 0xf1230040 +#define F0900_SDEMOD_IRQ_1 0xf1230020 +#define F0900_SBCH_ERRFLAG 0xf1230010 +#define F0900_SDISEQC2RX_IRQ 0xf1230008 +#define F0900_SDISEQC2TX_IRQ 0xf1230004 +#define F0900_SDISEQC1RX_IRQ 0xf1230002 +#define F0900_SDISEQC1TX_IRQ 0xf1230001 /*IRQMASK3*/ -#define R0900_IRQMASK3 0xf124 -#define F0900_MPLL_LOCK 0xf1240020 -#define F0900_MSTREAM_LCK_3 0xf1240010 -#define F0900_MSTREAM_LCK_2 0xf1240008 -#define F0900_MSTREAM_LCK_1 0xf1240004 -#define F0900_MDVBS1_PRF_2 0xf1240002 -#define F0900_MDVBS1_PRF_1 0xf1240001 +#define R0900_IRQMASK3 0xf124 +#define F0900_MPLL_LOCK 0xf1240020 +#define F0900_MSTREAM_LCK_3 0xf1240010 +#define F0900_MSTREAM_LCK_2 0xf1240008 +#define F0900_MSTREAM_LCK_1 0xf1240004 +#define F0900_MDVBS1_PRF_2 0xf1240002 +#define F0900_MDVBS1_PRF_1 0xf1240001 /*IRQMASK2*/ -#define R0900_IRQMASK2 0xf125 -#define F0900_MSPY_ENDSIM_3 0xf1250080 -#define F0900_MSPY_ENDSIM_2 0xf1250040 -#define F0900_MSPY_ENDSIM_1 0xf1250020 -#define F0900_MPKTDEL_ERROR_2 0xf1250010 -#define F0900_MPKTDEL_LOCKB_2 0xf1250008 -#define F0900_MPKTDEL_LOCK_2 0xf1250004 -#define F0900_MPKTDEL_ERROR_1 0xf1250002 -#define F0900_MPKTDEL_LOCKB_1 0xf1250001 +#define R0900_IRQMASK2 0xf125 +#define F0900_MSPY_ENDSIM_3 0xf1250080 +#define F0900_MSPY_ENDSIM_2 0xf1250040 +#define F0900_MSPY_ENDSIM_1 0xf1250020 +#define F0900_MPKTDEL_ERROR_2 0xf1250010 +#define F0900_MPKTDEL_LOCKB_2 0xf1250008 +#define F0900_MPKTDEL_LOCK_2 0xf1250004 +#define F0900_MPKTDEL_ERROR_1 0xf1250002 +#define F0900_MPKTDEL_LOCKB_1 0xf1250001 /*IRQMASK1*/ -#define R0900_IRQMASK1 0xf126 -#define F0900_MPKTDEL_LOCK_1 0xf1260080 -#define F0900_MEXTPINB2 0xf1260040 -#define F0900_MEXTPIN2 0xf1260020 -#define F0900_MEXTPINB1 0xf1260010 -#define F0900_MEXTPIN1 0xf1260008 -#define F0900_MDEMOD_LOCKB_2 0xf1260004 -#define F0900_MDEMOD_LOCK_2 0xf1260002 -#define F0900_MDEMOD_IRQ_2 0xf1260001 +#define R0900_IRQMASK1 0xf126 +#define F0900_MPKTDEL_LOCK_1 0xf1260080 +#define F0900_MEXTPINB2 0xf1260040 +#define F0900_MEXTPIN2 0xf1260020 +#define F0900_MEXTPINB1 0xf1260010 +#define F0900_MEXTPIN1 0xf1260008 +#define F0900_MDEMOD_LOCKB_2 0xf1260004 +#define F0900_MDEMOD_LOCK_2 0xf1260002 +#define F0900_MDEMOD_IRQ_2 0xf1260001 /*IRQMASK0*/ -#define R0900_IRQMASK0 0xf127 -#define F0900_MDEMOD_LOCKB_1 0xf1270080 -#define F0900_MDEMOD_LOCK_1 0xf1270040 -#define F0900_MDEMOD_IRQ_1 0xf1270020 -#define F0900_MBCH_ERRFLAG 0xf1270010 -#define F0900_MDISEQC2RX_IRQ 0xf1270008 -#define F0900_MDISEQC2TX_IRQ 0xf1270004 -#define F0900_MDISEQC1RX_IRQ 0xf1270002 -#define F0900_MDISEQC1TX_IRQ 0xf1270001 +#define R0900_IRQMASK0 0xf127 +#define F0900_MDEMOD_LOCKB_1 0xf1270080 +#define F0900_MDEMOD_LOCK_1 0xf1270040 +#define F0900_MDEMOD_IRQ_1 0xf1270020 +#define F0900_MBCH_ERRFLAG 0xf1270010 +#define F0900_MDISEQC2RX_IRQ 0xf1270008 +#define F0900_MDISEQC2TX_IRQ 0xf1270004 +#define F0900_MDISEQC1RX_IRQ 0xf1270002 +#define F0900_MDISEQC1TX_IRQ 0xf1270001 /*I2CCFG*/ -#define R0900_I2CCFG 0xf129 -#define F0900_I2C2_FASTMODE 0xf1290080 -#define F0900_STATUS_WR2 0xf1290040 -#define F0900_I2C2ADDR_INC 0xf1290030 -#define F0900_I2C_FASTMODE 0xf1290008 -#define F0900_STATUS_WR 0xf1290004 -#define F0900_I2CADDR_INC 0xf1290003 +#define R0900_I2CCFG 0xf129 +#define F0900_I2C_FASTMODE 0xf1290008 +#define F0900_I2CADDR_INC 0xf1290003 /*P1_I2CRPT*/ -#define R0900_P1_I2CRPT 0xf12a -#define F0900_P1_I2CT_ON 0xf12a0080 -#define F0900_P1_ENARPT_LEVEL 0xf12a0070 -#define F0900_P1_SCLT_DELAY 0xf12a0008 -#define F0900_P1_STOP_ENABLE 0xf12a0004 -#define F0900_P1_STOP_SDAT2SDA 0xf12a0002 +#define R0900_P1_I2CRPT 0xf12a +#define I2CRPT shiftx(R0900_P1_I2CRPT, demod, -1) +#define F0900_P1_I2CT_ON 0xf12a0080 +#define I2CT_ON shiftx(F0900_P1_I2CT_ON, demod, -0x10000) +#define F0900_P1_ENARPT_LEVEL 0xf12a0070 +#define F0900_P1_SCLT_DELAY 0xf12a0008 +#define F0900_P1_STOP_ENABLE 0xf12a0004 +#define F0900_P1_STOP_SDAT2SDA 0xf12a0002 /*P2_I2CRPT*/ -#define R0900_P2_I2CRPT 0xf12b -#define F0900_P2_I2CT_ON 0xf12b0080 -#define F0900_P2_ENARPT_LEVEL 0xf12b0070 -#define F0900_P2_SCLT_DELAY 0xf12b0008 -#define F0900_P2_STOP_ENABLE 0xf12b0004 -#define F0900_P2_STOP_SDAT2SDA 0xf12b0002 +#define R0900_P2_I2CRPT 0xf12b +#define F0900_P2_I2CT_ON 0xf12b0080 +#define F0900_P2_ENARPT_LEVEL 0xf12b0070 +#define F0900_P2_SCLT_DELAY 0xf12b0008 +#define F0900_P2_STOP_ENABLE 0xf12b0004 +#define F0900_P2_STOP_SDAT2SDA 0xf12b0002 + +/*IOPVALUE6*/ +#define R0900_IOPVALUE6 0xf138 +#define F0900_VSCL 0xf1380004 +#define F0900_VSDA 0xf1380002 +#define F0900_VDATA3_0 0xf1380001 + +/*IOPVALUE5*/ +#define R0900_IOPVALUE5 0xf139 +#define F0900_VDATA3_1 0xf1390080 +#define F0900_VDATA3_2 0xf1390040 +#define F0900_VDATA3_3 0xf1390020 +#define F0900_VDATA3_4 0xf1390010 +#define F0900_VDATA3_5 0xf1390008 +#define F0900_VDATA3_6 0xf1390004 +#define F0900_VDATA3_7 0xf1390002 +#define F0900_VCLKOUT3 0xf1390001 + +/*IOPVALUE4*/ +#define R0900_IOPVALUE4 0xf13a +#define F0900_VSTROUT3 0xf13a0080 +#define F0900_VDPN3 0xf13a0040 +#define F0900_VERROR3 0xf13a0020 +#define F0900_VDATA2_7 0xf13a0010 +#define F0900_VCLKOUT2 0xf13a0008 +#define F0900_VSTROUT2 0xf13a0004 +#define F0900_VDPN2 0xf13a0002 +#define F0900_VERROR2 0xf13a0001 + +/*IOPVALUE3*/ +#define R0900_IOPVALUE3 0xf13b +#define F0900_VDATA1_7 0xf13b0080 +#define F0900_VCLKOUT1 0xf13b0040 +#define F0900_VSTROUT1 0xf13b0020 +#define F0900_VDPN1 0xf13b0010 +#define F0900_VERROR1 0xf13b0008 +#define F0900_VCLKOUT27 0xf13b0004 +#define F0900_VDISEQCOUT2 0xf13b0002 +#define F0900_VSCLT2 0xf13b0001 + +/*IOPVALUE2*/ +#define R0900_IOPVALUE2 0xf13c +#define F0900_VSDAT2 0xf13c0080 +#define F0900_VAGCRF2 0xf13c0040 +#define F0900_VDISEQCOUT1 0xf13c0020 +#define F0900_VSCLT1 0xf13c0010 +#define F0900_VSDAT1 0xf13c0008 +#define F0900_VAGCRF1 0xf13c0004 +#define F0900_VDIRCLK 0xf13c0002 +#define F0900_VSTDBY 0xf13c0001 + +/*IOPVALUE1*/ +#define R0900_IOPVALUE1 0xf13d +#define F0900_VCS1 0xf13d0080 +#define F0900_VCS0 0xf13d0040 +#define F0900_VGPIO13 0xf13d0020 +#define F0900_VGPIO12 0xf13d0010 +#define F0900_VGPIO11 0xf13d0008 +#define F0900_VGPIO10 0xf13d0004 +#define F0900_VGPIO9 0xf13d0002 +#define F0900_VGPIO8 0xf13d0001 + +/*IOPVALUE0*/ +#define R0900_IOPVALUE0 0xf13e +#define F0900_VGPIO7 0xf13e0080 +#define F0900_VGPIO6 0xf13e0040 +#define F0900_VGPIO5 0xf13e0020 +#define F0900_VGPIO4 0xf13e0010 +#define F0900_VGPIO3 0xf13e0008 +#define F0900_VGPIO2 0xf13e0004 +#define F0900_VGPIO1 0xf13e0002 +#define F0900_VCLKI2 0xf13e0001 /*CLKI2CFG*/ -#define R0900_CLKI2CFG 0xf140 -#define F0900_CLKI2_OPD 0xf1400080 -#define F0900_CLKI2_CONFIG 0xf140007e -#define F0900_CLKI2_XOR 0xf1400001 +#define R0900_CLKI2CFG 0xf140 +#define F0900_CLKI2_OPD 0xf1400080 +#define F0900_CLKI2_CONFIG 0xf140007e +#define F0900_CLKI2_XOR 0xf1400001 /*GPIO1CFG*/ -#define R0900_GPIO1CFG 0xf141 -#define F0900_GPIO1_OPD 0xf1410080 -#define F0900_GPIO1_CONFIG 0xf141007e -#define F0900_GPIO1_XOR 0xf1410001 +#define R0900_GPIO1CFG 0xf141 +#define F0900_GPIO1_OPD 0xf1410080 +#define F0900_GPIO1_CONFIG 0xf141007e +#define F0900_GPIO1_XOR 0xf1410001 /*GPIO2CFG*/ -#define R0900_GPIO2CFG 0xf142 -#define F0900_GPIO2_OPD 0xf1420080 -#define F0900_GPIO2_CONFIG 0xf142007e -#define F0900_GPIO2_XOR 0xf1420001 +#define R0900_GPIO2CFG 0xf142 +#define F0900_GPIO2_OPD 0xf1420080 +#define F0900_GPIO2_CONFIG 0xf142007e +#define F0900_GPIO2_XOR 0xf1420001 /*GPIO3CFG*/ -#define R0900_GPIO3CFG 0xf143 -#define F0900_GPIO3_OPD 0xf1430080 -#define F0900_GPIO3_CONFIG 0xf143007e -#define F0900_GPIO3_XOR 0xf1430001 +#define R0900_GPIO3CFG 0xf143 +#define F0900_GPIO3_OPD 0xf1430080 +#define F0900_GPIO3_CONFIG 0xf143007e +#define F0900_GPIO3_XOR 0xf1430001 /*GPIO4CFG*/ -#define R0900_GPIO4CFG 0xf144 -#define F0900_GPIO4_OPD 0xf1440080 -#define F0900_GPIO4_CONFIG 0xf144007e -#define F0900_GPIO4_XOR 0xf1440001 +#define R0900_GPIO4CFG 0xf144 +#define F0900_GPIO4_OPD 0xf1440080 +#define F0900_GPIO4_CONFIG 0xf144007e +#define F0900_GPIO4_XOR 0xf1440001 /*GPIO5CFG*/ -#define R0900_GPIO5CFG 0xf145 -#define F0900_GPIO5_OPD 0xf1450080 -#define F0900_GPIO5_CONFIG 0xf145007e -#define F0900_GPIO5_XOR 0xf1450001 +#define R0900_GPIO5CFG 0xf145 +#define F0900_GPIO5_OPD 0xf1450080 +#define F0900_GPIO5_CONFIG 0xf145007e +#define F0900_GPIO5_XOR 0xf1450001 /*GPIO6CFG*/ -#define R0900_GPIO6CFG 0xf146 -#define F0900_GPIO6_OPD 0xf1460080 -#define F0900_GPIO6_CONFIG 0xf146007e -#define F0900_GPIO6_XOR 0xf1460001 +#define R0900_GPIO6CFG 0xf146 +#define F0900_GPIO6_OPD 0xf1460080 +#define F0900_GPIO6_CONFIG 0xf146007e +#define F0900_GPIO6_XOR 0xf1460001 /*GPIO7CFG*/ -#define R0900_GPIO7CFG 0xf147 -#define F0900_GPIO7_OPD 0xf1470080 -#define F0900_GPIO7_CONFIG 0xf147007e -#define F0900_GPIO7_XOR 0xf1470001 +#define R0900_GPIO7CFG 0xf147 +#define F0900_GPIO7_OPD 0xf1470080 +#define F0900_GPIO7_CONFIG 0xf147007e +#define F0900_GPIO7_XOR 0xf1470001 /*GPIO8CFG*/ -#define R0900_GPIO8CFG 0xf148 -#define F0900_GPIO8_OPD 0xf1480080 -#define F0900_GPIO8_CONFIG 0xf148007e -#define F0900_GPIO8_XOR 0xf1480001 +#define R0900_GPIO8CFG 0xf148 +#define F0900_GPIO8_OPD 0xf1480080 +#define F0900_GPIO8_CONFIG 0xf148007e +#define F0900_GPIO8_XOR 0xf1480001 /*GPIO9CFG*/ -#define R0900_GPIO9CFG 0xf149 -#define F0900_GPIO9_OPD 0xf1490080 -#define F0900_GPIO9_CONFIG 0xf149007e -#define F0900_GPIO9_XOR 0xf1490001 +#define R0900_GPIO9CFG 0xf149 +#define F0900_GPIO9_OPD 0xf1490080 +#define F0900_GPIO9_CONFIG 0xf149007e +#define F0900_GPIO9_XOR 0xf1490001 /*GPIO10CFG*/ -#define R0900_GPIO10CFG 0xf14a -#define F0900_GPIO10_OPD 0xf14a0080 -#define F0900_GPIO10_CONFIG 0xf14a007e -#define F0900_GPIO10_XOR 0xf14a0001 +#define R0900_GPIO10CFG 0xf14a +#define F0900_GPIO10_OPD 0xf14a0080 +#define F0900_GPIO10_CONFIG 0xf14a007e +#define F0900_GPIO10_XOR 0xf14a0001 /*GPIO11CFG*/ -#define R0900_GPIO11CFG 0xf14b -#define F0900_GPIO11_OPD 0xf14b0080 -#define F0900_GPIO11_CONFIG 0xf14b007e -#define F0900_GPIO11_XOR 0xf14b0001 +#define R0900_GPIO11CFG 0xf14b +#define F0900_GPIO11_OPD 0xf14b0080 +#define F0900_GPIO11_CONFIG 0xf14b007e +#define F0900_GPIO11_XOR 0xf14b0001 /*GPIO12CFG*/ -#define R0900_GPIO12CFG 0xf14c -#define F0900_GPIO12_OPD 0xf14c0080 -#define F0900_GPIO12_CONFIG 0xf14c007e -#define F0900_GPIO12_XOR 0xf14c0001 +#define R0900_GPIO12CFG 0xf14c +#define F0900_GPIO12_OPD 0xf14c0080 +#define F0900_GPIO12_CONFIG 0xf14c007e +#define F0900_GPIO12_XOR 0xf14c0001 /*GPIO13CFG*/ -#define R0900_GPIO13CFG 0xf14d -#define F0900_GPIO13_OPD 0xf14d0080 -#define F0900_GPIO13_CONFIG 0xf14d007e -#define F0900_GPIO13_XOR 0xf14d0001 +#define R0900_GPIO13CFG 0xf14d +#define F0900_GPIO13_OPD 0xf14d0080 +#define F0900_GPIO13_CONFIG 0xf14d007e +#define F0900_GPIO13_XOR 0xf14d0001 /*CS0CFG*/ -#define R0900_CS0CFG 0xf14e -#define F0900_CS0_OPD 0xf14e0080 -#define F0900_CS0_CONFIG 0xf14e007e -#define F0900_CS0_XOR 0xf14e0001 +#define R0900_CS0CFG 0xf14e +#define F0900_CS0_OPD 0xf14e0080 +#define F0900_CS0_CONFIG 0xf14e007e +#define F0900_CS0_XOR 0xf14e0001 /*CS1CFG*/ -#define R0900_CS1CFG 0xf14f -#define F0900_CS1_OPD 0xf14f0080 -#define F0900_CS1_CONFIG 0xf14f007e -#define F0900_CS1_XOR 0xf14f0001 +#define R0900_CS1CFG 0xf14f +#define F0900_CS1_OPD 0xf14f0080 +#define F0900_CS1_CONFIG 0xf14f007e +#define F0900_CS1_XOR 0xf14f0001 /*STDBYCFG*/ -#define R0900_STDBYCFG 0xf150 -#define F0900_STDBY_OPD 0xf1500080 -#define F0900_STDBY_CONFIG 0xf150007e -#define F0900_STBDY_XOR 0xf1500001 +#define R0900_STDBYCFG 0xf150 +#define F0900_STDBY_OPD 0xf1500080 +#define F0900_STDBY_CONFIG 0xf150007e +#define F0900_STBDY_XOR 0xf1500001 /*DIRCLKCFG*/ -#define R0900_DIRCLKCFG 0xf151 -#define F0900_DIRCLK_OPD 0xf1510080 -#define F0900_DIRCLK_CONFIG 0xf151007e -#define F0900_DIRCLK_XOR 0xf1510001 +#define R0900_DIRCLKCFG 0xf151 +#define F0900_DIRCLK_OPD 0xf1510080 +#define F0900_DIRCLK_CONFIG 0xf151007e +#define F0900_DIRCLK_XOR 0xf1510001 /*AGCRF1CFG*/ -#define R0900_AGCRF1CFG 0xf152 -#define F0900_AGCRF1_OPD 0xf1520080 -#define F0900_AGCRF1_CONFIG 0xf152007e -#define F0900_AGCRF1_XOR 0xf1520001 +#define R0900_AGCRF1CFG 0xf152 +#define F0900_AGCRF1_OPD 0xf1520080 +#define F0900_AGCRF1_CONFIG 0xf152007e +#define F0900_AGCRF1_XOR 0xf1520001 /*SDAT1CFG*/ -#define R0900_SDAT1CFG 0xf153 -#define F0900_SDAT1_OPD 0xf1530080 -#define F0900_SDAT1_CONFIG 0xf153007e -#define F0900_SDAT1_XOR 0xf1530001 +#define R0900_SDAT1CFG 0xf153 +#define F0900_SDAT1_OPD 0xf1530080 +#define F0900_SDAT1_CONFIG 0xf153007e +#define F0900_SDAT1_XOR 0xf1530001 /*SCLT1CFG*/ -#define R0900_SCLT1CFG 0xf154 -#define F0900_SCLT1_OPD 0xf1540080 -#define F0900_SCLT1_CONFIG 0xf154007e -#define F0900_SCLT1_XOR 0xf1540001 +#define R0900_SCLT1CFG 0xf154 +#define F0900_SCLT1_OPD 0xf1540080 +#define F0900_SCLT1_CONFIG 0xf154007e +#define F0900_SCLT1_XOR 0xf1540001 /*DISEQCO1CFG*/ -#define R0900_DISEQCO1CFG 0xf155 -#define F0900_DISEQCO1_OPD 0xf1550080 -#define F0900_DISEQCO1_CONFIG 0xf155007e -#define F0900_DISEQC1_XOR 0xf1550001 +#define R0900_DISEQCO1CFG 0xf155 +#define F0900_DISEQCO1_OPD 0xf1550080 +#define F0900_DISEQCO1_CONFIG 0xf155007e +#define F0900_DISEQC1_XOR 0xf1550001 /*AGCRF2CFG*/ -#define R0900_AGCRF2CFG 0xf156 -#define F0900_AGCRF2_OPD 0xf1560080 -#define F0900_AGCRF2_CONFIG 0xf156007e -#define F0900_AGCRF2_XOR 0xf1560001 +#define R0900_AGCRF2CFG 0xf156 +#define F0900_AGCRF2_OPD 0xf1560080 +#define F0900_AGCRF2_CONFIG 0xf156007e +#define F0900_AGCRF2_XOR 0xf1560001 /*SDAT2CFG*/ -#define R0900_SDAT2CFG 0xf157 -#define F0900_SDAT2_OPD 0xf1570080 -#define F0900_SDAT2_CONFIG 0xf157007e -#define F0900_SDAT2_XOR 0xf1570001 +#define R0900_SDAT2CFG 0xf157 +#define F0900_SDAT2_OPD 0xf1570080 +#define F0900_SDAT2_CONFIG 0xf157007e +#define F0900_SDAT2_XOR 0xf1570001 /*SCLT2CFG*/ -#define R0900_SCLT2CFG 0xf158 -#define F0900_SCLT2_OPD 0xf1580080 -#define F0900_SCLT2_CONFIG 0xf158007e -#define F0900_SCLT2_XOR 0xf1580001 +#define R0900_SCLT2CFG 0xf158 +#define F0900_SCLT2_OPD 0xf1580080 +#define F0900_SCLT2_CONFIG 0xf158007e +#define F0900_SCLT2_XOR 0xf1580001 /*DISEQCO2CFG*/ -#define R0900_DISEQCO2CFG 0xf159 -#define F0900_DISEQCO2_OPD 0xf1590080 -#define F0900_DISEQCO2_CONFIG 0xf159007e -#define F0900_DISEQC2_XOR 0xf1590001 +#define R0900_DISEQCO2CFG 0xf159 +#define F0900_DISEQCO2_OPD 0xf1590080 +#define F0900_DISEQCO2_CONFIG 0xf159007e +#define F0900_DISEQC2_XOR 0xf1590001 /*CLKOUT27CFG*/ -#define R0900_CLKOUT27CFG 0xf15a -#define F0900_CLKOUT27_OPD 0xf15a0080 -#define F0900_CLKOUT27_CONFIG 0xf15a007e -#define F0900_CLKOUT27_XOR 0xf15a0001 +#define R0900_CLKOUT27CFG 0xf15a +#define F0900_CLKOUT27_OPD 0xf15a0080 +#define F0900_CLKOUT27_CONFIG 0xf15a007e +#define F0900_CLKOUT27_XOR 0xf15a0001 /*ERROR1CFG*/ -#define R0900_ERROR1CFG 0xf15b -#define F0900_ERROR1_OPD 0xf15b0080 -#define F0900_ERROR1_CONFIG 0xf15b007e -#define F0900_ERROR1_XOR 0xf15b0001 +#define R0900_ERROR1CFG 0xf15b +#define F0900_ERROR1_OPD 0xf15b0080 +#define F0900_ERROR1_CONFIG 0xf15b007e +#define F0900_ERROR1_XOR 0xf15b0001 /*DPN1CFG*/ -#define R0900_DPN1CFG 0xf15c -#define F0900_DPN1_OPD 0xf15c0080 -#define F0900_DPN1_CONFIG 0xf15c007e -#define F0900_DPN1_XOR 0xf15c0001 +#define R0900_DPN1CFG 0xf15c +#define F0900_DPN1_OPD 0xf15c0080 +#define F0900_DPN1_CONFIG 0xf15c007e +#define F0900_DPN1_XOR 0xf15c0001 /*STROUT1CFG*/ -#define R0900_STROUT1CFG 0xf15d -#define F0900_STROUT1_OPD 0xf15d0080 -#define F0900_STROUT1_CONFIG 0xf15d007e -#define F0900_STROUT1_XOR 0xf15d0001 +#define R0900_STROUT1CFG 0xf15d +#define F0900_STROUT1_OPD 0xf15d0080 +#define F0900_STROUT1_CONFIG 0xf15d007e +#define F0900_STROUT1_XOR 0xf15d0001 /*CLKOUT1CFG*/ -#define R0900_CLKOUT1CFG 0xf15e -#define F0900_CLKOUT1_OPD 0xf15e0080 -#define F0900_CLKOUT1_CONFIG 0xf15e007e -#define F0900_CLKOUT1_XOR 0xf15e0001 +#define R0900_CLKOUT1CFG 0xf15e +#define F0900_CLKOUT1_OPD 0xf15e0080 +#define F0900_CLKOUT1_CONFIG 0xf15e007e +#define F0900_CLKOUT1_XOR 0xf15e0001 /*DATA71CFG*/ -#define R0900_DATA71CFG 0xf15f -#define F0900_DATA71_OPD 0xf15f0080 -#define F0900_DATA71_CONFIG 0xf15f007e -#define F0900_DATA71_XOR 0xf15f0001 +#define R0900_DATA71CFG 0xf15f +#define F0900_DATA71_OPD 0xf15f0080 +#define F0900_DATA71_CONFIG 0xf15f007e +#define F0900_DATA71_XOR 0xf15f0001 /*ERROR2CFG*/ -#define R0900_ERROR2CFG 0xf160 -#define F0900_ERROR2_OPD 0xf1600080 -#define F0900_ERROR2_CONFIG 0xf160007e -#define F0900_ERROR2_XOR 0xf1600001 +#define R0900_ERROR2CFG 0xf160 +#define F0900_ERROR2_OPD 0xf1600080 +#define F0900_ERROR2_CONFIG 0xf160007e +#define F0900_ERROR2_XOR 0xf1600001 /*DPN2CFG*/ -#define R0900_DPN2CFG 0xf161 -#define F0900_DPN2_OPD 0xf1610080 -#define F0900_DPN2_CONFIG 0xf161007e -#define F0900_DPN2_XOR 0xf1610001 +#define R0900_DPN2CFG 0xf161 +#define F0900_DPN2_OPD 0xf1610080 +#define F0900_DPN2_CONFIG 0xf161007e +#define F0900_DPN2_XOR 0xf1610001 /*STROUT2CFG*/ -#define R0900_STROUT2CFG 0xf162 -#define F0900_STROUT2_OPD 0xf1620080 -#define F0900_STROUT2_CONFIG 0xf162007e -#define F0900_STROUT2_XOR 0xf1620001 +#define R0900_STROUT2CFG 0xf162 +#define F0900_STROUT2_OPD 0xf1620080 +#define F0900_STROUT2_CONFIG 0xf162007e +#define F0900_STROUT2_XOR 0xf1620001 /*CLKOUT2CFG*/ -#define R0900_CLKOUT2CFG 0xf163 -#define F0900_CLKOUT2_OPD 0xf1630080 -#define F0900_CLKOUT2_CONFIG 0xf163007e -#define F0900_CLKOUT2_XOR 0xf1630001 +#define R0900_CLKOUT2CFG 0xf163 +#define F0900_CLKOUT2_OPD 0xf1630080 +#define F0900_CLKOUT2_CONFIG 0xf163007e +#define F0900_CLKOUT2_XOR 0xf1630001 /*DATA72CFG*/ -#define R0900_DATA72CFG 0xf164 -#define F0900_DATA72_OPD 0xf1640080 -#define F0900_DATA72_CONFIG 0xf164007e -#define F0900_DATA72_XOR 0xf1640001 +#define R0900_DATA72CFG 0xf164 +#define F0900_DATA72_OPD 0xf1640080 +#define F0900_DATA72_CONFIG 0xf164007e +#define F0900_DATA72_XOR 0xf1640001 /*ERROR3CFG*/ -#define R0900_ERROR3CFG 0xf165 -#define F0900_ERROR3_OPD 0xf1650080 -#define F0900_ERROR3_CONFIG 0xf165007e -#define F0900_ERROR3_XOR 0xf1650001 +#define R0900_ERROR3CFG 0xf165 +#define F0900_ERROR3_OPD 0xf1650080 +#define F0900_ERROR3_CONFIG 0xf165007e +#define F0900_ERROR3_XOR 0xf1650001 /*DPN3CFG*/ -#define R0900_DPN3CFG 0xf166 -#define F0900_DPN3_OPD 0xf1660080 -#define F0900_DPN3_CONFIG 0xf166007e -#define F0900_DPN3_XOR 0xf1660001 +#define R0900_DPN3CFG 0xf166 +#define F0900_DPN3_OPD 0xf1660080 +#define F0900_DPN3_CONFIG 0xf166007e +#define F0900_DPN3_XOR 0xf1660001 /*STROUT3CFG*/ -#define R0900_STROUT3CFG 0xf167 -#define F0900_STROUT3_OPD 0xf1670080 -#define F0900_STROUT3_CONFIG 0xf167007e -#define F0900_STROUT3_XOR 0xf1670001 +#define R0900_STROUT3CFG 0xf167 +#define F0900_STROUT3_OPD 0xf1670080 +#define F0900_STROUT3_CONFIG 0xf167007e +#define F0900_STROUT3_XOR 0xf1670001 /*CLKOUT3CFG*/ -#define R0900_CLKOUT3CFG 0xf168 -#define F0900_CLKOUT3_OPD 0xf1680080 -#define F0900_CLKOUT3_CONFIG 0xf168007e -#define F0900_CLKOUT3_XOR 0xf1680001 +#define R0900_CLKOUT3CFG 0xf168 +#define F0900_CLKOUT3_OPD 0xf1680080 +#define F0900_CLKOUT3_CONFIG 0xf168007e +#define F0900_CLKOUT3_XOR 0xf1680001 /*DATA73CFG*/ -#define R0900_DATA73CFG 0xf169 -#define F0900_DATA73_OPD 0xf1690080 -#define F0900_DATA73_CONFIG 0xf169007e -#define F0900_DATA73_XOR 0xf1690001 +#define R0900_DATA73CFG 0xf169 +#define F0900_DATA73_OPD 0xf1690080 +#define F0900_DATA73_CONFIG 0xf169007e +#define F0900_DATA73_XOR 0xf1690001 + +/*STRSTATUS1*/ +#define R0900_STRSTATUS1 0xf16a +#define F0900_STRSTATUS_SEL2 0xf16a00f0 +#define F0900_STRSTATUS_SEL1 0xf16a000f + +/*STRSTATUS2*/ +#define R0900_STRSTATUS2 0xf16b +#define F0900_STRSTATUS_SEL4 0xf16b00f0 +#define F0900_STRSTATUS_SEL3 0xf16b000f + +/*STRSTATUS3*/ +#define R0900_STRSTATUS3 0xf16c +#define F0900_STRSTATUS_SEL6 0xf16c00f0 +#define F0900_STRSTATUS_SEL5 0xf16c000f /*FSKTFC2*/ -#define R0900_FSKTFC2 0xf170 -#define F0900_FSKT_KMOD 0xf17000fc -#define F0900_FSKT_CAR2 0xf1700003 +#define R0900_FSKTFC2 0xf170 +#define F0900_FSKT_KMOD 0xf17000fc +#define F0900_FSKT_CAR2 0xf1700003 /*FSKTFC1*/ -#define R0900_FSKTFC1 0xf171 -#define F0900_FSKT_CAR1 0xf17100ff +#define R0900_FSKTFC1 0xf171 +#define F0900_FSKT_CAR1 0xf17100ff /*FSKTFC0*/ -#define R0900_FSKTFC0 0xf172 -#define F0900_FSKT_CAR0 0xf17200ff +#define R0900_FSKTFC0 0xf172 +#define F0900_FSKT_CAR0 0xf17200ff /*FSKTDELTAF1*/ -#define R0900_FSKTDELTAF1 0xf173 -#define F0900_FSKT_DELTAF1 0xf173000f +#define R0900_FSKTDELTAF1 0xf173 +#define F0900_FSKT_DELTAF1 0xf173000f /*FSKTDELTAF0*/ -#define R0900_FSKTDELTAF0 0xf174 -#define F0900_FSKT_DELTAF0 0xf17400ff +#define R0900_FSKTDELTAF0 0xf174 +#define F0900_FSKT_DELTAF0 0xf17400ff /*FSKTCTRL*/ -#define R0900_FSKTCTRL 0xf175 -#define F0900_FSKT_EN_SGN 0xf1750040 -#define F0900_FSKT_MOD_SGN 0xf1750020 -#define F0900_FSKT_MOD_EN 0xf175001c -#define F0900_FSKT_DACMODE 0xf1750003 +#define R0900_FSKTCTRL 0xf175 +#define F0900_FSKT_EN_SGN 0xf1750040 +#define F0900_FSKT_MOD_SGN 0xf1750020 +#define F0900_FSKT_MOD_EN 0xf175001c +#define F0900_FSKT_DACMODE 0xf1750003 /*FSKRFC2*/ -#define R0900_FSKRFC2 0xf176 -#define F0900_FSKR_DETSGN 0xf1760040 -#define F0900_FSKR_OUTSGN 0xf1760020 -#define F0900_FSKR_KAGC 0xf176001c -#define F0900_FSKR_CAR2 0xf1760003 +#define R0900_FSKRFC2 0xf176 +#define F0900_FSKR_DETSGN 0xf1760040 +#define F0900_FSKR_OUTSGN 0xf1760020 +#define F0900_FSKR_KAGC 0xf176001c +#define F0900_FSKR_CAR2 0xf1760003 /*FSKRFC1*/ -#define R0900_FSKRFC1 0xf177 -#define F0900_FSKR_CAR1 0xf17700ff +#define R0900_FSKRFC1 0xf177 +#define F0900_FSKR_CAR1 0xf17700ff /*FSKRFC0*/ -#define R0900_FSKRFC0 0xf178 -#define F0900_FSKR_CAR0 0xf17800ff +#define R0900_FSKRFC0 0xf178 +#define F0900_FSKR_CAR0 0xf17800ff /*FSKRK1*/ -#define R0900_FSKRK1 0xf179 -#define F0900_FSKR_K1_EXP 0xf17900e0 -#define F0900_FSKR_K1_MANT 0xf179001f +#define R0900_FSKRK1 0xf179 +#define F0900_FSKR_K1_EXP 0xf17900e0 +#define F0900_FSKR_K1_MANT 0xf179001f /*FSKRK2*/ -#define R0900_FSKRK2 0xf17a -#define F0900_FSKR_K2_EXP 0xf17a00e0 -#define F0900_FSKR_K2_MANT 0xf17a001f +#define R0900_FSKRK2 0xf17a +#define F0900_FSKR_K2_EXP 0xf17a00e0 +#define F0900_FSKR_K2_MANT 0xf17a001f /*FSKRAGCR*/ -#define R0900_FSKRAGCR 0xf17b -#define F0900_FSKR_OUTCTL 0xf17b00c0 -#define F0900_FSKR_AGC_REF 0xf17b003f +#define R0900_FSKRAGCR 0xf17b +#define F0900_FSKR_OUTCTL 0xf17b00c0 +#define F0900_FSKR_AGC_REF 0xf17b003f /*FSKRAGC*/ -#define R0900_FSKRAGC 0xf17c -#define F0900_FSKR_AGC_ACCU 0xf17c00ff +#define R0900_FSKRAGC 0xf17c +#define F0900_FSKR_AGC_ACCU 0xf17c00ff /*FSKRALPHA*/ -#define R0900_FSKRALPHA 0xf17d -#define F0900_FSKR_ALPHA_EXP 0xf17d001c -#define F0900_FSKR_ALPHA_M 0xf17d0003 +#define R0900_FSKRALPHA 0xf17d +#define F0900_FSKR_ALPHA_EXP 0xf17d001c +#define F0900_FSKR_ALPHA_M 0xf17d0003 /*FSKRPLTH1*/ -#define R0900_FSKRPLTH1 0xf17e -#define F0900_FSKR_BETA 0xf17e00f0 -#define F0900_FSKR_PLL_TRESH1 0xf17e000f +#define R0900_FSKRPLTH1 0xf17e +#define F0900_FSKR_BETA 0xf17e00f0 +#define F0900_FSKR_PLL_TRESH1 0xf17e000f /*FSKRPLTH0*/ -#define R0900_FSKRPLTH0 0xf17f -#define F0900_FSKR_PLL_TRESH0 0xf17f00ff +#define R0900_FSKRPLTH0 0xf17f +#define F0900_FSKR_PLL_TRESH0 0xf17f00ff /*FSKRDF1*/ -#define R0900_FSKRDF1 0xf180 -#define F0900_FSKR_OUT 0xf1800080 -#define F0900_FSKR_DELTAF1 0xf180001f +#define R0900_FSKRDF1 0xf180 +#define F0900_FSKR_OUT 0xf1800080 +#define F0900_FSKR_DELTAF1 0xf180001f /*FSKRDF0*/ -#define R0900_FSKRDF0 0xf181 -#define F0900_FSKR_DELTAF0 0xf18100ff +#define R0900_FSKRDF0 0xf181 +#define F0900_FSKR_DELTAF0 0xf18100ff /*FSKRSTEPP*/ -#define R0900_FSKRSTEPP 0xf182 -#define F0900_FSKR_STEP_PLUS 0xf18200ff +#define R0900_FSKRSTEPP 0xf182 +#define F0900_FSKR_STEP_PLUS 0xf18200ff /*FSKRSTEPM*/ -#define R0900_FSKRSTEPM 0xf183 -#define F0900_FSKR_STEP_MINUS 0xf18300ff +#define R0900_FSKRSTEPM 0xf183 +#define F0900_FSKR_STEP_MINUS 0xf18300ff /*FSKRDET1*/ -#define R0900_FSKRDET1 0xf184 -#define F0900_FSKR_DETECT 0xf1840080 -#define F0900_FSKR_CARDET_ACCU1 0xf184000f +#define R0900_FSKRDET1 0xf184 +#define F0900_FSKR_DETECT 0xf1840080 +#define F0900_FSKR_CARDET_ACCU1 0xf184000f /*FSKRDET0*/ -#define R0900_FSKRDET0 0xf185 -#define F0900_FSKR_CARDET_ACCU0 0xf18500ff +#define R0900_FSKRDET0 0xf185 +#define F0900_FSKR_CARDET_ACCU0 0xf18500ff /*FSKRDTH1*/ -#define R0900_FSKRDTH1 0xf186 -#define F0900_FSKR_CARLOSS_THRESH1 0xf18600f0 -#define F0900_FSKR_CARDET_THRESH1 0xf186000f +#define R0900_FSKRDTH1 0xf186 +#define F0900_FSKR_CARLOSS_THRESH1 0xf18600f0 +#define F0900_FSKR_CARDET_THRESH1 0xf186000f /*FSKRDTH0*/ -#define R0900_FSKRDTH0 0xf187 -#define F0900_FSKR_CARDET_THRESH0 0xf18700ff +#define R0900_FSKRDTH0 0xf187 +#define F0900_FSKR_CARDET_THRESH0 0xf18700ff /*FSKRLOSS*/ -#define R0900_FSKRLOSS 0xf188 -#define F0900_FSKR_CARLOSS_THRESH0 0xf18800ff +#define R0900_FSKRLOSS 0xf188 +#define F0900_FSKR_CARLOSS_THRESH0 0xf18800ff /*P2_DISTXCTL*/ -#define R0900_P2_DISTXCTL 0xf190 -#define F0900_P2_TIM_OFF 0xf1900080 -#define F0900_P2_DISEQC_RESET 0xf1900040 -#define F0900_P2_TIM_CMD 0xf1900030 -#define F0900_P2_DIS_PRECHARGE 0xf1900008 -#define F0900_P2_DISTX_MODE 0xf1900007 +#define R0900_P2_DISTXCTL 0xf190 +#define F0900_P2_TIM_OFF 0xf1900080 +#define F0900_P2_DISEQC_RESET 0xf1900040 +#define F0900_P2_TIM_CMD 0xf1900030 +#define F0900_P2_DIS_PRECHARGE 0xf1900008 +#define F0900_P2_DISTX_MODE 0xf1900007 /*P2_DISRXCTL*/ -#define R0900_P2_DISRXCTL 0xf191 -#define F0900_P2_RECEIVER_ON 0xf1910080 -#define F0900_P2_IGNO_SHORT22K 0xf1910040 -#define F0900_P2_ONECHIP_TRX 0xf1910020 -#define F0900_P2_EXT_ENVELOP 0xf1910010 -#define F0900_P2_PIN_SELECT 0xf191000c -#define F0900_P2_IRQ_RXEND 0xf1910002 -#define F0900_P2_IRQ_4NBYTES 0xf1910001 +#define R0900_P2_DISRXCTL 0xf191 +#define F0900_P2_RECEIVER_ON 0xf1910080 +#define F0900_P2_IGNO_SHORT22K 0xf1910040 +#define F0900_P2_ONECHIP_TRX 0xf1910020 +#define F0900_P2_EXT_ENVELOP 0xf1910010 +#define F0900_P2_PIN_SELECT0 0xf191000c +#define F0900_P2_IRQ_RXEND 0xf1910002 +#define F0900_P2_IRQ_4NBYTES 0xf1910001 /*P2_DISRX_ST0*/ -#define R0900_P2_DISRX_ST0 0xf194 -#define F0900_P2_RX_END 0xf1940080 -#define F0900_P2_RX_ACTIVE 0xf1940040 -#define F0900_P2_SHORT_22KHZ 0xf1940020 -#define F0900_P2_CONT_TONE 0xf1940010 -#define F0900_P2_FIFO_4BREADY 0xf1940008 -#define F0900_P2_FIFO_EMPTY 0xf1940004 -#define F0900_P2_ABORT_DISRX 0xf1940001 +#define R0900_P2_DISRX_ST0 0xf194 +#define F0900_P2_RX_END 0xf1940080 +#define F0900_P2_RX_ACTIVE 0xf1940040 +#define F0900_P2_SHORT_22KHZ 0xf1940020 +#define F0900_P2_CONT_TONE 0xf1940010 +#define F0900_P2_FIFO_4BREADY 0xf1940008 +#define F0900_P2_FIFO_EMPTY 0xf1940004 +#define F0900_P2_ABORT_DISRX 0xf1940001 /*P2_DISRX_ST1*/ -#define R0900_P2_DISRX_ST1 0xf195 -#define F0900_P2_RX_FAIL 0xf1950080 -#define F0900_P2_FIFO_PARITYFAIL 0xf1950040 -#define F0900_P2_RX_NONBYTE 0xf1950020 -#define F0900_P2_FIFO_OVERFLOW 0xf1950010 -#define F0900_P2_FIFO_BYTENBR 0xf195000f +#define R0900_P2_DISRX_ST1 0xf195 +#define F0900_P2_RX_FAIL 0xf1950080 +#define F0900_P2_FIFO_PARITYFAIL 0xf1950040 +#define F0900_P2_RX_NONBYTE 0xf1950020 +#define F0900_P2_FIFO_OVERFLOW 0xf1950010 +#define F0900_P2_FIFO_BYTENBR 0xf195000f /*P2_DISRXDATA*/ -#define R0900_P2_DISRXDATA 0xf196 -#define F0900_P2_DISRX_DATA 0xf19600ff +#define R0900_P2_DISRXDATA 0xf196 +#define F0900_P2_DISRX_DATA 0xf19600ff /*P2_DISTXDATA*/ -#define R0900_P2_DISTXDATA 0xf197 -#define F0900_P2_DISEQC_FIFO 0xf19700ff +#define R0900_P2_DISTXDATA 0xf197 +#define F0900_P2_DISEQC_FIFO 0xf19700ff /*P2_DISTXSTATUS*/ -#define R0900_P2_DISTXSTATUS 0xf198 -#define F0900_P2_TX_FAIL 0xf1980080 -#define F0900_P2_FIFO_FULL 0xf1980040 -#define F0900_P2_TX_IDLE 0xf1980020 -#define F0900_P2_GAP_BURST 0xf1980010 -#define F0900_P2_TXFIFO_BYTES 0xf198000f +#define R0900_P2_DISTXSTATUS 0xf198 +#define F0900_P2_TX_FAIL 0xf1980080 +#define F0900_P2_FIFO_FULL 0xf1980040 +#define F0900_P2_TX_IDLE 0xf1980020 +#define F0900_P2_GAP_BURST 0xf1980010 +#define F0900_P2_TXFIFO_BYTES 0xf198000f /*P2_F22TX*/ -#define R0900_P2_F22TX 0xf199 -#define F0900_P2_F22_REG 0xf19900ff +#define R0900_P2_F22TX 0xf199 +#define F0900_P2_F22_REG 0xf19900ff /*P2_F22RX*/ -#define R0900_P2_F22RX 0xf19a -#define F0900_P2_F22RX_REG 0xf19a00ff +#define R0900_P2_F22RX 0xf19a +#define F0900_P2_F22RX_REG 0xf19a00ff /*P2_ACRPRESC*/ -#define R0900_P2_ACRPRESC 0xf19c -#define F0900_P2_ACR_CODFRDY 0xf19c0008 -#define F0900_P2_ACR_PRESC 0xf19c0007 +#define R0900_P2_ACRPRESC 0xf19c +#define F0900_P2_ACR_PRESC 0xf19c0007 /*P2_ACRDIV*/ -#define R0900_P2_ACRDIV 0xf19d -#define F0900_P2_ACR_DIV 0xf19d00ff +#define R0900_P2_ACRDIV 0xf19d +#define F0900_P2_ACR_DIV 0xf19d00ff /*P1_DISTXCTL*/ -#define R0900_P1_DISTXCTL 0xf1a0 -#define F0900_P1_TIM_OFF 0xf1a00080 -#define F0900_P1_DISEQC_RESET 0xf1a00040 -#define F0900_P1_TIM_CMD 0xf1a00030 -#define F0900_P1_DIS_PRECHARGE 0xf1a00008 -#define F0900_P1_DISTX_MODE 0xf1a00007 +#define R0900_P1_DISTXCTL 0xf1a0 +#define DISTXCTL shiftx(R0900_P1_DISTXCTL, demod, 0x10) +#define F0900_P1_TIM_OFF 0xf1a00080 +#define F0900_P1_DISEQC_RESET 0xf1a00040 +#define DISEQC_RESET shiftx(F0900_P1_DISEQC_RESET, demod, 0x100000) +#define F0900_P1_TIM_CMD 0xf1a00030 +#define F0900_P1_DIS_PRECHARGE 0xf1a00008 +#define DIS_PRECHARGE shiftx(F0900_P1_DIS_PRECHARGE, demod, 0x100000) +#define F0900_P1_DISTX_MODE 0xf1a00007 +#define DISTX_MODE shiftx(F0900_P1_DISTX_MODE, demod, 0x100000) /*P1_DISRXCTL*/ -#define R0900_P1_DISRXCTL 0xf1a1 -#define F0900_P1_RECEIVER_ON 0xf1a10080 -#define F0900_P1_IGNO_SHORT22K 0xf1a10040 -#define F0900_P1_ONECHIP_TRX 0xf1a10020 -#define F0900_P1_EXT_ENVELOP 0xf1a10010 -#define F0900_P1_PIN_SELECT 0xf1a1000c -#define F0900_P1_IRQ_RXEND 0xf1a10002 -#define F0900_P1_IRQ_4NBYTES 0xf1a10001 +#define R0900_P1_DISRXCTL 0xf1a1 +#define DISRXCTL shiftx(R0900_P1_DISRXCTL, demod, 0x10) +#define F0900_P1_RECEIVER_ON 0xf1a10080 +#define F0900_P1_IGNO_SHORT22K 0xf1a10040 +#define F0900_P1_ONECHIP_TRX 0xf1a10020 +#define F0900_P1_EXT_ENVELOP 0xf1a10010 +#define F0900_P1_PIN_SELECT0 0xf1a1000c +#define F0900_P1_IRQ_RXEND 0xf1a10002 +#define F0900_P1_IRQ_4NBYTES 0xf1a10001 /*P1_DISRX_ST0*/ -#define R0900_P1_DISRX_ST0 0xf1a4 -#define F0900_P1_RX_END 0xf1a40080 -#define F0900_P1_RX_ACTIVE 0xf1a40040 -#define F0900_P1_SHORT_22KHZ 0xf1a40020 -#define F0900_P1_CONT_TONE 0xf1a40010 -#define F0900_P1_FIFO_4BREADY 0xf1a40008 -#define F0900_P1_FIFO_EMPTY 0xf1a40004 -#define F0900_P1_ABORT_DISRX 0xf1a40001 +#define R0900_P1_DISRX_ST0 0xf1a4 +#define DISRX_ST0 shiftx(R0900_P1_DISRX_ST0, demod, 0x10) +#define F0900_P1_RX_END 0xf1a40080 +#define RX_END shiftx(F0900_P1_RX_END, demod, 0x100000) +#define F0900_P1_RX_ACTIVE 0xf1a40040 +#define F0900_P1_SHORT_22KHZ 0xf1a40020 +#define F0900_P1_CONT_TONE 0xf1a40010 +#define F0900_P1_FIFO_4BREADY 0xf1a40008 +#define F0900_P1_FIFO_EMPTY 0xf1a40004 +#define F0900_P1_ABORT_DISRX 0xf1a40001 /*P1_DISRX_ST1*/ -#define R0900_P1_DISRX_ST1 0xf1a5 -#define F0900_P1_RX_FAIL 0xf1a50080 -#define F0900_P1_FIFO_PARITYFAIL 0xf1a50040 -#define F0900_P1_RX_NONBYTE 0xf1a50020 -#define F0900_P1_FIFO_OVERFLOW 0xf1a50010 -#define F0900_P1_FIFO_BYTENBR 0xf1a5000f +#define R0900_P1_DISRX_ST1 0xf1a5 +#define DISRX_ST1 shiftx(R0900_P1_DISRX_ST1, demod, 0x10) +#define F0900_P1_RX_FAIL 0xf1a50080 +#define F0900_P1_FIFO_PARITYFAIL 0xf1a50040 +#define F0900_P1_RX_NONBYTE 0xf1a50020 +#define F0900_P1_FIFO_OVERFLOW 0xf1a50010 +#define F0900_P1_FIFO_BYTENBR 0xf1a5000f +#define FIFO_BYTENBR shiftx(F0900_P1_FIFO_BYTENBR, demod, 0x100000) /*P1_DISRXDATA*/ -#define R0900_P1_DISRXDATA 0xf1a6 -#define F0900_P1_DISRX_DATA 0xf1a600ff +#define R0900_P1_DISRXDATA 0xf1a6 +#define DISRXDATA shiftx(R0900_P1_DISRXDATA, demod, 0x10) +#define F0900_P1_DISRX_DATA 0xf1a600ff /*P1_DISTXDATA*/ -#define R0900_P1_DISTXDATA 0xf1a7 -#define F0900_P1_DISEQC_FIFO 0xf1a700ff +#define R0900_P1_DISTXDATA 0xf1a7 +#define DISTXDATA shiftx(R0900_P1_DISTXDATA, demod, 0x10) +#define F0900_P1_DISEQC_FIFO 0xf1a700ff /*P1_DISTXSTATUS*/ -#define R0900_P1_DISTXSTATUS 0xf1a8 -#define F0900_P1_TX_FAIL 0xf1a80080 -#define F0900_P1_FIFO_FULL 0xf1a80040 -#define F0900_P1_TX_IDLE 0xf1a80020 -#define F0900_P1_GAP_BURST 0xf1a80010 -#define F0900_P1_TXFIFO_BYTES 0xf1a8000f +#define R0900_P1_DISTXSTATUS 0xf1a8 +#define F0900_P1_TX_FAIL 0xf1a80080 +#define F0900_P1_FIFO_FULL 0xf1a80040 +#define FIFO_FULL shiftx(F0900_P1_FIFO_FULL, demod, 0x100000) +#define F0900_P1_TX_IDLE 0xf1a80020 +#define TX_IDLE shiftx(F0900_P1_TX_IDLE, demod, 0x100000) +#define F0900_P1_GAP_BURST 0xf1a80010 +#define F0900_P1_TXFIFO_BYTES 0xf1a8000f /*P1_F22TX*/ -#define R0900_P1_F22TX 0xf1a9 -#define F0900_P1_F22_REG 0xf1a900ff +#define R0900_P1_F22TX 0xf1a9 +#define F22TX shiftx(R0900_P1_F22TX, demod, 0x10) +#define F0900_P1_F22_REG 0xf1a900ff /*P1_F22RX*/ -#define R0900_P1_F22RX 0xf1aa -#define F0900_P1_F22RX_REG 0xf1aa00ff +#define R0900_P1_F22RX 0xf1aa +#define F22RX shiftx(R0900_P1_F22RX, demod, 0x10) +#define F0900_P1_F22RX_REG 0xf1aa00ff /*P1_ACRPRESC*/ -#define R0900_P1_ACRPRESC 0xf1ac -#define F0900_P1_ACR_CODFRDY 0xf1ac0008 -#define F0900_P1_ACR_PRESC 0xf1ac0007 +#define R0900_P1_ACRPRESC 0xf1ac +#define ACRPRESC shiftx(R0900_P1_ACRPRESC, demod, 0x10) +#define F0900_P1_ACR_PRESC 0xf1ac0007 /*P1_ACRDIV*/ -#define R0900_P1_ACRDIV 0xf1ad -#define F0900_P1_ACR_DIV 0xf1ad00ff +#define R0900_P1_ACRDIV 0xf1ad +#define ACRDIV shiftx(R0900_P1_ACRDIV, demod, 0x10) +#define F0900_P1_ACR_DIV 0xf1ad00ff /*NCOARSE*/ -#define R0900_NCOARSE 0xf1b3 -#define F0900_M_DIV 0xf1b300ff +#define R0900_NCOARSE 0xf1b3 +#define F0900_M_DIV 0xf1b300ff /*SYNTCTRL*/ -#define R0900_SYNTCTRL 0xf1b6 -#define F0900_STANDBY 0xf1b60080 -#define F0900_BYPASSPLLCORE 0xf1b60040 -#define F0900_SELX1RATIO 0xf1b60020 -#define F0900_I2C_TUD 0xf1b60010 -#define F0900_STOP_PLL 0xf1b60008 -#define F0900_BYPASSPLLFSK 0xf1b60004 -#define F0900_SELOSCI 0xf1b60002 -#define F0900_BYPASSPLLADC 0xf1b60001 +#define R0900_SYNTCTRL 0xf1b6 +#define F0900_STANDBY 0xf1b60080 +#define F0900_BYPASSPLLCORE 0xf1b60040 +#define F0900_SELX1RATIO 0xf1b60020 +#define F0900_STOP_PLL 0xf1b60008 +#define F0900_BYPASSPLLFSK 0xf1b60004 +#define F0900_SELOSCI 0xf1b60002 +#define F0900_BYPASSPLLADC 0xf1b60001 /*FILTCTRL*/ -#define R0900_FILTCTRL 0xf1b7 -#define F0900_INV_CLK135 0xf1b70080 -#define F0900_PERM_BYPDIS 0xf1b70040 -#define F0900_SEL_FSKCKDIV 0xf1b70004 -#define F0900_INV_CLKFSK 0xf1b70002 -#define F0900_BYPASS_APPLI 0xf1b70001 +#define R0900_FILTCTRL 0xf1b7 +#define F0900_INV_CLK135 0xf1b70080 +#define F0900_SEL_FSKCKDIV 0xf1b70004 +#define F0900_INV_CLKFSK 0xf1b70002 +#define F0900_BYPASS_APPLI 0xf1b70001 /*PLLSTAT*/ -#define R0900_PLLSTAT 0xf1b8 -#define F0900_ACM_SEL 0xf1b80080 -#define F0900_DTV_SEL 0xf1b80040 -#define F0900_PLLLOCK 0xf1b80001 +#define R0900_PLLSTAT 0xf1b8 +#define F0900_PLLLOCK 0xf1b80001 /*STOPCLK1*/ -#define R0900_STOPCLK1 0xf1c2 -#define F0900_STOP_CLKPKDT2 0xf1c20040 -#define F0900_STOP_CLKPKDT1 0xf1c20020 -#define F0900_STOP_CLKFEC 0xf1c20010 -#define F0900_STOP_CLKADCI2 0xf1c20008 -#define F0900_INV_CLKADCI2 0xf1c20004 -#define F0900_STOP_CLKADCI1 0xf1c20002 -#define F0900_INV_CLKADCI1 0xf1c20001 +#define R0900_STOPCLK1 0xf1c2 +#define F0900_STOP_CLKPKDT2 0xf1c20040 +#define F0900_STOP_CLKPKDT1 0xf1c20020 +#define F0900_STOP_CLKFEC 0xf1c20010 +#define F0900_STOP_CLKADCI2 0xf1c20008 +#define F0900_INV_CLKADCI2 0xf1c20004 +#define F0900_STOP_CLKADCI1 0xf1c20002 +#define F0900_INV_CLKADCI1 0xf1c20001 /*STOPCLK2*/ -#define R0900_STOPCLK2 0xf1c3 -#define F0900_STOP_CLKSAMP2 0xf1c30010 -#define F0900_STOP_CLKSAMP1 0xf1c30008 -#define F0900_STOP_CLKVIT2 0xf1c30004 -#define F0900_STOP_CLKVIT1 0xf1c30002 -#define F0900_STOP_CLKTS 0xf1c30001 +#define R0900_STOPCLK2 0xf1c3 +#define F0900_STOP_CLKSAMP2 0xf1c30010 +#define F0900_STOP_CLKSAMP1 0xf1c30008 +#define F0900_STOP_CLKVIT2 0xf1c30004 +#define F0900_STOP_CLKVIT1 0xf1c30002 +#define STOP_CLKVIT shiftx(F0900_STOP_CLKVIT1, demod, -2) +#define F0900_STOP_CLKTS 0xf1c30001 /*TSTTNR0*/ -#define R0900_TSTTNR0 0xf1df -#define F0900_SEL_FSK 0xf1df0080 -#define F0900_FSK_PON 0xf1df0004 -#define F0900_FSK_OPENLOOP 0xf1df0002 +#define R0900_TSTTNR0 0xf1df +#define F0900_SEL_FSK 0xf1df0080 +#define F0900_FSK_PON 0xf1df0004 /*TSTTNR1*/ -#define R0900_TSTTNR1 0xf1e0 -#define F0900_BYPASS_ADC1 0xf1e00080 -#define F0900_INVADC1_CKOUT 0xf1e00040 -#define F0900_SELIQSRC1 0xf1e00030 -#define F0900_ADC1_PON 0xf1e00002 -#define F0900_ADC1_INMODE 0xf1e00001 +#define R0900_TSTTNR1 0xf1e0 +#define F0900_ADC1_PON 0xf1e00002 +#define F0900_ADC1_INMODE 0xf1e00001 /*TSTTNR2*/ -#define R0900_TSTTNR2 0xf1e1 -#define F0900_DISEQC1_PON 0xf1e10020 -#define F0900_DISEQC1_TEST 0xf1e1001f +#define R0900_TSTTNR2 0xf1e1 +#define F0900_DISEQC1_PON 0xf1e10020 /*TSTTNR3*/ -#define R0900_TSTTNR3 0xf1e2 -#define F0900_BYPASS_ADC2 0xf1e20080 -#define F0900_INVADC2_CKOUT 0xf1e20040 -#define F0900_SELIQSRC2 0xf1e20030 -#define F0900_ADC2_PON 0xf1e20002 -#define F0900_ADC2_INMODE 0xf1e20001 +#define R0900_TSTTNR3 0xf1e2 +#define F0900_ADC2_PON 0xf1e20002 +#define F0900_ADC2_INMODE 0xf1e20001 /*TSTTNR4*/ -#define R0900_TSTTNR4 0xf1e3 -#define F0900_DISEQC2_PON 0xf1e30020 -#define F0900_DISEQC2_TEST 0xf1e3001f +#define R0900_TSTTNR4 0xf1e3 +#define F0900_DISEQC2_PON 0xf1e30020 /*P2_IQCONST*/ -#define R0900_P2_IQCONST 0xf200 -#define F0900_P2_CONSTEL_SELECT 0xf2000060 -#define F0900_P2_IQSYMB_SEL 0xf200001f +#define R0900_P2_IQCONST 0xf200 +#define F0900_P2_CONSTEL_SELECT 0xf2000060 +#define F0900_P2_IQSYMB_SEL 0xf200001f /*P2_NOSCFG*/ -#define R0900_P2_NOSCFG 0xf201 -#define F0900_P2_DUMMYPL_NOSDATA 0xf2010020 -#define F0900_P2_NOSPLH_BETA 0xf2010018 -#define F0900_P2_NOSDATA_BETA 0xf2010007 +#define R0900_P2_NOSCFG 0xf201 +#define F0900_P2_DUMMYPL_NOSDATA 0xf2010020 +#define F0900_P2_NOSPLH_BETA 0xf2010018 +#define F0900_P2_NOSDATA_BETA 0xf2010007 /*P2_ISYMB*/ -#define R0900_P2_ISYMB 0xf202 -#define F0900_P2_I_SYMBOL 0xf20201ff +#define R0900_P2_ISYMB 0xf202 +#define F0900_P2_I_SYMBOL 0xf20201ff /*P2_QSYMB*/ -#define R0900_P2_QSYMB 0xf203 -#define F0900_P2_Q_SYMBOL 0xf20301ff +#define R0900_P2_QSYMB 0xf203 +#define F0900_P2_Q_SYMBOL 0xf20301ff /*P2_AGC1CFG*/ -#define R0900_P2_AGC1CFG 0xf204 -#define F0900_P2_DC_FROZEN 0xf2040080 -#define F0900_P2_DC_CORRECT 0xf2040040 -#define F0900_P2_AMM_FROZEN 0xf2040020 -#define F0900_P2_AMM_CORRECT 0xf2040010 -#define F0900_P2_QUAD_FROZEN 0xf2040008 -#define F0900_P2_QUAD_CORRECT 0xf2040004 -#define F0900_P2_DCCOMP_SLOW 0xf2040002 -#define F0900_P2_IQMISM_SLOW 0xf2040001 +#define R0900_P2_AGC1CFG 0xf204 +#define F0900_P2_DC_FROZEN 0xf2040080 +#define F0900_P2_DC_CORRECT 0xf2040040 +#define F0900_P2_AMM_FROZEN 0xf2040020 +#define F0900_P2_AMM_CORRECT 0xf2040010 +#define F0900_P2_QUAD_FROZEN 0xf2040008 +#define F0900_P2_QUAD_CORRECT 0xf2040004 /*P2_AGC1CN*/ -#define R0900_P2_AGC1CN 0xf206 -#define F0900_P2_AGC1_LOCKED 0xf2060080 -#define F0900_P2_AGC1_OVERFLOW 0xf2060040 -#define F0900_P2_AGC1_NOSLOWLK 0xf2060020 -#define F0900_P2_AGC1_MINPOWER 0xf2060010 -#define F0900_P2_AGCOUT_FAST 0xf2060008 -#define F0900_P2_AGCIQ_BETA 0xf2060007 +#define R0900_P2_AGC1CN 0xf206 +#define F0900_P2_AGC1_LOCKED 0xf2060080 +#define F0900_P2_AGC1_MINPOWER 0xf2060010 +#define F0900_P2_AGCOUT_FAST 0xf2060008 +#define F0900_P2_AGCIQ_BETA 0xf2060007 /*P2_AGC1REF*/ -#define R0900_P2_AGC1REF 0xf207 -#define F0900_P2_AGCIQ_REF 0xf20700ff +#define R0900_P2_AGC1REF 0xf207 +#define F0900_P2_AGCIQ_REF 0xf20700ff /*P2_IDCCOMP*/ -#define R0900_P2_IDCCOMP 0xf208 -#define F0900_P2_IAVERAGE_ADJ 0xf20801ff +#define R0900_P2_IDCCOMP 0xf208 +#define F0900_P2_IAVERAGE_ADJ 0xf20801ff /*P2_QDCCOMP*/ -#define R0900_P2_QDCCOMP 0xf209 -#define F0900_P2_QAVERAGE_ADJ 0xf20901ff +#define R0900_P2_QDCCOMP 0xf209 +#define F0900_P2_QAVERAGE_ADJ 0xf20901ff /*P2_POWERI*/ -#define R0900_P2_POWERI 0xf20a -#define F0900_P2_POWER_I 0xf20a00ff +#define R0900_P2_POWERI 0xf20a +#define F0900_P2_POWER_I 0xf20a00ff /*P2_POWERQ*/ -#define R0900_P2_POWERQ 0xf20b -#define F0900_P2_POWER_Q 0xf20b00ff +#define R0900_P2_POWERQ 0xf20b +#define F0900_P2_POWER_Q 0xf20b00ff /*P2_AGC1AMM*/ -#define R0900_P2_AGC1AMM 0xf20c -#define F0900_P2_AMM_VALUE 0xf20c00ff +#define R0900_P2_AGC1AMM 0xf20c +#define F0900_P2_AMM_VALUE 0xf20c00ff /*P2_AGC1QUAD*/ -#define R0900_P2_AGC1QUAD 0xf20d -#define F0900_P2_QUAD_VALUE 0xf20d01ff +#define R0900_P2_AGC1QUAD 0xf20d +#define F0900_P2_QUAD_VALUE 0xf20d01ff /*P2_AGCIQIN1*/ -#define R0900_P2_AGCIQIN1 0xf20e -#define F0900_P2_AGCIQ_VALUE1 0xf20e00ff +#define R0900_P2_AGCIQIN1 0xf20e +#define F0900_P2_AGCIQ_VALUE1 0xf20e00ff /*P2_AGCIQIN0*/ -#define R0900_P2_AGCIQIN0 0xf20f -#define F0900_P2_AGCIQ_VALUE0 0xf20f00ff +#define R0900_P2_AGCIQIN0 0xf20f +#define F0900_P2_AGCIQ_VALUE0 0xf20f00ff /*P2_DEMOD*/ -#define R0900_P2_DEMOD 0xf210 -#define F0900_P2_DEMOD_STOP 0xf2100040 -#define F0900_P2_SPECINV_CONTROL 0xf2100030 -#define F0900_P2_FORCE_ENASAMP 0xf2100008 -#define F0900_P2_MANUAL_ROLLOFF 0xf2100004 -#define F0900_P2_ROLLOFF_CONTROL 0xf2100003 +#define R0900_P2_DEMOD 0xf210 +#define F0900_P2_MANUALS2_ROLLOFF 0xf2100080 +#define F0900_P2_SPECINV_CONTROL 0xf2100030 +#define F0900_P2_FORCE_ENASAMP 0xf2100008 +#define F0900_P2_MANUALSX_ROLLOFF 0xf2100004 +#define F0900_P2_ROLLOFF_CONTROL 0xf2100003 /*P2_DMDMODCOD*/ -#define R0900_P2_DMDMODCOD 0xf211 -#define F0900_P2_MANUAL_MODCOD 0xf2110080 -#define F0900_P2_DEMOD_MODCOD 0xf211007c -#define F0900_P2_DEMOD_TYPE 0xf2110003 +#define R0900_P2_DMDMODCOD 0xf211 +#define F0900_P2_MANUAL_MODCOD 0xf2110080 +#define F0900_P2_DEMOD_MODCOD 0xf211007c +#define F0900_P2_DEMOD_TYPE 0xf2110003 /*P2_DSTATUS*/ -#define R0900_P2_DSTATUS 0xf212 -#define F0900_P2_CAR_LOCK 0xf2120080 -#define F0900_P2_TMGLOCK_QUALITY 0xf2120060 -#define F0900_P2_SDVBS1_ENABLE 0xf2120010 -#define F0900_P2_LOCK_DEFINITIF 0xf2120008 -#define F0900_P2_TIMING_IS_LOCKED 0xf2120004 -#define F0900_P2_COARSE_TMGLOCK 0xf2120002 -#define F0900_P2_COARSE_CARLOCK 0xf2120001 +#define R0900_P2_DSTATUS 0xf212 +#define F0900_P2_CAR_LOCK 0xf2120080 +#define F0900_P2_TMGLOCK_QUALITY 0xf2120060 +#define F0900_P2_LOCK_DEFINITIF 0xf2120008 +#define F0900_P2_OVADC_DETECT 0xf2120001 /*P2_DSTATUS2*/ -#define R0900_P2_DSTATUS2 0xf213 -#define F0900_P2_DEMOD_DELOCK 0xf2130080 -#define F0900_P2_DEMOD_TIMEOUT 0xf2130040 -#define F0900_P2_MODCODRQ_SYNCTAG 0xf2130020 -#define F0900_P2_POLYPH_SATEVENT 0xf2130010 -#define F0900_P2_AGC1_NOSIGNALACK 0xf2130008 -#define F0900_P2_AGC2_OVERFLOW 0xf2130004 -#define F0900_P2_CFR_OVERFLOW 0xf2130002 -#define F0900_P2_GAMMA_OVERUNDER 0xf2130001 +#define R0900_P2_DSTATUS2 0xf213 +#define F0900_P2_DEMOD_DELOCK 0xf2130080 +#define F0900_P2_AGC1_NOSIGNALACK 0xf2130008 +#define F0900_P2_AGC2_OVERFLOW 0xf2130004 +#define F0900_P2_CFR_OVERFLOW 0xf2130002 +#define F0900_P2_GAMMA_OVERUNDER 0xf2130001 /*P2_DMDCFGMD*/ -#define R0900_P2_DMDCFGMD 0xf214 -#define F0900_P2_DVBS2_ENABLE 0xf2140080 -#define F0900_P2_DVBS1_ENABLE 0xf2140040 -#define F0900_P2_CFR_AUTOSCAN 0xf2140020 -#define F0900_P2_SCAN_ENABLE 0xf2140010 -#define F0900_P2_TUN_AUTOSCAN 0xf2140008 -#define F0900_P2_NOFORCE_RELOCK 0xf2140004 -#define F0900_P2_TUN_RNG 0xf2140003 +#define R0900_P2_DMDCFGMD 0xf214 +#define F0900_P2_DVBS2_ENABLE 0xf2140080 +#define F0900_P2_DVBS1_ENABLE 0xf2140040 +#define F0900_P2_SCAN_ENABLE 0xf2140010 +#define F0900_P2_CFR_AUTOSCAN 0xf2140008 +#define F0900_P2_TUN_RNG 0xf2140003 /*P2_DMDCFG2*/ -#define R0900_P2_DMDCFG2 0xf215 -#define F0900_P2_AGC1_WAITLOCK 0xf2150080 -#define F0900_P2_S1S2_SEQUENTIAL 0xf2150040 -#define F0900_P2_OVERFLOW_TIMEOUT 0xf2150020 -#define F0900_P2_SCANFAIL_TIMEOUT 0xf2150010 -#define F0900_P2_DMDTOUT_BACK 0xf2150008 -#define F0900_P2_CARLOCK_S1ENABLE 0xf2150004 -#define F0900_P2_COARSE_LK3MODE 0xf2150002 -#define F0900_P2_COARSE_LK2MODE 0xf2150001 +#define R0900_P2_DMDCFG2 0xf215 +#define F0900_P2_S1S2_SEQUENTIAL 0xf2150040 +#define F0900_P2_INFINITE_RELOCK 0xf2150010 /*P2_DMDISTATE*/ -#define R0900_P2_DMDISTATE 0xf216 -#define F0900_P2_I2C_NORESETDMODE 0xf2160080 -#define F0900_P2_FORCE_ETAPED 0xf2160040 -#define F0900_P2_SDMDRST_DIRCLK 0xf2160020 -#define F0900_P2_I2C_DEMOD_MODE 0xf216001f +#define R0900_P2_DMDISTATE 0xf216 +#define F0900_P2_I2C_DEMOD_MODE 0xf216001f /*P2_DMDT0M*/ -#define R0900_P2_DMDT0M 0xf217 -#define F0900_P2_DMDT0_MIN 0xf21700ff +#define R0900_P2_DMDT0M 0xf217 +#define F0900_P2_DMDT0_MIN 0xf21700ff /*P2_DMDSTATE*/ -#define R0900_P2_DMDSTATE 0xf21b -#define F0900_P2_DEMOD_LOCKED 0xf21b0080 -#define F0900_P2_HEADER_MODE 0xf21b0060 -#define F0900_P2_DEMOD_MODE 0xf21b001f +#define R0900_P2_DMDSTATE 0xf21b +#define F0900_P2_HEADER_MODE 0xf21b0060 /*P2_DMDFLYW*/ -#define R0900_P2_DMDFLYW 0xf21c -#define F0900_P2_I2C_IRQVAL 0xf21c00f0 -#define F0900_P2_FLYWHEEL_CPT 0xf21c000f +#define R0900_P2_DMDFLYW 0xf21c +#define F0900_P2_I2C_IRQVAL 0xf21c00f0 +#define F0900_P2_FLYWHEEL_CPT 0xf21c000f /*P2_DSTATUS3*/ -#define R0900_P2_DSTATUS3 0xf21d -#define F0900_P2_CFR_ZIGZAG 0xf21d0080 -#define F0900_P2_DEMOD_CFGMODE 0xf21d0060 -#define F0900_P2_GAMMA_LOWBAUDRATE 0xf21d0010 -#define F0900_P2_RELOCK_MODE 0xf21d0008 -#define F0900_P2_DEMOD_FAIL 0xf21d0004 -#define F0900_P2_ETAPE1A_DVBXMEM 0xf21d0003 +#define R0900_P2_DSTATUS3 0xf21d +#define F0900_P2_DEMOD_CFGMODE 0xf21d0060 /*P2_DMDCFG3*/ -#define R0900_P2_DMDCFG3 0xf21e -#define F0900_P2_DVBS1_TMGWAIT 0xf21e0080 -#define F0900_P2_NO_BWCENTERING 0xf21e0040 -#define F0900_P2_INV_SEQSRCH 0xf21e0020 -#define F0900_P2_DIS_SFRUPLOW_TRK 0xf21e0010 -#define F0900_P2_NOSTOP_FIFOFULL 0xf21e0008 -#define F0900_P2_LOCKTIME_MODE 0xf21e0007 +#define R0900_P2_DMDCFG3 0xf21e +#define F0900_P2_NOSTOP_FIFOFULL 0xf21e0008 /*P2_DMDCFG4*/ -#define R0900_P2_DMDCFG4 0xf21f -#define F0900_P2_TUNER_NRELAUNCH 0xf21f0008 -#define F0900_P2_DIS_CLKENABLE 0xf21f0004 -#define F0900_P2_DIS_HDRDIVLOCK 0xf21f0002 -#define F0900_P2_NO_TNRWBINIT 0xf21f0001 +#define R0900_P2_DMDCFG4 0xf21f +#define F0900_P2_TUNER_NRELAUNCH 0xf21f0008 /*P2_CORRELMANT*/ -#define R0900_P2_CORRELMANT 0xf220 -#define F0900_P2_CORREL_MANT 0xf22000ff +#define R0900_P2_CORRELMANT 0xf220 +#define F0900_P2_CORREL_MANT 0xf22000ff /*P2_CORRELABS*/ -#define R0900_P2_CORRELABS 0xf221 -#define F0900_P2_CORREL_ABS 0xf22100ff +#define R0900_P2_CORRELABS 0xf221 +#define F0900_P2_CORREL_ABS 0xf22100ff /*P2_CORRELEXP*/ -#define R0900_P2_CORRELEXP 0xf222 -#define F0900_P2_CORREL_ABSEXP 0xf22200f0 -#define F0900_P2_CORREL_EXP 0xf222000f +#define R0900_P2_CORRELEXP 0xf222 +#define F0900_P2_CORREL_ABSEXP 0xf22200f0 +#define F0900_P2_CORREL_EXP 0xf222000f /*P2_PLHMODCOD*/ -#define R0900_P2_PLHMODCOD 0xf224 -#define F0900_P2_SPECINV_DEMOD 0xf2240080 -#define F0900_P2_PLH_MODCOD 0xf224007c -#define F0900_P2_PLH_TYPE 0xf2240003 - -/*P2_AGCK32*/ -#define R0900_P2_AGCK32 0xf22b -#define F0900_P2_R3ADJOFF_32APSK 0xf22b0080 -#define F0900_P2_R2ADJOFF_32APSK 0xf22b0040 -#define F0900_P2_R1ADJOFF_32APSK 0xf22b0020 -#define F0900_P2_RADJ_32APSK 0xf22b001f +#define R0900_P2_PLHMODCOD 0xf224 +#define F0900_P2_SPECINV_DEMOD 0xf2240080 +#define F0900_P2_PLH_MODCOD 0xf224007c +#define F0900_P2_PLH_TYPE 0xf2240003 + +/*P2_DMDREG*/ +#define R0900_P2_DMDREG 0xf225 +#define F0900_P2_DECIM_PLFRAMES 0xf2250001 /*P2_AGC2O*/ -#define R0900_P2_AGC2O 0xf22c -#define F0900_P2_AGC2REF_ADJUSTING 0xf22c0080 -#define F0900_P2_AGC2_COARSEFAST 0xf22c0040 -#define F0900_P2_AGC2_LKSQRT 0xf22c0020 -#define F0900_P2_AGC2_LKMODE 0xf22c0010 -#define F0900_P2_AGC2_LKEQUA 0xf22c0008 -#define F0900_P2_AGC2_COEF 0xf22c0007 +#define R0900_P2_AGC2O 0xf22c +#define F0900_P2_AGC2_COEF 0xf22c0007 /*P2_AGC2REF*/ -#define R0900_P2_AGC2REF 0xf22d -#define F0900_P2_AGC2_REF 0xf22d00ff +#define R0900_P2_AGC2REF 0xf22d +#define F0900_P2_AGC2_REF 0xf22d00ff /*P2_AGC1ADJ*/ -#define R0900_P2_AGC1ADJ 0xf22e -#define F0900_P2_AGC1ADJ_MANUAL 0xf22e0080 -#define F0900_P2_AGC1_ADJUSTED 0xf22e017f +#define R0900_P2_AGC1ADJ 0xf22e +#define F0900_P2_AGC1_ADJUSTED 0xf22e007f /*P2_AGC2I1*/ -#define R0900_P2_AGC2I1 0xf236 -#define F0900_P2_AGC2_INTEGRATOR1 0xf23600ff +#define R0900_P2_AGC2I1 0xf236 +#define F0900_P2_AGC2_INTEGRATOR1 0xf23600ff /*P2_AGC2I0*/ -#define R0900_P2_AGC2I0 0xf237 -#define F0900_P2_AGC2_INTEGRATOR0 0xf23700ff +#define R0900_P2_AGC2I0 0xf237 +#define F0900_P2_AGC2_INTEGRATOR0 0xf23700ff /*P2_CARCFG*/ -#define R0900_P2_CARCFG 0xf238 -#define F0900_P2_CFRUPLOW_AUTO 0xf2380080 -#define F0900_P2_CFRUPLOW_TEST 0xf2380040 -#define F0900_P2_EN_CAR2CENTER 0xf2380020 -#define F0900_P2_CARHDR_NODIV8 0xf2380010 -#define F0900_P2_I2C_ROTA 0xf2380008 -#define F0900_P2_ROTAON 0xf2380004 -#define F0900_P2_PH_DET_ALGO 0xf2380003 +#define R0900_P2_CARCFG 0xf238 +#define F0900_P2_CFRUPLOW_AUTO 0xf2380080 +#define F0900_P2_CFRUPLOW_TEST 0xf2380040 +#define F0900_P2_ROTAON 0xf2380004 +#define F0900_P2_PH_DET_ALGO 0xf2380003 /*P2_ACLC*/ -#define R0900_P2_ACLC 0xf239 -#define F0900_P2_STOP_S2ALPHA 0xf23900c0 -#define F0900_P2_CAR_ALPHA_MANT 0xf2390030 -#define F0900_P2_CAR_ALPHA_EXP 0xf239000f +#define R0900_P2_ACLC 0xf239 +#define F0900_P2_CAR_ALPHA_MANT 0xf2390030 +#define F0900_P2_CAR_ALPHA_EXP 0xf239000f /*P2_BCLC*/ -#define R0900_P2_BCLC 0xf23a -#define F0900_P2_STOP_S2BETA 0xf23a00c0 -#define F0900_P2_CAR_BETA_MANT 0xf23a0030 -#define F0900_P2_CAR_BETA_EXP 0xf23a000f +#define R0900_P2_BCLC 0xf23a +#define F0900_P2_CAR_BETA_MANT 0xf23a0030 +#define F0900_P2_CAR_BETA_EXP 0xf23a000f /*P2_CARFREQ*/ -#define R0900_P2_CARFREQ 0xf23d -#define F0900_P2_KC_COARSE_EXP 0xf23d00f0 -#define F0900_P2_BETA_FREQ 0xf23d000f +#define R0900_P2_CARFREQ 0xf23d +#define F0900_P2_KC_COARSE_EXP 0xf23d00f0 +#define F0900_P2_BETA_FREQ 0xf23d000f /*P2_CARHDR*/ -#define R0900_P2_CARHDR 0xf23e -#define F0900_P2_K_FREQ_HDR 0xf23e00ff +#define R0900_P2_CARHDR 0xf23e +#define F0900_P2_K_FREQ_HDR 0xf23e00ff /*P2_LDT*/ -#define R0900_P2_LDT 0xf23f -#define F0900_P2_CARLOCK_THRES 0xf23f01ff +#define R0900_P2_LDT 0xf23f +#define F0900_P2_CARLOCK_THRES 0xf23f01ff /*P2_LDT2*/ -#define R0900_P2_LDT2 0xf240 -#define F0900_P2_CARLOCK_THRES2 0xf24001ff +#define R0900_P2_LDT2 0xf240 +#define F0900_P2_CARLOCK_THRES2 0xf24001ff /*P2_CFRICFG*/ -#define R0900_P2_CFRICFG 0xf241 -#define F0900_P2_CFRINIT_UNVALRNG 0xf2410080 -#define F0900_P2_CFRINIT_LUNVALCPT 0xf2410040 -#define F0900_P2_CFRINIT_ABORTDBL 0xf2410020 -#define F0900_P2_CFRINIT_ABORTPRED 0xf2410010 -#define F0900_P2_CFRINIT_UNVALSKIP 0xf2410008 -#define F0900_P2_CFRINIT_CSTINC 0xf2410004 -#define F0900_P2_NEG_CFRSTEP 0xf2410001 +#define R0900_P2_CFRICFG 0xf241 +#define F0900_P2_NEG_CFRSTEP 0xf2410001 /*P2_CFRUP1*/ -#define R0900_P2_CFRUP1 0xf242 -#define F0900_P2_CFR_UP1 0xf24201ff +#define R0900_P2_CFRUP1 0xf242 +#define F0900_P2_CFR_UP1 0xf24201ff /*P2_CFRUP0*/ -#define R0900_P2_CFRUP0 0xf243 -#define F0900_P2_CFR_UP0 0xf24300ff +#define R0900_P2_CFRUP0 0xf243 +#define F0900_P2_CFR_UP0 0xf24300ff /*P2_CFRLOW1*/ -#define R0900_P2_CFRLOW1 0xf246 -#define F0900_P2_CFR_LOW1 0xf24601ff +#define R0900_P2_CFRLOW1 0xf246 +#define F0900_P2_CFR_LOW1 0xf24601ff /*P2_CFRLOW0*/ -#define R0900_P2_CFRLOW0 0xf247 -#define F0900_P2_CFR_LOW0 0xf24700ff +#define R0900_P2_CFRLOW0 0xf247 +#define F0900_P2_CFR_LOW0 0xf24700ff /*P2_CFRINIT1*/ -#define R0900_P2_CFRINIT1 0xf248 -#define F0900_P2_CFR_INIT1 0xf24801ff +#define R0900_P2_CFRINIT1 0xf248 +#define F0900_P2_CFR_INIT1 0xf24801ff /*P2_CFRINIT0*/ -#define R0900_P2_CFRINIT0 0xf249 -#define F0900_P2_CFR_INIT0 0xf24900ff +#define R0900_P2_CFRINIT0 0xf249 +#define F0900_P2_CFR_INIT0 0xf24900ff /*P2_CFRINC1*/ -#define R0900_P2_CFRINC1 0xf24a -#define F0900_P2_MANUAL_CFRINC 0xf24a0080 -#define F0900_P2_CFR_INC1 0xf24a017f +#define R0900_P2_CFRINC1 0xf24a +#define F0900_P2_MANUAL_CFRINC 0xf24a0080 +#define F0900_P2_CFR_INC1 0xf24a003f /*P2_CFRINC0*/ -#define R0900_P2_CFRINC0 0xf24b -#define F0900_P2_CFR_INC0 0xf24b00f0 +#define R0900_P2_CFRINC0 0xf24b +#define F0900_P2_CFR_INC0 0xf24b00f8 /*P2_CFR2*/ -#define R0900_P2_CFR2 0xf24c -#define F0900_P2_CAR_FREQ2 0xf24c01ff +#define R0900_P2_CFR2 0xf24c +#define F0900_P2_CAR_FREQ2 0xf24c01ff /*P2_CFR1*/ -#define R0900_P2_CFR1 0xf24d -#define F0900_P2_CAR_FREQ1 0xf24d00ff +#define R0900_P2_CFR1 0xf24d +#define F0900_P2_CAR_FREQ1 0xf24d00ff /*P2_CFR0*/ -#define R0900_P2_CFR0 0xf24e -#define F0900_P2_CAR_FREQ0 0xf24e00ff +#define R0900_P2_CFR0 0xf24e +#define F0900_P2_CAR_FREQ0 0xf24e00ff /*P2_LDI*/ -#define R0900_P2_LDI 0xf24f -#define F0900_P2_LOCK_DET_INTEGR 0xf24f01ff +#define R0900_P2_LDI 0xf24f +#define F0900_P2_LOCK_DET_INTEGR 0xf24f01ff /*P2_TMGCFG*/ -#define R0900_P2_TMGCFG 0xf250 -#define F0900_P2_TMGLOCK_BETA 0xf25000c0 -#define F0900_P2_NOTMG_GROUPDELAY 0xf2500020 -#define F0900_P2_DO_TIMING_CORR 0xf2500010 -#define F0900_P2_MANUAL_SCAN 0xf250000c -#define F0900_P2_TMG_MINFREQ 0xf2500003 +#define R0900_P2_TMGCFG 0xf250 +#define F0900_P2_TMGLOCK_BETA 0xf25000c0 +#define F0900_P2_DO_TIMING_CORR 0xf2500010 +#define F0900_P2_TMG_MINFREQ 0xf2500003 /*P2_RTC*/ -#define R0900_P2_RTC 0xf251 -#define F0900_P2_TMGALPHA_EXP 0xf25100f0 -#define F0900_P2_TMGBETA_EXP 0xf251000f +#define R0900_P2_RTC 0xf251 +#define F0900_P2_TMGALPHA_EXP 0xf25100f0 +#define F0900_P2_TMGBETA_EXP 0xf251000f /*P2_RTCS2*/ -#define R0900_P2_RTCS2 0xf252 -#define F0900_P2_TMGALPHAS2_EXP 0xf25200f0 -#define F0900_P2_TMGBETAS2_EXP 0xf252000f +#define R0900_P2_RTCS2 0xf252 +#define F0900_P2_TMGALPHAS2_EXP 0xf25200f0 +#define F0900_P2_TMGBETAS2_EXP 0xf252000f /*P2_TMGTHRISE*/ -#define R0900_P2_TMGTHRISE 0xf253 -#define F0900_P2_TMGLOCK_THRISE 0xf25300ff +#define R0900_P2_TMGTHRISE 0xf253 +#define F0900_P2_TMGLOCK_THRISE 0xf25300ff /*P2_TMGTHFALL*/ -#define R0900_P2_TMGTHFALL 0xf254 -#define F0900_P2_TMGLOCK_THFALL 0xf25400ff +#define R0900_P2_TMGTHFALL 0xf254 +#define F0900_P2_TMGLOCK_THFALL 0xf25400ff /*P2_SFRUPRATIO*/ -#define R0900_P2_SFRUPRATIO 0xf255 -#define F0900_P2_SFR_UPRATIO 0xf25500ff +#define R0900_P2_SFRUPRATIO 0xf255 +#define F0900_P2_SFR_UPRATIO 0xf25500ff /*P2_SFRLOWRATIO*/ -#define R0900_P2_SFRLOWRATIO 0xf256 -#define F0900_P2_SFR_LOWRATIO 0xf25600ff +#define R0900_P2_SFRLOWRATIO 0xf256 +#define F0900_P2_SFR_LOWRATIO 0xf25600ff /*P2_KREFTMG*/ -#define R0900_P2_KREFTMG 0xf258 -#define F0900_P2_KREF_TMG 0xf25800ff +#define R0900_P2_KREFTMG 0xf258 +#define F0900_P2_KREF_TMG 0xf25800ff /*P2_SFRSTEP*/ -#define R0900_P2_SFRSTEP 0xf259 -#define F0900_P2_SFR_SCANSTEP 0xf25900f0 -#define F0900_P2_SFR_CENTERSTEP 0xf259000f +#define R0900_P2_SFRSTEP 0xf259 +#define F0900_P2_SFR_SCANSTEP 0xf25900f0 +#define F0900_P2_SFR_CENTERSTEP 0xf259000f /*P2_TMGCFG2*/ -#define R0900_P2_TMGCFG2 0xf25a -#define F0900_P2_DIS_AUTOSAMP 0xf25a0008 -#define F0900_P2_SCANINIT_QUART 0xf25a0004 -#define F0900_P2_NOTMG_DVBS1DERAT 0xf25a0002 -#define F0900_P2_SFRRATIO_FINE 0xf25a0001 +#define R0900_P2_TMGCFG2 0xf25a +#define F0900_P2_SFRRATIO_FINE 0xf25a0001 + +/*P2_KREFTMG2*/ +#define R0900_P2_KREFTMG2 0xf25b +#define F0900_P2_KREF_TMG2 0xf25b00ff /*P2_SFRINIT1*/ -#define R0900_P2_SFRINIT1 0xf25e -#define F0900_P2_SFR_INIT1 0xf25e00ff +#define R0900_P2_SFRINIT1 0xf25e +#define F0900_P2_SFR_INIT1 0xf25e007f /*P2_SFRINIT0*/ -#define R0900_P2_SFRINIT0 0xf25f -#define F0900_P2_SFR_INIT0 0xf25f00ff +#define R0900_P2_SFRINIT0 0xf25f +#define F0900_P2_SFR_INIT0 0xf25f00ff /*P2_SFRUP1*/ -#define R0900_P2_SFRUP1 0xf260 -#define F0900_P2_AUTO_GUP 0xf2600080 -#define F0900_P2_SYMB_FREQ_UP1 0xf260007f +#define R0900_P2_SFRUP1 0xf260 +#define F0900_P2_AUTO_GUP 0xf2600080 +#define F0900_P2_SYMB_FREQ_UP1 0xf260007f /*P2_SFRUP0*/ -#define R0900_P2_SFRUP0 0xf261 -#define F0900_P2_SYMB_FREQ_UP0 0xf26100ff +#define R0900_P2_SFRUP0 0xf261 +#define F0900_P2_SYMB_FREQ_UP0 0xf26100ff /*P2_SFRLOW1*/ -#define R0900_P2_SFRLOW1 0xf262 -#define F0900_P2_AUTO_GLOW 0xf2620080 -#define F0900_P2_SYMB_FREQ_LOW1 0xf262007f +#define R0900_P2_SFRLOW1 0xf262 +#define F0900_P2_AUTO_GLOW 0xf2620080 +#define F0900_P2_SYMB_FREQ_LOW1 0xf262007f /*P2_SFRLOW0*/ -#define R0900_P2_SFRLOW0 0xf263 -#define F0900_P2_SYMB_FREQ_LOW0 0xf26300ff +#define R0900_P2_SFRLOW0 0xf263 +#define F0900_P2_SYMB_FREQ_LOW0 0xf26300ff /*P2_SFR3*/ -#define R0900_P2_SFR3 0xf264 -#define F0900_P2_SYMB_FREQ3 0xf26400ff +#define R0900_P2_SFR3 0xf264 +#define F0900_P2_SYMB_FREQ3 0xf26400ff /*P2_SFR2*/ -#define R0900_P2_SFR2 0xf265 -#define F0900_P2_SYMB_FREQ2 0xf26500ff +#define R0900_P2_SFR2 0xf265 +#define F0900_P2_SYMB_FREQ2 0xf26500ff /*P2_SFR1*/ -#define R0900_P2_SFR1 0xf266 -#define F0900_P2_SYMB_FREQ1 0xf26600ff +#define R0900_P2_SFR1 0xf266 +#define F0900_P2_SYMB_FREQ1 0xf26600ff /*P2_SFR0*/ -#define R0900_P2_SFR0 0xf267 -#define F0900_P2_SYMB_FREQ0 0xf26700ff +#define R0900_P2_SFR0 0xf267 +#define F0900_P2_SYMB_FREQ0 0xf26700ff /*P2_TMGREG2*/ -#define R0900_P2_TMGREG2 0xf268 -#define F0900_P2_TMGREG2 0xf26800ff +#define R0900_P2_TMGREG2 0xf268 +#define F0900_P2_TMGREG2 0xf26800ff /*P2_TMGREG1*/ -#define R0900_P2_TMGREG1 0xf269 -#define F0900_P2_TMGREG1 0xf26900ff +#define R0900_P2_TMGREG1 0xf269 +#define F0900_P2_TMGREG1 0xf26900ff /*P2_TMGREG0*/ -#define R0900_P2_TMGREG0 0xf26a -#define F0900_P2_TMGREG0 0xf26a00ff +#define R0900_P2_TMGREG0 0xf26a +#define F0900_P2_TMGREG0 0xf26a00ff /*P2_TMGLOCK1*/ -#define R0900_P2_TMGLOCK1 0xf26b -#define F0900_P2_TMGLOCK_LEVEL1 0xf26b01ff +#define R0900_P2_TMGLOCK1 0xf26b +#define F0900_P2_TMGLOCK_LEVEL1 0xf26b01ff /*P2_TMGLOCK0*/ -#define R0900_P2_TMGLOCK0 0xf26c -#define F0900_P2_TMGLOCK_LEVEL0 0xf26c00ff +#define R0900_P2_TMGLOCK0 0xf26c +#define F0900_P2_TMGLOCK_LEVEL0 0xf26c00ff /*P2_TMGOBS*/ -#define R0900_P2_TMGOBS 0xf26d -#define F0900_P2_ROLLOFF_STATUS 0xf26d00c0 -#define F0900_P2_SCAN_SIGN 0xf26d0030 -#define F0900_P2_TMG_SCANNING 0xf26d0008 -#define F0900_P2_CHCENTERING_MODE 0xf26d0004 -#define F0900_P2_TMG_SCANFAIL 0xf26d0002 +#define R0900_P2_TMGOBS 0xf26d +#define F0900_P2_ROLLOFF_STATUS 0xf26d00c0 /*P2_EQUALCFG*/ -#define R0900_P2_EQUALCFG 0xf26f -#define F0900_P2_NOTMG_NEGALWAIT 0xf26f0080 -#define F0900_P2_EQUAL_ON 0xf26f0040 -#define F0900_P2_SEL_EQUALCOR 0xf26f0038 -#define F0900_P2_MU_EQUALDFE 0xf26f0007 +#define R0900_P2_EQUALCFG 0xf26f +#define F0900_P2_EQUAL_ON 0xf26f0040 +#define F0900_P2_MU_EQUALDFE 0xf26f0007 /*P2_EQUAI1*/ -#define R0900_P2_EQUAI1 0xf270 -#define F0900_P2_EQUA_ACCI1 0xf27001ff +#define R0900_P2_EQUAI1 0xf270 +#define F0900_P2_EQUA_ACCI1 0xf27001ff /*P2_EQUAQ1*/ -#define R0900_P2_EQUAQ1 0xf271 -#define F0900_P2_EQUA_ACCQ1 0xf27101ff +#define R0900_P2_EQUAQ1 0xf271 +#define F0900_P2_EQUA_ACCQ1 0xf27101ff /*P2_EQUAI2*/ -#define R0900_P2_EQUAI2 0xf272 -#define F0900_P2_EQUA_ACCI2 0xf27201ff +#define R0900_P2_EQUAI2 0xf272 +#define F0900_P2_EQUA_ACCI2 0xf27201ff /*P2_EQUAQ2*/ -#define R0900_P2_EQUAQ2 0xf273 -#define F0900_P2_EQUA_ACCQ2 0xf27301ff +#define R0900_P2_EQUAQ2 0xf273 +#define F0900_P2_EQUA_ACCQ2 0xf27301ff /*P2_EQUAI3*/ -#define R0900_P2_EQUAI3 0xf274 -#define F0900_P2_EQUA_ACCI3 0xf27401ff +#define R0900_P2_EQUAI3 0xf274 +#define F0900_P2_EQUA_ACCI3 0xf27401ff /*P2_EQUAQ3*/ -#define R0900_P2_EQUAQ3 0xf275 -#define F0900_P2_EQUA_ACCQ3 0xf27501ff +#define R0900_P2_EQUAQ3 0xf275 +#define F0900_P2_EQUA_ACCQ3 0xf27501ff /*P2_EQUAI4*/ -#define R0900_P2_EQUAI4 0xf276 -#define F0900_P2_EQUA_ACCI4 0xf27601ff +#define R0900_P2_EQUAI4 0xf276 +#define F0900_P2_EQUA_ACCI4 0xf27601ff /*P2_EQUAQ4*/ -#define R0900_P2_EQUAQ4 0xf277 -#define F0900_P2_EQUA_ACCQ4 0xf27701ff +#define R0900_P2_EQUAQ4 0xf277 +#define F0900_P2_EQUA_ACCQ4 0xf27701ff /*P2_EQUAI5*/ -#define R0900_P2_EQUAI5 0xf278 -#define F0900_P2_EQUA_ACCI5 0xf27801ff +#define R0900_P2_EQUAI5 0xf278 +#define F0900_P2_EQUA_ACCI5 0xf27801ff /*P2_EQUAQ5*/ -#define R0900_P2_EQUAQ5 0xf279 -#define F0900_P2_EQUA_ACCQ5 0xf27901ff +#define R0900_P2_EQUAQ5 0xf279 +#define F0900_P2_EQUA_ACCQ5 0xf27901ff /*P2_EQUAI6*/ -#define R0900_P2_EQUAI6 0xf27a -#define F0900_P2_EQUA_ACCI6 0xf27a01ff +#define R0900_P2_EQUAI6 0xf27a +#define F0900_P2_EQUA_ACCI6 0xf27a01ff /*P2_EQUAQ6*/ -#define R0900_P2_EQUAQ6 0xf27b -#define F0900_P2_EQUA_ACCQ6 0xf27b01ff +#define R0900_P2_EQUAQ6 0xf27b +#define F0900_P2_EQUA_ACCQ6 0xf27b01ff /*P2_EQUAI7*/ -#define R0900_P2_EQUAI7 0xf27c -#define F0900_P2_EQUA_ACCI7 0xf27c01ff +#define R0900_P2_EQUAI7 0xf27c +#define F0900_P2_EQUA_ACCI7 0xf27c01ff /*P2_EQUAQ7*/ -#define R0900_P2_EQUAQ7 0xf27d -#define F0900_P2_EQUA_ACCQ7 0xf27d01ff +#define R0900_P2_EQUAQ7 0xf27d +#define F0900_P2_EQUA_ACCQ7 0xf27d01ff /*P2_EQUAI8*/ -#define R0900_P2_EQUAI8 0xf27e -#define F0900_P2_EQUA_ACCI8 0xf27e01ff +#define R0900_P2_EQUAI8 0xf27e +#define F0900_P2_EQUA_ACCI8 0xf27e01ff /*P2_EQUAQ8*/ -#define R0900_P2_EQUAQ8 0xf27f -#define F0900_P2_EQUA_ACCQ8 0xf27f01ff +#define R0900_P2_EQUAQ8 0xf27f +#define F0900_P2_EQUA_ACCQ8 0xf27f01ff /*P2_NNOSDATAT1*/ -#define R0900_P2_NNOSDATAT1 0xf280 -#define F0900_P2_NOSDATAT_NORMED1 0xf28000ff +#define R0900_P2_NNOSDATAT1 0xf280 +#define F0900_P2_NOSDATAT_NORMED1 0xf28000ff /*P2_NNOSDATAT0*/ -#define R0900_P2_NNOSDATAT0 0xf281 -#define F0900_P2_NOSDATAT_NORMED0 0xf28100ff +#define R0900_P2_NNOSDATAT0 0xf281 +#define F0900_P2_NOSDATAT_NORMED0 0xf28100ff /*P2_NNOSDATA1*/ -#define R0900_P2_NNOSDATA1 0xf282 -#define F0900_P2_NOSDATA_NORMED1 0xf28200ff +#define R0900_P2_NNOSDATA1 0xf282 +#define F0900_P2_NOSDATA_NORMED1 0xf28200ff /*P2_NNOSDATA0*/ -#define R0900_P2_NNOSDATA0 0xf283 -#define F0900_P2_NOSDATA_NORMED0 0xf28300ff +#define R0900_P2_NNOSDATA0 0xf283 +#define F0900_P2_NOSDATA_NORMED0 0xf28300ff /*P2_NNOSPLHT1*/ -#define R0900_P2_NNOSPLHT1 0xf284 -#define F0900_P2_NOSPLHT_NORMED1 0xf28400ff +#define R0900_P2_NNOSPLHT1 0xf284 +#define F0900_P2_NOSPLHT_NORMED1 0xf28400ff /*P2_NNOSPLHT0*/ -#define R0900_P2_NNOSPLHT0 0xf285 -#define F0900_P2_NOSPLHT_NORMED0 0xf28500ff +#define R0900_P2_NNOSPLHT0 0xf285 +#define F0900_P2_NOSPLHT_NORMED0 0xf28500ff /*P2_NNOSPLH1*/ -#define R0900_P2_NNOSPLH1 0xf286 -#define F0900_P2_NOSPLH_NORMED1 0xf28600ff +#define R0900_P2_NNOSPLH1 0xf286 +#define F0900_P2_NOSPLH_NORMED1 0xf28600ff /*P2_NNOSPLH0*/ -#define R0900_P2_NNOSPLH0 0xf287 -#define F0900_P2_NOSPLH_NORMED0 0xf28700ff +#define R0900_P2_NNOSPLH0 0xf287 +#define F0900_P2_NOSPLH_NORMED0 0xf28700ff /*P2_NOSDATAT1*/ -#define R0900_P2_NOSDATAT1 0xf288 -#define F0900_P2_NOSDATAT_UNNORMED1 0xf28800ff +#define R0900_P2_NOSDATAT1 0xf288 +#define F0900_P2_NOSDATAT_UNNORMED1 0xf28800ff /*P2_NOSDATAT0*/ -#define R0900_P2_NOSDATAT0 0xf289 -#define F0900_P2_NOSDATAT_UNNORMED0 0xf28900ff +#define R0900_P2_NOSDATAT0 0xf289 +#define F0900_P2_NOSDATAT_UNNORMED0 0xf28900ff /*P2_NOSDATA1*/ -#define R0900_P2_NOSDATA1 0xf28a -#define F0900_P2_NOSDATA_UNNORMED1 0xf28a00ff +#define R0900_P2_NOSDATA1 0xf28a +#define F0900_P2_NOSDATA_UNNORMED1 0xf28a00ff /*P2_NOSDATA0*/ -#define R0900_P2_NOSDATA0 0xf28b -#define F0900_P2_NOSDATA_UNNORMED0 0xf28b00ff +#define R0900_P2_NOSDATA0 0xf28b +#define F0900_P2_NOSDATA_UNNORMED0 0xf28b00ff /*P2_NOSPLHT1*/ -#define R0900_P2_NOSPLHT1 0xf28c -#define F0900_P2_NOSPLHT_UNNORMED1 0xf28c00ff +#define R0900_P2_NOSPLHT1 0xf28c +#define F0900_P2_NOSPLHT_UNNORMED1 0xf28c00ff /*P2_NOSPLHT0*/ -#define R0900_P2_NOSPLHT0 0xf28d -#define F0900_P2_NOSPLHT_UNNORMED0 0xf28d00ff +#define R0900_P2_NOSPLHT0 0xf28d +#define F0900_P2_NOSPLHT_UNNORMED0 0xf28d00ff /*P2_NOSPLH1*/ -#define R0900_P2_NOSPLH1 0xf28e -#define F0900_P2_NOSPLH_UNNORMED1 0xf28e00ff +#define R0900_P2_NOSPLH1 0xf28e +#define F0900_P2_NOSPLH_UNNORMED1 0xf28e00ff /*P2_NOSPLH0*/ -#define R0900_P2_NOSPLH0 0xf28f -#define F0900_P2_NOSPLH_UNNORMED0 0xf28f00ff +#define R0900_P2_NOSPLH0 0xf28f +#define F0900_P2_NOSPLH_UNNORMED0 0xf28f00ff /*P2_CAR2CFG*/ -#define R0900_P2_CAR2CFG 0xf290 -#define F0900_P2_DESCRAMB_OFF 0xf2900080 -#define F0900_P2_PN4_SELECT 0xf2900040 -#define F0900_P2_CFR2_STOPDVBS1 0xf2900020 -#define F0900_P2_STOP_CFR2UPDATE 0xf2900010 -#define F0900_P2_STOP_NCO2UPDATE 0xf2900008 -#define F0900_P2_ROTA2ON 0xf2900004 -#define F0900_P2_PH_DET_ALGO2 0xf2900003 - -/*P2_ACLC2*/ -#define R0900_P2_ACLC2 0xf291 -#define F0900_P2_CAR2_PUNCT_ADERAT 0xf2910040 -#define F0900_P2_CAR2_ALPHA_MANT 0xf2910030 -#define F0900_P2_CAR2_ALPHA_EXP 0xf291000f - -/*P2_BCLC2*/ -#define R0900_P2_BCLC2 0xf292 -#define F0900_P2_DVBS2_NIP 0xf2920080 -#define F0900_P2_CAR2_PUNCT_BDERAT 0xf2920040 -#define F0900_P2_CAR2_BETA_MANT 0xf2920030 -#define F0900_P2_CAR2_BETA_EXP 0xf292000f +#define R0900_P2_CAR2CFG 0xf290 +#define F0900_P2_CARRIER3_DISABLE 0xf2900040 +#define F0900_P2_ROTA2ON 0xf2900004 +#define F0900_P2_PH_DET_ALGO2 0xf2900003 + +/*P2_CFR2CFR1*/ +#define R0900_P2_CFR2CFR1 0xf291 +#define F0900_P2_CFR2TOCFR1_DVBS1 0xf29100c0 +#define F0900_P2_EN_S2CAR2CENTER 0xf2910020 +#define F0900_P2_DIS_BCHERRCFR2 0xf2910010 +#define F0900_P2_CFR2TOCFR1_BETA 0xf2910007 /*P2_CFR22*/ -#define R0900_P2_CFR22 0xf293 -#define F0900_P2_CAR2_FREQ2 0xf29301ff +#define R0900_P2_CFR22 0xf293 +#define F0900_P2_CAR2_FREQ2 0xf29301ff /*P2_CFR21*/ -#define R0900_P2_CFR21 0xf294 -#define F0900_P2_CAR2_FREQ1 0xf29400ff +#define R0900_P2_CFR21 0xf294 +#define F0900_P2_CAR2_FREQ1 0xf29400ff /*P2_CFR20*/ -#define R0900_P2_CFR20 0xf295 -#define F0900_P2_CAR2_FREQ0 0xf29500ff +#define R0900_P2_CFR20 0xf295 +#define F0900_P2_CAR2_FREQ0 0xf29500ff /*P2_ACLC2S2Q*/ -#define R0900_P2_ACLC2S2Q 0xf297 -#define F0900_P2_ENAB_SPSKSYMB 0xf2970080 -#define F0900_P2_CAR2S2_QADERAT 0xf2970040 -#define F0900_P2_CAR2S2_Q_ALPH_M 0xf2970030 -#define F0900_P2_CAR2S2_Q_ALPH_E 0xf297000f +#define R0900_P2_ACLC2S2Q 0xf297 +#define F0900_P2_ENAB_SPSKSYMB 0xf2970080 +#define F0900_P2_CAR2S2_Q_ALPH_M 0xf2970030 +#define F0900_P2_CAR2S2_Q_ALPH_E 0xf297000f /*P2_ACLC2S28*/ -#define R0900_P2_ACLC2S28 0xf298 -#define F0900_P2_OLDI3Q_MODE 0xf2980080 -#define F0900_P2_CAR2S2_8ADERAT 0xf2980040 -#define F0900_P2_CAR2S2_8_ALPH_M 0xf2980030 -#define F0900_P2_CAR2S2_8_ALPH_E 0xf298000f +#define R0900_P2_ACLC2S28 0xf298 +#define F0900_P2_OLDI3Q_MODE 0xf2980080 +#define F0900_P2_CAR2S2_8_ALPH_M 0xf2980030 +#define F0900_P2_CAR2S2_8_ALPH_E 0xf298000f /*P2_ACLC2S216A*/ -#define R0900_P2_ACLC2S216A 0xf299 -#define F0900_P2_CAR2S2_16ADERAT 0xf2990040 -#define F0900_P2_CAR2S2_16A_ALPH_M 0xf2990030 -#define F0900_P2_CAR2S2_16A_ALPH_E 0xf299000f +#define R0900_P2_ACLC2S216A 0xf299 +#define F0900_P2_DIS_C3STOPA2 0xf2990080 +#define F0900_P2_CAR2S2_16ADERAT 0xf2990040 +#define F0900_P2_CAR2S2_16A_ALPH_M 0xf2990030 +#define F0900_P2_CAR2S2_16A_ALPH_E 0xf299000f /*P2_ACLC2S232A*/ -#define R0900_P2_ACLC2S232A 0xf29a -#define F0900_P2_CAR2S2_32ADERAT 0xf29a0040 -#define F0900_P2_CAR2S2_32A_ALPH_M 0xf29a0030 -#define F0900_P2_CAR2S2_32A_ALPH_E 0xf29a000f +#define R0900_P2_ACLC2S232A 0xf29a +#define F0900_P2_CAR2S2_32ADERAT 0xf29a0040 +#define F0900_P2_CAR2S2_32A_ALPH_M 0xf29a0030 +#define F0900_P2_CAR2S2_32A_ALPH_E 0xf29a000f /*P2_BCLC2S2Q*/ -#define R0900_P2_BCLC2S2Q 0xf29c -#define F0900_P2_DVBS2S2Q_NIP 0xf29c0080 -#define F0900_P2_CAR2S2_QBDERAT 0xf29c0040 -#define F0900_P2_CAR2S2_Q_BETA_M 0xf29c0030 -#define F0900_P2_CAR2S2_Q_BETA_E 0xf29c000f +#define R0900_P2_BCLC2S2Q 0xf29c +#define F0900_P2_CAR2S2_Q_BETA_M 0xf29c0030 +#define F0900_P2_CAR2S2_Q_BETA_E 0xf29c000f /*P2_BCLC2S28*/ -#define R0900_P2_BCLC2S28 0xf29d -#define F0900_P2_DVBS2S28_NIP 0xf29d0080 -#define F0900_P2_CAR2S2_8BDERAT 0xf29d0040 -#define F0900_P2_CAR2S2_8_BETA_M 0xf29d0030 -#define F0900_P2_CAR2S2_8_BETA_E 0xf29d000f +#define R0900_P2_BCLC2S28 0xf29d +#define F0900_P2_CAR2S2_8_BETA_M 0xf29d0030 +#define F0900_P2_CAR2S2_8_BETA_E 0xf29d000f /*P2_BCLC2S216A*/ -#define R0900_P2_BCLC2S216A 0xf29e -#define F0900_P2_DVBS2S216A_NIP 0xf29e0080 -#define F0900_P2_CAR2S2_16BDERAT 0xf29e0040 -#define F0900_P2_CAR2S2_16A_BETA_M 0xf29e0030 -#define F0900_P2_CAR2S2_16A_BETA_E 0xf29e000f +#define R0900_P2_BCLC2S216A 0xf29e /*P2_BCLC2S232A*/ -#define R0900_P2_BCLC2S232A 0xf29f -#define F0900_P2_DVBS2S232A_NIP 0xf29f0080 -#define F0900_P2_CAR2S2_32BDERAT 0xf29f0040 -#define F0900_P2_CAR2S2_32A_BETA_M 0xf29f0030 -#define F0900_P2_CAR2S2_32A_BETA_E 0xf29f000f +#define R0900_P2_BCLC2S232A 0xf29f /*P2_PLROOT2*/ -#define R0900_P2_PLROOT2 0xf2ac -#define F0900_P2_SHORTFR_DISABLE 0xf2ac0080 -#define F0900_P2_LONGFR_DISABLE 0xf2ac0040 -#define F0900_P2_DUMMYPL_DISABLE 0xf2ac0020 -#define F0900_P2_SHORTFR_AVOID 0xf2ac0010 -#define F0900_P2_PLSCRAMB_MODE 0xf2ac000c -#define F0900_P2_PLSCRAMB_ROOT2 0xf2ac0003 +#define R0900_P2_PLROOT2 0xf2ac +#define F0900_P2_PLSCRAMB_MODE 0xf2ac000c +#define F0900_P2_PLSCRAMB_ROOT2 0xf2ac0003 /*P2_PLROOT1*/ -#define R0900_P2_PLROOT1 0xf2ad -#define F0900_P2_PLSCRAMB_ROOT1 0xf2ad00ff +#define R0900_P2_PLROOT1 0xf2ad +#define F0900_P2_PLSCRAMB_ROOT1 0xf2ad00ff /*P2_PLROOT0*/ -#define R0900_P2_PLROOT0 0xf2ae -#define F0900_P2_PLSCRAMB_ROOT0 0xf2ae00ff +#define R0900_P2_PLROOT0 0xf2ae +#define F0900_P2_PLSCRAMB_ROOT0 0xf2ae00ff /*P2_MODCODLST0*/ -#define R0900_P2_MODCODLST0 0xf2b0 -#define F0900_P2_EN_TOKEN31 0xf2b00080 -#define F0900_P2_SYNCTAG_SELECT 0xf2b00040 -#define F0900_P2_MODCODRQ_MODE 0xf2b00030 +#define R0900_P2_MODCODLST0 0xf2b0 /*P2_MODCODLST1*/ -#define R0900_P2_MODCODLST1 0xf2b1 -#define F0900_P2_DIS_MODCOD29 0xf2b100f0 -#define F0900_P2_DIS_32PSK_9_10 0xf2b1000f +#define R0900_P2_MODCODLST1 0xf2b1 +#define F0900_P2_DIS_MODCOD29 0xf2b100f0 +#define F0900_P2_DIS_32PSK_9_10 0xf2b1000f /*P2_MODCODLST2*/ -#define R0900_P2_MODCODLST2 0xf2b2 -#define F0900_P2_DIS_32PSK_8_9 0xf2b200f0 -#define F0900_P2_DIS_32PSK_5_6 0xf2b2000f +#define R0900_P2_MODCODLST2 0xf2b2 +#define F0900_P2_DIS_32PSK_8_9 0xf2b200f0 +#define F0900_P2_DIS_32PSK_5_6 0xf2b2000f /*P2_MODCODLST3*/ -#define R0900_P2_MODCODLST3 0xf2b3 -#define F0900_P2_DIS_32PSK_4_5 0xf2b300f0 -#define F0900_P2_DIS_32PSK_3_4 0xf2b3000f +#define R0900_P2_MODCODLST3 0xf2b3 +#define F0900_P2_DIS_32PSK_4_5 0xf2b300f0 +#define F0900_P2_DIS_32PSK_3_4 0xf2b3000f /*P2_MODCODLST4*/ -#define R0900_P2_MODCODLST4 0xf2b4 -#define F0900_P2_DIS_16PSK_9_10 0xf2b400f0 -#define F0900_P2_DIS_16PSK_8_9 0xf2b4000f +#define R0900_P2_MODCODLST4 0xf2b4 +#define F0900_P2_DIS_16PSK_9_10 0xf2b400f0 +#define F0900_P2_DIS_16PSK_8_9 0xf2b4000f /*P2_MODCODLST5*/ -#define R0900_P2_MODCODLST5 0xf2b5 -#define F0900_P2_DIS_16PSK_5_6 0xf2b500f0 -#define F0900_P2_DIS_16PSK_4_5 0xf2b5000f +#define R0900_P2_MODCODLST5 0xf2b5 +#define F0900_P2_DIS_16PSK_5_6 0xf2b500f0 +#define F0900_P2_DIS_16PSK_4_5 0xf2b5000f /*P2_MODCODLST6*/ -#define R0900_P2_MODCODLST6 0xf2b6 -#define F0900_P2_DIS_16PSK_3_4 0xf2b600f0 -#define F0900_P2_DIS_16PSK_2_3 0xf2b6000f +#define R0900_P2_MODCODLST6 0xf2b6 +#define F0900_P2_DIS_16PSK_3_4 0xf2b600f0 +#define F0900_P2_DIS_16PSK_2_3 0xf2b6000f /*P2_MODCODLST7*/ -#define R0900_P2_MODCODLST7 0xf2b7 -#define F0900_P2_DIS_8P_9_10 0xf2b700f0 -#define F0900_P2_DIS_8P_8_9 0xf2b7000f +#define R0900_P2_MODCODLST7 0xf2b7 +#define F0900_P2_DIS_8P_9_10 0xf2b700f0 +#define F0900_P2_DIS_8P_8_9 0xf2b7000f /*P2_MODCODLST8*/ -#define R0900_P2_MODCODLST8 0xf2b8 -#define F0900_P2_DIS_8P_5_6 0xf2b800f0 -#define F0900_P2_DIS_8P_3_4 0xf2b8000f +#define R0900_P2_MODCODLST8 0xf2b8 +#define F0900_P2_DIS_8P_5_6 0xf2b800f0 +#define F0900_P2_DIS_8P_3_4 0xf2b8000f /*P2_MODCODLST9*/ -#define R0900_P2_MODCODLST9 0xf2b9 -#define F0900_P2_DIS_8P_2_3 0xf2b900f0 -#define F0900_P2_DIS_8P_3_5 0xf2b9000f +#define R0900_P2_MODCODLST9 0xf2b9 +#define F0900_P2_DIS_8P_2_3 0xf2b900f0 +#define F0900_P2_DIS_8P_3_5 0xf2b9000f /*P2_MODCODLSTA*/ -#define R0900_P2_MODCODLSTA 0xf2ba -#define F0900_P2_DIS_QP_9_10 0xf2ba00f0 -#define F0900_P2_DIS_QP_8_9 0xf2ba000f +#define R0900_P2_MODCODLSTA 0xf2ba +#define F0900_P2_DIS_QP_9_10 0xf2ba00f0 +#define F0900_P2_DIS_QP_8_9 0xf2ba000f /*P2_MODCODLSTB*/ -#define R0900_P2_MODCODLSTB 0xf2bb -#define F0900_P2_DIS_QP_5_6 0xf2bb00f0 -#define F0900_P2_DIS_QP_4_5 0xf2bb000f +#define R0900_P2_MODCODLSTB 0xf2bb +#define F0900_P2_DIS_QP_5_6 0xf2bb00f0 +#define F0900_P2_DIS_QP_4_5 0xf2bb000f /*P2_MODCODLSTC*/ -#define R0900_P2_MODCODLSTC 0xf2bc -#define F0900_P2_DIS_QP_3_4 0xf2bc00f0 -#define F0900_P2_DIS_QP_2_3 0xf2bc000f +#define R0900_P2_MODCODLSTC 0xf2bc +#define F0900_P2_DIS_QP_3_4 0xf2bc00f0 +#define F0900_P2_DIS_QP_2_3 0xf2bc000f /*P2_MODCODLSTD*/ -#define R0900_P2_MODCODLSTD 0xf2bd -#define F0900_P2_DIS_QP_3_5 0xf2bd00f0 -#define F0900_P2_DIS_QP_1_2 0xf2bd000f +#define R0900_P2_MODCODLSTD 0xf2bd +#define F0900_P2_DIS_QP_3_5 0xf2bd00f0 +#define F0900_P2_DIS_QP_1_2 0xf2bd000f /*P2_MODCODLSTE*/ -#define R0900_P2_MODCODLSTE 0xf2be -#define F0900_P2_DIS_QP_2_5 0xf2be00f0 -#define F0900_P2_DIS_QP_1_3 0xf2be000f +#define R0900_P2_MODCODLSTE 0xf2be +#define F0900_P2_DIS_QP_2_5 0xf2be00f0 +#define F0900_P2_DIS_QP_1_3 0xf2be000f /*P2_MODCODLSTF*/ -#define R0900_P2_MODCODLSTF 0xf2bf -#define F0900_P2_DIS_QP_1_4 0xf2bf00f0 -#define F0900_P2_DDEMOD_SET 0xf2bf0002 -#define F0900_P2_DDEMOD_MASK 0xf2bf0001 +#define R0900_P2_MODCODLSTF 0xf2bf +#define F0900_P2_DIS_QP_1_4 0xf2bf00f0 + +/*P2_GAUSSR0*/ +#define R0900_P2_GAUSSR0 0xf2c0 +#define F0900_P2_EN_CCIMODE 0xf2c00080 +#define F0900_P2_R0_GAUSSIEN 0xf2c0007f + +/*P2_CCIR0*/ +#define R0900_P2_CCIR0 0xf2c1 +#define F0900_P2_CCIDETECT_PLHONLY 0xf2c10080 +#define F0900_P2_R0_CCI 0xf2c1007f + +/*P2_CCIQUANT*/ +#define R0900_P2_CCIQUANT 0xf2c2 +#define F0900_P2_CCI_BETA 0xf2c200e0 +#define F0900_P2_CCI_QUANT 0xf2c2001f + +/*P2_CCITHRES*/ +#define R0900_P2_CCITHRES 0xf2c3 +#define F0900_P2_CCI_THRESHOLD 0xf2c300ff + +/*P2_CCIACC*/ +#define R0900_P2_CCIACC 0xf2c4 +#define F0900_P2_CCI_VALUE 0xf2c400ff /*P2_DMDRESCFG*/ -#define R0900_P2_DMDRESCFG 0xf2c6 -#define F0900_P2_DMDRES_RESET 0xf2c60080 -#define F0900_P2_DMDRES_NOISESQR 0xf2c60010 -#define F0900_P2_DMDRES_STRALL 0xf2c60008 -#define F0900_P2_DMDRES_NEWONLY 0xf2c60004 -#define F0900_P2_DMDRES_NOSTORE 0xf2c60002 -#define F0900_P2_DMDRES_AGC2MEM 0xf2c60001 +#define R0900_P2_DMDRESCFG 0xf2c6 +#define F0900_P2_DMDRES_RESET 0xf2c60080 +#define F0900_P2_DMDRES_STRALL 0xf2c60008 +#define F0900_P2_DMDRES_NEWONLY 0xf2c60004 +#define F0900_P2_DMDRES_NOSTORE 0xf2c60002 /*P2_DMDRESADR*/ -#define R0900_P2_DMDRESADR 0xf2c7 -#define F0900_P2_SUSP_PREDCANAL 0xf2c70080 -#define F0900_P2_DMDRES_VALIDCFR 0xf2c70040 -#define F0900_P2_DMDRES_MEMFULL 0xf2c70030 -#define F0900_P2_DMDRES_RESNBR 0xf2c7000f +#define R0900_P2_DMDRESADR 0xf2c7 +#define F0900_P2_DMDRES_VALIDCFR 0xf2c70040 +#define F0900_P2_DMDRES_MEMFULL 0xf2c70030 +#define F0900_P2_DMDRES_RESNBR 0xf2c7000f /*P2_DMDRESDATA7*/ -#define R0900_P2_DMDRESDATA7 0xf2c8 -#define F0900_P2_DMDRES_DATA7 0xf2c800ff +#define R0900_P2_DMDRESDATA7 0xf2c8 +#define F0900_P2_DMDRES_DATA7 0xf2c800ff /*P2_DMDRESDATA6*/ -#define R0900_P2_DMDRESDATA6 0xf2c9 -#define F0900_P2_DMDRES_DATA6 0xf2c900ff +#define R0900_P2_DMDRESDATA6 0xf2c9 +#define F0900_P2_DMDRES_DATA6 0xf2c900ff /*P2_DMDRESDATA5*/ -#define R0900_P2_DMDRESDATA5 0xf2ca -#define F0900_P2_DMDRES_DATA5 0xf2ca00ff +#define R0900_P2_DMDRESDATA5 0xf2ca +#define F0900_P2_DMDRES_DATA5 0xf2ca00ff /*P2_DMDRESDATA4*/ -#define R0900_P2_DMDRESDATA4 0xf2cb -#define F0900_P2_DMDRES_DATA4 0xf2cb00ff +#define R0900_P2_DMDRESDATA4 0xf2cb +#define F0900_P2_DMDRES_DATA4 0xf2cb00ff /*P2_DMDRESDATA3*/ -#define R0900_P2_DMDRESDATA3 0xf2cc -#define F0900_P2_DMDRES_DATA3 0xf2cc00ff +#define R0900_P2_DMDRESDATA3 0xf2cc +#define F0900_P2_DMDRES_DATA3 0xf2cc00ff /*P2_DMDRESDATA2*/ -#define R0900_P2_DMDRESDATA2 0xf2cd -#define F0900_P2_DMDRES_DATA2 0xf2cd00ff +#define R0900_P2_DMDRESDATA2 0xf2cd +#define F0900_P2_DMDRES_DATA2 0xf2cd00ff /*P2_DMDRESDATA1*/ -#define R0900_P2_DMDRESDATA1 0xf2ce -#define F0900_P2_DMDRES_DATA1 0xf2ce00ff +#define R0900_P2_DMDRESDATA1 0xf2ce +#define F0900_P2_DMDRES_DATA1 0xf2ce00ff /*P2_DMDRESDATA0*/ -#define R0900_P2_DMDRESDATA0 0xf2cf -#define F0900_P2_DMDRES_DATA0 0xf2cf00ff +#define R0900_P2_DMDRESDATA0 0xf2cf +#define F0900_P2_DMDRES_DATA0 0xf2cf00ff /*P2_FFEI1*/ -#define R0900_P2_FFEI1 0xf2d0 -#define F0900_P2_FFE_ACCI1 0xf2d001ff +#define R0900_P2_FFEI1 0xf2d0 +#define F0900_P2_FFE_ACCI1 0xf2d001ff /*P2_FFEQ1*/ -#define R0900_P2_FFEQ1 0xf2d1 -#define F0900_P2_FFE_ACCQ1 0xf2d101ff +#define R0900_P2_FFEQ1 0xf2d1 +#define F0900_P2_FFE_ACCQ1 0xf2d101ff /*P2_FFEI2*/ -#define R0900_P2_FFEI2 0xf2d2 -#define F0900_P2_FFE_ACCI2 0xf2d201ff +#define R0900_P2_FFEI2 0xf2d2 +#define F0900_P2_FFE_ACCI2 0xf2d201ff /*P2_FFEQ2*/ -#define R0900_P2_FFEQ2 0xf2d3 -#define F0900_P2_FFE_ACCQ2 0xf2d301ff +#define R0900_P2_FFEQ2 0xf2d3 +#define F0900_P2_FFE_ACCQ2 0xf2d301ff /*P2_FFEI3*/ -#define R0900_P2_FFEI3 0xf2d4 -#define F0900_P2_FFE_ACCI3 0xf2d401ff +#define R0900_P2_FFEI3 0xf2d4 +#define F0900_P2_FFE_ACCI3 0xf2d401ff /*P2_FFEQ3*/ -#define R0900_P2_FFEQ3 0xf2d5 -#define F0900_P2_FFE_ACCQ3 0xf2d501ff +#define R0900_P2_FFEQ3 0xf2d5 +#define F0900_P2_FFE_ACCQ3 0xf2d501ff /*P2_FFEI4*/ -#define R0900_P2_FFEI4 0xf2d6 -#define F0900_P2_FFE_ACCI4 0xf2d601ff +#define R0900_P2_FFEI4 0xf2d6 +#define F0900_P2_FFE_ACCI4 0xf2d601ff /*P2_FFEQ4*/ -#define R0900_P2_FFEQ4 0xf2d7 -#define F0900_P2_FFE_ACCQ4 0xf2d701ff +#define R0900_P2_FFEQ4 0xf2d7 +#define F0900_P2_FFE_ACCQ4 0xf2d701ff /*P2_FFECFG*/ -#define R0900_P2_FFECFG 0xf2d8 -#define F0900_P2_EQUALFFE_ON 0xf2d80040 -#define F0900_P2_EQUAL_USEDSYMB 0xf2d80030 -#define F0900_P2_MU_EQUALFFE 0xf2d80007 +#define R0900_P2_FFECFG 0xf2d8 +#define F0900_P2_EQUALFFE_ON 0xf2d80040 +#define F0900_P2_MU_EQUALFFE 0xf2d80007 /*P2_TNRCFG*/ -#define R0900_P2_TNRCFG 0xf2e0 -#define F0900_P2_TUN_ACKFAIL 0xf2e00080 -#define F0900_P2_TUN_TYPE 0xf2e00070 -#define F0900_P2_TUN_SECSTOP 0xf2e00008 -#define F0900_P2_TUN_VCOSRCH 0xf2e00004 -#define F0900_P2_TUN_MADDRESS 0xf2e00003 +#define R0900_P2_TNRCFG 0xf2e0 +#define F0900_P2_TUN_ACKFAIL 0xf2e00080 +#define F0900_P2_TUN_TYPE 0xf2e00070 +#define F0900_P2_TUN_SECSTOP 0xf2e00008 +#define F0900_P2_TUN_VCOSRCH 0xf2e00004 +#define F0900_P2_TUN_MADDRESS 0xf2e00003 /*P2_TNRCFG2*/ -#define R0900_P2_TNRCFG2 0xf2e1 -#define F0900_P2_TUN_IQSWAP 0xf2e10080 -#define F0900_P2_STB6110_STEP2MHZ 0xf2e10040 -#define F0900_P2_STB6120_DBLI2C 0xf2e10020 -#define F0900_P2_DIS_FCCK 0xf2e10010 -#define F0900_P2_DIS_LPEN 0xf2e10008 -#define F0900_P2_DIS_BWCALC 0xf2e10004 -#define F0900_P2_SHORT_WAITSTATES 0xf2e10002 -#define F0900_P2_DIS_2BWAGC1 0xf2e10001 +#define R0900_P2_TNRCFG2 0xf2e1 +#define F0900_P2_TUN_IQSWAP 0xf2e10080 +#define F0900_P2_DIS_BWCALC 0xf2e10004 +#define F0900_P2_SHORT_WAITSTATES 0xf2e10002 /*P2_TNRXTAL*/ -#define R0900_P2_TNRXTAL 0xf2e4 -#define F0900_P2_TUN_MCLKDECIMAL 0xf2e400e0 -#define F0900_P2_TUN_XTALFREQ 0xf2e4001f +#define R0900_P2_TNRXTAL 0xf2e4 +#define F0900_P2_TUN_XTALFREQ 0xf2e4001f /*P2_TNRSTEPS*/ -#define R0900_P2_TNRSTEPS 0xf2e7 -#define F0900_P2_TUNER_BW1P6 0xf2e70080 -#define F0900_P2_BWINC_OFFSET 0xf2e70070 -#define F0900_P2_SOFTSTEP_RNG 0xf2e70008 -#define F0900_P2_TUN_BWOFFSET 0xf2e70107 +#define R0900_P2_TNRSTEPS 0xf2e7 +#define F0900_P2_TUNER_BW0P125 0xf2e70080 +#define F0900_P2_BWINC_OFFSET 0xf2e70170 +#define F0900_P2_SOFTSTEP_RNG 0xf2e70008 +#define F0900_P2_TUN_BWOFFSET 0xf2e70007 /*P2_TNRGAIN*/ -#define R0900_P2_TNRGAIN 0xf2e8 -#define F0900_P2_TUN_KDIVEN 0xf2e800c0 -#define F0900_P2_STB6X00_OCK 0xf2e80030 -#define F0900_P2_TUN_GAIN 0xf2e8000f +#define R0900_P2_TNRGAIN 0xf2e8 +#define F0900_P2_TUN_KDIVEN 0xf2e800c0 +#define F0900_P2_STB6X00_OCK 0xf2e80030 +#define F0900_P2_TUN_GAIN 0xf2e8000f /*P2_TNRRF1*/ -#define R0900_P2_TNRRF1 0xf2e9 -#define F0900_P2_TUN_RFFREQ2 0xf2e900ff +#define R0900_P2_TNRRF1 0xf2e9 +#define F0900_P2_TUN_RFFREQ2 0xf2e900ff /*P2_TNRRF0*/ -#define R0900_P2_TNRRF0 0xf2ea -#define F0900_P2_TUN_RFFREQ1 0xf2ea00ff +#define R0900_P2_TNRRF0 0xf2ea +#define F0900_P2_TUN_RFFREQ1 0xf2ea00ff /*P2_TNRBW*/ -#define R0900_P2_TNRBW 0xf2eb -#define F0900_P2_TUN_RFFREQ0 0xf2eb00c0 -#define F0900_P2_TUN_BW 0xf2eb003f +#define R0900_P2_TNRBW 0xf2eb +#define F0900_P2_TUN_RFFREQ0 0xf2eb00c0 +#define F0900_P2_TUN_BW 0xf2eb003f /*P2_TNRADJ*/ -#define R0900_P2_TNRADJ 0xf2ec -#define F0900_P2_STB61X0_RCLK 0xf2ec0080 -#define F0900_P2_STB61X0_CALTIME 0xf2ec0040 -#define F0900_P2_STB6X00_DLB 0xf2ec0038 -#define F0900_P2_STB6000_FCL 0xf2ec0007 +#define R0900_P2_TNRADJ 0xf2ec +#define F0900_P2_STB61X0_CALTIME 0xf2ec0040 /*P2_TNRCTL2*/ -#define R0900_P2_TNRCTL2 0xf2ed -#define F0900_P2_STB61X0_LCP1_RCCKOFF 0xf2ed0080 -#define F0900_P2_STB61X0_LCP0 0xf2ed0040 -#define F0900_P2_STB61X0_XTOUT_RFOUTS 0xf2ed0020 -#define F0900_P2_STB61X0_XTON_MCKDV 0xf2ed0010 -#define F0900_P2_STB61X0_CALOFF_DCOFF 0xf2ed0008 -#define F0900_P2_STB6110_LPT 0xf2ed0004 -#define F0900_P2_STB6110_RX 0xf2ed0002 -#define F0900_P2_STB6110_SYN 0xf2ed0001 +#define R0900_P2_TNRCTL2 0xf2ed +#define F0900_P2_STB61X0_RCCKOFF 0xf2ed0080 +#define F0900_P2_STB61X0_ICP_SDOFF 0xf2ed0040 +#define F0900_P2_STB61X0_DCLOOPOFF 0xf2ed0020 +#define F0900_P2_STB61X0_REFOUTSEL 0xf2ed0010 +#define F0900_P2_STB61X0_CALOFF 0xf2ed0008 +#define F0900_P2_STB6XX0_LPT_BEN 0xf2ed0004 +#define F0900_P2_STB6XX0_RX_OSCP 0xf2ed0002 +#define F0900_P2_STB6XX0_SYN 0xf2ed0001 /*P2_TNRCFG3*/ -#define R0900_P2_TNRCFG3 0xf2ee -#define F0900_P2_STB6120_DISCTRL1 0xf2ee0080 -#define F0900_P2_STB6120_INVORDER 0xf2ee0040 -#define F0900_P2_STB6120_ENCTRL6 0xf2ee0020 -#define F0900_P2_TUN_PLLFREQ 0xf2ee001c -#define F0900_P2_TUN_I2CFREQ_MODE 0xf2ee0003 +#define R0900_P2_TNRCFG3 0xf2ee +#define F0900_P2_TUN_PLLFREQ 0xf2ee001c +#define F0900_P2_TUN_I2CFREQ_MODE 0xf2ee0003 /*P2_TNRLAUNCH*/ -#define R0900_P2_TNRLAUNCH 0xf2f0 +#define R0900_P2_TNRLAUNCH 0xf2f0 /*P2_TNRLD*/ -#define R0900_P2_TNRLD 0xf2f0 -#define F0900_P2_TUNLD_VCOING 0xf2f00080 -#define F0900_P2_TUN_REG1FAIL 0xf2f00040 -#define F0900_P2_TUN_REG2FAIL 0xf2f00020 -#define F0900_P2_TUN_REG3FAIL 0xf2f00010 -#define F0900_P2_TUN_REG4FAIL 0xf2f00008 -#define F0900_P2_TUN_REG5FAIL 0xf2f00004 -#define F0900_P2_TUN_BWING 0xf2f00002 -#define F0900_P2_TUN_LOCKED 0xf2f00001 +#define R0900_P2_TNRLD 0xf2f0 +#define F0900_P2_TUNLD_VCOING 0xf2f00080 +#define F0900_P2_TUN_REG1FAIL 0xf2f00040 +#define F0900_P2_TUN_REG2FAIL 0xf2f00020 +#define F0900_P2_TUN_REG3FAIL 0xf2f00010 +#define F0900_P2_TUN_REG4FAIL 0xf2f00008 +#define F0900_P2_TUN_REG5FAIL 0xf2f00004 +#define F0900_P2_TUN_BWING 0xf2f00002 +#define F0900_P2_TUN_LOCKED 0xf2f00001 /*P2_TNROBSL*/ -#define R0900_P2_TNROBSL 0xf2f6 -#define F0900_P2_TUN_I2CABORTED 0xf2f60080 -#define F0900_P2_TUN_LPEN 0xf2f60040 -#define F0900_P2_TUN_FCCK 0xf2f60020 -#define F0900_P2_TUN_I2CLOCKED 0xf2f60010 -#define F0900_P2_TUN_PROGDONE 0xf2f6000c -#define F0900_P2_TUN_RFRESTE1 0xf2f60003 +#define R0900_P2_TNROBSL 0xf2f6 +#define F0900_P2_TUN_I2CABORTED 0xf2f60080 +#define F0900_P2_TUN_LPEN 0xf2f60040 +#define F0900_P2_TUN_FCCK 0xf2f60020 +#define F0900_P2_TUN_I2CLOCKED 0xf2f60010 +#define F0900_P2_TUN_PROGDONE 0xf2f6000c +#define F0900_P2_TUN_RFRESTE1 0xf2f60003 /*P2_TNRRESTE*/ -#define R0900_P2_TNRRESTE 0xf2f7 -#define F0900_P2_TUN_RFRESTE0 0xf2f700ff +#define R0900_P2_TNRRESTE 0xf2f7 +#define F0900_P2_TUN_RFRESTE0 0xf2f700ff /*P2_SMAPCOEF7*/ -#define R0900_P2_SMAPCOEF7 0xf300 -#define F0900_P2_DIS_QSCALE 0xf3000080 -#define F0900_P2_SMAPCOEF_Q_LLR12 0xf300017f +#define R0900_P2_SMAPCOEF7 0xf300 +#define F0900_P2_DIS_QSCALE 0xf3000080 +#define F0900_P2_SMAPCOEF_Q_LLR12 0xf300017f /*P2_SMAPCOEF6*/ -#define R0900_P2_SMAPCOEF6 0xf301 -#define F0900_P2_DIS_NEWSCALE 0xf3010008 -#define F0900_P2_ADJ_8PSKLLR1 0xf3010004 -#define F0900_P2_OLD_8PSKLLR1 0xf3010002 -#define F0900_P2_DIS_AB8PSK 0xf3010001 +#define R0900_P2_SMAPCOEF6 0xf301 +#define F0900_P2_ADJ_8PSKLLR1 0xf3010004 +#define F0900_P2_OLD_8PSKLLR1 0xf3010002 +#define F0900_P2_DIS_AB8PSK 0xf3010001 /*P2_SMAPCOEF5*/ -#define R0900_P2_SMAPCOEF5 0xf302 -#define F0900_P2_DIS_8SCALE 0xf3020080 -#define F0900_P2_SMAPCOEF_8P_LLR23 0xf302017f +#define R0900_P2_SMAPCOEF5 0xf302 +#define F0900_P2_DIS_8SCALE 0xf3020080 +#define F0900_P2_SMAPCOEF_8P_LLR23 0xf302017f + +/*P2_NCO2MAX1*/ +#define R0900_P2_NCO2MAX1 0xf314 +#define F0900_P2_TETA2_MAXVABS1 0xf31400ff + +/*P2_NCO2MAX0*/ +#define R0900_P2_NCO2MAX0 0xf315 +#define F0900_P2_TETA2_MAXVABS0 0xf31500ff + +/*P2_NCO2FR1*/ +#define R0900_P2_NCO2FR1 0xf316 +#define F0900_P2_NCO2FINAL_ANGLE1 0xf31600ff + +/*P2_NCO2FR0*/ +#define R0900_P2_NCO2FR0 0xf317 +#define F0900_P2_NCO2FINAL_ANGLE0 0xf31700ff + +/*P2_CFR2AVRGE1*/ +#define R0900_P2_CFR2AVRGE1 0xf318 +#define F0900_P2_I2C_CFR2AVERAGE1 0xf31800ff + +/*P2_CFR2AVRGE0*/ +#define R0900_P2_CFR2AVRGE0 0xf319 +#define F0900_P2_I2C_CFR2AVERAGE0 0xf31900ff /*P2_DMDPLHSTAT*/ -#define R0900_P2_DMDPLHSTAT 0xf320 -#define F0900_P2_PLH_STATISTIC 0xf32000ff +#define R0900_P2_DMDPLHSTAT 0xf320 +#define F0900_P2_PLH_STATISTIC 0xf32000ff /*P2_LOCKTIME3*/ -#define R0900_P2_LOCKTIME3 0xf322 -#define F0900_P2_DEMOD_LOCKTIME3 0xf32200ff +#define R0900_P2_LOCKTIME3 0xf322 +#define F0900_P2_DEMOD_LOCKTIME3 0xf32200ff /*P2_LOCKTIME2*/ -#define R0900_P2_LOCKTIME2 0xf323 -#define F0900_P2_DEMOD_LOCKTIME2 0xf32300ff +#define R0900_P2_LOCKTIME2 0xf323 +#define F0900_P2_DEMOD_LOCKTIME2 0xf32300ff /*P2_LOCKTIME1*/ -#define R0900_P2_LOCKTIME1 0xf324 -#define F0900_P2_DEMOD_LOCKTIME1 0xf32400ff +#define R0900_P2_LOCKTIME1 0xf324 +#define F0900_P2_DEMOD_LOCKTIME1 0xf32400ff /*P2_LOCKTIME0*/ -#define R0900_P2_LOCKTIME0 0xf325 -#define F0900_P2_DEMOD_LOCKTIME0 0xf32500ff +#define R0900_P2_LOCKTIME0 0xf325 +#define F0900_P2_DEMOD_LOCKTIME0 0xf32500ff /*P2_VITSCALE*/ -#define R0900_P2_VITSCALE 0xf332 -#define F0900_P2_NVTH_NOSRANGE 0xf3320080 -#define F0900_P2_VERROR_MAXMODE 0xf3320040 -#define F0900_P2_KDIV_MODE 0xf3320030 -#define F0900_P2_NSLOWSN_LOCKED 0xf3320008 -#define F0900_P2_DELOCK_PRFLOSS 0xf3320004 -#define F0900_P2_DIS_RSFLOCK 0xf3320002 +#define R0900_P2_VITSCALE 0xf332 +#define F0900_P2_NVTH_NOSRANGE 0xf3320080 +#define F0900_P2_VERROR_MAXMODE 0xf3320040 +#define F0900_P2_NSLOWSN_LOCKED 0xf3320008 +#define F0900_P2_DIS_RSFLOCK 0xf3320002 /*P2_FECM*/ -#define R0900_P2_FECM 0xf333 -#define F0900_P2_DSS_DVB 0xf3330080 -#define F0900_P2_DEMOD_BYPASS 0xf3330040 -#define F0900_P2_CMP_SLOWMODE 0xf3330020 -#define F0900_P2_DSS_SRCH 0xf3330010 -#define F0900_P2_DIFF_MODEVIT 0xf3330004 -#define F0900_P2_SYNCVIT 0xf3330002 -#define F0900_P2_IQINV 0xf3330001 +#define R0900_P2_FECM 0xf333 +#define F0900_P2_DSS_DVB 0xf3330080 +#define F0900_P2_DSS_SRCH 0xf3330010 +#define F0900_P2_SYNCVIT 0xf3330002 +#define F0900_P2_IQINV 0xf3330001 /*P2_VTH12*/ -#define R0900_P2_VTH12 0xf334 -#define F0900_P2_VTH12 0xf33400ff +#define R0900_P2_VTH12 0xf334 +#define F0900_P2_VTH12 0xf33400ff /*P2_VTH23*/ -#define R0900_P2_VTH23 0xf335 -#define F0900_P2_VTH23 0xf33500ff +#define R0900_P2_VTH23 0xf335 +#define F0900_P2_VTH23 0xf33500ff /*P2_VTH34*/ -#define R0900_P2_VTH34 0xf336 -#define F0900_P2_VTH34 0xf33600ff +#define R0900_P2_VTH34 0xf336 +#define F0900_P2_VTH34 0xf33600ff /*P2_VTH56*/ -#define R0900_P2_VTH56 0xf337 -#define F0900_P2_VTH56 0xf33700ff +#define R0900_P2_VTH56 0xf337 +#define F0900_P2_VTH56 0xf33700ff /*P2_VTH67*/ -#define R0900_P2_VTH67 0xf338 -#define F0900_P2_VTH67 0xf33800ff +#define R0900_P2_VTH67 0xf338 +#define F0900_P2_VTH67 0xf33800ff /*P2_VTH78*/ -#define R0900_P2_VTH78 0xf339 -#define F0900_P2_VTH78 0xf33900ff +#define R0900_P2_VTH78 0xf339 +#define F0900_P2_VTH78 0xf33900ff /*P2_VITCURPUN*/ -#define R0900_P2_VITCURPUN 0xf33a -#define F0900_P2_VIT_MAPPING 0xf33a00e0 -#define F0900_P2_VIT_CURPUN 0xf33a001f +#define R0900_P2_VITCURPUN 0xf33a +#define F0900_P2_VIT_CURPUN 0xf33a001f /*P2_VERROR*/ -#define R0900_P2_VERROR 0xf33b -#define F0900_P2_REGERR_VIT 0xf33b00ff +#define R0900_P2_VERROR 0xf33b +#define F0900_P2_REGERR_VIT 0xf33b00ff /*P2_PRVIT*/ -#define R0900_P2_PRVIT 0xf33c -#define F0900_P2_DIS_VTHLOCK 0xf33c0040 -#define F0900_P2_E7_8VIT 0xf33c0020 -#define F0900_P2_E6_7VIT 0xf33c0010 -#define F0900_P2_E5_6VIT 0xf33c0008 -#define F0900_P2_E3_4VIT 0xf33c0004 -#define F0900_P2_E2_3VIT 0xf33c0002 -#define F0900_P2_E1_2VIT 0xf33c0001 +#define R0900_P2_PRVIT 0xf33c +#define F0900_P2_DIS_VTHLOCK 0xf33c0040 +#define F0900_P2_E7_8VIT 0xf33c0020 +#define F0900_P2_E6_7VIT 0xf33c0010 +#define F0900_P2_E5_6VIT 0xf33c0008 +#define F0900_P2_E3_4VIT 0xf33c0004 +#define F0900_P2_E2_3VIT 0xf33c0002 +#define F0900_P2_E1_2VIT 0xf33c0001 /*P2_VAVSRVIT*/ -#define R0900_P2_VAVSRVIT 0xf33d -#define F0900_P2_AMVIT 0xf33d0080 -#define F0900_P2_FROZENVIT 0xf33d0040 -#define F0900_P2_SNVIT 0xf33d0030 -#define F0900_P2_TOVVIT 0xf33d000c -#define F0900_P2_HYPVIT 0xf33d0003 +#define R0900_P2_VAVSRVIT 0xf33d +#define F0900_P2_AMVIT 0xf33d0080 +#define F0900_P2_FROZENVIT 0xf33d0040 +#define F0900_P2_SNVIT 0xf33d0030 +#define F0900_P2_TOVVIT 0xf33d000c +#define F0900_P2_HYPVIT 0xf33d0003 /*P2_VSTATUSVIT*/ -#define R0900_P2_VSTATUSVIT 0xf33e -#define F0900_P2_VITERBI_ON 0xf33e0080 -#define F0900_P2_END_LOOPVIT 0xf33e0040 -#define F0900_P2_VITERBI_DEPRF 0xf33e0020 -#define F0900_P2_PRFVIT 0xf33e0010 -#define F0900_P2_LOCKEDVIT 0xf33e0008 -#define F0900_P2_VITERBI_DELOCK 0xf33e0004 -#define F0900_P2_VIT_DEMODSEL 0xf33e0002 -#define F0900_P2_VITERBI_COMPOUT 0xf33e0001 +#define R0900_P2_VSTATUSVIT 0xf33e +#define F0900_P2_PRFVIT 0xf33e0010 +#define F0900_P2_LOCKEDVIT 0xf33e0008 /*P2_VTHINUSE*/ -#define R0900_P2_VTHINUSE 0xf33f -#define F0900_P2_VIT_INUSE 0xf33f00ff +#define R0900_P2_VTHINUSE 0xf33f +#define F0900_P2_VIT_INUSE 0xf33f00ff /*P2_KDIV12*/ -#define R0900_P2_KDIV12 0xf340 -#define F0900_P2_KDIV12_MANUAL 0xf3400080 -#define F0900_P2_K_DIVIDER_12 0xf340007f +#define R0900_P2_KDIV12 0xf340 +#define F0900_P2_K_DIVIDER_12 0xf340007f /*P2_KDIV23*/ -#define R0900_P2_KDIV23 0xf341 -#define F0900_P2_KDIV23_MANUAL 0xf3410080 -#define F0900_P2_K_DIVIDER_23 0xf341007f +#define R0900_P2_KDIV23 0xf341 +#define F0900_P2_K_DIVIDER_23 0xf341007f /*P2_KDIV34*/ -#define R0900_P2_KDIV34 0xf342 -#define F0900_P2_KDIV34_MANUAL 0xf3420080 -#define F0900_P2_K_DIVIDER_34 0xf342007f +#define R0900_P2_KDIV34 0xf342 +#define F0900_P2_K_DIVIDER_34 0xf342007f /*P2_KDIV56*/ -#define R0900_P2_KDIV56 0xf343 -#define F0900_P2_KDIV56_MANUAL 0xf3430080 -#define F0900_P2_K_DIVIDER_56 0xf343007f +#define R0900_P2_KDIV56 0xf343 +#define F0900_P2_K_DIVIDER_56 0xf343007f /*P2_KDIV67*/ -#define R0900_P2_KDIV67 0xf344 -#define F0900_P2_KDIV67_MANUAL 0xf3440080 -#define F0900_P2_K_DIVIDER_67 0xf344007f +#define R0900_P2_KDIV67 0xf344 +#define F0900_P2_K_DIVIDER_67 0xf344007f /*P2_KDIV78*/ -#define R0900_P2_KDIV78 0xf345 -#define F0900_P2_KDIV78_MANUAL 0xf3450080 -#define F0900_P2_K_DIVIDER_78 0xf345007f +#define R0900_P2_KDIV78 0xf345 +#define F0900_P2_K_DIVIDER_78 0xf345007f /*P2_PDELCTRL1*/ -#define R0900_P2_PDELCTRL1 0xf350 -#define F0900_P2_INV_MISMASK 0xf3500080 -#define F0900_P2_FORCE_ACCEPTED 0xf3500040 -#define F0900_P2_FILTER_EN 0xf3500020 -#define F0900_P2_FORCE_PKTDELINUSE 0xf3500010 -#define F0900_P2_HYSTEN 0xf3500008 -#define F0900_P2_HYSTSWRST 0xf3500004 -#define F0900_P2_EN_MIS00 0xf3500002 -#define F0900_P2_ALGOSWRST 0xf3500001 +#define R0900_P2_PDELCTRL1 0xf350 +#define F0900_P2_INV_MISMASK 0xf3500080 +#define F0900_P2_FILTER_EN 0xf3500020 +#define F0900_P2_EN_MIS00 0xf3500002 +#define F0900_P2_ALGOSWRST 0xf3500001 /*P2_PDELCTRL2*/ -#define R0900_P2_PDELCTRL2 0xf351 -#define F0900_P2_FORCE_CONTINUOUS 0xf3510080 -#define F0900_P2_RESET_UPKO_COUNT 0xf3510040 -#define F0900_P2_USER_PKTDELIN_NB 0xf3510020 -#define F0900_P2_FORCE_LOCKED 0xf3510010 -#define F0900_P2_DATA_UNBBSCRAM 0xf3510008 -#define F0900_P2_FORCE_LONGPKT 0xf3510004 -#define F0900_P2_FRAME_MODE 0xf3510002 +#define R0900_P2_PDELCTRL2 0xf351 +#define F0900_P2_RESET_UPKO_COUNT 0xf3510040 +#define F0900_P2_FRAME_MODE 0xf3510002 +#define F0900_P2_NOBCHERRFLG_USE 0xf3510001 /*P2_HYSTTHRESH*/ -#define R0900_P2_HYSTTHRESH 0xf354 -#define F0900_P2_UNLCK_THRESH 0xf35400f0 -#define F0900_P2_DELIN_LCK_THRESH 0xf354000f +#define R0900_P2_HYSTTHRESH 0xf354 +#define F0900_P2_UNLCK_THRESH 0xf35400f0 +#define F0900_P2_DELIN_LCK_THRESH 0xf354000f /*P2_ISIENTRY*/ -#define R0900_P2_ISIENTRY 0xf35e -#define F0900_P2_ISI_ENTRY 0xf35e00ff +#define R0900_P2_ISIENTRY 0xf35e +#define F0900_P2_ISI_ENTRY 0xf35e00ff /*P2_ISIBITENA*/ -#define R0900_P2_ISIBITENA 0xf35f -#define F0900_P2_ISI_BIT_EN 0xf35f00ff +#define R0900_P2_ISIBITENA 0xf35f +#define F0900_P2_ISI_BIT_EN 0xf35f00ff /*P2_MATSTR1*/ -#define R0900_P2_MATSTR1 0xf360 -#define F0900_P2_MATYPE_CURRENT1 0xf36000ff +#define R0900_P2_MATSTR1 0xf360 +#define F0900_P2_MATYPE_CURRENT1 0xf36000ff /*P2_MATSTR0*/ -#define R0900_P2_MATSTR0 0xf361 -#define F0900_P2_MATYPE_CURRENT0 0xf36100ff +#define R0900_P2_MATSTR0 0xf361 +#define F0900_P2_MATYPE_CURRENT0 0xf36100ff /*P2_UPLSTR1*/ -#define R0900_P2_UPLSTR1 0xf362 -#define F0900_P2_UPL_CURRENT1 0xf36200ff +#define R0900_P2_UPLSTR1 0xf362 +#define F0900_P2_UPL_CURRENT1 0xf36200ff /*P2_UPLSTR0*/ -#define R0900_P2_UPLSTR0 0xf363 -#define F0900_P2_UPL_CURRENT0 0xf36300ff +#define R0900_P2_UPLSTR0 0xf363 +#define F0900_P2_UPL_CURRENT0 0xf36300ff /*P2_DFLSTR1*/ -#define R0900_P2_DFLSTR1 0xf364 -#define F0900_P2_DFL_CURRENT1 0xf36400ff +#define R0900_P2_DFLSTR1 0xf364 +#define F0900_P2_DFL_CURRENT1 0xf36400ff /*P2_DFLSTR0*/ -#define R0900_P2_DFLSTR0 0xf365 -#define F0900_P2_DFL_CURRENT0 0xf36500ff +#define R0900_P2_DFLSTR0 0xf365 +#define F0900_P2_DFL_CURRENT0 0xf36500ff /*P2_SYNCSTR*/ -#define R0900_P2_SYNCSTR 0xf366 -#define F0900_P2_SYNC_CURRENT 0xf36600ff +#define R0900_P2_SYNCSTR 0xf366 +#define F0900_P2_SYNC_CURRENT 0xf36600ff /*P2_SYNCDSTR1*/ -#define R0900_P2_SYNCDSTR1 0xf367 -#define F0900_P2_SYNCD_CURRENT1 0xf36700ff +#define R0900_P2_SYNCDSTR1 0xf367 +#define F0900_P2_SYNCD_CURRENT1 0xf36700ff /*P2_SYNCDSTR0*/ -#define R0900_P2_SYNCDSTR0 0xf368 -#define F0900_P2_SYNCD_CURRENT0 0xf36800ff +#define R0900_P2_SYNCDSTR0 0xf368 +#define F0900_P2_SYNCD_CURRENT0 0xf36800ff /*P2_PDELSTATUS1*/ -#define R0900_P2_PDELSTATUS1 0xf369 -#define F0900_P2_PKTDELIN_DELOCK 0xf3690080 -#define F0900_P2_SYNCDUPDFL_BADDFL 0xf3690040 -#define F0900_P2_CONTINUOUS_STREAM 0xf3690020 -#define F0900_P2_UNACCEPTED_STREAM 0xf3690010 -#define F0900_P2_BCH_ERROR_FLAG 0xf3690008 -#define F0900_P2_BBHCRCKO 0xf3690004 -#define F0900_P2_PKTDELIN_LOCK 0xf3690002 -#define F0900_P2_FIRST_LOCK 0xf3690001 +#define R0900_P2_PDELSTATUS1 0xf369 +#define F0900_P2_PKTDELIN_DELOCK 0xf3690080 +#define F0900_P2_SYNCDUPDFL_BADDFL 0xf3690040 +#define F0900_P2_CONTINUOUS_STREAM 0xf3690020 +#define F0900_P2_UNACCEPTED_STREAM 0xf3690010 +#define F0900_P2_BCH_ERROR_FLAG 0xf3690008 +#define F0900_P2_PKTDELIN_LOCK 0xf3690002 +#define F0900_P2_FIRST_LOCK 0xf3690001 /*P2_PDELSTATUS2*/ -#define R0900_P2_PDELSTATUS2 0xf36a -#define F0900_P2_PKTDEL_DEMODSEL 0xf36a0080 -#define F0900_P2_FRAME_MODCOD 0xf36a007c -#define F0900_P2_FRAME_TYPE 0xf36a0003 +#define R0900_P2_PDELSTATUS2 0xf36a +#define F0900_P2_FRAME_MODCOD 0xf36a007c +#define F0900_P2_FRAME_TYPE 0xf36a0003 /*P2_BBFCRCKO1*/ -#define R0900_P2_BBFCRCKO1 0xf36b -#define F0900_P2_BBHCRC_KOCNT1 0xf36b00ff +#define R0900_P2_BBFCRCKO1 0xf36b +#define F0900_P2_BBHCRC_KOCNT1 0xf36b00ff /*P2_BBFCRCKO0*/ -#define R0900_P2_BBFCRCKO0 0xf36c -#define F0900_P2_BBHCRC_KOCNT0 0xf36c00ff +#define R0900_P2_BBFCRCKO0 0xf36c +#define F0900_P2_BBHCRC_KOCNT0 0xf36c00ff /*P2_UPCRCKO1*/ -#define R0900_P2_UPCRCKO1 0xf36d -#define F0900_P2_PKTCRC_KOCNT1 0xf36d00ff +#define R0900_P2_UPCRCKO1 0xf36d +#define F0900_P2_PKTCRC_KOCNT1 0xf36d00ff /*P2_UPCRCKO0*/ -#define R0900_P2_UPCRCKO0 0xf36e -#define F0900_P2_PKTCRC_KOCNT0 0xf36e00ff +#define R0900_P2_UPCRCKO0 0xf36e +#define F0900_P2_PKTCRC_KOCNT0 0xf36e00ff + +/*P2_PDELCTRL3*/ +#define R0900_P2_PDELCTRL3 0xf36f +#define F0900_P2_PKTDEL_CONTFAIL 0xf36f0080 +#define F0900_P2_NOFIFO_BCHERR 0xf36f0020 /*P2_TSSTATEM*/ -#define R0900_P2_TSSTATEM 0xf370 -#define F0900_P2_TSDIL_ON 0xf3700080 -#define F0900_P2_TSSKIPRS_ON 0xf3700040 -#define F0900_P2_TSRS_ON 0xf3700020 -#define F0900_P2_TSDESCRAMB_ON 0xf3700010 -#define F0900_P2_TSFRAME_MODE 0xf3700008 -#define F0900_P2_TS_DISABLE 0xf3700004 -#define F0900_P2_TSACM_MODE 0xf3700002 -#define F0900_P2_TSOUT_NOSYNC 0xf3700001 +#define R0900_P2_TSSTATEM 0xf370 +#define F0900_P2_TSDIL_ON 0xf3700080 +#define F0900_P2_TSRS_ON 0xf3700020 +#define F0900_P2_TSDESCRAMB_ON 0xf3700010 +#define F0900_P2_TSFRAME_MODE 0xf3700008 +#define F0900_P2_TS_DISABLE 0xf3700004 +#define F0900_P2_TSOUT_NOSYNC 0xf3700001 /*P2_TSCFGH*/ -#define R0900_P2_TSCFGH 0xf372 -#define F0900_P2_TSFIFO_DVBCI 0xf3720080 -#define F0900_P2_TSFIFO_SERIAL 0xf3720040 -#define F0900_P2_TSFIFO_TEIUPDATE 0xf3720020 -#define F0900_P2_TSFIFO_DUTY50 0xf3720010 -#define F0900_P2_TSFIFO_HSGNLOUT 0xf3720008 -#define F0900_P2_TSFIFO_ERRMODE 0xf3720006 -#define F0900_P2_RST_HWARE 0xf3720001 +#define R0900_P2_TSCFGH 0xf372 +#define F0900_P2_TSFIFO_DVBCI 0xf3720080 +#define F0900_P2_TSFIFO_SERIAL 0xf3720040 +#define F0900_P2_TSFIFO_TEIUPDATE 0xf3720020 +#define F0900_P2_TSFIFO_DUTY50 0xf3720010 +#define F0900_P2_TSFIFO_HSGNLOUT 0xf3720008 +#define F0900_P2_TSFIFO_ERRMODE 0xf3720006 +#define F0900_P2_RST_HWARE 0xf3720001 /*P2_TSCFGM*/ -#define R0900_P2_TSCFGM 0xf373 -#define F0900_P2_TSFIFO_MANSPEED 0xf37300c0 -#define F0900_P2_TSFIFO_PERMDATA 0xf3730020 -#define F0900_P2_TSFIFO_NONEWSGNL 0xf3730010 -#define F0900_P2_TSFIFO_BITSPEED 0xf3730008 -#define F0900_P2_NPD_SPECDVBS2 0xf3730004 -#define F0900_P2_TSFIFO_STOPCKDIS 0xf3730002 -#define F0900_P2_TSFIFO_INVDATA 0xf3730001 +#define R0900_P2_TSCFGM 0xf373 +#define F0900_P2_TSFIFO_MANSPEED 0xf37300c0 +#define F0900_P2_TSFIFO_PERMDATA 0xf3730020 +#define F0900_P2_TSFIFO_DPUNACT 0xf3730002 +#define F0900_P2_TSFIFO_INVDATA 0xf3730001 /*P2_TSCFGL*/ -#define R0900_P2_TSCFGL 0xf374 -#define F0900_P2_TSFIFO_BCLKDEL1CK 0xf37400c0 -#define F0900_P2_BCHERROR_MODE 0xf3740030 -#define F0900_P2_TSFIFO_NSGNL2DATA 0xf3740008 -#define F0900_P2_TSFIFO_EMBINDVB 0xf3740004 -#define F0900_P2_TSFIFO_DPUNACT 0xf3740002 -#define F0900_P2_TSFIFO_NPDOFF 0xf3740001 +#define R0900_P2_TSCFGL 0xf374 +#define F0900_P2_TSFIFO_BCLKDEL1CK 0xf37400c0 +#define F0900_P2_BCHERROR_MODE 0xf3740030 +#define F0900_P2_TSFIFO_NSGNL2DATA 0xf3740008 +#define F0900_P2_TSFIFO_EMBINDVB 0xf3740004 +#define F0900_P2_TSFIFO_BITSPEED 0xf3740003 /*P2_TSINSDELH*/ -#define R0900_P2_TSINSDELH 0xf376 -#define F0900_P2_TSDEL_SYNCBYTE 0xf3760080 -#define F0900_P2_TSDEL_XXHEADER 0xf3760040 -#define F0900_P2_TSDEL_BBHEADER 0xf3760020 -#define F0900_P2_TSDEL_DATAFIELD 0xf3760010 -#define F0900_P2_TSINSDEL_ISCR 0xf3760008 -#define F0900_P2_TSINSDEL_NPD 0xf3760004 -#define F0900_P2_TSINSDEL_RSPARITY 0xf3760002 -#define F0900_P2_TSINSDEL_CRC8 0xf3760001 +#define R0900_P2_TSINSDELH 0xf376 +#define F0900_P2_TSDEL_SYNCBYTE 0xf3760080 +#define F0900_P2_TSDEL_XXHEADER 0xf3760040 +#define F0900_P2_TSDEL_BBHEADER 0xf3760020 +#define F0900_P2_TSDEL_DATAFIELD 0xf3760010 +#define F0900_P2_TSINSDEL_ISCR 0xf3760008 +#define F0900_P2_TSINSDEL_NPD 0xf3760004 +#define F0900_P2_TSINSDEL_RSPARITY 0xf3760002 +#define F0900_P2_TSINSDEL_CRC8 0xf3760001 + +/*P2_TSDIVN*/ +#define R0900_P2_TSDIVN 0xf379 +#define F0900_P2_TSFIFO_SPEEDMODE 0xf37900c0 + +/*P2_TSCFG4*/ +#define R0900_P2_TSCFG4 0xf37a +#define F0900_P2_TSFIFO_TSSPEEDMODE 0xf37a00c0 /*P2_TSSPEED*/ -#define R0900_P2_TSSPEED 0xf380 -#define F0900_P2_TSFIFO_OUTSPEED 0xf38000ff +#define R0900_P2_TSSPEED 0xf380 +#define F0900_P2_TSFIFO_OUTSPEED 0xf38000ff /*P2_TSSTATUS*/ -#define R0900_P2_TSSTATUS 0xf381 -#define F0900_P2_TSFIFO_LINEOK 0xf3810080 -#define F0900_P2_TSFIFO_ERROR 0xf3810040 -#define F0900_P2_TSFIFO_DATA7 0xf3810020 -#define F0900_P2_TSFIFO_NOSYNC 0xf3810010 -#define F0900_P2_ISCR_INITIALIZED 0xf3810008 -#define F0900_P2_ISCR_UPDATED 0xf3810004 -#define F0900_P2_SOFFIFO_UNREGUL 0xf3810002 -#define F0900_P2_DIL_READY 0xf3810001 +#define R0900_P2_TSSTATUS 0xf381 +#define F0900_P2_TSFIFO_LINEOK 0xf3810080 +#define F0900_P2_TSFIFO_ERROR 0xf3810040 +#define F0900_P2_DIL_READY 0xf3810001 /*P2_TSSTATUS2*/ -#define R0900_P2_TSSTATUS2 0xf382 -#define F0900_P2_TSFIFO_DEMODSEL 0xf3820080 -#define F0900_P2_TSFIFOSPEED_STORE 0xf3820040 -#define F0900_P2_DILXX_RESET 0xf3820020 -#define F0900_P2_TSSERIAL_IMPOS 0xf3820010 -#define F0900_P2_TSFIFO_LINENOK 0xf3820008 -#define F0900_P2_BITSPEED_EVENT 0xf3820004 -#define F0900_P2_SCRAMBDETECT 0xf3820002 -#define F0900_P2_ULDTV67_FALSELOCK 0xf3820001 +#define R0900_P2_TSSTATUS2 0xf382 +#define F0900_P2_TSFIFO_DEMODSEL 0xf3820080 +#define F0900_P2_TSFIFOSPEED_STORE 0xf3820040 +#define F0900_P2_DILXX_RESET 0xf3820020 +#define F0900_P2_TSSERIAL_IMPOS 0xf3820010 +#define F0900_P2_SCRAMBDETECT 0xf3820002 /*P2_TSBITRATE1*/ -#define R0900_P2_TSBITRATE1 0xf383 -#define F0900_P2_TSFIFO_BITRATE1 0xf38300ff +#define R0900_P2_TSBITRATE1 0xf383 +#define F0900_P2_TSFIFO_BITRATE1 0xf38300ff /*P2_TSBITRATE0*/ -#define R0900_P2_TSBITRATE0 0xf384 -#define F0900_P2_TSFIFO_BITRATE0 0xf38400ff +#define R0900_P2_TSBITRATE0 0xf384 +#define F0900_P2_TSFIFO_BITRATE0 0xf38400ff /*P2_ERRCTRL1*/ -#define R0900_P2_ERRCTRL1 0xf398 -#define F0900_P2_ERR_SOURCE1 0xf39800f0 -#define F0900_P2_NUM_EVENT1 0xf3980007 +#define R0900_P2_ERRCTRL1 0xf398 +#define F0900_P2_ERR_SOURCE1 0xf39800f0 +#define F0900_P2_NUM_EVENT1 0xf3980007 /*P2_ERRCNT12*/ -#define R0900_P2_ERRCNT12 0xf399 -#define F0900_P2_ERRCNT1_OLDVALUE 0xf3990080 -#define F0900_P2_ERR_CNT12 0xf399007f +#define R0900_P2_ERRCNT12 0xf399 +#define F0900_P2_ERRCNT1_OLDVALUE 0xf3990080 +#define F0900_P2_ERR_CNT12 0xf399007f /*P2_ERRCNT11*/ -#define R0900_P2_ERRCNT11 0xf39a -#define F0900_P2_ERR_CNT11 0xf39a00ff +#define R0900_P2_ERRCNT11 0xf39a +#define F0900_P2_ERR_CNT11 0xf39a00ff /*P2_ERRCNT10*/ -#define R0900_P2_ERRCNT10 0xf39b -#define F0900_P2_ERR_CNT10 0xf39b00ff +#define R0900_P2_ERRCNT10 0xf39b +#define F0900_P2_ERR_CNT10 0xf39b00ff /*P2_ERRCTRL2*/ -#define R0900_P2_ERRCTRL2 0xf39c -#define F0900_P2_ERR_SOURCE2 0xf39c00f0 -#define F0900_P2_NUM_EVENT2 0xf39c0007 +#define R0900_P2_ERRCTRL2 0xf39c +#define F0900_P2_ERR_SOURCE2 0xf39c00f0 +#define F0900_P2_NUM_EVENT2 0xf39c0007 /*P2_ERRCNT22*/ -#define R0900_P2_ERRCNT22 0xf39d -#define F0900_P2_ERRCNT2_OLDVALUE 0xf39d0080 -#define F0900_P2_ERR_CNT22 0xf39d007f +#define R0900_P2_ERRCNT22 0xf39d +#define F0900_P2_ERRCNT2_OLDVALUE 0xf39d0080 +#define F0900_P2_ERR_CNT22 0xf39d007f /*P2_ERRCNT21*/ -#define R0900_P2_ERRCNT21 0xf39e -#define F0900_P2_ERR_CNT21 0xf39e00ff +#define R0900_P2_ERRCNT21 0xf39e +#define F0900_P2_ERR_CNT21 0xf39e00ff /*P2_ERRCNT20*/ -#define R0900_P2_ERRCNT20 0xf39f -#define F0900_P2_ERR_CNT20 0xf39f00ff +#define R0900_P2_ERRCNT20 0xf39f +#define F0900_P2_ERR_CNT20 0xf39f00ff /*P2_FECSPY*/ -#define R0900_P2_FECSPY 0xf3a0 -#define F0900_P2_SPY_ENABLE 0xf3a00080 -#define F0900_P2_NO_SYNCBYTE 0xf3a00040 -#define F0900_P2_SERIAL_MODE 0xf3a00020 -#define F0900_P2_UNUSUAL_PACKET 0xf3a00010 -#define F0900_P2_BER_PACKMODE 0xf3a00008 -#define F0900_P2_BERMETER_LMODE 0xf3a00002 -#define F0900_P2_BERMETER_RESET 0xf3a00001 +#define R0900_P2_FECSPY 0xf3a0 +#define F0900_P2_SPY_ENABLE 0xf3a00080 +#define F0900_P2_NO_SYNCBYTE 0xf3a00040 +#define F0900_P2_SERIAL_MODE 0xf3a00020 +#define F0900_P2_UNUSUAL_PACKET 0xf3a00010 +#define F0900_P2_BERMETER_DATAMODE 0xf3a00008 +#define F0900_P2_BERMETER_LMODE 0xf3a00002 +#define F0900_P2_BERMETER_RESET 0xf3a00001 /*P2_FSPYCFG*/ -#define R0900_P2_FSPYCFG 0xf3a1 -#define F0900_P2_FECSPY_INPUT 0xf3a100c0 -#define F0900_P2_RST_ON_ERROR 0xf3a10020 -#define F0900_P2_ONE_SHOT 0xf3a10010 -#define F0900_P2_I2C_MODE 0xf3a1000c -#define F0900_P2_SPY_HYSTERESIS 0xf3a10003 +#define R0900_P2_FSPYCFG 0xf3a1 +#define F0900_P2_FECSPY_INPUT 0xf3a100c0 +#define F0900_P2_RST_ON_ERROR 0xf3a10020 +#define F0900_P2_ONE_SHOT 0xf3a10010 +#define F0900_P2_I2C_MODE 0xf3a1000c +#define F0900_P2_SPY_HYSTERESIS 0xf3a10003 /*P2_FSPYDATA*/ -#define R0900_P2_FSPYDATA 0xf3a2 -#define F0900_P2_SPY_STUFFING 0xf3a20080 -#define F0900_P2_NOERROR_PKTJITTER 0xf3a20040 -#define F0900_P2_SPY_CNULLPKT 0xf3a20020 -#define F0900_P2_SPY_OUTDATA_MODE 0xf3a2001f +#define R0900_P2_FSPYDATA 0xf3a2 +#define F0900_P2_SPY_STUFFING 0xf3a20080 +#define F0900_P2_SPY_CNULLPKT 0xf3a20020 +#define F0900_P2_SPY_OUTDATA_MODE 0xf3a2001f /*P2_FSPYOUT*/ -#define R0900_P2_FSPYOUT 0xf3a3 -#define F0900_P2_FSPY_DIRECT 0xf3a30080 -#define F0900_P2_SPY_OUTDATA_BUS 0xf3a30038 -#define F0900_P2_STUFF_MODE 0xf3a30007 +#define R0900_P2_FSPYOUT 0xf3a3 +#define F0900_P2_FSPY_DIRECT 0xf3a30080 +#define F0900_P2_STUFF_MODE 0xf3a30007 /*P2_FSTATUS*/ -#define R0900_P2_FSTATUS 0xf3a4 -#define F0900_P2_SPY_ENDSIM 0xf3a40080 -#define F0900_P2_VALID_SIM 0xf3a40040 -#define F0900_P2_FOUND_SIGNAL 0xf3a40020 -#define F0900_P2_DSS_SYNCBYTE 0xf3a40010 -#define F0900_P2_RESULT_STATE 0xf3a4000f +#define R0900_P2_FSTATUS 0xf3a4 +#define F0900_P2_SPY_ENDSIM 0xf3a40080 +#define F0900_P2_VALID_SIM 0xf3a40040 +#define F0900_P2_FOUND_SIGNAL 0xf3a40020 +#define F0900_P2_DSS_SYNCBYTE 0xf3a40010 +#define F0900_P2_RESULT_STATE 0xf3a4000f /*P2_FBERCPT4*/ -#define R0900_P2_FBERCPT4 0xf3a8 -#define F0900_P2_FBERMETER_CPT4 0xf3a800ff +#define R0900_P2_FBERCPT4 0xf3a8 +#define F0900_P2_FBERMETER_CPT4 0xf3a800ff /*P2_FBERCPT3*/ -#define R0900_P2_FBERCPT3 0xf3a9 -#define F0900_P2_FBERMETER_CPT3 0xf3a900ff +#define R0900_P2_FBERCPT3 0xf3a9 +#define F0900_P2_FBERMETER_CPT3 0xf3a900ff /*P2_FBERCPT2*/ -#define R0900_P2_FBERCPT2 0xf3aa -#define F0900_P2_FBERMETER_CPT2 0xf3aa00ff +#define R0900_P2_FBERCPT2 0xf3aa +#define F0900_P2_FBERMETER_CPT2 0xf3aa00ff /*P2_FBERCPT1*/ -#define R0900_P2_FBERCPT1 0xf3ab -#define F0900_P2_FBERMETER_CPT1 0xf3ab00ff +#define R0900_P2_FBERCPT1 0xf3ab +#define F0900_P2_FBERMETER_CPT1 0xf3ab00ff /*P2_FBERCPT0*/ -#define R0900_P2_FBERCPT0 0xf3ac -#define F0900_P2_FBERMETER_CPT0 0xf3ac00ff +#define R0900_P2_FBERCPT0 0xf3ac +#define F0900_P2_FBERMETER_CPT0 0xf3ac00ff /*P2_FBERERR2*/ -#define R0900_P2_FBERERR2 0xf3ad -#define F0900_P2_FBERMETER_ERR2 0xf3ad00ff +#define R0900_P2_FBERERR2 0xf3ad +#define F0900_P2_FBERMETER_ERR2 0xf3ad00ff /*P2_FBERERR1*/ -#define R0900_P2_FBERERR1 0xf3ae -#define F0900_P2_FBERMETER_ERR1 0xf3ae00ff +#define R0900_P2_FBERERR1 0xf3ae +#define F0900_P2_FBERMETER_ERR1 0xf3ae00ff /*P2_FBERERR0*/ -#define R0900_P2_FBERERR0 0xf3af -#define F0900_P2_FBERMETER_ERR0 0xf3af00ff +#define R0900_P2_FBERERR0 0xf3af +#define F0900_P2_FBERMETER_ERR0 0xf3af00ff /*P2_FSPYBER*/ -#define R0900_P2_FSPYBER 0xf3b2 -#define F0900_P2_FSPYOBS_XORREAD 0xf3b20040 -#define F0900_P2_FSPYBER_OBSMODE 0xf3b20020 -#define F0900_P2_FSPYBER_SYNCBYTE 0xf3b20010 -#define F0900_P2_FSPYBER_UNSYNC 0xf3b20008 -#define F0900_P2_FSPYBER_CTIME 0xf3b20007 +#define R0900_P2_FSPYBER 0xf3b2 +#define F0900_P2_FSPYBER_SYNCBYTE 0xf3b20010 +#define F0900_P2_FSPYBER_UNSYNC 0xf3b20008 +#define F0900_P2_FSPYBER_CTIME 0xf3b20007 /*P1_IQCONST*/ -#define R0900_P1_IQCONST 0xf400 -#define F0900_P1_CONSTEL_SELECT 0xf4000060 -#define F0900_P1_IQSYMB_SEL 0xf400001f +#define R0900_P1_IQCONST 0xf400 +#define IQCONST REGx(R0900_P1_IQCONST) +#define F0900_P1_CONSTEL_SELECT 0xf4000060 +#define F0900_P1_IQSYMB_SEL 0xf400001f /*P1_NOSCFG*/ -#define R0900_P1_NOSCFG 0xf401 -#define F0900_P1_DUMMYPL_NOSDATA 0xf4010020 -#define F0900_P1_NOSPLH_BETA 0xf4010018 -#define F0900_P1_NOSDATA_BETA 0xf4010007 +#define R0900_P1_NOSCFG 0xf401 +#define NOSCFG REGx(R0900_P1_NOSCFG) +#define F0900_P1_DUMMYPL_NOSDATA 0xf4010020 +#define F0900_P1_NOSPLH_BETA 0xf4010018 +#define F0900_P1_NOSDATA_BETA 0xf4010007 /*P1_ISYMB*/ -#define R0900_P1_ISYMB 0xf402 -#define F0900_P1_I_SYMBOL 0xf40201ff +#define R0900_P1_ISYMB 0xf402 +#define ISYMB REGx(R0900_P1_ISYMB) +#define F0900_P1_I_SYMBOL 0xf40201ff /*P1_QSYMB*/ -#define R0900_P1_QSYMB 0xf403 -#define F0900_P1_Q_SYMBOL 0xf40301ff +#define R0900_P1_QSYMB 0xf403 +#define QSYMB REGx(R0900_P1_QSYMB) +#define F0900_P1_Q_SYMBOL 0xf40301ff /*P1_AGC1CFG*/ -#define R0900_P1_AGC1CFG 0xf404 -#define F0900_P1_DC_FROZEN 0xf4040080 -#define F0900_P1_DC_CORRECT 0xf4040040 -#define F0900_P1_AMM_FROZEN 0xf4040020 -#define F0900_P1_AMM_CORRECT 0xf4040010 -#define F0900_P1_QUAD_FROZEN 0xf4040008 -#define F0900_P1_QUAD_CORRECT 0xf4040004 -#define F0900_P1_DCCOMP_SLOW 0xf4040002 -#define F0900_P1_IQMISM_SLOW 0xf4040001 +#define R0900_P1_AGC1CFG 0xf404 +#define AGC1CFG REGx(R0900_P1_AGC1CFG) +#define F0900_P1_DC_FROZEN 0xf4040080 +#define F0900_P1_DC_CORRECT 0xf4040040 +#define F0900_P1_AMM_FROZEN 0xf4040020 +#define F0900_P1_AMM_CORRECT 0xf4040010 +#define F0900_P1_QUAD_FROZEN 0xf4040008 +#define F0900_P1_QUAD_CORRECT 0xf4040004 /*P1_AGC1CN*/ -#define R0900_P1_AGC1CN 0xf406 -#define F0900_P1_AGC1_LOCKED 0xf4060080 -#define F0900_P1_AGC1_OVERFLOW 0xf4060040 -#define F0900_P1_AGC1_NOSLOWLK 0xf4060020 -#define F0900_P1_AGC1_MINPOWER 0xf4060010 -#define F0900_P1_AGCOUT_FAST 0xf4060008 -#define F0900_P1_AGCIQ_BETA 0xf4060007 +#define R0900_P1_AGC1CN 0xf406 +#define AGC1CN REGx(R0900_P1_AGC1CN) +#define F0900_P1_AGC1_LOCKED 0xf4060080 +#define F0900_P1_AGC1_MINPOWER 0xf4060010 +#define F0900_P1_AGCOUT_FAST 0xf4060008 +#define F0900_P1_AGCIQ_BETA 0xf4060007 /*P1_AGC1REF*/ -#define R0900_P1_AGC1REF 0xf407 -#define F0900_P1_AGCIQ_REF 0xf40700ff +#define R0900_P1_AGC1REF 0xf407 +#define AGC1REF REGx(R0900_P1_AGC1REF) +#define F0900_P1_AGCIQ_REF 0xf40700ff /*P1_IDCCOMP*/ -#define R0900_P1_IDCCOMP 0xf408 -#define F0900_P1_IAVERAGE_ADJ 0xf40801ff +#define R0900_P1_IDCCOMP 0xf408 +#define IDCCOMP REGx(R0900_P1_IDCCOMP) +#define F0900_P1_IAVERAGE_ADJ 0xf40801ff /*P1_QDCCOMP*/ -#define R0900_P1_QDCCOMP 0xf409 -#define F0900_P1_QAVERAGE_ADJ 0xf40901ff +#define R0900_P1_QDCCOMP 0xf409 +#define QDCCOMP REGx(R0900_P1_QDCCOMP) +#define F0900_P1_QAVERAGE_ADJ 0xf40901ff /*P1_POWERI*/ -#define R0900_P1_POWERI 0xf40a -#define F0900_P1_POWER_I 0xf40a00ff +#define R0900_P1_POWERI 0xf40a +#define POWERI REGx(R0900_P1_POWERI) +#define F0900_P1_POWER_I 0xf40a00ff +#define POWER_I FLDx(F0900_P1_POWER_I) /*P1_POWERQ*/ -#define R0900_P1_POWERQ 0xf40b -#define F0900_P1_POWER_Q 0xf40b00ff +#define R0900_P1_POWERQ 0xf40b +#define POWERQ REGx(R0900_P1_POWERQ) +#define F0900_P1_POWER_Q 0xf40b00ff +#define POWER_Q FLDx(F0900_P1_POWER_Q) /*P1_AGC1AMM*/ -#define R0900_P1_AGC1AMM 0xf40c -#define F0900_P1_AMM_VALUE 0xf40c00ff +#define R0900_P1_AGC1AMM 0xf40c +#define AGC1AMM REGx(R0900_P1_AGC1AMM) +#define F0900_P1_AMM_VALUE 0xf40c00ff /*P1_AGC1QUAD*/ -#define R0900_P1_AGC1QUAD 0xf40d -#define F0900_P1_QUAD_VALUE 0xf40d01ff +#define R0900_P1_AGC1QUAD 0xf40d +#define AGC1QUAD REGx(R0900_P1_AGC1QUAD) +#define F0900_P1_QUAD_VALUE 0xf40d01ff /*P1_AGCIQIN1*/ -#define R0900_P1_AGCIQIN1 0xf40e -#define F0900_P1_AGCIQ_VALUE1 0xf40e00ff +#define R0900_P1_AGCIQIN1 0xf40e +#define AGCIQIN1 REGx(R0900_P1_AGCIQIN1) +#define F0900_P1_AGCIQ_VALUE1 0xf40e00ff +#define AGCIQ_VALUE1 FLDx(F0900_P1_AGCIQ_VALUE1) /*P1_AGCIQIN0*/ -#define R0900_P1_AGCIQIN0 0xf40f -#define F0900_P1_AGCIQ_VALUE0 0xf40f00ff +#define R0900_P1_AGCIQIN0 0xf40f +#define AGCIQIN0 REGx(R0900_P1_AGCIQIN0) +#define F0900_P1_AGCIQ_VALUE0 0xf40f00ff +#define AGCIQ_VALUE0 FLDx(F0900_P1_AGCIQ_VALUE0) /*P1_DEMOD*/ -#define R0900_P1_DEMOD 0xf410 -#define F0900_P1_DEMOD_STOP 0xf4100040 -#define F0900_P1_SPECINV_CONTROL 0xf4100030 -#define F0900_P1_FORCE_ENASAMP 0xf4100008 -#define F0900_P1_MANUAL_ROLLOFF 0xf4100004 -#define F0900_P1_ROLLOFF_CONTROL 0xf4100003 +#define R0900_P1_DEMOD 0xf410 +#define DEMOD REGx(R0900_P1_DEMOD) +#define F0900_P1_MANUALS2_ROLLOFF 0xf4100080 +#define MANUALS2_ROLLOFF FLDx(F0900_P1_MANUALS2_ROLLOFF) + +#define F0900_P1_SPECINV_CONTROL 0xf4100030 +#define SPECINV_CONTROL FLDx(F0900_P1_SPECINV_CONTROL) +#define F0900_P1_FORCE_ENASAMP 0xf4100008 +#define F0900_P1_MANUALSX_ROLLOFF 0xf4100004 +#define MANUALSX_ROLLOFF FLDx(F0900_P1_MANUALSX_ROLLOFF) +#define F0900_P1_ROLLOFF_CONTROL 0xf4100003 +#define ROLLOFF_CONTROL FLDx(F0900_P1_ROLLOFF_CONTROL) /*P1_DMDMODCOD*/ -#define R0900_P1_DMDMODCOD 0xf411 -#define F0900_P1_MANUAL_MODCOD 0xf4110080 -#define F0900_P1_DEMOD_MODCOD 0xf411007c -#define F0900_P1_DEMOD_TYPE 0xf4110003 +#define R0900_P1_DMDMODCOD 0xf411 +#define DMDMODCOD REGx(R0900_P1_DMDMODCOD) +#define F0900_P1_MANUAL_MODCOD 0xf4110080 +#define F0900_P1_DEMOD_MODCOD 0xf411007c +#define DEMOD_MODCOD FLDx(F0900_P1_DEMOD_MODCOD) +#define F0900_P1_DEMOD_TYPE 0xf4110003 +#define DEMOD_TYPE FLDx(F0900_P1_DEMOD_TYPE) /*P1_DSTATUS*/ -#define R0900_P1_DSTATUS 0xf412 -#define F0900_P1_CAR_LOCK 0xf4120080 -#define F0900_P1_TMGLOCK_QUALITY 0xf4120060 -#define F0900_P1_SDVBS1_ENABLE 0xf4120010 -#define F0900_P1_LOCK_DEFINITIF 0xf4120008 -#define F0900_P1_TIMING_IS_LOCKED 0xf4120004 -#define F0900_P1_COARSE_TMGLOCK 0xf4120002 -#define F0900_P1_COARSE_CARLOCK 0xf4120001 +#define R0900_P1_DSTATUS 0xf412 +#define DSTATUS REGx(R0900_P1_DSTATUS) +#define F0900_P1_CAR_LOCK 0xf4120080 +#define F0900_P1_TMGLOCK_QUALITY 0xf4120060 +#define TMGLOCK_QUALITY FLDx(F0900_P1_TMGLOCK_QUALITY) +#define F0900_P1_LOCK_DEFINITIF 0xf4120008 +#define LOCK_DEFINITIF FLDx(F0900_P1_LOCK_DEFINITIF) +#define F0900_P1_OVADC_DETECT 0xf4120001 /*P1_DSTATUS2*/ -#define R0900_P1_DSTATUS2 0xf413 -#define F0900_P1_DEMOD_DELOCK 0xf4130080 -#define F0900_P1_DEMOD_TIMEOUT 0xf4130040 -#define F0900_P1_MODCODRQ_SYNCTAG 0xf4130020 -#define F0900_P1_POLYPH_SATEVENT 0xf4130010 -#define F0900_P1_AGC1_NOSIGNALACK 0xf4130008 -#define F0900_P1_AGC2_OVERFLOW 0xf4130004 -#define F0900_P1_CFR_OVERFLOW 0xf4130002 -#define F0900_P1_GAMMA_OVERUNDER 0xf4130001 +#define R0900_P1_DSTATUS2 0xf413 +#define DSTATUS2 REGx(R0900_P1_DSTATUS2) +#define F0900_P1_DEMOD_DELOCK 0xf4130080 +#define F0900_P1_AGC1_NOSIGNALACK 0xf4130008 +#define F0900_P1_AGC2_OVERFLOW 0xf4130004 +#define F0900_P1_CFR_OVERFLOW 0xf4130002 +#define F0900_P1_GAMMA_OVERUNDER 0xf4130001 /*P1_DMDCFGMD*/ -#define R0900_P1_DMDCFGMD 0xf414 -#define F0900_P1_DVBS2_ENABLE 0xf4140080 -#define F0900_P1_DVBS1_ENABLE 0xf4140040 -#define F0900_P1_CFR_AUTOSCAN 0xf4140020 -#define F0900_P1_SCAN_ENABLE 0xf4140010 -#define F0900_P1_TUN_AUTOSCAN 0xf4140008 -#define F0900_P1_NOFORCE_RELOCK 0xf4140004 -#define F0900_P1_TUN_RNG 0xf4140003 +#define R0900_P1_DMDCFGMD 0xf414 +#define DMDCFGMD REGx(R0900_P1_DMDCFGMD) +#define F0900_P1_DVBS2_ENABLE 0xf4140080 +#define DVBS2_ENABLE FLDx(F0900_P1_DVBS2_ENABLE) +#define F0900_P1_DVBS1_ENABLE 0xf4140040 +#define DVBS1_ENABLE FLDx(F0900_P1_DVBS1_ENABLE) +#define F0900_P1_SCAN_ENABLE 0xf4140010 +#define SCAN_ENABLE FLDx(F0900_P1_SCAN_ENABLE) +#define F0900_P1_CFR_AUTOSCAN 0xf4140008 +#define CFR_AUTOSCAN FLDx(F0900_P1_CFR_AUTOSCAN) +#define F0900_P1_TUN_RNG 0xf4140003 /*P1_DMDCFG2*/ -#define R0900_P1_DMDCFG2 0xf415 -#define F0900_P1_AGC1_WAITLOCK 0xf4150080 -#define F0900_P1_S1S2_SEQUENTIAL 0xf4150040 -#define F0900_P1_OVERFLOW_TIMEOUT 0xf4150020 -#define F0900_P1_SCANFAIL_TIMEOUT 0xf4150010 -#define F0900_P1_DMDTOUT_BACK 0xf4150008 -#define F0900_P1_CARLOCK_S1ENABLE 0xf4150004 -#define F0900_P1_COARSE_LK3MODE 0xf4150002 -#define F0900_P1_COARSE_LK2MODE 0xf4150001 +#define R0900_P1_DMDCFG2 0xf415 +#define DMDCFG2 REGx(R0900_P1_DMDCFG2) +#define F0900_P1_S1S2_SEQUENTIAL 0xf4150040 +#define S1S2_SEQUENTIAL FLDx(F0900_P1_S1S2_SEQUENTIAL) +#define F0900_P1_INFINITE_RELOCK 0xf4150010 /*P1_DMDISTATE*/ -#define R0900_P1_DMDISTATE 0xf416 -#define F0900_P1_I2C_NORESETDMODE 0xf4160080 -#define F0900_P1_FORCE_ETAPED 0xf4160040 -#define F0900_P1_SDMDRST_DIRCLK 0xf4160020 -#define F0900_P1_I2C_DEMOD_MODE 0xf416001f +#define R0900_P1_DMDISTATE 0xf416 +#define DMDISTATE REGx(R0900_P1_DMDISTATE) +#define F0900_P1_I2C_DEMOD_MODE 0xf416001f +#define DEMOD_MODE FLDx(F0900_P1_I2C_DEMOD_MODE) /*P1_DMDT0M*/ -#define R0900_P1_DMDT0M 0xf417 -#define F0900_P1_DMDT0_MIN 0xf41700ff +#define R0900_P1_DMDT0M 0xf417 +#define DMDT0M REGx(R0900_P1_DMDT0M) +#define F0900_P1_DMDT0_MIN 0xf41700ff /*P1_DMDSTATE*/ -#define R0900_P1_DMDSTATE 0xf41b -#define F0900_P1_DEMOD_LOCKED 0xf41b0080 -#define F0900_P1_HEADER_MODE 0xf41b0060 -#define F0900_P1_DEMOD_MODE 0xf41b001f +#define R0900_P1_DMDSTATE 0xf41b +#define DMDSTATE REGx(R0900_P1_DMDSTATE) +#define F0900_P1_HEADER_MODE 0xf41b0060 +#define HEADER_MODE FLDx(F0900_P1_HEADER_MODE) /*P1_DMDFLYW*/ -#define R0900_P1_DMDFLYW 0xf41c -#define F0900_P1_I2C_IRQVAL 0xf41c00f0 -#define F0900_P1_FLYWHEEL_CPT 0xf41c000f +#define R0900_P1_DMDFLYW 0xf41c +#define DMDFLYW REGx(R0900_P1_DMDFLYW) +#define F0900_P1_I2C_IRQVAL 0xf41c00f0 +#define F0900_P1_FLYWHEEL_CPT 0xf41c000f +#define FLYWHEEL_CPT FLDx(F0900_P1_FLYWHEEL_CPT) /*P1_DSTATUS3*/ -#define R0900_P1_DSTATUS3 0xf41d -#define F0900_P1_CFR_ZIGZAG 0xf41d0080 -#define F0900_P1_DEMOD_CFGMODE 0xf41d0060 -#define F0900_P1_GAMMA_LOWBAUDRATE 0xf41d0010 -#define F0900_P1_RELOCK_MODE 0xf41d0008 -#define F0900_P1_DEMOD_FAIL 0xf41d0004 -#define F0900_P1_ETAPE1A_DVBXMEM 0xf41d0003 +#define R0900_P1_DSTATUS3 0xf41d +#define DSTATUS3 REGx(R0900_P1_DSTATUS3) +#define F0900_P1_DEMOD_CFGMODE 0xf41d0060 /*P1_DMDCFG3*/ -#define R0900_P1_DMDCFG3 0xf41e -#define F0900_P1_DVBS1_TMGWAIT 0xf41e0080 -#define F0900_P1_NO_BWCENTERING 0xf41e0040 -#define F0900_P1_INV_SEQSRCH 0xf41e0020 -#define F0900_P1_DIS_SFRUPLOW_TRK 0xf41e0010 -#define F0900_P1_NOSTOP_FIFOFULL 0xf41e0008 -#define F0900_P1_LOCKTIME_MODE 0xf41e0007 +#define R0900_P1_DMDCFG3 0xf41e +#define DMDCFG3 REGx(R0900_P1_DMDCFG3) +#define F0900_P1_NOSTOP_FIFOFULL 0xf41e0008 /*P1_DMDCFG4*/ -#define R0900_P1_DMDCFG4 0xf41f -#define F0900_P1_TUNER_NRELAUNCH 0xf41f0008 -#define F0900_P1_DIS_CLKENABLE 0xf41f0004 -#define F0900_P1_DIS_HDRDIVLOCK 0xf41f0002 -#define F0900_P1_NO_TNRWBINIT 0xf41f0001 +#define R0900_P1_DMDCFG4 0xf41f +#define DMDCFG4 REGx(R0900_P1_DMDCFG4) +#define F0900_P1_TUNER_NRELAUNCH 0xf41f0008 /*P1_CORRELMANT*/ -#define R0900_P1_CORRELMANT 0xf420 -#define F0900_P1_CORREL_MANT 0xf42000ff +#define R0900_P1_CORRELMANT 0xf420 +#define CORRELMANT REGx(R0900_P1_CORRELMANT) +#define F0900_P1_CORREL_MANT 0xf42000ff /*P1_CORRELABS*/ -#define R0900_P1_CORRELABS 0xf421 -#define F0900_P1_CORREL_ABS 0xf42100ff +#define R0900_P1_CORRELABS 0xf421 +#define CORRELABS REGx(R0900_P1_CORRELABS) +#define F0900_P1_CORREL_ABS 0xf42100ff /*P1_CORRELEXP*/ -#define R0900_P1_CORRELEXP 0xf422 -#define F0900_P1_CORREL_ABSEXP 0xf42200f0 -#define F0900_P1_CORREL_EXP 0xf422000f +#define R0900_P1_CORRELEXP 0xf422 +#define CORRELEXP REGx(R0900_P1_CORRELEXP) +#define F0900_P1_CORREL_ABSEXP 0xf42200f0 +#define F0900_P1_CORREL_EXP 0xf422000f /*P1_PLHMODCOD*/ -#define R0900_P1_PLHMODCOD 0xf424 -#define F0900_P1_SPECINV_DEMOD 0xf4240080 -#define F0900_P1_PLH_MODCOD 0xf424007c -#define F0900_P1_PLH_TYPE 0xf4240003 - -/*P1_AGCK32*/ -#define R0900_P1_AGCK32 0xf42b -#define F0900_P1_R3ADJOFF_32APSK 0xf42b0080 -#define F0900_P1_R2ADJOFF_32APSK 0xf42b0040 -#define F0900_P1_R1ADJOFF_32APSK 0xf42b0020 -#define F0900_P1_RADJ_32APSK 0xf42b001f +#define R0900_P1_PLHMODCOD 0xf424 +#define PLHMODCOD REGx(R0900_P1_PLHMODCOD) +#define F0900_P1_SPECINV_DEMOD 0xf4240080 +#define SPECINV_DEMOD FLDx(F0900_P1_SPECINV_DEMOD) +#define F0900_P1_PLH_MODCOD 0xf424007c +#define F0900_P1_PLH_TYPE 0xf4240003 + +/*P1_DMDREG*/ +#define R0900_P1_DMDREG 0xf425 +#define DMDREG REGx(R0900_P1_DMDREG) +#define F0900_P1_DECIM_PLFRAMES 0xf4250001 /*P1_AGC2O*/ -#define R0900_P1_AGC2O 0xf42c -#define F0900_P1_AGC2REF_ADJUSTING 0xf42c0080 -#define F0900_P1_AGC2_COARSEFAST 0xf42c0040 -#define F0900_P1_AGC2_LKSQRT 0xf42c0020 -#define F0900_P1_AGC2_LKMODE 0xf42c0010 -#define F0900_P1_AGC2_LKEQUA 0xf42c0008 -#define F0900_P1_AGC2_COEF 0xf42c0007 +#define R0900_P1_AGC2O 0xf42c +#define AGC2O REGx(R0900_P1_AGC2O) +#define F0900_P1_AGC2_COEF 0xf42c0007 /*P1_AGC2REF*/ -#define R0900_P1_AGC2REF 0xf42d -#define F0900_P1_AGC2_REF 0xf42d00ff +#define R0900_P1_AGC2REF 0xf42d +#define AGC2REF REGx(R0900_P1_AGC2REF) +#define F0900_P1_AGC2_REF 0xf42d00ff /*P1_AGC1ADJ*/ -#define R0900_P1_AGC1ADJ 0xf42e -#define F0900_P1_AGC1ADJ_MANUAL 0xf42e0080 -#define F0900_P1_AGC1_ADJUSTED 0xf42e017f +#define R0900_P1_AGC1ADJ 0xf42e +#define AGC1ADJ REGx(R0900_P1_AGC1ADJ) +#define F0900_P1_AGC1_ADJUSTED 0xf42e007f /*P1_AGC2I1*/ -#define R0900_P1_AGC2I1 0xf436 -#define F0900_P1_AGC2_INTEGRATOR1 0xf43600ff +#define R0900_P1_AGC2I1 0xf436 +#define AGC2I1 REGx(R0900_P1_AGC2I1) +#define F0900_P1_AGC2_INTEGRATOR1 0xf43600ff /*P1_AGC2I0*/ -#define R0900_P1_AGC2I0 0xf437 -#define F0900_P1_AGC2_INTEGRATOR0 0xf43700ff +#define R0900_P1_AGC2I0 0xf437 +#define AGC2I0 REGx(R0900_P1_AGC2I0) +#define F0900_P1_AGC2_INTEGRATOR0 0xf43700ff /*P1_CARCFG*/ -#define R0900_P1_CARCFG 0xf438 -#define F0900_P1_CFRUPLOW_AUTO 0xf4380080 -#define F0900_P1_CFRUPLOW_TEST 0xf4380040 -#define F0900_P1_EN_CAR2CENTER 0xf4380020 -#define F0900_P1_CARHDR_NODIV8 0xf4380010 -#define F0900_P1_I2C_ROTA 0xf4380008 -#define F0900_P1_ROTAON 0xf4380004 -#define F0900_P1_PH_DET_ALGO 0xf4380003 +#define R0900_P1_CARCFG 0xf438 +#define CARCFG REGx(R0900_P1_CARCFG) +#define F0900_P1_CFRUPLOW_AUTO 0xf4380080 +#define F0900_P1_CFRUPLOW_TEST 0xf4380040 +#define F0900_P1_ROTAON 0xf4380004 +#define F0900_P1_PH_DET_ALGO 0xf4380003 /*P1_ACLC*/ -#define R0900_P1_ACLC 0xf439 -#define F0900_P1_STOP_S2ALPHA 0xf43900c0 -#define F0900_P1_CAR_ALPHA_MANT 0xf4390030 -#define F0900_P1_CAR_ALPHA_EXP 0xf439000f +#define R0900_P1_ACLC 0xf439 +#define ACLC REGx(R0900_P1_ACLC) +#define F0900_P1_CAR_ALPHA_MANT 0xf4390030 +#define F0900_P1_CAR_ALPHA_EXP 0xf439000f /*P1_BCLC*/ -#define R0900_P1_BCLC 0xf43a -#define F0900_P1_STOP_S2BETA 0xf43a00c0 -#define F0900_P1_CAR_BETA_MANT 0xf43a0030 -#define F0900_P1_CAR_BETA_EXP 0xf43a000f +#define R0900_P1_BCLC 0xf43a +#define BCLC REGx(R0900_P1_BCLC) +#define F0900_P1_CAR_BETA_MANT 0xf43a0030 +#define F0900_P1_CAR_BETA_EXP 0xf43a000f /*P1_CARFREQ*/ -#define R0900_P1_CARFREQ 0xf43d -#define F0900_P1_KC_COARSE_EXP 0xf43d00f0 -#define F0900_P1_BETA_FREQ 0xf43d000f +#define R0900_P1_CARFREQ 0xf43d +#define CARFREQ REGx(R0900_P1_CARFREQ) +#define F0900_P1_KC_COARSE_EXP 0xf43d00f0 +#define F0900_P1_BETA_FREQ 0xf43d000f /*P1_CARHDR*/ -#define R0900_P1_CARHDR 0xf43e -#define F0900_P1_K_FREQ_HDR 0xf43e00ff +#define R0900_P1_CARHDR 0xf43e +#define CARHDR REGx(R0900_P1_CARHDR) +#define F0900_P1_K_FREQ_HDR 0xf43e00ff /*P1_LDT*/ -#define R0900_P1_LDT 0xf43f -#define F0900_P1_CARLOCK_THRES 0xf43f01ff +#define R0900_P1_LDT 0xf43f +#define LDT REGx(R0900_P1_LDT) +#define F0900_P1_CARLOCK_THRES 0xf43f01ff /*P1_LDT2*/ -#define R0900_P1_LDT2 0xf440 -#define F0900_P1_CARLOCK_THRES2 0xf44001ff +#define R0900_P1_LDT2 0xf440 +#define LDT2 REGx(R0900_P1_LDT2) +#define F0900_P1_CARLOCK_THRES2 0xf44001ff /*P1_CFRICFG*/ -#define R0900_P1_CFRICFG 0xf441 -#define F0900_P1_CFRINIT_UNVALRNG 0xf4410080 -#define F0900_P1_CFRINIT_LUNVALCPT 0xf4410040 -#define F0900_P1_CFRINIT_ABORTDBL 0xf4410020 -#define F0900_P1_CFRINIT_ABORTPRED 0xf4410010 -#define F0900_P1_CFRINIT_UNVALSKIP 0xf4410008 -#define F0900_P1_CFRINIT_CSTINC 0xf4410004 -#define F0900_P1_NEG_CFRSTEP 0xf4410001 +#define R0900_P1_CFRICFG 0xf441 +#define CFRICFG REGx(R0900_P1_CFRICFG) +#define F0900_P1_NEG_CFRSTEP 0xf4410001 /*P1_CFRUP1*/ -#define R0900_P1_CFRUP1 0xf442 -#define F0900_P1_CFR_UP1 0xf44201ff +#define R0900_P1_CFRUP1 0xf442 +#define CFRUP1 REGx(R0900_P1_CFRUP1) +#define F0900_P1_CFR_UP1 0xf44201ff +#define CFR_UP1 FLDx(F0900_P1_CFR_UP1) /*P1_CFRUP0*/ -#define R0900_P1_CFRUP0 0xf443 -#define F0900_P1_CFR_UP0 0xf44300ff +#define R0900_P1_CFRUP0 0xf443 +#define CFRUP0 REGx(R0900_P1_CFRUP0) +#define F0900_P1_CFR_UP0 0xf44300ff +#define CFR_UP0 FLDx(F0900_P1_CFR_UP0) /*P1_CFRLOW1*/ -#define R0900_P1_CFRLOW1 0xf446 -#define F0900_P1_CFR_LOW1 0xf44601ff +#define R0900_P1_CFRLOW1 0xf446 +#define CFRLOW1 REGx(R0900_P1_CFRLOW1) +#define F0900_P1_CFR_LOW1 0xf44601ff +#define CFR_LOW1 FLDx(F0900_P1_CFR_LOW1) /*P1_CFRLOW0*/ -#define R0900_P1_CFRLOW0 0xf447 -#define F0900_P1_CFR_LOW0 0xf44700ff +#define R0900_P1_CFRLOW0 0xf447 +#define CFRLOW0 REGx(R0900_P1_CFRLOW0) +#define F0900_P1_CFR_LOW0 0xf44700ff +#define CFR_LOW0 FLDx(F0900_P1_CFR_LOW0) /*P1_CFRINIT1*/ -#define R0900_P1_CFRINIT1 0xf448 -#define F0900_P1_CFR_INIT1 0xf44801ff +#define R0900_P1_CFRINIT1 0xf448 +#define CFRINIT1 REGx(R0900_P1_CFRINIT1) +#define F0900_P1_CFR_INIT1 0xf44801ff +#define CFR_INIT1 FLDx(F0900_P1_CFR_INIT1) /*P1_CFRINIT0*/ -#define R0900_P1_CFRINIT0 0xf449 -#define F0900_P1_CFR_INIT0 0xf44900ff +#define R0900_P1_CFRINIT0 0xf449 +#define CFRINIT0 REGx(R0900_P1_CFRINIT0) +#define F0900_P1_CFR_INIT0 0xf44900ff +#define CFR_INIT0 FLDx(F0900_P1_CFR_INIT0) /*P1_CFRINC1*/ -#define R0900_P1_CFRINC1 0xf44a -#define F0900_P1_MANUAL_CFRINC 0xf44a0080 -#define F0900_P1_CFR_INC1 0xf44a017f +#define R0900_P1_CFRINC1 0xf44a +#define CFRINC1 REGx(R0900_P1_CFRINC1) +#define F0900_P1_MANUAL_CFRINC 0xf44a0080 +#define F0900_P1_CFR_INC1 0xf44a003f /*P1_CFRINC0*/ -#define R0900_P1_CFRINC0 0xf44b -#define F0900_P1_CFR_INC0 0xf44b00f0 +#define R0900_P1_CFRINC0 0xf44b +#define CFRINC0 REGx(R0900_P1_CFRINC0) +#define F0900_P1_CFR_INC0 0xf44b00f8 /*P1_CFR2*/ -#define R0900_P1_CFR2 0xf44c -#define F0900_P1_CAR_FREQ2 0xf44c01ff +#define R0900_P1_CFR2 0xf44c +#define CFR2 REGx(R0900_P1_CFR2) +#define F0900_P1_CAR_FREQ2 0xf44c01ff +#define CAR_FREQ2 FLDx(F0900_P1_CAR_FREQ2) /*P1_CFR1*/ -#define R0900_P1_CFR1 0xf44d -#define F0900_P1_CAR_FREQ1 0xf44d00ff +#define R0900_P1_CFR1 0xf44d +#define CFR1 REGx(R0900_P1_CFR1) +#define F0900_P1_CAR_FREQ1 0xf44d00ff +#define CAR_FREQ1 FLDx(F0900_P1_CAR_FREQ1) /*P1_CFR0*/ -#define R0900_P1_CFR0 0xf44e -#define F0900_P1_CAR_FREQ0 0xf44e00ff +#define R0900_P1_CFR0 0xf44e +#define CFR0 REGx(R0900_P1_CFR0) +#define F0900_P1_CAR_FREQ0 0xf44e00ff +#define CAR_FREQ0 FLDx(F0900_P1_CAR_FREQ0) /*P1_LDI*/ -#define R0900_P1_LDI 0xf44f -#define F0900_P1_LOCK_DET_INTEGR 0xf44f01ff +#define R0900_P1_LDI 0xf44f +#define LDI REGx(R0900_P1_LDI) +#define F0900_P1_LOCK_DET_INTEGR 0xf44f01ff /*P1_TMGCFG*/ -#define R0900_P1_TMGCFG 0xf450 -#define F0900_P1_TMGLOCK_BETA 0xf45000c0 -#define F0900_P1_NOTMG_GROUPDELAY 0xf4500020 -#define F0900_P1_DO_TIMING_CORR 0xf4500010 -#define F0900_P1_MANUAL_SCAN 0xf450000c -#define F0900_P1_TMG_MINFREQ 0xf4500003 +#define R0900_P1_TMGCFG 0xf450 +#define TMGCFG REGx(R0900_P1_TMGCFG) +#define F0900_P1_TMGLOCK_BETA 0xf45000c0 +#define F0900_P1_DO_TIMING_CORR 0xf4500010 +#define F0900_P1_TMG_MINFREQ 0xf4500003 /*P1_RTC*/ -#define R0900_P1_RTC 0xf451 -#define F0900_P1_TMGALPHA_EXP 0xf45100f0 -#define F0900_P1_TMGBETA_EXP 0xf451000f +#define R0900_P1_RTC 0xf451 +#define RTC REGx(R0900_P1_RTC) +#define F0900_P1_TMGALPHA_EXP 0xf45100f0 +#define F0900_P1_TMGBETA_EXP 0xf451000f /*P1_RTCS2*/ -#define R0900_P1_RTCS2 0xf452 -#define F0900_P1_TMGALPHAS2_EXP 0xf45200f0 -#define F0900_P1_TMGBETAS2_EXP 0xf452000f +#define R0900_P1_RTCS2 0xf452 +#define RTCS2 REGx(R0900_P1_RTCS2) +#define F0900_P1_TMGALPHAS2_EXP 0xf45200f0 +#define F0900_P1_TMGBETAS2_EXP 0xf452000f /*P1_TMGTHRISE*/ -#define R0900_P1_TMGTHRISE 0xf453 -#define F0900_P1_TMGLOCK_THRISE 0xf45300ff +#define R0900_P1_TMGTHRISE 0xf453 +#define TMGTHRISE REGx(R0900_P1_TMGTHRISE) +#define F0900_P1_TMGLOCK_THRISE 0xf45300ff /*P1_TMGTHFALL*/ -#define R0900_P1_TMGTHFALL 0xf454 -#define F0900_P1_TMGLOCK_THFALL 0xf45400ff +#define R0900_P1_TMGTHFALL 0xf454 +#define TMGTHFALL REGx(R0900_P1_TMGTHFALL) +#define F0900_P1_TMGLOCK_THFALL 0xf45400ff /*P1_SFRUPRATIO*/ -#define R0900_P1_SFRUPRATIO 0xf455 -#define F0900_P1_SFR_UPRATIO 0xf45500ff +#define R0900_P1_SFRUPRATIO 0xf455 +#define SFRUPRATIO REGx(R0900_P1_SFRUPRATIO) +#define F0900_P1_SFR_UPRATIO 0xf45500ff /*P1_SFRLOWRATIO*/ -#define R0900_P1_SFRLOWRATIO 0xf456 -#define F0900_P1_SFR_LOWRATIO 0xf45600ff +#define R0900_P1_SFRLOWRATIO 0xf456 +#define F0900_P1_SFR_LOWRATIO 0xf45600ff /*P1_KREFTMG*/ -#define R0900_P1_KREFTMG 0xf458 -#define F0900_P1_KREF_TMG 0xf45800ff +#define R0900_P1_KREFTMG 0xf458 +#define KREFTMG REGx(R0900_P1_KREFTMG) +#define F0900_P1_KREF_TMG 0xf45800ff /*P1_SFRSTEP*/ -#define R0900_P1_SFRSTEP 0xf459 -#define F0900_P1_SFR_SCANSTEP 0xf45900f0 -#define F0900_P1_SFR_CENTERSTEP 0xf459000f +#define R0900_P1_SFRSTEP 0xf459 +#define SFRSTEP REGx(R0900_P1_SFRSTEP) +#define F0900_P1_SFR_SCANSTEP 0xf45900f0 +#define F0900_P1_SFR_CENTERSTEP 0xf459000f /*P1_TMGCFG2*/ -#define R0900_P1_TMGCFG2 0xf45a -#define F0900_P1_DIS_AUTOSAMP 0xf45a0008 -#define F0900_P1_SCANINIT_QUART 0xf45a0004 -#define F0900_P1_NOTMG_DVBS1DERAT 0xf45a0002 -#define F0900_P1_SFRRATIO_FINE 0xf45a0001 +#define R0900_P1_TMGCFG2 0xf45a +#define TMGCFG2 REGx(R0900_P1_TMGCFG2) +#define F0900_P1_SFRRATIO_FINE 0xf45a0001 + +/*P1_KREFTMG2*/ +#define R0900_P1_KREFTMG2 0xf45b +#define KREFTMG2 REGx(R0900_P1_KREFTMG2) +#define F0900_P1_KREF_TMG2 0xf45b00ff /*P1_SFRINIT1*/ -#define R0900_P1_SFRINIT1 0xf45e -#define F0900_P1_SFR_INIT1 0xf45e00ff +#define R0900_P1_SFRINIT1 0xf45e +#define SFRINIT1 REGx(R0900_P1_SFRINIT1) +#define F0900_P1_SFR_INIT1 0xf45e007f /*P1_SFRINIT0*/ -#define R0900_P1_SFRINIT0 0xf45f -#define F0900_P1_SFR_INIT0 0xf45f00ff +#define R0900_P1_SFRINIT0 0xf45f +#define SFRINIT0 REGx(R0900_P1_SFRINIT0) +#define F0900_P1_SFR_INIT0 0xf45f00ff /*P1_SFRUP1*/ -#define R0900_P1_SFRUP1 0xf460 -#define F0900_P1_AUTO_GUP 0xf4600080 -#define F0900_P1_SYMB_FREQ_UP1 0xf460007f +#define R0900_P1_SFRUP1 0xf460 +#define SFRUP1 REGx(R0900_P1_SFRUP1) +#define F0900_P1_AUTO_GUP 0xf4600080 +#define AUTO_GUP FLDx(F0900_P1_AUTO_GUP) +#define F0900_P1_SYMB_FREQ_UP1 0xf460007f /*P1_SFRUP0*/ -#define R0900_P1_SFRUP0 0xf461 -#define F0900_P1_SYMB_FREQ_UP0 0xf46100ff +#define R0900_P1_SFRUP0 0xf461 +#define SFRUP0 REGx(R0900_P1_SFRUP0) +#define F0900_P1_SYMB_FREQ_UP0 0xf46100ff /*P1_SFRLOW1*/ -#define R0900_P1_SFRLOW1 0xf462 -#define F0900_P1_AUTO_GLOW 0xf4620080 -#define F0900_P1_SYMB_FREQ_LOW1 0xf462007f +#define R0900_P1_SFRLOW1 0xf462 +#define SFRLOW1 REGx(R0900_P1_SFRLOW1) +#define F0900_P1_AUTO_GLOW 0xf4620080 +#define AUTO_GLOW FLDx(F0900_P1_AUTO_GLOW) +#define F0900_P1_SYMB_FREQ_LOW1 0xf462007f /*P1_SFRLOW0*/ -#define R0900_P1_SFRLOW0 0xf463 -#define F0900_P1_SYMB_FREQ_LOW0 0xf46300ff +#define R0900_P1_SFRLOW0 0xf463 +#define SFRLOW0 REGx(R0900_P1_SFRLOW0) +#define F0900_P1_SYMB_FREQ_LOW0 0xf46300ff /*P1_SFR3*/ -#define R0900_P1_SFR3 0xf464 -#define F0900_P1_SYMB_FREQ3 0xf46400ff +#define R0900_P1_SFR3 0xf464 +#define SFR3 REGx(R0900_P1_SFR3) +#define F0900_P1_SYMB_FREQ3 0xf46400ff +#define SYMB_FREQ3 FLDx(F0900_P1_SYMB_FREQ3) /*P1_SFR2*/ -#define R0900_P1_SFR2 0xf465 -#define F0900_P1_SYMB_FREQ2 0xf46500ff +#define R0900_P1_SFR2 0xf465 +#define SFR2 REGx(R0900_P1_SFR2) +#define F0900_P1_SYMB_FREQ2 0xf46500ff +#define SYMB_FREQ2 FLDx(F0900_P1_SYMB_FREQ2) /*P1_SFR1*/ -#define R0900_P1_SFR1 0xf466 -#define F0900_P1_SYMB_FREQ1 0xf46600ff +#define R0900_P1_SFR1 0xf466 +#define SFR1 REGx(R0900_P1_SFR1) +#define F0900_P1_SYMB_FREQ1 0xf46600ff +#define SYMB_FREQ1 FLDx(F0900_P1_SYMB_FREQ1) /*P1_SFR0*/ -#define R0900_P1_SFR0 0xf467 -#define F0900_P1_SYMB_FREQ0 0xf46700ff +#define R0900_P1_SFR0 0xf467 +#define SFR0 REGx(R0900_P1_SFR0) +#define F0900_P1_SYMB_FREQ0 0xf46700ff +#define SYMB_FREQ0 FLDx(F0900_P1_SYMB_FREQ0) /*P1_TMGREG2*/ -#define R0900_P1_TMGREG2 0xf468 -#define F0900_P1_TMGREG2 0xf46800ff +#define R0900_P1_TMGREG2 0xf468 +#define TMGREG2 REGx(R0900_P1_TMGREG2) +#define F0900_P1_TMGREG2 0xf46800ff /*P1_TMGREG1*/ -#define R0900_P1_TMGREG1 0xf469 -#define F0900_P1_TMGREG1 0xf46900ff +#define R0900_P1_TMGREG1 0xf469 +#define TMGREG1 REGx(R0900_P1_TMGREG1) +#define F0900_P1_TMGREG1 0xf46900ff /*P1_TMGREG0*/ -#define R0900_P1_TMGREG0 0xf46a -#define F0900_P1_TMGREG0 0xf46a00ff +#define R0900_P1_TMGREG0 0xf46a +#define TMGREG0 REGx(R0900_P1_TMGREG0) +#define F0900_P1_TMGREG0 0xf46a00ff /*P1_TMGLOCK1*/ -#define R0900_P1_TMGLOCK1 0xf46b -#define F0900_P1_TMGLOCK_LEVEL1 0xf46b01ff +#define R0900_P1_TMGLOCK1 0xf46b +#define TMGLOCK1 REGx(R0900_P1_TMGLOCK1) +#define F0900_P1_TMGLOCK_LEVEL1 0xf46b01ff /*P1_TMGLOCK0*/ -#define R0900_P1_TMGLOCK0 0xf46c -#define F0900_P1_TMGLOCK_LEVEL0 0xf46c00ff +#define R0900_P1_TMGLOCK0 0xf46c +#define TMGLOCK0 REGx(R0900_P1_TMGLOCK0) +#define F0900_P1_TMGLOCK_LEVEL0 0xf46c00ff /*P1_TMGOBS*/ -#define R0900_P1_TMGOBS 0xf46d -#define F0900_P1_ROLLOFF_STATUS 0xf46d00c0 -#define F0900_P1_SCAN_SIGN 0xf46d0030 -#define F0900_P1_TMG_SCANNING 0xf46d0008 -#define F0900_P1_CHCENTERING_MODE 0xf46d0004 -#define F0900_P1_TMG_SCANFAIL 0xf46d0002 +#define R0900_P1_TMGOBS 0xf46d +#define TMGOBS REGx(R0900_P1_TMGOBS) +#define F0900_P1_ROLLOFF_STATUS 0xf46d00c0 +#define ROLLOFF_STATUS FLDx(F0900_P1_ROLLOFF_STATUS) /*P1_EQUALCFG*/ -#define R0900_P1_EQUALCFG 0xf46f -#define F0900_P1_NOTMG_NEGALWAIT 0xf46f0080 -#define F0900_P1_EQUAL_ON 0xf46f0040 -#define F0900_P1_SEL_EQUALCOR 0xf46f0038 -#define F0900_P1_MU_EQUALDFE 0xf46f0007 +#define R0900_P1_EQUALCFG 0xf46f +#define EQUALCFG REGx(R0900_P1_EQUALCFG) +#define F0900_P1_EQUAL_ON 0xf46f0040 +#define F0900_P1_MU_EQUALDFE 0xf46f0007 /*P1_EQUAI1*/ -#define R0900_P1_EQUAI1 0xf470 -#define F0900_P1_EQUA_ACCI1 0xf47001ff +#define R0900_P1_EQUAI1 0xf470 +#define EQUAI1 REGx(R0900_P1_EQUAI1) +#define F0900_P1_EQUA_ACCI1 0xf47001ff /*P1_EQUAQ1*/ -#define R0900_P1_EQUAQ1 0xf471 -#define F0900_P1_EQUA_ACCQ1 0xf47101ff +#define R0900_P1_EQUAQ1 0xf471 +#define EQUAQ1 REGx(R0900_P1_EQUAQ1) +#define F0900_P1_EQUA_ACCQ1 0xf47101ff /*P1_EQUAI2*/ -#define R0900_P1_EQUAI2 0xf472 -#define F0900_P1_EQUA_ACCI2 0xf47201ff +#define R0900_P1_EQUAI2 0xf472 +#define EQUAI2 REGx(R0900_P1_EQUAI2) +#define F0900_P1_EQUA_ACCI2 0xf47201ff /*P1_EQUAQ2*/ -#define R0900_P1_EQUAQ2 0xf473 -#define F0900_P1_EQUA_ACCQ2 0xf47301ff +#define R0900_P1_EQUAQ2 0xf473 +#define EQUAQ2 REGx(R0900_P1_EQUAQ2) +#define F0900_P1_EQUA_ACCQ2 0xf47301ff /*P1_EQUAI3*/ -#define R0900_P1_EQUAI3 0xf474 -#define F0900_P1_EQUA_ACCI3 0xf47401ff +#define R0900_P1_EQUAI3 0xf474 +#define EQUAI3 REGx(R0900_P1_EQUAI3) +#define F0900_P1_EQUA_ACCI3 0xf47401ff /*P1_EQUAQ3*/ -#define R0900_P1_EQUAQ3 0xf475 -#define F0900_P1_EQUA_ACCQ3 0xf47501ff +#define R0900_P1_EQUAQ3 0xf475 +#define EQUAQ3 REGx(R0900_P1_EQUAQ3) +#define F0900_P1_EQUA_ACCQ3 0xf47501ff /*P1_EQUAI4*/ -#define R0900_P1_EQUAI4 0xf476 -#define F0900_P1_EQUA_ACCI4 0xf47601ff +#define R0900_P1_EQUAI4 0xf476 +#define EQUAI4 REGx(R0900_P1_EQUAI4) +#define F0900_P1_EQUA_ACCI4 0xf47601ff /*P1_EQUAQ4*/ -#define R0900_P1_EQUAQ4 0xf477 -#define F0900_P1_EQUA_ACCQ4 0xf47701ff +#define R0900_P1_EQUAQ4 0xf477 +#define EQUAQ4 REGx(R0900_P1_EQUAQ4) +#define F0900_P1_EQUA_ACCQ4 0xf47701ff /*P1_EQUAI5*/ -#define R0900_P1_EQUAI5 0xf478 -#define F0900_P1_EQUA_ACCI5 0xf47801ff +#define R0900_P1_EQUAI5 0xf478 +#define EQUAI5 REGx(R0900_P1_EQUAI5) +#define F0900_P1_EQUA_ACCI5 0xf47801ff /*P1_EQUAQ5*/ -#define R0900_P1_EQUAQ5 0xf479 -#define F0900_P1_EQUA_ACCQ5 0xf47901ff +#define R0900_P1_EQUAQ5 0xf479 +#define EQUAQ5 REGx(R0900_P1_EQUAQ5) +#define F0900_P1_EQUA_ACCQ5 0xf47901ff /*P1_EQUAI6*/ -#define R0900_P1_EQUAI6 0xf47a -#define F0900_P1_EQUA_ACCI6 0xf47a01ff +#define R0900_P1_EQUAI6 0xf47a +#define EQUAI6 REGx(R0900_P1_EQUAI6) +#define F0900_P1_EQUA_ACCI6 0xf47a01ff /*P1_EQUAQ6*/ -#define R0900_P1_EQUAQ6 0xf47b -#define F0900_P1_EQUA_ACCQ6 0xf47b01ff +#define R0900_P1_EQUAQ6 0xf47b +#define EQUAQ6 REGx(R0900_P1_EQUAQ6) +#define F0900_P1_EQUA_ACCQ6 0xf47b01ff /*P1_EQUAI7*/ -#define R0900_P1_EQUAI7 0xf47c -#define F0900_P1_EQUA_ACCI7 0xf47c01ff +#define R0900_P1_EQUAI7 0xf47c +#define EQUAI7 REGx(R0900_P1_EQUAI7) +#define F0900_P1_EQUA_ACCI7 0xf47c01ff /*P1_EQUAQ7*/ -#define R0900_P1_EQUAQ7 0xf47d -#define F0900_P1_EQUA_ACCQ7 0xf47d01ff +#define R0900_P1_EQUAQ7 0xf47d +#define EQUAQ7 REGx(R0900_P1_EQUAQ7) +#define F0900_P1_EQUA_ACCQ7 0xf47d01ff /*P1_EQUAI8*/ -#define R0900_P1_EQUAI8 0xf47e -#define F0900_P1_EQUA_ACCI8 0xf47e01ff +#define R0900_P1_EQUAI8 0xf47e +#define EQUAI8 REGx(R0900_P1_EQUAI8) +#define F0900_P1_EQUA_ACCI8 0xf47e01ff /*P1_EQUAQ8*/ -#define R0900_P1_EQUAQ8 0xf47f -#define F0900_P1_EQUA_ACCQ8 0xf47f01ff +#define R0900_P1_EQUAQ8 0xf47f +#define EQUAQ8 REGx(R0900_P1_EQUAQ8) +#define F0900_P1_EQUA_ACCQ8 0xf47f01ff /*P1_NNOSDATAT1*/ -#define R0900_P1_NNOSDATAT1 0xf480 -#define F0900_P1_NOSDATAT_NORMED1 0xf48000ff +#define R0900_P1_NNOSDATAT1 0xf480 +#define NNOSDATAT1 REGx(R0900_P1_NNOSDATAT1) +#define F0900_P1_NOSDATAT_NORMED1 0xf48000ff +#define NOSDATAT_NORMED1 FLDx(F0900_P1_NOSDATAT_NORMED1) /*P1_NNOSDATAT0*/ -#define R0900_P1_NNOSDATAT0 0xf481 -#define F0900_P1_NOSDATAT_NORMED0 0xf48100ff +#define R0900_P1_NNOSDATAT0 0xf481 +#define NNOSDATAT0 REGx(R0900_P1_NNOSDATAT0) +#define F0900_P1_NOSDATAT_NORMED0 0xf48100ff +#define NOSDATAT_NORMED0 FLDx(F0900_P1_NOSDATAT_NORMED0) /*P1_NNOSDATA1*/ -#define R0900_P1_NNOSDATA1 0xf482 -#define F0900_P1_NOSDATA_NORMED1 0xf48200ff +#define R0900_P1_NNOSDATA1 0xf482 +#define NNOSDATA1 REGx(R0900_P1_NNOSDATA1) +#define F0900_P1_NOSDATA_NORMED1 0xf48200ff /*P1_NNOSDATA0*/ -#define R0900_P1_NNOSDATA0 0xf483 -#define F0900_P1_NOSDATA_NORMED0 0xf48300ff +#define R0900_P1_NNOSDATA0 0xf483 +#define NNOSDATA0 REGx(R0900_P1_NNOSDATA0) +#define F0900_P1_NOSDATA_NORMED0 0xf48300ff /*P1_NNOSPLHT1*/ -#define R0900_P1_NNOSPLHT1 0xf484 -#define F0900_P1_NOSPLHT_NORMED1 0xf48400ff +#define R0900_P1_NNOSPLHT1 0xf484 +#define NNOSPLHT1 REGx(R0900_P1_NNOSPLHT1) +#define F0900_P1_NOSPLHT_NORMED1 0xf48400ff +#define NOSPLHT_NORMED1 FLDx(F0900_P1_NOSPLHT_NORMED1) /*P1_NNOSPLHT0*/ -#define R0900_P1_NNOSPLHT0 0xf485 -#define F0900_P1_NOSPLHT_NORMED0 0xf48500ff +#define R0900_P1_NNOSPLHT0 0xf485 +#define NNOSPLHT0 REGx(R0900_P1_NNOSPLHT0) +#define F0900_P1_NOSPLHT_NORMED0 0xf48500ff +#define NOSPLHT_NORMED0 FLDx(F0900_P1_NOSPLHT_NORMED0) /*P1_NNOSPLH1*/ -#define R0900_P1_NNOSPLH1 0xf486 -#define F0900_P1_NOSPLH_NORMED1 0xf48600ff +#define R0900_P1_NNOSPLH1 0xf486 +#define NNOSPLH1 REGx(R0900_P1_NNOSPLH1) +#define F0900_P1_NOSPLH_NORMED1 0xf48600ff /*P1_NNOSPLH0*/ -#define R0900_P1_NNOSPLH0 0xf487 -#define F0900_P1_NOSPLH_NORMED0 0xf48700ff +#define R0900_P1_NNOSPLH0 0xf487 +#define NNOSPLH0 REGx(R0900_P1_NNOSPLH0) +#define F0900_P1_NOSPLH_NORMED0 0xf48700ff /*P1_NOSDATAT1*/ -#define R0900_P1_NOSDATAT1 0xf488 -#define F0900_P1_NOSDATAT_UNNORMED1 0xf48800ff +#define R0900_P1_NOSDATAT1 0xf488 +#define NOSDATAT1 REGx(R0900_P1_NOSDATAT1) +#define F0900_P1_NOSDATAT_UNNORMED1 0xf48800ff /*P1_NOSDATAT0*/ -#define R0900_P1_NOSDATAT0 0xf489 -#define F0900_P1_NOSDATAT_UNNORMED0 0xf48900ff +#define R0900_P1_NOSDATAT0 0xf489 +#define NOSDATAT0 REGx(R0900_P1_NOSDATAT0) +#define F0900_P1_NOSDATAT_UNNORMED0 0xf48900ff /*P1_NOSDATA1*/ -#define R0900_P1_NOSDATA1 0xf48a -#define F0900_P1_NOSDATA_UNNORMED1 0xf48a00ff +#define R0900_P1_NOSDATA1 0xf48a +#define NOSDATA1 REGx(R0900_P1_NOSDATA1) +#define F0900_P1_NOSDATA_UNNORMED1 0xf48a00ff /*P1_NOSDATA0*/ -#define R0900_P1_NOSDATA0 0xf48b -#define F0900_P1_NOSDATA_UNNORMED0 0xf48b00ff +#define R0900_P1_NOSDATA0 0xf48b +#define NOSDATA0 REGx(R0900_P1_NOSDATA0) +#define F0900_P1_NOSDATA_UNNORMED0 0xf48b00ff /*P1_NOSPLHT1*/ -#define R0900_P1_NOSPLHT1 0xf48c -#define F0900_P1_NOSPLHT_UNNORMED1 0xf48c00ff +#define R0900_P1_NOSPLHT1 0xf48c +#define NOSPLHT1 REGx(R0900_P1_NOSPLHT1) +#define F0900_P1_NOSPLHT_UNNORMED1 0xf48c00ff /*P1_NOSPLHT0*/ -#define R0900_P1_NOSPLHT0 0xf48d -#define F0900_P1_NOSPLHT_UNNORMED0 0xf48d00ff +#define R0900_P1_NOSPLHT0 0xf48d +#define NOSPLHT0 REGx(R0900_P1_NOSPLHT0) +#define F0900_P1_NOSPLHT_UNNORMED0 0xf48d00ff /*P1_NOSPLH1*/ -#define R0900_P1_NOSPLH1 0xf48e -#define F0900_P1_NOSPLH_UNNORMED1 0xf48e00ff +#define R0900_P1_NOSPLH1 0xf48e +#define NOSPLH1 REGx(R0900_P1_NOSPLH1) +#define F0900_P1_NOSPLH_UNNORMED1 0xf48e00ff /*P1_NOSPLH0*/ -#define R0900_P1_NOSPLH0 0xf48f -#define F0900_P1_NOSPLH_UNNORMED0 0xf48f00ff +#define R0900_P1_NOSPLH0 0xf48f +#define NOSPLH0 REGx(R0900_P1_NOSPLH0) +#define F0900_P1_NOSPLH_UNNORMED0 0xf48f00ff /*P1_CAR2CFG*/ -#define R0900_P1_CAR2CFG 0xf490 -#define F0900_P1_DESCRAMB_OFF 0xf4900080 -#define F0900_P1_PN4_SELECT 0xf4900040 -#define F0900_P1_CFR2_STOPDVBS1 0xf4900020 -#define F0900_P1_STOP_CFR2UPDATE 0xf4900010 -#define F0900_P1_STOP_NCO2UPDATE 0xf4900008 -#define F0900_P1_ROTA2ON 0xf4900004 -#define F0900_P1_PH_DET_ALGO2 0xf4900003 - -/*P1_ACLC2*/ -#define R0900_P1_ACLC2 0xf491 -#define F0900_P1_CAR2_PUNCT_ADERAT 0xf4910040 -#define F0900_P1_CAR2_ALPHA_MANT 0xf4910030 -#define F0900_P1_CAR2_ALPHA_EXP 0xf491000f - -/*P1_BCLC2*/ -#define R0900_P1_BCLC2 0xf492 -#define F0900_P1_DVBS2_NIP 0xf4920080 -#define F0900_P1_CAR2_PUNCT_BDERAT 0xf4920040 -#define F0900_P1_CAR2_BETA_MANT 0xf4920030 -#define F0900_P1_CAR2_BETA_EXP 0xf492000f +#define R0900_P1_CAR2CFG 0xf490 +#define CAR2CFG REGx(R0900_P1_CAR2CFG) +#define F0900_P1_CARRIER3_DISABLE 0xf4900040 +#define F0900_P1_ROTA2ON 0xf4900004 +#define F0900_P1_PH_DET_ALGO2 0xf4900003 + +/*P1_CFR2CFR1*/ +#define R0900_P1_CFR2CFR1 0xf491 +#define CFR2CFR1 REGx(R0900_P1_CFR2CFR1) +#define F0900_P1_CFR2TOCFR1_DVBS1 0xf49100c0 +#define F0900_P1_EN_S2CAR2CENTER 0xf4910020 +#define F0900_P1_DIS_BCHERRCFR2 0xf4910010 +#define F0900_P1_CFR2TOCFR1_BETA 0xf4910007 /*P1_CFR22*/ -#define R0900_P1_CFR22 0xf493 -#define F0900_P1_CAR2_FREQ2 0xf49301ff +#define R0900_P1_CFR22 0xf493 +#define CFR22 REGx(R0900_P1_CFR22) +#define F0900_P1_CAR2_FREQ2 0xf49301ff /*P1_CFR21*/ -#define R0900_P1_CFR21 0xf494 -#define F0900_P1_CAR2_FREQ1 0xf49400ff +#define R0900_P1_CFR21 0xf494 +#define CFR21 REGx(R0900_P1_CFR21) +#define F0900_P1_CAR2_FREQ1 0xf49400ff /*P1_CFR20*/ -#define R0900_P1_CFR20 0xf495 -#define F0900_P1_CAR2_FREQ0 0xf49500ff +#define R0900_P1_CFR20 0xf495 +#define CFR20 REGx(R0900_P1_CFR20) +#define F0900_P1_CAR2_FREQ0 0xf49500ff /*P1_ACLC2S2Q*/ -#define R0900_P1_ACLC2S2Q 0xf497 -#define F0900_P1_ENAB_SPSKSYMB 0xf4970080 -#define F0900_P1_CAR2S2_QADERAT 0xf4970040 -#define F0900_P1_CAR2S2_Q_ALPH_M 0xf4970030 -#define F0900_P1_CAR2S2_Q_ALPH_E 0xf497000f +#define R0900_P1_ACLC2S2Q 0xf497 +#define ACLC2S2Q REGx(R0900_P1_ACLC2S2Q) +#define F0900_P1_ENAB_SPSKSYMB 0xf4970080 +#define F0900_P1_CAR2S2_Q_ALPH_M 0xf4970030 +#define F0900_P1_CAR2S2_Q_ALPH_E 0xf497000f /*P1_ACLC2S28*/ -#define R0900_P1_ACLC2S28 0xf498 -#define F0900_P1_OLDI3Q_MODE 0xf4980080 -#define F0900_P1_CAR2S2_8ADERAT 0xf4980040 -#define F0900_P1_CAR2S2_8_ALPH_M 0xf4980030 -#define F0900_P1_CAR2S2_8_ALPH_E 0xf498000f +#define R0900_P1_ACLC2S28 0xf498 +#define ACLC2S28 REGx(R0900_P1_ACLC2S28) +#define F0900_P1_OLDI3Q_MODE 0xf4980080 +#define F0900_P1_CAR2S2_8_ALPH_M 0xf4980030 +#define F0900_P1_CAR2S2_8_ALPH_E 0xf498000f /*P1_ACLC2S216A*/ -#define R0900_P1_ACLC2S216A 0xf499 -#define F0900_P1_CAR2S2_16ADERAT 0xf4990040 -#define F0900_P1_CAR2S2_16A_ALPH_M 0xf4990030 -#define F0900_P1_CAR2S2_16A_ALPH_E 0xf499000f +#define R0900_P1_ACLC2S216A 0xf499 +#define ACLC2S216A REGx(R0900_P1_ACLC2S216A) +#define F0900_P1_DIS_C3STOPA2 0xf4990080 +#define F0900_P1_CAR2S2_16ADERAT 0xf4990040 +#define F0900_P1_CAR2S2_16A_ALPH_M 0xf4990030 +#define F0900_P1_CAR2S2_16A_ALPH_E 0xf499000f /*P1_ACLC2S232A*/ -#define R0900_P1_ACLC2S232A 0xf49a -#define F0900_P1_CAR2S2_32ADERAT 0xf49a0040 -#define F0900_P1_CAR2S2_32A_ALPH_M 0xf49a0030 -#define F0900_P1_CAR2S2_32A_ALPH_E 0xf49a000f +#define R0900_P1_ACLC2S232A 0xf49a +#define ACLC2S232A REGx(R0900_P1_ACLC2S232A) +#define F0900_P1_CAR2S2_32ADERAT 0xf49a0040 +#define F0900_P1_CAR2S2_32A_ALPH_M 0xf49a0030 +#define F0900_P1_CAR2S2_32A_ALPH_E 0xf49a000f /*P1_BCLC2S2Q*/ -#define R0900_P1_BCLC2S2Q 0xf49c -#define F0900_P1_DVBS2S2Q_NIP 0xf49c0080 -#define F0900_P1_CAR2S2_QBDERAT 0xf49c0040 -#define F0900_P1_CAR2S2_Q_BETA_M 0xf49c0030 -#define F0900_P1_CAR2S2_Q_BETA_E 0xf49c000f +#define R0900_P1_BCLC2S2Q 0xf49c +#define BCLC2S2Q REGx(R0900_P1_BCLC2S2Q) +#define F0900_P1_CAR2S2_Q_BETA_M 0xf49c0030 +#define F0900_P1_CAR2S2_Q_BETA_E 0xf49c000f /*P1_BCLC2S28*/ -#define R0900_P1_BCLC2S28 0xf49d -#define F0900_P1_DVBS2S28_NIP 0xf49d0080 -#define F0900_P1_CAR2S2_8BDERAT 0xf49d0040 -#define F0900_P1_CAR2S2_8_BETA_M 0xf49d0030 -#define F0900_P1_CAR2S2_8_BETA_E 0xf49d000f +#define R0900_P1_BCLC2S28 0xf49d +#define BCLC2S28 REGx(R0900_P1_BCLC2S28) +#define F0900_P1_CAR2S2_8_BETA_M 0xf49d0030 +#define F0900_P1_CAR2S2_8_BETA_E 0xf49d000f /*P1_BCLC2S216A*/ -#define R0900_P1_BCLC2S216A 0xf49e -#define F0900_P1_DVBS2S216A_NIP 0xf49e0080 -#define F0900_P1_CAR2S2_16BDERAT 0xf49e0040 -#define F0900_P1_CAR2S2_16A_BETA_M 0xf49e0030 -#define F0900_P1_CAR2S2_16A_BETA_E 0xf49e000f +#define R0900_P1_BCLC2S216A 0xf49e +#define BCLC2S216A REGx(R0900_P1_BCLC2S216A) /*P1_BCLC2S232A*/ -#define R0900_P1_BCLC2S232A 0xf49f -#define F0900_P1_DVBS2S232A_NIP 0xf49f0080 -#define F0900_P1_CAR2S2_32BDERAT 0xf49f0040 -#define F0900_P1_CAR2S2_32A_BETA_M 0xf49f0030 -#define F0900_P1_CAR2S2_32A_BETA_E 0xf49f000f +#define R0900_P1_BCLC2S232A 0xf49f +#define BCLC2S232A REGx(R0900_P1_BCLC2S232A) /*P1_PLROOT2*/ -#define R0900_P1_PLROOT2 0xf4ac -#define F0900_P1_SHORTFR_DISABLE 0xf4ac0080 -#define F0900_P1_LONGFR_DISABLE 0xf4ac0040 -#define F0900_P1_DUMMYPL_DISABLE 0xf4ac0020 -#define F0900_P1_SHORTFR_AVOID 0xf4ac0010 -#define F0900_P1_PLSCRAMB_MODE 0xf4ac000c -#define F0900_P1_PLSCRAMB_ROOT2 0xf4ac0003 +#define R0900_P1_PLROOT2 0xf4ac +#define PLROOT2 REGx(R0900_P1_PLROOT2) +#define F0900_P1_PLSCRAMB_MODE 0xf4ac000c +#define F0900_P1_PLSCRAMB_ROOT2 0xf4ac0003 /*P1_PLROOT1*/ -#define R0900_P1_PLROOT1 0xf4ad -#define F0900_P1_PLSCRAMB_ROOT1 0xf4ad00ff +#define R0900_P1_PLROOT1 0xf4ad +#define PLROOT1 REGx(R0900_P1_PLROOT1) +#define F0900_P1_PLSCRAMB_ROOT1 0xf4ad00ff /*P1_PLROOT0*/ -#define R0900_P1_PLROOT0 0xf4ae -#define F0900_P1_PLSCRAMB_ROOT0 0xf4ae00ff +#define R0900_P1_PLROOT0 0xf4ae +#define PLROOT0 REGx(R0900_P1_PLROOT0) +#define F0900_P1_PLSCRAMB_ROOT0 0xf4ae00ff /*P1_MODCODLST0*/ -#define R0900_P1_MODCODLST0 0xf4b0 -#define F0900_P1_EN_TOKEN31 0xf4b00080 -#define F0900_P1_SYNCTAG_SELECT 0xf4b00040 -#define F0900_P1_MODCODRQ_MODE 0xf4b00030 +#define R0900_P1_MODCODLST0 0xf4b0 +#define MODCODLST0 REGx(R0900_P1_MODCODLST0) /*P1_MODCODLST1*/ -#define R0900_P1_MODCODLST1 0xf4b1 -#define F0900_P1_DIS_MODCOD29 0xf4b100f0 -#define F0900_P1_DIS_32PSK_9_10 0xf4b1000f +#define R0900_P1_MODCODLST1 0xf4b1 +#define MODCODLST1 REGx(R0900_P1_MODCODLST1) +#define F0900_P1_DIS_MODCOD29 0xf4b100f0 +#define F0900_P1_DIS_32PSK_9_10 0xf4b1000f /*P1_MODCODLST2*/ -#define R0900_P1_MODCODLST2 0xf4b2 -#define F0900_P1_DIS_32PSK_8_9 0xf4b200f0 -#define F0900_P1_DIS_32PSK_5_6 0xf4b2000f +#define R0900_P1_MODCODLST2 0xf4b2 +#define MODCODLST2 REGx(R0900_P1_MODCODLST2) +#define F0900_P1_DIS_32PSK_8_9 0xf4b200f0 +#define F0900_P1_DIS_32PSK_5_6 0xf4b2000f /*P1_MODCODLST3*/ -#define R0900_P1_MODCODLST3 0xf4b3 -#define F0900_P1_DIS_32PSK_4_5 0xf4b300f0 -#define F0900_P1_DIS_32PSK_3_4 0xf4b3000f +#define R0900_P1_MODCODLST3 0xf4b3 +#define MODCODLST3 REGx(R0900_P1_MODCODLST3) +#define F0900_P1_DIS_32PSK_4_5 0xf4b300f0 +#define F0900_P1_DIS_32PSK_3_4 0xf4b3000f /*P1_MODCODLST4*/ -#define R0900_P1_MODCODLST4 0xf4b4 -#define F0900_P1_DIS_16PSK_9_10 0xf4b400f0 -#define F0900_P1_DIS_16PSK_8_9 0xf4b4000f +#define R0900_P1_MODCODLST4 0xf4b4 +#define MODCODLST4 REGx(R0900_P1_MODCODLST4) +#define F0900_P1_DIS_16PSK_9_10 0xf4b400f0 +#define F0900_P1_DIS_16PSK_8_9 0xf4b4000f /*P1_MODCODLST5*/ -#define R0900_P1_MODCODLST5 0xf4b5 -#define F0900_P1_DIS_16PSK_5_6 0xf4b500f0 -#define F0900_P1_DIS_16PSK_4_5 0xf4b5000f +#define R0900_P1_MODCODLST5 0xf4b5 +#define MODCODLST5 REGx(R0900_P1_MODCODLST5) +#define F0900_P1_DIS_16PSK_5_6 0xf4b500f0 +#define F0900_P1_DIS_16PSK_4_5 0xf4b5000f /*P1_MODCODLST6*/ -#define R0900_P1_MODCODLST6 0xf4b6 -#define F0900_P1_DIS_16PSK_3_4 0xf4b600f0 -#define F0900_P1_DIS_16PSK_2_3 0xf4b6000f +#define R0900_P1_MODCODLST6 0xf4b6 +#define MODCODLST6 REGx(R0900_P1_MODCODLST6) +#define F0900_P1_DIS_16PSK_3_4 0xf4b600f0 +#define F0900_P1_DIS_16PSK_2_3 0xf4b6000f /*P1_MODCODLST7*/ -#define R0900_P1_MODCODLST7 0xf4b7 -#define F0900_P1_DIS_8P_9_10 0xf4b700f0 -#define F0900_P1_DIS_8P_8_9 0xf4b7000f +#define R0900_P1_MODCODLST7 0xf4b7 +#define MODCODLST7 REGx(R0900_P1_MODCODLST7) +#define F0900_P1_DIS_8P_9_10 0xf4b700f0 +#define F0900_P1_DIS_8P_8_9 0xf4b7000f /*P1_MODCODLST8*/ -#define R0900_P1_MODCODLST8 0xf4b8 -#define F0900_P1_DIS_8P_5_6 0xf4b800f0 -#define F0900_P1_DIS_8P_3_4 0xf4b8000f +#define R0900_P1_MODCODLST8 0xf4b8 +#define MODCODLST8 REGx(R0900_P1_MODCODLST8) +#define F0900_P1_DIS_8P_5_6 0xf4b800f0 +#define F0900_P1_DIS_8P_3_4 0xf4b8000f /*P1_MODCODLST9*/ -#define R0900_P1_MODCODLST9 0xf4b9 -#define F0900_P1_DIS_8P_2_3 0xf4b900f0 -#define F0900_P1_DIS_8P_3_5 0xf4b9000f +#define R0900_P1_MODCODLST9 0xf4b9 +#define MODCODLST9 REGx(R0900_P1_MODCODLST9) +#define F0900_P1_DIS_8P_2_3 0xf4b900f0 +#define F0900_P1_DIS_8P_3_5 0xf4b9000f /*P1_MODCODLSTA*/ -#define R0900_P1_MODCODLSTA 0xf4ba -#define F0900_P1_DIS_QP_9_10 0xf4ba00f0 -#define F0900_P1_DIS_QP_8_9 0xf4ba000f +#define R0900_P1_MODCODLSTA 0xf4ba +#define MODCODLSTA REGx(R0900_P1_MODCODLSTA) +#define F0900_P1_DIS_QP_9_10 0xf4ba00f0 +#define F0900_P1_DIS_QP_8_9 0xf4ba000f /*P1_MODCODLSTB*/ -#define R0900_P1_MODCODLSTB 0xf4bb -#define F0900_P1_DIS_QP_5_6 0xf4bb00f0 -#define F0900_P1_DIS_QP_4_5 0xf4bb000f +#define R0900_P1_MODCODLSTB 0xf4bb +#define MODCODLSTB REGx(R0900_P1_MODCODLSTB) +#define F0900_P1_DIS_QP_5_6 0xf4bb00f0 +#define F0900_P1_DIS_QP_4_5 0xf4bb000f /*P1_MODCODLSTC*/ -#define R0900_P1_MODCODLSTC 0xf4bc -#define F0900_P1_DIS_QP_3_4 0xf4bc00f0 -#define F0900_P1_DIS_QP_2_3 0xf4bc000f +#define R0900_P1_MODCODLSTC 0xf4bc +#define MODCODLSTC REGx(R0900_P1_MODCODLSTC) +#define F0900_P1_DIS_QP_3_4 0xf4bc00f0 +#define F0900_P1_DIS_QP_2_3 0xf4bc000f /*P1_MODCODLSTD*/ -#define R0900_P1_MODCODLSTD 0xf4bd -#define F0900_P1_DIS_QP_3_5 0xf4bd00f0 -#define F0900_P1_DIS_QP_1_2 0xf4bd000f +#define R0900_P1_MODCODLSTD 0xf4bd +#define MODCODLSTD REGx(R0900_P1_MODCODLSTD) +#define F0900_P1_DIS_QP_3_5 0xf4bd00f0 +#define F0900_P1_DIS_QP_1_2 0xf4bd000f /*P1_MODCODLSTE*/ -#define R0900_P1_MODCODLSTE 0xf4be -#define F0900_P1_DIS_QP_2_5 0xf4be00f0 -#define F0900_P1_DIS_QP_1_3 0xf4be000f +#define R0900_P1_MODCODLSTE 0xf4be +#define MODCODLSTE REGx(R0900_P1_MODCODLSTE) +#define F0900_P1_DIS_QP_2_5 0xf4be00f0 +#define F0900_P1_DIS_QP_1_3 0xf4be000f /*P1_MODCODLSTF*/ -#define R0900_P1_MODCODLSTF 0xf4bf -#define F0900_P1_DIS_QP_1_4 0xf4bf00f0 -#define F0900_P1_DDEMOD_SET 0xf4bf0002 -#define F0900_P1_DDEMOD_MASK 0xf4bf0001 +#define R0900_P1_MODCODLSTF 0xf4bf +#define MODCODLSTF REGx(R0900_P1_MODCODLSTF) +#define F0900_P1_DIS_QP_1_4 0xf4bf00f0 + +/*P1_GAUSSR0*/ +#define R0900_P1_GAUSSR0 0xf4c0 +#define GAUSSR0 REGx(R0900_P1_GAUSSR0) +#define F0900_P1_EN_CCIMODE 0xf4c00080 +#define F0900_P1_R0_GAUSSIEN 0xf4c0007f + +/*P1_CCIR0*/ +#define R0900_P1_CCIR0 0xf4c1 +#define CCIR0 REGx(R0900_P1_CCIR0) +#define F0900_P1_CCIDETECT_PLHONLY 0xf4c10080 +#define F0900_P1_R0_CCI 0xf4c1007f + +/*P1_CCIQUANT*/ +#define R0900_P1_CCIQUANT 0xf4c2 +#define CCIQUANT REGx(R0900_P1_CCIQUANT) +#define F0900_P1_CCI_BETA 0xf4c200e0 +#define F0900_P1_CCI_QUANT 0xf4c2001f + +/*P1_CCITHRES*/ +#define R0900_P1_CCITHRES 0xf4c3 +#define CCITHRES REGx(R0900_P1_CCITHRES) +#define F0900_P1_CCI_THRESHOLD 0xf4c300ff + +/*P1_CCIACC*/ +#define R0900_P1_CCIACC 0xf4c4 +#define CCIACC REGx(R0900_P1_CCIACC) +#define F0900_P1_CCI_VALUE 0xf4c400ff /*P1_DMDRESCFG*/ -#define R0900_P1_DMDRESCFG 0xf4c6 -#define F0900_P1_DMDRES_RESET 0xf4c60080 -#define F0900_P1_DMDRES_NOISESQR 0xf4c60010 -#define F0900_P1_DMDRES_STRALL 0xf4c60008 -#define F0900_P1_DMDRES_NEWONLY 0xf4c60004 -#define F0900_P1_DMDRES_NOSTORE 0xf4c60002 -#define F0900_P1_DMDRES_AGC2MEM 0xf4c60001 +#define R0900_P1_DMDRESCFG 0xf4c6 +#define DMDRESCFG REGx(R0900_P1_DMDRESCFG) +#define F0900_P1_DMDRES_RESET 0xf4c60080 +#define F0900_P1_DMDRES_STRALL 0xf4c60008 +#define F0900_P1_DMDRES_NEWONLY 0xf4c60004 +#define F0900_P1_DMDRES_NOSTORE 0xf4c60002 /*P1_DMDRESADR*/ -#define R0900_P1_DMDRESADR 0xf4c7 -#define F0900_P1_SUSP_PREDCANAL 0xf4c70080 -#define F0900_P1_DMDRES_VALIDCFR 0xf4c70040 -#define F0900_P1_DMDRES_MEMFULL 0xf4c70030 -#define F0900_P1_DMDRES_RESNBR 0xf4c7000f +#define R0900_P1_DMDRESADR 0xf4c7 +#define DMDRESADR REGx(R0900_P1_DMDRESADR) +#define F0900_P1_DMDRES_VALIDCFR 0xf4c70040 +#define F0900_P1_DMDRES_MEMFULL 0xf4c70030 +#define F0900_P1_DMDRES_RESNBR 0xf4c7000f /*P1_DMDRESDATA7*/ -#define R0900_P1_DMDRESDATA7 0xf4c8 -#define F0900_P1_DMDRES_DATA7 0xf4c800ff +#define R0900_P1_DMDRESDATA7 0xf4c8 +#define F0900_P1_DMDRES_DATA7 0xf4c800ff /*P1_DMDRESDATA6*/ -#define R0900_P1_DMDRESDATA6 0xf4c9 -#define F0900_P1_DMDRES_DATA6 0xf4c900ff +#define R0900_P1_DMDRESDATA6 0xf4c9 +#define F0900_P1_DMDRES_DATA6 0xf4c900ff /*P1_DMDRESDATA5*/ -#define R0900_P1_DMDRESDATA5 0xf4ca -#define F0900_P1_DMDRES_DATA5 0xf4ca00ff +#define R0900_P1_DMDRESDATA5 0xf4ca +#define F0900_P1_DMDRES_DATA5 0xf4ca00ff /*P1_DMDRESDATA4*/ -#define R0900_P1_DMDRESDATA4 0xf4cb -#define F0900_P1_DMDRES_DATA4 0xf4cb00ff +#define R0900_P1_DMDRESDATA4 0xf4cb +#define F0900_P1_DMDRES_DATA4 0xf4cb00ff /*P1_DMDRESDATA3*/ -#define R0900_P1_DMDRESDATA3 0xf4cc -#define F0900_P1_DMDRES_DATA3 0xf4cc00ff +#define R0900_P1_DMDRESDATA3 0xf4cc +#define F0900_P1_DMDRES_DATA3 0xf4cc00ff /*P1_DMDRESDATA2*/ -#define R0900_P1_DMDRESDATA2 0xf4cd -#define F0900_P1_DMDRES_DATA2 0xf4cd00ff +#define R0900_P1_DMDRESDATA2 0xf4cd +#define F0900_P1_DMDRES_DATA2 0xf4cd00ff /*P1_DMDRESDATA1*/ -#define R0900_P1_DMDRESDATA1 0xf4ce -#define F0900_P1_DMDRES_DATA1 0xf4ce00ff +#define R0900_P1_DMDRESDATA1 0xf4ce +#define F0900_P1_DMDRES_DATA1 0xf4ce00ff /*P1_DMDRESDATA0*/ -#define R0900_P1_DMDRESDATA0 0xf4cf -#define F0900_P1_DMDRES_DATA0 0xf4cf00ff +#define R0900_P1_DMDRESDATA0 0xf4cf +#define F0900_P1_DMDRES_DATA0 0xf4cf00ff /*P1_FFEI1*/ -#define R0900_P1_FFEI1 0xf4d0 -#define F0900_P1_FFE_ACCI1 0xf4d001ff +#define R0900_P1_FFEI1 0xf4d0 +#define FFEI1 REGx(R0900_P1_FFEI1) +#define F0900_P1_FFE_ACCI1 0xf4d001ff /*P1_FFEQ1*/ -#define R0900_P1_FFEQ1 0xf4d1 -#define F0900_P1_FFE_ACCQ1 0xf4d101ff +#define R0900_P1_FFEQ1 0xf4d1 +#define FFEQ1 REGx(R0900_P1_FFEQ1) +#define F0900_P1_FFE_ACCQ1 0xf4d101ff /*P1_FFEI2*/ -#define R0900_P1_FFEI2 0xf4d2 -#define F0900_P1_FFE_ACCI2 0xf4d201ff +#define R0900_P1_FFEI2 0xf4d2 +#define FFEI2 REGx(R0900_P1_FFEI2) +#define F0900_P1_FFE_ACCI2 0xf4d201ff /*P1_FFEQ2*/ -#define R0900_P1_FFEQ2 0xf4d3 -#define F0900_P1_FFE_ACCQ2 0xf4d301ff +#define R0900_P1_FFEQ2 0xf4d3 +#define FFEQ2 REGx(R0900_P1_FFEQ2) +#define F0900_P1_FFE_ACCQ2 0xf4d301ff /*P1_FFEI3*/ -#define R0900_P1_FFEI3 0xf4d4 -#define F0900_P1_FFE_ACCI3 0xf4d401ff +#define R0900_P1_FFEI3 0xf4d4 +#define FFEI3 REGx(R0900_P1_FFEI3) +#define F0900_P1_FFE_ACCI3 0xf4d401ff /*P1_FFEQ3*/ -#define R0900_P1_FFEQ3 0xf4d5 -#define F0900_P1_FFE_ACCQ3 0xf4d501ff +#define R0900_P1_FFEQ3 0xf4d5 +#define FFEQ3 REGx(R0900_P1_FFEQ3) +#define F0900_P1_FFE_ACCQ3 0xf4d501ff /*P1_FFEI4*/ -#define R0900_P1_FFEI4 0xf4d6 -#define F0900_P1_FFE_ACCI4 0xf4d601ff +#define R0900_P1_FFEI4 0xf4d6 +#define FFEI4 REGx(R0900_P1_FFEI4) +#define F0900_P1_FFE_ACCI4 0xf4d601ff /*P1_FFEQ4*/ -#define R0900_P1_FFEQ4 0xf4d7 -#define F0900_P1_FFE_ACCQ4 0xf4d701ff +#define R0900_P1_FFEQ4 0xf4d7 +#define FFEQ4 REGx(R0900_P1_FFEQ4) +#define F0900_P1_FFE_ACCQ4 0xf4d701ff /*P1_FFECFG*/ -#define R0900_P1_FFECFG 0xf4d8 -#define F0900_P1_EQUALFFE_ON 0xf4d80040 -#define F0900_P1_EQUAL_USEDSYMB 0xf4d80030 -#define F0900_P1_MU_EQUALFFE 0xf4d80007 +#define R0900_P1_FFECFG 0xf4d8 +#define FFECFG REGx(R0900_P1_FFECFG) +#define F0900_P1_EQUALFFE_ON 0xf4d80040 +#define F0900_P1_MU_EQUALFFE 0xf4d80007 /*P1_TNRCFG*/ -#define R0900_P1_TNRCFG 0xf4e0 -#define F0900_P1_TUN_ACKFAIL 0xf4e00080 -#define F0900_P1_TUN_TYPE 0xf4e00070 -#define F0900_P1_TUN_SECSTOP 0xf4e00008 -#define F0900_P1_TUN_VCOSRCH 0xf4e00004 -#define F0900_P1_TUN_MADDRESS 0xf4e00003 +#define R0900_P1_TNRCFG 0xf4e0 +#define TNRCFG REGx(R0900_P1_TNRCFG) +#define F0900_P1_TUN_ACKFAIL 0xf4e00080 +#define F0900_P1_TUN_TYPE 0xf4e00070 +#define F0900_P1_TUN_SECSTOP 0xf4e00008 +#define F0900_P1_TUN_VCOSRCH 0xf4e00004 +#define F0900_P1_TUN_MADDRESS 0xf4e00003 /*P1_TNRCFG2*/ -#define R0900_P1_TNRCFG2 0xf4e1 -#define F0900_P1_TUN_IQSWAP 0xf4e10080 -#define F0900_P1_STB6110_STEP2MHZ 0xf4e10040 -#define F0900_P1_STB6120_DBLI2C 0xf4e10020 -#define F0900_P1_DIS_FCCK 0xf4e10010 -#define F0900_P1_DIS_LPEN 0xf4e10008 -#define F0900_P1_DIS_BWCALC 0xf4e10004 -#define F0900_P1_SHORT_WAITSTATES 0xf4e10002 -#define F0900_P1_DIS_2BWAGC1 0xf4e10001 +#define R0900_P1_TNRCFG2 0xf4e1 +#define TNRCFG2 REGx(R0900_P1_TNRCFG2) +#define F0900_P1_TUN_IQSWAP 0xf4e10080 +#define F0900_P1_DIS_BWCALC 0xf4e10004 +#define F0900_P1_SHORT_WAITSTATES 0xf4e10002 /*P1_TNRXTAL*/ -#define R0900_P1_TNRXTAL 0xf4e4 -#define F0900_P1_TUN_MCLKDECIMAL 0xf4e400e0 -#define F0900_P1_TUN_XTALFREQ 0xf4e4001f +#define R0900_P1_TNRXTAL 0xf4e4 +#define TNRXTAL REGx(R0900_P1_TNRXTAL) +#define F0900_P1_TUN_XTALFREQ 0xf4e4001f /*P1_TNRSTEPS*/ -#define R0900_P1_TNRSTEPS 0xf4e7 -#define F0900_P1_TUNER_BW1P6 0xf4e70080 -#define F0900_P1_BWINC_OFFSET 0xf4e70070 -#define F0900_P1_SOFTSTEP_RNG 0xf4e70008 -#define F0900_P1_TUN_BWOFFSET 0xf4e70107 +#define R0900_P1_TNRSTEPS 0xf4e7 +#define TNRSTEPS REGx(R0900_P1_TNRSTEPS) +#define F0900_P1_TUNER_BW0P125 0xf4e70080 +#define F0900_P1_BWINC_OFFSET 0xf4e70170 +#define F0900_P1_SOFTSTEP_RNG 0xf4e70008 +#define F0900_P1_TUN_BWOFFSET 0xf4e70007 /*P1_TNRGAIN*/ -#define R0900_P1_TNRGAIN 0xf4e8 -#define F0900_P1_TUN_KDIVEN 0xf4e800c0 -#define F0900_P1_STB6X00_OCK 0xf4e80030 -#define F0900_P1_TUN_GAIN 0xf4e8000f +#define R0900_P1_TNRGAIN 0xf4e8 +#define TNRGAIN REGx(R0900_P1_TNRGAIN) +#define F0900_P1_TUN_KDIVEN 0xf4e800c0 +#define F0900_P1_STB6X00_OCK 0xf4e80030 +#define F0900_P1_TUN_GAIN 0xf4e8000f /*P1_TNRRF1*/ -#define R0900_P1_TNRRF1 0xf4e9 -#define F0900_P1_TUN_RFFREQ2 0xf4e900ff +#define R0900_P1_TNRRF1 0xf4e9 +#define TNRRF1 REGx(R0900_P1_TNRRF1) +#define F0900_P1_TUN_RFFREQ2 0xf4e900ff /*P1_TNRRF0*/ -#define R0900_P1_TNRRF0 0xf4ea -#define F0900_P1_TUN_RFFREQ1 0xf4ea00ff +#define R0900_P1_TNRRF0 0xf4ea +#define TNRRF0 REGx(R0900_P1_TNRRF0) +#define F0900_P1_TUN_RFFREQ1 0xf4ea00ff /*P1_TNRBW*/ -#define R0900_P1_TNRBW 0xf4eb -#define F0900_P1_TUN_RFFREQ0 0xf4eb00c0 -#define F0900_P1_TUN_BW 0xf4eb003f +#define R0900_P1_TNRBW 0xf4eb +#define TNRBW REGx(R0900_P1_TNRBW) +#define F0900_P1_TUN_RFFREQ0 0xf4eb00c0 +#define F0900_P1_TUN_BW 0xf4eb003f /*P1_TNRADJ*/ -#define R0900_P1_TNRADJ 0xf4ec -#define F0900_P1_STB61X0_RCLK 0xf4ec0080 -#define F0900_P1_STB61X0_CALTIME 0xf4ec0040 -#define F0900_P1_STB6X00_DLB 0xf4ec0038 -#define F0900_P1_STB6000_FCL 0xf4ec0007 +#define R0900_P1_TNRADJ 0xf4ec +#define TNRADJ REGx(R0900_P1_TNRADJ) +#define F0900_P1_STB61X0_CALTIME 0xf4ec0040 /*P1_TNRCTL2*/ -#define R0900_P1_TNRCTL2 0xf4ed -#define F0900_P1_STB61X0_LCP1_RCCKOFF 0xf4ed0080 -#define F0900_P1_STB61X0_LCP0 0xf4ed0040 -#define F0900_P1_STB61X0_XTOUT_RFOUTS 0xf4ed0020 -#define F0900_P1_STB61X0_XTON_MCKDV 0xf4ed0010 -#define F0900_P1_STB61X0_CALOFF_DCOFF 0xf4ed0008 -#define F0900_P1_STB6110_LPT 0xf4ed0004 -#define F0900_P1_STB6110_RX 0xf4ed0002 -#define F0900_P1_STB6110_SYN 0xf4ed0001 +#define R0900_P1_TNRCTL2 0xf4ed +#define TNRCTL2 REGx(R0900_P1_TNRCTL2) +#define F0900_P1_STB61X0_RCCKOFF 0xf4ed0080 +#define F0900_P1_STB61X0_ICP_SDOFF 0xf4ed0040 +#define F0900_P1_STB61X0_DCLOOPOFF 0xf4ed0020 +#define F0900_P1_STB61X0_REFOUTSEL 0xf4ed0010 +#define F0900_P1_STB61X0_CALOFF 0xf4ed0008 +#define F0900_P1_STB6XX0_LPT_BEN 0xf4ed0004 +#define F0900_P1_STB6XX0_RX_OSCP 0xf4ed0002 +#define F0900_P1_STB6XX0_SYN 0xf4ed0001 /*P1_TNRCFG3*/ -#define R0900_P1_TNRCFG3 0xf4ee -#define F0900_P1_STB6120_DISCTRL1 0xf4ee0080 -#define F0900_P1_STB6120_INVORDER 0xf4ee0040 -#define F0900_P1_STB6120_ENCTRL6 0xf4ee0020 -#define F0900_P1_TUN_PLLFREQ 0xf4ee001c -#define F0900_P1_TUN_I2CFREQ_MODE 0xf4ee0003 +#define R0900_P1_TNRCFG3 0xf4ee +#define TNRCFG3 REGx(R0900_P1_TNRCFG3) +#define F0900_P1_TUN_PLLFREQ 0xf4ee001c +#define F0900_P1_TUN_I2CFREQ_MODE 0xf4ee0003 /*P1_TNRLAUNCH*/ -#define R0900_P1_TNRLAUNCH 0xf4f0 +#define R0900_P1_TNRLAUNCH 0xf4f0 +#define TNRLAUNCH REGx(R0900_P1_TNRLAUNCH) /*P1_TNRLD*/ -#define R0900_P1_TNRLD 0xf4f0 -#define F0900_P1_TUNLD_VCOING 0xf4f00080 -#define F0900_P1_TUN_REG1FAIL 0xf4f00040 -#define F0900_P1_TUN_REG2FAIL 0xf4f00020 -#define F0900_P1_TUN_REG3FAIL 0xf4f00010 -#define F0900_P1_TUN_REG4FAIL 0xf4f00008 -#define F0900_P1_TUN_REG5FAIL 0xf4f00004 -#define F0900_P1_TUN_BWING 0xf4f00002 -#define F0900_P1_TUN_LOCKED 0xf4f00001 +#define R0900_P1_TNRLD 0xf4f0 +#define TNRLD REGx(R0900_P1_TNRLD) +#define F0900_P1_TUNLD_VCOING 0xf4f00080 +#define F0900_P1_TUN_REG1FAIL 0xf4f00040 +#define F0900_P1_TUN_REG2FAIL 0xf4f00020 +#define F0900_P1_TUN_REG3FAIL 0xf4f00010 +#define F0900_P1_TUN_REG4FAIL 0xf4f00008 +#define F0900_P1_TUN_REG5FAIL 0xf4f00004 +#define F0900_P1_TUN_BWING 0xf4f00002 +#define F0900_P1_TUN_LOCKED 0xf4f00001 /*P1_TNROBSL*/ -#define R0900_P1_TNROBSL 0xf4f6 -#define F0900_P1_TUN_I2CABORTED 0xf4f60080 -#define F0900_P1_TUN_LPEN 0xf4f60040 -#define F0900_P1_TUN_FCCK 0xf4f60020 -#define F0900_P1_TUN_I2CLOCKED 0xf4f60010 -#define F0900_P1_TUN_PROGDONE 0xf4f6000c -#define F0900_P1_TUN_RFRESTE1 0xf4f60003 +#define R0900_P1_TNROBSL 0xf4f6 +#define TNROBSL REGx(R0900_P1_TNROBSL) +#define F0900_P1_TUN_I2CABORTED 0xf4f60080 +#define F0900_P1_TUN_LPEN 0xf4f60040 +#define F0900_P1_TUN_FCCK 0xf4f60020 +#define F0900_P1_TUN_I2CLOCKED 0xf4f60010 +#define F0900_P1_TUN_PROGDONE 0xf4f6000c +#define F0900_P1_TUN_RFRESTE1 0xf4f60003 /*P1_TNRRESTE*/ -#define R0900_P1_TNRRESTE 0xf4f7 -#define F0900_P1_TUN_RFRESTE0 0xf4f700ff +#define R0900_P1_TNRRESTE 0xf4f7 +#define TNRRESTE REGx(R0900_P1_TNRRESTE) +#define F0900_P1_TUN_RFRESTE0 0xf4f700ff /*P1_SMAPCOEF7*/ -#define R0900_P1_SMAPCOEF7 0xf500 -#define F0900_P1_DIS_QSCALE 0xf5000080 -#define F0900_P1_SMAPCOEF_Q_LLR12 0xf500017f +#define R0900_P1_SMAPCOEF7 0xf500 +#define SMAPCOEF7 REGx(R0900_P1_SMAPCOEF7) +#define F0900_P1_DIS_QSCALE 0xf5000080 +#define F0900_P1_SMAPCOEF_Q_LLR12 0xf500017f /*P1_SMAPCOEF6*/ -#define R0900_P1_SMAPCOEF6 0xf501 -#define F0900_P1_DIS_NEWSCALE 0xf5010008 -#define F0900_P1_ADJ_8PSKLLR1 0xf5010004 -#define F0900_P1_OLD_8PSKLLR1 0xf5010002 -#define F0900_P1_DIS_AB8PSK 0xf5010001 +#define R0900_P1_SMAPCOEF6 0xf501 +#define SMAPCOEF6 REGx(R0900_P1_SMAPCOEF6) +#define F0900_P1_ADJ_8PSKLLR1 0xf5010004 +#define F0900_P1_OLD_8PSKLLR1 0xf5010002 +#define F0900_P1_DIS_AB8PSK 0xf5010001 /*P1_SMAPCOEF5*/ -#define R0900_P1_SMAPCOEF5 0xf502 -#define F0900_P1_DIS_8SCALE 0xf5020080 -#define F0900_P1_SMAPCOEF_8P_LLR23 0xf502017f +#define R0900_P1_SMAPCOEF5 0xf502 +#define SMAPCOEF5 REGx(R0900_P1_SMAPCOEF5) +#define F0900_P1_DIS_8SCALE 0xf5020080 +#define F0900_P1_SMAPCOEF_8P_LLR23 0xf502017f + +/*P1_NCO2MAX1*/ +#define R0900_P1_NCO2MAX1 0xf514 +#define NCO2MAX1 REGx(R0900_P1_NCO2MAX1) +#define F0900_P1_TETA2_MAXVABS1 0xf51400ff + +/*P1_NCO2MAX0*/ +#define R0900_P1_NCO2MAX0 0xf515 +#define NCO2MAX0 REGx(R0900_P1_NCO2MAX0) +#define F0900_P1_TETA2_MAXVABS0 0xf51500ff + +/*P1_NCO2FR1*/ +#define R0900_P1_NCO2FR1 0xf516 +#define NCO2FR1 REGx(R0900_P1_NCO2FR1) +#define F0900_P1_NCO2FINAL_ANGLE1 0xf51600ff + +/*P1_NCO2FR0*/ +#define R0900_P1_NCO2FR0 0xf517 +#define NCO2FR0 REGx(R0900_P1_NCO2FR0) +#define F0900_P1_NCO2FINAL_ANGLE0 0xf51700ff + +/*P1_CFR2AVRGE1*/ +#define R0900_P1_CFR2AVRGE1 0xf518 +#define CFR2AVRGE1 REGx(R0900_P1_CFR2AVRGE1) +#define F0900_P1_I2C_CFR2AVERAGE1 0xf51800ff + +/*P1_CFR2AVRGE0*/ +#define R0900_P1_CFR2AVRGE0 0xf519 +#define CFR2AVRGE0 REGx(R0900_P1_CFR2AVRGE0) +#define F0900_P1_I2C_CFR2AVERAGE0 0xf51900ff /*P1_DMDPLHSTAT*/ -#define R0900_P1_DMDPLHSTAT 0xf520 -#define F0900_P1_PLH_STATISTIC 0xf52000ff +#define R0900_P1_DMDPLHSTAT 0xf520 +#define DMDPLHSTAT REGx(R0900_P1_DMDPLHSTAT) +#define F0900_P1_PLH_STATISTIC 0xf52000ff /*P1_LOCKTIME3*/ -#define R0900_P1_LOCKTIME3 0xf522 -#define F0900_P1_DEMOD_LOCKTIME3 0xf52200ff +#define R0900_P1_LOCKTIME3 0xf522 +#define LOCKTIME3 REGx(R0900_P1_LOCKTIME3) +#define F0900_P1_DEMOD_LOCKTIME3 0xf52200ff /*P1_LOCKTIME2*/ -#define R0900_P1_LOCKTIME2 0xf523 -#define F0900_P1_DEMOD_LOCKTIME2 0xf52300ff +#define R0900_P1_LOCKTIME2 0xf523 +#define LOCKTIME2 REGx(R0900_P1_LOCKTIME2) +#define F0900_P1_DEMOD_LOCKTIME2 0xf52300ff /*P1_LOCKTIME1*/ -#define R0900_P1_LOCKTIME1 0xf524 -#define F0900_P1_DEMOD_LOCKTIME1 0xf52400ff +#define R0900_P1_LOCKTIME1 0xf524 +#define LOCKTIME1 REGx(R0900_P1_LOCKTIME1) +#define F0900_P1_DEMOD_LOCKTIME1 0xf52400ff /*P1_LOCKTIME0*/ -#define R0900_P1_LOCKTIME0 0xf525 -#define F0900_P1_DEMOD_LOCKTIME0 0xf52500ff +#define R0900_P1_LOCKTIME0 0xf525 +#define LOCKTIME0 REGx(R0900_P1_LOCKTIME0) +#define F0900_P1_DEMOD_LOCKTIME0 0xf52500ff /*P1_VITSCALE*/ -#define R0900_P1_VITSCALE 0xf532 -#define F0900_P1_NVTH_NOSRANGE 0xf5320080 -#define F0900_P1_VERROR_MAXMODE 0xf5320040 -#define F0900_P1_KDIV_MODE 0xf5320030 -#define F0900_P1_NSLOWSN_LOCKED 0xf5320008 -#define F0900_P1_DELOCK_PRFLOSS 0xf5320004 -#define F0900_P1_DIS_RSFLOCK 0xf5320002 +#define R0900_P1_VITSCALE 0xf532 +#define VITSCALE REGx(R0900_P1_VITSCALE) +#define F0900_P1_NVTH_NOSRANGE 0xf5320080 +#define F0900_P1_VERROR_MAXMODE 0xf5320040 +#define F0900_P1_NSLOWSN_LOCKED 0xf5320008 +#define F0900_P1_DIS_RSFLOCK 0xf5320002 /*P1_FECM*/ -#define R0900_P1_FECM 0xf533 -#define F0900_P1_DSS_DVB 0xf5330080 -#define F0900_P1_DEMOD_BYPASS 0xf5330040 -#define F0900_P1_CMP_SLOWMODE 0xf5330020 -#define F0900_P1_DSS_SRCH 0xf5330010 -#define F0900_P1_DIFF_MODEVIT 0xf5330004 -#define F0900_P1_SYNCVIT 0xf5330002 -#define F0900_P1_IQINV 0xf5330001 +#define R0900_P1_FECM 0xf533 +#define FECM REGx(R0900_P1_FECM) +#define F0900_P1_DSS_DVB 0xf5330080 +#define DSS_DVB FLDx(F0900_P1_DSS_DVB) +#define F0900_P1_DSS_SRCH 0xf5330010 +#define F0900_P1_SYNCVIT 0xf5330002 +#define F0900_P1_IQINV 0xf5330001 +#define IQINV FLDx(F0900_P1_IQINV) /*P1_VTH12*/ -#define R0900_P1_VTH12 0xf534 -#define F0900_P1_VTH12 0xf53400ff +#define R0900_P1_VTH12 0xf534 +#define VTH12 REGx(R0900_P1_VTH12) +#define F0900_P1_VTH12 0xf53400ff /*P1_VTH23*/ -#define R0900_P1_VTH23 0xf535 -#define F0900_P1_VTH23 0xf53500ff +#define R0900_P1_VTH23 0xf535 +#define VTH23 REGx(R0900_P1_VTH23) +#define F0900_P1_VTH23 0xf53500ff /*P1_VTH34*/ -#define R0900_P1_VTH34 0xf536 -#define F0900_P1_VTH34 0xf53600ff +#define R0900_P1_VTH34 0xf536 +#define VTH34 REGx(R0900_P1_VTH34) +#define F0900_P1_VTH34 0xf53600ff /*P1_VTH56*/ -#define R0900_P1_VTH56 0xf537 -#define F0900_P1_VTH56 0xf53700ff +#define R0900_P1_VTH56 0xf537 +#define VTH56 REGx(R0900_P1_VTH56) +#define F0900_P1_VTH56 0xf53700ff /*P1_VTH67*/ -#define R0900_P1_VTH67 0xf538 -#define F0900_P1_VTH67 0xf53800ff +#define R0900_P1_VTH67 0xf538 +#define VTH67 REGx(R0900_P1_VTH67) +#define F0900_P1_VTH67 0xf53800ff /*P1_VTH78*/ -#define R0900_P1_VTH78 0xf539 -#define F0900_P1_VTH78 0xf53900ff +#define R0900_P1_VTH78 0xf539 +#define VTH78 REGx(R0900_P1_VTH78) +#define F0900_P1_VTH78 0xf53900ff /*P1_VITCURPUN*/ -#define R0900_P1_VITCURPUN 0xf53a -#define F0900_P1_VIT_MAPPING 0xf53a00e0 -#define F0900_P1_VIT_CURPUN 0xf53a001f +#define R0900_P1_VITCURPUN 0xf53a +#define VITCURPUN REGx(R0900_P1_VITCURPUN) +#define F0900_P1_VIT_CURPUN 0xf53a001f +#define VIT_CURPUN FLDx(F0900_P1_VIT_CURPUN) /*P1_VERROR*/ -#define R0900_P1_VERROR 0xf53b -#define F0900_P1_REGERR_VIT 0xf53b00ff +#define R0900_P1_VERROR 0xf53b +#define VERROR REGx(R0900_P1_VERROR) +#define F0900_P1_REGERR_VIT 0xf53b00ff /*P1_PRVIT*/ -#define R0900_P1_PRVIT 0xf53c -#define F0900_P1_DIS_VTHLOCK 0xf53c0040 -#define F0900_P1_E7_8VIT 0xf53c0020 -#define F0900_P1_E6_7VIT 0xf53c0010 -#define F0900_P1_E5_6VIT 0xf53c0008 -#define F0900_P1_E3_4VIT 0xf53c0004 -#define F0900_P1_E2_3VIT 0xf53c0002 -#define F0900_P1_E1_2VIT 0xf53c0001 +#define R0900_P1_PRVIT 0xf53c +#define PRVIT REGx(R0900_P1_PRVIT) +#define F0900_P1_DIS_VTHLOCK 0xf53c0040 +#define F0900_P1_E7_8VIT 0xf53c0020 +#define F0900_P1_E6_7VIT 0xf53c0010 +#define F0900_P1_E5_6VIT 0xf53c0008 +#define F0900_P1_E3_4VIT 0xf53c0004 +#define F0900_P1_E2_3VIT 0xf53c0002 +#define F0900_P1_E1_2VIT 0xf53c0001 /*P1_VAVSRVIT*/ -#define R0900_P1_VAVSRVIT 0xf53d -#define F0900_P1_AMVIT 0xf53d0080 -#define F0900_P1_FROZENVIT 0xf53d0040 -#define F0900_P1_SNVIT 0xf53d0030 -#define F0900_P1_TOVVIT 0xf53d000c -#define F0900_P1_HYPVIT 0xf53d0003 +#define R0900_P1_VAVSRVIT 0xf53d +#define VAVSRVIT REGx(R0900_P1_VAVSRVIT) +#define F0900_P1_AMVIT 0xf53d0080 +#define F0900_P1_FROZENVIT 0xf53d0040 +#define F0900_P1_SNVIT 0xf53d0030 +#define F0900_P1_TOVVIT 0xf53d000c +#define F0900_P1_HYPVIT 0xf53d0003 /*P1_VSTATUSVIT*/ -#define R0900_P1_VSTATUSVIT 0xf53e -#define F0900_P1_VITERBI_ON 0xf53e0080 -#define F0900_P1_END_LOOPVIT 0xf53e0040 -#define F0900_P1_VITERBI_DEPRF 0xf53e0020 -#define F0900_P1_PRFVIT 0xf53e0010 -#define F0900_P1_LOCKEDVIT 0xf53e0008 -#define F0900_P1_VITERBI_DELOCK 0xf53e0004 -#define F0900_P1_VIT_DEMODSEL 0xf53e0002 -#define F0900_P1_VITERBI_COMPOUT 0xf53e0001 +#define R0900_P1_VSTATUSVIT 0xf53e +#define VSTATUSVIT REGx(R0900_P1_VSTATUSVIT) +#define F0900_P1_PRFVIT 0xf53e0010 +#define PRFVIT FLDx(F0900_P1_PRFVIT) +#define F0900_P1_LOCKEDVIT 0xf53e0008 +#define LOCKEDVIT FLDx(F0900_P1_LOCKEDVIT) /*P1_VTHINUSE*/ -#define R0900_P1_VTHINUSE 0xf53f -#define F0900_P1_VIT_INUSE 0xf53f00ff +#define R0900_P1_VTHINUSE 0xf53f +#define VTHINUSE REGx(R0900_P1_VTHINUSE) +#define F0900_P1_VIT_INUSE 0xf53f00ff /*P1_KDIV12*/ -#define R0900_P1_KDIV12 0xf540 -#define F0900_P1_KDIV12_MANUAL 0xf5400080 -#define F0900_P1_K_DIVIDER_12 0xf540007f +#define R0900_P1_KDIV12 0xf540 +#define KDIV12 REGx(R0900_P1_KDIV12) +#define F0900_P1_K_DIVIDER_12 0xf540007f /*P1_KDIV23*/ -#define R0900_P1_KDIV23 0xf541 -#define F0900_P1_KDIV23_MANUAL 0xf5410080 -#define F0900_P1_K_DIVIDER_23 0xf541007f +#define R0900_P1_KDIV23 0xf541 +#define KDIV23 REGx(R0900_P1_KDIV23) +#define F0900_P1_K_DIVIDER_23 0xf541007f /*P1_KDIV34*/ -#define R0900_P1_KDIV34 0xf542 -#define F0900_P1_KDIV34_MANUAL 0xf5420080 -#define F0900_P1_K_DIVIDER_34 0xf542007f +#define R0900_P1_KDIV34 0xf542 +#define KDIV34 REGx(R0900_P1_KDIV34) +#define F0900_P1_K_DIVIDER_34 0xf542007f /*P1_KDIV56*/ -#define R0900_P1_KDIV56 0xf543 -#define F0900_P1_KDIV56_MANUAL 0xf5430080 -#define F0900_P1_K_DIVIDER_56 0xf543007f +#define R0900_P1_KDIV56 0xf543 +#define KDIV56 REGx(R0900_P1_KDIV56) +#define F0900_P1_K_DIVIDER_56 0xf543007f /*P1_KDIV67*/ -#define R0900_P1_KDIV67 0xf544 -#define F0900_P1_KDIV67_MANUAL 0xf5440080 -#define F0900_P1_K_DIVIDER_67 0xf544007f +#define R0900_P1_KDIV67 0xf544 +#define KDIV67 REGx(R0900_P1_KDIV67) +#define F0900_P1_K_DIVIDER_67 0xf544007f /*P1_KDIV78*/ -#define R0900_P1_KDIV78 0xf545 -#define F0900_P1_KDIV78_MANUAL 0xf5450080 -#define F0900_P1_K_DIVIDER_78 0xf545007f +#define R0900_P1_KDIV78 0xf545 +#define KDIV78 REGx(R0900_P1_KDIV78) +#define F0900_P1_K_DIVIDER_78 0xf545007f /*P1_PDELCTRL1*/ -#define R0900_P1_PDELCTRL1 0xf550 -#define F0900_P1_INV_MISMASK 0xf5500080 -#define F0900_P1_FORCE_ACCEPTED 0xf5500040 -#define F0900_P1_FILTER_EN 0xf5500020 -#define F0900_P1_FORCE_PKTDELINUSE 0xf5500010 -#define F0900_P1_HYSTEN 0xf5500008 -#define F0900_P1_HYSTSWRST 0xf5500004 -#define F0900_P1_EN_MIS00 0xf5500002 -#define F0900_P1_ALGOSWRST 0xf5500001 +#define R0900_P1_PDELCTRL1 0xf550 +#define PDELCTRL1 REGx(R0900_P1_PDELCTRL1) +#define F0900_P1_INV_MISMASK 0xf5500080 +#define F0900_P1_FILTER_EN 0xf5500020 +#define F0900_P1_EN_MIS00 0xf5500002 +#define F0900_P1_ALGOSWRST 0xf5500001 +#define ALGOSWRST FLDx(F0900_P1_ALGOSWRST) /*P1_PDELCTRL2*/ -#define R0900_P1_PDELCTRL2 0xf551 -#define F0900_P1_FORCE_CONTINUOUS 0xf5510080 -#define F0900_P1_RESET_UPKO_COUNT 0xf5510040 -#define F0900_P1_USER_PKTDELIN_NB 0xf5510020 -#define F0900_P1_FORCE_LOCKED 0xf5510010 -#define F0900_P1_DATA_UNBBSCRAM 0xf5510008 -#define F0900_P1_FORCE_LONGPKT 0xf5510004 -#define F0900_P1_FRAME_MODE 0xf5510002 +#define R0900_P1_PDELCTRL2 0xf551 +#define PDELCTRL2 REGx(R0900_P1_PDELCTRL2) +#define F0900_P1_RESET_UPKO_COUNT 0xf5510040 +#define RESET_UPKO_COUNT FLDx(F0900_P1_RESET_UPKO_COUNT) +#define F0900_P1_FRAME_MODE 0xf5510002 +#define F0900_P1_NOBCHERRFLG_USE 0xf5510001 /*P1_HYSTTHRESH*/ -#define R0900_P1_HYSTTHRESH 0xf554 -#define F0900_P1_UNLCK_THRESH 0xf55400f0 -#define F0900_P1_DELIN_LCK_THRESH 0xf554000f +#define R0900_P1_HYSTTHRESH 0xf554 +#define HYSTTHRESH REGx(R0900_P1_HYSTTHRESH) +#define F0900_P1_UNLCK_THRESH 0xf55400f0 +#define F0900_P1_DELIN_LCK_THRESH 0xf554000f /*P1_ISIENTRY*/ -#define R0900_P1_ISIENTRY 0xf55e -#define F0900_P1_ISI_ENTRY 0xf55e00ff +#define R0900_P1_ISIENTRY 0xf55e +#define ISIENTRY REGx(R0900_P1_ISIENTRY) +#define F0900_P1_ISI_ENTRY 0xf55e00ff /*P1_ISIBITENA*/ -#define R0900_P1_ISIBITENA 0xf55f -#define F0900_P1_ISI_BIT_EN 0xf55f00ff +#define R0900_P1_ISIBITENA 0xf55f +#define ISIBITENA REGx(R0900_P1_ISIBITENA) +#define F0900_P1_ISI_BIT_EN 0xf55f00ff /*P1_MATSTR1*/ -#define R0900_P1_MATSTR1 0xf560 -#define F0900_P1_MATYPE_CURRENT1 0xf56000ff +#define R0900_P1_MATSTR1 0xf560 +#define MATSTR1 REGx(R0900_P1_MATSTR1) +#define F0900_P1_MATYPE_CURRENT1 0xf56000ff /*P1_MATSTR0*/ -#define R0900_P1_MATSTR0 0xf561 -#define F0900_P1_MATYPE_CURRENT0 0xf56100ff +#define R0900_P1_MATSTR0 0xf561 +#define MATSTR0 REGx(R0900_P1_MATSTR0) +#define F0900_P1_MATYPE_CURRENT0 0xf56100ff /*P1_UPLSTR1*/ -#define R0900_P1_UPLSTR1 0xf562 -#define F0900_P1_UPL_CURRENT1 0xf56200ff +#define R0900_P1_UPLSTR1 0xf562 +#define UPLSTR1 REGx(R0900_P1_UPLSTR1) +#define F0900_P1_UPL_CURRENT1 0xf56200ff /*P1_UPLSTR0*/ -#define R0900_P1_UPLSTR0 0xf563 -#define F0900_P1_UPL_CURRENT0 0xf56300ff +#define R0900_P1_UPLSTR0 0xf563 +#define UPLSTR0 REGx(R0900_P1_UPLSTR0) +#define F0900_P1_UPL_CURRENT0 0xf56300ff /*P1_DFLSTR1*/ -#define R0900_P1_DFLSTR1 0xf564 -#define F0900_P1_DFL_CURRENT1 0xf56400ff +#define R0900_P1_DFLSTR1 0xf564 +#define DFLSTR1 REGx(R0900_P1_DFLSTR1) +#define F0900_P1_DFL_CURRENT1 0xf56400ff /*P1_DFLSTR0*/ -#define R0900_P1_DFLSTR0 0xf565 -#define F0900_P1_DFL_CURRENT0 0xf56500ff +#define R0900_P1_DFLSTR0 0xf565 +#define DFLSTR0 REGx(R0900_P1_DFLSTR0) +#define F0900_P1_DFL_CURRENT0 0xf56500ff /*P1_SYNCSTR*/ -#define R0900_P1_SYNCSTR 0xf566 -#define F0900_P1_SYNC_CURRENT 0xf56600ff +#define R0900_P1_SYNCSTR 0xf566 +#define SYNCSTR REGx(R0900_P1_SYNCSTR) +#define F0900_P1_SYNC_CURRENT 0xf56600ff /*P1_SYNCDSTR1*/ -#define R0900_P1_SYNCDSTR1 0xf567 -#define F0900_P1_SYNCD_CURRENT1 0xf56700ff +#define R0900_P1_SYNCDSTR1 0xf567 +#define SYNCDSTR1 REGx(R0900_P1_SYNCDSTR1) +#define F0900_P1_SYNCD_CURRENT1 0xf56700ff /*P1_SYNCDSTR0*/ -#define R0900_P1_SYNCDSTR0 0xf568 -#define F0900_P1_SYNCD_CURRENT0 0xf56800ff +#define R0900_P1_SYNCDSTR0 0xf568 +#define SYNCDSTR0 REGx(R0900_P1_SYNCDSTR0) +#define F0900_P1_SYNCD_CURRENT0 0xf56800ff /*P1_PDELSTATUS1*/ -#define R0900_P1_PDELSTATUS1 0xf569 -#define F0900_P1_PKTDELIN_DELOCK 0xf5690080 -#define F0900_P1_SYNCDUPDFL_BADDFL 0xf5690040 -#define F0900_P1_CONTINUOUS_STREAM 0xf5690020 -#define F0900_P1_UNACCEPTED_STREAM 0xf5690010 -#define F0900_P1_BCH_ERROR_FLAG 0xf5690008 -#define F0900_P1_BBHCRCKO 0xf5690004 -#define F0900_P1_PKTDELIN_LOCK 0xf5690002 -#define F0900_P1_FIRST_LOCK 0xf5690001 +#define R0900_P1_PDELSTATUS1 0xf569 +#define F0900_P1_PKTDELIN_DELOCK 0xf5690080 +#define F0900_P1_SYNCDUPDFL_BADDFL 0xf5690040 +#define F0900_P1_CONTINUOUS_STREAM 0xf5690020 +#define F0900_P1_UNACCEPTED_STREAM 0xf5690010 +#define F0900_P1_BCH_ERROR_FLAG 0xf5690008 +#define F0900_P1_PKTDELIN_LOCK 0xf5690002 +#define PKTDELIN_LOCK FLDx(F0900_P1_PKTDELIN_LOCK) +#define F0900_P1_FIRST_LOCK 0xf5690001 /*P1_PDELSTATUS2*/ -#define R0900_P1_PDELSTATUS2 0xf56a -#define F0900_P1_PKTDEL_DEMODSEL 0xf56a0080 -#define F0900_P1_FRAME_MODCOD 0xf56a007c -#define F0900_P1_FRAME_TYPE 0xf56a0003 +#define R0900_P1_PDELSTATUS2 0xf56a +#define F0900_P1_FRAME_MODCOD 0xf56a007c +#define F0900_P1_FRAME_TYPE 0xf56a0003 /*P1_BBFCRCKO1*/ -#define R0900_P1_BBFCRCKO1 0xf56b -#define F0900_P1_BBHCRC_KOCNT1 0xf56b00ff +#define R0900_P1_BBFCRCKO1 0xf56b +#define BBFCRCKO1 REGx(R0900_P1_BBFCRCKO1) +#define F0900_P1_BBHCRC_KOCNT1 0xf56b00ff /*P1_BBFCRCKO0*/ -#define R0900_P1_BBFCRCKO0 0xf56c -#define F0900_P1_BBHCRC_KOCNT0 0xf56c00ff +#define R0900_P1_BBFCRCKO0 0xf56c +#define BBFCRCKO0 REGx(R0900_P1_BBFCRCKO0) +#define F0900_P1_BBHCRC_KOCNT0 0xf56c00ff /*P1_UPCRCKO1*/ -#define R0900_P1_UPCRCKO1 0xf56d -#define F0900_P1_PKTCRC_KOCNT1 0xf56d00ff +#define R0900_P1_UPCRCKO1 0xf56d +#define UPCRCKO1 REGx(R0900_P1_UPCRCKO1) +#define F0900_P1_PKTCRC_KOCNT1 0xf56d00ff /*P1_UPCRCKO0*/ -#define R0900_P1_UPCRCKO0 0xf56e -#define F0900_P1_PKTCRC_KOCNT0 0xf56e00ff +#define R0900_P1_UPCRCKO0 0xf56e +#define UPCRCKO0 REGx(R0900_P1_UPCRCKO0) +#define F0900_P1_PKTCRC_KOCNT0 0xf56e00ff + +/*P1_PDELCTRL3*/ +#define R0900_P1_PDELCTRL3 0xf56f +#define PDELCTRL3 REGx(R0900_P1_PDELCTRL3) +#define F0900_P1_PKTDEL_CONTFAIL 0xf56f0080 +#define F0900_P1_NOFIFO_BCHERR 0xf56f0020 /*P1_TSSTATEM*/ -#define R0900_P1_TSSTATEM 0xf570 -#define F0900_P1_TSDIL_ON 0xf5700080 -#define F0900_P1_TSSKIPRS_ON 0xf5700040 -#define F0900_P1_TSRS_ON 0xf5700020 -#define F0900_P1_TSDESCRAMB_ON 0xf5700010 -#define F0900_P1_TSFRAME_MODE 0xf5700008 -#define F0900_P1_TS_DISABLE 0xf5700004 -#define F0900_P1_TSACM_MODE 0xf5700002 -#define F0900_P1_TSOUT_NOSYNC 0xf5700001 +#define R0900_P1_TSSTATEM 0xf570 +#define TSSTATEM REGx(R0900_P1_TSSTATEM) +#define F0900_P1_TSDIL_ON 0xf5700080 +#define F0900_P1_TSRS_ON 0xf5700020 +#define F0900_P1_TSDESCRAMB_ON 0xf5700010 +#define F0900_P1_TSFRAME_MODE 0xf5700008 +#define F0900_P1_TS_DISABLE 0xf5700004 +#define F0900_P1_TSOUT_NOSYNC 0xf5700001 /*P1_TSCFGH*/ -#define R0900_P1_TSCFGH 0xf572 -#define F0900_P1_TSFIFO_DVBCI 0xf5720080 -#define F0900_P1_TSFIFO_SERIAL 0xf5720040 -#define F0900_P1_TSFIFO_TEIUPDATE 0xf5720020 -#define F0900_P1_TSFIFO_DUTY50 0xf5720010 -#define F0900_P1_TSFIFO_HSGNLOUT 0xf5720008 -#define F0900_P1_TSFIFO_ERRMODE 0xf5720006 -#define F0900_P1_RST_HWARE 0xf5720001 +#define R0900_P1_TSCFGH 0xf572 +#define TSCFGH REGx(R0900_P1_TSCFGH) +#define F0900_P1_TSFIFO_DVBCI 0xf5720080 +#define F0900_P1_TSFIFO_SERIAL 0xf5720040 +#define F0900_P1_TSFIFO_TEIUPDATE 0xf5720020 +#define F0900_P1_TSFIFO_DUTY50 0xf5720010 +#define F0900_P1_TSFIFO_HSGNLOUT 0xf5720008 +#define F0900_P1_TSFIFO_ERRMODE 0xf5720006 +#define F0900_P1_RST_HWARE 0xf5720001 +#define RST_HWARE FLDx(F0900_P1_RST_HWARE) /*P1_TSCFGM*/ -#define R0900_P1_TSCFGM 0xf573 -#define F0900_P1_TSFIFO_MANSPEED 0xf57300c0 -#define F0900_P1_TSFIFO_PERMDATA 0xf5730020 -#define F0900_P1_TSFIFO_NONEWSGNL 0xf5730010 -#define F0900_P1_TSFIFO_BITSPEED 0xf5730008 -#define F0900_P1_NPD_SPECDVBS2 0xf5730004 -#define F0900_P1_TSFIFO_STOPCKDIS 0xf5730002 -#define F0900_P1_TSFIFO_INVDATA 0xf5730001 +#define R0900_P1_TSCFGM 0xf573 +#define TSCFGM REGx(R0900_P1_TSCFGM) +#define F0900_P1_TSFIFO_MANSPEED 0xf57300c0 +#define F0900_P1_TSFIFO_PERMDATA 0xf5730020 +#define F0900_P1_TSFIFO_DPUNACT 0xf5730002 +#define F0900_P1_TSFIFO_INVDATA 0xf5730001 /*P1_TSCFGL*/ -#define R0900_P1_TSCFGL 0xf574 -#define F0900_P1_TSFIFO_BCLKDEL1CK 0xf57400c0 -#define F0900_P1_BCHERROR_MODE 0xf5740030 -#define F0900_P1_TSFIFO_NSGNL2DATA 0xf5740008 -#define F0900_P1_TSFIFO_EMBINDVB 0xf5740004 -#define F0900_P1_TSFIFO_DPUNACT 0xf5740002 -#define F0900_P1_TSFIFO_NPDOFF 0xf5740001 +#define R0900_P1_TSCFGL 0xf574 +#define TSCFGL REGx(R0900_P1_TSCFGL) +#define F0900_P1_TSFIFO_BCLKDEL1CK 0xf57400c0 +#define F0900_P1_BCHERROR_MODE 0xf5740030 +#define F0900_P1_TSFIFO_NSGNL2DATA 0xf5740008 +#define F0900_P1_TSFIFO_EMBINDVB 0xf5740004 +#define F0900_P1_TSFIFO_BITSPEED 0xf5740003 /*P1_TSINSDELH*/ -#define R0900_P1_TSINSDELH 0xf576 -#define F0900_P1_TSDEL_SYNCBYTE 0xf5760080 -#define F0900_P1_TSDEL_XXHEADER 0xf5760040 -#define F0900_P1_TSDEL_BBHEADER 0xf5760020 -#define F0900_P1_TSDEL_DATAFIELD 0xf5760010 -#define F0900_P1_TSINSDEL_ISCR 0xf5760008 -#define F0900_P1_TSINSDEL_NPD 0xf5760004 -#define F0900_P1_TSINSDEL_RSPARITY 0xf5760002 -#define F0900_P1_TSINSDEL_CRC8 0xf5760001 +#define R0900_P1_TSINSDELH 0xf576 +#define TSINSDELH REGx(R0900_P1_TSINSDELH) +#define F0900_P1_TSDEL_SYNCBYTE 0xf5760080 +#define F0900_P1_TSDEL_XXHEADER 0xf5760040 +#define F0900_P1_TSDEL_BBHEADER 0xf5760020 +#define F0900_P1_TSDEL_DATAFIELD 0xf5760010 +#define F0900_P1_TSINSDEL_ISCR 0xf5760008 +#define F0900_P1_TSINSDEL_NPD 0xf5760004 +#define F0900_P1_TSINSDEL_RSPARITY 0xf5760002 +#define F0900_P1_TSINSDEL_CRC8 0xf5760001 + +/*P1_TSDIVN*/ +#define R0900_P1_TSDIVN 0xf579 +#define TSDIVN REGx(R0900_P1_TSDIVN) +#define F0900_P1_TSFIFO_SPEEDMODE 0xf57900c0 + +/*P1_TSCFG4*/ +#define R0900_P1_TSCFG4 0xf57a +#define TSCFG4 REGx(R0900_P1_TSCFG4) +#define F0900_P1_TSFIFO_TSSPEEDMODE 0xf57a00c0 /*P1_TSSPEED*/ -#define R0900_P1_TSSPEED 0xf580 -#define F0900_P1_TSFIFO_OUTSPEED 0xf58000ff +#define R0900_P1_TSSPEED 0xf580 +#define TSSPEED REGx(R0900_P1_TSSPEED) +#define F0900_P1_TSFIFO_OUTSPEED 0xf58000ff /*P1_TSSTATUS*/ -#define R0900_P1_TSSTATUS 0xf581 -#define F0900_P1_TSFIFO_LINEOK 0xf5810080 -#define F0900_P1_TSFIFO_ERROR 0xf5810040 -#define F0900_P1_TSFIFO_DATA7 0xf5810020 -#define F0900_P1_TSFIFO_NOSYNC 0xf5810010 -#define F0900_P1_ISCR_INITIALIZED 0xf5810008 -#define F0900_P1_ISCR_UPDATED 0xf5810004 -#define F0900_P1_SOFFIFO_UNREGUL 0xf5810002 -#define F0900_P1_DIL_READY 0xf5810001 +#define R0900_P1_TSSTATUS 0xf581 +#define TSSTATUS REGx(R0900_P1_TSSTATUS) +#define F0900_P1_TSFIFO_LINEOK 0xf5810080 +#define TSFIFO_LINEOK FLDx(F0900_P1_TSFIFO_LINEOK) +#define F0900_P1_TSFIFO_ERROR 0xf5810040 +#define F0900_P1_DIL_READY 0xf5810001 /*P1_TSSTATUS2*/ -#define R0900_P1_TSSTATUS2 0xf582 -#define F0900_P1_TSFIFO_DEMODSEL 0xf5820080 -#define F0900_P1_TSFIFOSPEED_STORE 0xf5820040 -#define F0900_P1_DILXX_RESET 0xf5820020 -#define F0900_P1_TSSERIAL_IMPOS 0xf5820010 -#define F0900_P1_TSFIFO_LINENOK 0xf5820008 -#define F0900_P1_BITSPEED_EVENT 0xf5820004 -#define F0900_P1_SCRAMBDETECT 0xf5820002 -#define F0900_P1_ULDTV67_FALSELOCK 0xf5820001 +#define R0900_P1_TSSTATUS2 0xf582 +#define TSSTATUS2 REGx(R0900_P1_TSSTATUS2) +#define F0900_P1_TSFIFO_DEMODSEL 0xf5820080 +#define F0900_P1_TSFIFOSPEED_STORE 0xf5820040 +#define F0900_P1_DILXX_RESET 0xf5820020 +#define F0900_P1_TSSERIAL_IMPOS 0xf5820010 +#define F0900_P1_SCRAMBDETECT 0xf5820002 /*P1_TSBITRATE1*/ -#define R0900_P1_TSBITRATE1 0xf583 -#define F0900_P1_TSFIFO_BITRATE1 0xf58300ff +#define R0900_P1_TSBITRATE1 0xf583 +#define TSBITRATE1 REGx(R0900_P1_TSBITRATE1) +#define F0900_P1_TSFIFO_BITRATE1 0xf58300ff /*P1_TSBITRATE0*/ -#define R0900_P1_TSBITRATE0 0xf584 -#define F0900_P1_TSFIFO_BITRATE0 0xf58400ff +#define R0900_P1_TSBITRATE0 0xf584 +#define TSBITRATE0 REGx(R0900_P1_TSBITRATE0) +#define F0900_P1_TSFIFO_BITRATE0 0xf58400ff /*P1_ERRCTRL1*/ -#define R0900_P1_ERRCTRL1 0xf598 -#define F0900_P1_ERR_SOURCE1 0xf59800f0 -#define F0900_P1_NUM_EVENT1 0xf5980007 +#define R0900_P1_ERRCTRL1 0xf598 +#define ERRCTRL1 REGx(R0900_P1_ERRCTRL1) +#define F0900_P1_ERR_SOURCE1 0xf59800f0 +#define F0900_P1_NUM_EVENT1 0xf5980007 /*P1_ERRCNT12*/ -#define R0900_P1_ERRCNT12 0xf599 -#define F0900_P1_ERRCNT1_OLDVALUE 0xf5990080 -#define F0900_P1_ERR_CNT12 0xf599007f +#define R0900_P1_ERRCNT12 0xf599 +#define ERRCNT12 REGx(R0900_P1_ERRCNT12) +#define F0900_P1_ERRCNT1_OLDVALUE 0xf5990080 +#define F0900_P1_ERR_CNT12 0xf599007f +#define ERR_CNT12 FLDx(F0900_P1_ERR_CNT12) /*P1_ERRCNT11*/ -#define R0900_P1_ERRCNT11 0xf59a -#define F0900_P1_ERR_CNT11 0xf59a00ff +#define R0900_P1_ERRCNT11 0xf59a +#define ERRCNT11 REGx(R0900_P1_ERRCNT11) +#define F0900_P1_ERR_CNT11 0xf59a00ff +#define ERR_CNT11 FLDx(F0900_P1_ERR_CNT11) /*P1_ERRCNT10*/ -#define R0900_P1_ERRCNT10 0xf59b -#define F0900_P1_ERR_CNT10 0xf59b00ff +#define R0900_P1_ERRCNT10 0xf59b +#define ERRCNT10 REGx(R0900_P1_ERRCNT10) +#define F0900_P1_ERR_CNT10 0xf59b00ff +#define ERR_CNT10 FLDx(F0900_P1_ERR_CNT10) /*P1_ERRCTRL2*/ -#define R0900_P1_ERRCTRL2 0xf59c -#define F0900_P1_ERR_SOURCE2 0xf59c00f0 -#define F0900_P1_NUM_EVENT2 0xf59c0007 +#define R0900_P1_ERRCTRL2 0xf59c +#define ERRCTRL2 REGx(R0900_P1_ERRCTRL2) +#define F0900_P1_ERR_SOURCE2 0xf59c00f0 +#define F0900_P1_NUM_EVENT2 0xf59c0007 /*P1_ERRCNT22*/ -#define R0900_P1_ERRCNT22 0xf59d -#define F0900_P1_ERRCNT2_OLDVALUE 0xf59d0080 -#define F0900_P1_ERR_CNT22 0xf59d007f +#define R0900_P1_ERRCNT22 0xf59d +#define ERRCNT22 REGx(R0900_P1_ERRCNT22) +#define F0900_P1_ERRCNT2_OLDVALUE 0xf59d0080 +#define F0900_P1_ERR_CNT22 0xf59d007f +#define ERR_CNT22 FLDx(F0900_P1_ERR_CNT22) /*P1_ERRCNT21*/ -#define R0900_P1_ERRCNT21 0xf59e -#define F0900_P1_ERR_CNT21 0xf59e00ff +#define R0900_P1_ERRCNT21 0xf59e +#define ERRCNT21 REGx(R0900_P1_ERRCNT21) +#define F0900_P1_ERR_CNT21 0xf59e00ff +#define ERR_CNT21 FLDx(F0900_P1_ERR_CNT21) /*P1_ERRCNT20*/ -#define R0900_P1_ERRCNT20 0xf59f -#define F0900_P1_ERR_CNT20 0xf59f00ff +#define R0900_P1_ERRCNT20 0xf59f +#define ERRCNT20 REGx(R0900_P1_ERRCNT20) +#define F0900_P1_ERR_CNT20 0xf59f00ff +#define ERR_CNT20 FLDx(F0900_P1_ERR_CNT20) /*P1_FECSPY*/ -#define R0900_P1_FECSPY 0xf5a0 -#define F0900_P1_SPY_ENABLE 0xf5a00080 -#define F0900_P1_NO_SYNCBYTE 0xf5a00040 -#define F0900_P1_SERIAL_MODE 0xf5a00020 -#define F0900_P1_UNUSUAL_PACKET 0xf5a00010 -#define F0900_P1_BER_PACKMODE 0xf5a00008 -#define F0900_P1_BERMETER_LMODE 0xf5a00002 -#define F0900_P1_BERMETER_RESET 0xf5a00001 +#define R0900_P1_FECSPY 0xf5a0 +#define FECSPY REGx(R0900_P1_FECSPY) +#define F0900_P1_SPY_ENABLE 0xf5a00080 +#define F0900_P1_NO_SYNCBYTE 0xf5a00040 +#define F0900_P1_SERIAL_MODE 0xf5a00020 +#define F0900_P1_UNUSUAL_PACKET 0xf5a00010 +#define F0900_P1_BERMETER_DATAMODE 0xf5a00008 +#define F0900_P1_BERMETER_LMODE 0xf5a00002 +#define F0900_P1_BERMETER_RESET 0xf5a00001 /*P1_FSPYCFG*/ -#define R0900_P1_FSPYCFG 0xf5a1 -#define F0900_P1_FECSPY_INPUT 0xf5a100c0 -#define F0900_P1_RST_ON_ERROR 0xf5a10020 -#define F0900_P1_ONE_SHOT 0xf5a10010 -#define F0900_P1_I2C_MODE 0xf5a1000c -#define F0900_P1_SPY_HYSTERESIS 0xf5a10003 +#define R0900_P1_FSPYCFG 0xf5a1 +#define FSPYCFG REGx(R0900_P1_FSPYCFG) +#define F0900_P1_FECSPY_INPUT 0xf5a100c0 +#define F0900_P1_RST_ON_ERROR 0xf5a10020 +#define F0900_P1_ONE_SHOT 0xf5a10010 +#define F0900_P1_I2C_MODE 0xf5a1000c +#define F0900_P1_SPY_HYSTERESIS 0xf5a10003 /*P1_FSPYDATA*/ -#define R0900_P1_FSPYDATA 0xf5a2 -#define F0900_P1_SPY_STUFFING 0xf5a20080 -#define F0900_P1_NOERROR_PKTJITTER 0xf5a20040 -#define F0900_P1_SPY_CNULLPKT 0xf5a20020 -#define F0900_P1_SPY_OUTDATA_MODE 0xf5a2001f +#define R0900_P1_FSPYDATA 0xf5a2 +#define FSPYDATA REGx(R0900_P1_FSPYDATA) +#define F0900_P1_SPY_STUFFING 0xf5a20080 +#define F0900_P1_SPY_CNULLPKT 0xf5a20020 +#define F0900_P1_SPY_OUTDATA_MODE 0xf5a2001f /*P1_FSPYOUT*/ -#define R0900_P1_FSPYOUT 0xf5a3 -#define F0900_P1_FSPY_DIRECT 0xf5a30080 -#define F0900_P1_SPY_OUTDATA_BUS 0xf5a30038 -#define F0900_P1_STUFF_MODE 0xf5a30007 +#define R0900_P1_FSPYOUT 0xf5a3 +#define FSPYOUT REGx(R0900_P1_FSPYOUT) +#define F0900_P1_FSPY_DIRECT 0xf5a30080 +#define F0900_P1_STUFF_MODE 0xf5a30007 /*P1_FSTATUS*/ -#define R0900_P1_FSTATUS 0xf5a4 -#define F0900_P1_SPY_ENDSIM 0xf5a40080 -#define F0900_P1_VALID_SIM 0xf5a40040 -#define F0900_P1_FOUND_SIGNAL 0xf5a40020 -#define F0900_P1_DSS_SYNCBYTE 0xf5a40010 -#define F0900_P1_RESULT_STATE 0xf5a4000f +#define R0900_P1_FSTATUS 0xf5a4 +#define FSTATUS REGx(R0900_P1_FSTATUS) +#define F0900_P1_SPY_ENDSIM 0xf5a40080 +#define F0900_P1_VALID_SIM 0xf5a40040 +#define F0900_P1_FOUND_SIGNAL 0xf5a40020 +#define F0900_P1_DSS_SYNCBYTE 0xf5a40010 +#define F0900_P1_RESULT_STATE 0xf5a4000f /*P1_FBERCPT4*/ -#define R0900_P1_FBERCPT4 0xf5a8 -#define F0900_P1_FBERMETER_CPT4 0xf5a800ff +#define R0900_P1_FBERCPT4 0xf5a8 +#define FBERCPT4 REGx(R0900_P1_FBERCPT4) +#define F0900_P1_FBERMETER_CPT4 0xf5a800ff /*P1_FBERCPT3*/ -#define R0900_P1_FBERCPT3 0xf5a9 -#define F0900_P1_FBERMETER_CPT3 0xf5a900ff +#define R0900_P1_FBERCPT3 0xf5a9 +#define FBERCPT3 REGx(R0900_P1_FBERCPT3) +#define F0900_P1_FBERMETER_CPT3 0xf5a900ff /*P1_FBERCPT2*/ -#define R0900_P1_FBERCPT2 0xf5aa -#define F0900_P1_FBERMETER_CPT2 0xf5aa00ff +#define R0900_P1_FBERCPT2 0xf5aa +#define FBERCPT2 REGx(R0900_P1_FBERCPT2) +#define F0900_P1_FBERMETER_CPT2 0xf5aa00ff /*P1_FBERCPT1*/ -#define R0900_P1_FBERCPT1 0xf5ab -#define F0900_P1_FBERMETER_CPT1 0xf5ab00ff +#define R0900_P1_FBERCPT1 0xf5ab +#define FBERCPT1 REGx(R0900_P1_FBERCPT1) +#define F0900_P1_FBERMETER_CPT1 0xf5ab00ff /*P1_FBERCPT0*/ -#define R0900_P1_FBERCPT0 0xf5ac -#define F0900_P1_FBERMETER_CPT0 0xf5ac00ff +#define R0900_P1_FBERCPT0 0xf5ac +#define FBERCPT0 REGx(R0900_P1_FBERCPT0) +#define F0900_P1_FBERMETER_CPT0 0xf5ac00ff /*P1_FBERERR2*/ -#define R0900_P1_FBERERR2 0xf5ad -#define F0900_P1_FBERMETER_ERR2 0xf5ad00ff +#define R0900_P1_FBERERR2 0xf5ad +#define FBERERR2 REGx(R0900_P1_FBERERR2) +#define F0900_P1_FBERMETER_ERR2 0xf5ad00ff /*P1_FBERERR1*/ -#define R0900_P1_FBERERR1 0xf5ae -#define F0900_P1_FBERMETER_ERR1 0xf5ae00ff +#define R0900_P1_FBERERR1 0xf5ae +#define FBERERR1 REGx(R0900_P1_FBERERR1) +#define F0900_P1_FBERMETER_ERR1 0xf5ae00ff /*P1_FBERERR0*/ -#define R0900_P1_FBERERR0 0xf5af -#define F0900_P1_FBERMETER_ERR0 0xf5af00ff +#define R0900_P1_FBERERR0 0xf5af +#define FBERERR0 REGx(R0900_P1_FBERERR0) +#define F0900_P1_FBERMETER_ERR0 0xf5af00ff /*P1_FSPYBER*/ -#define R0900_P1_FSPYBER 0xf5b2 -#define F0900_P1_FSPYOBS_XORREAD 0xf5b20040 -#define F0900_P1_FSPYBER_OBSMODE 0xf5b20020 -#define F0900_P1_FSPYBER_SYNCBYTE 0xf5b20010 -#define F0900_P1_FSPYBER_UNSYNC 0xf5b20008 -#define F0900_P1_FSPYBER_CTIME 0xf5b20007 - -/*RCCFGH*/ -#define R0900_RCCFGH 0xf600 -#define F0900_TSRCFIFO_DVBCI 0xf6000080 -#define F0900_TSRCFIFO_SERIAL 0xf6000040 -#define F0900_TSRCFIFO_DISABLE 0xf6000020 -#define F0900_TSFIFO_2TORC 0xf6000010 -#define F0900_TSRCFIFO_HSGNLOUT 0xf6000008 -#define F0900_TSRCFIFO_ERRMODE 0xf6000006 +#define R0900_P1_FSPYBER 0xf5b2 +#define FSPYBER REGx(R0900_P1_FSPYBER) +#define F0900_P1_FSPYBER_SYNCBYTE 0xf5b20010 +#define F0900_P1_FSPYBER_UNSYNC 0xf5b20008 +#define F0900_P1_FSPYBER_CTIME 0xf5b20007 + +/*RCCFG2*/ +#define R0900_RCCFG2 0xf600 /*TSGENERAL*/ -#define R0900_TSGENERAL 0xf630 -#define F0900_TSFIFO_BCLK1ALL 0xf6300020 -#define F0900_MUXSTREAM_OUTMODE 0xf6300008 -#define F0900_TSFIFO_PERMPARAL 0xf6300006 -#define F0900_RST_REEDSOLO 0xf6300001 +#define R0900_TSGENERAL 0xf630 +#define F0900_TSFIFO_DISTS2PAR 0xf6300040 +#define F0900_MUXSTREAM_OUTMODE 0xf6300008 +#define F0900_TSFIFO_PERMPARAL 0xf6300006 /*TSGENERAL1X*/ -#define R0900_TSGENERAL1X 0xf670 -#define F0900_TSFIFO1X_BCLK1ALL 0xf6700020 -#define F0900_MUXSTREAM1X_OUTMODE 0xf6700008 -#define F0900_TSFIFO1X_PERMPARAL 0xf6700006 -#define F0900_RST1X_REEDSOLO 0xf6700001 +#define R0900_TSGENERAL1X 0xf670 /*NBITER_NF4*/ -#define R0900_NBITER_NF4 0xfa03 -#define F0900_NBITER_NF_QP_1_2 0xfa0300ff +#define R0900_NBITER_NF4 0xfa03 +#define F0900_NBITER_NF_QP_1_2 0xfa0300ff /*NBITER_NF5*/ -#define R0900_NBITER_NF5 0xfa04 -#define F0900_NBITER_NF_QP_3_5 0xfa0400ff +#define R0900_NBITER_NF5 0xfa04 +#define F0900_NBITER_NF_QP_3_5 0xfa0400ff /*NBITER_NF6*/ -#define R0900_NBITER_NF6 0xfa05 -#define F0900_NBITER_NF_QP_2_3 0xfa0500ff +#define R0900_NBITER_NF6 0xfa05 +#define F0900_NBITER_NF_QP_2_3 0xfa0500ff /*NBITER_NF7*/ -#define R0900_NBITER_NF7 0xfa06 -#define F0900_NBITER_NF_QP_3_4 0xfa0600ff +#define R0900_NBITER_NF7 0xfa06 +#define F0900_NBITER_NF_QP_3_4 0xfa0600ff /*NBITER_NF8*/ -#define R0900_NBITER_NF8 0xfa07 -#define F0900_NBITER_NF_QP_4_5 0xfa0700ff +#define R0900_NBITER_NF8 0xfa07 +#define F0900_NBITER_NF_QP_4_5 0xfa0700ff /*NBITER_NF9*/ -#define R0900_NBITER_NF9 0xfa08 -#define F0900_NBITER_NF_QP_5_6 0xfa0800ff +#define R0900_NBITER_NF9 0xfa08 +#define F0900_NBITER_NF_QP_5_6 0xfa0800ff /*NBITER_NF10*/ -#define R0900_NBITER_NF10 0xfa09 -#define F0900_NBITER_NF_QP_8_9 0xfa0900ff +#define R0900_NBITER_NF10 0xfa09 +#define F0900_NBITER_NF_QP_8_9 0xfa0900ff /*NBITER_NF11*/ -#define R0900_NBITER_NF11 0xfa0a -#define F0900_NBITER_NF_QP_9_10 0xfa0a00ff +#define R0900_NBITER_NF11 0xfa0a +#define F0900_NBITER_NF_QP_9_10 0xfa0a00ff /*NBITER_NF12*/ -#define R0900_NBITER_NF12 0xfa0b -#define F0900_NBITER_NF_8P_3_5 0xfa0b00ff +#define R0900_NBITER_NF12 0xfa0b +#define F0900_NBITER_NF_8P_3_5 0xfa0b00ff /*NBITER_NF13*/ -#define R0900_NBITER_NF13 0xfa0c -#define F0900_NBITER_NF_8P_2_3 0xfa0c00ff +#define R0900_NBITER_NF13 0xfa0c +#define F0900_NBITER_NF_8P_2_3 0xfa0c00ff /*NBITER_NF14*/ -#define R0900_NBITER_NF14 0xfa0d -#define F0900_NBITER_NF_8P_3_4 0xfa0d00ff +#define R0900_NBITER_NF14 0xfa0d +#define F0900_NBITER_NF_8P_3_4 0xfa0d00ff /*NBITER_NF15*/ -#define R0900_NBITER_NF15 0xfa0e -#define F0900_NBITER_NF_8P_5_6 0xfa0e00ff +#define R0900_NBITER_NF15 0xfa0e +#define F0900_NBITER_NF_8P_5_6 0xfa0e00ff /*NBITER_NF16*/ -#define R0900_NBITER_NF16 0xfa0f -#define F0900_NBITER_NF_8P_8_9 0xfa0f00ff +#define R0900_NBITER_NF16 0xfa0f +#define F0900_NBITER_NF_8P_8_9 0xfa0f00ff /*NBITER_NF17*/ -#define R0900_NBITER_NF17 0xfa10 -#define F0900_NBITER_NF_8P_9_10 0xfa1000ff +#define R0900_NBITER_NF17 0xfa10 +#define F0900_NBITER_NF_8P_9_10 0xfa1000ff /*NBITERNOERR*/ -#define R0900_NBITERNOERR 0xfa3f -#define F0900_NBITER_STOP_CRIT 0xfa3f000f +#define R0900_NBITERNOERR 0xfa3f +#define F0900_NBITER_STOP_CRIT 0xfa3f000f /*GAINLLR_NF4*/ -#define R0900_GAINLLR_NF4 0xfa43 -#define F0900_GAINLLR_NF_QP_1_2 0xfa43007f +#define R0900_GAINLLR_NF4 0xfa43 +#define F0900_GAINLLR_NF_QP_1_2 0xfa43007f /*GAINLLR_NF5*/ -#define R0900_GAINLLR_NF5 0xfa44 -#define F0900_GAINLLR_NF_QP_3_5 0xfa44007f +#define R0900_GAINLLR_NF5 0xfa44 +#define F0900_GAINLLR_NF_QP_3_5 0xfa44007f /*GAINLLR_NF6*/ -#define R0900_GAINLLR_NF6 0xfa45 -#define F0900_GAINLLR_NF_QP_2_3 0xfa45007f +#define R0900_GAINLLR_NF6 0xfa45 +#define F0900_GAINLLR_NF_QP_2_3 0xfa45007f /*GAINLLR_NF7*/ -#define R0900_GAINLLR_NF7 0xfa46 -#define F0900_GAINLLR_NF_QP_3_4 0xfa46007f +#define R0900_GAINLLR_NF7 0xfa46 +#define F0900_GAINLLR_NF_QP_3_4 0xfa46007f /*GAINLLR_NF8*/ -#define R0900_GAINLLR_NF8 0xfa47 -#define F0900_GAINLLR_NF_QP_4_5 0xfa47007f +#define R0900_GAINLLR_NF8 0xfa47 +#define F0900_GAINLLR_NF_QP_4_5 0xfa47007f /*GAINLLR_NF9*/ -#define R0900_GAINLLR_NF9 0xfa48 -#define F0900_GAINLLR_NF_QP_5_6 0xfa48007f +#define R0900_GAINLLR_NF9 0xfa48 +#define F0900_GAINLLR_NF_QP_5_6 0xfa48007f /*GAINLLR_NF10*/ -#define R0900_GAINLLR_NF10 0xfa49 -#define F0900_GAINLLR_NF_QP_8_9 0xfa49007f +#define R0900_GAINLLR_NF10 0xfa49 +#define F0900_GAINLLR_NF_QP_8_9 0xfa49007f /*GAINLLR_NF11*/ -#define R0900_GAINLLR_NF11 0xfa4a -#define F0900_GAINLLR_NF_QP_9_10 0xfa4a007f +#define R0900_GAINLLR_NF11 0xfa4a +#define F0900_GAINLLR_NF_QP_9_10 0xfa4a007f /*GAINLLR_NF12*/ -#define R0900_GAINLLR_NF12 0xfa4b -#define F0900_GAINLLR_NF_8P_3_5 0xfa4b007f +#define R0900_GAINLLR_NF12 0xfa4b +#define F0900_GAINLLR_NF_8P_3_5 0xfa4b007f /*GAINLLR_NF13*/ -#define R0900_GAINLLR_NF13 0xfa4c -#define F0900_GAINLLR_NF_8P_2_3 0xfa4c007f +#define R0900_GAINLLR_NF13 0xfa4c +#define F0900_GAINLLR_NF_8P_2_3 0xfa4c007f /*GAINLLR_NF14*/ -#define R0900_GAINLLR_NF14 0xfa4d -#define F0900_GAINLLR_NF_8P_3_4 0xfa4d007f +#define R0900_GAINLLR_NF14 0xfa4d +#define F0900_GAINLLR_NF_8P_3_4 0xfa4d007f /*GAINLLR_NF15*/ -#define R0900_GAINLLR_NF15 0xfa4e -#define F0900_GAINLLR_NF_8P_5_6 0xfa4e007f +#define R0900_GAINLLR_NF15 0xfa4e +#define F0900_GAINLLR_NF_8P_5_6 0xfa4e007f /*GAINLLR_NF16*/ -#define R0900_GAINLLR_NF16 0xfa4f -#define F0900_GAINLLR_NF_8P_8_9 0xfa4f007f +#define R0900_GAINLLR_NF16 0xfa4f +#define F0900_GAINLLR_NF_8P_8_9 0xfa4f007f /*GAINLLR_NF17*/ -#define R0900_GAINLLR_NF17 0xfa50 -#define F0900_GAINLLR_NF_8P_9_10 0xfa50007f +#define R0900_GAINLLR_NF17 0xfa50 +#define F0900_GAINLLR_NF_8P_9_10 0xfa50007f /*CFGEXT*/ -#define R0900_CFGEXT 0xfa80 -#define F0900_STAGMODE 0xfa800080 -#define F0900_BYPBCH 0xfa800040 -#define F0900_BYPLDPC 0xfa800020 -#define F0900_LDPCMODE 0xfa800010 -#define F0900_INVLLRSIGN 0xfa800008 -#define F0900_SHORTMULT 0xfa800004 -#define F0900_EXTERNTX 0xfa800001 +#define R0900_CFGEXT 0xfa80 +#define F0900_STAGMODE 0xfa800080 +#define F0900_BYPBCH 0xfa800040 +#define F0900_BYPLDPC 0xfa800020 +#define F0900_LDPCMODE 0xfa800010 +#define F0900_INVLLRSIGN 0xfa800008 +#define F0900_SHORTMULT 0xfa800004 +#define F0900_EXTERNTX 0xfa800001 /*GENCFG*/ -#define R0900_GENCFG 0xfa86 -#define F0900_BROADCAST 0xfa860010 -#define F0900_NOSHFRD2 0xfa860008 -#define F0900_BCHERRFLAG 0xfa860004 -#define F0900_PRIORITY 0xfa860002 -#define F0900_DDEMOD 0xfa860001 +#define R0900_GENCFG 0xfa86 +#define F0900_BROADCAST 0xfa860010 +#define F0900_PRIORITY 0xfa860002 +#define F0900_DDEMOD 0xfa860001 /*LDPCERR1*/ -#define R0900_LDPCERR1 0xfa96 -#define F0900_LDPC_ERRORS_COUNTER1 0xfa9600ff +#define R0900_LDPCERR1 0xfa96 +#define F0900_LDPC_ERRORS_COUNTER1 0xfa9600ff /*LDPCERR0*/ -#define R0900_LDPCERR0 0xfa97 -#define F0900_LDPC_ERRORS_COUNTER0 0xfa9700ff +#define R0900_LDPCERR0 0xfa97 +#define F0900_LDPC_ERRORS_COUNTER0 0xfa9700ff /*BCHERR*/ -#define R0900_BCHERR 0xfa98 -#define F0900_ERRORFLAG 0xfa980010 -#define F0900_BCH_ERRORS_COUNTER 0xfa98000f +#define R0900_BCHERR 0xfa98 +#define F0900_ERRORFLAG 0xfa980010 +#define F0900_BCH_ERRORS_COUNTER 0xfa98000f /*TSTRES0*/ -#define R0900_TSTRES0 0xff11 -#define F0900_FRESFEC 0xff110080 -#define F0900_FRESTS 0xff110040 -#define F0900_FRESVIT1 0xff110020 -#define F0900_FRESVIT2 0xff110010 -#define F0900_FRESSYM1 0xff110008 -#define F0900_FRESSYM2 0xff110004 -#define F0900_FRESMAS 0xff110002 -#define F0900_FRESINT 0xff110001 +#define R0900_TSTRES0 0xff11 +#define F0900_FRESFEC 0xff110080 + +/*P2_TCTL4*/ +#define R0900_P2_TCTL4 0xff28 +#define F0900_P2_PN4_SELECT 0xff280020 + +/*P1_TCTL4*/ +#define R0900_P1_TCTL4 0xff48 +#define TCTL4 shiftx(R0900_P1_TCTL4, demod, 0x20) +#define F0900_P1_PN4_SELECT 0xff480020 /*P2_TSTDISRX*/ -#define R0900_P2_TSTDISRX 0xff65 -#define F0900_P2_EN_DISRX 0xff650080 -#define F0900_P2_TST_CURRSRC 0xff650040 -#define F0900_P2_IN_DIGSIGNAL 0xff650020 -#define F0900_P2_HIZ_CURRENTSRC 0xff650010 -#define F0900_TST_P2_PIN_SELECT 0xff650008 -#define F0900_P2_TST_DISRX 0xff650007 +#define R0900_P2_TSTDISRX 0xff65 +#define F0900_P2_PIN_SELECT1 0xff650008 /*P1_TSTDISRX*/ -#define R0900_P1_TSTDISRX 0xff67 -#define F0900_P1_EN_DISRX 0xff670080 -#define F0900_P1_TST_CURRSRC 0xff670040 -#define F0900_P1_IN_DIGSIGNAL 0xff670020 -#define F0900_P1_HIZ_CURRENTSRC 0xff670010 -#define F0900_TST_P1_PIN_SELECT 0xff670008 -#define F0900_P1_TST_DISRX 0xff670007 - -#define STV0900_NBREGS 684 -#define STV0900_NBFIELDS 1702 +#define R0900_P1_TSTDISRX 0xff67 +#define TSTDISRX shiftx(R0900_P1_TSTDISRX, demod, 2) +#define F0900_P1_PIN_SELECT1 0xff670008 +#define PIN_SELECT1 shiftx(F0900_P1_PIN_SELECT1, demod, 0x20000) + +#define STV0900_NBREGS 723 +#define STV0900_NBFIELDS 1420 #endif -- cgit v1.2.3-70-g09d2 From 1e0c397d5ee261b4d855bf38c1e9987caf0e37ca Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Fri, 6 Nov 2009 23:42:22 -0300 Subject: V4L/DVB (13340): stv0900: big rework to support cut 3.0. Patch 3 of 4. Also patch changes logic to prevent code repetitions and big indents. It makes checkpatch silent :) Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0900_core.c | 1453 ++++++++++++---------------- 1 file changed, 633 insertions(+), 820 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c index 11dbe942aa4..e2062048f43 100644 --- a/drivers/media/dvb/frontends/stv0900_core.c +++ b/drivers/media/dvb/frontends/stv0900_core.c @@ -105,7 +105,8 @@ static struct stv0900_inode *append_internal(struct stv0900_internal *internal) while (new_node->next_inode != NULL) new_node = new_node->next_inode; - new_node->next_inode = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL); + new_node->next_inode = kmalloc(sizeof(struct stv0900_inode), + GFP_KERNEL); if (new_node->next_inode != NULL) new_node = new_node->next_inode; else @@ -128,13 +129,13 @@ s32 ge2comp(s32 a, s32 width) return (a >= (1 << (width - 1))) ? (a - (1 << width)) : a; } -void stv0900_write_reg(struct stv0900_internal *i_params, u16 reg_addr, +void stv0900_write_reg(struct stv0900_internal *intp, u16 reg_addr, u8 reg_data) { u8 data[3]; int ret; struct i2c_msg i2cmsg = { - .addr = i_params->i2c_addr, + .addr = intp->i2c_addr, .flags = 0, .len = 3, .buf = data, @@ -144,31 +145,31 @@ void stv0900_write_reg(struct stv0900_internal *i_params, u16 reg_addr, data[1] = LSB(reg_addr); data[2] = reg_data; - ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1); + ret = i2c_transfer(intp->i2c_adap, &i2cmsg, 1); if (ret != 1) dprintk("%s: i2c error %d\n", __func__, ret); } -u8 stv0900_read_reg(struct stv0900_internal *i_params, u16 reg) +u8 stv0900_read_reg(struct stv0900_internal *intp, u16 reg) { int ret; u8 b0[] = { MSB(reg), LSB(reg) }; u8 buf = 0; struct i2c_msg msg[] = { { - .addr = i_params->i2c_addr, + .addr = intp->i2c_addr, .flags = 0, .buf = b0, .len = 2, }, { - .addr = i_params->i2c_addr, + .addr = intp->i2c_addr, .flags = I2C_M_RD, .buf = &buf, .len = 1, }, }; - ret = i2c_transfer(i_params->i2c_adap, msg, 2); + ret = i2c_transfer(intp->i2c_adap, msg, 2); if (ret != 2) dprintk("%s: i2c error %d, reg[0x%02x]\n", __func__, ret, reg); @@ -190,94 +191,103 @@ void extract_mask_pos(u32 label, u8 *mask, u8 *pos) (*pos) = (i - 1); } -void stv0900_write_bits(struct stv0900_internal *i_params, u32 label, u8 val) +void stv0900_write_bits(struct stv0900_internal *intp, u32 label, u8 val) { u8 reg, mask, pos; - reg = stv0900_read_reg(i_params, (label >> 16) & 0xffff); + reg = stv0900_read_reg(intp, (label >> 16) & 0xffff); extract_mask_pos(label, &mask, &pos); val = mask & (val << pos); reg = (reg & (~mask)) | val; - stv0900_write_reg(i_params, (label >> 16) & 0xffff, reg); + stv0900_write_reg(intp, (label >> 16) & 0xffff, reg); } -u8 stv0900_get_bits(struct stv0900_internal *i_params, u32 label) +u8 stv0900_get_bits(struct stv0900_internal *intp, u32 label) { u8 val = 0xff; u8 mask, pos; extract_mask_pos(label, &mask, &pos); - val = stv0900_read_reg(i_params, label >> 16); + val = stv0900_read_reg(intp, label >> 16); val = (val & mask) >> pos; return val; } -enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *i_params) +enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *intp) { s32 i; - enum fe_stv0900_error error; - - if (i_params != NULL) { - i_params->chip_id = stv0900_read_reg(i_params, R0900_MID); - if (i_params->errs == STV0900_NO_ERROR) { - /*Startup sequence*/ - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5c); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5c); - stv0900_write_reg(i_params, R0900_P1_TNRCFG, 0x6c); - stv0900_write_reg(i_params, R0900_P2_TNRCFG, 0x6f); - stv0900_write_reg(i_params, R0900_P1_I2CRPT, 0x20); - stv0900_write_reg(i_params, R0900_P2_I2CRPT, 0x20); - stv0900_write_reg(i_params, R0900_NCOARSE, 0x13); - msleep(3); - stv0900_write_reg(i_params, R0900_I2CCFG, 0x08); - - switch (i_params->clkmode) { - case 0: - case 2: - stv0900_write_reg(i_params, R0900_SYNTCTRL, 0x20 - | i_params->clkmode); - break; - default: - /* preserve SELOSCI bit */ - i = 0x02 & stv0900_read_reg(i_params, R0900_SYNTCTRL); - stv0900_write_reg(i_params, R0900_SYNTCTRL, 0x20 | i); - break; - } - msleep(3); - for (i = 0; i < 182; i++) - stv0900_write_reg(i_params, STV0900_InitVal[i][0], STV0900_InitVal[i][1]); + if (intp == NULL) + return STV0900_INVALID_HANDLE; - if (stv0900_read_reg(i_params, R0900_MID) >= 0x20) { - stv0900_write_reg(i_params, R0900_TSGENERAL, 0x0c); - for (i = 0; i < 32; i++) - stv0900_write_reg(i_params, STV0900_Cut20_AddOnVal[i][0], STV0900_Cut20_AddOnVal[i][1]); - } + intp->chip_id = stv0900_read_reg(intp, R0900_MID); - stv0900_write_reg(i_params, R0900_P1_FSPYCFG, 0x6c); - stv0900_write_reg(i_params, R0900_P2_FSPYCFG, 0x6c); - stv0900_write_reg(i_params, R0900_TSTRES0, 0x80); - stv0900_write_reg(i_params, R0900_TSTRES0, 0x00); - } - error = i_params->errs; - } else - error = STV0900_INVALID_HANDLE; + if (intp->errs != STV0900_NO_ERROR) + return intp->errs; - return error; + /*Startup sequence*/ + stv0900_write_reg(intp, R0900_P1_DMDISTATE, 0x5c); + stv0900_write_reg(intp, R0900_P2_DMDISTATE, 0x5c); + msleep(3); + stv0900_write_reg(intp, R0900_P1_TNRCFG, 0x6c); + stv0900_write_reg(intp, R0900_P2_TNRCFG, 0x6f); + stv0900_write_reg(intp, R0900_P1_I2CRPT, 0x20); + stv0900_write_reg(intp, R0900_P2_I2CRPT, 0x20); + stv0900_write_reg(intp, R0900_NCOARSE, 0x13); + msleep(3); + stv0900_write_reg(intp, R0900_I2CCFG, 0x08); + + switch (intp->clkmode) { + case 0: + case 2: + stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 + | intp->clkmode); + break; + default: + /* preserve SELOSCI bit */ + i = 0x02 & stv0900_read_reg(intp, R0900_SYNTCTRL); + stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | i); + break; + } + + msleep(3); + for (i = 0; i < 181; i++) + stv0900_write_reg(intp, STV0900_InitVal[i][0], + STV0900_InitVal[i][1]); + if (stv0900_read_reg(intp, R0900_MID) >= 0x20) { + stv0900_write_reg(intp, R0900_TSGENERAL, 0x0c); + for (i = 0; i < 32; i++) + stv0900_write_reg(intp, STV0900_Cut20_AddOnVal[i][0], + STV0900_Cut20_AddOnVal[i][1]); + } + + stv0900_write_reg(intp, R0900_P1_FSPYCFG, 0x6c); + stv0900_write_reg(intp, R0900_P2_FSPYCFG, 0x6c); + + stv0900_write_reg(intp, R0900_P1_PDELCTRL2, 0x01); + stv0900_write_reg(intp, R0900_P2_PDELCTRL2, 0x21); + + stv0900_write_reg(intp, R0900_P1_PDELCTRL3, 0x20); + stv0900_write_reg(intp, R0900_P2_PDELCTRL3, 0x20); + + stv0900_write_reg(intp, R0900_TSTRES0, 0x80); + stv0900_write_reg(intp, R0900_TSTRES0, 0x00); + + return STV0900_NO_ERROR; } -u32 stv0900_get_mclk_freq(struct stv0900_internal *i_params, u32 ext_clk) +u32 stv0900_get_mclk_freq(struct stv0900_internal *intp, u32 ext_clk) { u32 mclk = 90000000, div = 0, ad_div = 0; - div = stv0900_get_bits(i_params, F0900_M_DIV); - ad_div = ((stv0900_get_bits(i_params, F0900_SELX1RATIO) == 1) ? 4 : 6); + div = stv0900_get_bits(intp, F0900_M_DIV); + ad_div = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6); mclk = (div + 1) * ext_clk / ad_div; @@ -286,73 +296,60 @@ u32 stv0900_get_mclk_freq(struct stv0900_internal *i_params, u32 ext_clk) return mclk; } -enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *i_params, u32 mclk) +enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 mclk) { - enum fe_stv0900_error error = STV0900_NO_ERROR; u32 m_div, clk_sel; dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk, - i_params->quartz); + intp->quartz); - if (i_params == NULL) - error = STV0900_INVALID_HANDLE; - else { - if (i_params->errs) - error = STV0900_I2C_ERROR; - else { - clk_sel = ((stv0900_get_bits(i_params, F0900_SELX1RATIO) == 1) ? 4 : 6); - m_div = ((clk_sel * mclk) / i_params->quartz) - 1; - stv0900_write_bits(i_params, F0900_M_DIV, m_div); - i_params->mclk = stv0900_get_mclk_freq(i_params, - i_params->quartz); - - /*Set the DiseqC frequency to 22KHz */ - /* - Formula: - DiseqC_TX_Freq= MasterClock/(32*F22TX_Reg) - DiseqC_RX_Freq= MasterClock/(32*F22RX_Reg) - */ - m_div = i_params->mclk / 704000; - stv0900_write_reg(i_params, R0900_P1_F22TX, m_div); - stv0900_write_reg(i_params, R0900_P1_F22RX, m_div); - - stv0900_write_reg(i_params, R0900_P2_F22TX, m_div); - stv0900_write_reg(i_params, R0900_P2_F22RX, m_div); - - if ((i_params->errs)) - error = STV0900_I2C_ERROR; - } - } + if (intp == NULL) + return STV0900_INVALID_HANDLE; - return error; + if (intp->errs) + return STV0900_I2C_ERROR; + + clk_sel = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6); + m_div = ((clk_sel * mclk) / intp->quartz) - 1; + stv0900_write_bits(intp, F0900_M_DIV, m_div); + intp->mclk = stv0900_get_mclk_freq(intp, + intp->quartz); + + /*Set the DiseqC frequency to 22KHz */ + /* + Formula: + DiseqC_TX_Freq= MasterClock/(32*F22TX_Reg) + DiseqC_RX_Freq= MasterClock/(32*F22RX_Reg) + */ + m_div = intp->mclk / 704000; + stv0900_write_reg(intp, R0900_P1_F22TX, m_div); + stv0900_write_reg(intp, R0900_P1_F22RX, m_div); + + stv0900_write_reg(intp, R0900_P2_F22TX, m_div); + stv0900_write_reg(intp, R0900_P2_F22RX, m_div); + + if ((intp->errs)) + return STV0900_I2C_ERROR; + + return STV0900_NO_ERROR; } -u32 stv0900_get_err_count(struct stv0900_internal *i_params, int cntr, +u32 stv0900_get_err_count(struct stv0900_internal *intp, int cntr, enum fe_stv0900_demod_num demod) { u32 lsb, msb, hsb, err_val; - s32 err1field_hsb, err1field_msb, err1field_lsb; - s32 err2field_hsb, err2field_msb, err2field_lsb; - - dmd_reg(err1field_hsb, F0900_P1_ERR_CNT12, F0900_P2_ERR_CNT12); - dmd_reg(err1field_msb, F0900_P1_ERR_CNT11, F0900_P2_ERR_CNT11); - dmd_reg(err1field_lsb, F0900_P1_ERR_CNT10, F0900_P2_ERR_CNT10); - - dmd_reg(err2field_hsb, F0900_P1_ERR_CNT22, F0900_P2_ERR_CNT22); - dmd_reg(err2field_msb, F0900_P1_ERR_CNT21, F0900_P2_ERR_CNT21); - dmd_reg(err2field_lsb, F0900_P1_ERR_CNT20, F0900_P2_ERR_CNT20); switch (cntr) { case 0: default: - hsb = stv0900_get_bits(i_params, err1field_hsb); - msb = stv0900_get_bits(i_params, err1field_msb); - lsb = stv0900_get_bits(i_params, err1field_lsb); + hsb = stv0900_get_bits(intp, ERR_CNT12); + msb = stv0900_get_bits(intp, ERR_CNT11); + lsb = stv0900_get_bits(intp, ERR_CNT10); break; case 1: - hsb = stv0900_get_bits(i_params, err2field_hsb); - msb = stv0900_get_bits(i_params, err2field_msb); - lsb = stv0900_get_bits(i_params, err2field_lsb); + hsb = stv0900_get_bits(intp, ERR_CNT22); + msb = stv0900_get_bits(intp, ERR_CNT21); + lsb = stv0900_get_bits(intp, ERR_CNT20); break; } @@ -364,26 +361,22 @@ u32 stv0900_get_err_count(struct stv0900_internal *i_params, int cntr, static int stv0900_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) { struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; + struct stv0900_internal *intp = state->internal; enum fe_stv0900_demod_num demod = state->demod; - u32 fi2c; - - dmd_reg(fi2c, F0900_P1_I2CT_ON, F0900_P2_I2CT_ON); - - stv0900_write_bits(i_params, fi2c, enable); + stv0900_write_bits(intp, I2CT_ON, enable); return 0; } -static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params, +static void stv0900_set_ts_parallel_serial(struct stv0900_internal *intp, enum fe_stv0900_clock_type path1_ts, enum fe_stv0900_clock_type path2_ts) { dprintk("%s\n", __func__); - if (i_params->chip_id >= 0x20) { + if (intp->chip_id >= 0x20) { switch (path1_ts) { case STV0900_PARALLEL_PUNCT_CLOCK: case STV0900_DVBCI_CLOCK: @@ -391,20 +384,20 @@ static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params, case STV0900_SERIAL_PUNCT_CLOCK: case STV0900_SERIAL_CONT_CLOCK: default: - stv0900_write_reg(i_params, R0900_TSGENERAL, + stv0900_write_reg(intp, R0900_TSGENERAL, 0x00); break; case STV0900_PARALLEL_PUNCT_CLOCK: case STV0900_DVBCI_CLOCK: - stv0900_write_reg(i_params, R0900_TSGENERAL, + stv0900_write_reg(intp, R0900_TSGENERAL, 0x06); - stv0900_write_bits(i_params, + stv0900_write_bits(intp, F0900_P1_TSFIFO_MANSPEED, 3); - stv0900_write_bits(i_params, + stv0900_write_bits(intp, F0900_P2_TSFIFO_MANSPEED, 0); - stv0900_write_reg(i_params, + stv0900_write_reg(intp, R0900_P1_TSSPEED, 0x14); - stv0900_write_reg(i_params, + stv0900_write_reg(intp, R0900_P2_TSSPEED, 0x28); break; } @@ -416,12 +409,12 @@ static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params, case STV0900_SERIAL_PUNCT_CLOCK: case STV0900_SERIAL_CONT_CLOCK: default: - stv0900_write_reg(i_params, + stv0900_write_reg(intp, R0900_TSGENERAL, 0x0C); break; case STV0900_PARALLEL_PUNCT_CLOCK: case STV0900_DVBCI_CLOCK: - stv0900_write_reg(i_params, + stv0900_write_reg(intp, R0900_TSGENERAL, 0x0A); dprintk("%s: 0x0a\n", __func__); break; @@ -436,20 +429,20 @@ static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params, case STV0900_SERIAL_PUNCT_CLOCK: case STV0900_SERIAL_CONT_CLOCK: default: - stv0900_write_reg(i_params, R0900_TSGENERAL1X, + stv0900_write_reg(intp, R0900_TSGENERAL1X, 0x10); break; case STV0900_PARALLEL_PUNCT_CLOCK: case STV0900_DVBCI_CLOCK: - stv0900_write_reg(i_params, R0900_TSGENERAL1X, + stv0900_write_reg(intp, R0900_TSGENERAL1X, 0x16); - stv0900_write_bits(i_params, + stv0900_write_bits(intp, F0900_P1_TSFIFO_MANSPEED, 3); - stv0900_write_bits(i_params, + stv0900_write_bits(intp, F0900_P2_TSFIFO_MANSPEED, 0); - stv0900_write_reg(i_params, R0900_P1_TSSPEED, + stv0900_write_reg(intp, R0900_P1_TSSPEED, 0x14); - stv0900_write_reg(i_params, R0900_P2_TSSPEED, + stv0900_write_reg(intp, R0900_P2_TSSPEED, 0x28); break; } @@ -462,12 +455,12 @@ static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params, case STV0900_SERIAL_PUNCT_CLOCK: case STV0900_SERIAL_CONT_CLOCK: default: - stv0900_write_reg(i_params, R0900_TSGENERAL1X, + stv0900_write_reg(intp, R0900_TSGENERAL1X, 0x14); break; case STV0900_PARALLEL_PUNCT_CLOCK: case STV0900_DVBCI_CLOCK: - stv0900_write_reg(i_params, R0900_TSGENERAL1X, + stv0900_write_reg(intp, R0900_TSGENERAL1X, 0x12); dprintk("%s: 0x12\n", __func__); break; @@ -479,20 +472,20 @@ static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params, switch (path1_ts) { case STV0900_PARALLEL_PUNCT_CLOCK: - stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x00); - stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x00); + stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x00); + stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x00); break; case STV0900_DVBCI_CLOCK: - stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x00); - stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x01); + stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x00); + stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x01); break; case STV0900_SERIAL_PUNCT_CLOCK: - stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x01); - stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x00); + stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x01); + stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x00); break; case STV0900_SERIAL_CONT_CLOCK: - stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x01); - stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x01); + stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x01); + stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x01); break; default: break; @@ -500,29 +493,29 @@ static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params, switch (path2_ts) { case STV0900_PARALLEL_PUNCT_CLOCK: - stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x00); - stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x00); + stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x00); + stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x00); break; case STV0900_DVBCI_CLOCK: - stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x00); - stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x01); + stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x00); + stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x01); break; case STV0900_SERIAL_PUNCT_CLOCK: - stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x01); - stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x00); + stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x01); + stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x00); break; case STV0900_SERIAL_CONT_CLOCK: - stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x01); - stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x01); + stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x01); + stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x01); break; default: break; } - stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 1); - stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 0); - stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 1); - stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 0); + stv0900_write_bits(intp, F0900_P2_RST_HWARE, 1); + stv0900_write_bits(intp, F0900_P2_RST_HWARE, 0); + stv0900_write_bits(intp, F0900_P1_RST_HWARE, 1); + stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0); } void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency, @@ -574,7 +567,7 @@ void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) } } -static s32 stv0900_get_rf_level(struct stv0900_internal *i_params, +static s32 stv0900_get_rf_level(struct stv0900_internal *intp, const struct stv0900_table *lookup, enum fe_stv0900_demod_num demod) { @@ -586,43 +579,37 @@ static s32 stv0900_get_rf_level(struct stv0900_internal *i_params, dprintk("%s\n", __func__); - if ((lookup != NULL) && lookup->size) { - switch (demod) { - case STV0900_DEMOD_1: - default: - agc_gain = MAKEWORD(stv0900_get_bits(i_params, F0900_P1_AGCIQ_VALUE1), - stv0900_get_bits(i_params, F0900_P1_AGCIQ_VALUE0)); - break; - case STV0900_DEMOD_2: - agc_gain = MAKEWORD(stv0900_get_bits(i_params, F0900_P2_AGCIQ_VALUE1), - stv0900_get_bits(i_params, F0900_P2_AGCIQ_VALUE0)); - break; - } - - dprintk("%s: AGC Gain = 0x%x\n", __func__, agc_gain); + if ((lookup == NULL) || (lookup->size <= 0)) + return 0; - imin = 0; - imax = lookup->size - 1; - if (INRANGE(lookup->table[imin].regval, agc_gain, lookup->table[imax].regval)) { - while ((imax - imin) > 1) { - i = (imax + imin) >> 1; + agc_gain = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1), + stv0900_get_bits(intp, AGCIQ_VALUE0)); - if (INRANGE(lookup->table[imin].regval, agc_gain, lookup->table[i].regval)) - imax = i; - else - imin = i; - } + imin = 0; + imax = lookup->size - 1; + if (INRANGE(lookup->table[imin].regval, agc_gain, + lookup->table[imax].regval)) { + while ((imax - imin) > 1) { + i = (imax + imin) >> 1; - rf_lvl = (((s32)agc_gain - lookup->table[imin].regval) - * (lookup->table[imax].realval - lookup->table[imin].realval) - / (lookup->table[imax].regval - lookup->table[imin].regval)) - + lookup->table[imin].realval; - } else if (agc_gain > lookup->table[0].regval) - rf_lvl = 5; - else if (agc_gain < lookup->table[lookup->size-1].regval) - rf_lvl = -100; + if (INRANGE(lookup->table[imin].regval, + agc_gain, + lookup->table[i].regval)) + imax = i; + else + imin = i; + } - } + rf_lvl = (s32)agc_gain - lookup->table[imin].regval; + rf_lvl *= (lookup->table[imax].realval - + lookup->table[imin].realval); + rf_lvl /= (lookup->table[imax].regval - + lookup->table[imin].regval); + rf_lvl += lookup->table[imin].realval; + } else if (agc_gain > lookup->table[0].regval) + rf_lvl = 5; + else if (agc_gain < lookup->table[lookup->size-1].regval) + rf_lvl = -100; dprintk("%s: RFLevel = %d\n", __func__, rf_lvl); @@ -648,45 +635,39 @@ static int stv0900_read_signal_strength(struct dvb_frontend *fe, u16 *strength) return 0; } - static s32 stv0900_carr_get_quality(struct dvb_frontend *fe, const struct stv0900_table *lookup) { struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; + struct stv0900_internal *intp = state->internal; enum fe_stv0900_demod_num demod = state->demod; - s32 c_n = -100, - regval, imin, imax, + s32 c_n = -100, + regval, + imin, + imax, i, - lock_flag_field, noise_field1, noise_field0; dprintk("%s\n", __func__); - dmd_reg(lock_flag_field, F0900_P1_LOCK_DEFINITIF, - F0900_P2_LOCK_DEFINITIF); if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) { - dmd_reg(noise_field1, F0900_P1_NOSPLHT_NORMED1, - F0900_P2_NOSPLHT_NORMED1); - dmd_reg(noise_field0, F0900_P1_NOSPLHT_NORMED0, - F0900_P2_NOSPLHT_NORMED0); + noise_field1 = NOSPLHT_NORMED1; + noise_field0 = NOSPLHT_NORMED0; } else { - dmd_reg(noise_field1, F0900_P1_NOSDATAT_NORMED1, - F0900_P2_NOSDATAT_NORMED1); - dmd_reg(noise_field0, F0900_P1_NOSDATAT_NORMED0, - F0900_P2_NOSDATAT_NORMED0); + noise_field1 = NOSDATAT_NORMED1; + noise_field0 = NOSDATAT_NORMED0; } - if (stv0900_get_bits(i_params, lock_flag_field)) { + if (stv0900_get_bits(intp, LOCK_DEFINITIF)) { if ((lookup != NULL) && lookup->size) { regval = 0; msleep(5); for (i = 0; i < 16; i++) { - regval += MAKEWORD(stv0900_get_bits(i_params, + regval += MAKEWORD(stv0900_get_bits(intp, noise_field1), - stv0900_get_bits(i_params, + stv0900_get_bits(intp, noise_field0)); msleep(1); } @@ -718,18 +699,15 @@ static s32 stv0900_carr_get_quality(struct dvb_frontend *fe, } } - dprintk("%s: Quality = %d\n", __func__, c_n); - return c_n; } static int stv0900_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks) { struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; + struct stv0900_internal *intp = state->internal; enum fe_stv0900_demod_num demod = state->demod; u8 err_val1, err_val0; - s32 err_field1, err_field0; u32 header_err_val = 0; *ucblocks = 0x0; @@ -737,24 +715,14 @@ static int stv0900_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks) /* DVB-S2 delineator errors count */ /* retreiving number for errnous headers */ - dmd_reg(err_field0, R0900_P1_BBFCRCKO0, - R0900_P2_BBFCRCKO0); - dmd_reg(err_field1, R0900_P1_BBFCRCKO1, - R0900_P2_BBFCRCKO1); - - err_val1 = stv0900_read_reg(i_params, err_field1); - err_val0 = stv0900_read_reg(i_params, err_field0); - header_err_val = (err_val1<<8) | err_val0; + err_val1 = stv0900_read_reg(intp, BBFCRCKO1); + err_val0 = stv0900_read_reg(intp, BBFCRCKO0); + header_err_val = (err_val1 << 8) | err_val0; /* retreiving number for errnous packets */ - dmd_reg(err_field0, R0900_P1_UPCRCKO0, - R0900_P2_UPCRCKO0); - dmd_reg(err_field1, R0900_P1_UPCRCKO1, - R0900_P2_UPCRCKO1); - - err_val1 = stv0900_read_reg(i_params, err_field1); - err_val0 = stv0900_read_reg(i_params, err_field0); - *ucblocks = (err_val1<<8) | err_val0; + err_val1 = stv0900_read_reg(intp, UPCRCKO1); + err_val0 = stv0900_read_reg(intp, UPCRCKO0); + *ucblocks = (err_val1 << 8) | err_val0; *ucblocks += header_err_val; } @@ -777,25 +745,13 @@ static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr) return 0; } -static u32 stv0900_get_ber(struct stv0900_internal *i_params, +static u32 stv0900_get_ber(struct stv0900_internal *intp, enum fe_stv0900_demod_num demod) { u32 ber = 10000000, i; - s32 dmd_state_reg; s32 demod_state; - s32 vstatus_reg; - s32 prvit_field; - s32 pdel_status_reg; - s32 pdel_lock_field; - - dmd_reg(dmd_state_reg, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); - dmd_reg(vstatus_reg, R0900_P1_VSTATUSVIT, R0900_P2_VSTATUSVIT); - dmd_reg(prvit_field, F0900_P1_PRFVIT, F0900_P2_PRFVIT); - dmd_reg(pdel_status_reg, R0900_P1_PDELSTATUS1, R0900_P2_PDELSTATUS1); - dmd_reg(pdel_lock_field, F0900_P1_PKTDELIN_LOCK, - F0900_P2_PKTDELIN_LOCK); - demod_state = stv0900_get_bits(i_params, dmd_state_reg); + demod_state = stv0900_get_bits(intp, HEADER_MODE); switch (demod_state) { case STV0900_SEARCH: @@ -807,11 +763,11 @@ static u32 stv0900_get_ber(struct stv0900_internal *i_params, ber = 0; for (i = 0; i < 5; i++) { msleep(5); - ber += stv0900_get_err_count(i_params, 0, demod); + ber += stv0900_get_err_count(intp, 0, demod); } ber /= 5; - if (stv0900_get_bits(i_params, prvit_field)) { + if (stv0900_get_bits(intp, PRFVIT)) { ber *= 9766; ber = ber >> 13; } @@ -821,11 +777,11 @@ static u32 stv0900_get_ber(struct stv0900_internal *i_params, ber = 0; for (i = 0; i < 5; i++) { msleep(5); - ber += stv0900_get_err_count(i_params, 0, demod); + ber += stv0900_get_err_count(intp, 0, demod); } ber /= 5; - if (stv0900_get_bits(i_params, pdel_lock_field)) { + if (stv0900_get_bits(intp, PKTDELIN_LOCK)) { ber *= 9766; ber = ber >> 13; } @@ -846,20 +802,16 @@ static int stv0900_read_ber(struct dvb_frontend *fe, u32 *ber) return 0; } -int stv0900_get_demod_lock(struct stv0900_internal *i_params, +int stv0900_get_demod_lock(struct stv0900_internal *intp, enum fe_stv0900_demod_num demod, s32 time_out) { s32 timer = 0, - lock = 0, - header_field, - lock_field; + lock = 0; enum fe_stv0900_search_state dmd_state; - dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); - dmd_reg(lock_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF); while ((timer < time_out) && (lock == 0)) { - dmd_state = stv0900_get_bits(i_params, header_field); + dmd_state = stv0900_get_bits(intp, HEADER_MODE); dprintk("Demod State = %d\n", dmd_state); switch (dmd_state) { case STV0900_SEARCH: @@ -869,7 +821,7 @@ int stv0900_get_demod_lock(struct stv0900_internal *i_params, break; case STV0900_DVBS2_FOUND: case STV0900_DVBS_FOUND: - lock = stv0900_get_bits(i_params, lock_field); + lock = stv0900_get_bits(intp, LOCK_DEFINITIF); break; } @@ -887,7 +839,7 @@ int stv0900_get_demod_lock(struct stv0900_internal *i_params, return lock; } -void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params, +void stv0900_stop_all_s2_modcod(struct stv0900_internal *intp, enum fe_stv0900_demod_num demod) { s32 regflist, @@ -895,48 +847,32 @@ void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params, dprintk("%s\n", __func__); - dmd_reg(regflist, R0900_P1_MODCODLST0, R0900_P2_MODCODLST0); + regflist = MODCODLST0; for (i = 0; i < 16; i++) - stv0900_write_reg(i_params, regflist + i, 0xff); + stv0900_write_reg(intp, regflist + i, 0xff); } -void stv0900_activate_s2_modcode(struct stv0900_internal *i_params, +void stv0900_activate_s2_modcod(struct stv0900_internal *intp, enum fe_stv0900_demod_num demod) { u32 matype, - mod_code, - fmod, - reg_index, - field_index; + mod_code, + fmod, + reg_index, + field_index; dprintk("%s\n", __func__); - if (i_params->chip_id <= 0x11) { + if (intp->chip_id <= 0x11) { msleep(5); - switch (demod) { - case STV0900_DEMOD_1: - default: - mod_code = stv0900_read_reg(i_params, - R0900_P1_PLHMODCOD); - matype = mod_code & 0x3; - mod_code = (mod_code & 0x7f) >> 2; - - reg_index = R0900_P1_MODCODLSTF - mod_code / 2; - field_index = mod_code % 2; - break; - case STV0900_DEMOD_2: - mod_code = stv0900_read_reg(i_params, - R0900_P2_PLHMODCOD); - matype = mod_code & 0x3; - mod_code = (mod_code & 0x7f) >> 2; - - reg_index = R0900_P2_MODCODLSTF - mod_code / 2; - field_index = mod_code % 2; - break; - } + mod_code = stv0900_read_reg(intp, PLHMODCOD); + matype = mod_code & 0x3; + mod_code = (mod_code & 0x7f) >> 2; + reg_index = MODCODLSTF - mod_code / 2; + field_index = mod_code % 2; switch (matype) { case 0: @@ -955,70 +891,41 @@ void stv0900_activate_s2_modcode(struct stv0900_internal *i_params, } if ((INRANGE(STV0900_QPSK_12, mod_code, STV0900_8PSK_910)) - && (matype <= 1)) { + && (matype <= 1)) { if (field_index == 0) - stv0900_write_reg(i_params, reg_index, + stv0900_write_reg(intp, reg_index, 0xf0 | fmod); else - stv0900_write_reg(i_params, reg_index, + stv0900_write_reg(intp, reg_index, (fmod << 4) | 0xf); } - } else if (i_params->chip_id >= 0x12) { - switch (demod) { - case STV0900_DEMOD_1: - default: - for (reg_index = 0; reg_index < 7; reg_index++) - stv0900_write_reg(i_params, R0900_P1_MODCODLST0 + reg_index, 0xff); - - stv0900_write_reg(i_params, R0900_P1_MODCODLSTE, 0xff); - stv0900_write_reg(i_params, R0900_P1_MODCODLSTF, 0xcf); - for (reg_index = 0; reg_index < 8; reg_index++) - stv0900_write_reg(i_params, R0900_P1_MODCODLST7 + reg_index, 0xcc); - break; - case STV0900_DEMOD_2: - for (reg_index = 0; reg_index < 7; reg_index++) - stv0900_write_reg(i_params, R0900_P2_MODCODLST0 + reg_index, 0xff); + } else if (intp->chip_id >= 0x12) { + for (reg_index = 0; reg_index < 7; reg_index++) + stv0900_write_reg(intp, MODCODLST0 + reg_index, 0xff); - stv0900_write_reg(i_params, R0900_P2_MODCODLSTE, 0xff); - stv0900_write_reg(i_params, R0900_P2_MODCODLSTF, 0xcf); - for (reg_index = 0; reg_index < 8; reg_index++) - stv0900_write_reg(i_params, R0900_P2_MODCODLST7 + reg_index, 0xcc); + stv0900_write_reg(intp, MODCODLSTE, 0xff); + stv0900_write_reg(intp, MODCODLSTF, 0xcf); + for (reg_index = 0; reg_index < 8; reg_index++) + stv0900_write_reg(intp, MODCODLST7 + reg_index, 0xcc); - break; - } } } -void stv0900_activate_s2_modcode_single(struct stv0900_internal *i_params, +void stv0900_activate_s2_modcod_single(struct stv0900_internal *intp, enum fe_stv0900_demod_num demod) { u32 reg_index; dprintk("%s\n", __func__); - switch (demod) { - case STV0900_DEMOD_1: - default: - stv0900_write_reg(i_params, R0900_P1_MODCODLST0, 0xff); - stv0900_write_reg(i_params, R0900_P1_MODCODLST1, 0xf0); - stv0900_write_reg(i_params, R0900_P1_MODCODLSTF, 0x0f); - for (reg_index = 0; reg_index < 13; reg_index++) - stv0900_write_reg(i_params, - R0900_P1_MODCODLST2 + reg_index, 0); - - break; - case STV0900_DEMOD_2: - stv0900_write_reg(i_params, R0900_P2_MODCODLST0, 0xff); - stv0900_write_reg(i_params, R0900_P2_MODCODLST1, 0xf0); - stv0900_write_reg(i_params, R0900_P2_MODCODLSTF, 0x0f); - for (reg_index = 0; reg_index < 13; reg_index++) - stv0900_write_reg(i_params, - R0900_P2_MODCODLST2 + reg_index, 0); + stv0900_write_reg(intp, MODCODLST0, 0xff); + stv0900_write_reg(intp, MODCODLST1, 0xf0); + stv0900_write_reg(intp, MODCODLSTF, 0x0f); + for (reg_index = 0; reg_index < 13; reg_index++) + stv0900_write_reg(intp, MODCODLST2 + reg_index, 0); - break; - } } static enum dvbfe_algo stv0900_frontend_algo(struct dvb_frontend *fe) @@ -1042,161 +949,118 @@ static int stb0900_get_property(struct dvb_frontend *fe, return 0; } -void stv0900_start_search(struct stv0900_internal *i_params, +void stv0900_start_search(struct stv0900_internal *intp, enum fe_stv0900_demod_num demod) { - - switch (demod) { - case STV0900_DEMOD_1: - default: - stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x1f); - - if (i_params->chip_id == 0x10) - stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0xaa); - - if (i_params->chip_id < 0x20) - stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x55); - - if (i_params->dmd1_symbol_rate <= 5000000) { - stv0900_write_reg(i_params, R0900_P1_CARCFG, 0x44); - stv0900_write_reg(i_params, R0900_P1_CFRUP1, 0x0f); - stv0900_write_reg(i_params, R0900_P1_CFRUP0, 0xff); - stv0900_write_reg(i_params, R0900_P1_CFRLOW1, 0xf0); - stv0900_write_reg(i_params, R0900_P1_CFRLOW0, 0x00); - stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x68); + u32 freq; + s16 freq_s16 ; + + stv0900_write_bits(intp, DEMOD_MODE, 0x1f); + if (intp->chip_id == 0x10) + stv0900_write_reg(intp, CORRELEXP, 0xaa); + + if (intp->chip_id < 0x20) + stv0900_write_reg(intp, CARHDR, 0x55); + + if (intp->chip_id <= 0x20) { + if (intp->symbol_rate[0] <= 5000000) { + stv0900_write_reg(intp, CARCFG, 0x44); + stv0900_write_reg(intp, CFRUP1, 0x0f); + stv0900_write_reg(intp, CFRUP0, 0xff); + stv0900_write_reg(intp, CFRLOW1, 0xf0); + stv0900_write_reg(intp, CFRLOW0, 0x00); + stv0900_write_reg(intp, RTCS2, 0x68); } else { - stv0900_write_reg(i_params, R0900_P1_CARCFG, 0xc4); - stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x44); + stv0900_write_reg(intp, CARCFG, 0xc4); + stv0900_write_reg(intp, RTCS2, 0x44); } - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0); - - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P1_EQUALCFG, 0x41); - stv0900_write_reg(i_params, R0900_P1_FFECFG, 0x41); - - if ((i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS1) || (i_params->dmd1_srch_standard == STV0900_SEARCH_DSS) || (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH)) { - stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x82); - stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0); - } - } - - stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x00); - stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0xe0); - stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0xc0); - stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); - stv0900_write_bits(i_params, F0900_P1_S1S2_SEQUENTIAL, 0); - stv0900_write_reg(i_params, R0900_P1_RTC, 0x88); - if (i_params->chip_id >= 0x20) { - if (i_params->dmd1_symbol_rate < 2000000) { - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x39); - stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x40); - } - - if (i_params->dmd1_symbol_rate < 10000000) { - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x4c); - stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x20); - } else { - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x4b); - stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x20); - } + } else { /*cut 3.0 above*/ + if (intp->symbol_rate[demod] <= 5000000) + stv0900_write_reg(intp, RTCS2, 0x68); + else + stv0900_write_reg(intp, RTCS2, 0x44); + stv0900_write_reg(intp, CARCFG, 0x46); + if (intp->srch_algo[demod] == STV0900_WARM_START) { + freq = 1000 << 16; + freq /= (intp->mclk / 1000); + freq_s16 = (s16)freq; } else { - if (i_params->dmd1_symbol_rate < 10000000) - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xef); + freq = (intp->srch_range[demod] / 2000); + if (intp->symbol_rate[demod] <= 5000000) + freq += 80; else - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed); - } - - switch (i_params->dmd1_srch_algo) { - case STV0900_WARM_START: - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); - break; - case STV0900_COLD_START: - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15); - break; - default: - break; - } + freq += 600; - break; - case STV0900_DEMOD_2: - stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x1f); - if (i_params->chip_id == 0x10) - stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0xaa); - - if (i_params->chip_id < 0x20) - stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55); - - if (i_params->dmd2_symbol_rate <= 5000000) { - stv0900_write_reg(i_params, R0900_P2_CARCFG, 0x44); - stv0900_write_reg(i_params, R0900_P2_CFRUP1, 0x0f); - stv0900_write_reg(i_params, R0900_P2_CFRUP0, 0xff); - stv0900_write_reg(i_params, R0900_P2_CFRLOW1, 0xf0); - stv0900_write_reg(i_params, R0900_P2_CFRLOW0, 0x00); - stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x68); - } else { - stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xc4); - stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44); + freq = freq << 16; + freq /= (intp->mclk / 1000); + freq_s16 = (s16)freq; } - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0); + stv0900_write_bits(intp, CFR_UP1, MSB(freq_s16)); + stv0900_write_bits(intp, CFR_UP0, LSB(freq_s16)); + freq_s16 *= (-1); + stv0900_write_bits(intp, CFR_LOW1, MSB(freq_s16)); + stv0900_write_bits(intp, CFR_LOW0, LSB(freq_s16)); + } - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P2_EQUALCFG, 0x41); - stv0900_write_reg(i_params, R0900_P2_FFECFG, 0x41); - if ((i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS1) || (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DSS) || (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH)) { - stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x82); - stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0); - } - } + stv0900_write_reg(intp, CFRINIT1, 0); + stv0900_write_reg(intp, CFRINIT0, 0); - stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x00); - stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0xe0); - stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0xc0); - stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); - stv0900_write_bits(i_params, F0900_P2_S1S2_SEQUENTIAL, 0); - stv0900_write_reg(i_params, R0900_P2_RTC, 0x88); - if (i_params->chip_id >= 0x20) { - if (i_params->dmd2_symbol_rate < 2000000) { - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x39); - stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x40); - } + if (intp->chip_id >= 0x20) { + stv0900_write_reg(intp, EQUALCFG, 0x41); + stv0900_write_reg(intp, FFECFG, 0x41); - if (i_params->dmd2_symbol_rate < 10000000) { - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x4c); - stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x20); - } else { - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x4b); - stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x20); - } + if ((intp->srch_standard[demod] == STV0900_SEARCH_DVBS1) || + (intp->srch_standard[demod] == STV0900_SEARCH_DSS) || + (intp->srch_standard[demod] == STV0900_AUTO_SEARCH)) { + stv0900_write_reg(intp, VITSCALE, + 0x82); + stv0900_write_reg(intp, VAVSRVIT, 0x0); + } + } + stv0900_write_reg(intp, SFRSTEP, 0x00); + stv0900_write_reg(intp, TMGTHRISE, 0xe0); + stv0900_write_reg(intp, TMGTHFALL, 0xc0); + stv0900_write_bits(intp, SCAN_ENABLE, 0); + stv0900_write_bits(intp, CFR_AUTOSCAN, 0); + stv0900_write_bits(intp, S1S2_SEQUENTIAL, 0); + stv0900_write_reg(intp, RTC, 0x88); + if (intp->chip_id >= 0x20) { + if (intp->symbol_rate[demod] < 2000000) { + if (intp->chip_id <= 0x20) + stv0900_write_reg(intp, CARFREQ, 0x39); + else /*cut 3.0*/ + stv0900_write_reg(intp, CARFREQ, 0x89); + + stv0900_write_reg(intp, CARHDR, 0x40); + } else if (intp->symbol_rate[demod] < 10000000) { + stv0900_write_reg(intp, CARFREQ, 0x4c); + stv0900_write_reg(intp, CARHDR, 0x20); } else { - if (i_params->dmd2_symbol_rate < 10000000) - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xef); - else - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed); + stv0900_write_reg(intp, CARFREQ, 0x4b); + stv0900_write_reg(intp, CARHDR, 0x20); } - switch (i_params->dmd2_srch_algo) { - case STV0900_WARM_START: - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); - break; - case STV0900_COLD_START: - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15); - break; - default: - break; - } + } else { + if (intp->symbol_rate[demod] < 10000000) + stv0900_write_reg(intp, CARFREQ, 0xef); + else + stv0900_write_reg(intp, CARFREQ, 0xed); + } + switch (intp->srch_algo[demod]) { + case STV0900_WARM_START: + stv0900_write_reg(intp, DMDISTATE, 0x1f); + stv0900_write_reg(intp, DMDISTATE, 0x18); + break; + case STV0900_COLD_START: + stv0900_write_reg(intp, DMDISTATE, 0x1f); + stv0900_write_reg(intp, DMDISTATE, 0x15); + break; + default: break; } } @@ -1205,33 +1069,40 @@ u8 stv0900_get_optim_carr_loop(s32 srate, enum fe_stv0900_modcode modcode, s32 pilot, u8 chip_id) { u8 aclc_value = 0x29; - s32 i; - const struct stv0900_car_loop_optim *car_loop_s2; + s32 i; + const struct stv0900_car_loop_optim *cls2, *cllqs2, *cllas2; dprintk("%s\n", __func__); - if (chip_id <= 0x12) - car_loop_s2 = FE_STV0900_S2CarLoop; - else if (chip_id == 0x20) - car_loop_s2 = FE_STV0900_S2CarLoopCut20; - else - car_loop_s2 = FE_STV0900_S2CarLoop; + if (chip_id <= 0x12) { + cls2 = FE_STV0900_S2CarLoop; + cllqs2 = FE_STV0900_S2LowQPCarLoopCut30; + cllas2 = FE_STV0900_S2APSKCarLoopCut30; + } else if (chip_id == 0x20) { + cls2 = FE_STV0900_S2CarLoopCut20; + cllqs2 = FE_STV0900_S2LowQPCarLoopCut20; + cllas2 = FE_STV0900_S2APSKCarLoopCut20; + } else { + cls2 = FE_STV0900_S2CarLoopCut30; + cllqs2 = FE_STV0900_S2LowQPCarLoopCut30; + cllas2 = FE_STV0900_S2APSKCarLoopCut30; + } if (modcode < STV0900_QPSK_12) { i = 0; - while ((i < 3) && (modcode != FE_STV0900_S2LowQPCarLoopCut20[i].modcode)) + while ((i < 3) && (modcode != cllqs2[i].modcode)) i++; if (i >= 3) i = 2; } else { i = 0; - while ((i < 14) && (modcode != car_loop_s2[i].modcode)) + while ((i < 14) && (modcode != cls2[i].modcode)) i++; if (i >= 14) { i = 0; - while ((i < 11) && (modcode != FE_STV0900_S2APSKCarLoopCut20[i].modcode)) + while ((i < 11) && (modcode != cllas2[i].modcode)) i++; if (i >= 11) @@ -1242,77 +1113,83 @@ u8 stv0900_get_optim_carr_loop(s32 srate, enum fe_stv0900_modcode modcode, if (modcode <= STV0900_QPSK_25) { if (pilot) { if (srate <= 3000000) - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_2; + aclc_value = cllqs2[i].car_loop_pilots_on_2; else if (srate <= 7000000) - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_5; + aclc_value = cllqs2[i].car_loop_pilots_on_5; else if (srate <= 15000000) - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_10; + aclc_value = cllqs2[i].car_loop_pilots_on_10; else if (srate <= 25000000) - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_20; + aclc_value = cllqs2[i].car_loop_pilots_on_20; else - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_30; + aclc_value = cllqs2[i].car_loop_pilots_on_30; } else { if (srate <= 3000000) - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_2; + aclc_value = cllqs2[i].car_loop_pilots_off_2; else if (srate <= 7000000) - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_5; + aclc_value = cllqs2[i].car_loop_pilots_off_5; else if (srate <= 15000000) - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_10; + aclc_value = cllqs2[i].car_loop_pilots_off_10; else if (srate <= 25000000) - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_20; + aclc_value = cllqs2[i].car_loop_pilots_off_20; else - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_30; + aclc_value = cllqs2[i].car_loop_pilots_off_30; } } else if (modcode <= STV0900_8PSK_910) { if (pilot) { if (srate <= 3000000) - aclc_value = car_loop_s2[i].car_loop_pilots_on_2; + aclc_value = cls2[i].car_loop_pilots_on_2; else if (srate <= 7000000) - aclc_value = car_loop_s2[i].car_loop_pilots_on_5; + aclc_value = cls2[i].car_loop_pilots_on_5; else if (srate <= 15000000) - aclc_value = car_loop_s2[i].car_loop_pilots_on_10; + aclc_value = cls2[i].car_loop_pilots_on_10; else if (srate <= 25000000) - aclc_value = car_loop_s2[i].car_loop_pilots_on_20; + aclc_value = cls2[i].car_loop_pilots_on_20; else - aclc_value = car_loop_s2[i].car_loop_pilots_on_30; + aclc_value = cls2[i].car_loop_pilots_on_30; } else { if (srate <= 3000000) - aclc_value = car_loop_s2[i].car_loop_pilots_off_2; + aclc_value = cls2[i].car_loop_pilots_off_2; else if (srate <= 7000000) - aclc_value = car_loop_s2[i].car_loop_pilots_off_5; + aclc_value = cls2[i].car_loop_pilots_off_5; else if (srate <= 15000000) - aclc_value = car_loop_s2[i].car_loop_pilots_off_10; + aclc_value = cls2[i].car_loop_pilots_off_10; else if (srate <= 25000000) - aclc_value = car_loop_s2[i].car_loop_pilots_off_20; + aclc_value = cls2[i].car_loop_pilots_off_20; else - aclc_value = car_loop_s2[i].car_loop_pilots_off_30; + aclc_value = cls2[i].car_loop_pilots_off_30; } } else { if (srate <= 3000000) - aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_2; + aclc_value = cllas2[i].car_loop_pilots_on_2; else if (srate <= 7000000) - aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_5; + aclc_value = cllas2[i].car_loop_pilots_on_5; else if (srate <= 15000000) - aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_10; + aclc_value = cllas2[i].car_loop_pilots_on_10; else if (srate <= 25000000) - aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_20; + aclc_value = cllas2[i].car_loop_pilots_on_20; else - aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_30; + aclc_value = cllas2[i].car_loop_pilots_on_30; } return aclc_value; } -u8 stv0900_get_optim_short_carr_loop(s32 srate, enum fe_stv0900_modulation modulation, u8 chip_id) +u8 stv0900_get_optim_short_carr_loop(s32 srate, + enum fe_stv0900_modulation modulation, + u8 chip_id) { + const struct stv0900_short_frames_car_loop_optim *s2scl; + const struct stv0900_short_frames_car_loop_optim_vs_mod *s2sclc30; s32 mod_index = 0; - u8 aclc_value = 0x0b; dprintk("%s\n", __func__); + s2scl = FE_STV0900_S2ShortCarLoop; + s2sclc30 = FE_STV0900_S2ShortCarLoopCut30; + switch (modulation) { case STV0900_QPSK: default: @@ -1329,75 +1206,116 @@ u8 stv0900_get_optim_short_carr_loop(s32 srate, enum fe_stv0900_modulation modul break; } - switch (chip_id) { - case 0x20: + if (chip_id >= 0x30) { if (srate <= 3000000) - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_2; + aclc_value = s2sclc30[mod_index].car_loop_2; else if (srate <= 7000000) - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_5; + aclc_value = s2sclc30[mod_index].car_loop_5; else if (srate <= 15000000) - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_10; + aclc_value = s2sclc30[mod_index].car_loop_10; else if (srate <= 25000000) - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_20; + aclc_value = s2sclc30[mod_index].car_loop_20; else - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_30; + aclc_value = s2sclc30[mod_index].car_loop_30; - break; - case 0x12: - default: + } else if (chip_id >= 0x20) { if (srate <= 3000000) - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_2; + aclc_value = s2scl[mod_index].car_loop_cut20_2; else if (srate <= 7000000) - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_5; + aclc_value = s2scl[mod_index].car_loop_cut20_5; else if (srate <= 15000000) - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_10; + aclc_value = s2scl[mod_index].car_loop_cut20_10; else if (srate <= 25000000) - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_20; + aclc_value = s2scl[mod_index].car_loop_cut20_20; else - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_30; + aclc_value = s2scl[mod_index].car_loop_cut20_30; + + } else { + if (srate <= 3000000) + aclc_value = s2scl[mod_index].car_loop_cut12_2; + else if (srate <= 7000000) + aclc_value = s2scl[mod_index].car_loop_cut12_5; + else if (srate <= 15000000) + aclc_value = s2scl[mod_index].car_loop_cut12_10; + else if (srate <= 25000000) + aclc_value = s2scl[mod_index].car_loop_cut12_20; + else + aclc_value = s2scl[mod_index].car_loop_cut12_30; - break; } return aclc_value; } -static enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *i_params, +static +enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *intp, enum fe_stv0900_demod_mode LDPC_Mode, enum fe_stv0900_demod_num demod) { enum fe_stv0900_error error = STV0900_NO_ERROR; + s32 reg_ind; dprintk("%s\n", __func__); switch (LDPC_Mode) { case STV0900_DUAL: default: - if ((i_params->demod_mode != STV0900_DUAL) - || (stv0900_get_bits(i_params, F0900_DDEMOD) != 1)) { - stv0900_write_reg(i_params, R0900_GENCFG, 0x1d); - - i_params->demod_mode = STV0900_DUAL; - - stv0900_write_bits(i_params, F0900_FRESFEC, 1); - stv0900_write_bits(i_params, F0900_FRESFEC, 0); + if ((intp->demod_mode != STV0900_DUAL) + || (stv0900_get_bits(intp, F0900_DDEMOD) != 1)) { + stv0900_write_reg(intp, R0900_GENCFG, 0x1d); + + intp->demod_mode = STV0900_DUAL; + + stv0900_write_bits(intp, F0900_FRESFEC, 1); + stv0900_write_bits(intp, F0900_FRESFEC, 0); + + for (reg_ind = 0; reg_ind < 7; reg_ind++) + stv0900_write_reg(intp, + R0900_P1_MODCODLST0 + reg_ind, + 0xff); + for (reg_ind = 0; reg_ind < 8; reg_ind++) + stv0900_write_reg(intp, + R0900_P1_MODCODLST7 + reg_ind, + 0xcc); + + stv0900_write_reg(intp, R0900_P1_MODCODLSTE, 0xff); + stv0900_write_reg(intp, R0900_P1_MODCODLSTF, 0xcf); + + for (reg_ind = 0; reg_ind < 7; reg_ind++) + stv0900_write_reg(intp, + R0900_P2_MODCODLST0 + reg_ind, + 0xff); + for (reg_ind = 0; reg_ind < 8; reg_ind++) + stv0900_write_reg(intp, + R0900_P2_MODCODLST7 + reg_ind, + 0xcc); + + stv0900_write_reg(intp, R0900_P2_MODCODLSTE, 0xff); + stv0900_write_reg(intp, R0900_P2_MODCODLSTF, 0xcf); } break; case STV0900_SINGLE: - if (demod == STV0900_DEMOD_2) - stv0900_write_reg(i_params, R0900_GENCFG, 0x06); - else - stv0900_write_reg(i_params, R0900_GENCFG, 0x04); + if (demod == STV0900_DEMOD_2) { + stv0900_stop_all_s2_modcod(intp, STV0900_DEMOD_1); + stv0900_activate_s2_modcod_single(intp, + STV0900_DEMOD_2); + stv0900_write_reg(intp, R0900_GENCFG, 0x06); + } else { + stv0900_stop_all_s2_modcod(intp, STV0900_DEMOD_2); + stv0900_activate_s2_modcod_single(intp, + STV0900_DEMOD_1); + stv0900_write_reg(intp, R0900_GENCFG, 0x04); + } - i_params->demod_mode = STV0900_SINGLE; + intp->demod_mode = STV0900_SINGLE; - stv0900_write_bits(i_params, F0900_FRESFEC, 1); - stv0900_write_bits(i_params, F0900_FRESFEC, 0); - stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 1); - stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 0); - stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 1); - stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 0); + stv0900_write_bits(intp, F0900_FRESFEC, 1); + stv0900_write_bits(intp, F0900_FRESFEC, 0); + stv0900_write_bits(intp, F0900_P1_ALGOSWRST, 1); + stv0900_write_bits(intp, F0900_P1_ALGOSWRST, 0); + stv0900_write_bits(intp, F0900_P2_ALGOSWRST, 1); + stv0900_write_bits(intp, F0900_P2_ALGOSWRST, 0); break; } @@ -1410,6 +1328,8 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe, struct stv0900_state *state = fe->demodulator_priv; enum fe_stv0900_error error = STV0900_NO_ERROR; enum fe_stv0900_error demodError = STV0900_NO_ERROR; + struct stv0900_internal *intp = NULL; + int selosci, i; struct stv0900_inode *temp_int = find_inode(state->i2c_adap, @@ -1423,7 +1343,8 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe, dprintk("%s: Find Internal Structure!\n", __func__); return STV0900_NO_ERROR; } else { - state->internal = kmalloc(sizeof(struct stv0900_internal), GFP_KERNEL); + state->internal = kmalloc(sizeof(struct stv0900_internal), + GFP_KERNEL); temp_int = append_internal(state->internal); state->internal->dmds_used = 1; state->internal->i2c_adap = state->i2c_adap; @@ -1433,108 +1354,105 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe, dprintk("%s: Create New Internal Structure!\n", __func__); } - if (state->internal != NULL) { - demodError = stv0900_initialize(state->internal); - if (demodError == STV0900_NO_ERROR) { - error = STV0900_NO_ERROR; - } else { - if (demodError == STV0900_INVALID_HANDLE) - error = STV0900_INVALID_HANDLE; - else - error = STV0900_I2C_ERROR; - } + if (state->internal == NULL) { + error = STV0900_INVALID_HANDLE; + return error; + } - if (state->internal != NULL) { - if (error == STV0900_NO_ERROR) { - state->internal->demod_mode = p_init->demod_mode; - - stv0900_st_dvbs2_single(state->internal, state->internal->demod_mode, STV0900_DEMOD_1); - - state->internal->chip_id = stv0900_read_reg(state->internal, R0900_MID); - state->internal->rolloff = p_init->rolloff; - state->internal->quartz = p_init->dmd_ref_clk; - - stv0900_write_bits(state->internal, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff); - stv0900_write_bits(state->internal, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff); - - state->internal->ts_config = p_init->ts_config; - if (state->internal->ts_config == NULL) - stv0900_set_ts_parallel_serial(state->internal, - p_init->path1_ts_clock, - p_init->path2_ts_clock); - else { - for (i = 0; state->internal->ts_config[i].addr != 0xffff; i++) - stv0900_write_reg(state->internal, - state->internal->ts_config[i].addr, - state->internal->ts_config[i].val); - - stv0900_write_bits(state->internal, F0900_P2_RST_HWARE, 1); - stv0900_write_bits(state->internal, F0900_P2_RST_HWARE, 0); - stv0900_write_bits(state->internal, F0900_P1_RST_HWARE, 1); - stv0900_write_bits(state->internal, F0900_P1_RST_HWARE, 0); - } + demodError = stv0900_initialize(state->internal); + if (demodError == STV0900_NO_ERROR) { + error = STV0900_NO_ERROR; + } else { + if (demodError == STV0900_INVALID_HANDLE) + error = STV0900_INVALID_HANDLE; + else + error = STV0900_I2C_ERROR; - stv0900_write_bits(state->internal, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress); - switch (p_init->tuner1_adc) { - case 1: - stv0900_write_reg(state->internal, R0900_TSTTNR1, 0x26); - break; - default: - break; - } + return error; + } - stv0900_write_bits(state->internal, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress); - switch (p_init->tuner2_adc) { - case 1: - stv0900_write_reg(state->internal, R0900_TSTTNR3, 0x26); - break; - default: - break; - } + if (state->internal == NULL) { + error = STV0900_INVALID_HANDLE; + return error; + } - stv0900_write_bits(state->internal, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inversion); - stv0900_write_bits(state->internal, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inversion); - stv0900_set_mclk(state->internal, 135000000); - msleep(3); - - switch (state->internal->clkmode) { - case 0: - case 2: - stv0900_write_reg(state->internal, R0900_SYNTCTRL, 0x20 | state->internal->clkmode); - break; - default: - selosci = 0x02 & stv0900_read_reg(state->internal, R0900_SYNTCTRL); - stv0900_write_reg(state->internal, R0900_SYNTCTRL, 0x20 | selosci); - break; - } - msleep(3); + intp = state->internal; - state->internal->mclk = stv0900_get_mclk_freq(state->internal, state->internal->quartz); - if (state->internal->errs) - error = STV0900_I2C_ERROR; - } - } else { - error = STV0900_INVALID_HANDLE; - } + intp->demod_mode = p_init->demod_mode; + stv0900_st_dvbs2_single(intp, intp->demod_mode, STV0900_DEMOD_1); + intp->chip_id = stv0900_read_reg(intp, R0900_MID); + intp->rolloff = p_init->rolloff; + intp->quartz = p_init->dmd_ref_clk; + + stv0900_write_bits(intp, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff); + stv0900_write_bits(intp, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff); + + intp->ts_config = p_init->ts_config; + if (intp->ts_config == NULL) + stv0900_set_ts_parallel_serial(intp, + p_init->path1_ts_clock, + p_init->path2_ts_clock); + else { + for (i = 0; intp->ts_config[i].addr != 0xffff; i++) + stv0900_write_reg(intp, + intp->ts_config[i].addr, + intp->ts_config[i].val); + + stv0900_write_bits(intp, F0900_P2_RST_HWARE, 1); + stv0900_write_bits(intp, F0900_P2_RST_HWARE, 0); + stv0900_write_bits(intp, F0900_P1_RST_HWARE, 1); + stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0); + } + + stv0900_write_bits(intp, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress); + switch (p_init->tuner1_adc) { + case 1: + stv0900_write_reg(intp, R0900_TSTTNR1, 0x26); + break; + default: + break; + } + + stv0900_write_bits(intp, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress); + switch (p_init->tuner2_adc) { + case 1: + stv0900_write_reg(intp, R0900_TSTTNR3, 0x26); + break; + default: + break; } + stv0900_write_bits(intp, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inv); + stv0900_write_bits(intp, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inv); + stv0900_set_mclk(intp, 135000000); + msleep(3); + + switch (intp->clkmode) { + case 0: + case 2: + stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | intp->clkmode); + break; + default: + selosci = 0x02 & stv0900_read_reg(intp, R0900_SYNTCTRL); + stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | selosci); + break; + } + msleep(3); + + intp->mclk = stv0900_get_mclk_freq(intp, intp->quartz); + if (intp->errs) + error = STV0900_I2C_ERROR; + return error; } -static int stv0900_status(struct stv0900_internal *i_params, +static int stv0900_status(struct stv0900_internal *intp, enum fe_stv0900_demod_num demod) { enum fe_stv0900_search_state demod_state; - s32 mode_field, delin_field, lock_field, fifo_field, lockedvit_field; int locked = FALSE; - dmd_reg(mode_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); - dmd_reg(lock_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF); - dmd_reg(delin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK); - dmd_reg(fifo_field, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK); - dmd_reg(lockedvit_field, F0900_P1_LOCKEDVIT, F0900_P2_LOCKEDVIT); - - demod_state = stv0900_get_bits(i_params, mode_field); + demod_state = stv0900_get_bits(intp, HEADER_MODE); switch (demod_state) { case STV0900_SEARCH: case STV0900_PLH_DETECTED: @@ -1542,17 +1460,19 @@ static int stv0900_status(struct stv0900_internal *i_params, locked = FALSE; break; case STV0900_DVBS2_FOUND: - locked = stv0900_get_bits(i_params, lock_field) && - stv0900_get_bits(i_params, delin_field) && - stv0900_get_bits(i_params, fifo_field); + locked = stv0900_get_bits(intp, LOCK_DEFINITIF) && + stv0900_get_bits(intp, PKTDELIN_LOCK) && + stv0900_get_bits(intp, TSFIFO_LINEOK); break; case STV0900_DVBS_FOUND: - locked = stv0900_get_bits(i_params, lock_field) && - stv0900_get_bits(i_params, lockedvit_field) && - stv0900_get_bits(i_params, fifo_field); + locked = stv0900_get_bits(intp, LOCK_DEFINITIF) && + stv0900_get_bits(intp, LOCKEDVIT) && + stv0900_get_bits(intp, TSFIFO_LINEOK); break; } + dprintk("%s: locked = %d\n", __func__, locked); + return locked; } @@ -1560,7 +1480,8 @@ static enum dvbfe_search stv0900_search(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; + struct stv0900_internal *intp = state->internal; + enum fe_stv0900_demod_num demod = state->demod; struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct stv0900_search_params p_search; @@ -1570,8 +1491,11 @@ static enum dvbfe_search stv0900_search(struct dvb_frontend *fe, dprintk("%s: ", __func__); + if (!(INRANGE(100000, c->symbol_rate, 70000000))) + return DVBFE_ALGO_SEARCH_FAILED; + p_result.locked = FALSE; - p_search.path = state->demod; + p_search.path = demod; p_search.frequency = c->frequency; p_search.symbol_rate = c->symbol_rate; p_search.search_range = 10000000; @@ -1580,93 +1504,38 @@ static enum dvbfe_search stv0900_search(struct dvb_frontend *fe, p_search.iq_inversion = STV0900_IQ_AUTO; p_search.search_algo = STV0900_BLIND_SEARCH; - if ((INRANGE(100000, p_search.symbol_rate, 70000000)) && - (INRANGE(100000, p_search.search_range, 50000000))) { - switch (p_search.path) { - case STV0900_DEMOD_1: - default: - i_params->dmd1_srch_standard = p_search.standard; - i_params->dmd1_symbol_rate = p_search.symbol_rate; - i_params->dmd1_srch_range = p_search.search_range; - i_params->tuner1_freq = p_search.frequency; - i_params->dmd1_srch_algo = p_search.search_algo; - i_params->dmd1_srch_iq_inv = p_search.iq_inversion; - i_params->dmd1_fec = p_search.fec; + intp->srch_standard[demod] = p_search.standard; + intp->symbol_rate[demod] = p_search.symbol_rate; + intp->srch_range[demod] = p_search.search_range; + intp->freq[demod] = p_search.frequency; + intp->srch_algo[demod] = p_search.search_algo; + intp->srch_iq_inv[demod] = p_search.iq_inversion; + intp->fec[demod] = p_search.fec; + if ((stv0900_algo(fe) == STV0900_RANGEOK) && + (intp->errs == STV0900_NO_ERROR)) { + p_result.locked = intp->result[demod].locked; + p_result.standard = intp->result[demod].standard; + p_result.frequency = intp->result[demod].frequency; + p_result.symbol_rate = intp->result[demod].symbol_rate; + p_result.fec = intp->result[demod].fec; + p_result.modcode = intp->result[demod].modcode; + p_result.pilot = intp->result[demod].pilot; + p_result.frame_len = intp->result[demod].frame_len; + p_result.spectrum = intp->result[demod].spectrum; + p_result.rolloff = intp->result[demod].rolloff; + p_result.modulation = intp->result[demod].modulation; + } else { + p_result.locked = FALSE; + switch (intp->err[demod]) { + case STV0900_I2C_ERROR: + error = STV0900_I2C_ERROR; break; - - case STV0900_DEMOD_2: - i_params->dmd2_srch_stndrd = p_search.standard; - i_params->dmd2_symbol_rate = p_search.symbol_rate; - i_params->dmd2_srch_range = p_search.search_range; - i_params->tuner2_freq = p_search.frequency; - i_params->dmd2_srch_algo = p_search.search_algo; - i_params->dmd2_srch_iq_inv = p_search.iq_inversion; - i_params->dmd2_fec = p_search.fec; + case STV0900_NO_ERROR: + default: + error = STV0900_SEARCH_FAILED; break; } - - if ((stv0900_algo(fe) == STV0900_RANGEOK) && - (i_params->errs == STV0900_NO_ERROR)) { - switch (p_search.path) { - case STV0900_DEMOD_1: - default: - p_result.locked = i_params->dmd1_rslts.locked; - p_result.standard = i_params->dmd1_rslts.standard; - p_result.frequency = i_params->dmd1_rslts.frequency; - p_result.symbol_rate = i_params->dmd1_rslts.symbol_rate; - p_result.fec = i_params->dmd1_rslts.fec; - p_result.modcode = i_params->dmd1_rslts.modcode; - p_result.pilot = i_params->dmd1_rslts.pilot; - p_result.frame_length = i_params->dmd1_rslts.frame_length; - p_result.spectrum = i_params->dmd1_rslts.spectrum; - p_result.rolloff = i_params->dmd1_rslts.rolloff; - p_result.modulation = i_params->dmd1_rslts.modulation; - break; - case STV0900_DEMOD_2: - p_result.locked = i_params->dmd2_rslts.locked; - p_result.standard = i_params->dmd2_rslts.standard; - p_result.frequency = i_params->dmd2_rslts.frequency; - p_result.symbol_rate = i_params->dmd2_rslts.symbol_rate; - p_result.fec = i_params->dmd2_rslts.fec; - p_result.modcode = i_params->dmd2_rslts.modcode; - p_result.pilot = i_params->dmd2_rslts.pilot; - p_result.frame_length = i_params->dmd2_rslts.frame_length; - p_result.spectrum = i_params->dmd2_rslts.spectrum; - p_result.rolloff = i_params->dmd2_rslts.rolloff; - p_result.modulation = i_params->dmd2_rslts.modulation; - break; - } - - } else { - p_result.locked = FALSE; - switch (p_search.path) { - case STV0900_DEMOD_1: - switch (i_params->dmd1_err) { - case STV0900_I2C_ERROR: - error = STV0900_I2C_ERROR; - break; - case STV0900_NO_ERROR: - default: - error = STV0900_SEARCH_FAILED; - break; - } - break; - case STV0900_DEMOD_2: - switch (i_params->dmd2_err) { - case STV0900_I2C_ERROR: - error = STV0900_I2C_ERROR; - break; - case STV0900_NO_ERROR: - default: - error = STV0900_SEARCH_FAILED; - break; - } - break; - } - } - - } else - error = STV0900_BAD_PARAMETER; + } if ((p_result.locked == TRUE) && (error == STV0900_NO_ERROR)) { dprintk("Search Success\n"); @@ -1676,7 +1545,6 @@ static enum dvbfe_search stv0900_search(struct dvb_frontend *fe, return DVBFE_ALGO_SEARCH_FAILED; } - return DVBFE_ALGO_SEARCH_ERROR; } static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status) @@ -1707,16 +1575,13 @@ static int stv0900_stop_ts(struct dvb_frontend *fe, int stop_ts) { struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; + struct stv0900_internal *intp = state->internal; enum fe_stv0900_demod_num demod = state->demod; - s32 rst_field; - - dmd_reg(rst_field, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE); if (stop_ts == TRUE) - stv0900_write_bits(i_params, rst_field, 1); + stv0900_write_bits(intp, RST_HWARE, 1); else - stv0900_write_bits(i_params, rst_field, 0); + stv0900_write_bits(intp, RST_HWARE, 0); return 0; } @@ -1724,16 +1589,12 @@ static int stv0900_stop_ts(struct dvb_frontend *fe, int stop_ts) static int stv0900_diseqc_init(struct dvb_frontend *fe) { struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; + struct stv0900_internal *intp = state->internal; enum fe_stv0900_demod_num demod = state->demod; - s32 mode_field, reset_field; - dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE); - dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET); - - stv0900_write_bits(i_params, mode_field, state->config->diseqc_mode); - stv0900_write_bits(i_params, reset_field, 1); - stv0900_write_bits(i_params, reset_field, 0); + stv0900_write_bits(intp, DISTX_MODE, state->config->diseqc_mode); + stv0900_write_bits(intp, DISEQC_RESET, 1); + stv0900_write_bits(intp, DISEQC_RESET, 0); return 0; } @@ -1748,47 +1609,24 @@ static int stv0900_init(struct dvb_frontend *fe) return 0; } -static int stv0900_diseqc_send(struct stv0900_internal *i_params , u8 *Data, +static int stv0900_diseqc_send(struct stv0900_internal *intp , u8 *data, u32 NbData, enum fe_stv0900_demod_num demod) { s32 i = 0; - switch (demod) { - case STV0900_DEMOD_1: - default: - stv0900_write_bits(i_params, F0900_P1_DIS_PRECHARGE, 1); - while (i < NbData) { - while (stv0900_get_bits(i_params, F0900_P1_FIFO_FULL)) - ;/* checkpatch complains */ - stv0900_write_reg(i_params, R0900_P1_DISTXDATA, Data[i]); - i++; - } - - stv0900_write_bits(i_params, F0900_P1_DIS_PRECHARGE, 0); - i = 0; - while ((stv0900_get_bits(i_params, F0900_P1_TX_IDLE) != 1) && (i < 10)) { - msleep(10); - i++; - } - - break; - case STV0900_DEMOD_2: - stv0900_write_bits(i_params, F0900_P2_DIS_PRECHARGE, 1); - - while (i < NbData) { - while (stv0900_get_bits(i_params, F0900_P2_FIFO_FULL)) - ;/* checkpatch complains */ - stv0900_write_reg(i_params, R0900_P2_DISTXDATA, Data[i]); - i++; - } + stv0900_write_bits(intp, DIS_PRECHARGE, 1); + while (i < NbData) { + while (stv0900_get_bits(intp, FIFO_FULL)) + ;/* checkpatch complains */ + stv0900_write_reg(intp, DISTXDATA, data[i]); + i++; + } - stv0900_write_bits(i_params, F0900_P2_DIS_PRECHARGE, 0); - i = 0; - while ((stv0900_get_bits(i_params, F0900_P2_TX_IDLE) != 1) && (i < 10)) { - msleep(10); - i++; - } - break; + stv0900_write_bits(intp, DIS_PRECHARGE, 0); + i = 0; + while ((stv0900_get_bits(intp, TX_IDLE) != 1) && (i < 10)) { + msleep(10); + i++; } return 0; @@ -1808,23 +1646,21 @@ static int stv0900_send_master_cmd(struct dvb_frontend *fe, static int stv0900_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) { struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; + struct stv0900_internal *intp = state->internal; enum fe_stv0900_demod_num demod = state->demod; - s32 mode_field; u8 data; - dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE); switch (burst) { case SEC_MINI_A: - stv0900_write_bits(i_params, mode_field, 3);/* Unmodulated */ + stv0900_write_bits(intp, DISTX_MODE, 3);/* Unmodulated */ data = 0x00; - stv0900_diseqc_send(state->internal, &data, 1, state->demod); + stv0900_diseqc_send(intp, &data, 1, state->demod); break; case SEC_MINI_B: - stv0900_write_bits(i_params, mode_field, 2);/* Modulated */ + stv0900_write_bits(intp, DISTX_MODE, 2);/* Modulated */ data = 0xff; - stv0900_diseqc_send(state->internal, &data, 1, state->demod); + stv0900_diseqc_send(intp, &data, 1, state->demod); break; } @@ -1835,41 +1671,22 @@ static int stv0900_recv_slave_reply(struct dvb_frontend *fe, struct dvb_diseqc_slave_reply *reply) { struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; + struct stv0900_internal *intp = state->internal; + enum fe_stv0900_demod_num demod = state->demod; s32 i = 0; - switch (state->demod) { - case STV0900_DEMOD_1: - default: - reply->msg_len = 0; - - while ((stv0900_get_bits(i_params, F0900_P1_RX_END) != 1) && (i < 10)) { - msleep(10); - i++; - } - - if (stv0900_get_bits(i_params, F0900_P1_RX_END)) { - reply->msg_len = stv0900_get_bits(i_params, F0900_P1_FIFO_BYTENBR); + reply->msg_len = 0; - for (i = 0; i < reply->msg_len; i++) - reply->msg[i] = stv0900_read_reg(i_params, R0900_P1_DISRXDATA); - } - break; - case STV0900_DEMOD_2: - reply->msg_len = 0; - - while ((stv0900_get_bits(i_params, F0900_P2_RX_END) != 1) && (i < 10)) { - msleep(10); - i++; - } + while ((stv0900_get_bits(intp, RX_END) != 1) && (i < 10)) { + msleep(10); + i++; + } - if (stv0900_get_bits(i_params, F0900_P2_RX_END)) { - reply->msg_len = stv0900_get_bits(i_params, F0900_P2_FIFO_BYTENBR); + if (stv0900_get_bits(intp, RX_END)) { + reply->msg_len = stv0900_get_bits(intp, FIFO_BYTENBR); - for (i = 0; i < reply->msg_len; i++) - reply->msg[i] = stv0900_read_reg(i_params, R0900_P2_DISRXDATA); - } - break; + for (i = 0; i < reply->msg_len; i++) + reply->msg[i] = stv0900_read_reg(intp, DISRXDATA); } return 0; @@ -1878,31 +1695,27 @@ static int stv0900_recv_slave_reply(struct dvb_frontend *fe, static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t toneoff) { struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; + struct stv0900_internal *intp = state->internal; enum fe_stv0900_demod_num demod = state->demod; - s32 mode_field, reset_field; dprintk("%s: %s\n", __func__, ((toneoff == 0) ? "On" : "Off")); - dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE); - dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET); - switch (toneoff) { case SEC_TONE_ON: /*Set the DiseqC mode to 22Khz _continues_ tone*/ - stv0900_write_bits(i_params, mode_field, 0); - stv0900_write_bits(i_params, reset_field, 1); + stv0900_write_bits(intp, DISTX_MODE, 0); + stv0900_write_bits(intp, DISEQC_RESET, 1); /*release DiseqC reset to enable the 22KHz tone*/ - stv0900_write_bits(i_params, reset_field, 0); + stv0900_write_bits(intp, DISEQC_RESET, 0); break; case SEC_TONE_OFF: /*return diseqc mode to config->diseqc_mode. Usually it's without _continues_ tone */ - stv0900_write_bits(i_params, mode_field, + stv0900_write_bits(intp, DISTX_MODE, state->config->diseqc_mode); /*maintain the DiseqC reset to disable the 22KHz tone*/ - stv0900_write_bits(i_params, reset_field, 1); - stv0900_write_bits(i_params, reset_field, 0); + stv0900_write_bits(intp, DISEQC_RESET, 1); + stv0900_write_bits(intp, DISEQC_RESET, 0); break; default: return -EINVAL; @@ -1993,13 +1806,13 @@ struct dvb_frontend *stv0900_attach(const struct stv0900_config *config, init_params.rolloff = STV0900_35; init_params.path1_ts_clock = config->path1_mode; init_params.tun1_maddress = config->tun1_maddress; - init_params.tun1_iq_inversion = STV0900_IQ_NORMAL; + init_params.tun1_iq_inv = STV0900_IQ_NORMAL; init_params.tuner1_adc = config->tun1_adc; init_params.path2_ts_clock = config->path2_mode; init_params.ts_config = config->ts_config_regs; init_params.tun2_maddress = config->tun2_maddress; init_params.tuner2_adc = config->tun2_adc; - init_params.tun2_iq_inversion = STV0900_IQ_SWAPPED; + init_params.tun2_iq_inv = STV0900_IQ_SWAPPED; err_stv0900 = stv0900_init_internal(&state->frontend, &init_params); -- cgit v1.2.3-70-g09d2 From a3a4f7e167e77066b0b98b8f056efcda2d302f97 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Fri, 6 Nov 2009 23:46:32 -0300 Subject: V4L/DVB (13341): stv0900: big rework to support cut 3.0. Patch 4 of 4. Also patch changes logic to prevent code repetitions and big indents. It makes checkpatch silent :) Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0900_sw.c | 3158 +++++++++++------------------- 1 file changed, 1155 insertions(+), 2003 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv0900_sw.c b/drivers/media/dvb/frontends/stv0900_sw.c index 8c83c8b306a..b8da87fa637 100644 --- a/drivers/media/dvb/frontends/stv0900_sw.c +++ b/drivers/media/dvb/frontends/stv0900_sw.c @@ -27,56 +27,45 @@ #include "stv0900_reg.h" #include "stv0900_priv.h" -int stv0900_check_signal_presence(struct stv0900_internal *i_params, +s32 shiftx(s32 x, int demod, s32 shift) +{ + if (demod == 1) + return x - shift; + + return x; +} + +int stv0900_check_signal_presence(struct stv0900_internal *intp, enum fe_stv0900_demod_num demod) { - s32 carr_offset, - agc2_integr, - max_carrier; + s32 carr_offset, + agc2_integr, + max_carrier; - int no_signal; + int no_signal = FALSE; - switch (demod) { - case STV0900_DEMOD_1: - default: - carr_offset = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8) - | stv0900_read_reg(i_params, - R0900_P1_CFR1); - carr_offset = ge2comp(carr_offset, 16); - agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) - | stv0900_read_reg(i_params, - R0900_P1_AGC2I0); - max_carrier = i_params->dmd1_srch_range / 1000; - break; - case STV0900_DEMOD_2: - carr_offset = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8) - | stv0900_read_reg(i_params, - R0900_P2_CFR1); - carr_offset = ge2comp(carr_offset, 16); - agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8) - | stv0900_read_reg(i_params, - R0900_P2_AGC2I0); - max_carrier = i_params->dmd2_srch_range / 1000; - break; - } + carr_offset = (stv0900_read_reg(intp, CFR2) << 8) + | stv0900_read_reg(intp, CFR1); + carr_offset = ge2comp(carr_offset, 16); + agc2_integr = (stv0900_read_reg(intp, AGC2I1) << 8) + | stv0900_read_reg(intp, AGC2I0); + max_carrier = intp->srch_range[demod] / 1000; max_carrier += (max_carrier / 10); max_carrier = 65536 * (max_carrier / 2); - max_carrier /= i_params->mclk / 1000; + max_carrier /= intp->mclk / 1000; if (max_carrier > 0x4000) max_carrier = 0x4000; if ((agc2_integr > 0x2000) - || (carr_offset > + 2*max_carrier) - || (carr_offset < -2*max_carrier)) + || (carr_offset > (2 * max_carrier)) + || (carr_offset < (-2 * max_carrier))) no_signal = TRUE; - else - no_signal = FALSE; return no_signal; } -static void stv0900_get_sw_loop_params(struct stv0900_internal *i_params, +static void stv0900_get_sw_loop_params(struct stv0900_internal *intp, s32 *frequency_inc, s32 *sw_timeout, s32 *steps, enum fe_stv0900_demod_num demod) @@ -85,30 +74,19 @@ static void stv0900_get_sw_loop_params(struct stv0900_internal *i_params, enum fe_stv0900_search_standard standard; - switch (demod) { - case STV0900_DEMOD_1: - default: - srate = i_params->dmd1_symbol_rate; - max_carrier = i_params->dmd1_srch_range / 1000; - max_carrier += max_carrier / 10; - standard = i_params->dmd1_srch_standard; - break; - case STV0900_DEMOD_2: - srate = i_params->dmd2_symbol_rate; - max_carrier = i_params->dmd2_srch_range / 1000; - max_carrier += max_carrier / 10; - standard = i_params->dmd2_srch_stndrd; - break; - } + srate = intp->symbol_rate[demod]; + max_carrier = intp->srch_range[demod] / 1000; + max_carrier += max_carrier / 10; + standard = intp->srch_standard[demod]; max_carrier = 65536 * (max_carrier / 2); - max_carrier /= i_params->mclk / 1000; + max_carrier /= intp->mclk / 1000; if (max_carrier > 0x4000) max_carrier = 0x4000; freq_inc = srate; - freq_inc /= i_params->mclk >> 10; + freq_inc /= intp->mclk >> 10; freq_inc = freq_inc << 6; switch (standard) { @@ -154,7 +132,7 @@ static void stv0900_get_sw_loop_params(struct stv0900_internal *i_params, } -static int stv0900_search_carr_sw_loop(struct stv0900_internal *i_params, +static int stv0900_search_carr_sw_loop(struct stv0900_internal *intp, s32 FreqIncr, s32 Timeout, int zigzag, s32 MaxStep, enum fe_stv0900_demod_num demod) { @@ -164,20 +142,11 @@ static int stv0900_search_carr_sw_loop(struct stv0900_internal *i_params, freqOffset, max_carrier; - switch (demod) { - case STV0900_DEMOD_1: - default: - max_carrier = i_params->dmd1_srch_range / 1000; - max_carrier += (max_carrier / 10); - break; - case STV0900_DEMOD_2: - max_carrier = i_params->dmd2_srch_range / 1000; - max_carrier += (max_carrier / 10); - break; - } + max_carrier = intp->srch_range[demod] / 1000; + max_carrier += (max_carrier / 10); max_carrier = 65536 * (max_carrier / 2); - max_carrier /= i_params->mclk / 1000; + max_carrier /= intp->mclk / 1000; if (max_carrier > 0x4000) max_carrier = 0x4000; @@ -190,40 +159,15 @@ static int stv0900_search_carr_sw_loop(struct stv0900_internal *i_params, stepCpt = 0; do { - switch (demod) { - case STV0900_DEMOD_1: - default: - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C); - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, - (freqOffset / 256) & 0xFF); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, - freqOffset & 0xFF); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); - stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 1); - - if (i_params->chip_id == 0x12) { - stv0900_write_bits(i_params, - F0900_P1_RST_HWARE, 1); - stv0900_write_bits(i_params, - F0900_P1_RST_HWARE, 0); - } - break; - case STV0900_DEMOD_2: - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C); - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, - (freqOffset / 256) & 0xFF); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, - freqOffset & 0xFF); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); - stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 1); - - if (i_params->chip_id == 0x12) { - stv0900_write_bits(i_params, - F0900_P2_RST_HWARE, 1); - stv0900_write_bits(i_params, - F0900_P2_RST_HWARE, 0); - } - break; + stv0900_write_reg(intp, DMDISTATE, 0x1c); + stv0900_write_reg(intp, CFRINIT1, (freqOffset / 256) & 0xff); + stv0900_write_reg(intp, CFRINIT0, freqOffset & 0xff); + stv0900_write_reg(intp, DMDISTATE, 0x18); + stv0900_write_bits(intp, ALGOSWRST, 1); + + if (intp->chip_id == 0x12) { + stv0900_write_bits(intp, RST_HWARE, 1); + stv0900_write_bits(intp, RST_HWARE, 0); } if (zigzag == TRUE) { @@ -235,8 +179,8 @@ static int stv0900_search_carr_sw_loop(struct stv0900_internal *i_params, freqOffset += + 2 * FreqIncr; stepCpt++; - lock = stv0900_get_demod_lock(i_params, demod, Timeout); - no_signal = stv0900_check_signal_presence(i_params, demod); + lock = stv0900_get_demod_lock(intp, demod, Timeout); + no_signal = stv0900_check_signal_presence(intp, demod); } while ((lock == FALSE) && (no_signal == FALSE) @@ -244,269 +188,138 @@ static int stv0900_search_carr_sw_loop(struct stv0900_internal *i_params, && ((freqOffset + FreqIncr) > -max_carrier) && (stepCpt < MaxStep)); - switch (demod) { - case STV0900_DEMOD_1: - default: - stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 0); - break; - case STV0900_DEMOD_2: - stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 0); - break; - } + stv0900_write_bits(intp, ALGOSWRST, 0); return lock; } -int stv0900_sw_algo(struct stv0900_internal *i_params, +int stv0900_sw_algo(struct stv0900_internal *intp, enum fe_stv0900_demod_num demod) { - int lock = FALSE; - - int no_signal, - zigzag; - s32 dvbs2_fly_wheel; - - s32 freqIncrement, softStepTimeout, trialCounter, max_steps; - - stv0900_get_sw_loop_params(i_params, &freqIncrement, &softStepTimeout, + int lock = FALSE, + no_signal, + zigzag; + s32 s2fw, + fqc_inc, + sft_stp_tout, + trial_cntr, + max_steps; + + stv0900_get_sw_loop_params(intp, &fqc_inc, &sft_stp_tout, &max_steps, demod); - switch (demod) { - case STV0900_DEMOD_1: - default: - switch (i_params->dmd1_srch_standard) { - case STV0900_SEARCH_DVBS1: - case STV0900_SEARCH_DSS: - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P1_CARFREQ, - 0x3B); - else - stv0900_write_reg(i_params, R0900_P1_CARFREQ, - 0xef); - - stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x49); - zigzag = FALSE; - break; - case STV0900_SEARCH_DVBS2: - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P1_CORRELABS, - 0x79); - else - stv0900_write_reg(i_params, R0900_P1_CORRELABS, - 0x68); + switch (intp->srch_standard[demod]) { + case STV0900_SEARCH_DVBS1: + case STV0900_SEARCH_DSS: + if (intp->chip_id >= 0x20) + stv0900_write_reg(intp, CARFREQ, 0x3b); + else + stv0900_write_reg(intp, CARFREQ, 0xef); - stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, - 0x89); + stv0900_write_reg(intp, DMDCFGMD, 0x49); + zigzag = FALSE; + break; + case STV0900_SEARCH_DVBS2: + if (intp->chip_id >= 0x20) + stv0900_write_reg(intp, CORRELABS, 0x79); + else + stv0900_write_reg(intp, CORRELABS, 0x68); - zigzag = TRUE; - break; - case STV0900_AUTO_SEARCH: - default: - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P1_CARFREQ, - 0x3B); - stv0900_write_reg(i_params, R0900_P1_CORRELABS, - 0x79); - } else { - stv0900_write_reg(i_params, R0900_P1_CARFREQ, - 0xef); - stv0900_write_reg(i_params, R0900_P1_CORRELABS, - 0x68); - } + stv0900_write_reg(intp, DMDCFGMD, 0x89); - stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, - 0xc9); - zigzag = FALSE; - break; + zigzag = TRUE; + break; + case STV0900_AUTO_SEARCH: + default: + if (intp->chip_id >= 0x20) { + stv0900_write_reg(intp, CARFREQ, 0x3b); + stv0900_write_reg(intp, CORRELABS, 0x79); + } else { + stv0900_write_reg(intp, CARFREQ, 0xef); + stv0900_write_reg(intp, CORRELABS, 0x68); } - trialCounter = 0; - do { - lock = stv0900_search_carr_sw_loop(i_params, - freqIncrement, - softStepTimeout, - zigzag, - max_steps, - demod); - no_signal = stv0900_check_signal_presence(i_params, - demod); - trialCounter++; - if ((lock == TRUE) - || (no_signal == TRUE) - || (trialCounter == 2)) { - - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, - R0900_P1_CARFREQ, - 0x49); - stv0900_write_reg(i_params, - R0900_P1_CORRELABS, - 0x9e); - } else { - stv0900_write_reg(i_params, - R0900_P1_CARFREQ, - 0xed); - stv0900_write_reg(i_params, - R0900_P1_CORRELABS, - 0x88); - } - - if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS2_FOUND)) { - msleep(softStepTimeout); - dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT); - - if (dvbs2_fly_wheel < 0xd) { - msleep(softStepTimeout); - dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT); - } - - if (dvbs2_fly_wheel < 0xd) { - lock = FALSE; - - if (trialCounter < 2) { - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x79); - else - stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x68); - - stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x89); - } - } - } - } - - } while ((lock == FALSE) - && (trialCounter < 2) - && (no_signal == FALSE)); - + stv0900_write_reg(intp, DMDCFGMD, 0xc9); + zigzag = FALSE; break; - case STV0900_DEMOD_2: - switch (i_params->dmd2_srch_stndrd) { - case STV0900_SEARCH_DVBS1: - case STV0900_SEARCH_DSS: - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P2_CARFREQ, - 0x3b); - else - stv0900_write_reg(i_params, R0900_P2_CARFREQ, - 0xef); - - stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, - 0x49); - zigzag = FALSE; - break; - case STV0900_SEARCH_DVBS2: - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P2_CORRELABS, - 0x79); - else - stv0900_write_reg(i_params, R0900_P2_CORRELABS, - 0x68); + } - stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89); - zigzag = TRUE; - break; - case STV0900_AUTO_SEARCH: - default: - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P2_CARFREQ, - 0x3b); - stv0900_write_reg(i_params, R0900_P2_CORRELABS, - 0x79); + trial_cntr = 0; + do { + lock = stv0900_search_carr_sw_loop(intp, + fqc_inc, + sft_stp_tout, + zigzag, + max_steps, + demod); + no_signal = stv0900_check_signal_presence(intp, demod); + trial_cntr++; + if ((lock == TRUE) + || (no_signal == TRUE) + || (trial_cntr == 2)) { + + if (intp->chip_id >= 0x20) { + stv0900_write_reg(intp, CARFREQ, 0x49); + stv0900_write_reg(intp, CORRELABS, 0x9e); } else { - stv0900_write_reg(i_params, R0900_P2_CARFREQ, - 0xef); - stv0900_write_reg(i_params, R0900_P2_CORRELABS, - 0x68); + stv0900_write_reg(intp, CARFREQ, 0xed); + stv0900_write_reg(intp, CORRELABS, 0x88); } - stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0xc9); - - zigzag = FALSE; - break; - } + if ((stv0900_get_bits(intp, HEADER_MODE) == + STV0900_DVBS2_FOUND) && + (lock == TRUE)) { + msleep(sft_stp_tout); + s2fw = stv0900_get_bits(intp, FLYWHEEL_CPT); - trialCounter = 0; - - do { - lock = stv0900_search_carr_sw_loop(i_params, - freqIncrement, - softStepTimeout, - zigzag, - max_steps, - demod); - no_signal = stv0900_check_signal_presence(i_params, - demod); - trialCounter++; - if ((lock == TRUE) - || (no_signal == TRUE) - || (trialCounter == 2)) { - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, - R0900_P2_CARFREQ, - 0x49); - stv0900_write_reg(i_params, - R0900_P2_CORRELABS, - 0x9e); - } else { - stv0900_write_reg(i_params, - R0900_P2_CARFREQ, - 0xed); - stv0900_write_reg(i_params, - R0900_P2_CORRELABS, - 0x88); + if (s2fw < 0xd) { + msleep(sft_stp_tout); + s2fw = stv0900_get_bits(intp, + FLYWHEEL_CPT); } - if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS2_FOUND)) { - msleep(softStepTimeout); - dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT); - if (dvbs2_fly_wheel < 0xd) { - msleep(softStepTimeout); - dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT); - } + if (s2fw < 0xd) { + lock = FALSE; - if (dvbs2_fly_wheel < 0xd) { - lock = FALSE; - if (trialCounter < 2) { - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x79); - else - stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x68); + if (trial_cntr < 2) { + if (intp->chip_id >= 0x20) + stv0900_write_reg(intp, + CORRELABS, + 0x79); + else + stv0900_write_reg(intp, + CORRELABS, + 0x68); - stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89); - } + stv0900_write_reg(intp, + DMDCFGMD, + 0x89); } } } + } - } while ((lock == FALSE) && (trialCounter < 2) && (no_signal == FALSE)); - - break; - } + } while ((lock == FALSE) + && (trial_cntr < 2) + && (no_signal == FALSE)); return lock; } -static u32 stv0900_get_symbol_rate(struct stv0900_internal *i_params, +static u32 stv0900_get_symbol_rate(struct stv0900_internal *intp, u32 mclk, enum fe_stv0900_demod_num demod) { - s32 sfr_field3, sfr_field2, sfr_field1, sfr_field0, - rem1, rem2, intval1, intval2, srate; - - dmd_reg(sfr_field3, F0900_P1_SYMB_FREQ3, F0900_P2_SYMB_FREQ3); - dmd_reg(sfr_field2, F0900_P1_SYMB_FREQ2, F0900_P2_SYMB_FREQ2); - dmd_reg(sfr_field1, F0900_P1_SYMB_FREQ1, F0900_P2_SYMB_FREQ1); - dmd_reg(sfr_field0, F0900_P1_SYMB_FREQ0, F0900_P2_SYMB_FREQ0); - - srate = (stv0900_get_bits(i_params, sfr_field3) << 24) + - (stv0900_get_bits(i_params, sfr_field2) << 16) + - (stv0900_get_bits(i_params, sfr_field1) << 8) + - (stv0900_get_bits(i_params, sfr_field0)); + s32 rem1, rem2, intval1, intval2, srate; + + srate = (stv0900_get_bits(intp, SYMB_FREQ3) << 24) + + (stv0900_get_bits(intp, SYMB_FREQ2) << 16) + + (stv0900_get_bits(intp, SYMB_FREQ1) << 8) + + (stv0900_get_bits(intp, SYMB_FREQ0)); dprintk("lock: srate=%d r0=0x%x r1=0x%x r2=0x%x r3=0x%x \n", - srate, stv0900_get_bits(i_params, sfr_field0), - stv0900_get_bits(i_params, sfr_field1), - stv0900_get_bits(i_params, sfr_field2), - stv0900_get_bits(i_params, sfr_field3)); + srate, stv0900_get_bits(intp, SYMB_FREQ0), + stv0900_get_bits(intp, SYMB_FREQ1), + stv0900_get_bits(intp, SYMB_FREQ2), + stv0900_get_bits(intp, SYMB_FREQ3)); intval1 = (mclk) >> 16; intval2 = (srate) >> 16; @@ -520,18 +333,15 @@ static u32 stv0900_get_symbol_rate(struct stv0900_internal *i_params, return srate; } -static void stv0900_set_symbol_rate(struct stv0900_internal *i_params, +static void stv0900_set_symbol_rate(struct stv0900_internal *intp, u32 mclk, u32 srate, enum fe_stv0900_demod_num demod) { - s32 sfr_init_reg; u32 symb; dprintk("%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk, srate, demod); - dmd_reg(sfr_init_reg, R0900_P1_SFRINIT1, R0900_P2_SFRINIT1); - if (srate > 60000000) { symb = srate << 4; symb /= (mclk >> 12); @@ -543,19 +353,16 @@ static void stv0900_set_symbol_rate(struct stv0900_internal *i_params, symb /= (mclk >> 7); } - stv0900_write_reg(i_params, sfr_init_reg, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, sfr_init_reg + 1, (symb & 0xFF)); + stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0x7f); + stv0900_write_reg(intp, SFRINIT1 + 1, (symb & 0xff)); } -static void stv0900_set_max_symbol_rate(struct stv0900_internal *i_params, +static void stv0900_set_max_symbol_rate(struct stv0900_internal *intp, u32 mclk, u32 srate, enum fe_stv0900_demod_num demod) { - s32 sfr_max_reg; u32 symb; - dmd_reg(sfr_max_reg, R0900_P1_SFRUP1, R0900_P2_SFRUP1); - srate = 105 * (srate / 100); if (srate > 60000000) { @@ -570,23 +377,20 @@ static void stv0900_set_max_symbol_rate(struct stv0900_internal *i_params, } if (symb < 0x7fff) { - stv0900_write_reg(i_params, sfr_max_reg, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, sfr_max_reg + 1, (symb & 0xFF)); + stv0900_write_reg(intp, SFRUP1, (symb >> 8) & 0x7f); + stv0900_write_reg(intp, SFRUP1 + 1, (symb & 0xff)); } else { - stv0900_write_reg(i_params, sfr_max_reg, 0x7F); - stv0900_write_reg(i_params, sfr_max_reg + 1, 0xFF); + stv0900_write_reg(intp, SFRUP1, 0x7f); + stv0900_write_reg(intp, SFRUP1 + 1, 0xff); } } -static void stv0900_set_min_symbol_rate(struct stv0900_internal *i_params, +static void stv0900_set_min_symbol_rate(struct stv0900_internal *intp, u32 mclk, u32 srate, enum fe_stv0900_demod_num demod) { - s32 sfr_min_reg; u32 symb; - dmd_reg(sfr_min_reg, R0900_P1_SFRLOW1, R0900_P2_SFRLOW1); - srate = 95 * (srate / 100); if (srate > 60000000) { symb = srate << 4; @@ -601,22 +405,20 @@ static void stv0900_set_min_symbol_rate(struct stv0900_internal *i_params, symb /= (mclk >> 7); } - stv0900_write_reg(i_params, sfr_min_reg, (symb >> 8) & 0xFF); - stv0900_write_reg(i_params, sfr_min_reg + 1, (symb & 0xFF)); + stv0900_write_reg(intp, SFRLOW1, (symb >> 8) & 0xff); + stv0900_write_reg(intp, SFRLOW1 + 1, (symb & 0xff)); } -static s32 stv0900_get_timing_offst(struct stv0900_internal *i_params, +static s32 stv0900_get_timing_offst(struct stv0900_internal *intp, u32 srate, enum fe_stv0900_demod_num demod) { - s32 tmgreg, - timingoffset; + s32 timingoffset; - dmd_reg(tmgreg, R0900_P1_TMGREG2, R0900_P2_TMGREG2); - timingoffset = (stv0900_read_reg(i_params, tmgreg) << 16) + - (stv0900_read_reg(i_params, tmgreg + 1) << 8) + - (stv0900_read_reg(i_params, tmgreg + 2)); + timingoffset = (stv0900_read_reg(intp, TMGREG2) << 16) + + (stv0900_read_reg(intp, TMGREG2 + 1) << 8) + + (stv0900_read_reg(intp, TMGREG2 + 2)); timingoffset = ge2comp(timingoffset, 24); @@ -630,22 +432,19 @@ static s32 stv0900_get_timing_offst(struct stv0900_internal *i_params, return timingoffset; } -static void stv0900_set_dvbs2_rolloff(struct stv0900_internal *i_params, +static void stv0900_set_dvbs2_rolloff(struct stv0900_internal *intp, enum fe_stv0900_demod_num demod) { - s32 rolloff, man_fld, matstr_reg, rolloff_ctl_fld; - - dmd_reg(man_fld, F0900_P1_MANUAL_ROLLOFF, F0900_P2_MANUAL_ROLLOFF); - dmd_reg(matstr_reg, R0900_P1_MATSTR1, R0900_P2_MATSTR1); - dmd_reg(rolloff_ctl_fld, F0900_P1_ROLLOFF_CONTROL, - F0900_P2_ROLLOFF_CONTROL); - - if (i_params->chip_id == 0x10) { - stv0900_write_bits(i_params, man_fld, 1); - rolloff = stv0900_read_reg(i_params, matstr_reg) & 0x03; - stv0900_write_bits(i_params, rolloff_ctl_fld, rolloff); - } else - stv0900_write_bits(i_params, man_fld, 0); + s32 rolloff; + + if (intp->chip_id == 0x10) { + stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1); + rolloff = stv0900_read_reg(intp, MATSTR1) & 0x03; + stv0900_write_bits(intp, ROLLOFF_CONTROL, rolloff); + } else if (intp->chip_id <= 0x20) + stv0900_write_bits(intp, MANUALSX_ROLLOFF, 0); + else /* cut 3.0 */ + stv0900_write_bits(intp, MANUALS2_ROLLOFF, 0); } static u32 stv0900_carrier_width(u32 srate, enum fe_stv0900_rolloff ro) @@ -668,84 +467,47 @@ static u32 stv0900_carrier_width(u32 srate, enum fe_stv0900_rolloff ro) return srate + (srate * rolloff) / 100; } -static int stv0900_check_timing_lock(struct stv0900_internal *i_params, +static int stv0900_check_timing_lock(struct stv0900_internal *intp, enum fe_stv0900_demod_num demod) { int timingLock = FALSE; - s32 i, - timingcpt = 0; - u8 carFreq, - tmgTHhigh, - tmgTHLow; - - switch (demod) { - case STV0900_DEMOD_1: - default: - carFreq = stv0900_read_reg(i_params, R0900_P1_CARFREQ); - tmgTHhigh = stv0900_read_reg(i_params, R0900_P1_TMGTHRISE); - tmgTHLow = stv0900_read_reg(i_params, R0900_P1_TMGTHFALL); - stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20); - stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x0); - stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); - stv0900_write_reg(i_params, R0900_P1_RTC, 0x80); - stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x40); - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x0); - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0x0); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0x0); - stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x65); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); - msleep(7); - - for (i = 0; i < 10; i++) { - if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2) - timingcpt++; - - msleep(1); - } - - if (timingcpt >= 3) - timingLock = TRUE; - - stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38); - stv0900_write_reg(i_params, R0900_P1_RTC, 0x88); - stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x68); - stv0900_write_reg(i_params, R0900_P1_CARFREQ, carFreq); - stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, tmgTHhigh); - stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, tmgTHLow); - break; - case STV0900_DEMOD_2: - carFreq = stv0900_read_reg(i_params, R0900_P2_CARFREQ); - tmgTHhigh = stv0900_read_reg(i_params, R0900_P2_TMGTHRISE); - tmgTHLow = stv0900_read_reg(i_params, R0900_P2_TMGTHFALL); - stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20); - stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0); - stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); - stv0900_write_reg(i_params, R0900_P2_RTC, 0x80); - stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x40); - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x0); - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0x0); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0x0); - stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x65); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); - msleep(5); - for (i = 0; i < 10; i++) { - if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2) - timingcpt++; - - msleep(1); - } + s32 i, + timingcpt = 0; + u8 car_freq, + tmg_th_high, + tmg_th_low; + + car_freq = stv0900_read_reg(intp, CARFREQ); + tmg_th_high = stv0900_read_reg(intp, TMGTHRISE); + tmg_th_low = stv0900_read_reg(intp, TMGTHFALL); + stv0900_write_reg(intp, TMGTHRISE, 0x20); + stv0900_write_reg(intp, TMGTHFALL, 0x0); + stv0900_write_bits(intp, CFR_AUTOSCAN, 0); + stv0900_write_reg(intp, RTC, 0x80); + stv0900_write_reg(intp, RTCS2, 0x40); + stv0900_write_reg(intp, CARFREQ, 0x0); + stv0900_write_reg(intp, CFRINIT1, 0x0); + stv0900_write_reg(intp, CFRINIT0, 0x0); + stv0900_write_reg(intp, AGC2REF, 0x65); + stv0900_write_reg(intp, DMDISTATE, 0x18); + msleep(7); + + for (i = 0; i < 10; i++) { + if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2) + timingcpt++; + + msleep(1); + } - if (timingcpt >= 3) - timingLock = TRUE; + if (timingcpt >= 3) + timingLock = TRUE; - stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38); - stv0900_write_reg(i_params, R0900_P2_RTC, 0x88); - stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x68); - stv0900_write_reg(i_params, R0900_P2_CARFREQ, carFreq); - stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, tmgTHhigh); - stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, tmgTHLow); - break; - } + stv0900_write_reg(intp, AGC2REF, 0x38); + stv0900_write_reg(intp, RTC, 0x88); + stv0900_write_reg(intp, RTCS2, 0x68); + stv0900_write_reg(intp, CARFREQ, car_freq); + stv0900_write_reg(intp, TMGTHRISE, tmg_th_high); + stv0900_write_reg(intp, TMGTHFALL, tmg_th_low); return timingLock; } @@ -754,142 +516,114 @@ static int stv0900_get_demod_cold_lock(struct dvb_frontend *fe, s32 demod_timeout) { struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; + struct stv0900_internal *intp = state->internal; enum fe_stv0900_demod_num demod = state->demod; + int lock = FALSE, + d = demod; + s32 srate, + search_range, + locktimeout, + currier_step, + nb_steps, + current_step, + direction, + tuner_freq, + timeout, + freq; - int lock = FALSE; - s32 srate, search_range, locktimeout, - currier_step, nb_steps, current_step, - direction, tuner_freq, timeout; - - switch (demod) { - case STV0900_DEMOD_1: - default: - srate = i_params->dmd1_symbol_rate; - search_range = i_params->dmd1_srch_range; - break; - - case STV0900_DEMOD_2: - srate = i_params->dmd2_symbol_rate; - search_range = i_params->dmd2_srch_range; - break; - } + srate = intp->symbol_rate[d]; + search_range = intp->srch_range[d]; if (srate >= 10000000) locktimeout = demod_timeout / 3; else locktimeout = demod_timeout / 2; - lock = stv0900_get_demod_lock(i_params, demod, locktimeout); - - if (lock == FALSE) { - if (srate >= 10000000) { - if (stv0900_check_timing_lock(i_params, demod) == TRUE) { - switch (demod) { - case STV0900_DEMOD_1: - default: - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15); - break; - case STV0900_DEMOD_2: - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15); - break; - } + lock = stv0900_get_demod_lock(intp, d, locktimeout); - lock = stv0900_get_demod_lock(i_params, demod, demod_timeout); - } else - lock = FALSE; - } else { - if (srate <= 4000000) - currier_step = 1000; - else if (srate <= 7000000) - currier_step = 2000; - else if (srate <= 10000000) - currier_step = 3000; - else - currier_step = 5000; - - nb_steps = ((search_range / 1000) / currier_step); - nb_steps /= 2; - nb_steps = (2 * (nb_steps + 1)); - if (nb_steps < 0) - nb_steps = 2; - else if (nb_steps > 12) - nb_steps = 12; - - current_step = 1; - direction = 1; + if (lock != FALSE) + return lock; + + if (srate >= 10000000) { + if (stv0900_check_timing_lock(intp, d) == TRUE) { + stv0900_write_reg(intp, DMDISTATE, 0x1f); + stv0900_write_reg(intp, DMDISTATE, 0x15); + lock = stv0900_get_demod_lock(intp, d, demod_timeout); + } else + lock = FALSE; + + return lock; + } + + if (intp->chip_id <= 0x20) { + if (srate <= 1000000) + currier_step = 500; + else if (srate <= 4000000) + currier_step = 1000; + else if (srate <= 7000000) + currier_step = 2000; + else if (srate <= 10000000) + currier_step = 3000; + else + currier_step = 5000; + + if (srate >= 2000000) { timeout = (demod_timeout / 3); if (timeout > 1000) timeout = 1000; + } else + timeout = (demod_timeout / 2); + } else { + /*cut 3.0 */ + currier_step = srate / 4000; + timeout = (demod_timeout * 3) / 4; + } - switch (demod) { - case STV0900_DEMOD_1: - default: - if (lock == FALSE) { - tuner_freq = i_params->tuner1_freq; - i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + i_params->dmd1_symbol_rate; + nb_steps = ((search_range / 1000) / currier_step); - while ((current_step <= nb_steps) && (lock == FALSE)) { + if ((nb_steps % 2) != 0) + nb_steps += 1; - if (direction > 0) - tuner_freq += (current_step * currier_step); - else - tuner_freq -= (current_step * currier_step); - - stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C); - if (i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS2) { - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); - } - - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15); - lock = stv0900_get_demod_lock(i_params, demod, timeout); - direction *= -1; - current_step++; - } - } - break; - case STV0900_DEMOD_2: - if (lock == FALSE) { - tuner_freq = i_params->tuner2_freq; - i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + srate; + if (nb_steps <= 0) + nb_steps = 2; + else if (nb_steps > 12) + nb_steps = 12; - while ((current_step <= nb_steps) && (lock == FALSE)) { + current_step = 1; + direction = 1; - if (direction > 0) - tuner_freq += (current_step * currier_step); - else - tuner_freq -= (current_step * currier_step); - - stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C); - if (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS2) { - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); - } - - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15); - lock = stv0900_get_demod_lock(i_params, demod, timeout); - direction *= -1; - current_step++; - } - } - break; - } + if (intp->chip_id <= 0x20) { + tuner_freq = intp->freq[d]; + intp->bw[d] = stv0900_carrier_width(intp->symbol_rate[d], + intp->rolloff) + intp->symbol_rate[d]; + } else + tuner_freq = 0; + + while ((current_step <= nb_steps) && (lock == FALSE)) { + if (direction > 0) + tuner_freq += (current_step * currier_step); + else + tuner_freq -= (current_step * currier_step); + + if (intp->chip_id <= 0x20) { + stv0900_set_tuner(fe, tuner_freq, intp->bw[d]); + stv0900_write_reg(intp, DMDISTATE, 0x1c); + stv0900_write_reg(intp, CFRINIT1, 0); + stv0900_write_reg(intp, CFRINIT0, 0); + stv0900_write_reg(intp, DMDISTATE, 0x1f); + stv0900_write_reg(intp, DMDISTATE, 0x15); + } else { + stv0900_write_reg(intp, DMDISTATE, 0x1c); + freq = (tuner_freq * 65536) / (intp->mclk / 1000); + stv0900_write_bits(intp, CFR_INIT1, MSB(freq)); + stv0900_write_bits(intp, CFR_INIT0, LSB(freq)); + stv0900_write_reg(intp, DMDISTATE, 0x1f); + stv0900_write_reg(intp, DMDISTATE, 0x05); } + + lock = stv0900_get_demod_lock(intp, d, timeout); + direction *= -1; + current_step++; } return lock; @@ -931,9 +665,7 @@ static void stv0900_get_lock_timeout(s32 *demod_timeout, s32 *fec_timeout, } else if (srate <= 20000000) { (*demod_timeout) = 400; (*fec_timeout) = 130; - } - - else { + } else { (*demod_timeout) = 300; (*fec_timeout) = 100; } @@ -946,95 +678,77 @@ static void stv0900_get_lock_timeout(s32 *demod_timeout, s32 *fec_timeout, (*demod_timeout) /= 2; } -static void stv0900_set_viterbi_tracq(struct stv0900_internal *i_params, +static void stv0900_set_viterbi_tracq(struct stv0900_internal *intp, enum fe_stv0900_demod_num demod) { - s32 vth_reg; + s32 vth_reg = VTH12; dprintk("%s\n", __func__); - dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12); - - stv0900_write_reg(i_params, vth_reg++, 0xd0); - stv0900_write_reg(i_params, vth_reg++, 0x7d); - stv0900_write_reg(i_params, vth_reg++, 0x53); - stv0900_write_reg(i_params, vth_reg++, 0x2F); - stv0900_write_reg(i_params, vth_reg++, 0x24); - stv0900_write_reg(i_params, vth_reg++, 0x1F); + stv0900_write_reg(intp, vth_reg++, 0xd0); + stv0900_write_reg(intp, vth_reg++, 0x7d); + stv0900_write_reg(intp, vth_reg++, 0x53); + stv0900_write_reg(intp, vth_reg++, 0x2f); + stv0900_write_reg(intp, vth_reg++, 0x24); + stv0900_write_reg(intp, vth_reg++, 0x1f); } -static void stv0900_set_viterbi_standard(struct stv0900_internal *i_params, - enum fe_stv0900_search_standard Standard, - enum fe_stv0900_fec PunctureRate, +static void stv0900_set_viterbi_standard(struct stv0900_internal *intp, + enum fe_stv0900_search_standard standard, + enum fe_stv0900_fec fec, enum fe_stv0900_demod_num demod) { - - s32 fecmReg, - prvitReg; - dprintk("%s: ViterbiStandard = ", __func__); - switch (demod) { - case STV0900_DEMOD_1: - default: - fecmReg = R0900_P1_FECM; - prvitReg = R0900_P1_PRVIT; - break; - case STV0900_DEMOD_2: - fecmReg = R0900_P2_FECM; - prvitReg = R0900_P2_PRVIT; - break; - } - - switch (Standard) { + switch (standard) { case STV0900_AUTO_SEARCH: dprintk("Auto\n"); - stv0900_write_reg(i_params, fecmReg, 0x10); - stv0900_write_reg(i_params, prvitReg, 0x3F); + stv0900_write_reg(intp, FECM, 0x10); + stv0900_write_reg(intp, PRVIT, 0x3f); break; case STV0900_SEARCH_DVBS1: dprintk("DVBS1\n"); - stv0900_write_reg(i_params, fecmReg, 0x00); - switch (PunctureRate) { + stv0900_write_reg(intp, FECM, 0x00); + switch (fec) { case STV0900_FEC_UNKNOWN: default: - stv0900_write_reg(i_params, prvitReg, 0x2F); + stv0900_write_reg(intp, PRVIT, 0x2f); break; case STV0900_FEC_1_2: - stv0900_write_reg(i_params, prvitReg, 0x01); + stv0900_write_reg(intp, PRVIT, 0x01); break; case STV0900_FEC_2_3: - stv0900_write_reg(i_params, prvitReg, 0x02); + stv0900_write_reg(intp, PRVIT, 0x02); break; case STV0900_FEC_3_4: - stv0900_write_reg(i_params, prvitReg, 0x04); + stv0900_write_reg(intp, PRVIT, 0x04); break; case STV0900_FEC_5_6: - stv0900_write_reg(i_params, prvitReg, 0x08); + stv0900_write_reg(intp, PRVIT, 0x08); break; case STV0900_FEC_7_8: - stv0900_write_reg(i_params, prvitReg, 0x20); + stv0900_write_reg(intp, PRVIT, 0x20); break; } break; case STV0900_SEARCH_DSS: dprintk("DSS\n"); - stv0900_write_reg(i_params, fecmReg, 0x80); - switch (PunctureRate) { + stv0900_write_reg(intp, FECM, 0x80); + switch (fec) { case STV0900_FEC_UNKNOWN: default: - stv0900_write_reg(i_params, prvitReg, 0x13); + stv0900_write_reg(intp, PRVIT, 0x13); break; case STV0900_FEC_1_2: - stv0900_write_reg(i_params, prvitReg, 0x01); + stv0900_write_reg(intp, PRVIT, 0x01); break; case STV0900_FEC_2_3: - stv0900_write_reg(i_params, prvitReg, 0x02); + stv0900_write_reg(intp, PRVIT, 0x02); break; case STV0900_FEC_6_7: - stv0900_write_reg(i_params, prvitReg, 0x10); + stv0900_write_reg(intp, PRVIT, 0x10); break; } break; @@ -1043,340 +757,277 @@ static void stv0900_set_viterbi_standard(struct stv0900_internal *i_params, } } +static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *intp, + enum fe_stv0900_demod_num demod) +{ + enum fe_stv0900_fec prate; + s32 rate_fld = stv0900_get_bits(intp, VIT_CURPUN); + + switch (rate_fld) { + case 13: + prate = STV0900_FEC_1_2; + break; + case 18: + prate = STV0900_FEC_2_3; + break; + case 21: + prate = STV0900_FEC_3_4; + break; + case 24: + prate = STV0900_FEC_5_6; + break; + case 25: + prate = STV0900_FEC_6_7; + break; + case 26: + prate = STV0900_FEC_7_8; + break; + default: + prate = STV0900_FEC_UNKNOWN; + break; + } + + return prate; +} + +void stv0900_set_dvbs1_track_car_loop(struct stv0900_internal *intp, + enum fe_stv0900_demod_num demod, + u32 srate) +{ + if (intp->chip_id >= 0x30) { + if (srate >= 15000000) { + stv0900_write_reg(intp, ACLC, 0x2b); + stv0900_write_reg(intp, BCLC, 0x1a); + } else if ((srate >= 7000000) && (15000000 > srate)) { + stv0900_write_reg(intp, ACLC, 0x0c); + stv0900_write_reg(intp, BCLC, 0x1b); + } else if (srate < 7000000) { + stv0900_write_reg(intp, ACLC, 0x2c); + stv0900_write_reg(intp, BCLC, 0x1c); + } + + } else { /*cut 2.0 and 1.x*/ + stv0900_write_reg(intp, ACLC, 0x1a); + stv0900_write_reg(intp, BCLC, 0x09); + } + +} + static void stv0900_track_optimization(struct dvb_frontend *fe) { struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; + struct stv0900_internal *intp = state->internal; enum fe_stv0900_demod_num demod = state->demod; - s32 srate, pilots, aclc, freq1, freq0, - i = 0, timed, timef, blindTunSw = 0; + s32 srate, + pilots, + aclc, + freq1, + freq0, + i = 0, + timed, + timef, + blind_tun_sw = 0, + modulation; enum fe_stv0900_rolloff rolloff; enum fe_stv0900_modcode foundModcod; dprintk("%s\n", __func__); - srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); - srate += stv0900_get_timing_offst(i_params, srate, demod); + srate = stv0900_get_symbol_rate(intp, intp->mclk, demod); + srate += stv0900_get_timing_offst(intp, srate, demod); - switch (demod) { - case STV0900_DEMOD_1: - default: - switch (i_params->dmd1_rslts.standard) { - case STV0900_DVBS1_STANDARD: - if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) { - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); - } + switch (intp->result[demod].standard) { + case STV0900_DVBS1_STANDARD: + case STV0900_DSS_STANDARD: + dprintk("%s: found DVB-S or DSS\n", __func__); + if (intp->srch_standard[demod] == STV0900_AUTO_SEARCH) { + stv0900_write_bits(intp, DVBS1_ENABLE, 1); + stv0900_write_bits(intp, DVBS2_ENABLE, 0); + } - stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff); - stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1); - stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75); - break; - case STV0900_DSS_STANDARD: - if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) { - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); - } + stv0900_write_bits(intp, ROLLOFF_CONTROL, intp->rolloff); + stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1); - stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff); - stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1); - stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75); + if (intp->chip_id < 0x30) { + stv0900_write_reg(intp, ERRCTRL1, 0x75); break; - case STV0900_DVBS2_STANDARD: - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); - stv0900_write_reg(i_params, R0900_P1_ACLC, 0); - stv0900_write_reg(i_params, R0900_P1_BCLC, 0); - if (i_params->dmd1_rslts.frame_length == STV0900_LONG_FRAME) { - foundModcod = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD); - pilots = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01; - aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id); - if (foundModcod <= STV0900_QPSK_910) - stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc); - else if (foundModcod <= STV0900_8PSK_910) { - stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc); - } - - if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) { - if (foundModcod <= STV0900_16APSK_910) { - stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc); - } else if (foundModcod <= STV0900_32APSK_910) { - stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc); - } - } + } - } else { - aclc = stv0900_get_optim_short_carr_loop(srate, i_params->dmd1_rslts.modulation, i_params->chip_id); - if (i_params->dmd1_rslts.modulation == STV0900_QPSK) - stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc); - - else if (i_params->dmd1_rslts.modulation == STV0900_8PSK) { - stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc); - } else if (i_params->dmd1_rslts.modulation == STV0900_16APSK) { - stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc); - } else if (i_params->dmd1_rslts.modulation == STV0900_32APSK) { - stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc); - } + if (stv0900_get_vit_fec(intp, demod) == STV0900_FEC_1_2) { + stv0900_write_reg(intp, GAUSSR0, 0x98); + stv0900_write_reg(intp, CCIR0, 0x18); + } else { + stv0900_write_reg(intp, GAUSSR0, 0x18); + stv0900_write_reg(intp, CCIR0, 0x18); + } + stv0900_write_reg(intp, ERRCTRL1, 0x75); + break; + case STV0900_DVBS2_STANDARD: + dprintk("%s: found DVB-S2\n", __func__); + stv0900_write_bits(intp, DVBS1_ENABLE, 0); + stv0900_write_bits(intp, DVBS2_ENABLE, 1); + stv0900_write_reg(intp, ACLC, 0); + stv0900_write_reg(intp, BCLC, 0); + if (intp->result[demod].frame_len == STV0900_LONG_FRAME) { + foundModcod = stv0900_get_bits(intp, DEMOD_MODCOD); + pilots = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01; + aclc = stv0900_get_optim_carr_loop(srate, + foundModcod, + pilots, + intp->chip_id); + if (foundModcod <= STV0900_QPSK_910) + stv0900_write_reg(intp, ACLC2S2Q, aclc); + else if (foundModcod <= STV0900_8PSK_910) { + stv0900_write_reg(intp, ACLC2S2Q, 0x2a); + stv0900_write_reg(intp, ACLC2S28, aclc); } - if (i_params->chip_id <= 0x11) { - if (i_params->demod_mode != STV0900_SINGLE) - stv0900_activate_s2_modcode(i_params, demod); + if ((intp->demod_mode == STV0900_SINGLE) && + (foundModcod > STV0900_8PSK_910)) { + if (foundModcod <= STV0900_16APSK_910) { + stv0900_write_reg(intp, ACLC2S2Q, 0x2a); + stv0900_write_reg(intp, ACLC2S216A, + aclc); + } else if (foundModcod <= STV0900_32APSK_910) { + stv0900_write_reg(intp, ACLC2S2Q, 0x2a); + stv0900_write_reg(intp, ACLC2S232A, + aclc); + } + } + } else { + modulation = intp->result[demod].modulation; + aclc = stv0900_get_optim_short_carr_loop(srate, + modulation, intp->chip_id); + if (modulation == STV0900_QPSK) + stv0900_write_reg(intp, ACLC2S2Q, aclc); + else if (modulation == STV0900_8PSK) { + stv0900_write_reg(intp, ACLC2S2Q, 0x2a); + stv0900_write_reg(intp, ACLC2S28, aclc); + } else if (modulation == STV0900_16APSK) { + stv0900_write_reg(intp, ACLC2S2Q, 0x2a); + stv0900_write_reg(intp, ACLC2S216A, aclc); + } else if (modulation == STV0900_32APSK) { + stv0900_write_reg(intp, ACLC2S2Q, 0x2a); + stv0900_write_reg(intp, ACLC2S232A, aclc); } - stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67); - break; - case STV0900_UNKNOWN_STANDARD: - default: - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); - break; } - freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2); - freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1); - rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS); - if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) { - stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x00); - stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); - stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01); - stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod); - stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod); - stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod); - blindTunSw = 1; - } + if (intp->chip_id <= 0x11) { + if (intp->demod_mode != STV0900_SINGLE) + stv0900_activate_s2_modcod(intp, demod); - if (i_params->chip_id >= 0x20) { - if ((i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS1) || (i_params->dmd1_srch_standard == STV0900_SEARCH_DSS) || (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH)) { - stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0a); - stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x0); - } } - if (i_params->chip_id < 0x20) - stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x08); + stv0900_write_reg(intp, ERRCTRL1, 0x67); + break; + case STV0900_UNKNOWN_STANDARD: + default: + dprintk("%s: found unknown standard\n", __func__); + stv0900_write_bits(intp, DVBS1_ENABLE, 1); + stv0900_write_bits(intp, DVBS2_ENABLE, 1); + break; + } - if (i_params->chip_id == 0x10) - stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0x0A); + freq1 = stv0900_read_reg(intp, CFR2); + freq0 = stv0900_read_reg(intp, CFR1); + rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS); + if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) { + stv0900_write_reg(intp, SFRSTEP, 0x00); + stv0900_write_bits(intp, SCAN_ENABLE, 0); + stv0900_write_bits(intp, CFR_AUTOSCAN, 0); + stv0900_write_reg(intp, TMGCFG2, 0xc1); + stv0900_set_symbol_rate(intp, intp->mclk, srate, demod); + blind_tun_sw = 1; + if (intp->result[demod].standard != STV0900_DVBS2_STANDARD) + stv0900_set_dvbs1_track_car_loop(intp, demod, srate); - stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38); + } - if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd1_symbol_rate < 10000000)) { - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); - i_params->tuner1_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000; + if (intp->chip_id >= 0x20) { + if ((intp->srch_standard[demod] == STV0900_SEARCH_DVBS1) || + (intp->srch_standard[demod] == + STV0900_SEARCH_DSS) || + (intp->srch_standard[demod] == + STV0900_AUTO_SEARCH)) { + stv0900_write_reg(intp, VAVSRVIT, 0x0a); + stv0900_write_reg(intp, VITSCALE, 0x0); + } + } - if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) { - if (i_params->dmd1_srch_algo != STV0900_WARM_START) - stv0900_set_bandwidth(fe, i_params->tuner1_bw); - } + if (intp->chip_id < 0x20) + stv0900_write_reg(intp, CARHDR, 0x08); - if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000)) - msleep(50); - else - msleep(5); - - stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START); - - if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) { - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F); - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); - i = 0; - while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) { - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F); - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); - i++; - } - } + if (intp->chip_id == 0x10) + stv0900_write_reg(intp, CORRELEXP, 0x0a); - } + stv0900_write_reg(intp, AGC2REF, 0x38); - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49); + if ((intp->chip_id >= 0x20) || + (blind_tun_sw == 1) || + (intp->symbol_rate[demod] < 10000000)) { + stv0900_write_reg(intp, CFRINIT1, freq1); + stv0900_write_reg(intp, CFRINIT0, freq0); + intp->bw[demod] = stv0900_carrier_width(srate, + intp->rolloff) + 10000000; - if ((i_params->dmd1_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd1_rslts.standard == STV0900_DSS_STANDARD)) - stv0900_set_viterbi_tracq(i_params, demod); + if ((intp->chip_id >= 0x20) || (blind_tun_sw == 1)) { + if (intp->srch_algo[demod] != STV0900_WARM_START) + stv0900_set_bandwidth(fe, intp->bw[demod]); + } - break; + if ((intp->srch_algo[demod] == STV0900_BLIND_SEARCH) || + (intp->symbol_rate[demod] < 10000000)) + msleep(50); + else + msleep(5); - case STV0900_DEMOD_2: - switch (i_params->dmd2_rslts.standard) { - case STV0900_DVBS1_STANDARD: + stv0900_get_lock_timeout(&timed, &timef, srate, + STV0900_WARM_START); - if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) { - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); + if (stv0900_get_demod_lock(intp, demod, timed / 2) == FALSE) { + stv0900_write_reg(intp, DMDISTATE, 0x1f); + stv0900_write_reg(intp, CFRINIT1, freq1); + stv0900_write_reg(intp, CFRINIT0, freq0); + stv0900_write_reg(intp, DMDISTATE, 0x18); + i = 0; + while ((stv0900_get_demod_lock(intp, + demod, + timed / 2) == FALSE) && + (i <= 2)) { + stv0900_write_reg(intp, DMDISTATE, 0x1f); + stv0900_write_reg(intp, CFRINIT1, freq1); + stv0900_write_reg(intp, CFRINIT0, freq0); + stv0900_write_reg(intp, DMDISTATE, 0x18); + i++; } + } - stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff); - stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1); - stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75); - break; - case STV0900_DSS_STANDARD: - if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) { - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); - } + } - stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff); - stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1); - stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75); - break; - case STV0900_DVBS2_STANDARD: - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); - stv0900_write_reg(i_params, R0900_P2_ACLC, 0); - stv0900_write_reg(i_params, R0900_P2_BCLC, 0); - if (i_params->dmd2_rslts.frame_length == STV0900_LONG_FRAME) { - foundModcod = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD); - pilots = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01; - aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id); - if (foundModcod <= STV0900_QPSK_910) - stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc); - else if (foundModcod <= STV0900_8PSK_910) { - stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc); - } + if (intp->chip_id >= 0x20) + stv0900_write_reg(intp, CARFREQ, 0x49); - if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) { - if (foundModcod <= STV0900_16APSK_910) { - stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc); - } else if (foundModcod <= STV0900_32APSK_910) { - stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc); - } + if ((intp->result[demod].standard == STV0900_DVBS1_STANDARD) || + (intp->result[demod].standard == STV0900_DSS_STANDARD)) + stv0900_set_viterbi_tracq(intp, demod); - } +} - } else { - aclc = stv0900_get_optim_short_carr_loop(srate, - i_params->dmd2_rslts.modulation, - i_params->chip_id); - - if (i_params->dmd2_rslts.modulation == STV0900_QPSK) - stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc); - - else if (i_params->dmd2_rslts.modulation == STV0900_8PSK) { - stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc); - } else if (i_params->dmd2_rslts.modulation == STV0900_16APSK) { - stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc); - } else if (i_params->dmd2_rslts.modulation == STV0900_32APSK) { - stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc); - } - } +static int stv0900_get_fec_lock(struct stv0900_internal *intp, + enum fe_stv0900_demod_num demod, s32 time_out) +{ + s32 timer = 0, lock = 0; - stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67); - - break; - case STV0900_UNKNOWN_STANDARD: - default: - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); - break; - } - - freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2); - freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1); - rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS); - if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) { - stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x00); - stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); - stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01); - stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod); - stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod); - stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod); - blindTunSw = 1; - } - - if (i_params->chip_id >= 0x20) { - if ((i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS1) || (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DSS) || (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH)) { - stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0a); - stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x0); - } - } - - if (i_params->chip_id < 0x20) - stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x08); - - if (i_params->chip_id == 0x10) - stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0x0a); - - stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38); - if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd2_symbol_rate < 10000000)) { - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); - i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000; - - if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) { - if (i_params->dmd2_srch_algo != STV0900_WARM_START) - stv0900_set_bandwidth(fe, i_params->tuner2_bw); - } - - if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000)) - msleep(50); - else - msleep(5); - - stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START); - if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) { - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); - i = 0; - while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) { - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); - i++; - } - } - } - - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49); - - if ((i_params->dmd2_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd2_rslts.standard == STV0900_DSS_STANDARD)) - stv0900_set_viterbi_tracq(i_params, demod); - - break; - } -} - -static int stv0900_get_fec_lock(struct stv0900_internal *i_params, enum fe_stv0900_demod_num demod, s32 time_out) -{ - s32 timer = 0, lock = 0, header_field, pktdelin_field, lock_vit_field; - - enum fe_stv0900_search_state dmd_state; + enum fe_stv0900_search_state dmd_state; dprintk("%s\n", __func__); - dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); - dmd_reg(pktdelin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK); - dmd_reg(lock_vit_field, F0900_P1_LOCKEDVIT, F0900_P2_LOCKEDVIT); - - dmd_state = stv0900_get_bits(i_params, header_field); + dmd_state = stv0900_get_bits(intp, HEADER_MODE); while ((timer < time_out) && (lock == 0)) { switch (dmd_state) { @@ -1386,10 +1037,10 @@ static int stv0900_get_fec_lock(struct stv0900_internal *i_params, enum fe_stv09 lock = 0; break; case STV0900_DVBS2_FOUND: - lock = stv0900_get_bits(i_params, pktdelin_field); + lock = stv0900_get_bits(intp, PKTDELIN_LOCK); break; case STV0900_DVBS_FOUND: - lock = stv0900_get_bits(i_params, lock_vit_field); + lock = stv0900_get_bits(intp, LOCKEDVIT); break; } @@ -1400,38 +1051,35 @@ static int stv0900_get_fec_lock(struct stv0900_internal *i_params, enum fe_stv09 } if (lock) - dprintk("DEMOD FEC LOCK OK\n"); + dprintk("%s: DEMOD FEC LOCK OK\n", __func__); else - dprintk("DEMOD FEC LOCK FAIL\n"); + dprintk("%s: DEMOD FEC LOCK FAIL\n", __func__); return lock; } -static int stv0900_wait_for_lock(struct stv0900_internal *i_params, +static int stv0900_wait_for_lock(struct stv0900_internal *intp, enum fe_stv0900_demod_num demod, s32 dmd_timeout, s32 fec_timeout) { - s32 timer = 0, lock = 0, str_merg_rst_fld, str_merg_lock_fld; + s32 timer = 0, lock = 0; dprintk("%s\n", __func__); - dmd_reg(str_merg_rst_fld, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE); - dmd_reg(str_merg_lock_fld, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK); - - lock = stv0900_get_demod_lock(i_params, demod, dmd_timeout); + lock = stv0900_get_demod_lock(intp, demod, dmd_timeout); if (lock) - lock = lock && stv0900_get_fec_lock(i_params, demod, fec_timeout); + lock = lock && stv0900_get_fec_lock(intp, demod, fec_timeout); if (lock) { lock = 0; - dprintk("%s: Timer = %d, time_out = %d\n", __func__, timer, - fec_timeout); + dprintk("%s: Timer = %d, time_out = %d\n", + __func__, timer, fec_timeout); while ((timer < fec_timeout) && (lock == 0)) { - lock = stv0900_get_bits(i_params, str_merg_lock_fld); + lock = stv0900_get_bits(intp, TSFIFO_LINEOK); msleep(1); timer++; } @@ -1452,43 +1100,43 @@ enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe, enum fe_stv0900_demod_num demod) { struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; + struct stv0900_internal *intp = state->internal; enum fe_stv0900_tracking_standard fnd_standard; - s32 state_field, - dss_dvb_field; - dprintk("%s\n", __func__); - - dmd_reg(state_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); - dmd_reg(dss_dvb_field, F0900_P1_DSS_DVB, F0900_P2_DSS_DVB); + int hdr_mode = stv0900_get_bits(intp, HEADER_MODE); - if (stv0900_get_bits(i_params, state_field) == 2) + switch (hdr_mode) { + case 2: fnd_standard = STV0900_DVBS2_STANDARD; - - else if (stv0900_get_bits(i_params, state_field) == 3) { - if (stv0900_get_bits(i_params, dss_dvb_field) == 1) + break; + case 3: + if (stv0900_get_bits(intp, DSS_DVB) == 1) fnd_standard = STV0900_DSS_STANDARD; else fnd_standard = STV0900_DVBS1_STANDARD; - } else + + break; + default: fnd_standard = STV0900_UNKNOWN_STANDARD; + } + + dprintk("%s: standard %d\n", __func__, fnd_standard); return fnd_standard; } -static s32 stv0900_get_carr_freq(struct stv0900_internal *i_params, u32 mclk, +static s32 stv0900_get_carr_freq(struct stv0900_internal *intp, u32 mclk, enum fe_stv0900_demod_num demod) { - s32 cfr_field2, cfr_field1, cfr_field0, - derot, rem1, rem2, intval1, intval2; - - dmd_reg(cfr_field2, F0900_P1_CAR_FREQ2, F0900_P2_CAR_FREQ2); - dmd_reg(cfr_field1, F0900_P1_CAR_FREQ1, F0900_P2_CAR_FREQ1); - dmd_reg(cfr_field0, F0900_P1_CAR_FREQ0, F0900_P2_CAR_FREQ0); + s32 derot, + rem1, + rem2, + intval1, + intval2; - derot = (stv0900_get_bits(i_params, cfr_field2) << 16) + - (stv0900_get_bits(i_params, cfr_field1) << 8) + - (stv0900_get_bits(i_params, cfr_field0)); + derot = (stv0900_get_bits(intp, CAR_FREQ2) << 16) + + (stv0900_get_bits(intp, CAR_FREQ1) << 8) + + (stv0900_get_bits(intp, CAR_FREQ0)); derot = ge2comp(derot, 24); intval1 = mclk >> 12; @@ -1506,7 +1154,7 @@ static u32 stv0900_get_tuner_freq(struct dvb_frontend *fe) { struct dvb_frontend_ops *frontend_ops = NULL; struct dvb_tuner_ops *tuner_ops = NULL; - u32 frequency = 0; + u32 freq = 0; if (&fe->ops) frontend_ops = &fe->ops; @@ -1515,304 +1163,159 @@ static u32 stv0900_get_tuner_freq(struct dvb_frontend *fe) tuner_ops = &frontend_ops->tuner_ops; if (tuner_ops->get_frequency) { - if ((tuner_ops->get_frequency(fe, &frequency)) < 0) + if ((tuner_ops->get_frequency(fe, &freq)) < 0) dprintk("%s: Invalid parameter\n", __func__); else - dprintk("%s: Frequency=%d\n", __func__, frequency); - - } - - return frequency; -} - -static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod) -{ - s32 rate_fld, vit_curpun_fld; - enum fe_stv0900_fec prate; + dprintk("%s: Frequency=%d\n", __func__, freq); - dmd_reg(vit_curpun_fld, F0900_P1_VIT_CURPUN, F0900_P2_VIT_CURPUN); - rate_fld = stv0900_get_bits(i_params, vit_curpun_fld); - - switch (rate_fld) { - case 13: - prate = STV0900_FEC_1_2; - break; - case 18: - prate = STV0900_FEC_2_3; - break; - case 21: - prate = STV0900_FEC_3_4; - break; - case 24: - prate = STV0900_FEC_5_6; - break; - case 25: - prate = STV0900_FEC_6_7; - break; - case 26: - prate = STV0900_FEC_7_8; - break; - default: - prate = STV0900_FEC_UNKNOWN; - break; } - return prate; + return freq; } -static enum fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe) +static enum +fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe) { struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; + struct stv0900_internal *intp = state->internal; enum fe_stv0900_demod_num demod = state->demod; enum fe_stv0900_signal_type range = STV0900_OUTOFRANGE; - s32 offsetFreq, - srate_offset, - i = 0; + struct stv0900_signal_info *result = &intp->result[demod]; + s32 offsetFreq, + srate_offset; + int i = 0, + d = demod; u8 timing; msleep(5); - switch (demod) { - case STV0900_DEMOD_1: - default: - if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) { - timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2); - i = 0; - stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x5c); - - while ((i <= 50) && (timing != 0) && (timing != 0xFF)) { - timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2); - msleep(5); - i += 5; - } - } - - i_params->dmd1_rslts.standard = stv0900_get_standard(fe, demod); - i_params->dmd1_rslts.frequency = stv0900_get_tuner_freq(fe); - offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000; - i_params->dmd1_rslts.frequency += offsetFreq; - i_params->dmd1_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); - srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd1_rslts.symbol_rate, demod); - i_params->dmd1_rslts.symbol_rate += srate_offset; - i_params->dmd1_rslts.fec = stv0900_get_vit_fec(i_params, demod); - i_params->dmd1_rslts.modcode = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD); - i_params->dmd1_rslts.pilot = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01; - i_params->dmd1_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE)) >> 1; - i_params->dmd1_rslts.rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS); - switch (i_params->dmd1_rslts.standard) { - case STV0900_DVBS2_STANDARD: - i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_SPECINV_DEMOD); - if (i_params->dmd1_rslts.modcode <= STV0900_QPSK_910) - i_params->dmd1_rslts.modulation = STV0900_QPSK; - else if (i_params->dmd1_rslts.modcode <= STV0900_8PSK_910) - i_params->dmd1_rslts.modulation = STV0900_8PSK; - else if (i_params->dmd1_rslts.modcode <= STV0900_16APSK_910) - i_params->dmd1_rslts.modulation = STV0900_16APSK; - else if (i_params->dmd1_rslts.modcode <= STV0900_32APSK_910) - i_params->dmd1_rslts.modulation = STV0900_32APSK; - else - i_params->dmd1_rslts.modulation = STV0900_UNKNOWN; - break; - case STV0900_DVBS1_STANDARD: - case STV0900_DSS_STANDARD: - i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_IQINV); - i_params->dmd1_rslts.modulation = STV0900_QPSK; - break; - default: - break; + if (intp->srch_algo[d] == STV0900_BLIND_SEARCH) { + timing = stv0900_read_reg(intp, TMGREG2); + i = 0; + stv0900_write_reg(intp, SFRSTEP, 0x5c); + + while ((i <= 50) && (timing != 0) && (timing != 0xff)) { + timing = stv0900_read_reg(intp, TMGREG2); + msleep(5); + i += 5; } + } - if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000)) { - offsetFreq = i_params->dmd1_rslts.frequency - i_params->tuner1_freq; - i_params->tuner1_freq = stv0900_get_tuner_freq(fe); - if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500)) - range = STV0900_RANGEOK; - else - if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd1_rslts.symbol_rate, i_params->dmd1_rslts.rolloff) / 2000)) - range = STV0900_RANGEOK; - else - range = STV0900_OUTOFRANGE; - - } else { - if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500)) - range = STV0900_RANGEOK; - else - range = STV0900_OUTOFRANGE; - } + result->standard = stv0900_get_standard(fe, d); + result->frequency = stv0900_get_tuner_freq(fe); + offsetFreq = stv0900_get_carr_freq(intp, intp->mclk, d) / 1000; + result->frequency += offsetFreq; + result->symbol_rate = stv0900_get_symbol_rate(intp, intp->mclk, d); + srate_offset = stv0900_get_timing_offst(intp, result->symbol_rate, d); + result->symbol_rate += srate_offset; + result->fec = stv0900_get_vit_fec(intp, d); + result->modcode = stv0900_get_bits(intp, DEMOD_MODCOD); + result->pilot = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01; + result->frame_len = ((u32)stv0900_get_bits(intp, DEMOD_TYPE)) >> 1; + result->rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS); + switch (result->standard) { + case STV0900_DVBS2_STANDARD: + result->spectrum = stv0900_get_bits(intp, SPECINV_DEMOD); + if (result->modcode <= STV0900_QPSK_910) + result->modulation = STV0900_QPSK; + else if (result->modcode <= STV0900_8PSK_910) + result->modulation = STV0900_8PSK; + else if (result->modcode <= STV0900_16APSK_910) + result->modulation = STV0900_16APSK; + else if (result->modcode <= STV0900_32APSK_910) + result->modulation = STV0900_32APSK; + else + result->modulation = STV0900_UNKNOWN; break; - case STV0900_DEMOD_2: - if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) { - timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2); - i = 0; - stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x5c); - - while ((i <= 50) && (timing != 0) && (timing != 0xff)) { - timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2); - msleep(5); - i += 5; - } - } - - i_params->dmd2_rslts.standard = stv0900_get_standard(fe, demod); - i_params->dmd2_rslts.frequency = stv0900_get_tuner_freq(fe); - offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000; - i_params->dmd2_rslts.frequency += offsetFreq; - i_params->dmd2_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); - srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd2_rslts.symbol_rate, demod); - i_params->dmd2_rslts.symbol_rate += srate_offset; - i_params->dmd2_rslts.fec = stv0900_get_vit_fec(i_params, demod); - i_params->dmd2_rslts.modcode = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD); - i_params->dmd2_rslts.pilot = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01; - i_params->dmd2_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE)) >> 1; - i_params->dmd2_rslts.rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS); - switch (i_params->dmd2_rslts.standard) { - case STV0900_DVBS2_STANDARD: - i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_SPECINV_DEMOD); - if (i_params->dmd2_rslts.modcode <= STV0900_QPSK_910) - i_params->dmd2_rslts.modulation = STV0900_QPSK; - else if (i_params->dmd2_rslts.modcode <= STV0900_8PSK_910) - i_params->dmd2_rslts.modulation = STV0900_8PSK; - else if (i_params->dmd2_rslts.modcode <= STV0900_16APSK_910) - i_params->dmd2_rslts.modulation = STV0900_16APSK; - else if (i_params->dmd2_rslts.modcode <= STV0900_32APSK_910) - i_params->dmd2_rslts.modulation = STV0900_32APSK; - else - i_params->dmd2_rslts.modulation = STV0900_UNKNOWN; - break; - case STV0900_DVBS1_STANDARD: - case STV0900_DSS_STANDARD: - i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_IQINV); - i_params->dmd2_rslts.modulation = STV0900_QPSK; - break; - default: - break; - } + case STV0900_DVBS1_STANDARD: + case STV0900_DSS_STANDARD: + result->spectrum = stv0900_get_bits(intp, IQINV); + result->modulation = STV0900_QPSK; + break; + default: + break; + } - if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000)) { - offsetFreq = i_params->dmd2_rslts.frequency - i_params->tuner2_freq; - i_params->tuner2_freq = stv0900_get_tuner_freq(fe); + if ((intp->srch_algo[d] == STV0900_BLIND_SEARCH) || + (intp->symbol_rate[d] < 10000000)) { + offsetFreq = result->frequency - intp->freq[d]; + intp->freq[d] = stv0900_get_tuner_freq(fe); + if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500)) + range = STV0900_RANGEOK; + else if (ABS(offsetFreq) <= + (stv0900_carrier_width(result->symbol_rate, + result->rolloff) / 2000)) + range = STV0900_RANGEOK; - if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500)) - range = STV0900_RANGEOK; - else - if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd2_rslts.symbol_rate, i_params->dmd2_rslts.rolloff) / 2000)) - range = STV0900_RANGEOK; - else - range = STV0900_OUTOFRANGE; - } else { - if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500)) - range = STV0900_RANGEOK; - else - range = STV0900_OUTOFRANGE; - } + } else if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500)) + range = STV0900_RANGEOK; - break; - } + dprintk("%s: range %d\n", __func__, range); return range; } -static enum fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_frontend *fe) +static enum +fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_frontend *fe) { struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; + struct stv0900_internal *intp = state->internal; enum fe_stv0900_demod_num demod = state->demod; - - s32 srate, demod_timeout, - fec_timeout, freq1, freq0; enum fe_stv0900_signal_type signal_type = STV0900_NODATA; - switch (demod) { - case STV0900_DEMOD_1: - default: - i_params->dmd1_rslts.locked = FALSE; - if (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) { - srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); - srate += stv0900_get_timing_offst(i_params, srate, demod); - if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) - stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod); - - stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START); - freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2); - freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1); - stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); - stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C); - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); - if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) { - i_params->dmd1_rslts.locked = TRUE; - signal_type = stv0900_get_signal_params(fe); - stv0900_track_optimization(fe); - } else { - stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1c); - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); - if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) { - i_params->dmd1_rslts.locked = TRUE; - signal_type = stv0900_get_signal_params(fe); - stv0900_track_optimization(fe); - } - - } - - } else - i_params->dmd1_rslts.locked = FALSE; - - break; - case STV0900_DEMOD_2: - i_params->dmd2_rslts.locked = FALSE; - if (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) { - srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); - srate += stv0900_get_timing_offst(i_params, srate, demod); - - if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) - stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod); - - stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START); - freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2); - freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1); - stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); - stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C); - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); - - if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) { - i_params->dmd2_rslts.locked = TRUE; + s32 srate, + demod_timeout, + fec_timeout, + freq1, + freq0; + + intp->result[demod].locked = FALSE; + + if (stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) { + srate = stv0900_get_symbol_rate(intp, intp->mclk, demod); + srate += stv0900_get_timing_offst(intp, srate, demod); + if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) + stv0900_set_symbol_rate(intp, intp->mclk, srate, demod); + + stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, + srate, STV0900_WARM_START); + freq1 = stv0900_read_reg(intp, CFR2); + freq0 = stv0900_read_reg(intp, CFR1); + stv0900_write_bits(intp, CFR_AUTOSCAN, 0); + stv0900_write_bits(intp, SPECINV_CONTROL, + STV0900_IQ_FORCE_SWAPPED); + stv0900_write_reg(intp, DMDISTATE, 0x1c); + stv0900_write_reg(intp, CFRINIT1, freq1); + stv0900_write_reg(intp, CFRINIT0, freq0); + stv0900_write_reg(intp, DMDISTATE, 0x18); + if (stv0900_wait_for_lock(intp, demod, + demod_timeout, fec_timeout) == TRUE) { + intp->result[demod].locked = TRUE; + signal_type = stv0900_get_signal_params(fe); + stv0900_track_optimization(fe); + } else { + stv0900_write_bits(intp, SPECINV_CONTROL, + STV0900_IQ_FORCE_NORMAL); + stv0900_write_reg(intp, DMDISTATE, 0x1c); + stv0900_write_reg(intp, CFRINIT1, freq1); + stv0900_write_reg(intp, CFRINIT0, freq0); + stv0900_write_reg(intp, DMDISTATE, 0x18); + if (stv0900_wait_for_lock(intp, demod, + demod_timeout, fec_timeout) == TRUE) { + intp->result[demod].locked = TRUE; signal_type = stv0900_get_signal_params(fe); stv0900_track_optimization(fe); - } else { - stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1c); - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); - - if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) { - i_params->dmd2_rslts.locked = TRUE; - signal_type = stv0900_get_signal_params(fe); - stv0900_track_optimization(fe); - } - } - } else - i_params->dmd1_rslts.locked = FALSE; + } - break; - } + } else + intp->result[demod].locked = FALSE; return signal_type; } -static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *i_params, +static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *intp, enum fe_stv0900_demod_num demod) { u32 minagc2level = 0xffff, @@ -1823,103 +1326,52 @@ static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *i_params, dprintk("%s\n", __func__); - switch (demod) { - case STV0900_DEMOD_1: - default: - stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38); - stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1); + stv0900_write_reg(intp, AGC2REF, 0x38); + stv0900_write_bits(intp, SCAN_ENABLE, 0); + stv0900_write_bits(intp, CFR_AUTOSCAN, 0); - stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83); - stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0); + stv0900_write_bits(intp, AUTO_GUP, 1); + stv0900_write_bits(intp, AUTO_GLOW, 1); - stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82); - stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0); - stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0); + stv0900_write_reg(intp, DMDT0M, 0x0); - stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod); - nb_steps = -1 + (i_params->dmd1_srch_range / 1000000); - nb_steps /= 2; - nb_steps = (2 * nb_steps) + 1; + stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod); + nb_steps = -1 + (intp->srch_range[demod] / 1000000); + nb_steps /= 2; + nb_steps = (2 * nb_steps) + 1; - if (nb_steps < 0) - nb_steps = 1; + if (nb_steps < 0) + nb_steps = 1; - direction = 1; + direction = 1; - freq_step = (1000000 << 8) / (i_params->mclk >> 8); + freq_step = (1000000 << 8) / (intp->mclk >> 8); - init_freq = 0; + init_freq = 0; - for (i = 0; i < nb_steps; i++) { - if (direction > 0) - init_freq = init_freq + (freq_step * i); - else - init_freq = init_freq - (freq_step * i); - - direction *= -1; - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C); - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (init_freq >> 8) & 0xff); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, init_freq & 0xff); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x58); - msleep(10); - agc2level = 0; - - for (j = 0; j < 10; j++) - agc2level += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) - | stv0900_read_reg(i_params, R0900_P1_AGC2I0); - - agc2level /= 10; - - if (agc2level < minagc2level) - minagc2level = agc2level; - } - break; - case STV0900_DEMOD_2: - stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38); - stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1); - stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83); - stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0); - stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82); - stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0); - stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0); - stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod); - nb_steps = -1 + (i_params->dmd2_srch_range / 1000000); - nb_steps /= 2; - nb_steps = (2 * nb_steps) + 1; - - if (nb_steps < 0) - nb_steps = 1; - - direction = 1; - freq_step = (1000000 << 8) / (i_params->mclk >> 8); - init_freq = 0; - for (i = 0; i < nb_steps; i++) { - if (direction > 0) - init_freq = init_freq + (freq_step * i); - else - init_freq = init_freq - (freq_step * i); + for (i = 0; i < nb_steps; i++) { + if (direction > 0) + init_freq = init_freq + (freq_step * i); + else + init_freq = init_freq - (freq_step * i); - direction *= -1; + direction *= -1; + stv0900_write_reg(intp, DMDISTATE, 0x5C); + stv0900_write_reg(intp, CFRINIT1, (init_freq >> 8) & 0xff); + stv0900_write_reg(intp, CFRINIT0, init_freq & 0xff); + stv0900_write_reg(intp, DMDISTATE, 0x58); + msleep(10); + agc2level = 0; - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C); - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (init_freq >> 8) & 0xff); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, init_freq & 0xff); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x58); + for (j = 0; j < 10; j++) + agc2level += (stv0900_read_reg(intp, AGC2I1) << 8) + | stv0900_read_reg(intp, AGC2I0); - msleep(10); - agc2level = 0; - for (j = 0; j < 10; j++) - agc2level += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8) - | stv0900_read_reg(i_params, R0900_P2_AGC2I0); + agc2level /= 10; - agc2level /= 10; + if (agc2level < minagc2level) + minagc2level = agc2level; - if (agc2level < minagc2level) - minagc2level = agc2level; - } - break; } return (u16)minagc2level; @@ -1928,336 +1380,192 @@ static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *i_params, static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe) { struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; + struct stv0900_internal *intp = state->internal; enum fe_stv0900_demod_num demod = state->demod; - int timingLock = FALSE; + int timing_lck = FALSE; s32 i, timingcpt = 0, direction = 1, nb_steps, current_step = 0, tuner_freq; + u32 agc2_th, + coarse_srate = 0, + agc2_integr = 0, + currier_step = 1200; - u32 coarse_srate = 0, agc2_integr = 0, currier_step = 1200; - - switch (demod) { - case STV0900_DEMOD_1: - default: - stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x1F); - stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0x12); - stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0xf0); - stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0xe0); - stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1); - stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83); - stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0); - stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82); - stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0); - stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0); - stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x50); - - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x6a); - stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x95); - } else { - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed); - stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x73); - } + if (intp->chip_id >= 0x30) + agc2_th = 0x2e00; + else + agc2_th = 0x1f00; + + stv0900_write_bits(intp, DEMOD_MODE, 0x1f); + stv0900_write_reg(intp, TMGCFG, 0x12); + stv0900_write_reg(intp, TMGTHRISE, 0xf0); + stv0900_write_reg(intp, TMGTHFALL, 0xe0); + stv0900_write_bits(intp, SCAN_ENABLE, 1); + stv0900_write_bits(intp, CFR_AUTOSCAN, 1); + stv0900_write_reg(intp, SFRUP1, 0x83); + stv0900_write_reg(intp, SFRUP0, 0xc0); + stv0900_write_reg(intp, SFRLOW1, 0x82); + stv0900_write_reg(intp, SFRLOW0, 0xa0); + stv0900_write_reg(intp, DMDT0M, 0x0); + stv0900_write_reg(intp, AGC2REF, 0x50); + + if (intp->chip_id >= 0x30) { + stv0900_write_reg(intp, CARFREQ, 0x99); + stv0900_write_reg(intp, SFRSTEP, 0x98); + } else if (intp->chip_id >= 0x20) { + stv0900_write_reg(intp, CARFREQ, 0x6a); + stv0900_write_reg(intp, SFRSTEP, 0x95); + } else { + stv0900_write_reg(intp, CARFREQ, 0xed); + stv0900_write_reg(intp, SFRSTEP, 0x73); + } - if (i_params->dmd1_symbol_rate <= 2000000) - currier_step = 1000; - else if (i_params->dmd1_symbol_rate <= 5000000) - currier_step = 2000; - else if (i_params->dmd1_symbol_rate <= 12000000) - currier_step = 3000; - else + if (intp->symbol_rate[demod] <= 2000000) + currier_step = 1000; + else if (intp->symbol_rate[demod] <= 5000000) + currier_step = 2000; + else if (intp->symbol_rate[demod] <= 12000000) + currier_step = 3000; + else currier_step = 5000; - nb_steps = -1 + ((i_params->dmd1_srch_range / 1000) / currier_step); - nb_steps /= 2; - nb_steps = (2 * nb_steps) + 1; - - if (nb_steps < 0) - nb_steps = 1; - - else if (nb_steps > 10) { - nb_steps = 11; - currier_step = (i_params->dmd1_srch_range / 1000) / 10; - } - - current_step = 0; - - direction = 1; - tuner_freq = i_params->tuner1_freq; - - while ((timingLock == FALSE) && (current_step < nb_steps)) { - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5F); - stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x0); - - msleep(50); - - for (i = 0; i < 10; i++) { - if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2) - timingcpt++; - - agc2_integr += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) | stv0900_read_reg(i_params, R0900_P1_AGC2I0); - - } - - agc2_integr /= 10; - coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); - current_step++; - direction *= -1; - - dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started. tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n", tuner_freq, agc2_integr, coarse_srate, timingcpt); + nb_steps = -1 + ((intp->srch_range[demod] / 1000) / currier_step); + nb_steps /= 2; + nb_steps = (2 * nb_steps) + 1; - if ((timingcpt >= 5) && (agc2_integr < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000)) { - timingLock = TRUE; - } + if (nb_steps < 0) + nb_steps = 1; + else if (nb_steps > 10) { + nb_steps = 11; + currier_step = (intp->srch_range[demod] / 1000) / 10; + } - else if (current_step < nb_steps) { - if (direction > 0) - tuner_freq += (current_step * currier_step); - else - tuner_freq -= (current_step * currier_step); + current_step = 0; + direction = 1; - stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw); - } - } + tuner_freq = intp->freq[demod]; - if (timingLock == FALSE) - coarse_srate = 0; - else - coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); - break; - case STV0900_DEMOD_2: - stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x1F); - stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0x12); - stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0xf0); - stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0xe0); - stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1); - stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83); - stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0); - stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82); - stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0); - stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0); - stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x50); - - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x6a); - stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x95); - } else { - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed); - stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x73); - } - - if (i_params->dmd2_symbol_rate <= 2000000) - currier_step = 1000; - else if (i_params->dmd2_symbol_rate <= 5000000) - currier_step = 2000; - else if (i_params->dmd2_symbol_rate <= 12000000) - currier_step = 3000; - else - currier_step = 5000; + while ((timing_lck == FALSE) && (current_step < nb_steps)) { + stv0900_write_reg(intp, DMDISTATE, 0x5f); + stv0900_write_bits(intp, DEMOD_MODE, 0); + msleep(50); - nb_steps = -1 + ((i_params->dmd2_srch_range / 1000) / currier_step); - nb_steps /= 2; - nb_steps = (2 * nb_steps) + 1; + for (i = 0; i < 10; i++) { + if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2) + timingcpt++; - if (nb_steps < 0) - nb_steps = 1; - else if (nb_steps > 10) { - nb_steps = 11; - currier_step = (i_params->dmd2_srch_range / 1000) / 10; + agc2_integr += (stv0900_read_reg(intp, AGC2I1) << 8) | + stv0900_read_reg(intp, AGC2I0); } - current_step = 0; - direction = 1; - tuner_freq = i_params->tuner2_freq; - - while ((timingLock == FALSE) && (current_step < nb_steps)) { - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5F); - stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x0); - - msleep(50); - timingcpt = 0; - - for (i = 0; i < 20; i++) { - if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2) - timingcpt++; - agc2_integr += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8) - | stv0900_read_reg(i_params, R0900_P2_AGC2I0); - } - - agc2_integr /= 20; - coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); - if ((timingcpt >= 10) && (agc2_integr < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000)) - timingLock = TRUE; - else { - current_step++; - direction *= -1; - - if (direction > 0) - tuner_freq += (current_step * currier_step); - else - tuner_freq -= (current_step * currier_step); + agc2_integr /= 10; + coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod); + current_step++; + direction *= -1; + + dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started." + " tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n", + tuner_freq, agc2_integr, coarse_srate, timingcpt); + + if ((timingcpt >= 5) && + (agc2_integr < agc2_th) && + (coarse_srate < 55000000) && + (coarse_srate > 850000)) + timing_lck = TRUE; + else if (current_step < nb_steps) { + if (direction > 0) + tuner_freq += (current_step * currier_step); + else + tuner_freq -= (current_step * currier_step); - stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw); - } + stv0900_set_tuner(fe, tuner_freq, intp->bw[demod]); } - - if (timingLock == FALSE) - coarse_srate = 0; - else - coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); - break; } + if (timing_lck == FALSE) + coarse_srate = 0; + else + coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod); + return coarse_srate; } static u32 stv0900_search_srate_fine(struct dvb_frontend *fe) { struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; + struct stv0900_internal *intp = state->internal; enum fe_stv0900_demod_num demod = state->demod; - u32 coarse_srate, - coarse_freq, - symb; + u32 coarse_srate, + coarse_freq, + symb, + symbmax, + symbmin, + symbcomp; + + coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod); + + if (coarse_srate > 3000000) { + symbmax = 13 * (coarse_srate / 10); + symbmax = (symbmax / 1000) * 65536; + symbmax /= (intp->mclk / 1000); + + symbmin = 10 * (coarse_srate / 13); + symbmin = (symbmin / 1000)*65536; + symbmin /= (intp->mclk / 1000); + + symb = (coarse_srate / 1000) * 65536; + symb /= (intp->mclk / 1000); + } else { + symbmax = 13 * (coarse_srate / 10); + symbmax = (symbmax / 100) * 65536; + symbmax /= (intp->mclk / 100); - coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); + symbmin = 10 * (coarse_srate / 14); + symbmin = (symbmin / 100) * 65536; + symbmin /= (intp->mclk / 100); - switch (demod) { - case STV0900_DEMOD_1: - default: - coarse_freq = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8) - | stv0900_read_reg(i_params, R0900_P1_CFR1); - symb = 13 * (coarse_srate / 10); - - if (symb < i_params->dmd1_symbol_rate) - coarse_srate = 0; - else { - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F); - stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01); - stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20); - stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x00); - stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2); - stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); - - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49); - else - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed); - - if (coarse_srate > 3000000) { - symb = 13 * (coarse_srate / 10); - symb = (symb / 1000) * 65536; - symb /= (i_params->mclk / 1000); - stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF)); - - symb = 10 * (coarse_srate / 13); - symb = (symb / 1000) * 65536; - symb /= (i_params->mclk / 1000); - - stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF)); - - symb = (coarse_srate / 1000) * 65536; - symb /= (i_params->mclk / 1000); - stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF); - stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF)); - } else { - symb = 13 * (coarse_srate / 10); - symb = (symb / 100) * 65536; - symb /= (i_params->mclk / 100); - stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF)); - - symb = 10 * (coarse_srate / 14); - symb = (symb / 100) * 65536; - symb /= (i_params->mclk / 100); - stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF)); - - symb = (coarse_srate / 100) * 65536; - symb /= (i_params->mclk / 100); - stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF); - stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF)); - } + symb = (coarse_srate / 100) * 65536; + symb /= (intp->mclk / 100); + } - stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20); - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (coarse_freq >> 8) & 0xff); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, coarse_freq & 0xff); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15); - } - break; - case STV0900_DEMOD_2: - coarse_freq = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8) - | stv0900_read_reg(i_params, R0900_P2_CFR1); - - symb = 13 * (coarse_srate / 10); - - if (symb < i_params->dmd2_symbol_rate) - coarse_srate = 0; - else { - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); - stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01); - stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20); - stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0x00); - stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2); - stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); - - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49); - else - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed); - - if (coarse_srate > 3000000) { - symb = 13 * (coarse_srate / 10); - symb = (symb / 1000) * 65536; - symb /= (i_params->mclk / 1000); - stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF)); - - symb = 10 * (coarse_srate / 13); - symb = (symb / 1000) * 65536; - symb /= (i_params->mclk / 1000); - - stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF)); - - symb = (coarse_srate / 1000) * 65536; - symb /= (i_params->mclk / 1000); - stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF); - stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF)); - } else { - symb = 13 * (coarse_srate / 10); - symb = (symb / 100) * 65536; - symb /= (i_params->mclk / 100); - stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF)); - - symb = 10 * (coarse_srate / 14); - symb = (symb / 100) * 65536; - symb /= (i_params->mclk / 100); - stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF)); - - symb = (coarse_srate / 100) * 65536; - symb /= (i_params->mclk / 100); - stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF); - stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF)); - } + symbcomp = 13 * (coarse_srate / 10); + coarse_freq = (stv0900_read_reg(intp, CFR2) << 8) + | stv0900_read_reg(intp, CFR1); + + if (symbcomp < intp->symbol_rate[demod]) + coarse_srate = 0; + else { + stv0900_write_reg(intp, DMDISTATE, 0x1f); + stv0900_write_reg(intp, TMGCFG2, 0xc1); + stv0900_write_reg(intp, TMGTHRISE, 0x20); + stv0900_write_reg(intp, TMGTHFALL, 0x00); + stv0900_write_reg(intp, TMGCFG, 0xd2); + stv0900_write_bits(intp, CFR_AUTOSCAN, 0); + stv0900_write_reg(intp, AGC2REF, 0x38); + + if (intp->chip_id >= 0x30) + stv0900_write_reg(intp, CARFREQ, 0x79); + else if (intp->chip_id >= 0x20) + stv0900_write_reg(intp, CARFREQ, 0x49); + else + stv0900_write_reg(intp, CARFREQ, 0xed); - stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20); - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (coarse_freq >> 8) & 0xff); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, coarse_freq & 0xff); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15); - } + stv0900_write_reg(intp, SFRUP1, (symbmax >> 8) & 0x7f); + stv0900_write_reg(intp, SFRUP0, (symbmax & 0xff)); - break; + stv0900_write_reg(intp, SFRLOW1, (symbmin >> 8) & 0x7f); + stv0900_write_reg(intp, SFRLOW0, (symbmin & 0xff)); + + stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0xff); + stv0900_write_reg(intp, SFRINIT0, (symb & 0xff)); + + stv0900_write_reg(intp, DMDT0M, 0x20); + stv0900_write_reg(intp, CFRINIT1, (coarse_freq >> 8) & 0xff); + stv0900_write_reg(intp, CFRINIT0, coarse_freq & 0xff); + stv0900_write_reg(intp, DMDISTATE, 0x15); } return coarse_srate; @@ -2266,163 +1574,135 @@ static u32 stv0900_search_srate_fine(struct dvb_frontend *fe) static int stv0900_blind_search_algo(struct dvb_frontend *fe) { struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; + struct stv0900_internal *intp = state->internal; enum fe_stv0900_demod_num demod = state->demod; - u8 k_ref_tmg, k_ref_tmg_max, k_ref_tmg_min; - u32 coarse_srate; - int lock = FALSE, coarse_fail = FALSE; - s32 demod_timeout = 500, fec_timeout = 50, kref_tmg_reg, fail_cpt, i, agc2_overflow; - u16 agc2_integr; - u8 dstatus2; + u8 k_ref_tmg, + k_ref_tmg_max, + k_ref_tmg_min; + u32 coarse_srate, + agc2_th; + int lock = FALSE, + coarse_fail = FALSE; + s32 demod_timeout = 500, + fec_timeout = 50, + fail_cpt, + i, + agc2_overflow; + u16 agc2_int; + u8 dstatus2; dprintk("%s\n", __func__); - if (i_params->chip_id < 0x20) { + if (intp->chip_id < 0x20) { k_ref_tmg_max = 233; k_ref_tmg_min = 143; } else { - k_ref_tmg_max = 120; - k_ref_tmg_min = 30; + k_ref_tmg_max = 110; + k_ref_tmg_min = 10; } - agc2_integr = stv0900_blind_check_agc2_min_level(i_params, demod); - - if (agc2_integr > STV0900_BLIND_SEARCH_AGC2_TH) { - lock = FALSE; - - } else { - switch (demod) { - case STV0900_DEMOD_1: - default: - if (i_params->chip_id == 0x10) - stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0xAA); - - if (i_params->chip_id < 0x20) - stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x55); - - stv0900_write_reg(i_params, R0900_P1_CARCFG, 0xC4); - stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x44); - - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P1_EQUALCFG, 0x41); - stv0900_write_reg(i_params, R0900_P1_FFECFG, 0x41); - stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x82); - stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0); - } - - kref_tmg_reg = R0900_P1_KREFTMG; - break; - case STV0900_DEMOD_2: - if (i_params->chip_id == 0x10) - stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0xAA); + if (intp->chip_id <= 0x20) + agc2_th = STV0900_BLIND_SEARCH_AGC2_TH; + else + agc2_th = STV0900_BLIND_SEARCH_AGC2_TH_CUT30; - if (i_params->chip_id < 0x20) - stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55); + agc2_int = stv0900_blind_check_agc2_min_level(intp, demod); - stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xC4); - stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44); + if (agc2_int > STV0900_BLIND_SEARCH_AGC2_TH) + return FALSE; - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P2_EQUALCFG, 0x41); - stv0900_write_reg(i_params, R0900_P2_FFECFG, 0x41); - stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x82); - stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0); - } + if (intp->chip_id == 0x10) + stv0900_write_reg(intp, CORRELEXP, 0xaa); - kref_tmg_reg = R0900_P2_KREFTMG; - break; - } + if (intp->chip_id < 0x20) + stv0900_write_reg(intp, CARHDR, 0x55); + else + stv0900_write_reg(intp, CARHDR, 0x20); - k_ref_tmg = k_ref_tmg_max; + if (intp->chip_id <= 0x20) + stv0900_write_reg(intp, CARCFG, 0xc4); + else + stv0900_write_reg(intp, CARCFG, 0x6); - do { - stv0900_write_reg(i_params, kref_tmg_reg, k_ref_tmg); - if (stv0900_search_srate_coarse(fe) != 0) { - coarse_srate = stv0900_search_srate_fine(fe); + stv0900_write_reg(intp, RTCS2, 0x44); - if (coarse_srate != 0) { - stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, coarse_srate, STV0900_BLIND_SEARCH); - lock = stv0900_get_demod_lock(i_params, demod, demod_timeout); - } else - lock = FALSE; - } else { - fail_cpt = 0; - agc2_overflow = 0; - - switch (demod) { - case STV0900_DEMOD_1: - default: - for (i = 0; i < 10; i++) { - agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) - | stv0900_read_reg(i_params, R0900_P1_AGC2I0); + if (intp->chip_id >= 0x20) { + stv0900_write_reg(intp, EQUALCFG, 0x41); + stv0900_write_reg(intp, FFECFG, 0x41); + stv0900_write_reg(intp, VITSCALE, 0x82); + stv0900_write_reg(intp, VAVSRVIT, 0x0); + } - if (agc2_integr >= 0xff00) - agc2_overflow++; + k_ref_tmg = k_ref_tmg_max; - dstatus2 = stv0900_read_reg(i_params, R0900_P1_DSTATUS2); + do { + stv0900_write_reg(intp, KREFTMG, k_ref_tmg); + if (stv0900_search_srate_coarse(fe) != 0) { + coarse_srate = stv0900_search_srate_fine(fe); + + if (coarse_srate != 0) { + stv0900_get_lock_timeout(&demod_timeout, + &fec_timeout, + coarse_srate, + STV0900_BLIND_SEARCH); + lock = stv0900_get_demod_lock(intp, + demod, + demod_timeout); + } else + lock = FALSE; + } else { + fail_cpt = 0; + agc2_overflow = 0; - if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1)) - fail_cpt++; - } - break; - case STV0900_DEMOD_2: - for (i = 0; i < 10; i++) { - agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8) - | stv0900_read_reg(i_params, R0900_P2_AGC2I0); + for (i = 0; i < 10; i++) { + agc2_int = (stv0900_read_reg(intp, AGC2I1) << 8) + | stv0900_read_reg(intp, AGC2I0); - if (agc2_integr >= 0xff00) - agc2_overflow++; + if (agc2_int >= 0xff00) + agc2_overflow++; - dstatus2 = stv0900_read_reg(i_params, R0900_P2_DSTATUS2); + dstatus2 = stv0900_read_reg(intp, DSTATUS2); - if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1)) - fail_cpt++; - } - break; - } + if (((dstatus2 & 0x1) == 0x1) && + ((dstatus2 >> 7) == 1)) + fail_cpt++; + } - if ((fail_cpt > 7) || (agc2_overflow > 7)) - coarse_fail = TRUE; + if ((fail_cpt > 7) || (agc2_overflow > 7)) + coarse_fail = TRUE; - lock = FALSE; - } - k_ref_tmg -= 30; - } while ((k_ref_tmg >= k_ref_tmg_min) && (lock == FALSE) && (coarse_fail == FALSE)); - } + lock = FALSE; + } + k_ref_tmg -= 30; + } while ((k_ref_tmg >= k_ref_tmg_min) && + (lock == FALSE) && + (coarse_fail == FALSE)); return lock; } -static void stv0900_set_viterbi_acq(struct stv0900_internal *i_params, +static void stv0900_set_viterbi_acq(struct stv0900_internal *intp, enum fe_stv0900_demod_num demod) { - s32 vth_reg; + s32 vth_reg = VTH12; dprintk("%s\n", __func__); - dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12); - - stv0900_write_reg(i_params, vth_reg++, 0x96); - stv0900_write_reg(i_params, vth_reg++, 0x64); - stv0900_write_reg(i_params, vth_reg++, 0x36); - stv0900_write_reg(i_params, vth_reg++, 0x23); - stv0900_write_reg(i_params, vth_reg++, 0x1E); - stv0900_write_reg(i_params, vth_reg++, 0x19); + stv0900_write_reg(intp, vth_reg++, 0x96); + stv0900_write_reg(intp, vth_reg++, 0x64); + stv0900_write_reg(intp, vth_reg++, 0x36); + stv0900_write_reg(intp, vth_reg++, 0x23); + stv0900_write_reg(intp, vth_reg++, 0x1e); + stv0900_write_reg(intp, vth_reg++, 0x19); } -static void stv0900_set_search_standard(struct stv0900_internal *i_params, +static void stv0900_set_search_standard(struct stv0900_internal *intp, enum fe_stv0900_demod_num demod) { - int sstndrd; - dprintk("%s\n", __func__); - sstndrd = i_params->dmd1_srch_standard; - if (demod == 1) - sstndrd = i_params->dmd2_srch_stndrd; - - switch (sstndrd) { + switch (intp->srch_standard[demod]) { case STV0900_SEARCH_DVBS1: dprintk("Search Standard = DVBS1\n"); break; @@ -2437,129 +1717,74 @@ static void stv0900_set_search_standard(struct stv0900_internal *i_params, break; } - switch (demod) { - case STV0900_DEMOD_1: - default: - switch (i_params->dmd1_srch_standard) { - case STV0900_SEARCH_DVBS1: - case STV0900_SEARCH_DSS: - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); - - stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0); - stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a); - stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09); - stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x22); - - stv0900_set_viterbi_acq(i_params, demod); - stv0900_set_viterbi_standard(i_params, - i_params->dmd1_srch_standard, - i_params->dmd1_fec, demod); - - break; - case STV0900_SEARCH_DVBS2: - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); - stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 1); - stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a); - stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09); - stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26); - if (i_params->demod_mode != STV0900_SINGLE) { - if (i_params->chip_id <= 0x11) - stv0900_stop_all_s2_modcod(i_params, demod); - else - stv0900_activate_s2_modcode(i_params, demod); - - } else - stv0900_activate_s2_modcode_single(i_params, demod); - - stv0900_set_viterbi_tracq(i_params, demod); - - break; - case STV0900_AUTO_SEARCH: - default: - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); - stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0); - stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a); - stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09); - stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26); - if (i_params->demod_mode != STV0900_SINGLE) { - if (i_params->chip_id <= 0x11) - stv0900_stop_all_s2_modcod(i_params, demod); - else - stv0900_activate_s2_modcode(i_params, demod); + switch (intp->srch_standard[demod]) { + case STV0900_SEARCH_DVBS1: + case STV0900_SEARCH_DSS: + stv0900_write_bits(intp, DVBS1_ENABLE, 1); + stv0900_write_bits(intp, DVBS2_ENABLE, 0); + stv0900_write_bits(intp, STOP_CLKVIT, 0); + stv0900_set_dvbs1_track_car_loop(intp, + demod, + intp->symbol_rate[demod]); + stv0900_write_reg(intp, CAR2CFG, 0x22); + + stv0900_set_viterbi_acq(intp, demod); + stv0900_set_viterbi_standard(intp, + intp->srch_standard[demod], + intp->fec[demod], demod); - } else - stv0900_activate_s2_modcode_single(i_params, demod); + break; + case STV0900_SEARCH_DVBS2: + stv0900_write_bits(intp, DVBS1_ENABLE, 0); + stv0900_write_bits(intp, DVBS2_ENABLE, 1); + stv0900_write_bits(intp, STOP_CLKVIT, 1); + stv0900_write_reg(intp, ACLC, 0x1a); + stv0900_write_reg(intp, BCLC, 0x09); + if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/ + stv0900_write_reg(intp, CAR2CFG, 0x26); + else + stv0900_write_reg(intp, CAR2CFG, 0x66); - if (i_params->dmd1_symbol_rate >= 2000000) - stv0900_set_viterbi_acq(i_params, demod); + if (intp->demod_mode != STV0900_SINGLE) { + if (intp->chip_id <= 0x11) + stv0900_stop_all_s2_modcod(intp, demod); else - stv0900_set_viterbi_tracq(i_params, demod); + stv0900_activate_s2_modcod(intp, demod); - stv0900_set_viterbi_standard(i_params, i_params->dmd1_srch_standard, i_params->dmd1_fec, demod); + } else + stv0900_activate_s2_modcod_single(intp, demod); - break; - } - break; - case STV0900_DEMOD_2: - switch (i_params->dmd2_srch_stndrd) { - case STV0900_SEARCH_DVBS1: - case STV0900_SEARCH_DSS: - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); - stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0); - stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a); - stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09); - stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x22); - stv0900_set_viterbi_acq(i_params, demod); - stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod); - break; - case STV0900_SEARCH_DVBS2: - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); - stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 1); - stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a); - stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09); - stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26); - if (i_params->demod_mode != STV0900_SINGLE) - stv0900_activate_s2_modcode(i_params, demod); - else - stv0900_activate_s2_modcode_single(i_params, demod); + stv0900_set_viterbi_tracq(intp, demod); - stv0900_set_viterbi_tracq(i_params, demod); - break; - case STV0900_AUTO_SEARCH: - default: - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); - stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0); - stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a); - stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09); - stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26); - if (i_params->demod_mode != STV0900_SINGLE) - stv0900_activate_s2_modcode(i_params, demod); - else - stv0900_activate_s2_modcode_single(i_params, demod); + break; + case STV0900_AUTO_SEARCH: + default: + stv0900_write_bits(intp, DVBS1_ENABLE, 1); + stv0900_write_bits(intp, DVBS2_ENABLE, 1); + stv0900_write_bits(intp, STOP_CLKVIT, 0); + stv0900_write_reg(intp, ACLC, 0x1a); + stv0900_write_reg(intp, BCLC, 0x09); + stv0900_set_dvbs1_track_car_loop(intp, + demod, + intp->symbol_rate[demod]); + if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/ + stv0900_write_reg(intp, CAR2CFG, 0x26); + else + stv0900_write_reg(intp, CAR2CFG, 0x66); - if (i_params->dmd2_symbol_rate >= 2000000) - stv0900_set_viterbi_acq(i_params, demod); + if (intp->demod_mode != STV0900_SINGLE) { + if (intp->chip_id <= 0x11) + stv0900_stop_all_s2_modcod(intp, demod); else - stv0900_set_viterbi_tracq(i_params, demod); + stv0900_activate_s2_modcod(intp, demod); - stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod); + } else + stv0900_activate_s2_modcod_single(intp, demod); - break; - } + stv0900_set_viterbi_tracq(intp, demod); + stv0900_set_viterbi_standard(intp, + intp->srch_standard[demod], + intp->fec[demod], demod); break; } @@ -2568,10 +1793,11 @@ static void stv0900_set_search_standard(struct stv0900_internal *i_params, enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe) { struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; + struct stv0900_internal *intp = state->internal; enum fe_stv0900_demod_num demod = state->demod; - s32 demod_timeout = 500, fec_timeout = 50, stream_merger_field; + s32 demod_timeout = 500, fec_timeout = 50; + s32 aq_power, agc1_power, i; int lock = FALSE, low_sr = FALSE; @@ -2581,155 +1807,115 @@ enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe) dprintk("%s\n", __func__); - switch (demod) { - case STV0900_DEMOD_1: - default: - algo = i_params->dmd1_srch_algo; - - stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 1); - stream_merger_field = F0900_P1_RST_HWARE; - - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C); - - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x9e); + algo = intp->srch_algo[demod]; + stv0900_write_bits(intp, RST_HWARE, 1); + stv0900_write_reg(intp, DMDISTATE, 0x5c); + if (intp->chip_id >= 0x20) { + if (intp->symbol_rate[demod] > 5000000) + stv0900_write_reg(intp, CORRELABS, 0x9e); else - stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x88); - - stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd1_symbol_rate, i_params->dmd1_srch_algo); - - if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) { - i_params->tuner1_bw = 2 * 36000000; - - stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x00); - stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70); - - stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod); - } else { - stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20); - stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2); - - if (i_params->dmd1_symbol_rate < 2000000) - stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x63); - else - stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70); - - stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38); - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0x5a); - - if (i_params->dmd1_srch_algo == STV0900_COLD_START) - i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10; - else if (i_params->dmd1_srch_algo == STV0900_WARM_START) - i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000; - } else { - stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0xc1); - i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10; - } - - stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01); - - stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod); - stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod); - stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod); - if (i_params->dmd1_symbol_rate >= 10000000) - low_sr = FALSE; - else - low_sr = TRUE; - - } - - stv0900_set_tuner(fe, i_params->tuner1_freq, i_params->tuner1_bw); - - stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, i_params->dmd1_srch_iq_inv); - stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1); - - stv0900_set_search_standard(i_params, demod); + stv0900_write_reg(intp, CORRELABS, 0x82); + } else + stv0900_write_reg(intp, CORRELABS, 0x88); - if (i_params->dmd1_srch_algo != STV0900_BLIND_SEARCH) - stv0900_start_search(i_params, demod); - break; - case STV0900_DEMOD_2: - algo = i_params->dmd2_srch_algo; + stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, + intp->symbol_rate[demod], + intp->srch_algo[demod]); - stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 1); + if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) { + intp->bw[demod] = 2 * 36000000; - stream_merger_field = F0900_P2_RST_HWARE; + stv0900_write_reg(intp, TMGCFG2, 0xc0); + stv0900_write_reg(intp, CORRELMANT, 0x70); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C); + stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod); + } else { + stv0900_write_reg(intp, DMDT0M, 0x20); + stv0900_write_reg(intp, TMGCFG, 0xd2); - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x9e); + if (intp->symbol_rate[demod] < 2000000) + stv0900_write_reg(intp, CORRELMANT, 0x63); else - stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x88); + stv0900_write_reg(intp, CORRELMANT, 0x70); - stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd2_symbol_rate, i_params->dmd2_srch_algo); + stv0900_write_reg(intp, AGC2REF, 0x38); - if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) { - i_params->tuner2_bw = 2 * 36000000; + intp->bw[demod] = + stv0900_carrier_width(intp->symbol_rate[demod], + intp->rolloff); + if (intp->chip_id >= 0x20) { + stv0900_write_reg(intp, KREFTMG, 0x5a); - stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x00); - stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70); + if (intp->srch_algo[demod] == STV0900_COLD_START) { + intp->bw[demod] += 10000000; + intp->bw[demod] *= 15; + intp->bw[demod] /= 10; + } else if (intp->srch_algo[demod] == STV0900_WARM_START) + intp->bw[demod] += 10000000; - stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod); } else { - stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20); - stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2); + stv0900_write_reg(intp, KREFTMG, 0xc1); + intp->bw[demod] += 10000000; + intp->bw[demod] *= 15; + intp->bw[demod] /= 10; + } - if (i_params->dmd2_symbol_rate < 2000000) - stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x63); - else - stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70); + stv0900_write_reg(intp, TMGCFG2, 0xc1); - if (i_params->dmd2_symbol_rate >= 10000000) - stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38); - else - stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x60); + stv0900_set_symbol_rate(intp, intp->mclk, + intp->symbol_rate[demod], demod); + stv0900_set_max_symbol_rate(intp, intp->mclk, + intp->symbol_rate[demod], demod); + stv0900_set_min_symbol_rate(intp, intp->mclk, + intp->symbol_rate[demod], demod); + if (intp->symbol_rate[demod] >= 10000000) + low_sr = FALSE; + else + low_sr = TRUE; - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0x5a); + } - if (i_params->dmd2_srch_algo == STV0900_COLD_START) - i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate, - i_params->rolloff) + 10000000)) / 10; - else if (i_params->dmd2_srch_algo == STV0900_WARM_START) - i_params->tuner2_bw = stv0900_carrier_width(i_params->dmd2_symbol_rate, - i_params->rolloff) + 10000000; - } else { - stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0xc1); - i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate, - i_params->rolloff) + 10000000)) / 10; - } + stv0900_set_tuner(fe, intp->freq[demod], intp->bw[demod]); - stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01); + agc1_power = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1), + stv0900_get_bits(intp, AGCIQ_VALUE0)); - stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod); - stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod); - stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod); - if (i_params->dmd2_symbol_rate >= 10000000) - low_sr = FALSE; - else - low_sr = TRUE; + aq_power = 0; - } + if (agc1_power == 0) { + for (i = 0; i < 5; i++) + aq_power += (stv0900_get_bits(intp, POWER_I) + + stv0900_get_bits(intp, POWER_Q)) / 2; - stv0900_set_tuner(fe, i_params->tuner2_freq, i_params->tuner2_bw); + aq_power /= 5; + } - stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, i_params->dmd2_srch_iq_inv); - stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1); + if ((agc1_power == 0) && (aq_power < IQPOWER_THRESHOLD)) { + intp->result[demod].locked = FALSE; + signal_type = STV0900_NOAGC1; + dprintk("%s: NO AGC1, POWERI, POWERQ\n", __func__); + } else { + stv0900_write_bits(intp, SPECINV_CONTROL, + intp->srch_iq_inv[demod]); + if (intp->chip_id <= 0x20) /*cut 2.0*/ + stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1); + else /*cut 3.0*/ + stv0900_write_bits(intp, MANUALS2_ROLLOFF, 1); - stv0900_set_search_standard(i_params, demod); + stv0900_set_search_standard(intp, demod); - if (i_params->dmd2_srch_algo != STV0900_BLIND_SEARCH) - stv0900_start_search(i_params, demod); - break; + if (intp->srch_algo[demod] != STV0900_BLIND_SEARCH) + stv0900_start_search(intp, demod); } - if (i_params->chip_id == 0x12) { - stv0900_write_bits(i_params, stream_merger_field, 0); + if (signal_type == STV0900_NOAGC1) + return signal_type; + + if (intp->chip_id == 0x12) { + stv0900_write_bits(intp, RST_HWARE, 0); msleep(3); - stv0900_write_bits(i_params, stream_merger_field, 1); - stv0900_write_bits(i_params, stream_merger_field, 0); + stv0900_write_bits(intp, RST_HWARE, 1); + stv0900_write_bits(intp, RST_HWARE, 0); } if (algo == STV0900_BLIND_SEARCH) @@ -2737,12 +1923,12 @@ enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe) else if (algo == STV0900_COLD_START) lock = stv0900_get_demod_cold_lock(fe, demod_timeout); else if (algo == STV0900_WARM_START) - lock = stv0900_get_demod_lock(i_params, demod, demod_timeout); + lock = stv0900_get_demod_lock(intp, demod, demod_timeout); if ((lock == FALSE) && (algo == STV0900_COLD_START)) { if (low_sr == FALSE) { - if (stv0900_check_timing_lock(i_params, demod) == TRUE) - lock = stv0900_sw_algo(i_params, demod); + if (stv0900_check_timing_lock(intp, demod) == TRUE) + lock = stv0900_sw_algo(intp, demod); } } @@ -2751,98 +1937,64 @@ enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe) if ((lock == TRUE) && (signal_type == STV0900_RANGEOK)) { stv0900_track_optimization(fe); - if (i_params->chip_id <= 0x11) { - if ((stv0900_get_standard(fe, STV0900_DEMOD_1) == STV0900_DVBS1_STANDARD) && (stv0900_get_standard(fe, STV0900_DEMOD_2) == STV0900_DVBS1_STANDARD)) { + if (intp->chip_id <= 0x11) { + if ((stv0900_get_standard(fe, 0) == + STV0900_DVBS1_STANDARD) && + (stv0900_get_standard(fe, 1) == + STV0900_DVBS1_STANDARD)) { msleep(20); - stv0900_write_bits(i_params, stream_merger_field, 0); + stv0900_write_bits(intp, RST_HWARE, 0); } else { - stv0900_write_bits(i_params, stream_merger_field, 0); + stv0900_write_bits(intp, RST_HWARE, 0); msleep(3); - stv0900_write_bits(i_params, stream_merger_field, 1); - stv0900_write_bits(i_params, stream_merger_field, 0); + stv0900_write_bits(intp, RST_HWARE, 1); + stv0900_write_bits(intp, RST_HWARE, 0); } - } else if (i_params->chip_id == 0x20) { - stv0900_write_bits(i_params, stream_merger_field, 0); + + } else if (intp->chip_id >= 0x20) { + stv0900_write_bits(intp, RST_HWARE, 0); msleep(3); - stv0900_write_bits(i_params, stream_merger_field, 1); - stv0900_write_bits(i_params, stream_merger_field, 0); + stv0900_write_bits(intp, RST_HWARE, 1); + stv0900_write_bits(intp, RST_HWARE, 0); } - if (stv0900_wait_for_lock(i_params, demod, fec_timeout, fec_timeout) == TRUE) { + if (stv0900_wait_for_lock(intp, demod, + fec_timeout, fec_timeout) == TRUE) { lock = TRUE; - switch (demod) { - case STV0900_DEMOD_1: - default: - i_params->dmd1_rslts.locked = TRUE; - if (i_params->dmd1_rslts.standard == STV0900_DVBS2_STANDARD) { - stv0900_set_dvbs2_rolloff(i_params, demod); - stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0x40); - stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0); - stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67); - } else { - stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75); - } - - stv0900_write_reg(i_params, R0900_P1_FBERCPT4, 0); - stv0900_write_reg(i_params, R0900_P1_ERRCTRL2, 0xc1); - break; - case STV0900_DEMOD_2: - i_params->dmd2_rslts.locked = TRUE; - - if (i_params->dmd2_rslts.standard == STV0900_DVBS2_STANDARD) { - stv0900_set_dvbs2_rolloff(i_params, demod); - stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x60); - stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x20); - stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67); - } else { - stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75); - } - - stv0900_write_reg(i_params, R0900_P2_FBERCPT4, 0); - - stv0900_write_reg(i_params, R0900_P2_ERRCTRL2, 0xc1); - break; + intp->result[demod].locked = TRUE; + if (intp->result[demod].standard == + STV0900_DVBS2_STANDARD) { + stv0900_set_dvbs2_rolloff(intp, demod); + stv0900_write_bits(intp, RESET_UPKO_COUNT, 1); + stv0900_write_bits(intp, RESET_UPKO_COUNT, 0); + stv0900_write_reg(intp, ERRCTRL1, 0x67); + } else { + stv0900_write_reg(intp, ERRCTRL1, 0x75); } + + stv0900_write_reg(intp, FBERCPT4, 0); + stv0900_write_reg(intp, ERRCTRL2, 0xc1); } else { lock = FALSE; signal_type = STV0900_NODATA; - no_signal = stv0900_check_signal_presence(i_params, demod); - - switch (demod) { - case STV0900_DEMOD_1: - default: - i_params->dmd1_rslts.locked = FALSE; - break; - case STV0900_DEMOD_2: - i_params->dmd2_rslts.locked = FALSE; - break; - } + no_signal = stv0900_check_signal_presence(intp, demod); + + intp->result[demod].locked = FALSE; } } - if ((signal_type == STV0900_NODATA) && (no_signal == FALSE)) { - switch (demod) { - case STV0900_DEMOD_1: - default: - if (i_params->chip_id <= 0x11) { - if ((stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) && - (i_params->dmd1_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST)) - signal_type = stv0900_dvbs1_acq_workaround(fe); - } else - i_params->dmd1_rslts.locked = FALSE; + if ((signal_type != STV0900_NODATA) || (no_signal != FALSE)) + return signal_type; - break; - case STV0900_DEMOD_2: - if (i_params->chip_id <= 0x11) { - if ((stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) && - (i_params->dmd2_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST)) - signal_type = stv0900_dvbs1_acq_workaround(fe); - } else - i_params->dmd2_rslts.locked = FALSE; - break; - } + if (intp->chip_id > 0x11) { + intp->result[demod].locked = FALSE; + return signal_type; } + if ((stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) && + (intp->srch_iq_inv[demod] <= STV0900_IQ_AUTO_NORMAL_FIRST)) + signal_type = stv0900_dvbs1_acq_workaround(fe); + return signal_type; } -- cgit v1.2.3-70-g09d2 From aee0b24c05f6e9615115748a8ea5042d8ee0e6a0 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 11 Nov 2009 01:52:45 -0300 Subject: V4L/DVB (13347): cx23885: add digital television support for Hauppauge WinTV-HVR1290 Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.cx23885 | 1 + drivers/media/video/cx23885/cx23885-cards.c | 12 ++++++++++++ drivers/media/video/cx23885/cx23885-dvb.c | 1 + drivers/media/video/cx23885/cx23885.h | 1 + 4 files changed, 15 insertions(+) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885 index 5f33d848610..be293346ffe 100644 --- a/Documentation/video4linux/CARDLIST.cx23885 +++ b/Documentation/video4linux/CARDLIST.cx23885 @@ -24,3 +24,4 @@ 23 -> Magic-Pro ProHDTV Extreme 2 [14f1:8657] 24 -> Hauppauge WinTV-HVR1850 [0070:8541] 25 -> Compro VideoMate E800 [1858:e800] + 26 -> Hauppauge WinTV-HVR1290 [0070:8551] diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 2cbac93866b..2f4db970152 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -265,6 +265,10 @@ struct cx23885_board cx23885_boards[] = { .name = "Compro VideoMate E800", .portc = CX23885_MPEG_DVB, }, + [CX23885_BOARD_HAUPPAUGE_HVR1290] = { + .name = "Hauppauge WinTV-HVR1290", + .portc = CX23885_MPEG_DVB, + }, }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); @@ -400,6 +404,10 @@ struct cx23885_subid cx23885_subids[] = { .subvendor = 0x1858, .subdevice = 0xe800, .card = CX23885_BOARD_COMPRO_VIDEOMATE_E800, + }, { + .subvendor = 0x0070, + .subdevice = 0x8551, + .card = CX23885_BOARD_HAUPPAUGE_HVR1290, }, }; const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); @@ -819,6 +827,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) mdelay(100); break; case CX23885_BOARD_HAUPPAUGE_HVR1850: + case CX23885_BOARD_HAUPPAUGE_HVR1290: /* GPIO-0 656_CLK */ /* GPIO-1 656_D0 */ /* GPIO-2 Wake# */ @@ -934,6 +943,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1255: case CX23885_BOARD_HAUPPAUGE_HVR1210: case CX23885_BOARD_HAUPPAUGE_HVR1850: + case CX23885_BOARD_HAUPPAUGE_HVR1290: if (dev->i2c_bus[0].i2c_rc == 0) hauppauge_eeprom(dev, eeprom+0xc0); break; @@ -1003,6 +1013,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1210: case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_COMPRO_VIDEOMATE_E800: + case CX23885_BOARD_HAUPPAUGE_HVR1290: default: ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ @@ -1023,6 +1034,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_MYGICA_X8506: case CX23885_BOARD_MAGICPRO_PROHDTVE2: + case CX23885_BOARD_HAUPPAUGE_HVR1290: dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_bus[2].i2c_adap, "cx25840", "cx25840", 0x88 >> 1, NULL); diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 44e5fade048..133e8029071 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -898,6 +898,7 @@ static int dvb_register(struct cx23885_tsport *port) } break; case CX23885_BOARD_HAUPPAUGE_HVR1850: + case CX23885_BOARD_HAUPPAUGE_HVR1290: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1411_attach, &hcw_s5h1411_config, diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index 813eaf7c5e9..12d1a344a8a 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h @@ -79,6 +79,7 @@ #define CX23885_BOARD_MAGICPRO_PROHDTVE2 23 #define CX23885_BOARD_HAUPPAUGE_HVR1850 24 #define CX23885_BOARD_COMPRO_VIDEOMATE_E800 25 +#define CX23885_BOARD_HAUPPAUGE_HVR1290 26 #define GPIO_0 0x00000001 #define GPIO_1 0x00000002 -- cgit v1.2.3-70-g09d2 From 73a5f4196dcdf1f5b0bcfa208cb485c4fde840cc Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 11 Nov 2009 10:46:40 -0300 Subject: V4L/DVB (13348): cx23885: update model matrix for models 85021 and 85721 Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-cards.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 2f4db970152..632d76a432a 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -568,9 +568,13 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) * DVB-T and MPEG2 HW Encoder */ break; case 85021: - /* WinTV-HVR1850 (PCIe, OEM, RCA in, IR, FM, + /* WinTV-HVR1850 (PCIe, Retail, 3.5mm in, IR, FM, Dual channel ATSC and MPEG2 HW Encoder */ break; + case 85721: + /* WinTV-HVR1290 (PCIe, OEM, RCA in, IR, + Dual channel ATSC and Basic analog */ + break; default: printk(KERN_WARNING "%s: warning: " "unknown hauppauge model #%d\n", -- cgit v1.2.3-70-g09d2 From 7fec6fee56def62a53e3bc4db5baf6bca12c3474 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 11 Nov 2009 15:46:09 -0300 Subject: V4L/DVB (13349): cx23885: Enable IR input keypress handling for the Hauppauge WinTV HVR-1290 The IR on the HVR-1290 is identical to that of the HVR-1850 Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-cards.c | 3 +++ drivers/media/video/cx23885/cx23885-input.c | 5 +++++ 2 files changed, 8 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 632d76a432a..d9d71c8c794 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -881,6 +881,7 @@ int cx23885_ir_init(struct cx23885_dev *dev) /* FIXME: Implement me */ break; case CX23885_BOARD_HAUPPAUGE_HVR1850: + case CX23885_BOARD_HAUPPAUGE_HVR1290: ret = cx23888_ir_probe(dev); if (ret) break; @@ -899,6 +900,7 @@ void cx23885_ir_fini(struct cx23885_dev *dev) { switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1850: + case CX23885_BOARD_HAUPPAUGE_HVR1290: dev->pci_irqmask &= ~PCI_MSK_IR; cx_clear(PCI_INT_MSK, PCI_MSK_IR); cx23888_ir_remove(dev); @@ -911,6 +913,7 @@ void cx23885_ir_pci_int_enable(struct cx23885_dev *dev) { switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1850: + case CX23885_BOARD_HAUPPAUGE_HVR1290: if (dev->sd_ir && (dev->pci_irqmask & PCI_MSK_IR)) cx_set(PCI_INT_MSK, PCI_MSK_IR); break; diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c index c208079f4e9..f000ed787d4 100644 --- a/drivers/media/video/cx23885/cx23885-input.c +++ b/drivers/media/video/cx23885/cx23885-input.c @@ -202,6 +202,7 @@ void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events) switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1850: + case CX23885_BOARD_HAUPPAUGE_HVR1290: /* * The only board we handle right now. However other boards * using the CX2388x integrated IR controller should be similar @@ -252,6 +253,7 @@ static void cx23885_input_ir_start(struct cx23885_dev *dev) /* keyup timer set up, if needed */ switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1850: + case CX23885_BOARD_HAUPPAUGE_HVR1290: setup_timer(&ir_input->timer_keyup, ir_rc5_timer_keyup, /* Not actually RC-5 specific */ (unsigned long) ir_input); @@ -268,6 +270,7 @@ static void cx23885_input_ir_start(struct cx23885_dev *dev) v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, ¶ms); switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1850: + case CX23885_BOARD_HAUPPAUGE_HVR1290: /* * The IR controller on this board only returns pulse widths. * Any other mode setting will fail to set up the device. @@ -325,6 +328,7 @@ static void cx23885_input_ir_stop(struct cx23885_dev *dev) switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1850: + case CX23885_BOARD_HAUPPAUGE_HVR1290: del_timer_sync(&ir_input->timer_keyup); break; } @@ -347,6 +351,7 @@ int cx23885_input_init(struct cx23885_dev *dev) switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1850: + case CX23885_BOARD_HAUPPAUGE_HVR1290: /* Parameters for the grey Hauppauge remote for the HVR-1850 */ ir_codes = &ir_codes_hauppauge_new_table; ir_type = IR_TYPE_RC5; -- cgit v1.2.3-70-g09d2 From c879d8cef4c5fc31ff2ab6e5b83bf4a537e77844 Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Fri, 13 Nov 2009 18:11:26 -0300 Subject: V4L/DVB (13351): stv090x: increases search range based on symbol rate Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 488bdfb34fb..6c99a86c8ef 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -3296,7 +3296,13 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_fron state->search_mode = STV090x_SEARCH_AUTO; state->algo = STV090x_COLD_SEARCH; state->fec = STV090x_PRERR; - state->search_range = 2000000; + if (state->srate > 10000000) { + dprintk(FE_DEBUG, 1, "Search range: 10 MHz"); + state->search_range = 10000000; + } else { + dprintk(FE_DEBUG, 1, "Search range: 5 MHz"); + state->search_range = 5000000; + } if (stv090x_algo(state) == STV090x_RANGEOK) { dprintk(FE_DEBUG, 1, "Search success!"); -- cgit v1.2.3-70-g09d2 From 45433d3f8dec42179ebe0f27966073a71fd1c612 Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Fri, 13 Nov 2009 18:12:48 -0300 Subject: V4L/DVB (13352): stv090x: fixes errors and typos in register definitions Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x_reg.h | 70 +++++++++++++++---------------- 1 file changed, 34 insertions(+), 36 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv090x_reg.h b/drivers/media/dvb/frontends/stv090x_reg.h index 57b6abbbd32..2502855dd78 100644 --- a/drivers/media/dvb/frontends/stv090x_reg.h +++ b/drivers/media/dvb/frontends/stv090x_reg.h @@ -44,7 +44,7 @@ #define STV090x_OFFST_OUTSERRS2_HZ_FIELD 5 #define STV090x_WIDTH_OUTSERRS2_HZ_FIELD 1 #define STV090x_OFFST_OUTSERRS3_HZ_FIELD 4 -#define STV090x_WIDTH_OUTPARRS3_HZ_FIELD 1 +#define STV090x_WIDTH_OUTSERRS3_HZ_FIELD 1 #define STV090x_OFFST_OUTPARRS3_HZ_FIELD 3 #define STV090x_WIDTH_OUTPARRS3_HZ_FIELD 1 @@ -113,24 +113,24 @@ #define STV090x_IRQMASK3 0xf124 #define STV090x_OFFST_MPLL_LOCK_FIELD 5 #define STV090x_WIDTH_MPLL_LOCK_FIELD 1 -#define STV090x_OFFST_MSTREAM_LCK_3_FIELD 2 -#define STV090x_WIDTH_MSTREAM_LCK_3_FIELD 3 -#define STV090x_OFFST_MSTREAM_LCK_2_FIELD 2 -#define STV090x_WIDTH_MSTREAM_LCK_2_FIELD 3 +#define STV090x_OFFST_MSTREAM_LCK_3_FIELD 4 +#define STV090x_WIDTH_MSTREAM_LCK_3_FIELD 1 +#define STV090x_OFFST_MSTREAM_LCK_2_FIELD 3 +#define STV090x_WIDTH_MSTREAM_LCK_2_FIELD 1 #define STV090x_OFFST_MSTREAM_LCK_1_FIELD 2 -#define STV090x_WIDTH_MSTREAM_LCK_1_FIELD 3 +#define STV090x_WIDTH_MSTREAM_LCK_1_FIELD 1 #define STV090x_OFFST_MDVBS1_PRF_2_FIELD 1 #define STV090x_WIDTH_MDVBS1_PRF_2_FIELD 1 #define STV090x_OFFST_MDVBS1_PRF_1_FIELD 0 #define STV090x_WIDTH_MDVBS1_PRF_1_FIELD 1 #define STV090x_IRQMASK2 0xf125 -#define STV090x_OFFST_MSPY_ENDSIM_3_FIELD 5 -#define STV090x_WIDTH_MSPY_ENDSIM_3_FIELD 3 -#define STV090x_OFFST_MSPY_ENDSIM_2_FIELD 5 -#define STV090x_WIDTH_MSPY_ENDSIM_2_FIELD 3 +#define STV090x_OFFST_MSPY_ENDSIM_3_FIELD 7 +#define STV090x_WIDTH_MSPY_ENDSIM_3_FIELD 1 +#define STV090x_OFFST_MSPY_ENDSIM_2_FIELD 6 +#define STV090x_WIDTH_MSPY_ENDSIM_2_FIELD 1 #define STV090x_OFFST_MSPY_ENDSIM_1_FIELD 5 -#define STV090x_WIDTH_MSPY_ENDSIM_1_FIELD 3 +#define STV090x_WIDTH_MSPY_ENDSIM_1_FIELD 1 #define STV090x_OFFST_MPKTDEL_ERROR_2_FIELD 4 #define STV090x_WIDTH_MPKTDEL_ERROR_2_FIELD 1 #define STV090x_OFFST_MPKTDEL_LOCKB_2_FIELD 3 @@ -370,7 +370,7 @@ #define STV090x_OFFST_SELX1RATIO_FIELD 5 #define STV090x_WIDTH_SELX1RATIO_FIELD 1 #define STV090x_OFFST_STOP_PLL_FIELD 3 -#define STV090x_WIDTH_SELX1RATIO_FIELD 1 +#define STV090x_WIDTH_STOP_PLL_FIELD 1 #define STV090x_OFFST_BYPASSPLLFSK_FIELD 2 #define STV090x_WIDTH_BYPASSPLLFSK_FIELD 1 #define STV090x_OFFST_SELOSCI_FIELD 1 @@ -616,7 +616,7 @@ #define STV090x_OFFST_Px_CONT_TONE_FIELD 4 #define STV090x_WIDTH_Px_CONT_TONE_FIELD 1 #define STV090x_OFFST_Px_FIFO_4BREADY_FIELD 3 -#define STV090x_WIDTH_Px_FIFO_4BREADY_FIELD 2 +#define STV090x_WIDTH_Px_FIFO_4BREADY_FIELD 1 #define STV090x_OFFST_Px_FIFO_EMPTY_FIELD 2 #define STV090x_WIDTH_Px_FIFO_EMPTY_FIELD 1 #define STV090x_OFFST_Px_ABORT_DISRX_FIELD 0 @@ -847,12 +847,10 @@ #define STV090x_WIDTH_Px_DVBS2_ENABLE_FIELD 1 #define STV090x_OFFST_Px_DVBS1_ENABLE_FIELD 6 #define STV090x_WIDTH_Px_DVBS1_ENABLE_FIELD 1 -#define STV090x_OFFST_Px_CFR_AUTOSCAN_FIELD 5 /* check */ -#define STV090x_WIDTH_Px_CFR_AUTOSCAN_FIELD 1 -#define STV090x_OFFST_Px_SCAN_ENABLE_FIELD 4 /* check */ +#define STV090x_OFFST_Px_SCAN_ENABLE_FIELD 4 #define STV090x_WIDTH_Px_SCAN_ENABLE_FIELD 1 -#define STV090x_OFFST_Px_TUN_AUTOSCAN_FIELD 3 -#define STV090x_WIDTH_Px_TUN_AUTOSCAN_FIELD 1 +#define STV090x_OFFST_Px_CFR_AUTOSCAN_FIELD 3 +#define STV090x_WIDTH_Px_CFR_AUTOSCAN_FIELD 1 #define STV090x_OFFST_Px_NOFORCE_RELOCK_FIELD 2 #define STV090x_WIDTH_Px_NOFORCE_RELOCK_FIELD 1 #define STV090x_OFFST_Px_TUN_RNG_FIELD 0 @@ -885,7 +883,7 @@ #define STV090x_P2_DMDFLYW STV090x_Px_DMDFLYW(2) #define STV090x_OFFST_Px_I2C_IRQVAL_FIELD 4 #define STV090x_WIDTH_Px_I2C_IRQVAL_FIELD 4 -#define STV090x_OFFST_Px_FLYWHEEL_CPT_FIELD 0 /* check */ +#define STV090x_OFFST_Px_FLYWHEEL_CPT_FIELD 0 #define STV090x_WIDTH_Px_FLYWHEEL_CPT_FIELD 4 #define STV090x_Px_DSTATUS3(__x) (0xF41D - (__x - 1) * 0x200) @@ -1048,12 +1046,12 @@ #define STV090x_P1_CFRINC1 STV090x_Px_CFRINC1(1) #define STV090x_P2_CFRINC1 STV090x_Px_CFRINC1(2) #define STV090x_OFFST_Px_CFR_INC1_FIELD 0 -#define STV090x_WIDTH_Px_CFR_INC1_FIELD 7 +#define STV090x_WIDTH_Px_CFR_INC1_FIELD 7 /* check */ #define STV090x_Px_CFRINC0(__x) (0xF44B - (__x - 1) * 0x200) #define STV090x_P1_CFRINC0 STV090x_Px_CFRINC0(1) #define STV090x_P2_CFRINC0 STV090x_Px_CFRINC0(2) -#define STV090x_OFFST_Px_CFR_INC0_FIELD 4 +#define STV090x_OFFST_Px_CFR_INC0_FIELD 4 /* check */ #define STV090x_WIDTH_Px_CFR_INC0_FIELD 4 #define STV090x_Pn_CFRy(__x, __y) (0xF44E - (__x - 1) * 0x200 - __y * 0x1) @@ -1145,14 +1143,14 @@ #define STV090x_Px_SFRINIT1(__x) (0xF45E - (__x - 1) * 0x200) #define STV090x_P1_SFRINIT1 STV090x_Px_SFRINIT1(1) #define STV090x_P2_SFRINIT1 STV090x_Px_SFRINIT1(2) -#define STV090x_OFFST_Px_SFR_INIT_FIELD 0 -#define STV090x_WIDTH_Px_SFR_INIT_FIELD 8 +#define STV090x_OFFST_Px_SFR_INIT1_FIELD 0 +#define STV090x_WIDTH_Px_SFR_INIT1_FIELD 7 #define STV090x_Px_SFRINIT0(__x) (0xF45F - (__x - 1) * 0x200) #define STV090x_P1_SFRINIT0 STV090x_Px_SFRINIT0(1) #define STV090x_P2_SFRINIT0 STV090x_Px_SFRINIT0(2) -#define STV090x_OFFST_Px_SFR_INIT_FIELD 0 -#define STV090x_WIDTH_Px_SFR_INIT_FIELD 8 +#define STV090x_OFFST_Px_SFR_INIT0_FIELD 0 +#define STV090x_WIDTH_Px_SFR_INIT0_FIELD 8 #define STV090x_Px_SFRUP1(__x) (0xF460 - (__x - 1) * 0x200) #define STV090x_P1_SFRUP1 STV090x_Px_SFRUP1(1) @@ -1178,7 +1176,7 @@ #define STV090x_OFFST_Px_SYMB_FREQ_LOW0_FIELD 0 #define STV090x_WIDTH_Px_SYMB_FREQ_LOW0_FIELD 8 -#define STV090x_Px_SFRy(__x, __y) (0xF464 - (__x-1) * 0x200 + (3 - __y)) +#define STV090x_Px_SFRy(__x, __y) (0xF467 - (__x-1) * 0x200 - __y) #define STV090x_P1_SFR0 STV090x_Px_SFRy(1, 0) #define STV090x_P1_SFR1 STV090x_Px_SFRy(1, 1) #define STV090x_P1_SFR2 STV090x_Px_SFRy(1, 2) @@ -1188,7 +1186,7 @@ #define STV090x_P2_SFR2 STV090x_Px_SFRy(2, 2) #define STV090x_P2_SFR3 STV090x_Px_SFRy(2, 3) #define STV090x_OFFST_Px_SYMB_FREQ_FIELD 0 -#define STV090x_WIDTH_Px_SYMB_FREQ_FIELD 32 +#define STV090x_WIDTH_Px_SYMB_FREQ_FIELD 8 #define STV090x_Px_TMGREG2(__x) (0xF468 - (__x - 1) * 0x200) #define STV090x_P1_TMGREG2 STV090x_Px_TMGREG2(1) @@ -1198,7 +1196,7 @@ #define STV090x_Px_TMGREG1(__x) (0xF469 - (__x - 1) * 0x200) #define STV090x_P1_TMGREG1 STV090x_Px_TMGREG1(1) -#define STV090x_P2_TMGREG1 STV090x_Px_TMGREG1(2) +#define STV090x_P2_TMGREG1 STV090x_Px_TMGREG1(2) #define STV090x_OFFST_Px_TMGREG_FIELD 0 #define STV090x_WIDTH_Px_TMGREG_FIELD 8 @@ -1230,7 +1228,7 @@ #define STV090x_OFFST_Px_MU_EQUALDFE_FIELD 0 #define STV090x_WIDTH_Px_MU_EQUALDFE_FIELD 3 -#define STV090x_Px_EQUAIy(__x, __y) (0xf470 - (__x - 1) * 0x200 + (__y - 1)) +#define STV090x_Px_EQUAIy(__x, __y) (0xf470 - (__x-1) * 0x200 + 2 * (__y-1)) #define STV090x_P1_EQUAI1 STV090x_Px_EQUAIy(1, 1) #define STV090x_P1_EQUAI2 STV090x_Px_EQUAIy(1, 2) #define STV090x_P1_EQUAI3 STV090x_Px_EQUAIy(1, 3) @@ -1251,7 +1249,7 @@ #define STV090x_OFFST_Px_EQUA_ACCIy_FIELD 0 #define STV090x_WIDTH_Px_EQUA_ACCIy_FIELD 8 -#define STV090x_Px_EQUAQy(__x, __y) (0xf471 - (__x - 1) * 0x200 + (__y - 1)) +#define STV090x_Px_EQUAQy(__x, __y) (0xf471 - (__x-1) * 0x200 + 2 * (__y-1)) #define STV090x_P1_EQUAQ1 STV090x_Px_EQUAQy(1, 1) #define STV090x_P1_EQUAQ2 STV090x_Px_EQUAQy(1, 2) #define STV090x_P1_EQUAQ3 STV090x_Px_EQUAQy(1, 3) @@ -1390,7 +1388,7 @@ #define STV090x_OFFST_Px_CAR2S2_16A_ALPH_E_FIELD 0 #define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_E_FIELD 4 -#define STV090x_Px_ACLC2S232A(__x) (0xf499 - (__x - 1) * 0x200) +#define STV090x_Px_ACLC2S232A(__x) (0xf49A - (__x - 1) * 0x200) #define STV090x_P1_ACLC2S232A STV090x_Px_ACLC2S232A(1) #define STV090x_P2_ACLC2S232A STV090x_Px_ACLC2S232A(2) #define STV090x_OFFST_Px_CAR2S2_32A_ALPH_M_FIELD 4 @@ -1414,7 +1412,7 @@ #define STV090x_OFFST_Px_CAR2S2_8_BETA_E_FIELD 0 #define STV090x_WIDTH_Px_CAR2S2_8_BETA_E_FIELD 4 -#define STV090x_Px_BCLC2S216A(__x) (0xf49d - (__x - 1) * 0x200) +#define STV090x_Px_BCLC2S216A(__x) (0xf49e - (__x - 1) * 0x200) #define STV090x_P1_BCLC2S216A STV090x_Px_BCLC2S216A(1) #define STV090x_P2_BCLC2S216A STV090x_Px_BCLC2S216A(1) #define STV090x_OFFST_Px_CAR2S2_16A_BETA_M_FIELD 4 @@ -1422,7 +1420,7 @@ #define STV090x_OFFST_Px_CAR2S2_16A_BETA_E_FIELD 0 #define STV090x_WIDTH_Px_CAR2S2_16A_BETA_E_FIELD 4 -#define STV090x_Px_BCLC2S232A(__x) (0xf49d - (__x - 1) * 0x200) +#define STV090x_Px_BCLC2S232A(__x) (0xf49f - (__x - 1) * 0x200) #define STV090x_P1_BCLC2S232A STV090x_Px_BCLC2S232A(1) #define STV090x_P2_BCLC2S232A STV090x_Px_BCLC2S232A(1) #define STV090x_OFFST_Px_CAR2S2_32A_BETA_M_FIELD 4 @@ -1458,7 +1456,7 @@ #define STV090x_P1_MODCODLST1 STV090x_Px_MODCODLST1(1) #define STV090x_P2_MODCODLST1 STV090x_Px_MODCODLST1(2) #define STV090x_OFFST_Px_DIS_MODCOD29_FIELD 4 -#define STV090x_WIDTH_Px_DIS_MODCOD29T_FIELD 4 +#define STV090x_WIDTH_Px_DIS_MODCOD29_FIELD 4 #define STV090x_OFFST_Px_DIS_32PSK_9_10_FIELD 0 #define STV090x_WIDTH_Px_DIS_32PSK_9_10_FIELD 4 @@ -2180,7 +2178,7 @@ #define STV090x_WIDTH_Px_TSFIFOSPEED_STORE_FIELD 1 #define STV090x_OFFST_Px_DILXX_RESET_FIELD 5 #define STV090x_WIDTH_Px_DILXX_RESET_FIELD 1 -#define STV090x_OFFST_Px_TSSERIAL_IMPOS_FIELD 5 +#define STV090x_OFFST_Px_TSSERIAL_IMPOS_FIELD 4 #define STV090x_WIDTH_Px_TSSERIAL_IMPOS_FIELD 1 #define STV090x_OFFST_Px_SCRAMBDETECT_FIELD 1 #define STV090x_WIDTH_Px_SCRAMBDETECT_FIELD 1 @@ -2190,7 +2188,7 @@ #define STV090x_P1_TSBITRATE1 STV090x_Px_TSBITRATEy(1, 1) #define STV090x_P2_TSBITRATE0 STV090x_Px_TSBITRATEy(2, 0) #define STV090x_P2_TSBITRATE1 STV090x_Px_TSBITRATEy(2, 1) -#define STV090x_OFFST_Px_TSFIFO_BITRATE_FIELD 7 +#define STV090x_OFFST_Px_TSFIFO_BITRATE_FIELD 0 #define STV090x_WIDTH_Px_TSFIFO_BITRATE_FIELD 8 #define STV090x_Px_ERRCTRL1(__x) (0xF598 - (__x - 1) * 0x200) -- cgit v1.2.3-70-g09d2 From dbeb7dbf867dc976c66332e6f2c3e24bf87df258 Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Fri, 13 Nov 2009 18:14:00 -0300 Subject: V4L/DVB (13353): stv090x: fixes STR and SNR calculation and normalizes the value into the 0..0xFFFF range Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 58 +++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 19 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 6c99a86c8ef..e74419b682d 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -3418,14 +3418,12 @@ static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val) int res = 0; int min = 0, med; - if (val < tab[min].read) - res = tab[min].real; - else if (val >= tab[max].read) - res = tab[max].real; - else { + if ((val >= tab[min].read && val < tab[max].read) || + (val >= tab[max].read && val < tab[min].read)) { while ((max - min) > 1) { med = (max + min) / 2; - if (val >= tab[min].read && val < tab[med].read) + if ((val >= tab[min].read && val < tab[med].read) || + (val >= tab[med].read && val < tab[min].read)) max = med; else min = med; @@ -3434,6 +3432,18 @@ static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val) (tab[max].real - tab[min].real) / (tab[max].read - tab[min].read)) + tab[min].real; + } else { + if (tab[min].read < tab[max].read) { + if (val < tab[min].read) + res = tab[min].real; + else if (val >= tab[max].read) + res = tab[max].real; + } else { + if (val >= tab[min].read) + res = tab[min].real; + else if (val < tab[max].read) + res = tab[max].real; + } } return res; @@ -3443,16 +3453,22 @@ static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { struct stv090x_state *state = fe->demodulator_priv; u32 reg; - s32 agc; + s32 agc_0, agc_1, agc; + s32 str; reg = STV090x_READ_DEMOD(state, AGCIQIN1); - agc = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD); + agc_1 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD); + reg = STV090x_READ_DEMOD(state, AGCIQIN0); + agc_0 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD); + agc = MAKEWORD16(agc_1, agc_0); - *strength = stv090x_table_lookup(stv090x_rf_tab, ARRAY_SIZE(stv090x_rf_tab) - 1, agc); + str = stv090x_table_lookup(stv090x_rf_tab, + ARRAY_SIZE(stv090x_rf_tab) - 1, agc); if (agc > stv090x_rf_tab[0].read) - *strength = 5; + str = 0; else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read) - *strength = -100; + str = -100; + *strength = (str + 100) * 0xFFFF / 100; return 0; } @@ -3463,6 +3479,8 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) u32 reg_0, reg_1, reg, i; s32 val_0, val_1, val = 0; u8 lock_f; + s32 div; + u32 last; switch (state->delsys) { case STV090x_DVBS2: @@ -3474,14 +3492,15 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) reg_1 = STV090x_READ_DEMOD(state, NNOSPLHT1); val_1 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD); reg_0 = STV090x_READ_DEMOD(state, NNOSPLHT0); - val_0 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD); + val_0 = STV090x_GETFIELD_Px(reg_0, NOSPLHT_NORMED_FIELD); val += MAKEWORD16(val_1, val_0); msleep(1); } val /= 16; - *cnr = stv090x_table_lookup(stv090x_s2cn_tab, ARRAY_SIZE(stv090x_s2cn_tab) - 1, val); - if (val < stv090x_s2cn_tab[ARRAY_SIZE(stv090x_s2cn_tab) - 1].read) - *cnr = 1000; + last = ARRAY_SIZE(stv090x_s2cn_tab) - 1; + div = stv090x_s2cn_tab[0].read - + stv090x_s2cn_tab[last].read; + *cnr = 0xFFFF - ((val * 0xFFFF) / div); } break; @@ -3495,14 +3514,15 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) reg_1 = STV090x_READ_DEMOD(state, NOSDATAT1); val_1 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD); reg_0 = STV090x_READ_DEMOD(state, NOSDATAT0); - val_0 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD); + val_0 = STV090x_GETFIELD_Px(reg_0, NOSDATAT_UNNORMED_FIELD); val += MAKEWORD16(val_1, val_0); msleep(1); } val /= 16; - *cnr = stv090x_table_lookup(stv090x_s1cn_tab, ARRAY_SIZE(stv090x_s1cn_tab) - 1, val); - if (val < stv090x_s2cn_tab[ARRAY_SIZE(stv090x_s1cn_tab) - 1].read) - *cnr = 1000; + last = ARRAY_SIZE(stv090x_s1cn_tab) - 1; + div = stv090x_s1cn_tab[0].read - + stv090x_s1cn_tab[last].read; + *cnr = 0xFFFF - ((val * 0xFFFF) / div); } break; default: -- cgit v1.2.3-70-g09d2 From b671a8d4b68626142a9a34da59c55396d2cf0ce9 Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Fri, 13 Nov 2009 18:15:27 -0300 Subject: V4L/DVB (13354): stv090x: fixes some typos like wrong register or variable names Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index e74419b682d..fe03bac5b2e 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -825,7 +825,7 @@ static int stv090x_set_min_srate(struct stv090x_state *state, u32 clk, u32 srate sym /= (state->mclk >> 7); } - if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0xff)) < 0) /* MSB */ + if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0x7f)) < 0) /* MSB */ goto err; if (STV090x_WRITE_DEMOD(state, SFRLOW0, (sym & 0xff)) < 0) /* LSB */ goto err; @@ -1317,7 +1317,7 @@ static int stv090x_start_search(struct stv090x_state *state) goto err; if (STV090x_WRITE_DEMOD(state, CFRUP1, 0x0f) < 0) goto err; - if (STV090x_WRITE_DEMOD(state, CFRUP1, 0xff) < 0) + if (STV090x_WRITE_DEMOD(state, CFRUP0, 0xff) < 0) goto err; if (STV090x_WRITE_DEMOD(state, CFRLOW1, 0xf0) < 0) goto err; @@ -1371,7 +1371,7 @@ static int stv090x_start_search(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, CFRUP1, MSB(freq)) < 0) goto err; - if (STV090x_WRITE_DEMOD(state, CFRUP1, LSB(freq)) < 0) + if (STV090x_WRITE_DEMOD(state, CFRUP0, LSB(freq)) < 0) goto err; freq *= -1; @@ -1525,7 +1525,7 @@ static int stv090x_get_agc2_min_level(struct stv090x_state *state) else freq_init = freq_init - (freq_step * i); - dir = -1; + dir *= -1; if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod RESET */ goto err; @@ -2425,7 +2425,7 @@ static s32 stv090x_get_car_freq(struct stv090x_state *state, u32 mclk) derot = (int_1 * int_2) + ((int_1 * tmp_2) >> 12) + - ((int_1 * tmp_1) >> 12); + ((int_2 * tmp_1) >> 12); return derot; } @@ -2732,7 +2732,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) switch (state->delsys) { case STV090x_DVBS1: case STV090x_DSS: - if (state->algo == STV090x_SEARCH_AUTO) { + if (state->search_mode == STV090x_SEARCH_AUTO) { reg = STV090x_READ_DEMOD(state, DMDCFGMD); STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); -- cgit v1.2.3-70-g09d2 From b4a4248d56a6985f5d37fc5a219ba0675fc6f503 Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Fri, 13 Nov 2009 18:16:44 -0300 Subject: V4L/DVB (13355): stv090x: fixes calculation of AGC2 and uses a different AGC2 threshold for cut 3 chips Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 33 ++++++++++++++++++++---------- drivers/media/dvb/frontends/stv090x_priv.h | 2 +- 2 files changed, 23 insertions(+), 12 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index fe03bac5b2e..8c0d351405f 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -1485,7 +1485,7 @@ err: static int stv090x_get_agc2_min_level(struct stv090x_state *state) { - u32 agc2_min = 0, agc2 = 0, freq_init, freq_step, reg; + u32 agc2_min = 0xffff, agc2 = 0, freq_init, freq_step, reg; s32 i, j, steps, dir; if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) @@ -1536,13 +1536,14 @@ static int stv090x_get_agc2_min_level(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x58) < 0) /* Demod RESET */ goto err; msleep(10); + + agc2 = 0; for (j = 0; j < 10; j++) { - agc2 += STV090x_READ_DEMOD(state, AGC2I1) << 8; - agc2 |= STV090x_READ_DEMOD(state, AGC2I0); + agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) | + STV090x_READ_DEMOD(state, AGC2I0); } agc2 /= 10; - agc2_min = 0xffff; - if (agc2 < 0xffff) + if (agc2 < agc2_min) agc2_min = agc2; } @@ -1584,6 +1585,12 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) int tmg_lock = 0, i; s32 tmg_cpt = 0, dir = 1, steps, cur_step = 0, freq; u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg; + u32 agc2th; + + if (state->dev_ver >= 0x30) + agc2th = 0x2e00; + else + agc2th = 0x1f00; reg = STV090x_READ_DEMOD(state, DMDISTATE); STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f); /* Demod RESET */ @@ -1611,7 +1618,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) goto err; if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0) goto err; - if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x60) < 0) + if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x50) < 0) goto err; if (state->dev_ver >= 0x30) { @@ -1661,14 +1668,15 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) reg = STV090x_READ_DEMOD(state, DSTATUS); if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2) tmg_cpt++; - agc2 += STV090x_READ_DEMOD(state, AGC2I1) << 8; - agc2 |= STV090x_READ_DEMOD(state, AGC2I0); + agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) | + STV090x_READ_DEMOD(state, AGC2I0); } agc2 /= 10; srate_coarse = stv090x_get_srate(state, state->mclk); cur_step++; dir *= -1; - if ((tmg_cpt >= 5) && (agc2 < 0x1f00) && (srate_coarse < 55000000) && (srate_coarse > 850000)) + if ((tmg_cpt >= 5) && (agc2 < agc2th) && + (srate_coarse < 50000000) && (srate_coarse > 850000)) tmg_lock = 1; else if (cur_step < steps) { if (dir > 0) @@ -1751,6 +1759,9 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) goto err; + if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) + goto err; + if (state->dev_ver >= 0x30) { if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0) goto err; @@ -1908,8 +1919,8 @@ static int stv090x_blind_search(struct stv090x_state *state) cpt_fail = 0; agc2_ovflw = 0; for (i = 0; i < 10; i++) { - agc2 = STV090x_READ_DEMOD(state, AGC2I1) << 8; - agc2 |= STV090x_READ_DEMOD(state, AGC2I0); + agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) | + STV090x_READ_DEMOD(state, AGC2I0); if (agc2 >= 0xff00) agc2_ovflw++; reg = STV090x_READ_DEMOD(state, DSTATUS2); diff --git a/drivers/media/dvb/frontends/stv090x_priv.h b/drivers/media/dvb/frontends/stv090x_priv.h index 5a4a01740d8..5696816b88a 100644 --- a/drivers/media/dvb/frontends/stv090x_priv.h +++ b/drivers/media/dvb/frontends/stv090x_priv.h @@ -83,7 +83,7 @@ #define STV090x_IQPOWER_THRESHOLD 30 #define STV090x_SEARCH_AGC2_TH_CUT20 700 -#define STV090x_SEARCH_AGC2_TH_CUT30 1200 +#define STV090x_SEARCH_AGC2_TH_CUT30 1400 #define STV090x_SEARCH_AGC2_TH(__ver) \ ((__ver <= 0x20) ? \ -- cgit v1.2.3-70-g09d2 From a4978a83e51324aed08b1f1105a58f7e6491b751 Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Fri, 13 Nov 2009 18:17:45 -0300 Subject: V4L/DVB (13356): stv090x: fixes signal lock logic This patch contains several fixes for the stv090x driver: - added missing else - use calculated timeout instead of fixed one - use correct frequency when doing zigzag scan - added missing read of GENCFG register Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 8c0d351405f..a2ec0ed4883 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -1436,9 +1436,7 @@ static int stv090x_start_search(struct stv090x_state *state) } if (STV090x_WRITE_DEMOD(state, CARHDR, 0x40) < 0) goto err; - } - - if (state->srate < 10000000) { + } else if (state->srate < 10000000) { if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4c) < 0) goto err; } else { @@ -1689,7 +1687,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) goto err; if (state->config->tuner_set_frequency) { - if (state->config->tuner_set_frequency(fe, state->frequency) < 0) + if (state->config->tuner_set_frequency(fe, freq) < 0) goto err; } @@ -1867,7 +1865,7 @@ static int stv090x_get_dmdlock(struct stv090x_state *state, s32 timeout) static int stv090x_blind_search(struct stv090x_state *state) { u32 agc2, reg, srate_coarse; - s32 timeout_dmd = 500, cpt_fail, agc2_ovflw, i; + s32 cpt_fail, agc2_ovflw, i; u8 k_ref, k_max, k_min; int coarse_fail, lock; @@ -1911,7 +1909,8 @@ static int stv090x_blind_search(struct stv090x_state *state) srate_coarse = stv090x_srate_srch_fine(state); if (srate_coarse != 0) { stv090x_get_lock_tmg(state); - lock = stv090x_get_dmdlock(state, timeout_dmd); + lock = stv090x_get_dmdlock(state, + state->DemodTimeout); } else { lock = 0; } @@ -2073,7 +2072,7 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd) goto err; if (state->config->tuner_set_frequency) { - if (state->config->tuner_set_frequency(fe, state->frequency) < 0) + if (state->config->tuner_set_frequency(fe, freq) < 0) goto err; } @@ -3053,7 +3052,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) struct dvb_frontend *fe = &state->frontend; enum stv090x_signal_state signal_state = STV090x_NOCARRIER; u32 reg; - s32 timeout_dmd = 500, timeout_fec = 50, agc1_power, power_iq = 0, i; + s32 agc1_power, power_iq = 0, i; int lock = 0, low_sr = 0, no_signal = 0; reg = STV090x_READ_DEMOD(state, TSCFGH); @@ -3218,10 +3217,10 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) lock = stv090x_blind_search(state); else if (state->algo == STV090x_COLD_SEARCH) - lock = stv090x_get_coldlock(state, timeout_dmd); + lock = stv090x_get_coldlock(state, state->DemodTimeout); else if (state->algo == STV090x_WARM_SEARCH) - lock = stv090x_get_dmdlock(state, timeout_dmd); + lock = stv090x_get_dmdlock(state, state->DemodTimeout); if ((!lock) && (state->algo == STV090x_COLD_SEARCH)) { if (!low_sr) { @@ -3256,8 +3255,9 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) goto err; } - if (stv090x_get_lock(state, timeout_fec, timeout_fec)) { - lock = 1; + lock = stv090x_get_lock(state, state->FecTimeout, + state->FecTimeout); + if (lock) { if (state->delsys == STV090x_DVBS2) { stv090x_set_s2rolloff(state); @@ -3284,7 +3284,6 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0) goto err; } else { - lock = 0; signal_state = STV090x_NODATA; no_signal = stv090x_chk_signal(state); } @@ -3769,6 +3768,8 @@ static int stv090x_ldpc_mode(struct stv090x_state *state, enum stv090x_mode ldpc { u32 reg = 0; + reg = stv090x_read_reg(state, STV090x_GENCFG); + switch (ldpc_mode) { case STV090x_DUAL: default: -- cgit v1.2.3-70-g09d2 From c4fa649a3beca1e311d7f244de67306673f4c285 Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Fri, 13 Nov 2009 18:18:53 -0300 Subject: V4L/DVB (13357): stv090x: adds an additional check for signal presence based on AGC1 Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 7 +++---- drivers/media/dvb/frontends/stv090x_priv.h | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index a2ec0ed4883..647c5354300 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -3185,7 +3185,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) if ((agc1_power == 0) && (power_iq < STV090x_IQPOWER_THRESHOLD)) { dprintk(FE_ERROR, 1, "No Signal: POWER_IQ=0x%02x", power_iq); lock = 0; - + signal_state = STV090x_NOAGC1; } else { reg = STV090x_READ_DEMOD(state, DEMOD); STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion); @@ -3209,9 +3209,8 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) } } - /* need to check for AGC1 state */ - - + if (signal_state == STV090x_NOAGC1) + return signal_state; if (state->algo == STV090x_BLIND_SEARCH) lock = stv090x_blind_search(state); diff --git a/drivers/media/dvb/frontends/stv090x_priv.h b/drivers/media/dvb/frontends/stv090x_priv.h index 5696816b88a..5921a8d6c89 100644 --- a/drivers/media/dvb/frontends/stv090x_priv.h +++ b/drivers/media/dvb/frontends/stv090x_priv.h @@ -91,6 +91,7 @@ STV090x_SEARCH_AGC2_TH_CUT30) enum stv090x_signal_state { + STV090x_NOAGC1, STV090x_NOCARRIER, STV090x_NODATA, STV090x_DATAOK, -- cgit v1.2.3-70-g09d2 From 1d4361718a47fba3b51f6e155524b5473a5b8d18 Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Fri, 13 Nov 2009 18:19:54 -0300 Subject: V4L/DVB (13358): stv090x: add an additional check for packet delineator lock in stv090x_read_status in case of a tuned DVB-S2 signal Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 647c5354300..65ae677015e 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -3324,7 +3324,6 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_fron return DVBFE_ALGO_SEARCH_ERROR; } -/* FIXME! */ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct stv090x_state *state = fe->demodulator_priv; @@ -3346,9 +3345,15 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) dprintk(FE_DEBUG, 1, "Delivery system: DVB-S2"); reg = STV090x_READ_DEMOD(state, DSTATUS); if (STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD)) { - reg = STV090x_READ_DEMOD(state, TSSTATUS); - if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) { - *status = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; + reg = STV090x_READ_DEMOD(state, PDELSTATUS1); + if (STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD)) { + reg = STV090x_READ_DEMOD(state, TSSTATUS); + if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) { + *status = FE_HAS_CARRIER | + FE_HAS_VITERBI | + FE_HAS_SYNC | + FE_HAS_LOCK; + } } } break; -- cgit v1.2.3-70-g09d2 From 7b035da93eb6ba839b39c61c5d993365ae308684 Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Fri, 13 Nov 2009 18:20:54 -0300 Subject: V4L/DVB (13359): stv090x: adds corrections of some register values While here, also do some blind scan related fixes. Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 84 ++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 40 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 65ae677015e..48edd542242 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -1238,6 +1238,8 @@ static int stv090x_delivery_search(struct stv090x_state *state) goto err; } + if (stv090x_set_vit_thtracq(state) < 0) + goto err; break; case STV090x_SEARCH_AUTO: @@ -1278,17 +1280,8 @@ static int stv090x_delivery_search(struct stv090x_state *state) goto err; } - if (state->srate >= 2000000) { - /* Srate >= 2MSPS, Viterbi threshold to acquire */ - if (stv090x_set_vit_thacq(state) < 0) - goto err; - } else { - /* Srate < 2MSPS, Reset Viterbi thresholdto track - * and then re-acquire - */ - if (stv090x_set_vit_thtracq(state) < 0) - goto err; - } + if (stv090x_set_vit_thacq(state) < 0) + goto err; if (stv090x_set_viterbi(state) < 0) goto err; @@ -1422,6 +1415,9 @@ static int stv090x_start_search(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, DMDCFG2, reg) < 0) goto err; + if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0) + goto err; + if (state->dev_ver >= 0x20) { /*Frequency offset detector setting*/ if (state->srate < 2000000) { @@ -1430,7 +1426,7 @@ static int stv090x_start_search(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0) goto err; } else { - /* Cut 2 */ + /* Cut 3 */ if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x89) < 0) goto err; } @@ -1439,9 +1435,13 @@ static int stv090x_start_search(struct stv090x_state *state) } else if (state->srate < 10000000) { if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4c) < 0) goto err; + if (STV090x_WRITE_DEMOD(state, CARHDR, 0x20) < 0) + goto err; } else { if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4b) < 0) goto err; + if (STV090x_WRITE_DEMOD(state, CARHDR, 0x20) < 0) + goto err; } } else { if (state->srate < 10000000) { @@ -1489,8 +1489,8 @@ static int stv090x_get_agc2_min_level(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) goto err; reg = STV090x_READ_DEMOD(state, DMDCFGMD); - STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1); - STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 1); + STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0); + STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0); if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) goto err; @@ -1507,10 +1507,8 @@ static int stv090x_get_agc2_min_level(struct stv090x_state *state) if (stv090x_set_srate(state, 1000000) < 0) goto err; - steps = -1 + state->search_range / 1000000; - steps /= 2; - steps = (2 * steps) + 1; - if (steps < 0) + steps = state->search_range / 1000000; + if (steps <= 0) steps = 1; dir = 1; @@ -1596,13 +1594,15 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) goto err; if (STV090x_WRITE_DEMOD(state, TMGCFG, 0x12) < 0) goto err; + if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc0) < 0) + goto err; if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xf0) < 0) goto err; if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xe0) < 0) goto err; reg = STV090x_READ_DEMOD(state, DMDCFGMD); STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1); - STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 1); + STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0); if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) goto err; @@ -1622,7 +1622,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) if (state->dev_ver >= 0x30) { if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0) goto err; - if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0) + if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x98) < 0) goto err; } else if (state->dev_ver >= 0x20) { @@ -1657,9 +1657,16 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) while ((!tmg_lock) && (cur_step < steps)) { if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5f) < 0) /* Demod RESET */ goto err; - reg = STV090x_READ_DEMOD(state, DMDISTATE); - STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x00); /* trigger acquisition */ - if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0) + if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, SFRINIT1, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, SFRINIT0, 0x00) < 0) + goto err; + /* trigger acquisition */ + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x40) < 0) goto err; msleep(50); for (i = 0; i < 10; i++) { @@ -1744,7 +1751,7 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state) else { if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) /* Demod RESET */ goto err; - if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0x01) < 0) + if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0) goto err; if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0) goto err; @@ -1869,8 +1876,8 @@ static int stv090x_blind_search(struct stv090x_state *state) u8 k_ref, k_max, k_min; int coarse_fail, lock; - k_max = 120; - k_min = 30; + k_max = 110; + k_min = 10; agc2 = stv090x_get_agc2_min_level(state); @@ -1933,7 +1940,7 @@ static int stv090x_blind_search(struct stv090x_state *state) lock = 0; } - k_ref -= 30; + k_ref -= 20; } while ((k_ref >= k_min) && (!lock) && (!coarse_fail)); } @@ -2103,17 +2110,6 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd) goto err; STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c); - if (state->delsys == STV090x_DVBS2) { - reg = STV090x_READ_DEMOD(state, DMDCFGMD); - STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0); - STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); - if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) - goto err; - STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); - STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); - if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) - goto err; - } if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) goto err; if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0) @@ -2867,6 +2863,9 @@ static int stv090x_optimize_track(struct stv090x_state *state) if (stv090x_set_srate(state, srate) < 0) goto err; blind_tune = 1; + + if (stv090x_dvbs_track_crl(state) < 0) + goto err; } if (state->dev_ver >= 0x20) { @@ -3064,8 +3063,13 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) goto err; if (state->dev_ver >= 0x20) { - if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) /* cut 2.0 */ - goto err; + if (state->srate > 5000000) { + if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) + goto err; + } else { + if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x82) < 0) + goto err; + } } stv090x_get_lock_tmg(state); -- cgit v1.2.3-70-g09d2 From 7c236e37dd027c0bf35ffbda8de03cbe0c6a750d Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Fri, 13 Nov 2009 18:22:02 -0300 Subject: V4L/DVB (13360): stv090x: fix the calculation of the r divider in stv6110x_set_frequency It had always the value 3 no matter what frequency was given. Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv6110x.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb/frontends/stv6110x.c index 3d8a2e01c9c..bcfcb652464 100644 --- a/drivers/media/dvb/frontends/stv6110x.c +++ b/drivers/media/dvb/frontends/stv6110x.c @@ -95,7 +95,7 @@ static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency) { struct stv6110x_state *stv6110x = fe->tuner_priv; u32 rDiv, divider; - s32 pVal, pCalc, rDivOpt = 0; + s32 pVal, pCalc, rDivOpt = 0, pCalcOpt = 1000; u8 i; STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16)); @@ -121,8 +121,10 @@ static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency) for (rDiv = 0; rDiv <= 3; rDiv++) { pCalc = (REFCLOCK_kHz / 100) / R_DIV(rDiv); - if ((abs((s32)(pCalc - pVal))) < (abs((s32)(1000 - pVal)))) + if ((abs((s32)(pCalc - pVal))) < (abs((s32)(pCalcOpt - pVal)))) rDivOpt = rDiv; + + pCalcOpt = (REFCLOCK_kHz / 100) / R_DIV(rDivOpt); } divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz; -- cgit v1.2.3-70-g09d2 From c1426df678c5e9a095ff40285ff3d698d0d25658 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Fri, 13 Nov 2009 18:51:39 -0300 Subject: V4L/DVB (13361): stv090x: fix TS corruption with High Symbol Rate streams With a lower bandwidth setup, the Transport Stream gets corrupted due to TSFIFO overrun. The patch fixes the issue. The issue is seen with Transport Streams having a Symbol Rate of 22MSPS and/or greater. Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/budget-av.c | 2 +- drivers/media/dvb/ttpci/budget-ci.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index 8ea91522767..983672aa245 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c @@ -1055,7 +1055,7 @@ static const struct stb0899_s1_reg knc1_stb0899_s1_init_3[] = { { STB0899_TSCFGH , 0x0c }, { STB0899_TSCFGM , 0x00 }, { STB0899_TSCFGL , 0x0c }, - { STB0899_TSOUT , 0x0d }, /* 0x0d for CAM */ + { STB0899_TSOUT , 0x4d }, /* 0x0d for CAM */ { STB0899_RSSYNCDEL , 0x00 }, { STB0899_TSINHDELH , 0x02 }, { STB0899_TSINHDELM , 0x00 }, diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index b5c681372b6..88a0a5670cc 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -1248,7 +1248,7 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = { { STB0899_TSCFGH , 0x0c }, { STB0899_TSCFGM , 0x00 }, { STB0899_TSCFGL , 0x0c }, - { STB0899_TSOUT , 0x0d }, /* 0x0d for CAM */ + { STB0899_TSOUT , 0x4d }, /* 0x0d for CAM */ { STB0899_RSSYNCDEL , 0x00 }, { STB0899_TSINHDELH , 0x02 }, { STB0899_TSINHDELM , 0x00 }, -- cgit v1.2.3-70-g09d2 From a15c7b42b2b8eda719920e93b81be031f2e0b01b Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Fri, 13 Nov 2009 22:33:45 -0300 Subject: V4L/DVB (13363): ec100: add new driver for E3C EC100 DVB-T demodulator E3C EC100 DVB-T demodulator driver Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/Kconfig | 7 + drivers/media/dvb/frontends/Makefile | 1 + drivers/media/dvb/frontends/ec100.c | 335 +++++++++++++++++++++++++++++++ drivers/media/dvb/frontends/ec100.h | 46 +++++ drivers/media/dvb/frontends/ec100_priv.h | 39 ++++ 5 files changed, 428 insertions(+) create mode 100644 drivers/media/dvb/frontends/ec100.c create mode 100644 drivers/media/dvb/frontends/ec100.h create mode 100644 drivers/media/dvb/frontends/ec100_priv.h (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index d7c4837fa71..4f785f549d0 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -342,6 +342,13 @@ config DVB_AF9013 help Say Y when you want to support this frontend. +config DVB_EC100 + tristate "E3C EC100" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + Say Y when you want to support this frontend. + comment "DVB-C (cable) frontends" depends on DVB_CORE diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 3523767e7a7..1ca758eeff5 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -76,3 +76,4 @@ obj-$(CONFIG_DVB_STV0900) += stv0900.o obj-$(CONFIG_DVB_STV090x) += stv090x.o obj-$(CONFIG_DVB_STV6110x) += stv6110x.o obj-$(CONFIG_DVB_ISL6423) += isl6423.o +obj-$(CONFIG_DVB_EC100) += ec100.o diff --git a/drivers/media/dvb/frontends/ec100.c b/drivers/media/dvb/frontends/ec100.c new file mode 100644 index 00000000000..2414dc6ee5d --- /dev/null +++ b/drivers/media/dvb/frontends/ec100.c @@ -0,0 +1,335 @@ +/* + * E3C EC100 demodulator driver + * + * Copyright (C) 2009 Antti Palosaari + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "dvb_frontend.h" +#include "ec100_priv.h" +#include "ec100.h" + +int ec100_debug; +module_param_named(debug, ec100_debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); + +struct ec100_state { + struct i2c_adapter *i2c; + struct dvb_frontend frontend; + struct ec100_config config; + + u16 ber; +}; + +/* write single register */ +static int ec100_write_reg(struct ec100_state *state, u8 reg, u8 val) +{ + u8 buf[2] = {reg, val}; + struct i2c_msg msg = { + .addr = state->config.demod_address, + .flags = 0, + .len = 2, + .buf = buf}; + + if (i2c_transfer(state->i2c, &msg, 1) != 1) { + warn("I2C write failed reg:%02x", reg); + return -EREMOTEIO; + } + return 0; +} + +/* read single register */ +static int ec100_read_reg(struct ec100_state *state, u8 reg, u8 *val) +{ + struct i2c_msg msg[2] = { + { + .addr = state->config.demod_address, + .flags = 0, + .len = 1, + .buf = ® + }, { + .addr = state->config.demod_address, + .flags = I2C_M_RD, + .len = 1, + .buf = val + } + }; + + if (i2c_transfer(state->i2c, msg, 2) != 2) { + warn("I2C read failed reg:%02x", reg); + return -EREMOTEIO; + } + return 0; +} + +static int ec100_set_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + struct ec100_state *state = fe->demodulator_priv; + int ret; + u8 tmp, tmp2; + + deb_info("%s: freq:%d bw:%d\n", __func__, params->frequency, + params->u.ofdm.bandwidth); + + /* program tuner */ + if (fe->ops.tuner_ops.set_params) + fe->ops.tuner_ops.set_params(fe, params); + + ret = ec100_write_reg(state, 0x04, 0x06); + if (ret) + goto error; + ret = ec100_write_reg(state, 0x67, 0x58); + if (ret) + goto error; + ret = ec100_write_reg(state, 0x05, 0x18); + if (ret) + goto error; + + /* reg/bw | 6 | 7 | 8 + -------+------+------+------ + A 0x1b | 0xa1 | 0xe7 | 0x2c + A 0x1c | 0x55 | 0x63 | 0x72 + -------+------+------+------ + B 0x1b | 0xb7 | 0x00 | 0x49 + B 0x1c | 0x55 | 0x64 | 0x72 */ + + switch (params->u.ofdm.bandwidth) { + case BANDWIDTH_6_MHZ: + tmp = 0xb7; + tmp2 = 0x55; + break; + case BANDWIDTH_7_MHZ: + tmp = 0x00; + tmp2 = 0x64; + break; + case BANDWIDTH_8_MHZ: + default: + tmp = 0x49; + tmp2 = 0x72; + } + + ret = ec100_write_reg(state, 0x1b, tmp); + if (ret) + goto error; + ret = ec100_write_reg(state, 0x1c, tmp2); + if (ret) + goto error; + + ret = ec100_write_reg(state, 0x0c, 0xbb); /* if freq */ + if (ret) + goto error; + ret = ec100_write_reg(state, 0x0d, 0x31); /* if freq */ + if (ret) + goto error; + + ret = ec100_write_reg(state, 0x08, 0x24); + if (ret) + goto error; + + ret = ec100_write_reg(state, 0x00, 0x00); /* go */ + if (ret) + goto error; + ret = ec100_write_reg(state, 0x00, 0x20); /* go */ + if (ret) + goto error; + + return ret; +error: + deb_info("%s: failed:%d\n", __func__, ret); + return ret; +} + +static int ec100_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings *fesettings) +{ + fesettings->min_delay_ms = 300; + fesettings->step_size = 0; + fesettings->max_drift = 0; + + return 0; +} + +static int ec100_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + struct ec100_state *state = fe->demodulator_priv; + int ret; + u8 tmp; + *status = 0; + + ret = ec100_read_reg(state, 0x42, &tmp); + if (ret) + goto error; + + if (tmp & 0x80) { + /* bit7 set - have lock */ + *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | + FE_HAS_SYNC | FE_HAS_LOCK; + } else { + ret = ec100_read_reg(state, 0x01, &tmp); + if (ret) + goto error; + + if (tmp & 0x10) { + /* bit4 set - have signal */ + *status |= FE_HAS_SIGNAL; + if (!(tmp & 0x01)) { + /* bit0 clear - have ~valid signal */ + *status |= FE_HAS_CARRIER | FE_HAS_VITERBI; + } + } + } + + return ret; +error: + deb_info("%s: failed:%d\n", __func__, ret); + return ret; +} + +static int ec100_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + struct ec100_state *state = fe->demodulator_priv; + int ret; + u8 tmp, tmp2; + u16 ber2; + + *ber = 0; + + ret = ec100_read_reg(state, 0x65, &tmp); + if (ret) + goto error; + ret = ec100_read_reg(state, 0x66, &tmp2); + if (ret) + goto error; + + ber2 = (tmp2 << 8) | tmp; + + /* if counter overflow or clear */ + if (ber2 < state->ber) + *ber = ber2; + else + *ber = ber2 - state->ber; + + state->ber = ber2; + + return ret; +error: + deb_info("%s: failed:%d\n", __func__, ret); + return ret; +} + +static int ec100_read_signal_strength(struct dvb_frontend *fe, u16 *strength) +{ + struct ec100_state *state = fe->demodulator_priv; + int ret; + u8 tmp; + + ret = ec100_read_reg(state, 0x24, &tmp); + if (ret) { + *strength = 0; + goto error; + } + + *strength = ((tmp << 8) | tmp); + + return ret; +error: + deb_info("%s: failed:%d\n", __func__, ret); + return ret; +} + +static int ec100_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + *snr = 0; + return 0; +} + +static int ec100_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + *ucblocks = 0; + return 0; +} + +static void ec100_release(struct dvb_frontend *fe) +{ + struct ec100_state *state = fe->demodulator_priv; + kfree(state); +} + +static struct dvb_frontend_ops ec100_ops; + +struct dvb_frontend *ec100_attach(const struct ec100_config *config, + struct i2c_adapter *i2c) +{ + int ret; + struct ec100_state *state = NULL; + u8 tmp; + + /* allocate memory for the internal state */ + state = kzalloc(sizeof(struct ec100_state), GFP_KERNEL); + if (state == NULL) + goto error; + + /* setup the state */ + state->i2c = i2c; + memcpy(&state->config, config, sizeof(struct ec100_config)); + + /* check if the demod is there */ + ret = ec100_read_reg(state, 0x33, &tmp); + if (ret || tmp != 0x0b) + goto error; + + /* create dvb_frontend */ + memcpy(&state->frontend.ops, &ec100_ops, + sizeof(struct dvb_frontend_ops)); + state->frontend.demodulator_priv = state; + + return &state->frontend; +error: + kfree(state); + return NULL; +} +EXPORT_SYMBOL(ec100_attach); + +static struct dvb_frontend_ops ec100_ops = { + .info = { + .name = "E3C EC100 DVB-T", + .type = FE_OFDM, + .caps = + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | + FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO | + FE_CAN_MUTE_TS + }, + + .release = ec100_release, + .set_frontend = ec100_set_frontend, + .get_tune_settings = ec100_get_tune_settings, + .read_status = ec100_read_status, + .read_ber = ec100_read_ber, + .read_signal_strength = ec100_read_signal_strength, + .read_snr = ec100_read_snr, + .read_ucblocks = ec100_read_ucblocks, +}; + +MODULE_AUTHOR("Antti Palosaari "); +MODULE_DESCRIPTION("E3C EC100 DVB-T demodulator driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/ec100.h b/drivers/media/dvb/frontends/ec100.h new file mode 100644 index 00000000000..ee8e5241795 --- /dev/null +++ b/drivers/media/dvb/frontends/ec100.h @@ -0,0 +1,46 @@ +/* + * E3C EC100 demodulator driver + * + * Copyright (C) 2009 Antti Palosaari + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef EC100_H +#define EC100_H + +#include + +struct ec100_config { + /* demodulator's I2C address */ + u8 demod_address; +}; + + +#if defined(CONFIG_DVB_EC100) || \ + (defined(CONFIG_DVB_EC100_MODULE) && defined(MODULE)) +extern struct dvb_frontend *ec100_attach(const struct ec100_config *config, + struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend *ec100_attach( + const struct ec100_config *config, struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif + +#endif /* EC100_H */ diff --git a/drivers/media/dvb/frontends/ec100_priv.h b/drivers/media/dvb/frontends/ec100_priv.h new file mode 100644 index 00000000000..5c990144bc4 --- /dev/null +++ b/drivers/media/dvb/frontends/ec100_priv.h @@ -0,0 +1,39 @@ +/* + * E3C EC100 demodulator driver + * + * Copyright (C) 2009 Antti Palosaari + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef EC100_PRIV +#define EC100_PRIV + +#define LOG_PREFIX "ec100" + +#define dprintk(var, level, args...) \ + do { if ((var & level)) printk(args); } while (0) + +#define deb_info(args...) dprintk(ec100_debug, 0x01, args) + +#undef err +#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg) +#undef info +#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg) +#undef warn +#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg) + +#endif /* EC100_PRIV */ -- cgit v1.2.3-70-g09d2 From 2bf290be4f3ef11889026d750244cc3bd1164974 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Fri, 13 Nov 2009 22:38:55 -0300 Subject: V4L/DVB (13364): ec168: add new driver for E3C EC168 DVB USB E3C EC168 DVB USB driver Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/Kconfig | 8 + drivers/media/dvb/dvb-usb/Makefile | 3 + drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 6 + drivers/media/dvb/dvb-usb/ec168.c | 440 ++++++++++++++++++++++++++++++++ drivers/media/dvb/dvb-usb/ec168.h | 73 ++++++ 5 files changed, 530 insertions(+) create mode 100644 drivers/media/dvb/dvb-usb/ec168.c create mode 100644 drivers/media/dvb/dvb-usb/ec168.h (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 0e4b97fba38..2dee1bf7357 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -322,3 +322,11 @@ config DVB_USB_FRIIO depends on DVB_USB help Say Y here to support the Japanese DTV receiver Friio. + +config DVB_USB_EC168 + tristate "E3C EC168 DVB-T USB2.0 support" + depends on DVB_USB && EXPERIMENTAL + select DVB_EC100 + select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE + help + Say Y here to support the E3C EC168 DVB-T USB2.0 receiver. diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile index 85b83a43d55..72c92cb69a2 100644 --- a/drivers/media/dvb/dvb-usb/Makefile +++ b/drivers/media/dvb/dvb-usb/Makefile @@ -82,6 +82,9 @@ obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o dvb-usb-friio-objs = friio.o friio-fe.o obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o +dvb-usb-ec168-objs = ec168.o +obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o + EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ # due to tuner-xc3028 EXTRA_CFLAGS += -Idrivers/media/common/tuners diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 128fca63df9..491440d6e65 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -27,6 +27,7 @@ #define USB_VID_DIBCOM 0x10b8 #define USB_VID_DPOSH 0x1498 #define USB_VID_DVICO 0x0fe9 +#define USB_VID_E3C 0x18b4 #define USB_VID_ELGATO 0x0fd9 #define USB_VID_EMPIA 0xeb1a #define USB_VID_GENPIX 0x09c0 @@ -104,6 +105,11 @@ #define USB_PID_DIBCOM_STK7770P 0x1e80 #define USB_PID_DPOSH_M9206_COLD 0x9206 #define USB_PID_DPOSH_M9206_WARM 0xa090 +#define USB_PID_E3C_EC168 0x1689 +#define USB_PID_E3C_EC168_2 0xfffa +#define USB_PID_E3C_EC168_3 0xfffb +#define USB_PID_E3C_EC168_4 0x1001 +#define USB_PID_E3C_EC168_5 0x1002 #define USB_PID_UNIWILL_STK7700P 0x6003 #define USB_PID_GENIUS_TVGO_DVB_T03 0x4012 #define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 diff --git a/drivers/media/dvb/dvb-usb/ec168.c b/drivers/media/dvb/dvb-usb/ec168.c new file mode 100644 index 00000000000..52f5d4f0f23 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/ec168.c @@ -0,0 +1,440 @@ +/* + * E3C EC168 DVB USB driver + * + * Copyright (C) 2009 Antti Palosaari + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "ec168.h" +#include "ec100.h" +#include "mxl5005s.h" + +/* debug */ +static int dvb_usb_ec168_debug; +module_param_named(debug, dvb_usb_ec168_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +static struct ec100_config ec168_ec100_config; + +static int ec168_rw_udev(struct usb_device *udev, struct ec168_req *req) +{ + int ret; + unsigned int pipe; + u8 request, requesttype; + u8 buf[req->size]; + + switch (req->cmd) { + case DOWNLOAD_FIRMWARE: + case GPIO: + case WRITE_I2C: + case STREAMING_CTRL: + requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT); + request = req->cmd; + break; + case READ_I2C: + requesttype = (USB_TYPE_VENDOR | USB_DIR_IN); + request = req->cmd; + break; + case GET_CONFIG: + requesttype = (USB_TYPE_VENDOR | USB_DIR_IN); + request = CONFIG; + break; + case SET_CONFIG: + requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT); + request = CONFIG; + break; + case WRITE_DEMOD: + requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT); + request = DEMOD_RW; + break; + case READ_DEMOD: + requesttype = (USB_TYPE_VENDOR | USB_DIR_IN); + request = DEMOD_RW; + break; + default: + err("unknown command:%02x", req->cmd); + ret = -EPERM; + goto error; + } + + if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) { + /* write */ + memcpy(buf, req->data, req->size); + pipe = usb_sndctrlpipe(udev, 0); + } else { + /* read */ + pipe = usb_rcvctrlpipe(udev, 0); + } + + msleep(1); /* avoid I2C errors */ + + ret = usb_control_msg(udev, pipe, request, requesttype, req->value, + req->index, buf, sizeof(buf), EC168_USB_TIMEOUT); + + ec168_debug_dump(request, requesttype, req->value, req->index, buf, + req->size, deb_xfer); + + if (ret < 0) + goto error; + else + ret = 0; + + /* read request, copy returned data to return buf */ + if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN)) + memcpy(req->data, buf, req->size); + + return ret; +error: + deb_info("%s: failed:%d\n", __func__, ret); + return ret; +} + +static int ec168_ctrl_msg(struct dvb_usb_device *d, struct ec168_req *req) +{ + return ec168_rw_udev(d->udev, req); +} + +/* I2C */ +static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], + int num) +{ + struct dvb_usb_device *d = i2c_get_adapdata(adap); + struct ec168_req req; + int i = 0; + int ret; + + if (num > 2) + return -EINVAL; + + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + while (i < num) { + if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { + if (msg[i].addr == ec168_ec100_config.demod_address) { + req.cmd = READ_DEMOD; + req.value = 0; + req.index = 0xff00 + msg[i].buf[0]; /* reg */ + req.size = msg[i+1].len; /* bytes to read */ + req.data = &msg[i+1].buf[0]; + ret = ec168_ctrl_msg(d, &req); + i += 2; + } else { + err("I2C read not implemented"); + ret = -ENOSYS; + i += 2; + } + } else { + if (msg[i].addr == ec168_ec100_config.demod_address) { + req.cmd = WRITE_DEMOD; + req.value = msg[i].buf[1]; /* val */ + req.index = 0xff00 + msg[i].buf[0]; /* reg */ + req.size = 0; + req.data = NULL; + ret = ec168_ctrl_msg(d, &req); + i += 1; + } else { + req.cmd = WRITE_I2C; + req.value = msg[i].buf[0]; /* val */ + req.index = 0x0100 + msg[i].addr; /* I2C addr */ + req.size = msg[i].len-1; + req.data = &msg[i].buf[1]; + ret = ec168_ctrl_msg(d, &req); + i += 1; + } + } + if (ret) + goto error; + + } + ret = i; + +error: + mutex_unlock(&d->i2c_mutex); + return i; +} + + +static u32 ec168_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +static struct i2c_algorithm ec168_i2c_algo = { + .master_xfer = ec168_i2c_xfer, + .functionality = ec168_i2c_func, +}; + +/* Callbacks for DVB USB */ +static struct ec100_config ec168_ec100_config = { + .demod_address = 0xff, /* not real address, demod is integrated */ +}; + +static int ec168_ec100_frontend_attach(struct dvb_usb_adapter *adap) +{ + deb_info("%s:\n", __func__); + adap->fe = dvb_attach(ec100_attach, &ec168_ec100_config, + &adap->dev->i2c_adap); + if (adap->fe == NULL) + return -ENODEV; + + return 0; +} + +static struct mxl5005s_config ec168_mxl5003s_config = { + .i2c_address = 0xc6, + .if_freq = IF_FREQ_4570000HZ, + .xtal_freq = CRYSTAL_FREQ_16000000HZ, + .agc_mode = MXL_SINGLE_AGC, + .tracking_filter = MXL_TF_OFF, + .rssi_enable = MXL_RSSI_ENABLE, + .cap_select = MXL_CAP_SEL_ENABLE, + .div_out = MXL_DIV_OUT_4, + .clock_out = MXL_CLOCK_OUT_DISABLE, + .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, + .top = MXL5005S_TOP_25P2, + .mod_mode = MXL_DIGITAL_MODE, + .if_mode = MXL_ZERO_IF, + .AgcMasterByte = 0x00, +}; + +static int ec168_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap) +{ + deb_info("%s:\n", __func__); + return dvb_attach(mxl5005s_attach, adap->fe, &adap->dev->i2c_adap, + &ec168_mxl5003s_config) == NULL ? -ENODEV : 0; +} + +static int ec168_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) +{ + struct ec168_req req = {STREAMING_CTRL, 0x7f01, 0x0202, 0, NULL}; + deb_info("%s: onoff:%d\n", __func__, onoff); + if (onoff) + req.index = 0x0102; + return ec168_ctrl_msg(adap->dev, &req); +} + +static int ec168_download_firmware(struct usb_device *udev, + const struct firmware *fw) +{ + int i, len, packets, remainder, ret; + u16 addr = 0x0000; /* firmware start address */ + struct ec168_req req = {DOWNLOAD_FIRMWARE, 0, 0, 0, NULL}; + deb_info("%s:\n", __func__); + + #define FW_PACKET_MAX_DATA 2048 + packets = fw->size / FW_PACKET_MAX_DATA; + remainder = fw->size % FW_PACKET_MAX_DATA; + len = FW_PACKET_MAX_DATA; + for (i = 0; i <= packets; i++) { + if (i == packets) /* set size of the last packet */ + len = remainder; + + req.size = len; + req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA); + req.index = addr; + addr += FW_PACKET_MAX_DATA; + + ret = ec168_rw_udev(udev, &req); + if (ret) { + err("firmware download failed:%d packet:%d", ret, i); + goto error; + } + } + req.size = 0; + + /* set "warm"? */ + req.cmd = SET_CONFIG; + req.value = 0; + req.index = 0x0001; + ret = ec168_rw_udev(udev, &req); + if (ret) + goto error; + + /* really needed - no idea what does */ + req.cmd = GPIO; + req.value = 0; + req.index = 0x0206; + ret = ec168_rw_udev(udev, &req); + if (ret) + goto error; + + /* activate tuner I2C? */ + req.cmd = WRITE_I2C; + req.value = 0; + req.index = 0x00c6; + ret = ec168_rw_udev(udev, &req); + if (ret) + goto error; + + return ret; +error: + deb_info("%s: failed:%d\n", __func__, ret); + return ret; +} + +static int ec168_identify_state(struct usb_device *udev, + struct dvb_usb_device_properties *props, + struct dvb_usb_device_description **desc, int *cold) +{ + int ret; + u8 reply; + struct ec168_req req = {GET_CONFIG, 0, 1, sizeof(reply), &reply}; + deb_info("%s:\n", __func__); + + ret = ec168_rw_udev(udev, &req); + if (ret) + goto error; + + deb_info("%s: reply:%02x\n", __func__, reply); + + if (reply == 0x01) + *cold = 0; + else + *cold = 1; + + return ret; +error: + deb_info("%s: failed:%d\n", __func__, ret); + return ret; +} + +/* DVB USB Driver stuff */ +static struct dvb_usb_device_properties ec168_properties; + +static int ec168_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + int ret; + deb_info("%s: interface:%d\n", __func__, + intf->cur_altsetting->desc.bInterfaceNumber); + + ret = dvb_usb_device_init(intf, &ec168_properties, THIS_MODULE, NULL, + adapter_nr); + if (ret) + goto error; + + return ret; +error: + deb_info("%s: failed:%d\n", __func__, ret); + return ret; +} + +#define E3C_EC168_1689 0 +#define E3C_EC168_FFFA 1 +#define E3C_EC168_FFFB 2 +#define E3C_EC168_1001 3 +#define E3C_EC168_1002 4 + +static struct usb_device_id ec168_id[] = { + [E3C_EC168_1689] = + {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168)}, + [E3C_EC168_FFFA] = + {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_2)}, + [E3C_EC168_FFFB] = + {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_3)}, + [E3C_EC168_1001] = + {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_4)}, + [E3C_EC168_1002] = + {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_5)}, + {} /* terminating entry */ +}; + +MODULE_DEVICE_TABLE(usb, ec168_id); + +static struct dvb_usb_device_properties ec168_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = DEVICE_SPECIFIC, + .download_firmware = ec168_download_firmware, + .firmware = "dvb-usb-ec168.fw", + .no_reconnect = 1, + + .size_of_priv = 0, + + .num_adapters = 1, + .adapter = { + { + .streaming_ctrl = ec168_streaming_ctrl, + .frontend_attach = ec168_ec100_frontend_attach, + .tuner_attach = ec168_mxl5003s_tuner_attach, + .stream = { + .type = USB_BULK, + .count = 6, + .endpoint = 0x82, + .u = { + .bulk = { + .buffersize = (32*512), + } + } + }, + } + }, + + .identify_state = ec168_identify_state, + + .i2c_algo = &ec168_i2c_algo, + + .num_device_descs = 1, + .devices = { + { + .name = "E3C EC168 DVB-T USB2.0 reference design", + .cold_ids = { + &ec168_id[E3C_EC168_1689], + &ec168_id[E3C_EC168_FFFA], + &ec168_id[E3C_EC168_FFFB], + &ec168_id[E3C_EC168_1001], + &ec168_id[E3C_EC168_1002], + NULL}, + .warm_ids = {NULL}, + }, + } +}; + +static struct usb_driver ec168_driver = { + .name = "dvb_usb_ec168", + .probe = ec168_probe, + .disconnect = dvb_usb_device_exit, + .id_table = ec168_id, +}; + +/* module stuff */ +static int __init ec168_module_init(void) +{ + int ret; + deb_info("%s:\n", __func__); + ret = usb_register(&ec168_driver); + if (ret) + err("module init failed:%d", ret); + + return ret; +} + +static void __exit ec168_module_exit(void) +{ + deb_info("%s:\n", __func__); + /* deregister this driver from the USB subsystem */ + usb_deregister(&ec168_driver); +} + +module_init(ec168_module_init); +module_exit(ec168_module_exit); + +MODULE_AUTHOR("Antti Palosaari "); +MODULE_DESCRIPTION("E3C EC168 DVB-T USB2.0 driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/ec168.h b/drivers/media/dvb/dvb-usb/ec168.h new file mode 100644 index 00000000000..e7e0b831314 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/ec168.h @@ -0,0 +1,73 @@ +/* + * E3C EC168 DVB USB driver + * + * Copyright (C) 2009 Antti Palosaari + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef EC168_H +#define EC168_H + +#define DVB_USB_LOG_PREFIX "ec168" +#include "dvb-usb.h" + +#define deb_info(args...) dprintk(dvb_usb_ec168_debug, 0x01, args) +#define deb_rc(args...) dprintk(dvb_usb_ec168_debug, 0x02, args) +#define deb_xfer(args...) dprintk(dvb_usb_ec168_debug, 0x04, args) +#define deb_reg(args...) dprintk(dvb_usb_ec168_debug, 0x08, args) +#define deb_i2c(args...) dprintk(dvb_usb_ec168_debug, 0x10, args) +#define deb_fw(args...) dprintk(dvb_usb_ec168_debug, 0x20, args) + +#define ec168_debug_dump(r, t, v, i, b, l, func) { \ + int loop_; \ + func("%02x %02x %02x %02x %02x %02x %02x %02x", \ + t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, l & 0xff, l >> 8); \ + if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \ + func(" >>> "); \ + else \ + func(" <<< "); \ + for (loop_ = 0; loop_ < l; loop_++) \ + func("%02x ", b[loop_]); \ + func("\n");\ +} + +#define EC168_USB_TIMEOUT 1000 + +struct ec168_req { + u8 cmd; /* [1] */ + u16 value; /* [2|3] */ + u16 index; /* [4|5] */ + u16 size; /* [6|7] */ + u8 *data; +}; + +enum ec168_cmd { + DOWNLOAD_FIRMWARE = 0x00, + CONFIG = 0x01, + DEMOD_RW = 0x03, + GPIO = 0x04, + STREAMING_CTRL = 0x10, + READ_I2C = 0x20, + WRITE_I2C = 0x21, + HID_DOWNLOAD = 0x30, + GET_CONFIG, + SET_CONFIG, + READ_DEMOD, + WRITE_DEMOD, +}; + +#endif -- cgit v1.2.3-70-g09d2 From 5232263a7daa1247fe4a30579c296ddccfeeb7e6 Mon Sep 17 00:00:00 2001 From: Ignacio de Miguel Diaz Date: Fri, 13 Nov 2009 23:13:34 -0300 Subject: V4L/DVB (13368): af9015: support for Sveon STV20 Tuner USB DVB-T HDTV Add USB ID 1b80:e39d for Sveon STV20 Tuner USB DVB-T HDTV. Signed-off-by: Ignacio de Miguel Diaz Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/af9015.c | 8 +++++++- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index bad3e10f372..8b60a601fb8 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -1294,6 +1294,7 @@ static struct usb_device_id af9015_usb_table[] = { {USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)}, /* 25 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)}, {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)}, + {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)}, {0}, }; MODULE_DEVICE_TABLE(usb, af9015_usb_table); @@ -1565,7 +1566,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { .i2c_algo = &af9015_i2c_algo, - .num_device_descs = 5, /* max 9 */ + .num_device_descs = 6, /* max 9 */ .devices = { { .name = "AverMedia AVerTV Volar GPS 805 (A805)", @@ -1594,6 +1595,11 @@ static struct dvb_usb_device_properties af9015_properties[] = { .cold_ids = {&af9015_usb_table[26], NULL}, .warm_ids = {NULL}, }, + { + .name = "Sveon STV20 Tuner USB DVB-T HDTV", + .cold_ids = {&af9015_usb_table[27], NULL}, + .warm_ids = {NULL}, + }, } }, }; diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 491440d6e65..dc57fe1b6f0 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -285,5 +285,6 @@ #define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM 0x5001 #define USB_PID_FRIIO_WHITE 0x0001 #define USB_PID_TVWAY_PLUS 0x0002 +#define USB_PID_SVEON_STV20 0xe39d #endif -- cgit v1.2.3-70-g09d2 From 95963cbcd0ee00026cc34ba84906ee4aa2029f4d Mon Sep 17 00:00:00 2001 From: "David T.L. Wong" Date: Mon, 26 Oct 2009 06:42:34 -0300 Subject: V4L/DVB (13373): Maxium MAX2165 silicon tuner Adds support for Maxim MAX2165 silicon tuner. It is tested on Mygica X8558Pro, which has MAX2165, ATBM8830 and CX23885 Signed-off-by: David T. L. Wong Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/Kconfig | 7 + drivers/media/common/tuners/Makefile | 1 + drivers/media/common/tuners/max2165.c | 442 +++++++++++++++++++++++++++++ drivers/media/common/tuners/max2165.h | 48 ++++ drivers/media/common/tuners/max2165_priv.h | 60 ++++ 5 files changed, 558 insertions(+) create mode 100644 drivers/media/common/tuners/max2165.c create mode 100644 drivers/media/common/tuners/max2165.h create mode 100644 drivers/media/common/tuners/max2165_priv.h (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig index 607d319ce8e..409a4261e5b 100644 --- a/drivers/media/common/tuners/Kconfig +++ b/drivers/media/common/tuners/Kconfig @@ -172,4 +172,11 @@ config MEDIA_TUNER_MC44S803 help Say Y here to support the Freescale MC44S803 based tuners +config MEDIA_TUNER_MAX2165 + tristate "Maxim MAX2165 silicon tuner" + depends on VIDEO_MEDIA && I2C + default m if MEDIA_TUNER_CUSTOMISE + help + A driver for the silicon tuner MAX2165 from Maxim. + endif # MEDIA_TUNER_CUSTOMISE diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile index 4132b2be79e..a5438523f30 100644 --- a/drivers/media/common/tuners/Makefile +++ b/drivers/media/common/tuners/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o +obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/frontends diff --git a/drivers/media/common/tuners/max2165.c b/drivers/media/common/tuners/max2165.c new file mode 100644 index 00000000000..1b486cfb8ed --- /dev/null +++ b/drivers/media/common/tuners/max2165.c @@ -0,0 +1,442 @@ +/* + * Driver for Maxim MAX2165 silicon tuner + * + * Copyright (c) 2009 David T. L. Wong + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include "dvb_frontend.h" + +#include "max2165.h" +#include "max2165_priv.h" +#include "tuner-i2c.h" + +#define dprintk(args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG "max2165: " args); \ + } while (0) + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); + +static int max2165_write_reg(struct max2165_priv *priv, u8 reg, u8 data) +{ + int ret; + u8 buf[] = { reg, data }; + struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 }; + + msg.addr = priv->config->i2c_address; + + if (debug >= 2) + printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n", + __func__, reg, data); + + ret = i2c_transfer(priv->i2c, &msg, 1); + + if (ret != 1) + dprintk(KERN_DEBUG "%s: error reg=0x%x, data=0x%x, ret=%i\n", + __func__, reg, data, ret); + + return (ret != 1) ? -EIO : 0; +} + +static int max2165_read_reg(struct max2165_priv *priv, u8 reg, u8 *p_data) +{ + int ret; + u8 dev_addr = priv->config->i2c_address; + + u8 b0[] = { reg }; + u8 b1[] = { 0 }; + struct i2c_msg msg[] = { + { .addr = dev_addr, .flags = 0, .buf = b0, .len = 1 }, + { .addr = dev_addr, .flags = I2C_M_RD, .buf = b1, .len = 1 }, + }; + + ret = i2c_transfer(priv->i2c, msg, 2); + if (ret != 2) { + dprintk(KERN_DEBUG "%s: error reg=0x%x, ret=%i\n", + __func__, reg, ret); + return -EIO; + } + + *p_data = b1[0]; + if (debug >= 2) + printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n", + __func__, reg, b1[0]); + return 0; +} + +static int max2165_mask_write_reg(struct max2165_priv *priv, u8 reg, + u8 mask, u8 data) +{ + int ret; + u8 v; + + data &= mask; + ret = max2165_read_reg(priv, reg, &v); + if (ret != 0) + return ret; + v &= ~mask; + v |= data; + ret = max2165_write_reg(priv, reg, v); + + return ret; +} + +static int max2165_read_rom_table(struct max2165_priv *priv) +{ + u8 dat[3]; + int i; + + for (i = 0; i < 3; i++) { + max2165_write_reg(priv, REG_ROM_TABLE_ADDR, i + 1); + max2165_read_reg(priv, REG_ROM_TABLE_DATA, &dat[i]); + } + + priv->tf_ntch_low_cfg = dat[0] >> 4; + priv->tf_ntch_hi_cfg = dat[0] & 0x0F; + priv->tf_balun_low_ref = dat[1] & 0x0F; + priv->tf_balun_hi_ref = dat[1] >> 4; + priv->bb_filter_7mhz_cfg = dat[2] & 0x0F; + priv->bb_filter_8mhz_cfg = dat[2] >> 4; + + dprintk("tf_ntch_low_cfg = 0x%X\n", priv->tf_ntch_low_cfg); + dprintk("tf_ntch_hi_cfg = 0x%X\n", priv->tf_ntch_hi_cfg); + dprintk("tf_balun_low_ref = 0x%X\n", priv->tf_balun_low_ref); + dprintk("tf_balun_hi_ref = 0x%X\n", priv->tf_balun_hi_ref); + dprintk("bb_filter_7mhz_cfg = 0x%X\n", priv->bb_filter_7mhz_cfg); + dprintk("bb_filter_8mhz_cfg = 0x%X\n", priv->bb_filter_8mhz_cfg); + + return 0; +} + +static int max2165_set_osc(struct max2165_priv *priv, u8 osc /*MHz*/) +{ + u8 v; + + v = (osc / 2); + if (v == 2) + v = 0x7; + else + v -= 8; + + max2165_mask_write_reg(priv, REG_PLL_CFG, 0x07, v); + + return 0; +} + +static int max2165_set_bandwidth(struct max2165_priv *priv, u32 bw) +{ + u8 val; + + if (bw == BANDWIDTH_8_MHZ) + val = priv->bb_filter_8mhz_cfg; + else + val = priv->bb_filter_7mhz_cfg; + + max2165_mask_write_reg(priv, REG_BASEBAND_CTRL, 0xF0, val << 4); + + return 0; +} + +int fixpt_div32(u32 dividend, u32 divisor, u32 *quotient, u32 *fraction) +{ + u32 remainder; + u32 q, f = 0; + int i; + + if (0 == divisor) + return -1; + + q = dividend / divisor; + remainder = dividend - q * divisor; + + for (i = 0; i < 31; i++) { + remainder <<= 1; + if (remainder >= divisor) { + f += 1; + remainder -= divisor; + } + f <<= 1; + } + + *quotient = q; + *fraction = f; + + return 0; +} + +static int max2165_set_rf(struct max2165_priv *priv, u32 freq) +{ + u8 tf; + u8 tf_ntch; + double t; + u32 quotient, fraction; + + /* Set PLL divider according to RF frequency */ + fixpt_div32(freq / 1000, priv->config->osc_clk * 1000, + "ient, &fraction); + + /* 20-bit fraction */ + fraction >>= 12; + + max2165_write_reg(priv, REG_NDIV_INT, quotient); + max2165_mask_write_reg(priv, REG_NDIV_FRAC2, 0x0F, fraction >> 16); + max2165_write_reg(priv, REG_NDIV_FRAC1, fraction >> 8); + max2165_write_reg(priv, REG_NDIV_FRAC0, fraction); + + /* Norch Filter */ + tf_ntch = (freq < 725000000) ? + priv->tf_ntch_low_cfg : priv->tf_ntch_hi_cfg; + + /* Tracking filter balun */ + t = priv->tf_balun_low_ref; + t += (priv->tf_balun_hi_ref - priv->tf_balun_low_ref) + * (freq / 1000 - 470000) / (780000 - 470000); + + tf = t; + dprintk("tf = %X\n", tf); + tf |= tf_ntch << 4; + + max2165_write_reg(priv, REG_TRACK_FILTER, tf); + + return 0; +} + +static void max2165_debug_status(struct max2165_priv *priv) +{ + u8 status, autotune; + u8 auto_vco_success, auto_vco_active; + u8 pll_locked; + u8 dc_offset_low, dc_offset_hi; + u8 signal_lv_over_threshold; + u8 vco, vco_sub_band, adc; + + max2165_read_reg(priv, REG_STATUS, &status); + max2165_read_reg(priv, REG_AUTOTUNE, &autotune); + + auto_vco_success = (status >> 6) & 0x01; + auto_vco_active = (status >> 5) & 0x01; + pll_locked = (status >> 4) & 0x01; + dc_offset_low = (status >> 3) & 0x01; + dc_offset_hi = (status >> 2) & 0x01; + signal_lv_over_threshold = status & 0x01; + + vco = autotune >> 6; + vco_sub_band = (autotune >> 3) & 0x7; + adc = autotune & 0x7; + + dprintk("auto VCO active: %d, auto VCO success: %d\n", + auto_vco_active, auto_vco_success); + dprintk("PLL locked: %d\n", pll_locked); + dprintk("DC offset low: %d, DC offset high: %d\n", + dc_offset_low, dc_offset_hi); + dprintk("Signal lvl over threshold: %d\n", signal_lv_over_threshold); + dprintk("VCO: %d, VCO Sub-band: %d, ADC: %d\n", vco, vco_sub_band, adc); +} + +static int max2165_set_params(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + struct max2165_priv *priv = fe->tuner_priv; + int ret; + + dprintk("%s() frequency=%d (Hz)\n", __func__, params->frequency); + if (fe->ops.info.type == FE_ATSC) { + return -EINVAL; + } else if (fe->ops.info.type == FE_OFDM) { + dprintk("%s() OFDM\n", __func__); + switch (params->u.ofdm.bandwidth) { + case BANDWIDTH_6_MHZ: + return -EINVAL; + case BANDWIDTH_7_MHZ: + case BANDWIDTH_8_MHZ: + priv->frequency = params->frequency; + priv->bandwidth = params->u.ofdm.bandwidth; + break; + default: + printk(KERN_ERR "MAX2165 bandwidth not set!\n"); + return -EINVAL; + } + } else { + printk(KERN_ERR "MAX2165 modulation type not supported!\n"); + return -EINVAL; + } + + dprintk("%s() frequency=%d\n", __func__, priv->frequency); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + max2165_set_bandwidth(priv, priv->bandwidth); + ret = max2165_set_rf(priv, priv->frequency); + mdelay(50); + max2165_debug_status(priv); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + if (ret != 0) + return -EREMOTEIO; + + return 0; +} + +static int max2165_get_frequency(struct dvb_frontend *fe, u32 *freq) +{ + struct max2165_priv *priv = fe->tuner_priv; + dprintk("%s()\n", __func__); + *freq = priv->frequency; + return 0; +} + +static int max2165_get_bandwidth(struct dvb_frontend *fe, u32 *bw) +{ + struct max2165_priv *priv = fe->tuner_priv; + dprintk("%s()\n", __func__); + + *bw = priv->bandwidth; + return 0; +} + +static int max2165_get_status(struct dvb_frontend *fe, u32 *status) +{ + struct max2165_priv *priv = fe->tuner_priv; + u16 lock_status = 0; + + dprintk("%s()\n", __func__); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + max2165_debug_status(priv); + *status = lock_status; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + return 0; +} + +static int max2165_sleep(struct dvb_frontend *fe) +{ + dprintk("%s()\n", __func__); + return 0; +} + +static int max2165_init(struct dvb_frontend *fe) +{ + struct max2165_priv *priv = fe->tuner_priv; + dprintk("%s()\n", __func__); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + /* Setup initial values */ + /* Fractional Mode on */ + max2165_write_reg(priv, REG_NDIV_FRAC2, 0x18); + /* LNA on */ + max2165_write_reg(priv, REG_LNA, 0x01); + max2165_write_reg(priv, REG_PLL_CFG, 0x7A); + max2165_write_reg(priv, REG_TEST, 0x08); + max2165_write_reg(priv, REG_SHUTDOWN, 0x40); + max2165_write_reg(priv, REG_VCO_CTRL, 0x84); + max2165_write_reg(priv, REG_BASEBAND_CTRL, 0xC3); + max2165_write_reg(priv, REG_DC_OFFSET_CTRL, 0x75); + max2165_write_reg(priv, REG_DC_OFFSET_DAC, 0x00); + max2165_write_reg(priv, REG_ROM_TABLE_ADDR, 0x00); + + max2165_set_osc(priv, priv->config->osc_clk); + + max2165_read_rom_table(priv); + + max2165_set_bandwidth(priv, BANDWIDTH_8_MHZ); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + return 0; +} + +static int max2165_release(struct dvb_frontend *fe) +{ + struct max2165_priv *priv = fe->tuner_priv; + dprintk("%s()\n", __func__); + + kfree(priv); + fe->tuner_priv = NULL; + + return 0; +} + +static const struct dvb_tuner_ops max2165_tuner_ops = { + .info = { + .name = "Maxim MAX2165", + .frequency_min = 470000000, + .frequency_max = 780000000, + .frequency_step = 50000, + }, + + .release = max2165_release, + .init = max2165_init, + .sleep = max2165_sleep, + + .set_params = max2165_set_params, + .set_analog_params = NULL, + .get_frequency = max2165_get_frequency, + .get_bandwidth = max2165_get_bandwidth, + .get_status = max2165_get_status +}; + +struct dvb_frontend *max2165_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + struct max2165_config *cfg) +{ + struct max2165_priv *priv = NULL; + + dprintk("%s(%d-%04x)\n", __func__, + i2c ? i2c_adapter_id(i2c) : -1, + cfg ? cfg->i2c_address : -1); + + priv = kzalloc(sizeof(struct max2165_priv), GFP_KERNEL); + if (priv == NULL) + return NULL; + + memcpy(&fe->ops.tuner_ops, &max2165_tuner_ops, + sizeof(struct dvb_tuner_ops)); + + priv->config = cfg; + priv->i2c = i2c; + fe->tuner_priv = priv; + + max2165_init(fe); + max2165_debug_status(priv); + + return fe; +} +EXPORT_SYMBOL(max2165_attach); + +MODULE_AUTHOR("David T. L. Wong "); +MODULE_DESCRIPTION("Maxim MAX2165 silicon tuner driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/common/tuners/max2165.h b/drivers/media/common/tuners/max2165.h new file mode 100644 index 00000000000..c063c36a93d --- /dev/null +++ b/drivers/media/common/tuners/max2165.h @@ -0,0 +1,48 @@ +/* + * Driver for Maxim MAX2165 silicon tuner + * + * Copyright (c) 2009 David T. L. Wong + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __MAX2165_H__ +#define __MAX2165_H__ + +struct dvb_frontend; +struct i2c_adapter; + +struct max2165_config { + u8 i2c_address; + u8 osc_clk; /* in MHz, selectable values: 4,16,18,20,22,24,26,28 */ +}; + +#if defined(CONFIG_MEDIA_TUNER_MAX2165) || \ + (defined(CONFIG_MEDIA_TUNER_MAX2165_MODULE) && defined(MODULE)) +extern struct dvb_frontend *max2165_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + struct max2165_config *cfg); +#else +static inline struct dvb_frontend *max2165_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + struct max2165_config *cfg) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif + +#endif diff --git a/drivers/media/common/tuners/max2165_priv.h b/drivers/media/common/tuners/max2165_priv.h new file mode 100644 index 00000000000..91bbe021a08 --- /dev/null +++ b/drivers/media/common/tuners/max2165_priv.h @@ -0,0 +1,60 @@ +/* + * Driver for Maxim MAX2165 silicon tuner + * + * Copyright (c) 2009 David T. L. Wong + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __MAX2165_PRIV_H__ +#define __MAX2165_PRIV_H__ + +#define REG_NDIV_INT 0x00 +#define REG_NDIV_FRAC2 0x01 +#define REG_NDIV_FRAC1 0x02 +#define REG_NDIV_FRAC0 0x03 +#define REG_TRACK_FILTER 0x04 +#define REG_LNA 0x05 +#define REG_PLL_CFG 0x06 +#define REG_TEST 0x07 +#define REG_SHUTDOWN 0x08 +#define REG_VCO_CTRL 0x09 +#define REG_BASEBAND_CTRL 0x0A +#define REG_DC_OFFSET_CTRL 0x0B +#define REG_DC_OFFSET_DAC 0x0C +#define REG_ROM_TABLE_ADDR 0x0D + +/* Read Only Registers */ +#define REG_ROM_TABLE_DATA 0x10 +#define REG_STATUS 0x11 +#define REG_AUTOTUNE 0x12 + +struct max2165_priv { + struct max2165_config *config; + struct i2c_adapter *i2c; + + u32 frequency; + u32 bandwidth; + + u8 tf_ntch_low_cfg; + u8 tf_ntch_hi_cfg; + u8 tf_balun_low_ref; + u8 tf_balun_hi_ref; + u8 bb_filter_7mhz_cfg; + u8 bb_filter_8mhz_cfg; +}; + +#endif -- cgit v1.2.3-70-g09d2 From ec27b6aafb1796a09aad401143f70ad079421ca4 Mon Sep 17 00:00:00 2001 From: "David T.L. Wong" Date: Mon, 26 Oct 2009 07:08:17 -0300 Subject: V4L/DVB (13374): AltoBeam ATBM8830 GB20600-2006(DMB-TH) demodulator Adds support for Maxim MAX2165 silicon tuner. It was tested on Mygica X8558Pro, which has MAX2165, ATBM8830 and CX23885. Signed-off-by: David T. L. Wong Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/Kconfig | 7 + drivers/media/dvb/frontends/Makefile | 1 + drivers/media/dvb/frontends/atbm8830.c | 495 ++++++++++++++++++++++++++++ drivers/media/dvb/frontends/atbm8830.h | 76 +++++ drivers/media/dvb/frontends/atbm8830_priv.h | 75 +++++ 5 files changed, 654 insertions(+) create mode 100644 drivers/media/dvb/frontends/atbm8830.c create mode 100644 drivers/media/dvb/frontends/atbm8830.h create mode 100644 drivers/media/dvb/frontends/atbm8830_priv.h (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 4f785f549d0..fdc7926cb2d 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -564,6 +564,13 @@ config DVB_LGS8GXX help A DMB-TH tuner module. Say Y when you want to support this frontend. +config DVB_ATBM8830 + tristate "AltoBeam ATBM8830/8831 DMB-TH demodulator" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + A DMB-TH tuner module. Say Y when you want to support this frontend. + comment "Tools to develop new frontends" config DVB_DUMMY_FE diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 1ca758eeff5..390eec6d5d8 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -64,6 +64,7 @@ obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o obj-$(CONFIG_DVB_S5H1411) += s5h1411.o obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o obj-$(CONFIG_DVB_LGS8GXX) += lgs8gxx.o +obj-$(CONFIG_DVB_ATBM8830) += atbm8830.o obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o obj-$(CONFIG_DVB_AF9013) += af9013.o obj-$(CONFIG_DVB_CX24116) += cx24116.o diff --git a/drivers/media/dvb/frontends/atbm8830.c b/drivers/media/dvb/frontends/atbm8830.c new file mode 100644 index 00000000000..87fb3c23b80 --- /dev/null +++ b/drivers/media/dvb/frontends/atbm8830.c @@ -0,0 +1,495 @@ +/* + * Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator + * ATBM8830, ATBM8831 + * + * Copyright (C) 2009 David T.L. Wong + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dvb_frontend.h" + +#include "atbm8830.h" +#include "atbm8830_priv.h" + +#define dprintk(args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG "atbm8830: " args); \ + } while (0) + +static int debug; + +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); + +static int atbm8830_write_reg(struct atbm_state *priv, u16 reg, u8 data) +{ + int ret = 0; + u8 dev_addr; + u8 buf1[] = { reg >> 8, reg & 0xFF }; + u8 buf2[] = { data }; + struct i2c_msg msg1 = { .flags = 0, .buf = buf1, .len = 2 }; + struct i2c_msg msg2 = { .flags = 0, .buf = buf2, .len = 1 }; + + dev_addr = priv->config->demod_address; + msg1.addr = dev_addr; + msg2.addr = dev_addr; + + if (debug >= 2) + printk(KERN_DEBUG "%s: reg=0x%04X, data=0x%02X\n", + __func__, reg, data); + + ret = i2c_transfer(priv->i2c, &msg1, 1); + if (ret != 1) + return -EIO; + + ret = i2c_transfer(priv->i2c, &msg2, 1); + return (ret != 1) ? -EIO : 0; +} + +static int atbm8830_read_reg(struct atbm_state *priv, u16 reg, u8 *p_data) +{ + int ret; + u8 dev_addr; + + u8 buf1[] = { reg >> 8, reg & 0xFF }; + u8 buf2[] = { 0 }; + struct i2c_msg msg1 = { .flags = 0, .buf = buf1, .len = 2 }; + struct i2c_msg msg2 = { .flags = I2C_M_RD, .buf = buf2, .len = 1 }; + + dev_addr = priv->config->demod_address; + msg1.addr = dev_addr; + msg2.addr = dev_addr; + + ret = i2c_transfer(priv->i2c, &msg1, 1); + if (ret != 1) { + dprintk(KERN_DEBUG "%s: error reg=0x%04x, ret=%i\n", + __func__, reg, ret); + return -EIO; + } + + ret = i2c_transfer(priv->i2c, &msg2, 1); + if (ret != 1) + return -EIO; + + *p_data = buf2[0]; + if (debug >= 2) + printk(KERN_DEBUG "%s: reg=0x%04X, data=0x%02X\n", + __func__, reg, buf2[0]); + + return 0; +} + +/* Lock register latch so that multi-register read is atomic */ +static inline int atbm8830_reglatch_lock(struct atbm_state *priv, int lock) +{ + return atbm8830_write_reg(priv, REG_READ_LATCH, lock ? 1 : 0); +} + +static int set_osc_freq(struct atbm_state *priv, u32 freq /*in kHz*/) +{ + u32 val; + + val = (u64)0x100000 * freq / 30400; + + atbm8830_write_reg(priv, REG_OSC_CLK, val); + atbm8830_write_reg(priv, REG_OSC_CLK + 1, val >> 8); + atbm8830_write_reg(priv, REG_OSC_CLK + 2, val >> 16); + + return 0; +} + +static int set_if_freq(struct atbm_state *priv, u32 freq /*in kHz*/) +{ + + u32 fs = priv->config->osc_clk_freq; + double t; + u32 val; + u8 dat; + + t = 2 * 3.141593 * (freq - fs) / fs * (1 << 22); + val = t; + + if (freq != 0) { + atbm8830_write_reg(priv, REG_TUNER_BASEBAND, 1); + atbm8830_write_reg(priv, REG_IF_FREQ, val); + atbm8830_write_reg(priv, REG_IF_FREQ+1, val >> 8); + atbm8830_write_reg(priv, REG_IF_FREQ+2, val >> 16); + + atbm8830_read_reg(priv, REG_ADC_CONFIG, &dat); + dat &= 0xFC; + atbm8830_write_reg(priv, REG_ADC_CONFIG, dat); + } else { + /* Zero IF */ + atbm8830_write_reg(priv, REG_TUNER_BASEBAND, 0); + + atbm8830_read_reg(priv, REG_ADC_CONFIG, &dat); + dat &= 0xFC; + dat |= 0x02; + atbm8830_write_reg(priv, REG_ADC_CONFIG, dat); + + if (priv->config->zif_swap_iq) + atbm8830_write_reg(priv, REG_SWAP_I_Q, 0x03); + else + atbm8830_write_reg(priv, REG_SWAP_I_Q, 0x01); + } + + return 0; +} + +static int is_locked(struct atbm_state *priv, u8 *locked) +{ + u8 status; + + atbm8830_read_reg(priv, REG_LOCK_STATUS, &status); + + if (locked != NULL) + *locked = (status == 1); + return 0; +} + +static int set_agc_config(struct atbm_state *priv, + u8 min, u8 max, u8 hold_loop) +{ + atbm8830_write_reg(priv, REG_AGC_MIN, min); + atbm8830_write_reg(priv, REG_AGC_MAX, max); + atbm8830_write_reg(priv, REG_AGC_HOLD_LOOP, hold_loop); + + return 0; +} + +static int set_static_channel_mode(struct atbm_state *priv) +{ + int i; + + for (i = 0; i < 5; i++) + atbm8830_write_reg(priv, 0x099B + i, 0x08); + + atbm8830_write_reg(priv, 0x095B, 0x7F); + atbm8830_write_reg(priv, 0x09CB, 0x01); + atbm8830_write_reg(priv, 0x09CC, 0x7F); + atbm8830_write_reg(priv, 0x09CD, 0x7F); + atbm8830_write_reg(priv, 0x0E01, 0x20); + + /* For single carrier */ + atbm8830_write_reg(priv, 0x0B03, 0x0A); + atbm8830_write_reg(priv, 0x0935, 0x10); + atbm8830_write_reg(priv, 0x0936, 0x08); + atbm8830_write_reg(priv, 0x093E, 0x08); + atbm8830_write_reg(priv, 0x096E, 0x06); + + /* frame_count_max0 */ + atbm8830_write_reg(priv, 0x0B09, 0x00); + /* frame_count_max1 */ + atbm8830_write_reg(priv, 0x0B0A, 0x08); + + return 0; +} + +static int set_ts_config(struct atbm_state *priv) +{ + const struct atbm8830_config *cfg = priv->config; + + /*Set parallel/serial ts mode*/ + atbm8830_write_reg(priv, REG_TS_SERIAL, cfg->serial_ts ? 1 : 0); + atbm8830_write_reg(priv, REG_TS_CLK_MODE, cfg->serial_ts ? 1 : 0); + /*Set ts sampling edge*/ + atbm8830_write_reg(priv, REG_TS_SAMPLE_EDGE, + cfg->ts_sampling_edge ? 1 : 0); + /*Set ts clock freerun*/ + atbm8830_write_reg(priv, REG_TS_CLK_FREERUN, + cfg->ts_clk_gated ? 0 : 1); + + return 0; +} + +static int atbm8830_init(struct dvb_frontend *fe) +{ + struct atbm_state *priv = fe->demodulator_priv; + const struct atbm8830_config *cfg = priv->config; + + /*Set oscillator frequency*/ + set_osc_freq(priv, cfg->osc_clk_freq); + + /*Set IF frequency*/ + set_if_freq(priv, cfg->if_freq); + + + /*Set static channel mode*/ + set_static_channel_mode(priv); + + set_ts_config(priv); + /*Turn off DSP reset*/ + atbm8830_write_reg(priv, 0x000A, 0); + + /*SW version test*/ + atbm8830_write_reg(priv, 0x020C, 11); + + /* Run */ + atbm8830_write_reg(priv, REG_DEMOD_RUN, 1); + + return 0; +} + + +static void atbm8830_release(struct dvb_frontend *fe) +{ + struct atbm_state *state = fe->demodulator_priv; + dprintk("%s\n", __func__); + + kfree(state); +} + +static int atbm8830_set_fe(struct dvb_frontend *fe, + struct dvb_frontend_parameters *fe_params) +{ + struct atbm_state *priv = fe->demodulator_priv; + int i; + u8 locked = 0; + dprintk("%s\n", __func__); + + /* set frequency */ + if (fe->ops.tuner_ops.set_params) { + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + fe->ops.tuner_ops.set_params(fe, fe_params); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + } + + /* start auto lock */ + for (i = 0; i < 10; i++) { + mdelay(100); + dprintk("Try %d\n", i); + is_locked(priv, &locked); + if (locked != 0) { + dprintk("ATBM8830 locked!\n"); + break; + } + } + + return 0; +} + +static int atbm8830_get_fe(struct dvb_frontend *fe, + struct dvb_frontend_parameters *fe_params) +{ + dprintk("%s\n", __func__); + + /* TODO: get real readings from device */ + /* inversion status */ + fe_params->inversion = INVERSION_OFF; + + /* bandwidth */ + fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; + + fe_params->u.ofdm.code_rate_HP = FEC_AUTO; + fe_params->u.ofdm.code_rate_LP = FEC_AUTO; + + fe_params->u.ofdm.constellation = QAM_AUTO; + + /* transmission mode */ + fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; + + /* guard interval */ + fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; + + /* hierarchy */ + fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE; + + return 0; +} + +static int atbm8830_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings *fesettings) +{ + fesettings->min_delay_ms = 0; + fesettings->step_size = 0; + fesettings->max_drift = 0; + return 0; +} + +static int atbm8830_read_status(struct dvb_frontend *fe, fe_status_t *fe_status) +{ + struct atbm_state *priv = fe->demodulator_priv; + u8 locked = 0; + u8 agc_locked = 0; + + dprintk("%s\n", __func__); + *fe_status = 0; + + is_locked(priv, &locked); + if (locked) { + *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; + } + dprintk("%s: fe_status=0x%x\n", __func__, *fe_status); + + atbm8830_read_reg(priv, REG_AGC_LOCK, &agc_locked); + dprintk("AGC Lock: %d\n", agc_locked); + + return 0; +} + +static int atbm8830_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + struct atbm_state *priv = fe->demodulator_priv; + u32 frame_err; + u8 t; + + dprintk("%s\n", __func__); + + atbm8830_reglatch_lock(priv, 1); + + atbm8830_read_reg(priv, REG_FRAME_ERR_CNT + 1, &t); + frame_err = t & 0x7F; + frame_err <<= 8; + atbm8830_read_reg(priv, REG_FRAME_ERR_CNT, &t); + frame_err |= t; + + atbm8830_reglatch_lock(priv, 0); + + *ber = frame_err * 100 / 32767; + + dprintk("%s: ber=0x%x\n", __func__, *ber); + return 0; +} + +static int atbm8830_read_signal_strength(struct dvb_frontend *fe, u16 *signal) +{ + struct atbm_state *priv = fe->demodulator_priv; + u32 pwm; + u8 t; + + dprintk("%s\n", __func__); + atbm8830_reglatch_lock(priv, 1); + + atbm8830_read_reg(priv, REG_AGC_PWM_VAL + 1, &t); + pwm = t & 0x03; + pwm <<= 8; + atbm8830_read_reg(priv, REG_AGC_PWM_VAL, &t); + pwm |= t; + + atbm8830_reglatch_lock(priv, 0); + + dprintk("AGC PWM = 0x%02X\n", pwm); + pwm = 0x400 - pwm; + + *signal = pwm * 0x10000 / 0x400; + + return 0; +} + +static int atbm8830_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + dprintk("%s\n", __func__); + *snr = 0; + return 0; +} + +static int atbm8830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + dprintk("%s\n", __func__); + *ucblocks = 0; + return 0; +} + +static int atbm8830_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct atbm_state *priv = fe->demodulator_priv; + + return atbm8830_write_reg(priv, REG_I2C_GATE, enable ? 1 : 0); +} + +static struct dvb_frontend_ops atbm8830_ops = { + .info = { + .name = "AltoBeam ATBM8830/8831 DMB-TH", + .type = FE_OFDM, + .frequency_min = 474000000, + .frequency_max = 858000000, + .frequency_stepsize = 10000, + .caps = + FE_CAN_FEC_AUTO | + FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO + }, + + .release = atbm8830_release, + + .init = atbm8830_init, + .sleep = NULL, + .write = NULL, + .i2c_gate_ctrl = atbm8830_i2c_gate_ctrl, + + .set_frontend = atbm8830_set_fe, + .get_frontend = atbm8830_get_fe, + .get_tune_settings = atbm8830_get_tune_settings, + + .read_status = atbm8830_read_status, + .read_ber = atbm8830_read_ber, + .read_signal_strength = atbm8830_read_signal_strength, + .read_snr = atbm8830_read_snr, + .read_ucblocks = atbm8830_read_ucblocks, +}; + +struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config, + struct i2c_adapter *i2c) +{ + struct atbm_state *priv = NULL; + u8 data = 0; + + dprintk("%s()\n", __func__); + + if (config == NULL || i2c == NULL) + return NULL; + + priv = kzalloc(sizeof(struct atbm_state), GFP_KERNEL); + if (priv == NULL) + goto error_out; + + priv->config = config; + priv->i2c = i2c; + + /* check if the demod is there */ + if (atbm8830_read_reg(priv, REG_CHIP_ID, &data) != 0) { + dprintk("%s atbm8830/8831 not found at i2c addr 0x%02X\n", + __func__, priv->config->demod_address); + goto error_out; + } + dprintk("atbm8830 chip id: 0x%02X\n", data); + + memcpy(&priv->frontend.ops, &atbm8830_ops, + sizeof(struct dvb_frontend_ops)); + priv->frontend.demodulator_priv = priv; + + atbm8830_init(&priv->frontend); + + atbm8830_i2c_gate_ctrl(&priv->frontend, 1); + + return &priv->frontend; + +error_out: + dprintk("%s() error_out\n", __func__); + kfree(priv); + return NULL; + +} +EXPORT_SYMBOL(atbm8830_attach); + +MODULE_DESCRIPTION("AltoBeam ATBM8830/8831 GB20600 demodulator driver"); +MODULE_AUTHOR("David T. L. Wong "); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/atbm8830.h b/drivers/media/dvb/frontends/atbm8830.h new file mode 100644 index 00000000000..e8149f39330 --- /dev/null +++ b/drivers/media/dvb/frontends/atbm8830.h @@ -0,0 +1,76 @@ +/* + * Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator + * ATBM8830, ATBM8831 + * + * Copyright (C) 2009 David T.L. Wong + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __ATBM8830_H__ +#define __ATBM8830_H__ + +#include +#include + +#define ATBM8830_PROD_8830 0 +#define ATBM8830_PROD_8831 1 + +struct atbm8830_config { + + /* product type */ + u8 prod; + + /* the demodulator's i2c address */ + u8 demod_address; + + /* parallel or serial transport stream */ + u8 serial_ts; + + /* transport stream clock output only when receving valid stream */ + u8 ts_clk_gated; + + /* Decoder sample TS data at rising edge of clock */ + u8 ts_sampling_edge; + + /* Oscillator clock frequency */ + u32 osc_clk_freq; /* in kHz */ + + /* IF frequency */ + u32 if_freq; /* in kHz */ + + /* Swap I/Q for zero IF */ + u8 zif_swap_iq; + + /* Tuner AGC settings */ + u8 agc_min; + u8 agc_max; + u8 agc_hold_loop; +}; + +#if defined(CONFIG_DVB_ATBM8830) || \ + (defined(CONFIG_DVB_ATBM8830_MODULE) && defined(MODULE)) +extern struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config, + struct i2c_adapter *i2c); +#else +static inline +struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config, + struct i2c_adapter *i2c) { + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* CONFIG_DVB_ATBM8830 */ + +#endif /* __ATBM8830_H__ */ diff --git a/drivers/media/dvb/frontends/atbm8830_priv.h b/drivers/media/dvb/frontends/atbm8830_priv.h new file mode 100644 index 00000000000..ce960f76092 --- /dev/null +++ b/drivers/media/dvb/frontends/atbm8830_priv.h @@ -0,0 +1,75 @@ +/* + * Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator + * ATBM8830, ATBM8831 + * + * Copyright (C) 2009 David T.L. Wong + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __ATBM8830_PRIV_H +#define __ATBM8830_PRIV_H + +struct atbm_state { + struct i2c_adapter *i2c; + /* configuration settings */ + const struct atbm8830_config *config; + struct dvb_frontend frontend; +}; + +#define REG_CHIP_ID 0x0000 +#define REG_TUNER_BASEBAND 0x0001 +#define REG_DEMOD_RUN 0x0004 +#define REG_DSP_RESET 0x0005 +#define REG_RAM_RESET 0x0006 +#define REG_ADC_RESET 0x0007 +#define REG_TSPORT_RESET 0x0008 +#define REG_BLKERR_POL 0x000C +#define REG_I2C_GATE 0x0103 +#define REG_TS_SAMPLE_EDGE 0x0301 +#define REG_TS_PKT_LEN_204 0x0302 +#define REG_TS_PKT_LEN_AUTO 0x0303 +#define REG_TS_SERIAL 0x0305 +#define REG_TS_CLK_FREERUN 0x0306 +#define REG_TS_VALID_MODE 0x0307 +#define REG_TS_CLK_MODE 0x030B /* 1 for serial, 0 for parallel */ + +#define REG_TS_ERRBIT_USE 0x030C +#define REG_LOCK_STATUS 0x030D +#define REG_ADC_CONFIG 0x0602 +#define REG_CARRIER_OFFSET 0x0827 /* 0x0827-0x0829 little endian */ +#define REG_DETECTED_PN_MODE 0x082D +#define REG_READ_LATCH 0x084D +#define REG_IF_FREQ 0x0A00 /* 0x0A00-0x0A02 little endian */ +#define REG_OSC_CLK 0x0A03 /* 0x0A03-0x0A05 little endian */ +#define REG_BYPASS_CCI 0x0A06 +#define REG_ANALOG_LUMA_DETECTED 0x0A25 +#define REG_ANALOG_AUDIO_DETECTED 0x0A26 +#define REG_ANALOG_CHROMA_DETECTED 0x0A39 +#define REG_FRAME_ERR_CNT 0x0B04 +#define REG_USE_EXT_ADC 0x0C00 +#define REG_SWAP_I_Q 0x0C01 +#define REG_TPS_MANUAL 0x0D01 +#define REG_TPS_CONFIG 0x0D02 +#define REG_BYPASS_DEINTERLEAVER 0x0E00 +#define REG_AGC_TARGET 0x1003 /* 0x1003-0x1005 little endian */ +#define REG_AGC_MIN 0x1020 +#define REG_AGC_MAX 0x1023 +#define REG_AGC_LOCK 0x1027 +#define REG_AGC_PWM_VAL 0x1028 /* 0x1028-0x1029 little endian */ +#define REG_AGC_HOLD_LOOP 0x1031 + +#endif + -- cgit v1.2.3-70-g09d2 From ea5697fe9ed6a1d534de436eff3138041e3c8aa9 Mon Sep 17 00:00:00 2001 From: "David T. L. Wong" Date: Mon, 26 Oct 2009 08:54:04 -0300 Subject: V4L/DVB (13375): cx23885: Add support for Mygica X8558Pro DMB-TH Adds support for cx23885 card Mygica X8558 Pro DMB-TH Signed-off-by: David T. L. Wong Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.cx23885 | 1 + drivers/media/video/cx23885/cx23885-cards.c | 26 ++++++++++++ drivers/media/video/cx23885/cx23885-dvb.c | 64 +++++++++++++++++++++++++++++ drivers/media/video/cx23885/cx23885.h | 1 + 4 files changed, 92 insertions(+) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885 index be293346ffe..7539e8fa1ff 100644 --- a/Documentation/video4linux/CARDLIST.cx23885 +++ b/Documentation/video4linux/CARDLIST.cx23885 @@ -25,3 +25,4 @@ 24 -> Hauppauge WinTV-HVR1850 [0070:8541] 25 -> Compro VideoMate E800 [1858:e800] 26 -> Hauppauge WinTV-HVR1290 [0070:8551] + 27 -> Mygica X8558 PRO DMB-TH [14f1:8578] diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index d9d71c8c794..23302ddf418 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -269,6 +269,11 @@ struct cx23885_board cx23885_boards[] = { .name = "Hauppauge WinTV-HVR1290", .portc = CX23885_MPEG_DVB, }, + [CX23885_BOARD_MYGICA_X8558PRO] = { + .name = "Mygica X8558 PRO DMB-TH", + .portb = CX23885_MPEG_DVB, + .portc = CX23885_MPEG_DVB, + }, }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); @@ -408,6 +413,10 @@ struct cx23885_subid cx23885_subids[] = { .subvendor = 0x0070, .subdevice = 0x8551, .card = CX23885_BOARD_HAUPPAUGE_HVR1290, + }, { + .subvendor = 0x14f1, + .subdevice = 0x8578, + .card = CX23885_BOARD_MYGICA_X8558PRO, }, }; const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); @@ -830,6 +839,15 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) cx23885_gpio_set(dev, GPIO_0 | GPIO_1 | GPIO_2); mdelay(100); break; + case CX23885_BOARD_MYGICA_X8558PRO: + /* GPIO-0 reset first ATBM8830 */ + /* GPIO-1 reset second ATBM8830 */ + cx23885_gpio_enable(dev, GPIO_0 | GPIO_1, 1); + cx23885_gpio_clear(dev, GPIO_0 | GPIO_1); + mdelay(100); + cx23885_gpio_set(dev, GPIO_0 | GPIO_1); + mdelay(100); + break; case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_HAUPPAUGE_HVR1290: /* GPIO-0 656_CLK */ @@ -1005,6 +1023,14 @@ void cx23885_card_setup(struct cx23885_dev *dev) ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; break; + case CX23885_BOARD_MYGICA_X8558PRO: + ts1->gen_ctrl_val = 0x5; /* Parallel */ + ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ + ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ + ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ + ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + break; case CX23885_BOARD_HAUPPAUGE_HVR1250: case CX23885_BOARD_HAUPPAUGE_HVR1500: case CX23885_BOARD_HAUPPAUGE_HVR1500Q: diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 133e8029071..bf24e86293c 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -38,6 +38,7 @@ #include "tda18271.h" #include "lgdt330x.h" #include "xc5000.h" +#include "max2165.h" #include "tda10048.h" #include "tuner-xc2028.h" #include "tuner-simple.h" @@ -54,6 +55,7 @@ #include "netup-eeprom.h" #include "netup-init.h" #include "lgdt3305.h" +#include "atbm8830.h" static unsigned int debug; @@ -543,6 +545,38 @@ static struct xc5000_config magicpro_prohdtve2_xc5000_config = { .if_khz = 6500, }; +static struct atbm8830_config mygica_x8558pro_atbm8830_cfg1 = { + .prod = ATBM8830_PROD_8830, + .demod_address = 0x44, + .serial_ts = 0, + .ts_sampling_edge = 1, + .ts_clk_gated = 0, + .osc_clk_freq = 30400, /* in kHz */ + .if_freq = 0, /* zero IF */ + .zif_swap_iq = 1, +}; + +static struct max2165_config mygic_x8558pro_max2165_cfg1 = { + .i2c_address = 0x60, + .osc_clk = 20 +}; + +static struct atbm8830_config mygica_x8558pro_atbm8830_cfg2 = { + .prod = ATBM8830_PROD_8830, + .demod_address = 0x44, + .serial_ts = 1, + .ts_sampling_edge = 1, + .ts_clk_gated = 0, + .osc_clk_freq = 30400, /* in kHz */ + .if_freq = 0, /* zero IF */ + .zif_swap_iq = 1, +}; + +static struct max2165_config mygic_x8558pro_max2165_cfg2 = { + .i2c_address = 0x60, + .osc_clk = 20 +}; + static int dvb_register(struct cx23885_tsport *port) { struct cx23885_dev *dev = port->dev; @@ -908,6 +942,36 @@ static int dvb_register(struct cx23885_tsport *port) 0x60, &dev->i2c_bus[0].i2c_adap, &hauppauge_tda18271_config); break; + case CX23885_BOARD_MYGICA_X8558PRO: + switch (port->nr) { + /* port B */ + case 1: + i2c_bus = &dev->i2c_bus[0]; + fe0->dvb.frontend = dvb_attach(atbm8830_attach, + &mygica_x8558pro_atbm8830_cfg1, + &i2c_bus->i2c_adap); + if (fe0->dvb.frontend != NULL) { + dvb_attach(max2165_attach, + fe0->dvb.frontend, + &i2c_bus->i2c_adap, + &mygic_x8558pro_max2165_cfg1); + } + break; + /* port C */ + case 2: + i2c_bus = &dev->i2c_bus[1]; + fe0->dvb.frontend = dvb_attach(atbm8830_attach, + &mygica_x8558pro_atbm8830_cfg2, + &i2c_bus->i2c_adap); + if (fe0->dvb.frontend != NULL) { + dvb_attach(max2165_attach, + fe0->dvb.frontend, + &i2c_bus->i2c_adap, + &mygic_x8558pro_max2165_cfg2); + } + break; + } + break; default: printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index 12d1a344a8a..33832002552 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h @@ -80,6 +80,7 @@ #define CX23885_BOARD_HAUPPAUGE_HVR1850 24 #define CX23885_BOARD_COMPRO_VIDEOMATE_E800 25 #define CX23885_BOARD_HAUPPAUGE_HVR1290 26 +#define CX23885_BOARD_MYGICA_X8558PRO 27 #define GPIO_0 0x00000001 #define GPIO_1 0x00000002 -- cgit v1.2.3-70-g09d2 From b18bd1d8806c0982c7835dcb58a27c4e9005e4fb Mon Sep 17 00:00:00 2001 From: David Wong Date: Mon, 26 Oct 2009 09:41:22 -0300 Subject: V4L/DVB (13376): cx-usb: add Mygica D689 DMB-TH USB support X-Patchwork-Id: 55873 Add support for cxusb card Mygica D689 DBM-TH USB Signed-off-by: David T. L. Wong Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/cxusb.c | 118 ++++++++++++++++++++++++++++++++ drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 119 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 2a53dd096ee..542de171874 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -36,9 +36,11 @@ #include "tuner-xc2028.h" #include "tuner-simple.h" #include "mxl5005s.h" +#include "max2165.h" #include "dib7000p.h" #include "dib0070.h" #include "lgs8gxx.h" +#include "atbm8830.h" /* debug */ static int dvb_usb_cxusb_debug; @@ -714,6 +716,11 @@ static struct mxl5005s_config d680_dmb_tuner = { .AgcMasterByte = 0x00, }; +static struct max2165_config mygica_d689_max2165_cfg = { + .i2c_address = 0x60, + .osc_clk = 20 +}; + /* Callbacks for DVB USB */ static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap) { @@ -813,6 +820,14 @@ static int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap) return (fe == NULL) ? -EIO : 0; } +static int cxusb_mygica_d689_tuner_attach(struct dvb_usb_adapter *adap) +{ + struct dvb_frontend *fe; + fe = dvb_attach(max2165_attach, adap->fe, + &adap->dev->i2c_adap, &mygica_d689_max2165_cfg); + return (fe == NULL) ? -EIO : 0; +} + static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap) { u8 b; @@ -1160,6 +1175,56 @@ static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap) return 0; } +static struct atbm8830_config mygica_d689_atbm8830_cfg = { + .prod = ATBM8830_PROD_8830, + .demod_address = 0x40, + .serial_ts = 0, + .ts_sampling_edge = 1, + .ts_clk_gated = 0, + .osc_clk_freq = 30400, /* in kHz */ + .if_freq = 0, /* zero IF */ + .zif_swap_iq = 1, +}; + +static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap) +{ + struct dvb_usb_device *d = adap->dev; + int n; + + /* Select required USB configuration */ + if (usb_set_interface(d->udev, 0, 0) < 0) + err("set interface failed"); + + /* Unblock all USB pipes */ + usb_clear_halt(d->udev, + usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); + usb_clear_halt(d->udev, + usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); + usb_clear_halt(d->udev, + usb_rcvbulkpipe(d->udev, d->props.adapter[0].stream.endpoint)); + + + /* Reset the tuner */ + if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) { + err("clear tuner gpio failed"); + return -EIO; + } + msleep(100); + if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) { + err("set tuner gpio failed"); + return -EIO; + } + msleep(100); + + /* Attach frontend */ + adap->fe = dvb_attach(atbm8830_attach, &mygica_d689_atbm8830_cfg, + &d->i2c_adap); + if (adap->fe == NULL) + return -EIO; + + return 0; +} + /* * DViCO has shipped two devices with the same USB ID, but only one of them * needs a firmware download. Check the device class details to see if they @@ -1240,6 +1305,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties; static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties; static struct dvb_usb_device_properties cxusb_aver_a868r_properties; static struct dvb_usb_device_properties cxusb_d680_dmb_properties; +static struct dvb_usb_device_properties cxusb_mygica_d689_properties; static int cxusb_probe(struct usb_interface *intf, const struct usb_device_id *id) @@ -1268,6 +1334,8 @@ static int cxusb_probe(struct usb_interface *intf, THIS_MODULE, NULL, adapter_nr) || 0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties, THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties, + THIS_MODULE, NULL, adapter_nr) || 0) return 0; @@ -1294,6 +1362,7 @@ static struct usb_device_id cxusb_table [] = { { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) }, { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) }, { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) }, + { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) }, {} /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, cxusb_table); @@ -1837,6 +1906,55 @@ static struct dvb_usb_device_properties cxusb_d680_dmb_properties = { } }; +static struct dvb_usb_device_properties cxusb_mygica_d689_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = CYPRESS_FX2, + + .size_of_priv = sizeof(struct cxusb_state), + + .num_adapters = 1, + .adapter = { + { + .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl, + .frontend_attach = cxusb_mygica_d689_frontend_attach, + .tuner_attach = cxusb_mygica_d689_tuner_attach, + + /* parameter for the MPEG2-data transfer */ + .stream = { + .type = USB_BULK, + .count = 5, + .endpoint = 0x02, + .u = { + .bulk = { + .buffersize = 8192, + } + } + }, + }, + }, + + .power_ctrl = cxusb_d680_dmb_power_ctrl, + + .i2c_algo = &cxusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + + .rc_interval = 100, + .rc_key_map = d680_dmb_rc_keys, + .rc_key_map_size = ARRAY_SIZE(d680_dmb_rc_keys), + .rc_query = cxusb_d680_dmb_rc_query, + + .num_device_descs = 1, + .devices = { + { + "Mygica D689 DMB-TH", + { NULL }, + { &cxusb_table[19], NULL }, + }, + } +}; + static struct usb_driver cxusb_driver = { .name = "dvb_usb_cxusb", .probe = cxusb_probe, diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index dc57fe1b6f0..f1602d4ace6 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -279,6 +279,7 @@ #define USB_PID_TELESTAR_STARSTICK_2 0x8000 #define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807 #define USB_PID_SONY_PLAYTV 0x0003 +#define USB_PID_MYGICA_D689 0xd811 #define USB_PID_ELGATO_EYETV_DTT 0x0021 #define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020 #define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000 -- cgit v1.2.3-70-g09d2 From 38a54f35a0a90c0b62b111dd4de24248b22616b9 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Tue, 17 Nov 2009 19:43:41 -0300 Subject: V4L/DVB (13377): make struct videobuf_queue_ops constant The videobuf_queue_ops function vector is not declared constant, but there's no need for the videobuf layer to ever change it. Make it const so that videobuf users can make their operations const without warnings. Signed-off-by: Jonathan Corbet Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videobuf-core.c | 2 +- drivers/media/video/videobuf-dma-contig.c | 2 +- drivers/media/video/videobuf-dma-sg.c | 2 +- drivers/media/video/videobuf-vmalloc.c | 2 +- include/media/videobuf-core.h | 4 ++-- include/media/videobuf-dma-contig.h | 2 +- include/media/videobuf-dma-sg.h | 2 +- include/media/videobuf-vmalloc.h | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index a96b08d3df5..136bc3496c8 100644 --- a/drivers/media/video/videobuf-core.c +++ b/drivers/media/video/videobuf-core.c @@ -110,7 +110,7 @@ EXPORT_SYMBOL_GPL(videobuf_queue_to_vmalloc); void videobuf_queue_core_init(struct videobuf_queue *q, - struct videobuf_queue_ops *ops, + const struct videobuf_queue_ops *ops, struct device *dev, spinlock_t *irqlock, enum v4l2_buf_type type, diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c index c3065c4bcba..d25f28461da 100644 --- a/drivers/media/video/videobuf-dma-contig.c +++ b/drivers/media/video/videobuf-dma-contig.c @@ -429,7 +429,7 @@ static struct videobuf_qtype_ops qops = { }; void videobuf_queue_dma_contig_init(struct videobuf_queue *q, - struct videobuf_queue_ops *ops, + const struct videobuf_queue_ops *ops, struct device *dev, spinlock_t *irqlock, enum v4l2_buf_type type, diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index a583d394696..fa78555b118 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c @@ -702,7 +702,7 @@ void *videobuf_sg_alloc(size_t size) } void videobuf_queue_sg_init(struct videobuf_queue* q, - struct videobuf_queue_ops *ops, + const struct videobuf_queue_ops *ops, struct device *dev, spinlock_t *irqlock, enum v4l2_buf_type type, diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c index 35f3900c563..99d646ed024 100644 --- a/drivers/media/video/videobuf-vmalloc.c +++ b/drivers/media/video/videobuf-vmalloc.c @@ -391,7 +391,7 @@ static struct videobuf_qtype_ops qops = { }; void videobuf_queue_vmalloc_init(struct videobuf_queue* q, - struct videobuf_queue_ops *ops, + const struct videobuf_queue_ops *ops, void *dev, spinlock_t *irqlock, enum v4l2_buf_type type, diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h index 1c5946c4475..316fdccdcaa 100644 --- a/include/media/videobuf-core.h +++ b/include/media/videobuf-core.h @@ -166,7 +166,7 @@ struct videobuf_queue { enum v4l2_field field; enum v4l2_field last; /* for field=V4L2_FIELD_ALTERNATE */ struct videobuf_buffer *bufs[VIDEO_MAX_FRAME]; - struct videobuf_queue_ops *ops; + const struct videobuf_queue_ops *ops; struct videobuf_qtype_ops *int_ops; unsigned int streaming:1; @@ -195,7 +195,7 @@ void *videobuf_queue_to_vmalloc (struct videobuf_queue* q, struct videobuf_buffer *buf); void videobuf_queue_core_init(struct videobuf_queue *q, - struct videobuf_queue_ops *ops, + const struct videobuf_queue_ops *ops, struct device *dev, spinlock_t *irqlock, enum v4l2_buf_type type, diff --git a/include/media/videobuf-dma-contig.h b/include/media/videobuf-dma-contig.h index 549386681aa..ebaa9bc1ee8 100644 --- a/include/media/videobuf-dma-contig.h +++ b/include/media/videobuf-dma-contig.h @@ -17,7 +17,7 @@ #include void videobuf_queue_dma_contig_init(struct videobuf_queue *q, - struct videobuf_queue_ops *ops, + const struct videobuf_queue_ops *ops, struct device *dev, spinlock_t *irqlock, enum v4l2_buf_type type, diff --git a/include/media/videobuf-dma-sg.h b/include/media/videobuf-dma-sg.h index dda47f0082e..53e72f78717 100644 --- a/include/media/videobuf-dma-sg.h +++ b/include/media/videobuf-dma-sg.h @@ -103,7 +103,7 @@ struct videobuf_dmabuf *videobuf_to_dma (struct videobuf_buffer *buf); void *videobuf_sg_alloc(size_t size); void videobuf_queue_sg_init(struct videobuf_queue* q, - struct videobuf_queue_ops *ops, + const struct videobuf_queue_ops *ops, struct device *dev, spinlock_t *irqlock, enum v4l2_buf_type type, diff --git a/include/media/videobuf-vmalloc.h b/include/media/videobuf-vmalloc.h index e87222c6a12..1ffdb662443 100644 --- a/include/media/videobuf-vmalloc.h +++ b/include/media/videobuf-vmalloc.h @@ -30,7 +30,7 @@ struct videobuf_vmalloc_memory }; void videobuf_queue_vmalloc_init(struct videobuf_queue* q, - struct videobuf_queue_ops *ops, + const struct videobuf_queue_ops *ops, void *dev, spinlock_t *irqlock, enum v4l2_buf_type type, -- cgit v1.2.3-70-g09d2 From caac970f91f39f67b5e48680840605e24896ff99 Mon Sep 17 00:00:00 2001 From: Alexander Strakh Date: Tue, 17 Nov 2009 19:43:37 -0300 Subject: V4L/DVB (13378): konicawc.c: possible buffer overflow while use strncat In driver ./drivers/media/video/usbvideo/konicawc.c in line 227: 227 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname)); After this line we use strncat: 228 strncat(cam->input_physname, "/input0", sizeof(cam->input_physname)); where sizeof(cam->input_physname) returns length of cam->input_phisname without length for null-symbol. But this parameter must be - "maximum numbers of bytes to copy", i.e.: sizeof(cam->input_physname)-strlen(cam->input_physname)-1. In this case, after call to usb_make_path the similar drivers use strlcat. Like in drivers/hid/usbhid/hid-core.c: 1152 usb_make_path(dev, hid->phys, sizeof(hid->phys)); 1153 strlcat(hid->phys, "/input", sizeof(hid->phys)); Found by Linux Driver Verification Project. Use strlcat instead of strncat. Signed-off-by: Alexander Strakh Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/usbvideo/konicawc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c index 31d57f2d09e..a0addcb0429 100644 --- a/drivers/media/video/usbvideo/konicawc.c +++ b/drivers/media/video/usbvideo/konicawc.c @@ -225,7 +225,7 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev int error; usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname)); - strncat(cam->input_physname, "/input0", sizeof(cam->input_physname)); + strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname)); cam->input = input_dev = input_allocate_device(); if (!input_dev) { -- cgit v1.2.3-70-g09d2 From 2b588db82d2c210e84da129a223bb403d3131abe Mon Sep 17 00:00:00 2001 From: Alexander Strakh Date: Tue, 17 Nov 2009 19:43:38 -0300 Subject: V4L/DVB (13379): quickcam_messenger: possible buffer overflow while use strncat In driver ./drivers/media/video/usbvideo/quickcam_messenger.c in line 91: 91 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname)); After this line we use strncat: 92 strncat(cam->input_physname, "/input0", sizeof(cam->input_physname)); where sizeof(cam->input_physname) returns length of cam->input_phisname without length for null-symbol. But this parameter must be - "maximum numbers of bytes to copy", i.e.: sizeof(cam->input_physname)-strlen(cam->input_physname)-1. In this case, after call to usb_make_path the similar drivers use strlcat. Like in: drivers/hid/usbhid/hid-core.c: 1152 usb_make_path(dev, hid->phys, sizeof(hid->phys)); 1153 strlcat(hid->phys, "/input", sizeof(hid->phys)); Found by Linux Driver Verification Project. Use strlcat instead of strncat. Signed-off-by: Alexander Strakh Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/usbvideo/quickcam_messenger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c index 803d3e4e29a..c4d1b96b5ce 100644 --- a/drivers/media/video/usbvideo/quickcam_messenger.c +++ b/drivers/media/video/usbvideo/quickcam_messenger.c @@ -89,7 +89,7 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev) int error; usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname)); - strncat(cam->input_physname, "/input0", sizeof(cam->input_physname)); + strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname)); cam->input = input_dev = input_allocate_device(); if (!input_dev) { -- cgit v1.2.3-70-g09d2 From 3a054627cc949c3b7bb8387543919e7d4022753a Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Tue, 17 Nov 2009 19:43:40 -0300 Subject: V4L/DVB (13380): sms-cards: make id unsigned in sms_get_board() Make id signed so we can't get an invalid pointer when we pass a negative id. Signed-off-by: Roel Kluin Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/sms-cards.c | 2 +- drivers/media/dvb/siano/sms-cards.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index e21638969cd..1067b22eb0c 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c @@ -97,7 +97,7 @@ static struct sms_board sms_boards[] = { }, }; -struct sms_board *sms_get_board(int id) +struct sms_board *sms_get_board(unsigned id) { BUG_ON(id >= ARRAY_SIZE(sms_boards)); diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h index 38f062f6ad6..8f19fc000b4 100644 --- a/drivers/media/dvb/siano/sms-cards.h +++ b/drivers/media/dvb/siano/sms-cards.h @@ -81,7 +81,7 @@ struct sms_board { int led_power, led_hi, led_lo, lna_ctrl, rf_switch; }; -struct sms_board *sms_get_board(int id); +struct sms_board *sms_get_board(unsigned id); extern struct smscore_device_t *coredev; -- cgit v1.2.3-70-g09d2 From 67c98f72e132e191ff4db0ac7bd81ea94fa5c667 Mon Sep 17 00:00:00 2001 From: Márton Németh Date: Sat, 7 Nov 2009 05:45:33 -0300 Subject: V4L/DVB (13382): gspca - pac7302: Remove redundant stream off command. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The stream off command is sent to the device twice, one is enough. Signed-off-by: Márton Németh Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac7302.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index 09d3d191d94..ae1d90a85c5 100644 --- a/drivers/media/video/gspca/pac7302.c +++ b/drivers/media/video/gspca/pac7302.c @@ -606,9 +606,9 @@ static int sd_start(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev) { + /* stop stream */ reg_w(gspca_dev, 0xff, 0x01); reg_w(gspca_dev, 0x78, 0x00); - reg_w(gspca_dev, 0x78, 0x00); } /* called on streamoff with alt 0 and on disconnect for pac7302 */ -- cgit v1.2.3-70-g09d2 From b1784b3377bdeaeb6b9d01e651ff07bd44fec0f4 Mon Sep 17 00:00:00 2001 From: Márton Németh Date: Sat, 7 Nov 2009 05:52:02 -0300 Subject: V4L/DVB (13383): gspca - pac7311/pac7302: Propagate error to higher level software. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The usb_control_msg() can fail any time. Only continue writing sequence if there was no error with the previous write. If there was any problem stop sending URBs and propagate the error to the gspca_main. Signed-off-by: Márton Németh Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac7302.c | 155 ++++++++++++++++++++++------------ drivers/media/video/gspca/pac7311.c | 161 +++++++++++++++++++++++------------- 2 files changed, 207 insertions(+), 109 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index ae1d90a85c5..ec2930871d1 100644 --- a/drivers/media/video/gspca/pac7302.c +++ b/drivers/media/video/gspca/pac7302.c @@ -331,7 +331,7 @@ static const __u8 page3_7302[] = { 0x00 }; -static void reg_w_buf(struct gspca_dev *gspca_dev, +static int reg_w_buf(struct gspca_dev *gspca_dev, __u8 index, const char *buffer, int len) { @@ -349,10 +349,11 @@ static void reg_w_buf(struct gspca_dev *gspca_dev, PDEBUG(D_ERR, "reg_w_buf(): " "Failed to write registers to index 0x%x, error %i", index, ret); + return ret; } -static void reg_w(struct gspca_dev *gspca_dev, +static int reg_w(struct gspca_dev *gspca_dev, __u8 index, __u8 value) { @@ -369,23 +370,27 @@ static void reg_w(struct gspca_dev *gspca_dev, PDEBUG(D_ERR, "reg_w(): " "Failed to write register to index 0x%x, value 0x%x, error %i", index, value, ret); + return ret; } -static void reg_w_seq(struct gspca_dev *gspca_dev, +static int reg_w_seq(struct gspca_dev *gspca_dev, const __u8 *seq, int len) { + int ret = 0; while (--len >= 0) { - reg_w(gspca_dev, seq[0], seq[1]); + if (0 <= ret) + ret = reg_w(gspca_dev, seq[0], seq[1]); seq += 2; } + return ret; } /* load the beginning of a page */ -static void reg_w_page(struct gspca_dev *gspca_dev, +static int reg_w_page(struct gspca_dev *gspca_dev, const __u8 *page, int len) { int index; - int ret; + int ret = 0; for (index = 0; index < len; index++) { if (page[index] == SKIP) /* skip this index */ @@ -397,52 +402,61 @@ static void reg_w_page(struct gspca_dev *gspca_dev, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, index, gspca_dev->usb_buf, 1, 500); - if (ret < 0) + if (ret < 0) { PDEBUG(D_ERR, "reg_w_page(): " "Failed to write register to index 0x%x, " "value 0x%x, error %i", index, page[index], ret); + break; + } } + return ret; } /* output a variable sequence */ -static void reg_w_var(struct gspca_dev *gspca_dev, +static int reg_w_var(struct gspca_dev *gspca_dev, const __u8 *seq, const __u8 *page3, unsigned int page3_len, const __u8 *page4, unsigned int page4_len) { int index, len; + int ret = 0; for (;;) { index = *seq++; len = *seq++; switch (len) { case END_OF_SEQUENCE: - return; + return ret; case LOAD_PAGE4: - reg_w_page(gspca_dev, page4, page4_len); + ret = reg_w_page(gspca_dev, page4, page4_len); break; case LOAD_PAGE3: - reg_w_page(gspca_dev, page3, page3_len); + ret = reg_w_page(gspca_dev, page3, page3_len); break; default: if (len > USB_BUF_SZ) { PDEBUG(D_ERR|D_STREAM, "Incorrect variable sequence"); - return; + return -EINVAL; } while (len > 0) { if (len < 8) { - reg_w_buf(gspca_dev, index, seq, len); + ret = reg_w_buf(gspca_dev, + index, seq, len); + if (ret < 0) + return ret; seq += len; break; } - reg_w_buf(gspca_dev, index, seq, 8); + ret = reg_w_buf(gspca_dev, index, seq, 8); seq += 8; index += 8; len -= 8; } } + if (ret < 0) + return ret; } /* not reached */ } @@ -472,10 +486,11 @@ static int sd_config(struct gspca_dev *gspca_dev, } /* This function is used by pac7302 only */ -static void setbrightcont(struct gspca_dev *gspca_dev) +static int setbrightcont(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int i, v; + int ret; static const __u8 max[10] = {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb, 0xd4, 0xec}; @@ -483,7 +498,7 @@ static void setbrightcont(struct gspca_dev *gspca_dev) {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17, 0x11, 0x0b}; - reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ + ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ for (i = 0; i < 10; i++) { v = max[i]; v += (sd->brightness - BRIGHTNESS_MAX) @@ -493,47 +508,62 @@ static void setbrightcont(struct gspca_dev *gspca_dev) v = 0; else if (v > 0xff) v = 0xff; - reg_w(gspca_dev, 0xa2 + i, v); + if (0 <= ret) + ret = reg_w(gspca_dev, 0xa2 + i, v); } - reg_w(gspca_dev, 0xdc, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0xdc, 0x01); + return ret; } /* This function is used by pac7302 only */ -static void setcolors(struct gspca_dev *gspca_dev) +static int setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int i, v; + int ret; static const int a[9] = {217, -212, 0, -101, 170, -67, -38, -315, 355}; static const int b[9] = {19, 106, 0, 19, 106, 1, 19, 106, 1}; - reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ - reg_w(gspca_dev, 0x11, 0x01); - reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ + ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ + if (0 <= ret) + ret = reg_w(gspca_dev, 0x11, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ for (i = 0; i < 9; i++) { v = a[i] * sd->colors / COLOR_MAX + b[i]; - reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07); - reg_w(gspca_dev, 0x0f + 2 * i + 1, v); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x0f + 2 * i + 1, v); } - reg_w(gspca_dev, 0xdc, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0xdc, 0x01); PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); + return ret; } -static void setgain(struct gspca_dev *gspca_dev) +static int setgain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + int ret; - reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ - reg_w(gspca_dev, 0x10, sd->gain >> 3); + ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ + if (0 <= ret) + ret = reg_w(gspca_dev, 0x10, sd->gain >> 3); /* load registers to sensor (Bit 0, auto clear) */ - reg_w(gspca_dev, 0x11, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x11, 0x01); + return ret; } -static void setexposure(struct gspca_dev *gspca_dev) +static int setexposure(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + int ret; __u8 reg; /* register 2 of frame 3/4 contains the clock divider configuring the @@ -549,47 +579,58 @@ static void setexposure(struct gspca_dev *gspca_dev) the nearest multiple of 3, except when between 6 and 12? */ if (reg < 6 || reg > 12) reg = ((reg + 1) / 3) * 3; - reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ - reg_w(gspca_dev, 0x02, reg); + ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ + if (0 <= ret) + ret = reg_w(gspca_dev, 0x02, reg); /* load registers to sensor (Bit 0, auto clear) */ - reg_w(gspca_dev, 0x11, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x11, 0x01); + return ret; } -static void sethvflip(struct gspca_dev *gspca_dev) +static int sethvflip(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + int ret; __u8 data; - reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ + ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ data = (sd->hflip ? 0x08 : 0x00) | (sd->vflip ? 0x04 : 0x00); - reg_w(gspca_dev, 0x21, data); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x21, data); /* load registers to sensor (Bit 0, auto clear) */ - reg_w(gspca_dev, 0x11, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x11, 0x01); + return ret; } /* this function is called at probe and resume time for pac7302 */ static int sd_init(struct gspca_dev *gspca_dev) { - reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2); - - return 0; + return reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2); } static int sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + int ret = 0; sd->sof_read = 0; - reg_w_var(gspca_dev, start_7302, + ret = reg_w_var(gspca_dev, start_7302, page3_7302, sizeof(page3_7302), NULL, 0); - setbrightcont(gspca_dev); - setcolors(gspca_dev); - setgain(gspca_dev); - setexposure(gspca_dev); - sethvflip(gspca_dev); + if (0 <= ret) + ret = setbrightcont(gspca_dev); + if (0 <= ret) + ret = setcolors(gspca_dev); + if (0 <= ret) + setgain(gspca_dev); + if (0 <= ret) + setexposure(gspca_dev); + if (0 <= ret) + sethvflip(gspca_dev); /* only resolution 640x480 is supported for pac7302 */ @@ -598,26 +639,34 @@ static int sd_start(struct gspca_dev *gspca_dev) atomic_set(&sd->avg_lum, -1); /* start stream */ - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x78, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0xff, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x78, 0x01); - return 0; + return ret; } static void sd_stopN(struct gspca_dev *gspca_dev) { + int ret; + /* stop stream */ - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x78, 0x00); + ret = reg_w(gspca_dev, 0xff, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x78, 0x00); } /* called on streamoff with alt 0 and on disconnect for pac7302 */ static void sd_stop0(struct gspca_dev *gspca_dev) { + int ret; + if (!gspca_dev->present) return; - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x78, 0x40); + ret = reg_w(gspca_dev, 0xff, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x78, 0x40); } /* Include pac common sof detection functions */ diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index b1127d94897..c3e1f80351a 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -259,7 +259,7 @@ static const __u8 page4_7311[] = { 0x23, 0x28, 0x04, 0x11, 0x00, 0x00 }; -static void reg_w_buf(struct gspca_dev *gspca_dev, +static int reg_w_buf(struct gspca_dev *gspca_dev, __u8 index, const char *buffer, int len) { @@ -277,10 +277,11 @@ static void reg_w_buf(struct gspca_dev *gspca_dev, PDEBUG(D_ERR, "reg_w_buf(): " "Failed to write registers to index 0x%x, error %i", index, ret); + return ret; } -static void reg_w(struct gspca_dev *gspca_dev, +static int reg_w(struct gspca_dev *gspca_dev, __u8 index, __u8 value) { @@ -297,23 +298,27 @@ static void reg_w(struct gspca_dev *gspca_dev, PDEBUG(D_ERR, "reg_w(): " "Failed to write register to index 0x%x, value 0x%x, error %i", index, value, ret); + return ret; } -static void reg_w_seq(struct gspca_dev *gspca_dev, +static int reg_w_seq(struct gspca_dev *gspca_dev, const __u8 *seq, int len) { + int ret = 0; while (--len >= 0) { - reg_w(gspca_dev, seq[0], seq[1]); + if (0 <= ret) + ret = reg_w(gspca_dev, seq[0], seq[1]); seq += 2; } + return ret; } /* load the beginning of a page */ -static void reg_w_page(struct gspca_dev *gspca_dev, +static int reg_w_page(struct gspca_dev *gspca_dev, const __u8 *page, int len) { int index; - int ret; + int ret = 0; for (index = 0; index < len; index++) { if (page[index] == SKIP) /* skip this index */ @@ -325,52 +330,61 @@ static void reg_w_page(struct gspca_dev *gspca_dev, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, index, gspca_dev->usb_buf, 1, 500); - if (ret < 0) + if (ret < 0) { PDEBUG(D_ERR, "reg_w_page(): " "Failed to write register to index 0x%x, " "value 0x%x, error %i", index, page[index], ret); + break; + } } + return ret; } /* output a variable sequence */ -static void reg_w_var(struct gspca_dev *gspca_dev, +static int reg_w_var(struct gspca_dev *gspca_dev, const __u8 *seq, const __u8 *page3, unsigned int page3_len, const __u8 *page4, unsigned int page4_len) { int index, len; + int ret = 0; for (;;) { index = *seq++; len = *seq++; switch (len) { case END_OF_SEQUENCE: - return; + return ret; case LOAD_PAGE4: - reg_w_page(gspca_dev, page4, page4_len); + ret = reg_w_page(gspca_dev, page4, page4_len); break; case LOAD_PAGE3: - reg_w_page(gspca_dev, page3, page3_len); + ret = reg_w_page(gspca_dev, page3, page3_len); break; default: if (len > USB_BUF_SZ) { PDEBUG(D_ERR|D_STREAM, "Incorrect variable sequence"); - return; + return -EINVAL; } while (len > 0) { if (len < 8) { - reg_w_buf(gspca_dev, index, seq, len); + ret = reg_w_buf(gspca_dev, + index, seq, len); + if (ret < 0) + return ret; seq += len; break; } - reg_w_buf(gspca_dev, index, seq, 8); + ret = reg_w_buf(gspca_dev, index, seq, 8); seq += 8; index += 8; len -= 8; } } + if (ret < 0) + return ret; } /* not reached */ } @@ -398,36 +412,46 @@ static int sd_config(struct gspca_dev *gspca_dev, } /* This function is used by pac7311 only */ -static void setcontrast(struct gspca_dev *gspca_dev) +static int setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + int ret; - reg_w(gspca_dev, 0xff, 0x04); - reg_w(gspca_dev, 0x10, sd->contrast >> 4); + ret = reg_w(gspca_dev, 0xff, 0x04); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x10, sd->contrast >> 4); /* load registers to sensor (Bit 0, auto clear) */ - reg_w(gspca_dev, 0x11, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x11, 0x01); + return ret; } -static void setgain(struct gspca_dev *gspca_dev) +static int setgain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int gain = GAIN_MAX - sd->gain; + int ret; if (gain < 1) gain = 1; else if (gain > 245) gain = 245; - reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ - reg_w(gspca_dev, 0x0e, 0x00); - reg_w(gspca_dev, 0x0f, gain); + ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ + if (0 <= ret) + ret = reg_w(gspca_dev, 0x0e, 0x00); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x0f, gain); /* load registers to sensor (Bit 0, auto clear) */ - reg_w(gspca_dev, 0x11, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x11, 0x01); + return ret; } -static void setexposure(struct gspca_dev *gspca_dev) +static int setexposure(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + int ret; __u8 reg; /* register 2 of frame 3/4 contains the clock divider configuring the @@ -439,71 +463,94 @@ static void setexposure(struct gspca_dev *gspca_dev) else if (reg > 63) reg = 63; - reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ - reg_w(gspca_dev, 0x02, reg); + ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ + if (0 <= ret) + ret = reg_w(gspca_dev, 0x02, reg); /* Page 1 register 8 must always be 0x08 except when not in 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */ - reg_w(gspca_dev, 0xff, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0xff, 0x01); if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv && - reg <= 3) - reg_w(gspca_dev, 0x08, 0x09); - else - reg_w(gspca_dev, 0x08, 0x08); + reg <= 3) { + if (0 <= ret) + ret = reg_w(gspca_dev, 0x08, 0x09); + } else { + if (0 <= ret) + ret = reg_w(gspca_dev, 0x08, 0x08); + } /* load registers to sensor (Bit 0, auto clear) */ - reg_w(gspca_dev, 0x11, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x11, 0x01); + return ret; } -static void sethvflip(struct gspca_dev *gspca_dev) +static int sethvflip(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + int ret; __u8 data; - reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ + ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00); - reg_w(gspca_dev, 0x21, data); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x21, data); /* load registers to sensor (Bit 0, auto clear) */ - reg_w(gspca_dev, 0x11, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x11, 0x01); + return ret; } /* this function is called at probe and resume time for pac7311 */ static int sd_init(struct gspca_dev *gspca_dev) { - reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2); - - return 0; + return reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2); } static int sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + int ret; sd->sof_read = 0; - reg_w_var(gspca_dev, start_7311, + ret = reg_w_var(gspca_dev, start_7311, NULL, 0, page4_7311, sizeof(page4_7311)); - setcontrast(gspca_dev); - setgain(gspca_dev); - setexposure(gspca_dev); - sethvflip(gspca_dev); + if (0 <= ret) + ret = setcontrast(gspca_dev); + if (0 <= ret) + ret = setgain(gspca_dev); + if (0 <= ret) + ret = setexposure(gspca_dev); + if (0 <= ret) + ret = sethvflip(gspca_dev); /* set correct resolution */ switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { case 2: /* 160x120 pac7311 */ - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x17, 0x20); - reg_w(gspca_dev, 0x87, 0x10); + if (0 <= ret) + ret = reg_w(gspca_dev, 0xff, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x17, 0x20); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x87, 0x10); break; case 1: /* 320x240 pac7311 */ - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x17, 0x30); - reg_w(gspca_dev, 0x87, 0x11); + if (0 <= ret) + ret = reg_w(gspca_dev, 0xff, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x17, 0x30); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x87, 0x11); break; case 0: /* 640x480 */ - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x17, 0x00); - reg_w(gspca_dev, 0x87, 0x12); + if (0 <= ret) + ret = reg_w(gspca_dev, 0xff, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x17, 0x00); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x87, 0x12); break; } @@ -512,10 +559,12 @@ static int sd_start(struct gspca_dev *gspca_dev) atomic_set(&sd->avg_lum, -1); /* start stream */ - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x78, 0x05); + if (0 <= ret) + ret = reg_w(gspca_dev, 0xff, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x78, 0x05); - return 0; + return ret; } static void sd_stopN(struct gspca_dev *gspca_dev) -- cgit v1.2.3-70-g09d2 From d5aa3856fd09ad0ea04619d6cba31192dac08e84 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 7 Nov 2009 06:10:08 -0300 Subject: V4L/DVB (13384): gspca - sonixj: Optimize code and add some comments. - the i2c base address is now taken from the sn9c1xx register table Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 161 +++++++++++++++++++------------------ 1 file changed, 82 insertions(+), 79 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index a9643a0f78d..5f82efb93d9 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -1,5 +1,6 @@ /* * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver + * * Copyright (C) 2009 Jean-Francois Moine * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr * @@ -72,7 +73,7 @@ struct sd { #define SENSOR_OV7648 6 #define SENSOR_OV7660 7 #define SENSOR_SP80708 8 - u8 i2c_base; + u8 i2c_addr; u8 *jpeg_hdr; }; @@ -597,10 +598,11 @@ static const u8 om6802_sensor_init[][8] = { {0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10}, /* factory mode */ {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10}, + /* output raw RGB */ {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10}, /* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */ {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10}, - /* white balance & auto-exposure */ + /* auto-exposure speed (0) / white balance mode (auto RGB) */ /* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10}, * set color mode */ /* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10}, @@ -614,7 +616,7 @@ static const u8 om6802_sensor_init[][8] = { /* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10}, * preset gamma */ {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10}, - /* luminance mode (0x4f = AE) */ + /* luminance mode (0x4f -> AutoExpo on) */ {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10}, /* preset shutter */ /* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10}, @@ -999,7 +1001,7 @@ static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) gspca_dev->usb_buf[0] = 0x81 | (2 << 4); break; } - gspca_dev->usb_buf[1] = sd->i2c_base; + gspca_dev->usb_buf[1] = sd->i2c_addr; gspca_dev->usb_buf[2] = reg; gspca_dev->usb_buf[3] = val; gspca_dev->usb_buf[4] = 0; @@ -1045,7 +1047,7 @@ static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg) mode[0] = 0x81 | 0x10; break; } - mode[1] = sd->i2c_base; + mode[1] = sd->i2c_addr; mode[2] = reg; mode[3] = 0; mode[4] = 0; @@ -1132,7 +1134,6 @@ static void mi0360_probe(struct gspca_dev *gspca_dev) case 0x823a: PDEBUG(D_PROBE, "Sensor mt9v111"); sd->sensor = SENSOR_MT9V111; - sd->i2c_base = 0x5c; break; case 0x8243: PDEBUG(D_PROBE, "Sensor mi0360"); @@ -1160,7 +1161,7 @@ static void bridge_init(struct gspca_dev *gspca_dev, /* configure gpio */ reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); - reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */ + reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); switch (sd->sensor) { case SENSOR_OV7660: case SENSOR_SP80708: @@ -1172,7 +1173,7 @@ static void bridge_init(struct gspca_dev *gspca_dev, } reg_w(gspca_dev, 0x9a, reg9a, 6); - reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/ + reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); @@ -1222,14 +1223,15 @@ static void bridge_init(struct gspca_dev *gspca_dev, msleep(100); reg_w1(gspca_dev, 0x02, 0x62); break; + default: /* case SENSOR_HV7131R: */ /* case SENSOR_MI0360: */ /* case SENSOR_MO4000: */ - default: reg_w1(gspca_dev, 0x01, 0x43); reg_w1(gspca_dev, 0x17, 0x61); reg_w1(gspca_dev, 0x01, 0x42); - if (sd->sensor == SENSOR_HV7131R) + if (sd->sensor == SENSOR_HV7131R + && sd->bridge == BRIDGE_SN9C102P) hv7131r_probe(gspca_dev); break; } @@ -1248,8 +1250,7 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->npkt = 24; /* 24 packets per ISOC message */ sd->bridge = id->driver_info >> 16; - sd->sensor = id->driver_info >> 8; - sd->i2c_base = id->driver_info; + sd->sensor = id->driver_info; sd->brightness = BRIGHTNESS_DEF; sd->contrast = CONTRAST_DEF; @@ -1273,6 +1274,7 @@ static int sd_config(struct gspca_dev *gspca_dev, static int sd_init(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + const u8 *sn9c1xx; u8 regGpio[] = { 0x29, 0x74 }; u8 regF1; @@ -1315,6 +1317,10 @@ static int sd_init(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0xf1, 0x01); + /* set the i2c address */ + sn9c1xx = sn_tb[sd->sensor]; + sd->i2c_addr = sn9c1xx[9]; + return 0; } @@ -1326,7 +1332,7 @@ static u32 setexposure(struct gspca_dev *gspca_dev, switch (sd->sensor) { case SENSOR_HV7131R: { u8 Expodoit[] = - { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 }; + { 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 }; Expodoit[3] = expo >> 16; Expodoit[4] = expo >> 8; @@ -1336,7 +1342,7 @@ static u32 setexposure(struct gspca_dev *gspca_dev, } case SENSOR_MI0360: { u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */ - { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 }; + { 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 }; static const u8 doit[] = /* update sensor */ { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 }; static const u8 sensorgo[] = /* sensor on */ @@ -1355,9 +1361,9 @@ static u32 setexposure(struct gspca_dev *gspca_dev, } case SENSOR_MO4000: { u8 expoMof[] = - { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 }; + { 0xa1, 0x21, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x10 }; u8 expoMo10[] = - { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 }; + { 0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10 }; static const u8 gainMo[] = { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d }; @@ -1393,6 +1399,7 @@ static u32 setexposure(struct gspca_dev *gspca_dev, case SENSOR_OM6802: { u8 gainOm[] = { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 }; + /* preset AGC - works when AutoExpo = off */ if (expo > 0x03ff) expo = 0x03ff; @@ -1400,7 +1407,7 @@ static u32 setexposure(struct gspca_dev *gspca_dev, expo = 0x0001; gainOm[3] = expo >> 2; i2c_w8(gspca_dev, gainOm); - reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f); + reg_w1(gspca_dev, 0x96, expo >> 5); PDEBUG(D_FRAM, "set exposure %d", gainOm[3]); break; } @@ -1432,7 +1439,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) case SENSOR_MT9V111: expo = sd->brightness >> 8; sd->exposure = setexposure(gspca_dev, expo); - break; + return; /* don't set the Y offset */ case SENSOR_OM6802: expo = sd->brightness >> 6; sd->exposure = setexposure(gspca_dev, expo); @@ -1440,8 +1447,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) break; } - if (sd->sensor != SENSOR_MT9V111) - reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */ + reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */ } static void setcontrast(struct gspca_dev *gspca_dev) @@ -1469,6 +1475,7 @@ static void setcolors(struct gspca_dev *gspca_dev) -24, -38, 64, /* UR UG UB */ 62, -51, -9 /* VR VG VB */ }; + for (i = 0; i < 6; i++) { v = uv[i] * sd->colors / COLOR_DEF; reg8a[i * 2] = v; @@ -1692,6 +1699,7 @@ static int sd_start(struct gspca_dev *gspca_dev) /* initialize the bridge */ sn9c1xx = sn_tb[sd->sensor]; bridge_init(gspca_dev, sn9c1xx); + /* initialize the sensor */ i2c_w_seq(gspca_dev, sensor_init[sd->sensor]); @@ -1779,7 +1787,7 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */ init = NULL; - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; + mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; if (mode) reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */ else @@ -1913,12 +1921,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev) case SENSOR_OV7630: data = 0x29; break; - default: -/* case SENSOR_MO4000: */ -/* case SENSOR_OV7660: */ - break; } - sn9c1xx = sn_tb[(int) sd->sensor]; + sn9c1xx = sn_tb[sd->sensor]; reg_w1(gspca_dev, 0x01, sn9c1xx[1]); reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]); reg_w1(gspca_dev, 0x01, sn9c1xx[1]); @@ -2277,70 +2281,69 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define BSI(bridge, sensor, i2c_addr) \ +#define BS(bridge, sensor) \ .driver_info = (BRIDGE_ ## bridge << 16) \ - | (SENSOR_ ## sensor << 8) \ - | (i2c_addr) + | SENSOR_ ## sensor static const __devinitdata struct usb_device_id device_table[] = { #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE - {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)}, - {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)}, + {USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)}, + {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)}, #endif - {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)}, - {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)}, - {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)}, - {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)}, - {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)}, - {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)}, - {USB_DEVICE(0x06f8, 0x3008), BSI(SN9C105, OV7660, 0x21)}, -/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x21)}, */ - {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)}, -/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x21)}, */ -/* {USB_DEVICE(0x0c45, 0x607b), BSI(SN9C102P, OV7660, 0x21)}, */ - {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)}, -/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x21)}, */ - {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)}, -/* {USB_DEVICE(0x0c45, 0x60c2), BSI(SN9C105, P1030xC, 0x??)}, */ -/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6802, 0x34)}, */ -/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */ - {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)}, -/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */ -/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x21)}, */ - {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)}, + {USB_DEVICE(0x045e, 0x00f5), BS(SN9C105, OV7660)}, + {USB_DEVICE(0x045e, 0x00f7), BS(SN9C105, OV7660)}, + {USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)}, + {USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)}, + {USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)}, + {USB_DEVICE(0x06f8, 0x3004), BS(SN9C105, OV7660)}, + {USB_DEVICE(0x06f8, 0x3008), BS(SN9C105, OV7660)}, +/* {USB_DEVICE(0x0c45, 0x603a), BS(SN9C102P, OV7648)}, */ + {USB_DEVICE(0x0c45, 0x6040), BS(SN9C102P, HV7131R)}, +/* {USB_DEVICE(0x0c45, 0x607a), BS(SN9C102P, OV7648)}, */ +/* {USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */ + {USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)}, +/* {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */ + {USB_DEVICE(0x0c45, 0x60c0), BS(SN9C105, MI0360)}, +/* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */ +/* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */ +/* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */ + {USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)}, +/* {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */ +/* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */ + {USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)}, #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE - {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)}, - {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)}, + {USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)}, + {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)}, #endif - {USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/ -/* {USB_DEVICE(0x0c45, 0x6102), BSI(SN9C120, P1030xC, ??)}, */ -/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6802, 0x34)}, */ - {USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/ - {USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/ - {USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/ - {USB_DEVICE(0x0c45, 0x610e), BSI(SN9C120, OV7630, 0x21)}, /*sn9c128*/ -/* {USB_DEVICE(0x0c45, 0x610f), BSI(SN9C120, S5K53BEB, 0x??)}, */ -/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ -/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ - {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C120, OM6802, 0x34)}, /*sn9c325?*/ + {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/ +/* {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, P1030xC)}, */ +/* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */ + {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)}, /*sn9c128*/ + {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)}, /*sn9c128*/ + {USB_DEVICE(0x0c45, 0x610c), BS(SN9C120, HV7131R)}, /*sn9c128*/ + {USB_DEVICE(0x0c45, 0x610e), BS(SN9C120, OV7630)}, /*sn9c128*/ +/* {USB_DEVICE(0x0c45, 0x610f), BS(SN9C120, S5K53BEB)}, */ +/* {USB_DEVICE(0x0c45, 0x6122), BS(SN9C110, ICM105C)}, */ +/* {USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */ + {USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)}, /*sn9c325?*/ /*bw600.inf:*/ - {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/ - {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)}, - {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)}, -/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */ + {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)}, /*sn9c110?*/ + {USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)}, + {USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)}, +/* {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */ #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE - {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)}, + {USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)}, #endif -/* {USB_DEVICE(0x0c45, 0x6132), BSI(SN9C120, OV7670, 0x21)}, */ - {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)}, - {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)}, +/* {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */ + {USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)}, + {USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)}, #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE - {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)}, + {USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)}, #endif - {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)}, - {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x21)}, -/* {USB_DEVICE(0x0c45, 0x6142), BSI(SN9C120, PO2030N, ??)}, *sn9c120b*/ - {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)}, /*sn9c120b*/ - {USB_DEVICE(0x0c45, 0x6148), BSI(SN9C120, OM6802, 0x34)}, /*sn9c120b*/ + {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)}, + {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)}, +/* {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, *sn9c120b*/ + {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/ + {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/ {} }; MODULE_DEVICE_TABLE(usb, device_table); -- cgit v1.2.3-70-g09d2 From 265a8098e75e156985abfaac250ee4f2b407f863 Mon Sep 17 00:00:00 2001 From: Márton Németh Date: Sat, 7 Nov 2009 15:15:56 -0300 Subject: V4L/DVB (13385): gspca - pac7302: Add red and blue balance control. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The valid values for these controls are 0..3 (lower two bits) which was identified by trial and error on Labtec Webcam 2200 (USB ID 093a:2626). The upper 6 bits are ignored on page 0, registers 0xc5 and 0xc7 by the camera. Signed-off-by: Márton Németh Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac7302.c | 126 ++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index ec2930871d1..e7a4ced86e9 100644 --- a/drivers/media/video/gspca/pac7302.c +++ b/drivers/media/video/gspca/pac7302.c @@ -49,6 +49,20 @@ -/0x27 Seems to toggle various gains on / off, Setting bit 7 seems to completely disable the analog amplification block. Set to 0x68 for max gain, 0x14 for minimal gain. + + The registers are accessed in the following functions: + + Page | Register | Function + -----+------------+--------------------------------------------------- + 0 | 0x0f..0x20 | setcolors() + 0 | 0xa2..0xab | setbrightcont() + 0 | 0xc5 | setredbalance() + 0 | 0xc7 | setbluebalance() + 0 | 0xdc | setbrightcont(), setcolors() + 3 | 0x02 | setexposure() + 3 | 0x10 | setgain() + 3 | 0x11 | setcolors(), setgain(), setexposure(), sethvflip() + 3 | 0x21 | sethvflip() */ #define MODULE_NAME "pac7302" @@ -66,6 +80,8 @@ struct sd { unsigned char brightness; unsigned char contrast; unsigned char colors; + unsigned char red_balance; + unsigned char blue_balance; unsigned char gain; unsigned char exposure; unsigned char autogain; @@ -85,6 +101,10 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); @@ -145,6 +165,34 @@ static struct ctrl sd_ctrls[] = { .set = sd_setcolors, .get = sd_getcolors, }, + { + { + .id = V4L2_CID_RED_BALANCE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Red", + .minimum = 0, + .maximum = 3, + .step = 1, +#define REDBALANCE_DEF 1 + .default_value = REDBALANCE_DEF, + }, + .set = sd_setredbalance, + .get = sd_getredbalance, + }, + { + { + .id = V4L2_CID_BLUE_BALANCE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Blue", + .minimum = 0, + .maximum = 3, + .step = 1, +#define BLUEBALANCE_DEF 1 + .default_value = BLUEBALANCE_DEF, + }, + .set = sd_setbluebalance, + .get = sd_getbluebalance, + }, /* All controls below are for both the 7302 and the 7311 */ { { @@ -477,6 +525,8 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->brightness = BRIGHTNESS_DEF; sd->contrast = CONTRAST_DEF; sd->colors = COLOR_DEF; + sd->red_balance = REDBALANCE_DEF; + sd->blue_balance = BLUEBALANCE_DEF; sd->gain = GAIN_DEF; sd->exposure = EXPOSURE_DEF; sd->autogain = AUTOGAIN_DEF; @@ -545,6 +595,36 @@ static int setcolors(struct gspca_dev *gspca_dev) return ret; } +static int setredbalance(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int ret; + + ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ + if (0 <= ret) + ret = reg_w(gspca_dev, 0xc5, sd->red_balance); + + if (0 <= ret) + ret = reg_w(gspca_dev, 0xdc, 0x01); + PDEBUG(D_CONF|D_STREAM, "red_balance: %i", sd->red_balance); + return ret; +} + +static int setbluebalance(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int ret; + + ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ + if (0 <= ret) + ret = reg_w(gspca_dev, 0xc7, sd->blue_balance); + + if (0 <= ret) + ret = reg_w(gspca_dev, 0xdc, 0x01); + PDEBUG(D_CONF|D_STREAM, "blue_balance: %i", sd->blue_balance); + return ret; +} + static int setgain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -625,6 +705,10 @@ static int sd_start(struct gspca_dev *gspca_dev) ret = setbrightcont(gspca_dev); if (0 <= ret) ret = setcolors(gspca_dev); + if (0 <= ret) + ret = setredbalance(gspca_dev); + if (0 <= ret) + ret = setbluebalance(gspca_dev); if (0 <= ret) setgain(gspca_dev); if (0 <= ret) @@ -857,6 +941,48 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + int ret = 0; + + sd->red_balance = val; + if (gspca_dev->streaming) + ret = setredbalance(gspca_dev); + if (0 <= ret) + ret = 0; + return ret; +} + +static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->red_balance; + return 0; +} + +static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + int ret = 0; + + sd->blue_balance = val; + if (gspca_dev->streaming) + ret = setbluebalance(gspca_dev); + if (0 <= ret) + ret = 0; + return ret; +} + +static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->blue_balance; + return 0; +} + static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; -- cgit v1.2.3-70-g09d2 From 77ee33184fb4a37926c460d337c8d181f7c4c680 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 7 Nov 2009 15:30:50 -0300 Subject: V4L/DVB (13386): gspca - main: Change version to 2.8.0. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index eb166048540..ecf449be189 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -47,7 +47,7 @@ MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("GSPCA USB Camera Driver"); MODULE_LICENSE("GPL"); -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 7, 0) +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 8, 0) #ifdef GSPCA_DEBUG int gspca_debug = D_ERR | D_PROBE; @@ -74,7 +74,7 @@ static void PDEBUG_MODE(char *txt, __u32 pixfmt, int w, int h) #define PDEBUG_MODE(txt, pixfmt, w, h) #endif -/* specific memory types - !! should different from V4L2_MEMORY_xxx */ +/* specific memory types - !! should be different from V4L2_MEMORY_xxx */ #define GSPCA_MEMORY_NO 0 /* V4L2_MEMORY_xxx starts from 1 */ #define GSPCA_MEMORY_READ 7 -- cgit v1.2.3-70-g09d2 From b760812ed78c93249ac7957fedb87ba9c3ca3906 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 7 Nov 2009 16:38:55 -0300 Subject: V4L/DVB (13387): gspca - main: Fix a compilation warning. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index ecf449be189..afd99beab30 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -1619,7 +1619,7 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma) size -= PAGE_SIZE; } - vma->vm_ops = &gspca_vm_ops; + vma->vm_ops = (struct vm_operations_struct *) &gspca_vm_ops; vma->vm_private_data = frame; gspca_vm_open(vma); ret = 0; -- cgit v1.2.3-70-g09d2 From 23fbee6f88d59b4edca0855242d55e5b7cfc2401 Mon Sep 17 00:00:00 2001 From: Marton Nemeth Date: Sun, 8 Nov 2009 04:35:12 -0300 Subject: V4L/DVB (13388): gspca - pac7302: Add white balance control. Signed-off-by: Marton Nemeth Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac7302.c | 57 +++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index e7a4ced86e9..f8bf6a63f04 100644 --- a/drivers/media/video/gspca/pac7302.c +++ b/drivers/media/video/gspca/pac7302.c @@ -57,6 +57,7 @@ 0 | 0x0f..0x20 | setcolors() 0 | 0xa2..0xab | setbrightcont() 0 | 0xc5 | setredbalance() + 0 | 0xc6 | setwhitebalance() 0 | 0xc7 | setbluebalance() 0 | 0xdc | setbrightcont(), setcolors() 3 | 0x02 | setexposure() @@ -80,6 +81,7 @@ struct sd { unsigned char brightness; unsigned char contrast; unsigned char colors; + unsigned char white_balance; unsigned char red_balance; unsigned char blue_balance; unsigned char gain; @@ -101,6 +103,8 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val); static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val); @@ -165,6 +169,20 @@ static struct ctrl sd_ctrls[] = { .set = sd_setcolors, .get = sd_getcolors, }, + { + { + .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "White Balance", + .minimum = 0, + .maximum = 255, + .step = 1, +#define WHITEBALANCE_DEF 4 + .default_value = WHITEBALANCE_DEF, + }, + .set = sd_setwhitebalance, + .get = sd_getwhitebalance, + }, { { .id = V4L2_CID_RED_BALANCE, @@ -525,6 +543,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->brightness = BRIGHTNESS_DEF; sd->contrast = CONTRAST_DEF; sd->colors = COLOR_DEF; + sd->white_balance = WHITEBALANCE_DEF; sd->red_balance = REDBALANCE_DEF; sd->blue_balance = BLUEBALANCE_DEF; sd->gain = GAIN_DEF; @@ -595,6 +614,21 @@ static int setcolors(struct gspca_dev *gspca_dev) return ret; } +static int setwhitebalance(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int ret; + + ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ + if (0 <= ret) + ret = reg_w(gspca_dev, 0xc6, sd->white_balance); + + if (0 <= ret) + ret = reg_w(gspca_dev, 0xdc, 0x01); + PDEBUG(D_CONF|D_STREAM, "white_balance: %i", sd->white_balance); + return ret; +} + static int setredbalance(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -705,6 +739,8 @@ static int sd_start(struct gspca_dev *gspca_dev) ret = setbrightcont(gspca_dev); if (0 <= ret) ret = setcolors(gspca_dev); + if (0 <= ret) + ret = setwhitebalance(gspca_dev); if (0 <= ret) ret = setredbalance(gspca_dev); if (0 <= ret) @@ -941,6 +977,27 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + int ret = 0; + + sd->white_balance = val; + if (gspca_dev->streaming) + ret = setwhitebalance(gspca_dev); + if (0 <= ret) + ret = 0; + return ret; +} + +static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->white_balance; + return 0; +} + static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; -- cgit v1.2.3-70-g09d2 From 012880be6e1c8503e2901f8de90cc1e711334989 Mon Sep 17 00:00:00 2001 From: Marton Nemeth Date: Sun, 8 Nov 2009 04:41:28 -0300 Subject: V4L/DVB (13389): gspca - pac7302: Handle return values in sd_start(). Signed-off-by: Marton Nemeth Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac7302.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index f8bf6a63f04..5cd02571bbf 100644 --- a/drivers/media/video/gspca/pac7302.c +++ b/drivers/media/video/gspca/pac7302.c @@ -746,11 +746,11 @@ static int sd_start(struct gspca_dev *gspca_dev) if (0 <= ret) ret = setbluebalance(gspca_dev); if (0 <= ret) - setgain(gspca_dev); + ret = setgain(gspca_dev); if (0 <= ret) - setexposure(gspca_dev); + ret = setexposure(gspca_dev); if (0 <= ret) - sethvflip(gspca_dev); + ret = sethvflip(gspca_dev); /* only resolution 640x480 is supported for pac7302 */ -- cgit v1.2.3-70-g09d2 From c4c1e295d2721470141843e31a69c4b1c131e0f7 Mon Sep 17 00:00:00 2001 From: "hiranotaka@zng.jp" Date: Sun, 8 Nov 2009 05:42:28 -0300 Subject: V4L/DVB (13394): pt1: Support FE_READ_SNR Signed-off-by: HIRANO Takahito Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/pt1/va1j5jf8007s.c | 55 ++++++++++++++++++++++++++++++++++++ drivers/media/dvb/pt1/va1j5jf8007t.c | 47 ++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.c b/drivers/media/dvb/pt1/va1j5jf8007s.c index 2db940f8635..a20927e10d7 100644 --- a/drivers/media/dvb/pt1/va1j5jf8007s.c +++ b/drivers/media/dvb/pt1/va1j5jf8007s.c @@ -48,6 +48,60 @@ struct va1j5jf8007s_state { enum va1j5jf8007s_tune_state tune_state; }; +static int va1j5jf8007s_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + struct va1j5jf8007s_state *state; + u8 addr; + int i; + u8 write_buf[1], read_buf[1]; + struct i2c_msg msgs[2]; + s32 word, x1, x2, x3, x4, x5, y; + + state = fe->demodulator_priv; + addr = state->config->demod_address; + + word = 0; + for (i = 0; i < 2; i++) { + write_buf[0] = 0xbc + i; + + msgs[0].addr = addr; + msgs[0].flags = 0; + msgs[0].len = sizeof(write_buf); + msgs[0].buf = write_buf; + + msgs[1].addr = addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = sizeof(read_buf); + msgs[1].buf = read_buf; + + if (i2c_transfer(state->adap, msgs, 2) != 2) + return -EREMOTEIO; + + word <<= 8; + word |= read_buf[0]; + } + + word -= 3000; + if (word < 0) + word = 0; + + x1 = int_sqrt(word << 16) * ((15625ll << 21) / 1000000); + x2 = (s64)x1 * x1 >> 31; + x3 = (s64)x2 * x1 >> 31; + x4 = (s64)x2 * x2 >> 31; + x5 = (s64)x4 * x1 >> 31; + + y = (58857ll << 23) / 1000; + y -= (s64)x1 * ((89565ll << 24) / 1000) >> 30; + y += (s64)x2 * ((88977ll << 24) / 1000) >> 28; + y -= (s64)x3 * ((50259ll << 25) / 1000) >> 27; + y += (s64)x4 * ((14341ll << 27) / 1000) >> 27; + y -= (s64)x5 * ((16346ll << 30) / 10000) >> 28; + + *snr = y < 0 ? 0 : y >> 15; + return 0; +} + static int va1j5jf8007s_get_frontend_algo(struct dvb_frontend *fe) { return DVBFE_ALGO_HW; @@ -536,6 +590,7 @@ static struct dvb_frontend_ops va1j5jf8007s_ops = { FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO, }, + .read_snr = va1j5jf8007s_read_snr, .get_frontend_algo = va1j5jf8007s_get_frontend_algo, .read_status = va1j5jf8007s_read_status, .tune = va1j5jf8007s_tune, diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.c b/drivers/media/dvb/pt1/va1j5jf8007t.c index 71117f4ca7e..fe897343f4f 100644 --- a/drivers/media/dvb/pt1/va1j5jf8007t.c +++ b/drivers/media/dvb/pt1/va1j5jf8007t.c @@ -46,6 +46,52 @@ struct va1j5jf8007t_state { enum va1j5jf8007t_tune_state tune_state; }; +static int va1j5jf8007t_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + struct va1j5jf8007t_state *state; + u8 addr; + int i; + u8 write_buf[1], read_buf[1]; + struct i2c_msg msgs[2]; + s32 word, x, y; + + state = fe->demodulator_priv; + addr = state->config->demod_address; + + word = 0; + for (i = 0; i < 3; i++) { + write_buf[0] = 0x8b + i; + + msgs[0].addr = addr; + msgs[0].flags = 0; + msgs[0].len = sizeof(write_buf); + msgs[0].buf = write_buf; + + msgs[1].addr = addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = sizeof(read_buf); + msgs[1].buf = read_buf; + + if (i2c_transfer(state->adap, msgs, 2) != 2) + return -EREMOTEIO; + + word <<= 8; + word |= read_buf[0]; + } + + if (!word) + return -EIO; + + x = 10 * (intlog10(0x540000 * 100 / word) - (2 << 24)); + y = (24ll << 46) / 1000000; + y = ((s64)y * x >> 30) - (16ll << 40) / 10000; + y = ((s64)y * x >> 29) + (398ll << 35) / 10000; + y = ((s64)y * x >> 30) + (5491ll << 29) / 10000; + y = ((s64)y * x >> 30) + (30965ll << 23) / 10000; + *snr = y >> 15; + return 0; +} + static int va1j5jf8007t_get_frontend_algo(struct dvb_frontend *fe) { return DVBFE_ALGO_HW; @@ -393,6 +439,7 @@ static struct dvb_frontend_ops va1j5jf8007t_ops = { FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO, }, + .read_snr = va1j5jf8007t_read_snr, .get_frontend_algo = va1j5jf8007t_get_frontend_algo, .read_status = va1j5jf8007t_read_status, .tune = va1j5jf8007t_tune, -- cgit v1.2.3-70-g09d2 From b921d929f4a012be3e809fbb1ff1e8e6c0751c06 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 8 Nov 2009 14:49:05 -0300 Subject: V4L/DVB (13396): correct initialization of audio_mode This initialization of the value of audio_mode is the one used if nothing matches in the subsequent switch. The variable audio_mode is subsequently assigned to constants such as TUNER_AUDIO_MONO and TUNER_AUDIO_STEREO. TUNER_AUDIO_STEREO has the same value as V4L2_TUNER_MODE_STEREO, so it would seem better to use that value here. Signed-off-by: Julia Lawall Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa717x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c index ad6cd37311f..6818df57116 100644 --- a/drivers/media/video/saa717x.c +++ b/drivers/media/video/saa717x.c @@ -1312,7 +1312,7 @@ static int saa717x_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) "MONO", "STEREO", "LANG1", "LANG2/SAP" }; - audio_mode = V4L2_TUNER_MODE_STEREO; + audio_mode = TUNER_AUDIO_STEREO; switch (vt->audmode) { case V4L2_TUNER_MODE_MONO: -- cgit v1.2.3-70-g09d2 From 56411f49f69140b97e259256b99dc276f2b2b427 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 8 Nov 2009 18:28:45 -0300 Subject: V4L/DVB (13397): firedtv: move remote control workqueue handling into rc source file Preparation for the port of firedtv to the firewire-core kernel API: Canceling of the remote control workqueue job is factored into firedtv-rc.c. Plus trivial whitespace change. Signed-off-by: Stefan Richter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/firewire/firedtv-1394.c | 5 +++-- drivers/media/dvb/firewire/firedtv-rc.c | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c index 2b6eeeab5b2..a2e3841f8ee 100644 --- a/drivers/media/dvb/firewire/firedtv-1394.c +++ b/drivers/media/dvb/firewire/firedtv-1394.c @@ -212,6 +212,7 @@ static int node_probe(struct device *dev) goto fail; avc_register_remote_control(fdtv); + return 0; fail: spin_lock_irq(&node_list_lock); @@ -220,6 +221,7 @@ fail: fdtv_unregister_rc(fdtv); fail_free: kfree(fdtv); + return err; } @@ -233,10 +235,9 @@ static int node_remove(struct device *dev) list_del(&fdtv->list); spin_unlock_irq(&node_list_lock); - cancel_work_sync(&fdtv->remote_ctrl_work); fdtv_unregister_rc(fdtv); - kfree(fdtv); + return 0; } diff --git a/drivers/media/dvb/firewire/firedtv-rc.c b/drivers/media/dvb/firewire/firedtv-rc.c index 27bca2e283d..599d66e5843 100644 --- a/drivers/media/dvb/firewire/firedtv-rc.c +++ b/drivers/media/dvb/firewire/firedtv-rc.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "firedtv.h" @@ -163,6 +164,7 @@ fail: void fdtv_unregister_rc(struct firedtv *fdtv) { + cancel_work_sync(&fdtv->remote_ctrl_work); kfree(fdtv->remote_ctrl_dev->keycode); input_unregister_device(fdtv->remote_ctrl_dev); } -- cgit v1.2.3-70-g09d2 From 054286b12c7ba7d37a945326d38716a00434002b Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 8 Nov 2009 18:29:08 -0300 Subject: V4L/DVB (13398): firedtv: reform lock transaction backend call Preparation for the port of firedtv to the firewire-core kernel API: The fdtv->backend->lock() hook and thus the CMP code is slightly changed to better fit with the new API. Signed-off-by: Stefan Richter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/firewire/firedtv-1394.c | 11 +++++-- drivers/media/dvb/firewire/firedtv-avc.c | 50 +++++++++++++++++-------------- drivers/media/dvb/firewire/firedtv.h | 2 +- 3 files changed, 37 insertions(+), 26 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c index a2e3841f8ee..22ea4c90f5c 100644 --- a/drivers/media/dvb/firewire/firedtv-1394.c +++ b/drivers/media/dvb/firewire/firedtv-1394.c @@ -87,10 +87,15 @@ static inline struct node_entry *node_of(struct firedtv *fdtv) return container_of(fdtv->device, struct unit_directory, device)->ne; } -static int node_lock(struct firedtv *fdtv, u64 addr, void *data, __be32 arg) +static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[]) { - return hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP, data, - (__force quadlet_t)arg); + int ret; + + ret = hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP, + (__force quadlet_t *)&data[1], (__force quadlet_t)data[0]); + data[0] = data[1]; + + return ret; } static int node_read(struct firedtv *fdtv, u64 addr, void *data, size_t len) diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c index 485d061319a..5516c33b145 100644 --- a/drivers/media/dvb/firewire/firedtv-avc.c +++ b/drivers/media/dvb/firewire/firedtv-avc.c @@ -1251,14 +1251,14 @@ static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len) return ret; } -static int cmp_lock(struct firedtv *fdtv, void *data, u64 addr, __be32 arg) +static int cmp_lock(struct firedtv *fdtv, u64 addr, __be32 data[]) { int ret; if (mutex_lock_interruptible(&fdtv->avc_mutex)) return -EINTR; - ret = fdtv->backend->lock(fdtv, addr, data, arg); + ret = fdtv->backend->lock(fdtv, addr, data); if (ret < 0) dev_err(fdtv->device, "CMP: lock I/O error\n"); @@ -1288,25 +1288,25 @@ static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift) int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel) { - __be32 old_opcr, opcr; + __be32 old_opcr, opcr[2]; u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); int attempts = 0; int ret; - ret = cmp_read(fdtv, &opcr, opcr_address, 4); + ret = cmp_read(fdtv, opcr, opcr_address, 4); if (ret < 0) return ret; repeat: - if (!get_opcr_online(opcr)) { + if (!get_opcr_online(*opcr)) { dev_err(fdtv->device, "CMP: output offline\n"); return -EBUSY; } - old_opcr = opcr; + old_opcr = *opcr; - if (get_opcr_p2p_connections(opcr)) { - if (get_opcr_channel(opcr) != channel) { + if (get_opcr_p2p_connections(*opcr)) { + if (get_opcr_channel(*opcr) != channel) { dev_err(fdtv->device, "CMP: cannot change channel\n"); return -EBUSY; } @@ -1314,11 +1314,11 @@ repeat: /* We don't allocate isochronous resources. */ } else { - set_opcr_channel(&opcr, channel); - set_opcr_data_rate(&opcr, 2); /* S400 */ + set_opcr_channel(opcr, channel); + set_opcr_data_rate(opcr, 2); /* S400 */ /* FIXME: this is for the worst case - optimize */ - set_opcr_overhead_id(&opcr, 0); + set_opcr_overhead_id(opcr, 0); /* * FIXME: allocate isochronous channel and bandwidth at IRM @@ -1326,13 +1326,16 @@ repeat: */ } - set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1); + set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) + 1); - ret = cmp_lock(fdtv, &opcr, opcr_address, old_opcr); + opcr[1] = *opcr; + opcr[0] = old_opcr; + + ret = cmp_lock(fdtv, opcr_address, opcr); if (ret < 0) return ret; - if (old_opcr != opcr) { + if (old_opcr != *opcr) { /* * FIXME: if old_opcr.P2P_Connections > 0, * deallocate isochronous channel and bandwidth at IRM @@ -1350,27 +1353,30 @@ repeat: void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel) { - __be32 old_opcr, opcr; + __be32 old_opcr, opcr[2]; u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); int attempts = 0; - if (cmp_read(fdtv, &opcr, opcr_address, 4) < 0) + if (cmp_read(fdtv, opcr, opcr_address, 4) < 0) return; repeat: - if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) || - get_opcr_channel(opcr) != channel) { + if (!get_opcr_online(*opcr) || !get_opcr_p2p_connections(*opcr) || + get_opcr_channel(*opcr) != channel) { dev_err(fdtv->device, "CMP: no connection to break\n"); return; } - old_opcr = opcr; - set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1); + old_opcr = *opcr; + set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) - 1); + + opcr[1] = *opcr; + opcr[0] = old_opcr; - if (cmp_lock(fdtv, &opcr, opcr_address, old_opcr) < 0) + if (cmp_lock(fdtv, opcr_address, opcr) < 0) return; - if (old_opcr != opcr) { + if (old_opcr != *opcr) { /* * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last * owner, deallocate isochronous channel and bandwidth at IRM diff --git a/drivers/media/dvb/firewire/firedtv.h b/drivers/media/dvb/firewire/firedtv.h index d48530b81e6..1b99660a839 100644 --- a/drivers/media/dvb/firewire/firedtv.h +++ b/drivers/media/dvb/firewire/firedtv.h @@ -72,7 +72,7 @@ struct input_dev; struct firedtv; struct firedtv_backend { - int (*lock)(struct firedtv *fdtv, u64 addr, void *data, __be32 arg); + int (*lock)(struct firedtv *fdtv, u64 addr, __be32 data[]); int (*read)(struct firedtv *fdtv, u64 addr, void *data, size_t len); int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len); int (*start_iso)(struct firedtv *fdtv); -- cgit v1.2.3-70-g09d2 From 6e25abb522e055beeaf887f50a49cb370acc62b6 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 8 Nov 2009 18:29:41 -0300 Subject: V4L/DVB (13399): firedtv: add missing include, rename a constant Add #include for dvb_dmx_swfilter_packets(). This was already indirectly included via firedtv.h, but don't rely on it. The 4 bytes which were referred to as FIREWIRE_HEADER_SIZE are actually the source packet header from IEC 61883-4 (MPEG2-TS data transmission over 1394), not e.g. the IEEE 1394 isochronous packet header. So choose a more precise name. Also, express the payload size as a preprocessor constant too. Signed-off-by: Stefan Richter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/firewire/firedtv-1394.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c index 22ea4c90f5c..82b576a4774 100644 --- a/drivers/media/dvb/firewire/firedtv-1394.c +++ b/drivers/media/dvb/firewire/firedtv-1394.c @@ -26,13 +26,16 @@ #include #include +#include + #include "firedtv.h" static LIST_HEAD(node_list); static DEFINE_SPINLOCK(node_list_lock); -#define FIREWIRE_HEADER_SIZE 4 -#define CIP_HEADER_SIZE 8 +#define CIP_HEADER_SIZE 8 +#define MPEG2_TS_HEADER_SIZE 4 +#define MPEG2_TS_SOURCE_PACKET_SIZE (4 + 188) static void rawiso_activity_cb(struct hpsb_iso *iso) { @@ -62,20 +65,20 @@ static void rawiso_activity_cb(struct hpsb_iso *iso) buf = dma_region_i(&iso->data_buf, unsigned char, iso->infos[packet].offset + CIP_HEADER_SIZE); count = (iso->infos[packet].len - CIP_HEADER_SIZE) / - (188 + FIREWIRE_HEADER_SIZE); + MPEG2_TS_SOURCE_PACKET_SIZE; /* ignore empty packet */ if (iso->infos[packet].len <= CIP_HEADER_SIZE) continue; while (count--) { - if (buf[FIREWIRE_HEADER_SIZE] == 0x47) + if (buf[MPEG2_TS_HEADER_SIZE] == 0x47) dvb_dmx_swfilter_packets(&fdtv->demux, - &buf[FIREWIRE_HEADER_SIZE], 1); + &buf[MPEG2_TS_HEADER_SIZE], 1); else dev_err(fdtv->device, "skipping invalid packet\n"); - buf += 188 + FIREWIRE_HEADER_SIZE; + buf += MPEG2_TS_SOURCE_PACKET_SIZE; } } out: -- cgit v1.2.3-70-g09d2 From 87918334792a4d8a73b0511466b77bd6aa055db3 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 8 Nov 2009 18:30:54 -0300 Subject: V4L/DVB (13400): firedtv: port to new firewire core The firedtv DVB driver will now work not only on top of the old ieee1394 driver stack but also on the new firewire driver stack. Alongside to the firedtv-1394.c backend for driver binding and I/O, the firedtv-fw.c backend is added. Depending on which of the two 1394 stacks is configured, one or the other or both backends will be built into the firedtv driver. This has been tested with a DVB-T and a DVB-C box on x86-64 and x86-32 together with a few different controllers (Agere FW323, a NEC chip, TI TSB82AA2, TSB43AB22/A, VIA VT6306). Signed-off-by: Stefan Richter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/firewire/Kconfig | 7 +- drivers/media/dvb/firewire/Makefile | 1 + drivers/media/dvb/firewire/firedtv-1394.c | 6 +- drivers/media/dvb/firewire/firedtv-dvb.c | 15 +- drivers/media/dvb/firewire/firedtv-fw.c | 385 ++++++++++++++++++++++++++++++ drivers/media/dvb/firewire/firedtv.h | 15 +- 6 files changed, 420 insertions(+), 9 deletions(-) create mode 100644 drivers/media/dvb/firewire/firedtv-fw.c (limited to 'drivers/media') diff --git a/drivers/media/dvb/firewire/Kconfig b/drivers/media/dvb/firewire/Kconfig index 69028253e98..4afa29256df 100644 --- a/drivers/media/dvb/firewire/Kconfig +++ b/drivers/media/dvb/firewire/Kconfig @@ -1,6 +1,6 @@ config DVB_FIREDTV tristate "FireDTV and FloppyDTV" - depends on DVB_CORE && IEEE1394 + depends on DVB_CORE && (FIREWIRE || IEEE1394) help Support for DVB receivers from Digital Everywhere which are connected via IEEE 1394 (FireWire). @@ -13,8 +13,11 @@ config DVB_FIREDTV if DVB_FIREDTV +config DVB_FIREDTV_FIREWIRE + def_bool FIREWIRE = y || (FIREWIRE = m && DVB_FIREDTV = m) + config DVB_FIREDTV_IEEE1394 - def_bool IEEE1394 + def_bool IEEE1394 = y || (IEEE1394 = m && DVB_FIREDTV = m) config DVB_FIREDTV_INPUT def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m) diff --git a/drivers/media/dvb/firewire/Makefile b/drivers/media/dvb/firewire/Makefile index 2034695ba19..da84203d51c 100644 --- a/drivers/media/dvb/firewire/Makefile +++ b/drivers/media/dvb/firewire/Makefile @@ -1,6 +1,7 @@ obj-$(CONFIG_DVB_FIREDTV) += firedtv.o firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o +firedtv-$(CONFIG_DVB_FIREDTV_FIREWIRE) += firedtv-fw.o firedtv-$(CONFIG_DVB_FIREDTV_IEEE1394) += firedtv-1394.o firedtv-$(CONFIG_DVB_FIREDTV_INPUT) += firedtv-rc.o diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c index 82b576a4774..ed98fdb650c 100644 --- a/drivers/media/dvb/firewire/firedtv-1394.c +++ b/drivers/media/dvb/firewire/firedtv-1394.c @@ -1,5 +1,5 @@ /* - * FireDTV driver (formerly known as FireSAT) + * FireDTV driver -- ieee1394 I/O backend * * Copyright (C) 2004 Andreas Monitzer * Copyright (C) 2007-2008 Ben Backx @@ -261,6 +261,7 @@ static int node_update(struct unit_directory *ud) static struct hpsb_protocol_driver fdtv_driver = { .name = "firedtv", + .id_table = fdtv_id_table, .update = node_update, .driver = { .probe = node_probe, @@ -273,12 +274,11 @@ static struct hpsb_highlevel fdtv_highlevel = { .fcp_request = fcp_request, }; -int __init fdtv_1394_init(struct ieee1394_device_id id_table[]) +int __init fdtv_1394_init(void) { int ret; hpsb_register_highlevel(&fdtv_highlevel); - fdtv_driver.id_table = id_table; ret = hpsb_register_protocol(&fdtv_driver); if (ret) { printk(KERN_ERR "firedtv: failed to register protocol\n"); diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c index 5742fde79d9..fc9996c13e1 100644 --- a/drivers/media/dvb/firewire/firedtv-dvb.c +++ b/drivers/media/dvb/firewire/firedtv-dvb.c @@ -297,7 +297,7 @@ struct firedtv *fdtv_alloc(struct device *dev, #define AVC_UNIT_SPEC_ID_ENTRY 0x00a02d #define AVC_SW_VERSION_ENTRY 0x010001 -static struct ieee1394_device_id fdtv_id_table[] = { +const struct ieee1394_device_id fdtv_id_table[] = { { /* FloppyDTV S/CI and FloppyDTV S2 */ .match_flags = MATCH_FLAGS, @@ -346,12 +346,23 @@ MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table); static int __init fdtv_init(void) { - return fdtv_1394_init(fdtv_id_table); + int ret; + + ret = fdtv_fw_init(); + if (ret < 0) + return ret; + + ret = fdtv_1394_init(); + if (ret < 0) + fdtv_fw_exit(); + + return ret; } static void __exit fdtv_exit(void) { fdtv_1394_exit(); + fdtv_fw_exit(); } module_init(fdtv_init); diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/dvb/firewire/firedtv-fw.c new file mode 100644 index 00000000000..208e5b59e83 --- /dev/null +++ b/drivers/media/dvb/firewire/firedtv-fw.c @@ -0,0 +1,385 @@ +/* + * FireDTV driver -- firewire I/O backend + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "firedtv.h" + +static LIST_HEAD(node_list); +static DEFINE_SPINLOCK(node_list_lock); + +static inline struct fw_device *device_of(struct firedtv *fdtv) +{ + return fw_device(fdtv->device->parent); +} + +static int node_req(struct firedtv *fdtv, u64 addr, void *data, size_t len, + int tcode) +{ + struct fw_device *device = device_of(fdtv); + int rcode, generation = device->generation; + + smp_rmb(); /* node_id vs. generation */ + + rcode = fw_run_transaction(device->card, tcode, device->node_id, + generation, device->max_speed, addr, data, len); + + return rcode != RCODE_COMPLETE ? -EIO : 0; +} + +static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[]) +{ + return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP); +} + +static int node_read(struct firedtv *fdtv, u64 addr, void *data, size_t len) +{ + return node_req(fdtv, addr, data, len, len == 4 ? + TCODE_READ_QUADLET_REQUEST : TCODE_READ_BLOCK_REQUEST); +} + +static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len) +{ + return node_req(fdtv, addr, data, len, TCODE_WRITE_BLOCK_REQUEST); +} + +#define ISO_HEADER_SIZE 4 +#define CIP_HEADER_SIZE 8 +#define MPEG2_TS_HEADER_SIZE 4 +#define MPEG2_TS_SOURCE_PACKET_SIZE (4 + 188) + +#define MAX_PACKET_SIZE 1024 /* 776, rounded up to 2^n */ +#define PACKETS_PER_PAGE (PAGE_SIZE / MAX_PACKET_SIZE) +#define N_PACKETS 64 /* buffer size */ +#define N_PAGES DIV_ROUND_UP(N_PACKETS, PACKETS_PER_PAGE) +#define IRQ_INTERVAL 16 + +struct firedtv_receive_context { + struct fw_iso_context *context; + struct fw_iso_buffer buffer; + int interrupt_packet; + int current_packet; + char *packets[N_PACKETS]; +}; + +static int queue_iso(struct firedtv_receive_context *ctx, int index) +{ + struct fw_iso_packet p; + int err; + + p.payload_length = MAX_PACKET_SIZE; + p.interrupt = !(ctx->interrupt_packet & (IRQ_INTERVAL - 1)); + p.skip = 0; + p.header_length = ISO_HEADER_SIZE; + + err = fw_iso_context_queue(ctx->context, &p, &ctx->buffer, + index * MAX_PACKET_SIZE); + if (!err) + ctx->interrupt_packet++; + + return err; +} + +static void handle_iso(struct fw_iso_context *context, u32 cycle, + size_t header_length, void *header, void *data) +{ + struct firedtv *fdtv = data; + struct firedtv_receive_context *ctx = fdtv->backend_data; + __be32 *h, *h_end; + int i = ctx->current_packet, length, err; + char *p, *p_end; + + for (h = header, h_end = h + header_length / 4; h < h_end; h++) { + length = be32_to_cpup(h) >> 16; + if (unlikely(length > MAX_PACKET_SIZE)) { + dev_err(fdtv->device, "length = %d\n", length); + length = MAX_PACKET_SIZE; + } + + p = ctx->packets[i]; + p_end = p + length; + + for (p += CIP_HEADER_SIZE + MPEG2_TS_HEADER_SIZE; p < p_end; + p += MPEG2_TS_SOURCE_PACKET_SIZE) + dvb_dmx_swfilter_packets(&fdtv->demux, p, 1); + + err = queue_iso(ctx, i); + if (unlikely(err)) + dev_err(fdtv->device, "requeue failed\n"); + + i = (i + 1) & (N_PACKETS - 1); + } + ctx->current_packet = i; +} + +static int start_iso(struct firedtv *fdtv) +{ + struct firedtv_receive_context *ctx; + struct fw_device *device = device_of(fdtv); + char *p; + int i, j, k, err; + + ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + ctx->context = fw_iso_context_create(device->card, + FW_ISO_CONTEXT_RECEIVE, fdtv->isochannel, + device->max_speed, ISO_HEADER_SIZE, handle_iso, fdtv); + if (IS_ERR(ctx->context)) { + err = PTR_ERR(ctx->context); + goto fail_free; + } + + err = fw_iso_buffer_init(&ctx->buffer, device->card, + N_PAGES, DMA_FROM_DEVICE); + if (err) + goto fail_context_destroy; + + ctx->interrupt_packet = 1; + ctx->current_packet = 0; + + for (i = 0, k = 0; k < N_PAGES; k++) { + p = kmap(ctx->buffer.pages[k]); + for (j = 0; j < PACKETS_PER_PAGE && i < N_PACKETS; j++, i++) + ctx->packets[i] = p + j * MAX_PACKET_SIZE; + } + + for (i = 0; i < N_PACKETS; i++) { + err = queue_iso(ctx, i); + if (err) + goto fail; + } + + err = fw_iso_context_start(ctx->context, -1, 0, + FW_ISO_CONTEXT_MATCH_ALL_TAGS); + if (err) + goto fail; + + fdtv->backend_data = ctx; + + return 0; +fail: + fw_iso_buffer_destroy(&ctx->buffer, device->card); +fail_context_destroy: + fw_iso_context_destroy(ctx->context); +fail_free: + kfree(ctx); + + return err; +} + +static void stop_iso(struct firedtv *fdtv) +{ + struct firedtv_receive_context *ctx = fdtv->backend_data; + + fw_iso_context_stop(ctx->context); + fw_iso_buffer_destroy(&ctx->buffer, device_of(fdtv)->card); + fw_iso_context_destroy(ctx->context); + kfree(ctx); +} + +static const struct firedtv_backend backend = { + .lock = node_lock, + .read = node_read, + .write = node_write, + .start_iso = start_iso, + .stop_iso = stop_iso, +}; + +static void handle_fcp(struct fw_card *card, struct fw_request *request, + int tcode, int destination, int source, int generation, + int speed, unsigned long long offset, + void *payload, size_t length, void *callback_data) +{ + struct firedtv *f, *fdtv = NULL; + struct fw_device *device; + unsigned long flags; + int su; + + if ((tcode != TCODE_WRITE_QUADLET_REQUEST && + tcode != TCODE_WRITE_BLOCK_REQUEST) || + offset != CSR_REGISTER_BASE + CSR_FCP_RESPONSE || + length == 0 || + (((u8 *)payload)[0] & 0xf0) != 0) { + fw_send_response(card, request, RCODE_TYPE_ERROR); + return; + } + + su = ((u8 *)payload)[1] & 0x7; + + spin_lock_irqsave(&node_list_lock, flags); + list_for_each_entry(f, &node_list, list) { + device = device_of(f); + if (device->generation != generation) + continue; + + smp_rmb(); /* node_id vs. generation */ + + if (device->card == card && + device->node_id == source && + (f->subunit == su || (f->subunit == 0 && su == 0x7))) { + fdtv = f; + break; + } + } + spin_unlock_irqrestore(&node_list_lock, flags); + + if (fdtv) { + avc_recv(fdtv, payload, length); + fw_send_response(card, request, RCODE_COMPLETE); + } +} + +static struct fw_address_handler fcp_handler = { + .length = CSR_FCP_END - CSR_FCP_RESPONSE, + .address_callback = handle_fcp, +}; + +static const struct fw_address_region fcp_region = { + .start = CSR_REGISTER_BASE + CSR_FCP_RESPONSE, + .end = CSR_REGISTER_BASE + CSR_FCP_END, +}; + +/* Adjust the template string if models with longer names appear. */ +#define MAX_MODEL_NAME_LEN ((int)DIV_ROUND_UP(sizeof("FireDTV ????"), 4)) + +static size_t model_name(u32 *directory, __be32 *buffer) +{ + struct fw_csr_iterator ci; + int i, length, key, value, last_key = 0; + u32 *block = NULL; + + fw_csr_iterator_init(&ci, directory); + while (fw_csr_iterator_next(&ci, &key, &value)) { + if (last_key == CSR_MODEL && + key == (CSR_DESCRIPTOR | CSR_LEAF)) + block = ci.p - 1 + value; + last_key = key; + } + + if (block == NULL) + return 0; + + length = min((int)(block[0] >> 16) - 2, MAX_MODEL_NAME_LEN); + if (length <= 0) + return 0; + + /* fast-forward to text string */ + block += 3; + + for (i = 0; i < length; i++) + buffer[i] = cpu_to_be32(block[i]); + + return length * 4; +} + +static int node_probe(struct device *dev) +{ + struct firedtv *fdtv; + __be32 name[MAX_MODEL_NAME_LEN]; + int name_len, err; + + name_len = model_name(fw_unit(dev)->directory, name); + + fdtv = fdtv_alloc(dev, &backend, (char *)name, name_len); + if (!fdtv) + return -ENOMEM; + + err = fdtv_register_rc(fdtv, dev); + if (err) + goto fail_free; + + spin_lock_irq(&node_list_lock); + list_add_tail(&fdtv->list, &node_list); + spin_unlock_irq(&node_list_lock); + + err = avc_identify_subunit(fdtv); + if (err) + goto fail; + + err = fdtv_dvb_register(fdtv); + if (err) + goto fail; + + avc_register_remote_control(fdtv); + + return 0; +fail: + spin_lock_irq(&node_list_lock); + list_del(&fdtv->list); + spin_unlock_irq(&node_list_lock); + fdtv_unregister_rc(fdtv); +fail_free: + kfree(fdtv); + + return err; +} + +static int node_remove(struct device *dev) +{ + struct firedtv *fdtv = dev_get_drvdata(dev); + + fdtv_dvb_unregister(fdtv); + + spin_lock_irq(&node_list_lock); + list_del(&fdtv->list); + spin_unlock_irq(&node_list_lock); + + fdtv_unregister_rc(fdtv); + + kfree(fdtv); + return 0; +} + +static void node_update(struct fw_unit *unit) +{ + struct firedtv *fdtv = dev_get_drvdata(&unit->device); + + if (fdtv->isochannel >= 0) + cmp_establish_pp_connection(fdtv, fdtv->subunit, + fdtv->isochannel); +} + +static struct fw_driver fdtv_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "firedtv", + .bus = &fw_bus_type, + .probe = node_probe, + .remove = node_remove, + }, + .update = node_update, + .id_table = fdtv_id_table, +}; + +int __init fdtv_fw_init(void) +{ + int ret; + + ret = fw_core_add_address_handler(&fcp_handler, &fcp_region); + if (ret < 0) + return ret; + + return driver_register(&fdtv_driver.driver); +} + +void fdtv_fw_exit(void) +{ + driver_unregister(&fdtv_driver.driver); + fw_core_remove_address_handler(&fcp_handler); +} diff --git a/drivers/media/dvb/firewire/firedtv.h b/drivers/media/dvb/firewire/firedtv.h index 1b99660a839..f7b5c030bed 100644 --- a/drivers/media/dvb/firewire/firedtv.h +++ b/drivers/media/dvb/firewire/firedtv.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -119,10 +120,10 @@ struct firedtv { /* firedtv-1394.c */ #ifdef CONFIG_DVB_FIREDTV_IEEE1394 -int fdtv_1394_init(struct ieee1394_device_id id_table[]); +int fdtv_1394_init(void); void fdtv_1394_exit(void); #else -static inline int fdtv_1394_init(struct ieee1394_device_id it[]) { return 0; } +static inline int fdtv_1394_init(void) { return 0; } static inline void fdtv_1394_exit(void) {} #endif @@ -163,10 +164,20 @@ struct firedtv *fdtv_alloc(struct device *dev, const struct firedtv_backend *backend, const char *name, size_t name_len); extern const char *fdtv_model_names[]; +extern const struct ieee1394_device_id fdtv_id_table[]; /* firedtv-fe.c */ void fdtv_frontend_init(struct firedtv *fdtv); +/* firedtv-fw.c */ +#ifdef CONFIG_DVB_FIREDTV_FIREWIRE +int fdtv_fw_init(void); +void fdtv_fw_exit(void); +#else +static inline int fdtv_fw_init(void) { return 0; } +static inline void fdtv_fw_exit(void) {} +#endif + /* firedtv-rc.c */ #ifdef CONFIG_DVB_FIREDTV_INPUT int fdtv_register_rc(struct firedtv *fdtv, struct device *dev); -- cgit v1.2.3-70-g09d2 From d89ce0d9ec9f980d59eae8d5a0ead98988e3b545 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 9 Nov 2009 19:09:49 -0300 Subject: V4L/DVB (13402): radio-mr800 - autosuspend for radio-mr800 driver Patch adds autosuspend support for mr800 radio driver. Signed-off-by: Oliver Neukum Acked-by: Alexey Klimov Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-mr800.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 4064109c420..44efa68d9f8 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -132,6 +132,7 @@ static int usb_amradio_resume(struct usb_interface *intf); struct amradio_device { /* reference to USB and video device */ struct usb_device *usbdev; + struct usb_interface *intf; struct video_device videodev; struct v4l2_device v4l2_dev; @@ -163,7 +164,7 @@ static struct usb_driver usb_amradio_driver = { .resume = usb_amradio_resume, .reset_resume = usb_amradio_resume, .id_table = usb_amradio_device_table, - .supports_autosuspend = 0, + .supports_autosuspend = 1, }; /* switch on/off the radio. Send 8 bytes to device */ @@ -506,9 +507,15 @@ static int usb_amradio_open(struct file *file) } file->private_data = radio; + retval = usb_autopm_get_interface(radio->intf); + if (retval) + goto unlock; - if (unlikely(!radio->initialized)) + if (unlikely(!radio->initialized)) { retval = usb_amradio_init(radio); + if (retval) + usb_autopm_put_interface(radio->intf); + } unlock: mutex_unlock(&radio->lock); @@ -525,6 +532,8 @@ static int usb_amradio_close(struct file *file) if (!radio->usbdev) retval = -EIO; + else + usb_autopm_put_interface(radio->intf); mutex_unlock(&radio->lock); return retval; @@ -666,6 +675,7 @@ static int usb_amradio_probe(struct usb_interface *intf, radio->videodev.release = usb_amradio_video_device_release; radio->usbdev = interface_to_usbdev(intf); + radio->intf = intf; radio->curfreq = 95.16 * FREQ_MUL; mutex_init(&radio->lock); -- cgit v1.2.3-70-g09d2 From fa26ae3e8260530121e6e0e57427468a9f0038d7 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Thu, 12 Nov 2009 10:16:09 -0300 Subject: V4L/DVB: pt1: remove duplicated #include Remove duplicated #include('s) in drivers/media/dvb/pt1/pt1.c Signed-off-by: Huang Weiyi Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/pt1/pt1.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c index 1fd8306371e..81e623a90f0 100644 --- a/drivers/media/dvb/pt1/pt1.c +++ b/drivers/media/dvb/pt1/pt1.c @@ -27,7 +27,6 @@ #include #include #include -#include #include "dvbdev.h" #include "dvb_demux.h" -- cgit v1.2.3-70-g09d2 From b699c2712b1ddcc3ef4491adde00a47a880fde97 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Mon, 16 Nov 2009 22:22:32 -0300 Subject: V4L/DVB (13407): Add Prof 7301 PCI DVB-S2 card Add Prof 7301 PCI DVB-S2 card The card based on stv0903 demod, stb6100 tuner. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.cx88 | 1 + drivers/media/dvb/frontends/stb6100_proc.h | 138 +++++++++++++++++++++++++++++ drivers/media/dvb/frontends/stv0900.h | 2 + drivers/media/dvb/frontends/stv0900_core.c | 3 + drivers/media/video/cx88/Kconfig | 2 + drivers/media/video/cx88/cx88-cards.c | 17 ++++ drivers/media/video/cx88/cx88-dvb.c | 54 +++++++++++ drivers/media/video/cx88/cx88-input.c | 2 + drivers/media/video/cx88/cx88.h | 1 + 9 files changed, 220 insertions(+) create mode 100644 drivers/media/dvb/frontends/stb6100_proc.h (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88 index 3385f8b094a..7ec3c4e4b60 100644 --- a/Documentation/video4linux/CARDLIST.cx88 +++ b/Documentation/video4linux/CARDLIST.cx88 @@ -81,3 +81,4 @@ 80 -> Hauppauge WinTV-IR Only [0070:9290] 81 -> Leadtek WinFast DTV1800 Hybrid [107d:6654] 82 -> WinFast DTV2000 H rev. J [107d:6f2b] + 83 -> Prof 7301 DVB-S/S2 [b034:3034] diff --git a/drivers/media/dvb/frontends/stb6100_proc.h b/drivers/media/dvb/frontends/stb6100_proc.h new file mode 100644 index 00000000000..112163a4862 --- /dev/null +++ b/drivers/media/dvb/frontends/stb6100_proc.h @@ -0,0 +1,138 @@ +/* + STB6100 Silicon Tuner wrapper + Copyright (C)2009 Igor M. Liplianin (liplianin@me.by) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +static int stb6100_get_freq(struct dvb_frontend *fe, u32 *frequency) +{ + struct dvb_frontend_ops *frontend_ops = NULL; + struct dvb_tuner_ops *tuner_ops = NULL; + struct tuner_state state; + int err = 0; + + if (&fe->ops) + frontend_ops = &fe->ops; + if (&frontend_ops->tuner_ops) + tuner_ops = &frontend_ops->tuner_ops; + if (tuner_ops->get_state) { + if (frontend_ops->i2c_gate_ctrl) + frontend_ops->i2c_gate_ctrl(fe, 1); + + err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &state); + if (err < 0) { + printk(KERN_ERR "%s: Invalid parameter\n", __func__); + return err; + } + + if (frontend_ops->i2c_gate_ctrl) + frontend_ops->i2c_gate_ctrl(fe, 0); + + *frequency = state.frequency; + } + + return 0; +} + +static int stb6100_set_freq(struct dvb_frontend *fe, u32 frequency) +{ + struct dvb_frontend_ops *frontend_ops = NULL; + struct dvb_tuner_ops *tuner_ops = NULL; + struct tuner_state state; + int err = 0; + + state.frequency = frequency; + if (&fe->ops) + frontend_ops = &fe->ops; + if (&frontend_ops->tuner_ops) + tuner_ops = &frontend_ops->tuner_ops; + if (tuner_ops->set_state) { + if (frontend_ops->i2c_gate_ctrl) + frontend_ops->i2c_gate_ctrl(fe, 1); + + err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &state); + if (err < 0) { + printk(KERN_ERR "%s: Invalid parameter\n", __func__); + return err; + } + + if (frontend_ops->i2c_gate_ctrl) + frontend_ops->i2c_gate_ctrl(fe, 0); + + } + + return 0; +} + +static int stb6100_get_bandw(struct dvb_frontend *fe, u32 *bandwidth) +{ + struct dvb_frontend_ops *frontend_ops = NULL; + struct dvb_tuner_ops *tuner_ops = NULL; + struct tuner_state state; + int err = 0; + + if (&fe->ops) + frontend_ops = &fe->ops; + if (&frontend_ops->tuner_ops) + tuner_ops = &frontend_ops->tuner_ops; + if (tuner_ops->get_state) { + if (frontend_ops->i2c_gate_ctrl) + frontend_ops->i2c_gate_ctrl(fe, 1); + + err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &state); + if (err < 0) { + printk(KERN_ERR "%s: Invalid parameter\n", __func__); + return err; + } + + if (frontend_ops->i2c_gate_ctrl) + frontend_ops->i2c_gate_ctrl(fe, 0); + + *bandwidth = state.bandwidth; + } + + return 0; +} + +static int stb6100_set_bandw(struct dvb_frontend *fe, u32 bandwidth) +{ + struct dvb_frontend_ops *frontend_ops = NULL; + struct dvb_tuner_ops *tuner_ops = NULL; + struct tuner_state state; + int err = 0; + + state.bandwidth = bandwidth; + if (&fe->ops) + frontend_ops = &fe->ops; + if (&frontend_ops->tuner_ops) + tuner_ops = &frontend_ops->tuner_ops; + if (tuner_ops->set_state) { + if (frontend_ops->i2c_gate_ctrl) + frontend_ops->i2c_gate_ctrl(fe, 1); + + err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &state); + if (err < 0) { + printk(KERN_ERR "%s: Invalid parameter\n", __func__); + return err; + } + + if (frontend_ops->i2c_gate_ctrl) + frontend_ops->i2c_gate_ctrl(fe, 0); + + } + + return 0; +} diff --git a/drivers/media/dvb/frontends/stv0900.h b/drivers/media/dvb/frontends/stv0900.h index 446bdfc8ad1..29c3fa85c22 100644 --- a/drivers/media/dvb/frontends/stv0900.h +++ b/drivers/media/dvb/frontends/stv0900.h @@ -49,6 +49,8 @@ struct stv0900_config { u8 tun2_maddress; u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */ u8 tun2_adc; + /* Set device param to start dma */ + int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); }; #if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \ diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c index e2062048f43..df49ea0983b 100644 --- a/drivers/media/dvb/frontends/stv0900_core.c +++ b/drivers/media/dvb/frontends/stv0900_core.c @@ -1494,6 +1494,9 @@ static enum dvbfe_search stv0900_search(struct dvb_frontend *fe, if (!(INRANGE(100000, c->symbol_rate, 70000000))) return DVBFE_ALGO_SEARCH_FAILED; + if (state->config->set_ts_params) + state->config->set_ts_params(fe, 0); + p_result.locked = FALSE; p_search.path = demod; p_search.frequency = c->frequency; diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index 49952980dab..c7e5851d348 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig @@ -61,6 +61,8 @@ config VIDEO_CX88_DVB select DVB_STV0299 if !DVB_FE_CUSTOMISE select DVB_STV0288 if !DVB_FE_CUSTOMISE select DVB_STB6000 if !DVB_FE_CUSTOMISE + select DVB_STV0900 if !DVB_FE_CUSTOMISE + select DVB_STB6100 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE ---help--- This adds support for DVB/ATSC cards based on the diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 7330a2d7043..d844f2aaa01 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c @@ -2075,6 +2075,18 @@ static const struct cx88_board cx88_boards[] = { }, .mpeg = CX88_MPEG_DVB, }, + [CX88_BOARD_PROF_7301] = { + .name = "Prof 7301 DVB-S/S2", + .tuner_type = UNSET, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .input = { { + .type = CX88_VMUX_DVB, + .vmux = 0, + } }, + .mpeg = CX88_MPEG_DVB, + }, }; /* ------------------------------------------------------------------ */ @@ -2535,6 +2547,10 @@ static const struct cx88_subid cx88_subids[] = { .subvendor = 0x107d, .subdevice = 0x6618, .card = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL, + }, { + .subvendor = 0xb034, + .subdevice = 0x3034, + .card = CX88_BOARD_PROF_7301, }, }; @@ -3211,6 +3227,7 @@ static void cx88_card_setup(struct cx88_core *core) case CX88_BOARD_TBS_8920: case CX88_BOARD_PROF_6200: case CX88_BOARD_PROF_7300: + case CX88_BOARD_PROF_7301: case CX88_BOARD_SATTRADE_ST4200: cx_write(MO_GP0_IO, 0x8000); msleep(100); diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index 9df71d0244a..b1429692325 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c @@ -53,6 +53,9 @@ #include "stv0288.h" #include "stb6000.h" #include "cx24116.h" +#include "stv0900.h" +#include "stb6100.h" +#include "stb6100_proc.h" MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); MODULE_AUTHOR("Chris Pascoe "); @@ -573,6 +576,15 @@ static int cx24116_set_ts_param(struct dvb_frontend *fe, return 0; } +static int stv0900_set_ts_param(struct dvb_frontend *fe, + int is_punctured) +{ + struct cx8802_dev *dev = fe->dvb->priv; + dev->ts_gen_cntrl = 0; + + return 0; +} + static int cx24116_reset_device(struct dvb_frontend *fe) { struct cx8802_dev *dev = fe->dvb->priv; @@ -601,6 +613,23 @@ static struct cx24116_config tevii_s460_config = { .reset_device = cx24116_reset_device, }; +static struct stv0900_config prof_7301_stv0900_config = { + .demod_address = 0x6a, +/* demod_mode = 0,*/ + .xtal = 27000000, + .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */ + .diseqc_mode = 2,/* 2/3 PWM */ + .tun1_maddress = 0,/* 0x60 */ + .tun1_adc = 0,/* 2 Vpp */ + .path1_mode = 3, + .set_ts_params = stv0900_set_ts_param, +}; + +static struct stb6100_config prof_7301_stb6100_config = { + .tuner_address = 0x60, + .refclock = 27000000, +}; + static struct stv0299_config tevii_tuner_sharp_config = { .demod_address = 0x68, .inittab = sharp_z0194a_inittab, @@ -1149,6 +1178,31 @@ static int dvb_register(struct cx8802_dev *dev) goto frontend_detach; } break; + case CX88_BOARD_PROF_7301:{ + struct dvb_tuner_ops *tuner_ops = NULL; + + fe0->dvb.frontend = dvb_attach(stv0900_attach, + &prof_7301_stv0900_config, + &core->i2c_adap, 0); + if (fe0->dvb.frontend != NULL) { + if (!dvb_attach(stb6100_attach, fe0->dvb.frontend, + &prof_7301_stb6100_config, + &core->i2c_adap)) + goto frontend_detach; + + tuner_ops = &fe0->dvb.frontend->ops.tuner_ops; + tuner_ops->set_frequency = stb6100_set_freq; + tuner_ops->get_frequency = stb6100_get_freq; + tuner_ops->set_bandwidth = stb6100_set_bandw; + tuner_ops->get_bandwidth = stb6100_get_bandw; + + core->prev_set_voltage = + fe0->dvb.frontend->ops.set_voltage; + fe0->dvb.frontend->ops.set_voltage = + tevii_dvbs_set_voltage; + } + break; + } default: printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", core->name); diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index c0047c1960c..47c03019357 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c @@ -308,6 +308,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) case CX88_BOARD_TBS_8920: case CX88_BOARD_TBS_8910: case CX88_BOARD_PROF_7300: + case CX88_BOARD_PROF_7301: case CX88_BOARD_PROF_6200: ir_codes = &ir_codes_tbs_nec_table; ir_type = IR_TYPE_PD; @@ -457,6 +458,7 @@ void cx88_ir_irq(struct cx88_core *core) case CX88_BOARD_TBS_8920: case CX88_BOARD_TBS_8910: case CX88_BOARD_PROF_7300: + case CX88_BOARD_PROF_7301: case CX88_BOARD_PROF_6200: ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4); diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index d5cea41f420..e1c52171010 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -238,6 +238,7 @@ extern struct sram_channel cx88_sram_channels[]; #define CX88_BOARD_HAUPPAUGE_IRONLY 80 #define CX88_BOARD_WINFAST_DTV1800H 81 #define CX88_BOARD_WINFAST_DTV2000H_J 82 +#define CX88_BOARD_PROF_7301 83 enum cx88_itype { CX88_VMUX_COMPOSITE1 = 1, -- cgit v1.2.3-70-g09d2 From a8aeb7836edac3e0cce1286eefbca793c54cbad0 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Wed, 18 Nov 2009 16:00:55 -0300 Subject: V4L/DVB (13408): firedtv: shrink buffer pointer table Cache only addresses of whole pages, not of each buffer chunk. Besides, page addresses can be obtained by page_address() instead of kmap() since they were allocated in lowmem. Signed-off-by: Stefan Richter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/firewire/firedtv-fw.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/dvb/firewire/firedtv-fw.c index 208e5b59e83..6954848b580 100644 --- a/drivers/media/dvb/firewire/firedtv-fw.c +++ b/drivers/media/dvb/firewire/firedtv-fw.c @@ -6,9 +6,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -73,7 +73,7 @@ struct firedtv_receive_context { struct fw_iso_buffer buffer; int interrupt_packet; int current_packet; - char *packets[N_PACKETS]; + char *pages[N_PAGES]; }; static int queue_iso(struct firedtv_receive_context *ctx, int index) @@ -100,7 +100,7 @@ static void handle_iso(struct fw_iso_context *context, u32 cycle, struct firedtv *fdtv = data; struct firedtv_receive_context *ctx = fdtv->backend_data; __be32 *h, *h_end; - int i = ctx->current_packet, length, err; + int length, err, i = ctx->current_packet; char *p, *p_end; for (h = header, h_end = h + header_length / 4; h < h_end; h++) { @@ -110,7 +110,8 @@ static void handle_iso(struct fw_iso_context *context, u32 cycle, length = MAX_PACKET_SIZE; } - p = ctx->packets[i]; + p = ctx->pages[i / PACKETS_PER_PAGE] + + (i % PACKETS_PER_PAGE) * MAX_PACKET_SIZE; p_end = p + length; for (p += CIP_HEADER_SIZE + MPEG2_TS_HEADER_SIZE; p < p_end; @@ -130,8 +131,7 @@ static int start_iso(struct firedtv *fdtv) { struct firedtv_receive_context *ctx; struct fw_device *device = device_of(fdtv); - char *p; - int i, j, k, err; + int i, err; ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) @@ -153,11 +153,8 @@ static int start_iso(struct firedtv *fdtv) ctx->interrupt_packet = 1; ctx->current_packet = 0; - for (i = 0, k = 0; k < N_PAGES; k++) { - p = kmap(ctx->buffer.pages[k]); - for (j = 0; j < PACKETS_PER_PAGE && i < N_PACKETS; j++, i++) - ctx->packets[i] = p + j * MAX_PACKET_SIZE; - } + for (i = 0; i < N_PAGES; i++) + ctx->pages[i] = page_address(ctx->buffer.pages[i]); for (i = 0; i < N_PACKETS; i++) { err = queue_iso(ctx, i); -- cgit v1.2.3-70-g09d2 From b1d33f4b0ae319ca79b6bafd6e815cbe0dcd7c14 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Wed, 18 Nov 2009 16:01:14 -0300 Subject: V4L/DVB (13409): firedtv: packet requeuing is likely to succeed Packet DMA buffers are queued either initially all at once (then, a queueing failure will cause firedtv to release the DMA context as a whole) or subsequently one by one as they recycled after use (then a failure is extremely unlikely). Therefore we can be a little less cautious when counting at which packet buffer to set the interrupt flag. Signed-off-by: Stefan Richter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/firewire/firedtv-fw.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/dvb/firewire/firedtv-fw.c index 6954848b580..d8408cea335 100644 --- a/drivers/media/dvb/firewire/firedtv-fw.c +++ b/drivers/media/dvb/firewire/firedtv-fw.c @@ -79,19 +79,14 @@ struct firedtv_receive_context { static int queue_iso(struct firedtv_receive_context *ctx, int index) { struct fw_iso_packet p; - int err; p.payload_length = MAX_PACKET_SIZE; - p.interrupt = !(ctx->interrupt_packet & (IRQ_INTERVAL - 1)); + p.interrupt = !(++ctx->interrupt_packet & (IRQ_INTERVAL - 1)); p.skip = 0; p.header_length = ISO_HEADER_SIZE; - err = fw_iso_context_queue(ctx->context, &p, &ctx->buffer, - index * MAX_PACKET_SIZE); - if (!err) - ctx->interrupt_packet++; - - return err; + return fw_iso_context_queue(ctx->context, &p, &ctx->buffer, + index * MAX_PACKET_SIZE); } static void handle_iso(struct fw_iso_context *context, u32 cycle, @@ -150,7 +145,7 @@ static int start_iso(struct firedtv *fdtv) if (err) goto fail_context_destroy; - ctx->interrupt_packet = 1; + ctx->interrupt_packet = 0; ctx->current_packet = 0; for (i = 0; i < N_PAGES; i++) -- cgit v1.2.3-70-g09d2 From 5375659a3df319700d97d911e44926fb43354839 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Wed, 18 Nov 2009 16:01:34 -0300 Subject: V4L/DVB (13410): firedtv: remove an unnecessary function argument All read transactions initiated by firedtv are only quadlet-sized, hence the backend->read call can be simplified a little. Signed-off-by: Stefan Richter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/firewire/firedtv-1394.c | 4 ++-- drivers/media/dvb/firewire/firedtv-avc.c | 8 ++++---- drivers/media/dvb/firewire/firedtv-fw.c | 5 ++--- drivers/media/dvb/firewire/firedtv.h | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c index ed98fdb650c..7c5459c27b7 100644 --- a/drivers/media/dvb/firewire/firedtv-1394.c +++ b/drivers/media/dvb/firewire/firedtv-1394.c @@ -101,9 +101,9 @@ static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[]) return ret; } -static int node_read(struct firedtv *fdtv, u64 addr, void *data, size_t len) +static int node_read(struct firedtv *fdtv, u64 addr, void *data) { - return hpsb_node_read(node_of(fdtv), addr, data, len); + return hpsb_node_read(node_of(fdtv), addr, data, 4); } static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len) diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c index 5516c33b145..50c42a4b972 100644 --- a/drivers/media/dvb/firewire/firedtv-avc.c +++ b/drivers/media/dvb/firewire/firedtv-avc.c @@ -1236,14 +1236,14 @@ int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len) #define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL -static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len) +static int cmp_read(struct firedtv *fdtv, u64 addr, __be32 *data) { int ret; if (mutex_lock_interruptible(&fdtv->avc_mutex)) return -EINTR; - ret = fdtv->backend->read(fdtv, addr, buf, len); + ret = fdtv->backend->read(fdtv, addr, data); if (ret < 0) dev_err(fdtv->device, "CMP: read I/O error\n"); @@ -1293,7 +1293,7 @@ int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel) int attempts = 0; int ret; - ret = cmp_read(fdtv, opcr, opcr_address, 4); + ret = cmp_read(fdtv, opcr_address, opcr); if (ret < 0) return ret; @@ -1357,7 +1357,7 @@ void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel) u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); int attempts = 0; - if (cmp_read(fdtv, opcr, opcr_address, 4) < 0) + if (cmp_read(fdtv, opcr_address, opcr) < 0) return; repeat: diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/dvb/firewire/firedtv-fw.c index d8408cea335..fe44789ab03 100644 --- a/drivers/media/dvb/firewire/firedtv-fw.c +++ b/drivers/media/dvb/firewire/firedtv-fw.c @@ -46,10 +46,9 @@ static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[]) return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP); } -static int node_read(struct firedtv *fdtv, u64 addr, void *data, size_t len) +static int node_read(struct firedtv *fdtv, u64 addr, void *data) { - return node_req(fdtv, addr, data, len, len == 4 ? - TCODE_READ_QUADLET_REQUEST : TCODE_READ_BLOCK_REQUEST); + return node_req(fdtv, addr, data, 4, TCODE_READ_QUADLET_REQUEST); } static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len) diff --git a/drivers/media/dvb/firewire/firedtv.h b/drivers/media/dvb/firewire/firedtv.h index f7b5c030bed..35080dbb3c6 100644 --- a/drivers/media/dvb/firewire/firedtv.h +++ b/drivers/media/dvb/firewire/firedtv.h @@ -74,7 +74,7 @@ struct firedtv; struct firedtv_backend { int (*lock)(struct firedtv *fdtv, u64 addr, __be32 data[]); - int (*read)(struct firedtv *fdtv, u64 addr, void *data, size_t len); + int (*read)(struct firedtv *fdtv, u64 addr, void *data); int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len); int (*start_iso)(struct firedtv *fdtv); void (*stop_iso)(struct firedtv *fdtv); -- cgit v1.2.3-70-g09d2 From c95a419a5604ec8a23cd73f61e9bb151e8cbe89b Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Fri, 20 Nov 2009 15:34:13 -0300 Subject: V4L/DVB: Fix test in copy_reg_bits() The reg_pair2[j].reg was tested twice. Cc: Signed-off-by: Roel Kluin Acked-by: Michael Krufky Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/mxl5007t.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c index 2d02698d4f4..7eb1bf75cd0 100644 --- a/drivers/media/common/tuners/mxl5007t.c +++ b/drivers/media/common/tuners/mxl5007t.c @@ -196,7 +196,7 @@ static void copy_reg_bits(struct reg_pair_t *reg_pair1, i = j = 0; while (reg_pair1[i].reg || reg_pair1[i].val) { - while (reg_pair2[j].reg || reg_pair2[j].reg) { + while (reg_pair2[j].reg || reg_pair2[j].val) { if (reg_pair1[i].reg != reg_pair2[j].reg) { j++; continue; -- cgit v1.2.3-70-g09d2 From cd0e280f1bbecebcd20ed0ddd4dd8fb03a506b3c Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 21 Nov 2009 08:49:41 -0300 Subject: V4L/DVB (13413): introduce missing kfree Error handling code following a kzalloc should free the allocated data. Similarly for usb-alloc urb. The semantic match that finds the first problem is as follows: (http://www.emn.fr/x-info/coccinelle/) // @r exists@ local idexpression x; statement S; expression E; identifier f,f1,l; position p1,p2; expression *ptr != NULL; @@ x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...); ... if (x == NULL) S <... when != x when != if (...) { <+...x...+> } ( x->f1 = E | (x->f1 == NULL || ...) | f(...,x->f1,...) ) ...> ( return \(0\|<+...x...+>\|ptr\); | return@p2 ...; ) @script:python@ p1 << r.p1; p2 << r.p2; @@ print "* file: %s kmalloc %s return %s" % (p1[0].file,p1[0].line,p2[0].line) // Signed-off-by: Julia Lawall Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/hdpvr/hdpvr-video.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c index 2eb9dc2ebe5..b5439cabb38 100644 --- a/drivers/media/video/hdpvr/hdpvr-video.c +++ b/drivers/media/video/hdpvr/hdpvr-video.c @@ -139,7 +139,7 @@ int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count) urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { v4l2_err(&dev->v4l2_dev, "cannot allocate urb\n"); - goto exit; + goto exit_urb; } buf->urb = urb; @@ -148,7 +148,7 @@ int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count) if (!mem) { v4l2_err(&dev->v4l2_dev, "cannot allocate usb transfer buffer\n"); - goto exit; + goto exit_urb_buffer; } usb_fill_bulk_urb(buf->urb, dev->udev, @@ -161,6 +161,10 @@ int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count) list_add_tail(&buf->buff_list, &dev->free_buff_list); } return 0; +exit_urb_buffer: + usb_free_urb(urb); +exit_urb: + kfree(buf); exit: hdpvr_free_buffers(dev); return retval; -- cgit v1.2.3-70-g09d2 From b1858190fc0180df70e9e7bab24a679129643f43 Mon Sep 17 00:00:00 2001 From: Márton Németh Date: Sat, 21 Nov 2009 13:46:12 -0300 Subject: V4L/DVB (13414): ttusb-dec: do not overwrite the first part of phys string MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use strlcat() to append a string to the previously created first part. The semantic match that finds this kind of problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression dev; expression phys; expression str; expression size; @@ usb_make_path(dev, phys, size); - strlcpy(phys, str, size); + strlcat(phys, str, size); // Signed-off-by: Márton Németh Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttusb-dec/ttusb_dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c index d91e0638448..53baccbab17 100644 --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -1198,7 +1198,7 @@ static int ttusb_init_rc( struct ttusb_dec *dec) int err; usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys)); - strlcpy(dec->rc_phys, "/input0", sizeof(dec->rc_phys)); + strlcat(dec->rc_phys, "/input0", sizeof(dec->rc_phys)); input_dev = input_allocate_device(); if (!input_dev) -- cgit v1.2.3-70-g09d2 From 296372e3b04a41853df1be6623a5bd634051458c Mon Sep 17 00:00:00 2001 From: Márton Németh Date: Sun, 22 Nov 2009 18:03:05 -0300 Subject: V4L/DVB (13415): videobuf-core: explicitly cast page count MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Explicitly cast page count in the debug message. Signed-off-by: Márton Németh Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videobuf-core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index 136bc3496c8..bb0a1c8de41 100644 --- a/drivers/media/video/videobuf-core.c +++ b/drivers/media/video/videobuf-core.c @@ -430,8 +430,9 @@ int videobuf_reqbufs(struct videobuf_queue *q, count = VIDEO_MAX_FRAME; size = 0; q->ops->buf_setup(q, &count, &size); - dprintk(1, "reqbufs: bufs=%d, size=0x%x [%d pages total]\n", - count, size, (count*PAGE_ALIGN(size))>>PAGE_SHIFT); + dprintk(1, "reqbufs: bufs=%d, size=0x%x [%u pages total]\n", + count, size, + (unsigned int)((count*PAGE_ALIGN(size))>>PAGE_SHIFT) ); retval = __videobuf_mmap_setup(q, count, size, req->memory); if (retval < 0) { -- cgit v1.2.3-70-g09d2 From f58d7856695b6a3a03a56250c6c591022ac9918f Mon Sep 17 00:00:00 2001 From: Márton Németh Date: Sun, 22 Nov 2009 18:52:31 -0300 Subject: V4L/DVB (13416): smssdio: initialize return value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The return value may be used uninitialized when the size parameter happens to be 0. Signed-off-by: Márton Németh Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smssdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smssdio.c b/drivers/media/dvb/siano/smssdio.c index d1d652e7f89..24206cbda26 100644 --- a/drivers/media/dvb/siano/smssdio.c +++ b/drivers/media/dvb/siano/smssdio.c @@ -78,7 +78,7 @@ struct smssdio_device { static int smssdio_sendrequest(void *context, void *buffer, size_t size) { - int ret; + int ret = 0; struct smssdio_device *smsdev; smsdev = context; -- cgit v1.2.3-70-g09d2 From f8b0bca1a7ea8479490bcc06835ccbf590ba2c4e Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Mon, 23 Nov 2009 14:29:35 -0300 Subject: V4L/DVB (13417): Fix videobuf_queue_vmalloc_init() prototype For whatever reason, the device structure pointer to videobuf_queue_vmalloc_init is typed "void *", even though it's passed right through to videobuf_queue_core_init(), which expects a struct device pointer. The other videobuf implementations use struct device *; I think vmalloc should too. Signed-off-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videobuf-vmalloc.c | 2 +- include/media/videobuf-vmalloc.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c index 99d646ed024..d6e6a28fb6b 100644 --- a/drivers/media/video/videobuf-vmalloc.c +++ b/drivers/media/video/videobuf-vmalloc.c @@ -392,7 +392,7 @@ static struct videobuf_qtype_ops qops = { void videobuf_queue_vmalloc_init(struct videobuf_queue* q, const struct videobuf_queue_ops *ops, - void *dev, + struct device *dev, spinlock_t *irqlock, enum v4l2_buf_type type, enum v4l2_field field, diff --git a/include/media/videobuf-vmalloc.h b/include/media/videobuf-vmalloc.h index 1ffdb662443..4b419a257a7 100644 --- a/include/media/videobuf-vmalloc.h +++ b/include/media/videobuf-vmalloc.h @@ -31,7 +31,7 @@ struct videobuf_vmalloc_memory void videobuf_queue_vmalloc_init(struct videobuf_queue* q, const struct videobuf_queue_ops *ops, - void *dev, + struct device *dev, spinlock_t *irqlock, enum v4l2_buf_type type, enum v4l2_field field, -- cgit v1.2.3-70-g09d2 From 4d0fc03a76d96fff0cf6c815702ae04896b74cde Mon Sep 17 00:00:00 2001 From: Márton Németh Date: Mon, 9 Nov 2009 07:08:04 -0300 Subject: V4L/DVB (13418): gspca - pac7311: Stop sending URBs on first error. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Márton Németh Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac7311.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index c3e1f80351a..1a27da00ccc 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -569,16 +569,27 @@ static int sd_start(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev) { - reg_w(gspca_dev, 0xff, 0x04); - reg_w(gspca_dev, 0x27, 0x80); - reg_w(gspca_dev, 0x28, 0xca); - reg_w(gspca_dev, 0x29, 0x53); - reg_w(gspca_dev, 0x2a, 0x0e); - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x3e, 0x20); - reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */ - reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */ - reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */ + int ret; + + ret = reg_w(gspca_dev, 0xff, 0x04); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x27, 0x80); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x28, 0xca); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x29, 0x53); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x2a, 0x0e); + if (0 <= ret) + ret = reg_w(gspca_dev, 0xff, 0x01); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x3e, 0x20); + if (0 <= ret) + ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */ + if (0 <= ret) + ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */ + if (0 <= ret) + ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */ } /* called on streamoff with alt 0 and on disconnect for 7311 */ -- cgit v1.2.3-70-g09d2 From 6763cc0e54e95eea356e15f9cd9a2f7b5ebeb7e8 Mon Sep 17 00:00:00 2001 From: Márton Németh Date: Mon, 9 Nov 2009 07:10:46 -0300 Subject: V4L/DVB (13419): gspca - pac7302: Add debug register write interface. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add debug register write interface to pac7302 to be able to set for example the edge detect mode (bit 2 register 0x55) or the test pattern (bit 0..3, register 0x72) and test overlay (bit 4, register 0x72) from the user space. Only write of register page 0 is supported by this patch. Signed-off-by: Márton Németh Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac7302.c | 54 +++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index 5cd02571bbf..e0fd767984b 100644 --- a/drivers/media/video/gspca/pac7302.c +++ b/drivers/media/video/gspca/pac7302.c @@ -68,6 +68,7 @@ #define MODULE_NAME "pac7302" +#include #include "gspca.h" MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); @@ -1143,6 +1144,55 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int sd_dbg_s_register(struct gspca_dev *gspca_dev, + struct v4l2_dbg_register *reg) +{ + int ret = -EINVAL; + __u8 index; + __u8 value; + + /* reg->reg: bit0..15: reserved for register index (wIndex is 16bit + long on the USB bus) + */ + if (reg->match.type == V4L2_CHIP_MATCH_HOST && + reg->match.addr == 0 && + (reg->reg < 0x000000ff) && + (reg->val <= 0x000000ff) + ) { + /* Currently writing to page 0 is only supported. */ + /* reg_w() only supports 8bit index */ + index = reg->reg & 0x000000ff; + value = reg->val & 0x000000ff; + + /* Note that there shall be no access to other page + by any other function between the page swith and + the actual register write */ + ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ + if (0 <= ret) + ret = reg_w(gspca_dev, index, value); + + if (0 <= ret) + ret = reg_w(gspca_dev, 0xdc, 0x01); + } + return ret; +} + +static int sd_chip_ident(struct gspca_dev *gspca_dev, + struct v4l2_dbg_chip_ident *chip) +{ + int ret = -EINVAL; + + if (chip->match.type == V4L2_CHIP_MATCH_HOST && + chip->match.addr == 0) { + chip->revision = 0; + chip->ident = V4L2_IDENT_UNKNOWN; + ret = 0; + } + return ret; +} +#endif + /* sub-driver description for pac7302 */ static struct sd_desc sd_desc = { .name = MODULE_NAME, @@ -1155,6 +1205,10 @@ static struct sd_desc sd_desc = { .stop0 = sd_stop0, .pkt_scan = sd_pkt_scan, .dq_callback = do_autogain, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .set_register = sd_dbg_s_register, + .get_chip_ident = sd_chip_ident, +#endif }; /* -- module initialisation -- */ -- cgit v1.2.3-70-g09d2 From 4bdf4a8342ca01ff794f5de8f9766cf15947a2ef Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 10 Nov 2009 14:49:43 -0300 Subject: V4L/DVB (13421): gspca - main: Clearer message when bandwidth too small. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index afd99beab30..6915db2d36d 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -657,15 +657,19 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) } if (ret >= 0) break; - PDEBUG(D_ERR|D_STREAM, - "usb_submit_urb alt %d err %d", gspca_dev->alt, ret); gspca_dev->streaming = 0; destroy_urbs(gspca_dev); - if (ret != -ENOSPC) + if (ret != -ENOSPC) { + PDEBUG(D_ERR|D_STREAM, + "usb_submit_urb alt %d err %d", + gspca_dev->alt, ret); goto out; + } /* the bandwidth is not wide enough * negociate or try a lower alternate setting */ + PDEBUG(D_ERR|D_STREAM, + "bandwidth not wide enough - trying again"); msleep(20); /* wait for kill complete */ if (gspca_dev->sd_desc->isoc_nego) { ret = gspca_dev->sd_desc->isoc_nego(gspca_dev); -- cgit v1.2.3-70-g09d2 From 189d92af707ead6aa4a3e14511662462e8e956e2 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 11 Nov 2009 07:46:28 -0300 Subject: V4L/DVB (13422): gspca - ov534: ov772x changes from Richard Kaswy. - 320x240 resolution added - controls added - different sd_desc tables Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 676 +++++++++++++++++++++++++++++++++----- 1 file changed, 591 insertions(+), 85 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 4b528b37291..fa28316c06e 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -1,5 +1,6 @@ /* * ov534 gspca driver + * * Copyright (C) 2008 Antonio Ospite * Copyright (C) 2008 Jim Paris * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr @@ -8,6 +9,8 @@ * USB protocol reverse engineered by Jim Paris * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/ * + * PS3 Eye camera enhanced by Richard Kaswy http://kaswy.free.fr + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -50,6 +53,14 @@ struct sd { __u32 last_pts; u16 last_fid; u8 frame_rate; + u8 gain; + u8 exposure; + u8 redblc; + u8 blueblc; + u8 autogain; + u8 sharpness; + u8 hflip; + u8 vflip; u8 sensor; #define SENSOR_OV772X 0 @@ -57,10 +68,146 @@ struct sd { }; /* V4L2 controls supported by the driver */ -static struct ctrl sd_ctrls[] = { +static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getredblc(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setblueblc(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); +static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls_ov772x[] = { + { + { + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Main Gain", + .minimum = 0, + .maximum = 63, + .step = 1, +#define GAIN_DEF 20 + .default_value = GAIN_DEF, + }, + .set = sd_setgain, + .get = sd_getgain, + }, + { + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure", + .minimum = 0, + .maximum = 255, + .step = 1, +#define EXPO_DEF 255 + .default_value = EXPO_DEF, + }, + .set = sd_setexposure, + .get = sd_getexposure, + }, + { + { + .id = V4L2_CID_RED_BALANCE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Red Balance", + .minimum = 0, + .maximum = 255, + .step = 1, +#define RED_BALANCE_DEF 128 + .default_value = RED_BALANCE_DEF, + }, + .set = sd_setredblc, + .get = sd_getredblc, + }, + { + { + .id = V4L2_CID_BLUE_BALANCE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Blue Balance", + .minimum = 0, + .maximum = 255, + .step = 1, +#define BLUE_BALANCE_DEF 128 + .default_value = BLUE_BALANCE_DEF, + }, + .set = sd_setblueblc, + .get = sd_getblueblc, + }, + { + { + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Autogain", + .minimum = 0, + .maximum = 1, + .step = 1, +#define AUTOGAIN_DEF 1 + .default_value = AUTOGAIN_DEF, + }, + .set = sd_setautogain, + .get = sd_getautogain, + }, + { + { + .id = V4L2_CID_SHARPNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Sharpness", + .minimum = 0, + .maximum = 63, + .step = 1, +#define SHARPNESS_DEF 4 + .default_value = SHARPNESS_DEF, + }, + .set = sd_setsharpness, + .get = sd_getsharpness, + }, + { + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "HFlip", + .minimum = 0, + .maximum = 1, + .step = 1, +#define HFLIP_DEF 0 + .default_value = HFLIP_DEF, + }, + .set = sd_sethflip, + .get = sd_gethflip, + }, + { + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "VFlip", + .minimum = 0, + .maximum = 1, + .step = 1, +#define VFLIP_DEF 0 + .default_value = VFLIP_DEF, + }, + .set = sd_setvflip, + .get = sd_getvflip, + }, +}; +static struct ctrl sd_ctrls_ov965x[] = { }; static const struct v4l2_pix_format vga_yuyv_mode[] = { + {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + .bytesperline = 320 * 2, + .sizeimage = 320 * 240 * 2, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 1}, {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, .bytesperline = 640 * 2, .sizeimage = 640 * 480 * 2, @@ -80,8 +227,7 @@ static const struct v4l2_pix_format vga_jpeg_mode[] = { .colorspace = V4L2_COLORSPACE_JPEG, .priv = 0}, }; - -static const u8 bridge_init_ov722x[][2] = { +static const u8 bridge_init_ov772x[][2] = { { 0xc2, 0x0c }, { 0x88, 0xf8 }, { 0xc3, 0x69 }, @@ -122,6 +268,7 @@ static const u8 bridge_init_ov722x[][2] = { { 0x1d, 0x40 }, { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */ { 0x1d, 0x00 }, /* payload size */ + { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */ { 0x1d, 0x58 }, /* frame size */ { 0x1d, 0x00 }, /* frame size */ @@ -138,10 +285,20 @@ static const u8 bridge_init_ov722x[][2] = { { 0xc1, 0x3c }, { 0xc2, 0x0c }, }; - -static const u8 sensor_init_ov722x[][2] = { +static const u8 sensor_init_ov772x[][2] = { { 0x12, 0x80 }, { 0x11, 0x01 }, +/*fixme: better have a delay?*/ + { 0x11, 0x01 }, + { 0x11, 0x01 }, + { 0x11, 0x01 }, + { 0x11, 0x01 }, + { 0x11, 0x01 }, + { 0x11, 0x01 }, + { 0x11, 0x01 }, + { 0x11, 0x01 }, + { 0x11, 0x01 }, + { 0x11, 0x01 }, { 0x3d, 0x03 }, { 0x17, 0x26 }, @@ -154,7 +311,7 @@ static const u8 sensor_init_ov722x[][2] = { { 0x65, 0x20 }, { 0x11, 0x01 }, { 0x42, 0x7f }, - { 0x63, 0xe0 }, + { 0x63, 0xaa }, /* was e0 */ { 0x64, 0xff }, { 0x66, 0x00 }, { 0x13, 0xf0 }, @@ -221,6 +378,46 @@ static const u8 sensor_init_ov722x[][2] = { { 0x8e, 0x00 }, { 0x0c, 0xd0 } }; +static const u8 bridge_start_ov772x_vga[][2] = { + {0x1c, 0x00}, + {0x1d, 0x40}, + {0x1d, 0x02}, + {0x1d, 0x00}, + {0x1d, 0x02}, + {0x1d, 0x58}, + {0x1d, 0x00}, + {0xc0, 0x50}, + {0xc1, 0x3c}, +}; +static const u8 sensor_start_ov772x_vga[][2] = { + {0x12, 0x00}, + {0x17, 0x26}, + {0x18, 0xa0}, + {0x19, 0x07}, + {0x1a, 0xf0}, + {0x29, 0xa0}, + {0x2c, 0xf0}, +}; +static const u8 bridge_start_ov772x_qvga[][2] = { + {0x1c, 0x00}, + {0x1d, 0x40}, + {0x1d, 0x02}, + {0x1d, 0x00}, + {0x1d, 0x01}, + {0x1d, 0x4b}, + {0x1d, 0x00}, + {0xc0, 0x28}, + {0xc1, 0x1e}, +}; +static const u8 sensor_start_ov772x_qvga[][2] = { + {0x12, 0x40}, + {0x17, 0x3f}, + {0x18, 0x50}, + {0x19, 0x03}, + {0x1a, 0x78}, + {0x29, 0x50}, + {0x2c, 0x78}, +}; static const u8 bridge_init_ov965x[][2] = { {0x88, 0xf8}, @@ -757,35 +954,150 @@ static void sccb_w_array(struct gspca_dev *gspca_dev, static void ov534_set_frame_rate(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - int fr = sd->frame_rate; + int i; + struct rate_s { + u8 fps; + u8 r11; + u8 r0d; + u8 re5; + }; + const struct rate_s *r; + static const struct rate_s rate_0[] = { /* 640x480 */ + {60, 0x01, 0xc1, 0x04}, + {50, 0x01, 0x41, 0x02}, + {40, 0x02, 0xc1, 0x04}, + {30, 0x04, 0x81, 0x02}, + {15, 0x03, 0x41, 0x04}, + }; + static const struct rate_s rate_1[] = { /* 320x240 */ + {125, 0x02, 0x81, 0x02}, + {100, 0x02, 0xc1, 0x04}, + {75, 0x03, 0xc1, 0x04}, + {60, 0x04, 0xc1, 0x04}, + {50, 0x02, 0x41, 0x04}, + {40, 0x03, 0x41, 0x04}, + {30, 0x04, 0x41, 0x04}, + }; + + if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv == 0) { + r = rate_0; + i = ARRAY_SIZE(rate_0); + } else { + r = rate_1; + i = ARRAY_SIZE(rate_1); + } + while (--i > 0) { + if (sd->frame_rate >= r->fps) + break; + r++; + } + + sccb_reg_write(gspca_dev, 0x11, r->r11); + sccb_reg_write(gspca_dev, 0x0d, r->r0d); + ov534_reg_write(gspca_dev, 0xe5, r->re5); + + PDEBUG(D_PROBE, "frame_rate: %d", r->fps); +} + +/* ov772x controls */ +static void setgain(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + u8 val; - switch (fr) { - case 50: - sccb_reg_write(gspca_dev, 0x11, 0x01); - sccb_reg_write(gspca_dev, 0x0d, 0x41); - ov534_reg_write(gspca_dev, 0xe5, 0x02); + val = sd->gain; + switch (val & 0x30) { + case 0x00: + val &= 0x0f; break; - case 40: - sccb_reg_write(gspca_dev, 0x11, 0x02); - sccb_reg_write(gspca_dev, 0x0d, 0xc1); - ov534_reg_write(gspca_dev, 0xe5, 0x04); + case 0x10: + val &= 0x0f; + val |= 0x30; break; -/* case 30: */ - default: - fr = 30; - sccb_reg_write(gspca_dev, 0x11, 0x04); - sccb_reg_write(gspca_dev, 0x0d, 0x81); - ov534_reg_write(gspca_dev, 0xe5, 0x02); + case 0x20: + val &= 0x0f; + val |= 0x70; break; - case 15: - sccb_reg_write(gspca_dev, 0x11, 0x03); - sccb_reg_write(gspca_dev, 0x0d, 0x41); - ov534_reg_write(gspca_dev, 0xe5, 0x04); + default: +/* case 0x30: */ + val &= 0x0f; + val |= 0xf0; break; } + sccb_reg_write(gspca_dev, 0x00, val); +} + +static void setexposure(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + u8 val; + + val = sd->exposure; + sccb_reg_write(gspca_dev, 0x08, val >> 7); + sccb_reg_write(gspca_dev, 0x10, val << 1); +} + +static void setredblc(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; - sd->frame_rate = fr; - PDEBUG(D_PROBE, "frame_rate: %d", fr); + sccb_reg_write(gspca_dev, 0x43, sd->redblc); +} + +static void setblueblc(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sccb_reg_write(gspca_dev, 0x42, sd->blueblc); +} + +static void setautogain(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + if (sd->autogain) { + sccb_reg_write(gspca_dev, 0x13, 0xf7); /* AGC,AEC,AWB ON */ + sccb_reg_write(gspca_dev, 0x64, + sccb_reg_read(gspca_dev, 0x64) | 0x03); + } else { + sccb_reg_write(gspca_dev, 0x13, 0xf0); /* AGC,AEC,AWB OFF */ + sccb_reg_write(gspca_dev, 0x64, + sccb_reg_read(gspca_dev, 0x64) & 0xfc); + } +} + +static void setsharpness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + u8 val; + + val = sd->sharpness; + sccb_reg_write(gspca_dev, 0x91, val); /* vga noise */ + sccb_reg_write(gspca_dev, 0x8e, val); /* qvga noise */ +} + +static void sethflip(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + if (sd->hflip == 0) + sccb_reg_write(gspca_dev, 0x0c, + sccb_reg_read(gspca_dev, 0x0c) | 0x40); + else + sccb_reg_write(gspca_dev, 0x0c, + sccb_reg_read(gspca_dev, 0x0c) & 0xbf); +} + +static void setvflip(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + if (sd->vflip == 0) + sccb_reg_write(gspca_dev, 0x0c, + sccb_reg_read(gspca_dev, 0x0c) | 0x80); + else + sccb_reg_write(gspca_dev, 0x0c, + sccb_reg_read(gspca_dev, 0x0c) & 0x7f); } /* this function is called at probe time */ @@ -811,6 +1123,19 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->nmodes = ARRAY_SIZE(vga_jpeg_mode); } + sd->frame_rate = 30; + sd->gain = GAIN_DEF; + sd->exposure = EXPO_DEF; + sd->redblc = RED_BALANCE_DEF; + sd->blueblc = BLUE_BALANCE_DEF; + sd->autogain = AUTOGAIN_DEF; + sd->sharpness = SHARPNESS_DEF; +#if HFLIP_DEF != 0 + sd->hflip = HFLIP_DEF; +#endif +#if VFLIP_DEF != 0 + sd->vflip = VFLIP_DEF; +#endif return 0; } @@ -847,11 +1172,11 @@ static int sd_init(struct gspca_dev *gspca_dev) /* initialize */ switch (sd->sensor) { case SENSOR_OV772X: - reg_w_array(gspca_dev, bridge_init_ov722x, - ARRAY_SIZE(bridge_init_ov722x)); + reg_w_array(gspca_dev, bridge_init_ov772x, + ARRAY_SIZE(bridge_init_ov772x)); ov534_set_led(gspca_dev, 1); - sccb_w_array(gspca_dev, sensor_init_ov722x, - ARRAY_SIZE(sensor_init_ov722x)); + sccb_w_array(gspca_dev, sensor_init_ov772x, + ARRAY_SIZE(sensor_init_ov772x)); ov534_reg_write(gspca_dev, 0xe0, 0x09); ov534_set_led(gspca_dev, 0); ov534_set_frame_rate(gspca_dev); @@ -875,60 +1200,78 @@ static int sd_init(struct gspca_dev *gspca_dev) return 0; } -static int sd_start(struct gspca_dev *gspca_dev) +static int sd_start_ov772x(struct gspca_dev *gspca_dev) { - struct sd *sd = (struct sd *) gspca_dev; int mode; - switch (sd->sensor) { - case SENSOR_OV772X: - ov534_set_led(gspca_dev, 1); - ov534_reg_write(gspca_dev, 0xe0, 0x00); - break; - default: -/* case SENSOR_OV965X: */ - - sccb_w_array(gspca_dev, sensor_start_ov965x, - ARRAY_SIZE(sensor_start_ov965x)); - reg_w_array(gspca_dev, bridge_start_ov965x, - ARRAY_SIZE(bridge_start_ov965x)); - mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; - if (mode != 0) { /* 320x240 */ - reg_w_array(gspca_dev, bridge_start_ov965x_cif, - ARRAY_SIZE(bridge_start_ov965x_cif)); - sccb_w_array(gspca_dev, sensor_start_ov965x_cif, - ARRAY_SIZE(sensor_start_ov965x_cif)); - } else { /* 640x480 */ - reg_w_array(gspca_dev, bridge_start_ov965x_vga, - ARRAY_SIZE(bridge_start_ov965x_vga)); - sccb_w_array(gspca_dev, sensor_start_ov965x_vga, - ARRAY_SIZE(sensor_start_ov965x_vga)); - } - sccb_w_array(gspca_dev, sensor_start_ov965x_2, - ARRAY_SIZE(sensor_start_ov965x_2)); - ov534_reg_write(gspca_dev, 0xe0, 0x00); - ov534_reg_write(gspca_dev, 0xe0, 0x00); - ov534_set_led(gspca_dev, 1); + mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; + if (mode != 0) { /* 320x240 */ + reg_w_array(gspca_dev, bridge_start_ov772x_qvga, + ARRAY_SIZE(bridge_start_ov772x_qvga)); + sccb_w_array(gspca_dev, sensor_start_ov772x_qvga, + ARRAY_SIZE(sensor_start_ov772x_qvga)); + } else { /* 640x480 */ + reg_w_array(gspca_dev, bridge_start_ov772x_vga, + ARRAY_SIZE(bridge_start_ov772x_vga)); + sccb_w_array(gspca_dev, sensor_start_ov772x_vga, + ARRAY_SIZE(sensor_start_ov772x_vga)); } + ov534_set_frame_rate(gspca_dev); + + setautogain(gspca_dev); + setgain(gspca_dev); + setredblc(gspca_dev); + setblueblc(gspca_dev); + setexposure(gspca_dev); + setsharpness(gspca_dev); + setvflip(gspca_dev); + sethflip(gspca_dev); + + ov534_set_led(gspca_dev, 1); + ov534_reg_write(gspca_dev, 0xe0, 0x00); return 0; } -static void sd_stopN(struct gspca_dev *gspca_dev) +static int sd_start_ov965x(struct gspca_dev *gspca_dev) { - struct sd *sd = (struct sd *) gspca_dev; + int mode; - switch (sd->sensor) { - case SENSOR_OV772X: - ov534_reg_write(gspca_dev, 0xe0, 0x09); - ov534_set_led(gspca_dev, 0); - break; - default: -/* case SENSOR_OV965X: */ - ov534_reg_write(gspca_dev, 0xe0, 0x01); - ov534_set_led(gspca_dev, 0); - ov534_reg_write(gspca_dev, 0xe0, 0x00); - break; + sccb_w_array(gspca_dev, sensor_start_ov965x, + ARRAY_SIZE(sensor_start_ov965x)); + reg_w_array(gspca_dev, bridge_start_ov965x, + ARRAY_SIZE(bridge_start_ov965x)); + + mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; + if (mode != 0) { /* 320x240 */ + reg_w_array(gspca_dev, bridge_start_ov965x_cif, + ARRAY_SIZE(bridge_start_ov965x_cif)); + sccb_w_array(gspca_dev, sensor_start_ov965x_cif, + ARRAY_SIZE(sensor_start_ov965x_cif)); + } else { /* 640x480 */ + reg_w_array(gspca_dev, bridge_start_ov965x_vga, + ARRAY_SIZE(bridge_start_ov965x_vga)); + sccb_w_array(gspca_dev, sensor_start_ov965x_vga, + ARRAY_SIZE(sensor_start_ov965x_vga)); } + sccb_w_array(gspca_dev, sensor_start_ov965x_2, + ARRAY_SIZE(sensor_start_ov965x_2)); + ov534_reg_write(gspca_dev, 0xe0, 0x00); + ov534_reg_write(gspca_dev, 0xe0, 0x00); + ov534_set_led(gspca_dev, 1); + return 0; +} + +static void sd_stopN_ov772x(struct gspca_dev *gspca_dev) +{ + ov534_reg_write(gspca_dev, 0xe0, 0x09); + ov534_set_led(gspca_dev, 0); +} + +static void sd_stopN_ov965x(struct gspca_dev *gspca_dev) +{ + ov534_reg_write(gspca_dev, 0xe0, 0x01); + ov534_set_led(gspca_dev, 0); + ov534_reg_write(gspca_dev, 0xe0, 0x00); } /* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ @@ -1002,7 +1345,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, data + 12, len - 12); } - /* Done this payload */ goto scan_next; @@ -1016,6 +1358,151 @@ scan_next: } while (remaining_len > 0); } +/* ov772x controls */ +static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->gain = val; + if (gspca_dev->streaming) + setgain(gspca_dev); + return 0; +} + +static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->gain; + return 0; +} + +static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->exposure = val; + if (gspca_dev->streaming) + setexposure(gspca_dev); + return 0; +} + +static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->exposure; + return 0; +} + +static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->redblc = val; + if (gspca_dev->streaming) + setredblc(gspca_dev); + return 0; +} + +static int sd_getredblc(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->redblc; + return 0; +} + +static int sd_setblueblc(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->blueblc = val; + if (gspca_dev->streaming) + setblueblc(gspca_dev); + return 0; +} + +static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->blueblc; + return 0; +} + +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->autogain = val; + if (gspca_dev->streaming) + setautogain(gspca_dev); + return 0; +} + +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->autogain; + return 0; +} + +static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->sharpness = val; + if (gspca_dev->streaming) + setsharpness(gspca_dev); + return 0; +} + +static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->sharpness; + return 0; +} + +static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->hflip = val; + if (gspca_dev->streaming) + sethflip(gspca_dev); + return 0; +} + +static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->hflip; + return 0; +} + +static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->vflip = val; + if (gspca_dev->streaming) + setvflip(gspca_dev); + return 0; +} + +static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->vflip; + return 0; +} + /* get stream parameters (framerate) */ static int sd_get_streamparm(struct gspca_dev *gspca_dev, struct v4l2_streamparm *parm) @@ -1047,7 +1534,8 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev, /* Set requested framerate */ sd->frame_rate = tpf->denominator / tpf->numerator; - ov534_set_frame_rate(gspca_dev); + if (gspca_dev->streaming) + ov534_set_frame_rate(gspca_dev); /* Return the actual framerate */ tpf->numerator = 1; @@ -1057,14 +1545,27 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev, } /* sub-driver description */ -static const struct sd_desc sd_desc = { +static const struct sd_desc sd_desc_ov772x = { .name = MODULE_NAME, - .ctrls = sd_ctrls, - .nctrls = ARRAY_SIZE(sd_ctrls), + .ctrls = sd_ctrls_ov772x, + .nctrls = ARRAY_SIZE(sd_ctrls_ov772x), .config = sd_config, .init = sd_init, - .start = sd_start, - .stopN = sd_stopN, + .start = sd_start_ov772x, + .stopN = sd_stopN_ov772x, + .pkt_scan = sd_pkt_scan, + .get_streamparm = sd_get_streamparm, + .set_streamparm = sd_set_streamparm, +}; + +static const struct sd_desc sd_desc_ov965x = { + .name = MODULE_NAME, + .ctrls = sd_ctrls_ov965x, + .nctrls = ARRAY_SIZE(sd_ctrls_ov965x), + .config = sd_config, + .init = sd_init, + .start = sd_start_ov965x, + .stopN = sd_stopN_ov965x, .pkt_scan = sd_pkt_scan, .get_streamparm = sd_get_streamparm, .set_streamparm = sd_set_streamparm, @@ -1082,8 +1583,12 @@ MODULE_DEVICE_TABLE(usb, device_table); /* -- device connect -- */ static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) { - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); + return gspca_dev_probe(intf, id, + id->driver_info == SENSOR_OV772X + ? &sd_desc_ov772x + : &sd_desc_ov965x, + sizeof(struct sd), + THIS_MODULE); } static struct usb_driver sd_driver = { @@ -1101,6 +1606,7 @@ static struct usb_driver sd_driver = { static int __init sd_mod_init(void) { int ret; + ret = usb_register(&sd_driver); if (ret < 0) return ret; -- cgit v1.2.3-70-g09d2 From b014f94b28713e169a438131a5ce2752068068ad Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 11 Nov 2009 14:28:53 -0300 Subject: V4L/DVB (13423): gspca - ov534: More ov772x changes from Max Thrun. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 205 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 197 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index fa28316c06e..b665c84ca86 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -10,6 +10,8 @@ * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/ * * PS3 Eye camera enhanced by Richard Kaswy http://kaswy.free.fr + * PS3 Eye camera, brightness, contrast, hue, AWB control added + * by Max Thrun * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -53,11 +55,16 @@ struct sd { __u32 last_pts; u16 last_fid; u8 frame_rate; + + u8 brightness; + u8 contrast; u8 gain; u8 exposure; u8 redblc; u8 blueblc; + u8 hue; u8 autogain; + u8 awb; u8 sharpness; u8 hflip; u8 vflip; @@ -84,8 +91,44 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val); +static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls_ov772x[] = { + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 255, + .step = 1, +#define BRIGHTNESS_DEF 20 + .default_value = BRIGHTNESS_DEF, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 255, + .step = 1, +#define CONTRAST_DEF 37 + .default_value = CONTRAST_DEF, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, { { .id = V4L2_CID_GAIN, @@ -108,7 +151,7 @@ static struct ctrl sd_ctrls_ov772x[] = { .minimum = 0, .maximum = 255, .step = 1, -#define EXPO_DEF 255 +#define EXPO_DEF 120 .default_value = EXPO_DEF, }, .set = sd_setexposure, @@ -142,6 +185,20 @@ static struct ctrl sd_ctrls_ov772x[] = { .set = sd_setblueblc, .get = sd_getblueblc, }, + { + { + .id = V4L2_CID_HUE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Hue", + .minimum = 0, + .maximum = 255, + .step = 1, +#define HUE_DEF 143 + .default_value = HUE_DEF, + }, + .set = sd_sethue, + .get = sd_gethue, + }, { { .id = V4L2_CID_AUTOGAIN, @@ -150,12 +207,26 @@ static struct ctrl sd_ctrls_ov772x[] = { .minimum = 0, .maximum = 1, .step = 1, -#define AUTOGAIN_DEF 1 +#define AUTOGAIN_DEF 0 .default_value = AUTOGAIN_DEF, }, .set = sd_setautogain, .get = sd_getautogain, }, + { + { + .id = V4L2_CID_AUTO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Auto White Balance", + .minimum = 0, + .maximum = 1, + .step = 1, +#define AWB_DEF 0 + .default_value = AWB_DEF, + }, + .set = sd_setawb, + .get = sd_getawb, + }, { { .id = V4L2_CID_SHARPNESS, @@ -164,7 +235,7 @@ static struct ctrl sd_ctrls_ov772x[] = { .minimum = 0, .maximum = 63, .step = 1, -#define SHARPNESS_DEF 4 +#define SHARPNESS_DEF 0 .default_value = SHARPNESS_DEF, }, .set = sd_setsharpness, @@ -206,7 +277,7 @@ static const struct v4l2_pix_format vga_yuyv_mode[] = { {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, .bytesperline = 320 * 2, .sizeimage = 320 * 240 * 2, - .colorspace = V4L2_COLORSPACE_JPEG, + .colorspace = V4L2_COLORSPACE_SRGB, .priv = 1}, {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, .bytesperline = 640 * 2, @@ -311,10 +382,10 @@ static const u8 sensor_init_ov772x[][2] = { { 0x65, 0x20 }, { 0x11, 0x01 }, { 0x42, 0x7f }, - { 0x63, 0xaa }, /* was e0 */ + { 0x63, 0xaa }, /* AWB - was e0 */ { 0x64, 0xff }, { 0x66, 0x00 }, - { 0x13, 0xf0 }, + { 0x13, 0xf0 }, /* com8 */ { 0x0d, 0x41 }, { 0x0f, 0xc5 }, { 0x14, 0x11 }, @@ -327,7 +398,7 @@ static const u8 sensor_init_ov772x[][2] = { { 0x2a, 0x00 }, { 0x2b, 0x00 }, { 0x6b, 0xaa }, - { 0x13, 0xff }, + { 0x13, 0xff }, /* AWB */ { 0x90, 0x05 }, { 0x91, 0x01 }, @@ -375,7 +446,7 @@ static const u8 sensor_init_ov772x[][2] = { { 0x14, 0x41 }, { 0x0e, 0xcd }, { 0xac, 0xbf }, - { 0x8e, 0x00 }, + { 0x8e, 0x00 }, /* De-noise threshold */ { 0x0c, 0xd0 } }; static const u8 bridge_start_ov772x_vga[][2] = { @@ -397,6 +468,7 @@ static const u8 sensor_start_ov772x_vga[][2] = { {0x1a, 0xf0}, {0x29, 0xa0}, {0x2c, 0xf0}, + {0x65, 0x20}, }; static const u8 bridge_start_ov772x_qvga[][2] = { {0x1c, 0x00}, @@ -417,6 +489,7 @@ static const u8 sensor_start_ov772x_qvga[][2] = { {0x1a, 0x78}, {0x29, 0x50}, {0x2c, 0x78}, + {0x65, 0x2f}, }; static const u8 bridge_init_ov965x[][2] = { @@ -1000,6 +1073,20 @@ static void ov534_set_frame_rate(struct gspca_dev *gspca_dev) } /* ov772x controls */ +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sccb_reg_write(gspca_dev, 0x9B, sd->brightness); +} + +static void setcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sccb_reg_write(gspca_dev, 0x9C, sd->contrast); +} + static void setgain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1051,6 +1138,13 @@ static void setblueblc(struct gspca_dev *gspca_dev) sccb_reg_write(gspca_dev, 0x42, sd->blueblc); } +static void sethue(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sccb_reg_write(gspca_dev, 0x01, sd->hue); +} + static void setautogain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1066,6 +1160,16 @@ static void setautogain(struct gspca_dev *gspca_dev) } } +static void setawb(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + if (sd->awb) + sccb_reg_write(gspca_dev, 0x63, 0xe0); /* AWB on */ + else + sccb_reg_write(gspca_dev, 0x63, 0xaa); /* AWB off */ +} + static void setsharpness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1124,11 +1228,20 @@ static int sd_config(struct gspca_dev *gspca_dev, } sd->frame_rate = 30; + + sd->brightness = BRIGHTNESS_DEF; + sd->contrast = CONTRAST_DEF; sd->gain = GAIN_DEF; sd->exposure = EXPO_DEF; sd->redblc = RED_BALANCE_DEF; sd->blueblc = BLUE_BALANCE_DEF; + sd->hue = HUE_DEF; +#if AUTOGAIN_DEF != 0 sd->autogain = AUTOGAIN_DEF; +#endif +#if AWB_DEF != 0 + sd->awb = AWB_DEF +#endif sd->sharpness = SHARPNESS_DEF; #if HFLIP_DEF != 0 sd->hflip = HFLIP_DEF; @@ -1219,10 +1332,14 @@ static int sd_start_ov772x(struct gspca_dev *gspca_dev) ov534_set_frame_rate(gspca_dev); setautogain(gspca_dev); + setawb(gspca_dev); setgain(gspca_dev); setredblc(gspca_dev); setblueblc(gspca_dev); + sethue(gspca_dev); setexposure(gspca_dev); + setbrightness(gspca_dev); + setcontrast(gspca_dev); setsharpness(gspca_dev); setvflip(gspca_dev); sethflip(gspca_dev); @@ -1395,6 +1512,42 @@ static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + if (gspca_dev->streaming) + setcontrast(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->brightness; + return 0; +} + +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = val; + if (gspca_dev->streaming) + setcontrast(gspca_dev); + return 0; +} + +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->contrast; + return 0; +} + static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -1431,6 +1584,24 @@ static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->hue = val; + if (gspca_dev->streaming) + sethue(gspca_dev); + return 0; +} + +static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->hue; + return 0; +} + static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -1449,6 +1620,24 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->awb = val; + if (gspca_dev->streaming) + setawb(gspca_dev); + return 0; +} + +static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->awb; + return 0; +} + static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; -- cgit v1.2.3-70-g09d2 From 69f1fe28f08000a123b3d71fac88564109da09fd Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 12 Nov 2009 06:10:36 -0300 Subject: V4L/DVB (13424): gspca - ov534: Fix ov772x brightness and ov965x frame rate. - the ov772x brightness was not setteble (fixed by M. Thrun) - the set_frame_rate function does not work for ov965x Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index b665c84ca86..548f9e7edd8 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -1023,8 +1023,8 @@ static void sccb_w_array(struct gspca_dev *gspca_dev, } } -/* set framerate */ -static void ov534_set_frame_rate(struct gspca_dev *gspca_dev) +/* ov772x specific controls */ +static void set_frame_rate(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int i; @@ -1072,7 +1072,6 @@ static void ov534_set_frame_rate(struct gspca_dev *gspca_dev) PDEBUG(D_PROBE, "frame_rate: %d", r->fps); } -/* ov772x controls */ static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1292,7 +1291,7 @@ static int sd_init(struct gspca_dev *gspca_dev) ARRAY_SIZE(sensor_init_ov772x)); ov534_reg_write(gspca_dev, 0xe0, 0x09); ov534_set_led(gspca_dev, 0); - ov534_set_frame_rate(gspca_dev); + set_frame_rate(gspca_dev); break; default: /* case SENSOR_OV965X: */ @@ -1329,7 +1328,7 @@ static int sd_start_ov772x(struct gspca_dev *gspca_dev) sccb_w_array(gspca_dev, sensor_start_ov772x_vga, ARRAY_SIZE(sensor_start_ov772x_vga)); } - ov534_set_frame_rate(gspca_dev); + set_frame_rate(gspca_dev); setautogain(gspca_dev); setawb(gspca_dev); @@ -1518,7 +1517,7 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) sd->brightness = val; if (gspca_dev->streaming) - setcontrast(gspca_dev); + setbrightness(gspca_dev); return 0; } @@ -1723,8 +1722,8 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev, /* Set requested framerate */ sd->frame_rate = tpf->denominator / tpf->numerator; - if (gspca_dev->streaming) - ov534_set_frame_rate(gspca_dev); + if (gspca_dev->streaming && sd->sensor == SENSOR_OV772X) + set_frame_rate(gspca_dev); /* Return the actual framerate */ tpf->numerator = 1; -- cgit v1.2.3-70-g09d2 From c76e6f11662f49dd31a49a07f4c06ee9bea6572b Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 12 Nov 2009 06:13:41 -0300 Subject: V4L/DVB (13425): gspca - ov534: Bad name of the ov965x 320x240 resolution. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 548f9e7edd8..f2f844af54c 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -828,7 +828,7 @@ static const u8 bridge_start_ov965x_vga[][2] = { {} }; -static const u8 bridge_start_ov965x_cif[][2] = { +static const u8 bridge_start_ov965x_qvga[][2] = { {0xc2, 0x4c}, {0xc3, 0xf9}, {0xda, 0x00}, @@ -865,7 +865,7 @@ static const u8 sensor_start_ov965x_vga[][2] = { {} }; -static const u8 sensor_start_ov965x_cif[][2] = { +static const u8 sensor_start_ov965x_qvga[][2] = { {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */ {0x1e, 0x04}, /* mvfp */ {0x13, 0xe0}, /* com8 */ @@ -1359,10 +1359,10 @@ static int sd_start_ov965x(struct gspca_dev *gspca_dev) mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; if (mode != 0) { /* 320x240 */ - reg_w_array(gspca_dev, bridge_start_ov965x_cif, - ARRAY_SIZE(bridge_start_ov965x_cif)); - sccb_w_array(gspca_dev, sensor_start_ov965x_cif, - ARRAY_SIZE(sensor_start_ov965x_cif)); + reg_w_array(gspca_dev, bridge_start_ov965x_qvga, + ARRAY_SIZE(bridge_start_ov965x_qvga)); + sccb_w_array(gspca_dev, sensor_start_ov965x_qvga, + ARRAY_SIZE(sensor_start_ov965x_qvga)); } else { /* 640x480 */ reg_w_array(gspca_dev, bridge_start_ov965x_vga, ARRAY_SIZE(bridge_start_ov965x_vga)); -- cgit v1.2.3-70-g09d2 From f0076e60b5a61072b671b597ed2cc210f1b3cbf1 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Wed, 4 Nov 2009 22:33:33 -0300 Subject: V4L/DVB (13426): cx18: Rename struct cx18_mdl to struct cx18_mdl_ent Rename type in anticipation of implementing a struct cx18_mdl type that actually keeps track of a memory descriptor list. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-queue.c | 2 +- drivers/media/video/cx18/cx18-scb.h | 4 ++-- drivers/media/video/cx18/cx23418.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c index fa1ed7897d9..9061ff3eac6 100644 --- a/drivers/media/video/cx18/cx18-queue.c +++ b/drivers/media/video/cx18/cx18-queue.c @@ -201,7 +201,7 @@ int cx18_stream_alloc(struct cx18_stream *s) CX18_ERR("Too many buffers, cannot fit in SCB area\n"); CX18_ERR("Max buffers = %zd\n", - bufsz / sizeof(struct cx18_mdl)); + bufsz / sizeof(struct cx18_mdl_ent)); return -ENOMEM; } diff --git a/drivers/media/video/cx18/cx18-scb.h b/drivers/media/video/cx18/cx18-scb.h index 1dc1c431f5a..368f23d0870 100644 --- a/drivers/media/video/cx18/cx18-scb.h +++ b/drivers/media/video/cx18/cx18-scb.h @@ -81,7 +81,7 @@ /* This structure is used by EPU to provide memory descriptors in its memory */ -struct cx18_mdl { +struct cx18_mdl_ent { u32 paddr; /* Physical address of a buffer segment */ u32 length; /* Length of the buffer segment */ }; @@ -272,7 +272,7 @@ struct cx18_scb { struct cx18_mailbox ppu2epu_mb; struct cx18_mdl_ack cpu_mdl_ack[CX18_MAX_STREAMS][CX18_MAX_MDL_ACKS]; - struct cx18_mdl cpu_mdl[1]; + struct cx18_mdl_ent cpu_mdl[1]; }; void cx18_init_scb(struct cx18 *cx); diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h index 9956abf576c..868806effdc 100644 --- a/drivers/media/video/cx18/cx23418.h +++ b/drivers/media/video/cx18/cx23418.h @@ -363,7 +363,7 @@ /* Description: This command provides the offset to a Memory Descriptor List IN[0] - Task handle. Handle of the task to start IN[1] - Offset of the MDL from the beginning of the local DDR. - IN[2] - Number of cx18_mdl structures in the array pointed to by IN[1] + IN[2] - Number of cx18_mdl_ent structures in the array pointed to by IN[1] IN[3] - Buffer ID IN[4] - Total buffer length ReturnCode - One of the ERR_DE_... */ -- cgit v1.2.3-70-g09d2 From c37b11bf17b66b960b217c35283aa9c55eacb292 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Wed, 4 Nov 2009 23:13:58 -0300 Subject: V4L/DVB (13427): cx18: Rename struct cx18_queue.buffers to struct cx18_queue.depth Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-driver.h | 2 +- drivers/media/video/cx18/cx18-fileops.c | 4 ++-- drivers/media/video/cx18/cx18-ioctl.c | 2 +- drivers/media/video/cx18/cx18-queue.c | 16 ++++++++-------- drivers/media/video/cx18/cx18-streams.c | 6 +++--- 5 files changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index c6a1e907f63..0b182fa2ad0 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -285,7 +285,7 @@ struct cx18_buffer { struct cx18_queue { struct list_head list; - atomic_t buffers; + atomic_t depth; u32 bytesused; spinlock_t lock; }; diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c index 04d9c2508b8..e4a3faebff4 100644 --- a/drivers/media/video/cx18/cx18-fileops.c +++ b/drivers/media/video/cx18/cx18-fileops.c @@ -229,7 +229,7 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); /* New buffers might have become available before we were added to the waitqueue */ - if (!atomic_read(&s->q_full.buffers)) + if (!atomic_read(&s->q_full.depth)) schedule(); finish_wait(&s->waitq, &wait); if (signal_pending(current)) { @@ -543,7 +543,7 @@ unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait) CX18_DEBUG_HI_FILE("Encoder poll\n"); poll_wait(filp, &s->waitq, wait); - if (atomic_read(&s->q_full.buffers)) + if (atomic_read(&s->q_full.depth)) return POLLIN | POLLRDNORM; if (eof) return POLLHUP; diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index fc76e4d6ffa..6539b031b4e 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -910,7 +910,7 @@ static int cx18_log_status(struct file *file, void *fh) continue; CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, - atomic_read(&s->q_full.buffers) * 100 / s->buffers, + atomic_read(&s->q_full.depth) * 100 / s->buffers, (s->buffers * s->buf_size) / 1024, s->buffers); } CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n", diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c index 9061ff3eac6..bc4c5e4a6c0 100644 --- a/drivers/media/video/cx18/cx18-queue.c +++ b/drivers/media/video/cx18/cx18-queue.c @@ -38,7 +38,7 @@ void cx18_buf_swap(struct cx18_buffer *buf) void cx18_queue_init(struct cx18_queue *q) { INIT_LIST_HEAD(&q->list); - atomic_set(&q->buffers, 0); + atomic_set(&q->depth, 0); q->bytesused = 0; } @@ -55,7 +55,7 @@ struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, /* q_busy is restricted to a max buffer count imposed by firmware */ if (q == &s->q_busy && - atomic_read(&q->buffers) >= CX18_MAX_FW_MDLS_PER_STREAM) + atomic_read(&q->depth) >= CX18_MAX_FW_MDLS_PER_STREAM) q = &s->q_free; spin_lock(&q->lock); @@ -65,7 +65,7 @@ struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, else list_add_tail(&buf->list, &q->list); /* FIFO */ q->bytesused += buf->bytesused - buf->readpos; - atomic_inc(&q->buffers); + atomic_inc(&q->depth); spin_unlock(&q->lock); return q; @@ -81,7 +81,7 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) list_del_init(&buf->list); q->bytesused -= buf->bytesused - buf->readpos; buf->skipped = 0; - atomic_dec(&q->buffers); + atomic_dec(&q->depth); } spin_unlock(&q->lock); return buf; @@ -113,7 +113,7 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id, */ if (buf->id != id) { buf->skipped++; - if (buf->skipped >= atomic_read(&s->q_busy.buffers)-1) { + if (buf->skipped >= atomic_read(&s->q_busy.depth)-1) { /* buffer must have fallen out of rotation */ CX18_WARN("Skipped %s, buffer %d, %d " "times - it must have dropped out of " @@ -121,7 +121,7 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id, buf->skipped); /* Sweep it up to put it back into rotation */ list_move_tail(&buf->list, &sweep_up); - atomic_dec(&s->q_busy.buffers); + atomic_dec(&s->q_busy.depth); } continue; } @@ -130,7 +130,7 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id, * will have to put it back on a queue later. */ list_del_init(&buf->list); - atomic_dec(&s->q_busy.buffers); + atomic_dec(&s->q_busy.depth); ret = buf; break; } @@ -170,7 +170,7 @@ static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q) buf = list_first_entry(&q->list, struct cx18_buffer, list); list_move_tail(&buf->list, &s->q_free.list); buf->bytesused = buf->readpos = buf->b_flags = buf->skipped = 0; - atomic_inc(&s->q_free.buffers); + atomic_inc(&s->q_free.depth); } cx18_queue_init(q); spin_unlock(&q->lock); diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 7df513a2dba..10228c5ca5a 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c @@ -470,8 +470,8 @@ void _cx18_stream_load_fw_queue(struct cx18_stream *s) struct cx18_queue *q; struct cx18_buffer *buf; - if (atomic_read(&s->q_free.buffers) == 0 || - atomic_read(&s->q_busy.buffers) >= CX18_MAX_FW_MDLS_PER_STREAM) + if (atomic_read(&s->q_free.depth) == 0 || + atomic_read(&s->q_busy.depth) >= CX18_MAX_FW_MDLS_PER_STREAM) return; /* Move from q_free to q_busy notifying the firmware, until the limit */ @@ -480,7 +480,7 @@ void _cx18_stream_load_fw_queue(struct cx18_stream *s) if (buf == NULL) break; q = _cx18_stream_put_buf_fw(s, buf); - } while (atomic_read(&s->q_busy.buffers) < CX18_MAX_FW_MDLS_PER_STREAM + } while (atomic_read(&s->q_busy.depth) < CX18_MAX_FW_MDLS_PER_STREAM && q == &s->q_busy); } -- cgit v1.2.3-70-g09d2 From fa655dda5ce6e5ac4a9b94fd451358edca2ddab8 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Thu, 5 Nov 2009 21:51:24 -0300 Subject: V4L/DVB (13428): cx18: Rename mdl_offset to mdl_base_idx or free_mdl_idx as appropriate Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-driver.h | 4 ++-- drivers/media/video/cx18/cx18-mailbox.c | 4 ++-- drivers/media/video/cx18/cx18-queue.c | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index 0b182fa2ad0..1a899e0773d 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -337,7 +337,7 @@ struct cx18_stream { const char *name; /* name of the stream */ int type; /* stream type */ u32 handle; /* task handle */ - unsigned mdl_offset; + unsigned int mdl_base_idx; u32 id; unsigned long s_flags; /* status flags, see above */ @@ -514,7 +514,7 @@ struct cx18 { u16 buffer_id; /* buffer ID counter */ u32 v4l2_cap; /* V4L2 capabilities of card */ u32 hw_flags; /* Hardware description of the board */ - unsigned mdl_offset; + unsigned int free_mdl_idx; struct cx18_scb __iomem *scb; /* pointer to SCB */ struct mutex epu2apu_mb_lock; /* protect driver to chip mailbox in SCB*/ struct mutex epu2cpu_mb_lock; /* protect driver to chip mailbox in SCB*/ diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c index afe46c3d405..4a1249a7d46 100644 --- a/drivers/media/video/cx18/cx18-mailbox.c +++ b/drivers/media/video/cx18/cx18-mailbox.c @@ -178,8 +178,8 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order) * and send them back to q_free for fw rotation eventually. */ if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) && - !(id >= s->mdl_offset && - id < (s->mdl_offset + s->buffers))) { + !(id >= s->mdl_base_idx && + id < (s->mdl_base_idx + s->buffers))) { CX18_WARN("Fell behind! Ignoring stale mailbox with " " inconsistent data. Lost buffer for mailbox " "seq no %d\n", mb->request); diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c index bc4c5e4a6c0..b9bd4ff5535 100644 --- a/drivers/media/video/cx18/cx18-queue.c +++ b/drivers/media/video/cx18/cx18-queue.c @@ -194,7 +194,7 @@ int cx18_stream_alloc(struct cx18_stream *s) s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024); - if (((char __iomem *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] - + if (((char __iomem *)&cx->scb->cpu_mdl[cx->free_mdl_idx + s->buffers] - (char __iomem *)cx->scb) > SCB_RESERVED_SIZE) { unsigned bufsz = (((char __iomem *)cx->scb) + SCB_RESERVED_SIZE - ((char __iomem *)cx->scb->cpu_mdl)); @@ -205,7 +205,7 @@ int cx18_stream_alloc(struct cx18_stream *s) return -ENOMEM; } - s->mdl_offset = cx->mdl_offset; + s->mdl_base_idx = cx->free_mdl_idx; /* allocate stream buffers. Initially all buffers are in q_free. */ for (i = 0; i < s->buffers; i++) { @@ -227,7 +227,7 @@ int cx18_stream_alloc(struct cx18_stream *s) cx18_enqueue(s, buf, &s->q_free); } if (i == s->buffers) { - cx->mdl_offset += s->buffers; + cx->free_mdl_idx += s->buffers; return 0; } CX18_ERR("Couldn't allocate buffers for %s stream\n", s->name); -- cgit v1.2.3-70-g09d2 From 52fcb3ecc6707f52dfe4297f96b7609d4ba517fb Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 8 Nov 2009 23:45:24 -0300 Subject: V4L/DVB (13429): cx18: Add Memory Descriptor List (MDL) layer to buffer handling Add a Memory Descriptor List (MDL) layer to buffer handling to implement scatter-gather I/O. Currently there is still only 1 buffer per MDL. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-driver.c | 6 + drivers/media/video/cx18/cx18-driver.h | 45 +++-- drivers/media/video/cx18/cx18-fileops.c | 128 +++++++++---- drivers/media/video/cx18/cx18-ioctl.c | 3 +- drivers/media/video/cx18/cx18-mailbox.c | 58 ++++-- drivers/media/video/cx18/cx18-mailbox.h | 6 +- drivers/media/video/cx18/cx18-queue.c | 316 +++++++++++++++++++++++++------- drivers/media/video/cx18/cx18-queue.h | 54 +++++- drivers/media/video/cx18/cx18-streams.c | 50 ++--- drivers/media/video/cx18/cx18-streams.h | 10 +- drivers/media/video/cx18/cx18-vbi.c | 35 +++- drivers/media/video/cx18/cx18-vbi.h | 2 +- 12 files changed, 540 insertions(+), 173 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index e12082b8a08..ba4c3ceffbb 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -669,6 +669,12 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced; + /* IVTV style VBI insertion into MPEG streams */ + INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_buf.list); + INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_mdl.list); + INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_mdl.buf_list); + list_add(&cx->vbi.sliced_mpeg_buf.list, + &cx->vbi.sliced_mpeg_mdl.buf_list); return 0; } diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index 1a899e0773d..bed8bcc6541 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -246,8 +246,8 @@ struct cx18_options { int radio; /* enable/disable radio */ }; -/* per-buffer bit flags */ -#define CX18_F_B_NEED_BUF_SWAP 0 /* this buffer should be byte swapped */ +/* per-mdl bit flags */ +#define CX18_F_M_NEED_SWAP 0 /* mdl buffer data must be endianess swapped */ /* per-stream, s_flags */ #define CX18_F_S_CLAIMED 3 /* this stream is claimed */ @@ -274,15 +274,26 @@ struct cx18_options { struct cx18_buffer { struct list_head list; dma_addr_t dma_handle; - u32 id; - unsigned long b_flags; - unsigned skipped; char *buf; u32 bytesused; u32 readpos; }; +struct cx18_mdl { + struct list_head list; + u32 id; /* index into cx->scb->cpu_mdl[] of 1st cx18_mdl_ent */ + + unsigned int skipped; + unsigned long m_flags; + + struct list_head buf_list; + struct cx18_buffer *curr_buf; /* current buffer in list for reading */ + + u32 bytesused; + u32 readpos; +}; + struct cx18_queue { struct list_head list; atomic_t depth; @@ -346,14 +357,20 @@ struct cx18_stream { PCI_DMA_NONE */ wait_queue_head_t waitq; - /* Buffer Stats */ - u32 buffers; - u32 buf_size; + /* Buffers */ + struct list_head buf_pool; /* buffers not attached to an MDL */ + u32 buffers; /* total buffers owned by this stream */ + u32 buf_size; /* size in bytes of a single buffer */ + + /* MDL sizes - all stream MDLs are the same size */ + u32 bufs_per_mdl; + u32 mdl_size; /* total bytes in all buffers in a mdl */ - /* Buffer Queues */ - struct cx18_queue q_free; /* free buffers */ - struct cx18_queue q_busy; /* busy buffers - in use by firmware */ - struct cx18_queue q_full; /* full buffers - data for user apps */ + /* MDL Queues */ + struct cx18_queue q_free; /* free - in rotation, not committed */ + struct cx18_queue q_busy; /* busy - in use by firmware */ + struct cx18_queue q_full; /* full - data for user apps */ + struct cx18_queue q_idle; /* idle - not in rotation */ struct work_struct out_work_order; @@ -481,10 +498,11 @@ struct vbi_info { u32 inserted_frame; /* - * A dummy driver stream transfer buffer with a copy of the next + * A dummy driver stream transfer mdl & buffer with a copy of the next * sliced_mpeg_data[] buffer for output to userland apps. * Only used in cx18-fileops.c, but its state needs to persist at times. */ + struct cx18_mdl sliced_mpeg_mdl; struct cx18_buffer sliced_mpeg_buf; }; @@ -511,7 +529,6 @@ struct cx18 { u8 is_60hz; u8 nof_inputs; /* number of video inputs */ u8 nof_audio_inputs; /* number of audio inputs */ - u16 buffer_id; /* buffer ID counter */ u32 v4l2_cap; /* V4L2 capabilities of card */ u32 hw_flags; /* Hardware description of the board */ unsigned int free_mdl_idx; diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c index e4a3faebff4..4e278db31cc 100644 --- a/drivers/media/video/cx18/cx18-fileops.c +++ b/drivers/media/video/cx18/cx18-fileops.c @@ -166,11 +166,12 @@ static void cx18_dualwatch(struct cx18 *cx) } -static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, int *err) +static struct cx18_mdl *cx18_get_mdl(struct cx18_stream *s, int non_block, + int *err) { struct cx18 *cx = s->cx; struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI]; - struct cx18_buffer *buf; + struct cx18_mdl *mdl; DEFINE_WAIT(wait); *err = 0; @@ -185,32 +186,33 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, } if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) && !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) { - while ((buf = cx18_dequeue(s_vbi, &s_vbi->q_full))) { + while ((mdl = cx18_dequeue(s_vbi, + &s_vbi->q_full))) { /* byteswap and process VBI data */ - cx18_process_vbi_data(cx, buf, + cx18_process_vbi_data(cx, mdl, s_vbi->type); - cx18_stream_put_buf_fw(s_vbi, buf); + cx18_stream_put_mdl_fw(s_vbi, mdl); } } - buf = &cx->vbi.sliced_mpeg_buf; - if (buf->readpos != buf->bytesused) - return buf; + mdl = &cx->vbi.sliced_mpeg_mdl; + if (mdl->readpos != mdl->bytesused) + return mdl; } /* do we have new data? */ - buf = cx18_dequeue(s, &s->q_full); - if (buf) { - if (!test_and_clear_bit(CX18_F_B_NEED_BUF_SWAP, - &buf->b_flags)) - return buf; + mdl = cx18_dequeue(s, &s->q_full); + if (mdl) { + if (!test_and_clear_bit(CX18_F_M_NEED_SWAP, + &mdl->m_flags)) + return mdl; if (s->type == CX18_ENC_STREAM_TYPE_MPG) /* byteswap MPG data */ - cx18_buf_swap(buf); + cx18_mdl_swap(mdl); else { /* byteswap and process VBI data */ - cx18_process_vbi_data(cx, buf, s->type); + cx18_process_vbi_data(cx, mdl, s->type); } - return buf; + return mdl; } /* return if end of stream */ @@ -241,21 +243,28 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, } } -static void cx18_setup_sliced_vbi_buf(struct cx18 *cx) +static void cx18_setup_sliced_vbi_mdl(struct cx18 *cx) { + struct cx18_mdl *mdl = &cx->vbi.sliced_mpeg_mdl; + struct cx18_buffer *buf = &cx->vbi.sliced_mpeg_buf; int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES; - cx->vbi.sliced_mpeg_buf.buf = cx->vbi.sliced_mpeg_data[idx]; - cx->vbi.sliced_mpeg_buf.bytesused = cx->vbi.sliced_mpeg_size[idx]; - cx->vbi.sliced_mpeg_buf.readpos = 0; + buf->buf = cx->vbi.sliced_mpeg_data[idx]; + buf->bytesused = cx->vbi.sliced_mpeg_size[idx]; + buf->readpos = 0; + + mdl->curr_buf = NULL; + mdl->bytesused = cx->vbi.sliced_mpeg_size[idx]; + mdl->readpos = 0; } static size_t cx18_copy_buf_to_user(struct cx18_stream *s, - struct cx18_buffer *buf, char __user *ubuf, size_t ucount) + struct cx18_buffer *buf, char __user *ubuf, size_t ucount, bool *stop) { struct cx18 *cx = s->cx; size_t len = buf->bytesused - buf->readpos; + *stop = false; if (len > ucount) len = ucount; if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG && @@ -335,7 +344,8 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s, /* We declare we actually found a Program Pack*/ cx->search_pack_header = 0; /* expect vid PES */ len = (char *)q - start; - cx18_setup_sliced_vbi_buf(cx); + cx18_setup_sliced_vbi_mdl(cx); + *stop = true; break; } } @@ -352,6 +362,60 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s, return len; } +/** + * list_entry_is_past_end - check if a previous loop cursor is off list end + * @pos: the type * previously used as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Check if the entry's list_head is the head of the list, thus it's not a + * real entry but was the loop cursor that walked past the end + */ +#define list_entry_is_past_end(pos, head, member) \ + (&pos->member == (head)) + +static size_t cx18_copy_mdl_to_user(struct cx18_stream *s, + struct cx18_mdl *mdl, char __user *ubuf, size_t ucount) +{ + size_t tot_written = 0; + int rc; + bool stop = false; + + if (mdl->curr_buf == NULL) + mdl->curr_buf = list_first_entry(&mdl->buf_list, + struct cx18_buffer, list); + + if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) { + /* + * For some reason we've exhausted the buffers, but the MDL + * object still said some data was unread. + * Fix that and bail out. + */ + mdl->readpos = mdl->bytesused; + return 0; + } + + list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) { + + if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused) + continue; + + rc = cx18_copy_buf_to_user(s, mdl->curr_buf, ubuf + tot_written, + ucount - tot_written, &stop); + if (rc < 0) + return rc; + mdl->readpos += rc; + tot_written += rc; + + if (stop || /* Forced stopping point for VBI insertion */ + tot_written >= ucount || /* Reader request statisfied */ + mdl->curr_buf->readpos < mdl->curr_buf->bytesused || + mdl->readpos >= mdl->bytesused) /* MDL buffers drained */ + break; + } + return tot_written; +} + static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf, size_t tot_count, int non_block) { @@ -373,12 +437,12 @@ static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf, single_frame = 1; for (;;) { - struct cx18_buffer *buf; + struct cx18_mdl *mdl; int rc; - buf = cx18_get_buffer(s, non_block, &rc); + mdl = cx18_get_mdl(s, non_block, &rc); /* if there is no data available... */ - if (buf == NULL) { + if (mdl == NULL) { /* if we got data, then return that regardless */ if (tot_written) break; @@ -392,20 +456,20 @@ static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf, return rc; } - rc = cx18_copy_buf_to_user(s, buf, ubuf + tot_written, + rc = cx18_copy_mdl_to_user(s, mdl, ubuf + tot_written, tot_count - tot_written); - if (buf != &cx->vbi.sliced_mpeg_buf) { - if (buf->readpos == buf->bytesused) - cx18_stream_put_buf_fw(s, buf); + if (mdl != &cx->vbi.sliced_mpeg_mdl) { + if (mdl->readpos == mdl->bytesused) + cx18_stream_put_mdl_fw(s, mdl); else - cx18_push(s, buf, &s->q_full); - } else if (buf->readpos == buf->bytesused) { + cx18_push(s, mdl, &s->q_full); + } else if (mdl->readpos == mdl->bytesused) { int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES; cx->vbi.sliced_mpeg_size[idx] = 0; cx->vbi.inserted_frame++; - cx->vbi_data_inserted += buf->bytesused; + cx->vbi_data_inserted += mdl->bytesused; } if (rc < 0) return rc; diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 6539b031b4e..3e4fc192fde 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -910,7 +910,8 @@ static int cx18_log_status(struct file *file, void *fh) continue; CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, - atomic_read(&s->q_full.depth) * 100 / s->buffers, + atomic_read(&s->q_full.depth) * s->bufs_per_mdl * 100 + / s->buffers, (s->buffers * s->buf_size) / 1024, s->buffers); } CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n", diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c index 4a1249a7d46..f231dd09c72 100644 --- a/drivers/media/video/cx18/cx18-mailbox.c +++ b/drivers/media/video/cx18/cx18-mailbox.c @@ -131,13 +131,39 @@ static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name) * Functions that run in a work_queue work handling context */ +static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl) +{ + struct cx18_buffer *buf; + + if (!s->dvb.enabled || mdl->bytesused == 0) + return; + + /* We ignore mdl and buf readpos accounting here - it doesn't matter */ + + /* The likely case */ + if (list_is_singular(&mdl->buf_list)) { + buf = list_first_entry(&mdl->buf_list, struct cx18_buffer, + list); + if (buf->bytesused) + dvb_dmx_swfilter(&s->dvb.demux, + buf->buf, buf->bytesused); + return; + } + + list_for_each_entry(buf, &mdl->buf_list, list) { + if (buf->bytesused == 0) + break; + dvb_dmx_swfilter(&s->dvb.demux, buf->buf, buf->bytesused); + } +} + static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order) { u32 handle, mdl_ack_count, id; struct cx18_mailbox *mb; struct cx18_mdl_ack *mdl_ack; struct cx18_stream *s; - struct cx18_buffer *buf; + struct cx18_mdl *mdl; int i; mb = &order->mb; @@ -158,7 +184,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order) id = mdl_ack->id; /* * Simple integrity check for processing a stale (and possibly - * inconsistent mailbox): make sure the buffer id is in the + * inconsistent mailbox): make sure the MDL id is in the * valid range for the stream. * * We go through the trouble of dealing with stale mailboxes @@ -169,44 +195,42 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order) * There are occasions when we get a half changed mailbox, * which this check catches for a handle & id mismatch. If the * handle and id do correspond, the worst case is that we - * completely lost the old buffer, but pick up the new buffer + * completely lost the old MDL, but pick up the new MDL * early (but the new mdl_ack is guaranteed to be good in this * case as the firmware wouldn't point us to a new mdl_ack until * it's filled in). * - * cx18_queue_get buf() will detect the lost buffers + * cx18_queue_get_mdl() will detect the lost MDLs * and send them back to q_free for fw rotation eventually. */ if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) && !(id >= s->mdl_base_idx && id < (s->mdl_base_idx + s->buffers))) { CX18_WARN("Fell behind! Ignoring stale mailbox with " - " inconsistent data. Lost buffer for mailbox " + " inconsistent data. Lost MDL for mailbox " "seq no %d\n", mb->request); break; } - buf = cx18_queue_get_buf(s, id, mdl_ack->data_used); + mdl = cx18_queue_get_mdl(s, id, mdl_ack->data_used); - CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id); - if (buf == NULL) { - CX18_WARN("Could not find buf %d for stream %s\n", + CX18_DEBUG_HI_DMA("DMA DONE for %s (MDL %d)\n", s->name, id); + if (mdl == NULL) { + CX18_WARN("Could not find MDL %d for stream %s\n", id, s->name); continue; } CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n", - s->name, buf->bytesused); + s->name, mdl->bytesused); if (s->type != CX18_ENC_STREAM_TYPE_TS) - cx18_enqueue(s, buf, &s->q_full); + cx18_enqueue(s, mdl, &s->q_full); else { - if (s->dvb.enabled) - dvb_dmx_swfilter(&s->dvb.demux, buf->buf, - buf->bytesused); - cx18_enqueue(s, buf, &s->q_free); + cx18_mdl_send_to_dvb(s, mdl); + cx18_enqueue(s, mdl, &s->q_free); } } - /* Put as many buffers as possible back into fw use */ + /* Put as many MDLs as possible back into fw use */ cx18_stream_load_fw_queue(s); wake_up(&cx->dma_waitq); @@ -616,7 +640,7 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) /* * Wait for XPU to perform extra actions for the caller in some cases. - * e.g. CX18_CPU_DE_RELEASE_MDL will cause the CPU to send all buffers + * e.g. CX18_CPU_DE_RELEASE_MDL will cause the CPU to send all MDLs * back in a burst shortly thereafter */ if (info->flags & API_SLOW) diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h index e23aaac5b28..5ea07359904 100644 --- a/drivers/media/video/cx18/cx18-mailbox.h +++ b/drivers/media/video/cx18/cx18-mailbox.h @@ -39,14 +39,14 @@ struct cx18; /* - * This structure is used by CPU to provide completed buffers information - * Its structure is dictrated by the layout of the SCB, required by the + * This structure is used by CPU to provide completed MDL & buffers information. + * Its structure is dictated by the layout of the SCB, required by the * firmware, but its defintion needs to be here, instead of in cx18-scb.h, * for mailbox work order scheduling */ struct cx18_mdl_ack { u32 id; /* ID of a completed MDL */ - u32 data_used; /* Total data filled in the MDL for buffer 'id' */ + u32 data_used; /* Total data filled in the MDL with 'id' */ }; /* The cx18_mailbox struct is the mailbox structure which is used for passing diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c index b9bd4ff5535..c1a49ecf9d9 100644 --- a/drivers/media/video/cx18/cx18-queue.c +++ b/drivers/media/video/cx18/cx18-queue.c @@ -26,6 +26,7 @@ #include "cx18-queue.h" #include "cx18-streams.h" #include "cx18-scb.h" +#include "cx18-io.h" void cx18_buf_swap(struct cx18_buffer *buf) { @@ -35,6 +36,17 @@ void cx18_buf_swap(struct cx18_buffer *buf) swab32s((u32 *)(buf->buf + i)); } +void _cx18_mdl_swap(struct cx18_mdl *mdl) +{ + struct cx18_buffer *buf; + + list_for_each_entry(buf, &mdl->buf_list, list) { + if (buf->bytesused == 0) + break; + cx18_buf_swap(buf); + } +} + void cx18_queue_init(struct cx18_queue *q) { INIT_LIST_HEAD(&q->list); @@ -42,15 +54,16 @@ void cx18_queue_init(struct cx18_queue *q) q->bytesused = 0; } -struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, +struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl, struct cx18_queue *q, int to_front) { - /* clear the buffer if it is not to be enqueued to the full queue */ + /* clear the mdl if it is not to be enqueued to the full queue */ if (q != &s->q_full) { - buf->bytesused = 0; - buf->readpos = 0; - buf->b_flags = 0; - buf->skipped = 0; + mdl->bytesused = 0; + mdl->readpos = 0; + mdl->m_flags = 0; + mdl->skipped = 0; + mdl->curr_buf = NULL; } /* q_busy is restricted to a max buffer count imposed by firmware */ @@ -61,125 +74,270 @@ struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, spin_lock(&q->lock); if (to_front) - list_add(&buf->list, &q->list); /* LIFO */ + list_add(&mdl->list, &q->list); /* LIFO */ else - list_add_tail(&buf->list, &q->list); /* FIFO */ - q->bytesused += buf->bytesused - buf->readpos; + list_add_tail(&mdl->list, &q->list); /* FIFO */ + q->bytesused += mdl->bytesused - mdl->readpos; atomic_inc(&q->depth); spin_unlock(&q->lock); return q; } -struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) +struct cx18_mdl *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) { - struct cx18_buffer *buf = NULL; + struct cx18_mdl *mdl = NULL; spin_lock(&q->lock); if (!list_empty(&q->list)) { - buf = list_first_entry(&q->list, struct cx18_buffer, list); - list_del_init(&buf->list); - q->bytesused -= buf->bytesused - buf->readpos; - buf->skipped = 0; + mdl = list_first_entry(&q->list, struct cx18_mdl, list); + list_del_init(&mdl->list); + q->bytesused -= mdl->bytesused - mdl->readpos; + mdl->skipped = 0; atomic_dec(&q->depth); } spin_unlock(&q->lock); - return buf; + return mdl; +} + +static void _cx18_mdl_set_buf_bytesused(struct cx18_stream *s, + struct cx18_mdl *mdl) +{ + struct cx18_buffer *buf; + u32 buf_size = s->buf_size; + u32 bytesused = mdl->bytesused; + + list_for_each_entry(buf, &mdl->buf_list, list) { + buf->readpos = 0; + if (bytesused >= buf_size) { + buf->bytesused = buf_size; + bytesused -= buf_size; + } else { + buf->bytesused = bytesused; + bytesused = 0; + } + } } -struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id, +static inline void cx18_mdl_set_buf_bytesused(struct cx18_stream *s, + struct cx18_mdl *mdl) +{ + struct cx18_buffer *buf; + + if (list_is_singular(&mdl->buf_list)) { + buf = list_first_entry(&mdl->buf_list, struct cx18_buffer, + list); + buf->bytesused = mdl->bytesused; + buf->readpos = 0; + } else { + _cx18_mdl_set_buf_bytesused(s, mdl); + } +} + +struct cx18_mdl *cx18_queue_get_mdl(struct cx18_stream *s, u32 id, u32 bytesused) { struct cx18 *cx = s->cx; - struct cx18_buffer *buf; - struct cx18_buffer *tmp; - struct cx18_buffer *ret = NULL; + struct cx18_mdl *mdl; + struct cx18_mdl *tmp; + struct cx18_mdl *ret = NULL; LIST_HEAD(sweep_up); /* * We don't have to acquire multiple q locks here, because we are * serialized by the single threaded work handler. - * Buffers from the firmware will thus remain in order as + * MDLs from the firmware will thus remain in order as * they are moved from q_busy to q_full or to the dvb ring buffer. */ spin_lock(&s->q_busy.lock); - list_for_each_entry_safe(buf, tmp, &s->q_busy.list, list) { + list_for_each_entry_safe(mdl, tmp, &s->q_busy.list, list) { /* * We should find what the firmware told us is done, * right at the front of the queue. If we don't, we likely have - * missed a buffer done message from the firmware. - * Once we skip a buffer repeatedly, relative to the size of + * missed an mdl done message from the firmware. + * Once we skip an mdl repeatedly, relative to the size of * q_busy, we have high confidence we've missed it. */ - if (buf->id != id) { - buf->skipped++; - if (buf->skipped >= atomic_read(&s->q_busy.depth)-1) { - /* buffer must have fallen out of rotation */ - CX18_WARN("Skipped %s, buffer %d, %d " + if (mdl->id != id) { + mdl->skipped++; + if (mdl->skipped >= atomic_read(&s->q_busy.depth)-1) { + /* mdl must have fallen out of rotation */ + CX18_WARN("Skipped %s, MDL %d, %d " "times - it must have dropped out of " - "rotation\n", s->name, buf->id, - buf->skipped); + "rotation\n", s->name, mdl->id, + mdl->skipped); /* Sweep it up to put it back into rotation */ - list_move_tail(&buf->list, &sweep_up); + list_move_tail(&mdl->list, &sweep_up); atomic_dec(&s->q_busy.depth); } continue; } /* - * We pull the desired buffer off of the queue here. Something + * We pull the desired mdl off of the queue here. Something * will have to put it back on a queue later. */ - list_del_init(&buf->list); + list_del_init(&mdl->list); atomic_dec(&s->q_busy.depth); - ret = buf; + ret = mdl; break; } spin_unlock(&s->q_busy.lock); /* - * We found the buffer for which we were looking. Get it ready for + * We found the mdl for which we were looking. Get it ready for * the caller to put on q_full or in the dvb ring buffer. */ if (ret != NULL) { ret->bytesused = bytesused; ret->skipped = 0; - /* readpos and b_flags were 0'ed when the buf went on q_busy */ - cx18_buf_sync_for_cpu(s, ret); + /* 0'ed readpos, m_flags & curr_buf when mdl went on q_busy */ + cx18_mdl_set_buf_bytesused(s, ret); + cx18_mdl_sync_for_cpu(s, ret); if (s->type != CX18_ENC_STREAM_TYPE_TS) - set_bit(CX18_F_B_NEED_BUF_SWAP, &ret->b_flags); + set_bit(CX18_F_M_NEED_SWAP, &ret->m_flags); } - /* Put any buffers the firmware is ignoring back into normal rotation */ - list_for_each_entry_safe(buf, tmp, &sweep_up, list) { - list_del_init(&buf->list); - cx18_enqueue(s, buf, &s->q_free); + /* Put any mdls the firmware is ignoring back into normal rotation */ + list_for_each_entry_safe(mdl, tmp, &sweep_up, list) { + list_del_init(&mdl->list); + cx18_enqueue(s, mdl, &s->q_free); } return ret; } -/* Move all buffers of a queue to q_free, while flushing the buffers */ -static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q) +/* Move all mdls of a queue, while flushing the mdl */ +static void cx18_queue_flush(struct cx18_stream *s, + struct cx18_queue *q_src, struct cx18_queue *q_dst) { - struct cx18_buffer *buf; + struct cx18_mdl *mdl; - if (q == &s->q_free) + /* It only makes sense to flush to q_free or q_idle */ + if (q_src == q_dst || q_dst == &s->q_full || q_dst == &s->q_busy) return; - spin_lock(&q->lock); - while (!list_empty(&q->list)) { - buf = list_first_entry(&q->list, struct cx18_buffer, list); - list_move_tail(&buf->list, &s->q_free.list); - buf->bytesused = buf->readpos = buf->b_flags = buf->skipped = 0; - atomic_inc(&s->q_free.depth); + spin_lock(&q_src->lock); + spin_lock(&q_dst->lock); + while (!list_empty(&q_src->list)) { + mdl = list_first_entry(&q_src->list, struct cx18_mdl, list); + list_move_tail(&mdl->list, &q_dst->list); + mdl->bytesused = 0; + mdl->readpos = 0; + mdl->m_flags = 0; + mdl->skipped = 0; + mdl->curr_buf = NULL; + atomic_inc(&q_dst->depth); } - cx18_queue_init(q); - spin_unlock(&q->lock); + cx18_queue_init(q_src); + spin_unlock(&q_src->lock); + spin_unlock(&q_dst->lock); } void cx18_flush_queues(struct cx18_stream *s) { - cx18_queue_flush(s, &s->q_busy); - cx18_queue_flush(s, &s->q_full); + cx18_queue_flush(s, &s->q_busy, &s->q_free); + cx18_queue_flush(s, &s->q_full, &s->q_free); +} + +/* + * Note, s->buf_pool is not protected by a lock, + * the stream better not have *anything* going on when calling this + */ +void cx18_unload_queues(struct cx18_stream *s) +{ + struct cx18_queue *q_idle = &s->q_idle; + struct cx18_mdl *mdl; + struct cx18_buffer *buf; + + /* Move all MDLS to q_idle */ + cx18_queue_flush(s, &s->q_busy, q_idle); + cx18_queue_flush(s, &s->q_full, q_idle); + cx18_queue_flush(s, &s->q_free, q_idle); + + /* Reset MDL id's and move all buffers back to the stream's buf_pool */ + spin_lock(&q_idle->lock); + list_for_each_entry(mdl, &q_idle->list, list) { + while (!list_empty(&mdl->buf_list)) { + buf = list_first_entry(&mdl->buf_list, + struct cx18_buffer, list); + list_move_tail(&buf->list, &s->buf_pool); + buf->bytesused = 0; + buf->readpos = 0; + } + mdl->id = s->mdl_base_idx; /* reset id to a "safe" value */ + /* all other mdl fields were cleared by cx18_queue_flush() */ + } + spin_unlock(&q_idle->lock); +} + +/* + * Note, s->buf_pool is not protected by a lock, + * the stream better not have *anything* going on when calling this + */ +void cx18_load_queues(struct cx18_stream *s) +{ + struct cx18 *cx = s->cx; + struct cx18_mdl *mdl; + struct cx18_buffer *buf; + int mdl_id; + int i; + + /* + * Attach buffers to MDLs, give the MDLs ids, and add MDLs to q_free + * Excess MDLs are left on q_idle + * Excess buffers are left in buf_pool and/or on an MDL in q_idle + */ + mdl_id = s->mdl_base_idx; + for (mdl = cx18_dequeue(s, &s->q_idle), i = s->bufs_per_mdl; + mdl != NULL && i == s->bufs_per_mdl; + mdl = cx18_dequeue(s, &s->q_idle)) { + + mdl->id = mdl_id; + + for (i = 0; i < s->bufs_per_mdl; i++) { + if (list_empty(&s->buf_pool)) + break; + + buf = list_first_entry(&s->buf_pool, struct cx18_buffer, + list); + list_move_tail(&buf->list, &mdl->buf_list); + + /* update the firmware's MDL array with this buffer */ + cx18_writel(cx, buf->dma_handle, + &cx->scb->cpu_mdl[mdl_id + i].paddr); + cx18_writel(cx, s->buf_size, + &cx->scb->cpu_mdl[mdl_id + i].length); + } + + if (i == s->bufs_per_mdl) + cx18_enqueue(s, mdl, &s->q_free); + else + cx18_push(s, mdl, &s->q_idle); /* not enough buffers */ + mdl_id += i; + } +} + +void _cx18_mdl_sync_for_cpu(struct cx18_stream *s, struct cx18_mdl *mdl) +{ + int dma = s->dma; + u32 buf_size = s->buf_size; + struct pci_dev *pci_dev = s->cx->pci_dev; + struct cx18_buffer *buf; + + list_for_each_entry(buf, &mdl->buf_list, list) + pci_dma_sync_single_for_cpu(pci_dev, buf->dma_handle, + buf_size, dma); +} + +void _cx18_mdl_sync_for_device(struct cx18_stream *s, struct cx18_mdl *mdl) +{ + int dma = s->dma; + u32 buf_size = s->buf_size; + struct pci_dev *pci_dev = s->cx->pci_dev; + struct cx18_buffer *buf; + + list_for_each_entry(buf, &mdl->buf_list, list) + pci_dma_sync_single_for_device(pci_dev, buf->dma_handle, + buf_size, dma); } int cx18_stream_alloc(struct cx18_stream *s) @@ -207,24 +365,40 @@ int cx18_stream_alloc(struct cx18_stream *s) s->mdl_base_idx = cx->free_mdl_idx; - /* allocate stream buffers. Initially all buffers are in q_free. */ + /* allocate stream buffers and MDLs */ for (i = 0; i < s->buffers; i++) { - struct cx18_buffer *buf = kzalloc(sizeof(struct cx18_buffer), - GFP_KERNEL|__GFP_NOWARN); + struct cx18_mdl *mdl; + struct cx18_buffer *buf; - if (buf == NULL) + /* 1 MDL per buffer to handle the worst & also default case */ + mdl = kzalloc(sizeof(struct cx18_mdl), GFP_KERNEL|__GFP_NOWARN); + if (mdl == NULL) break; + + buf = kzalloc(sizeof(struct cx18_buffer), + GFP_KERNEL|__GFP_NOWARN); + if (buf == NULL) { + kfree(mdl); + break; + } + buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN); if (buf->buf == NULL) { + kfree(mdl); kfree(buf); break; } - buf->id = cx->buffer_id++; + + INIT_LIST_HEAD(&mdl->list); + INIT_LIST_HEAD(&mdl->buf_list); + mdl->id = s->mdl_base_idx; /* a somewhat safe value */ + cx18_enqueue(s, mdl, &s->q_idle); + INIT_LIST_HEAD(&buf->list); buf->dma_handle = pci_map_single(s->cx->pci_dev, buf->buf, s->buf_size, s->dma); cx18_buf_sync_for_cpu(s, buf); - cx18_enqueue(s, buf, &s->q_free); + list_add_tail(&buf->list, &s->buf_pool); } if (i == s->buffers) { cx->free_mdl_idx += s->buffers; @@ -237,13 +411,21 @@ int cx18_stream_alloc(struct cx18_stream *s) void cx18_stream_free(struct cx18_stream *s) { + struct cx18_mdl *mdl; struct cx18_buffer *buf; - /* move all buffers to q_free */ - cx18_flush_queues(s); + /* move all buffers to buf_pool and all MDLs to q_idle */ + cx18_unload_queues(s); + + /* empty q_idle */ + while ((mdl = cx18_dequeue(s, &s->q_idle))) + kfree(mdl); + + /* empty buf_pool */ + while (!list_empty(&s->buf_pool)) { + buf = list_first_entry(&s->buf_pool, struct cx18_buffer, list); + list_del_init(&buf->list); - /* empty q_free */ - while ((buf = cx18_dequeue(s, &s->q_free))) { pci_unmap_single(s->cx->pci_dev, buf->dma_handle, s->buf_size, s->dma); kfree(buf->buf); diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h index 4de06269d88..96747e5e7c3 100644 --- a/drivers/media/video/cx18/cx18-queue.h +++ b/drivers/media/video/cx18/cx18-queue.h @@ -33,6 +33,19 @@ static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s, s->buf_size, s->dma); } +void _cx18_mdl_sync_for_cpu(struct cx18_stream *s, struct cx18_mdl *mdl); + +static inline void cx18_mdl_sync_for_cpu(struct cx18_stream *s, + struct cx18_mdl *mdl) +{ + if (list_is_singular(&mdl->buf_list)) + cx18_buf_sync_for_cpu(s, list_first_entry(&mdl->buf_list, + struct cx18_buffer, + list)); + else + _cx18_mdl_sync_for_cpu(s, mdl); +} + static inline void cx18_buf_sync_for_device(struct cx18_stream *s, struct cx18_buffer *buf) { @@ -40,32 +53,59 @@ static inline void cx18_buf_sync_for_device(struct cx18_stream *s, s->buf_size, s->dma); } +void _cx18_mdl_sync_for_device(struct cx18_stream *s, struct cx18_mdl *mdl); + +static inline void cx18_mdl_sync_for_device(struct cx18_stream *s, + struct cx18_mdl *mdl) +{ + if (list_is_singular(&mdl->buf_list)) + cx18_buf_sync_for_device(s, list_first_entry(&mdl->buf_list, + struct cx18_buffer, + list)); + else + _cx18_mdl_sync_for_device(s, mdl); +} + void cx18_buf_swap(struct cx18_buffer *buf); +void _cx18_mdl_swap(struct cx18_mdl *mdl); + +static inline void cx18_mdl_swap(struct cx18_mdl *mdl) +{ + if (list_is_singular(&mdl->buf_list)) + cx18_buf_swap(list_first_entry(&mdl->buf_list, + struct cx18_buffer, list)); + else + _cx18_mdl_swap(mdl); +} /* cx18_queue utility functions */ -struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, +struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl, struct cx18_queue *q, int to_front); static inline -struct cx18_queue *cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, +struct cx18_queue *cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl, struct cx18_queue *q) { - return _cx18_enqueue(s, buf, q, 0); /* FIFO */ + return _cx18_enqueue(s, mdl, q, 0); /* FIFO */ } static inline -struct cx18_queue *cx18_push(struct cx18_stream *s, struct cx18_buffer *buf, +struct cx18_queue *cx18_push(struct cx18_stream *s, struct cx18_mdl *mdl, struct cx18_queue *q) { - return _cx18_enqueue(s, buf, q, 1); /* LIFO */ + return _cx18_enqueue(s, mdl, q, 1); /* LIFO */ } void cx18_queue_init(struct cx18_queue *q); -struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q); -struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id, +struct cx18_mdl *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q); +struct cx18_mdl *cx18_queue_get_mdl(struct cx18_stream *s, u32 id, u32 bytesused); void cx18_flush_queues(struct cx18_stream *s); +/* queue MDL reconfiguration helpers */ +void cx18_unload_queues(struct cx18_stream *s); +void cx18_load_queues(struct cx18_stream *s); + /* cx18_stream utility functions */ int cx18_stream_alloc(struct cx18_stream *s); void cx18_stream_free(struct cx18_stream *s); diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 10228c5ca5a..9f8adda6f26 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c @@ -115,6 +115,9 @@ static void cx18_stream_init(struct cx18 *cx, int type) s->dma = cx18_stream_info[type].dma; s->buffers = cx->stream_buffers[type]; s->buf_size = cx->stream_buf_size[type]; + INIT_LIST_HEAD(&s->buf_pool); + s->bufs_per_mdl = 1; + s->mdl_size = s->buf_size * s->bufs_per_mdl; init_waitqueue_head(&s->waitq); s->id = -1; @@ -124,6 +127,8 @@ static void cx18_stream_init(struct cx18 *cx, int type) cx18_queue_init(&s->q_busy); spin_lock_init(&s->q_full.lock); cx18_queue_init(&s->q_full); + spin_lock_init(&s->q_idle.lock); + cx18_queue_init(&s->q_idle); INIT_WORK(&s->out_work_order, cx18_out_work_handler); } @@ -441,8 +446,8 @@ static void cx18_vbi_setup(struct cx18_stream *s) } static -struct cx18_queue *_cx18_stream_put_buf_fw(struct cx18_stream *s, - struct cx18_buffer *buf) +struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s, + struct cx18_mdl *mdl) { struct cx18 *cx = s->cx; struct cx18_queue *q; @@ -451,16 +456,16 @@ struct cx18_queue *_cx18_stream_put_buf_fw(struct cx18_stream *s, if (s->handle == CX18_INVALID_TASK_HANDLE || test_bit(CX18_F_S_STOPPING, &s->s_flags) || !test_bit(CX18_F_S_STREAMING, &s->s_flags)) - return cx18_enqueue(s, buf, &s->q_free); + return cx18_enqueue(s, mdl, &s->q_free); - q = cx18_enqueue(s, buf, &s->q_busy); + q = cx18_enqueue(s, mdl, &s->q_busy); if (q != &s->q_busy) - return q; /* The firmware has the max buffers it can handle */ + return q; /* The firmware has the max MDLs it can handle */ - cx18_buf_sync_for_device(s, buf); + cx18_mdl_sync_for_device(s, mdl); cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, - (void __iomem *) &cx->scb->cpu_mdl[buf->id] - cx->enc_mem, - 1, buf->id, s->buf_size); + (void __iomem *) &cx->scb->cpu_mdl[mdl->id] - cx->enc_mem, + s->bufs_per_mdl, mdl->id, s->mdl_size); return q; } @@ -468,7 +473,7 @@ static void _cx18_stream_load_fw_queue(struct cx18_stream *s) { struct cx18_queue *q; - struct cx18_buffer *buf; + struct cx18_mdl *mdl; if (atomic_read(&s->q_free.depth) == 0 || atomic_read(&s->q_busy.depth) >= CX18_MAX_FW_MDLS_PER_STREAM) @@ -476,10 +481,10 @@ void _cx18_stream_load_fw_queue(struct cx18_stream *s) /* Move from q_free to q_busy notifying the firmware, until the limit */ do { - buf = cx18_dequeue(s, &s->q_free); - if (buf == NULL) + mdl = cx18_dequeue(s, &s->q_free); + if (mdl == NULL) break; - q = _cx18_stream_put_buf_fw(s, buf); + q = _cx18_stream_put_mdl_fw(s, mdl); } while (atomic_read(&s->q_busy.depth) < CX18_MAX_FW_MDLS_PER_STREAM && q == &s->q_busy); } @@ -492,11 +497,21 @@ void cx18_out_work_handler(struct work_struct *work) _cx18_stream_load_fw_queue(s); } +static void cx18_stream_configure_mdls(struct cx18_stream *s) +{ + cx18_unload_queues(s); + + /* For now */ + s->bufs_per_mdl = 1; + s->mdl_size = s->buf_size * s->bufs_per_mdl; + + cx18_load_queues(s); +} + int cx18_start_v4l2_encode_stream(struct cx18_stream *s) { u32 data[MAX_MB_ARGUMENTS]; struct cx18 *cx = s->cx; - struct cx18_buffer *buf; int captype = 0; struct cx18_api_func_private priv; @@ -619,14 +634,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem); /* Init all the cpu_mdls for this stream */ - cx18_flush_queues(s); - spin_lock(&s->q_free.lock); - list_for_each_entry(buf, &s->q_free.list, list) { - cx18_writel(cx, buf->dma_handle, - &cx->scb->cpu_mdl[buf->id].paddr); - cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length); - } - spin_unlock(&s->q_free.lock); + cx18_stream_configure_mdls(s); _cx18_stream_load_fw_queue(s); /* begin_capture */ diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h index 1afc3fd9d82..4a01db5e5a3 100644 --- a/drivers/media/video/cx18/cx18-streams.h +++ b/drivers/media/video/cx18/cx18-streams.h @@ -28,18 +28,18 @@ int cx18_streams_setup(struct cx18 *cx); int cx18_streams_register(struct cx18 *cx); void cx18_streams_cleanup(struct cx18 *cx, int unregister); -/* Related to submission of buffers to firmware */ +/* Related to submission of mdls to firmware */ static inline void cx18_stream_load_fw_queue(struct cx18_stream *s) { struct cx18 *cx = s->cx; queue_work(cx->out_work_queue, &s->out_work_order); } -static inline void cx18_stream_put_buf_fw(struct cx18_stream *s, - struct cx18_buffer *buf) +static inline void cx18_stream_put_mdl_fw(struct cx18_stream *s, + struct cx18_mdl *mdl) { - /* Put buf on q_free; the out work handler will move buf(s) to q_busy */ - cx18_enqueue(s, buf, &s->q_free); + /* Put mdl on q_free; the out work handler will move mdl(s) to q_busy */ + cx18_enqueue(s, mdl, &s->q_free); cx18_stream_load_fw_queue(s); } diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c index c2aef4add31..574c1c6974f 100644 --- a/drivers/media/video/cx18/cx18-vbi.c +++ b/drivers/media/video/cx18/cx18-vbi.c @@ -105,6 +105,7 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp) /* Compress raw VBI format, removes leading SAV codes and surplus space after the frame. Returns new compressed size. */ +/* FIXME - this function ignores the input size. */ static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size, u32 hdr_size) { u32 line_size = vbi_active_samples; @@ -185,8 +186,7 @@ static u32 compress_sliced_buf(struct cx18 *cx, u8 *buf, u32 size, return line; } -void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, - int streamtype) +static void _cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf) { /* * The CX23418 provides a 12 byte header in its raw VBI buffers to us: @@ -203,9 +203,6 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, u32 pts; int lines; - if (streamtype != CX18_ENC_STREAM_TYPE_VBI) - return; - /* * The CX23418 sends us data that is 32 bit little-endian swapped, * but we want the raw VBI bytes in the order they were in the raster @@ -250,3 +247,31 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, copy_vbi_data(cx, lines, pts); cx->vbi.frame++; } + +void cx18_process_vbi_data(struct cx18 *cx, struct cx18_mdl *mdl, + int streamtype) +{ + struct cx18_buffer *buf; + u32 orig_used; + + if (streamtype != CX18_ENC_STREAM_TYPE_VBI) + return; + + /* + * Big assumption here: + * Every buffer hooked to the MDL's buf_list is a complete VBI frame + * that ends at the end of the buffer. + * + * To assume anything else would make the code in this file + * more complex, or require extra memcpy()'s to make the + * buffers satisfy the above assumption. It's just simpler to set + * up the encoder buffer transfers to make the assumption true. + */ + list_for_each_entry(buf, &mdl->buf_list, list) { + orig_used = buf->bytesused; + if (orig_used == 0) + break; + _cx18_process_vbi_data(cx, buf); + mdl->bytesused -= (orig_used - buf->bytesused); + } +} diff --git a/drivers/media/video/cx18/cx18-vbi.h b/drivers/media/video/cx18/cx18-vbi.h index e7e1ae427f3..b365cf4b466 100644 --- a/drivers/media/video/cx18/cx18-vbi.h +++ b/drivers/media/video/cx18/cx18-vbi.h @@ -21,6 +21,6 @@ * 02111-1307 USA */ -void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, +void cx18_process_vbi_data(struct cx18 *cx, struct cx18_mdl *mdl, int streamtype); int cx18_used_line(struct cx18 *cx, int line, int field); -- cgit v1.2.3-70-g09d2 From 22dce188ef3e1e058ceabe3b3072640d7568f764 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Mon, 9 Nov 2009 23:55:30 -0300 Subject: V4L/DVB (13430): cx18: Fix YUV capture so that encoder passes a single frame per transfer Fix YUV capture such that the encoder will pass one frame per transfer. This will allow the application to maintain frame alignment when a transfer from the encoder is missed due to high system latency in service the CX23418 IRQ. Also force YUV buffer sizes to be specified in multiples of 33.75 kB, the smalled amount of buffer sizes need to store a complete set of HM12 4:2:0 macroblocks specifying 32 lines of the frame. A full 60Hz/525 line screen requires 15 * 33.75 kB per frame and a full 50Hz/625 line screen requires 18 * 33.75 kB per frame so the default buffer size is 3 * 33.75 kB, requiring exactly 5 or 6 buffers per MDL respectively. The bytes needed per frame and hence MDL need not be the bytes in an integer number of buffers. However, if frame artifacts are seen with scaled screen sizes, the YUV buffer size can be set 34 kB (33.75 kB) to get rid of the artifacts at the cost of more copies between the kernel and userspace. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-driver.c | 49 +++++++++++++++++++++++++-------- drivers/media/video/cx18/cx18-driver.h | 7 ++++- drivers/media/video/cx18/cx18-dvb.c | 5 ++-- drivers/media/video/cx18/cx18-queue.c | 6 ++-- drivers/media/video/cx18/cx18-streams.c | 26 +++++++++++++---- 5 files changed, 71 insertions(+), 22 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index ba4c3ceffbb..87a735f1ee9 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -211,7 +211,9 @@ MODULE_PARM_DESC(enc_yuv_buffers, "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS)); MODULE_PARM_DESC(enc_yuv_bufsize, "Size of an encoder YUV buffer (kB)\n" - "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFSIZE)); + "\t\t\tAllowed values are multiples of 33.75 kB rounded up\n" + "\t\t\t(multiples of size required for 32 screen lines)\n" + "\t\t\tDefault: 102"); MODULE_PARM_DESC(enc_yuv_bufs, "Number of encoder YUV buffers\n" "\t\t\tDefault is computed from other enc_yuv_* parameters"); @@ -499,10 +501,27 @@ static void cx18_process_options(struct cx18 *cx) continue; } /* + * YUV is a special case where the stream_buf_size needs to be + * an integral multiple of 33.75 kB (storage for 32 screens + * lines to maintain alignment in case of lost buffers + */ + if (i == CX18_ENC_STREAM_TYPE_YUV) { + cx->stream_buf_size[i] *= 1024; + cx->stream_buf_size[i] -= + (cx->stream_buf_size[i] % CX18_UNIT_ENC_YUV_BUFSIZE); + + if (cx->stream_buf_size[i] < CX18_UNIT_ENC_YUV_BUFSIZE) + cx->stream_buf_size[i] = + CX18_UNIT_ENC_YUV_BUFSIZE; + } + /* + * YUV is a special case where the stream_buf_size is + * now in bytes. * VBI is a special case where the stream_buf_size is fixed * and already in bytes */ - if (i == CX18_ENC_STREAM_TYPE_VBI) { + if (i == CX18_ENC_STREAM_TYPE_VBI || + i == CX18_ENC_STREAM_TYPE_YUV) { if (cx->stream_buffers[i] < 0) { cx->stream_buffers[i] = cx->options.megabytes[i] * 1024 * 1024 @@ -513,18 +532,24 @@ static void cx18_process_options(struct cx18 *cx) cx->stream_buffers[i] * cx->stream_buf_size[i]/(1024 * 1024); } - continue; - } - /* All other streams have stream_buf_size in kB at this point */ - if (cx->stream_buffers[i] < 0) { - cx->stream_buffers[i] = cx->options.megabytes[i] * 1024 - / cx->stream_buf_size[i]; } else { - /* N.B. This might round down to 0 */ - cx->options.megabytes[i] = - cx->stream_buffers[i] * cx->stream_buf_size[i] / 1024; + /* All other streams have stream_buf_size in kB here */ + if (cx->stream_buffers[i] < 0) { + cx->stream_buffers[i] = + cx->options.megabytes[i] * 1024 + / cx->stream_buf_size[i]; + } else { + /* N.B. This might round down to 0 */ + cx->options.megabytes[i] = + cx->stream_buffers[i] + * cx->stream_buf_size[i] / 1024; + } + /* convert from kB to bytes */ + cx->stream_buf_size[i] *= 1024; } - cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */ + CX18_DEBUG_INFO("Stream type %d options: %d MB, %d buffers, " + "%d bytes\n", i, cx->options.megabytes[i], + cx->stream_buffers[i], cx->stream_buf_size[i]); } cx->options.cardtype = cardtype[cx->instance]; diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index bed8bcc6541..5c78b014dbc 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -120,11 +120,16 @@ /* Maximum firmware DMA buffers per stream */ #define CX18_MAX_FW_MDLS_PER_STREAM 63 +/* YUV buffer sizes in bytes to ensure integer # of frames per buffer */ +#define CX18_UNIT_ENC_YUV_BUFSIZE (720 * 32 * 3 / 2) /* bytes */ +#define CX18_625_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 576/32) +#define CX18_525_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 480/32) + /* DMA buffer, default size in kB allocated */ #define CX18_DEFAULT_ENC_TS_BUFSIZE 32 #define CX18_DEFAULT_ENC_MPG_BUFSIZE 32 #define CX18_DEFAULT_ENC_IDX_BUFSIZE 32 -#define CX18_DEFAULT_ENC_YUV_BUFSIZE 128 +#define CX18_DEFAULT_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 3 / 1024 + 1) /* Default VBI bufsize based on standards supported by card tuner for now */ #define CX18_DEFAULT_ENC_PCM_BUFSIZE 4 diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c index 54a6fd3f7af..71ad2d1b4c2 100644 --- a/drivers/media/video/cx18/cx18-dvb.c +++ b/drivers/media/video/cx18/cx18-dvb.c @@ -362,9 +362,10 @@ int cx18_dvb_register(struct cx18_stream *stream) dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx); CX18_INFO("DVB Frontend registered\n"); - CX18_INFO("Registered DVB adapter%d for %s (%d x %d kB)\n", + CX18_INFO("Registered DVB adapter%d for %s (%d x %d.%02d kB)\n", stream->dvb.dvb_adapter.num, stream->name, - stream->buffers, stream->buf_size/1024); + stream->buffers, stream->buf_size/1024, + (stream->buf_size * 100 / 1024) % 100); mutex_init(&dvb->feedlock); dvb->enabled = 1; diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c index c1a49ecf9d9..98cbf001f8d 100644 --- a/drivers/media/video/cx18/cx18-queue.c +++ b/drivers/media/video/cx18/cx18-queue.c @@ -348,9 +348,11 @@ int cx18_stream_alloc(struct cx18_stream *s) if (s->buffers == 0) return 0; - CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers (%dkB total)\n", + CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers " + "(%d.%02d kB total)\n", s->name, s->buffers, s->buf_size, - s->buffers * s->buf_size / 1024); + s->buffers * s->buf_size / 1024, + (s->buffers * s->buf_size * 100 / 1024) % 100); if (((char __iomem *)&cx->scb->cpu_mdl[cx->free_mdl_idx + s->buffers] - (char __iomem *)cx->scb) > SCB_RESERVED_SIZE) { diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 9f8adda6f26..7755937fc52 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c @@ -262,9 +262,11 @@ static int cx18_reg_dev(struct cx18 *cx, int type) switch (vfl_type) { case VFL_TYPE_GRABBER: - CX18_INFO("Registered device video%d for %s (%d x %d kB)\n", + CX18_INFO("Registered device video%d for %s " + "(%d x %d.%02d kB)\n", num, s->name, cx->stream_buffers[type], - cx->stream_buf_size[type]/1024); + cx->stream_buf_size[type] / 1024, + (cx->stream_buf_size[type] * 100 / 1024) % 100); break; case VFL_TYPE_RADIO: @@ -501,9 +503,23 @@ static void cx18_stream_configure_mdls(struct cx18_stream *s) { cx18_unload_queues(s); - /* For now */ - s->bufs_per_mdl = 1; - s->mdl_size = s->buf_size * s->bufs_per_mdl; + switch (s->type) { + case CX18_ENC_STREAM_TYPE_YUV: + /* + * Height should be a multiple of 32 lines. + * Set the MDL size to the exact size needed for one frame. + * Use enough buffers per MDL to cover the MDL size + */ + s->mdl_size = 720 * s->cx->params.height * 3 / 2; + s->bufs_per_mdl = s->mdl_size / s->buf_size; + if (s->mdl_size % s->buf_size) + s->bufs_per_mdl++; + break; + default: + s->bufs_per_mdl = 1; + s->mdl_size = s->buf_size * s->bufs_per_mdl; + break; + } cx18_load_queues(s); } -- cgit v1.2.3-70-g09d2 From 1047a83844a4d894a068d94aca2d3efe54ac7a9c Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Tue, 10 Nov 2009 23:28:30 -0300 Subject: V4L/DVB (13431): cx18: Adjust an MDL's final buffer size to force encoder transfer size The encoder was not honoring the MDL size sent in DE_SET_MDL mailbox commands. This change adjusts the size of the last buffer in an MDL, as reported to the firmware, so that the encoder will send the exact amount of bytes we specify per MDL transfer. This eliminates tearing in YUV playback when using non-default YUV buffer sizes. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-queue.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c index 98cbf001f8d..f2d539f6bdf 100644 --- a/drivers/media/video/cx18/cx18-queue.c +++ b/drivers/media/video/cx18/cx18-queue.c @@ -280,6 +280,7 @@ void cx18_load_queues(struct cx18_stream *s) struct cx18_buffer *buf; int mdl_id; int i; + u32 partial_buf_size; /* * Attach buffers to MDLs, give the MDLs ids, and add MDLs to q_free @@ -308,10 +309,24 @@ void cx18_load_queues(struct cx18_stream *s) &cx->scb->cpu_mdl[mdl_id + i].length); } - if (i == s->bufs_per_mdl) + if (i == s->bufs_per_mdl) { + /* + * The encoder doesn't honor s->mdl_size. So in the + * case of a non-integral number of buffers to meet + * mdl_size, we lie about the size of the last buffer + * in the MDL to get the encoder to really only send + * us mdl_size bytes per MDL transfer. + */ + partial_buf_size = s->mdl_size % s->buf_size; + if (partial_buf_size) { + cx18_writel(cx, partial_buf_size, + &cx->scb->cpu_mdl[mdl_id + i - 1].length); + } cx18_enqueue(s, mdl, &s->q_free); - else - cx18_push(s, mdl, &s->q_idle); /* not enough buffers */ + } else { + /* Not enough buffers for this MDL; we won't use it */ + cx18_push(s, mdl, &s->q_idle); + } mdl_id += i; } } -- cgit v1.2.3-70-g09d2 From 127ce5f0adcca71eeeed2386ed4742ea6363a063 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Wed, 11 Nov 2009 00:22:57 -0300 Subject: V4L/DVB (13432): cx18: Adjust encoder VBI MDL size to be exactly frame's worth of VBI data Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-driver.c | 4 +--- drivers/media/video/cx18/cx18-driver.h | 1 - drivers/media/video/cx18/cx18-streams.c | 16 ++++++++++++++++ 3 files changed, 17 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 87a735f1ee9..1a67ad5daad 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -87,7 +87,6 @@ static int enc_ts_bufsize = CX18_DEFAULT_ENC_TS_BUFSIZE; static int enc_mpg_bufsize = CX18_DEFAULT_ENC_MPG_BUFSIZE; static int enc_idx_bufsize = CX18_DEFAULT_ENC_IDX_BUFSIZE; static int enc_yuv_bufsize = CX18_DEFAULT_ENC_YUV_BUFSIZE; -/* VBI bufsize based on standards supported by card tuner for now */ static int enc_pcm_bufsize = CX18_DEFAULT_ENC_PCM_BUFSIZE; static int enc_ts_bufs = -1; @@ -128,7 +127,6 @@ module_param(enc_ts_bufsize, int, 0644); module_param(enc_mpg_bufsize, int, 0644); module_param(enc_idx_bufsize, int, 0644); module_param(enc_yuv_bufsize, int, 0644); -/* VBI bufsize based on standards supported by card tuner for now */ module_param(enc_pcm_bufsize, int, 0644); module_param(enc_ts_bufs, int, 0644); @@ -222,7 +220,7 @@ MODULE_PARM_DESC(enc_vbi_buffers, "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS)); MODULE_PARM_DESC(enc_vbi_bufs, "Number of encoder VBI buffers\n" - "\t\t\tDefault is computed from enc_vbi_buffers & tuner std"); + "\t\t\tDefault is computed from enc_vbi_buffers"); MODULE_PARM_DESC(enc_pcm_buffers, "Encoder PCM buffer memory (MB). (enc_pcm_bufs can override)\n" "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS)); diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index 5c78b014dbc..fe767b82c9a 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -130,7 +130,6 @@ #define CX18_DEFAULT_ENC_MPG_BUFSIZE 32 #define CX18_DEFAULT_ENC_IDX_BUFSIZE 32 #define CX18_DEFAULT_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 3 / 1024 + 1) -/* Default VBI bufsize based on standards supported by card tuner for now */ #define CX18_DEFAULT_ENC_PCM_BUFSIZE 4 /* i2c stuff */ diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 7755937fc52..c398651dd74 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c @@ -515,6 +515,22 @@ static void cx18_stream_configure_mdls(struct cx18_stream *s) if (s->mdl_size % s->buf_size) s->bufs_per_mdl++; break; + case CX18_ENC_STREAM_TYPE_VBI: + s->bufs_per_mdl = 1; + if (cx18_raw_vbi(s->cx)) { + s->mdl_size = (s->cx->is_60hz ? 12 : 18) + * 2 * vbi_active_samples; + } else { + /* + * See comment in cx18_vbi_setup() below about the + * extra lines we capture in sliced VBI mode due to + * the lines on which EAV RP codes toggle. + */ + s->mdl_size = s->cx->is_60hz + ? (21 - 4 + 1) * 2 * vbi_hblank_samples_60Hz + : (23 - 2 + 1) * 2 * vbi_hblank_samples_50Hz; + } + break; default: s->bufs_per_mdl = 1; s->mdl_size = s->buf_size * s->bufs_per_mdl; -- cgit v1.2.3-70-g09d2 From ad689d54f979233c024c25a2221f4fd6f56543fe Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Wed, 11 Nov 2009 00:57:16 -0300 Subject: V4L/DVB (13433): cx18: Remove duplicate list traversal when processing incoming MDLs Update the incoming MDL's buffers' bytesused and sync the buffers for the cpu in one pass instead of two. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-queue.c | 27 ++++++++------------------- drivers/media/video/cx18/cx18-queue.h | 13 ------------- 2 files changed, 8 insertions(+), 32 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c index f2d539f6bdf..63304823cef 100644 --- a/drivers/media/video/cx18/cx18-queue.c +++ b/drivers/media/video/cx18/cx18-queue.c @@ -100,8 +100,8 @@ struct cx18_mdl *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) return mdl; } -static void _cx18_mdl_set_buf_bytesused(struct cx18_stream *s, - struct cx18_mdl *mdl) +static void _cx18_mdl_update_bufs_for_cpu(struct cx18_stream *s, + struct cx18_mdl *mdl) { struct cx18_buffer *buf; u32 buf_size = s->buf_size; @@ -116,11 +116,12 @@ static void _cx18_mdl_set_buf_bytesused(struct cx18_stream *s, buf->bytesused = bytesused; bytesused = 0; } + cx18_buf_sync_for_cpu(s, buf); } } -static inline void cx18_mdl_set_buf_bytesused(struct cx18_stream *s, - struct cx18_mdl *mdl) +static inline void cx18_mdl_update_bufs_for_cpu(struct cx18_stream *s, + struct cx18_mdl *mdl) { struct cx18_buffer *buf; @@ -129,8 +130,9 @@ static inline void cx18_mdl_set_buf_bytesused(struct cx18_stream *s, list); buf->bytesused = mdl->bytesused; buf->readpos = 0; + cx18_buf_sync_for_cpu(s, buf); } else { - _cx18_mdl_set_buf_bytesused(s, mdl); + _cx18_mdl_update_bufs_for_cpu(s, mdl); } } @@ -191,8 +193,7 @@ struct cx18_mdl *cx18_queue_get_mdl(struct cx18_stream *s, u32 id, ret->bytesused = bytesused; ret->skipped = 0; /* 0'ed readpos, m_flags & curr_buf when mdl went on q_busy */ - cx18_mdl_set_buf_bytesused(s, ret); - cx18_mdl_sync_for_cpu(s, ret); + cx18_mdl_update_bufs_for_cpu(s, ret); if (s->type != CX18_ENC_STREAM_TYPE_TS) set_bit(CX18_F_M_NEED_SWAP, &ret->m_flags); } @@ -331,18 +332,6 @@ void cx18_load_queues(struct cx18_stream *s) } } -void _cx18_mdl_sync_for_cpu(struct cx18_stream *s, struct cx18_mdl *mdl) -{ - int dma = s->dma; - u32 buf_size = s->buf_size; - struct pci_dev *pci_dev = s->cx->pci_dev; - struct cx18_buffer *buf; - - list_for_each_entry(buf, &mdl->buf_list, list) - pci_dma_sync_single_for_cpu(pci_dev, buf->dma_handle, - buf_size, dma); -} - void _cx18_mdl_sync_for_device(struct cx18_stream *s, struct cx18_mdl *mdl) { int dma = s->dma; diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h index 96747e5e7c3..88a6d34ad3b 100644 --- a/drivers/media/video/cx18/cx18-queue.h +++ b/drivers/media/video/cx18/cx18-queue.h @@ -33,19 +33,6 @@ static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s, s->buf_size, s->dma); } -void _cx18_mdl_sync_for_cpu(struct cx18_stream *s, struct cx18_mdl *mdl); - -static inline void cx18_mdl_sync_for_cpu(struct cx18_stream *s, - struct cx18_mdl *mdl) -{ - if (list_is_singular(&mdl->buf_list)) - cx18_buf_sync_for_cpu(s, list_first_entry(&mdl->buf_list, - struct cx18_buffer, - list)); - else - _cx18_mdl_sync_for_cpu(s, mdl); -} - static inline void cx18_buf_sync_for_device(struct cx18_stream *s, struct cx18_buffer *buf) { -- cgit v1.2.3-70-g09d2 From 543ae45a7fc88c773358da326bc9e965b69aad06 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Wed, 11 Nov 2009 01:18:41 -0300 Subject: V4L/DVB (13434): cx18: Bump version number due to significant buffer handling changes. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h index 45494b094e7..9c0b5bb1b01 100644 --- a/drivers/media/video/cx18/cx18-version.h +++ b/drivers/media/video/cx18/cx18-version.h @@ -24,7 +24,7 @@ #define CX18_DRIVER_NAME "cx18" #define CX18_DRIVER_VERSION_MAJOR 1 -#define CX18_DRIVER_VERSION_MINOR 2 +#define CX18_DRIVER_VERSION_MINOR 3 #define CX18_DRIVER_VERSION_PATCHLEVEL 0 #define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL) -- cgit v1.2.3-70-g09d2 From 9018f6c3a22ef2d7413da17813312d781163d950 Mon Sep 17 00:00:00 2001 From: Antoine Jacquet Date: Thu, 19 Nov 2009 22:35:38 -0300 Subject: V4L/DVB (13438): zr364xx: add support for Trust Powerc@m 910Z Tested-by: Enrique Dominguez Signed-off-by: Antoine Jacquet Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/zr364xx.txt | 1 + drivers/media/video/zr364xx.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/Documentation/video4linux/zr364xx.txt b/Documentation/video4linux/zr364xx.txt index 7f3d1955d21..d98e4d30297 100644 --- a/Documentation/video4linux/zr364xx.txt +++ b/Documentation/video4linux/zr364xx.txt @@ -66,3 +66,4 @@ Vendor Product Distributor Model 0x0a17 0x004e Pentax Optio 50 0x041e 0x405d Creative DiVi CAM 516 0x08ca 0x2102 Aiptek DV T300 +0x06d6 0x003d Trust Powerc@m 910Z diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c index 9aae011d92a..2ef110b5221 100644 --- a/drivers/media/video/zr364xx.c +++ b/drivers/media/video/zr364xx.c @@ -115,6 +115,7 @@ static struct usb_device_id device_table[] = { {USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 }, {USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 }, {USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD2 }, + {USB_DEVICE(0x06d6, 0x003d), .driver_info = METHOD0 }, {} /* Terminating entry */ }; -- cgit v1.2.3-70-g09d2 From 23bff27aaf81f58a042ee2c9c58c1881635703c3 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 21 Nov 2009 00:08:09 -0300 Subject: V4L/DVB (13440): ivtv: Update the cards definitions to add another AVerMedia M113 variant Add an AVerMedia M113 variant that was... Reported-by: Hiemanshu Sharma Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-cards.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c index 4873b6ca580..ec7883723d1 100644 --- a/drivers/media/video/ivtv/ivtv-cards.c +++ b/drivers/media/video/ivtv/ivtv-cards.c @@ -1025,13 +1025,15 @@ static const struct ivtv_card ivtv_card_aver_pvr150 = { /* AVerMedia UltraTV 1500 MCE (newer non-cx88 version, M113 variant) card */ static const struct ivtv_card_pci_info ivtv_pci_aver_ultra1500mce[] = { - { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc019 }, + { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc019 }, /* NTSC */ + { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc01b }, /* PAL/SECAM */ { 0, 0, 0 } }; static const struct ivtv_card ivtv_card_aver_ultra1500mce = { .type = IVTV_CARD_AVER_ULTRA1500MCE, .name = "AVerMedia UltraTV 1500 MCE / AVerTV M113 Philips Tuner", + .comment = "For non-NTSC tuners, use the pal= or secam= module options", .v4l2_capabilities = IVTV_CAP_ENCODER, .hw_video = IVTV_HW_CX25840, .hw_audio = IVTV_HW_CX25840, @@ -1058,6 +1060,7 @@ static const struct ivtv_card ivtv_card_aver_ultra1500mce = { .tuners = { /* The UltraTV 1500 MCE has a Philips FM1236 MK5 TV/FM tuner */ { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 }, + { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216MK5 }, }, .pci_list = ivtv_pci_aver_ultra1500mce, .i2c = &ivtv_i2c_std, -- cgit v1.2.3-70-g09d2 From e45e8f5cee75b0559ce1ca7007b4963b91910fa8 Mon Sep 17 00:00:00 2001 From: "Aleksandr V. Piskunov" Date: Sat, 21 Nov 2009 00:47:25 -0300 Subject: V4L/DVB (13441): ivtv: Added FM radio support to Avermedia AVerTV MCE 116 Plus card Signed-off-by: Aleksandr V. Piskunov Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-cards.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c index ec7883723d1..e15c153b301 100644 --- a/drivers/media/video/ivtv/ivtv-cards.c +++ b/drivers/media/video/ivtv/ivtv-cards.c @@ -965,6 +965,7 @@ static const struct ivtv_card ivtv_card_avertv_mce116 = { { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 }, { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 }, }, + .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 }, /* enable line-in */ .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 }, .xceive_pin = 10, -- cgit v1.2.3-70-g09d2 From f412d36a8c9f8e40e057b71e80d534ac388e903e Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 21 Nov 2009 01:47:45 -0300 Subject: V4L/DVB (13442): ivtv: Add module parameter to adjust I2C SCL clock period per board Add a module parameter to adjust I2C SCL clock period per board. This allows some experimental fine tuning by end users to overcome quirky I2C device problems. Reported-by: "Aleksandr V. Piskunov" Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-driver.c | 19 +++++++++++++++++++ drivers/media/video/ivtv/ivtv-driver.h | 4 ++++ drivers/media/video/ivtv/ivtv-i2c.c | 7 +++++-- 3 files changed, 28 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 7cdbc1a8f21..8330fb5c7eb 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -91,10 +91,15 @@ static int radio[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; +static int i2c_clock_period[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 }; static unsigned int cardtype_c = 1; static unsigned int tuner_c = 1; static unsigned int radio_c = 1; +static unsigned int i2c_clock_period_c = 1; static char pal[] = "---"; static char secam[] = "--"; static char ntsc[] = "-"; @@ -151,6 +156,7 @@ module_param(dec_vbi_buffers, int, 0644); module_param(tunertype, int, 0644); module_param(newi2c, int, 0644); +module_param_array(i2c_clock_period, int, &i2c_clock_period_c, 0644); MODULE_PARM_DESC(tuner, "Tuner type selection,\n" "\t\t\tsee tuner.h for values"); @@ -245,6 +251,10 @@ MODULE_PARM_DESC(newi2c, "Use new I2C implementation\n" "\t\t\t-1 is autodetect, 0 is off, 1 is on\n" "\t\t\tDefault is autodetect"); +MODULE_PARM_DESC(i2c_clock_period, + "Period of SCL for the I2C bus controlled by the CX23415/6\n" + "\t\t\tMin: 10 usec (100 kHz), Max: 4500 usec (222 Hz)\n" + "\t\t\tDefault: " __stringify(IVTV_DEFAULT_I2C_CLOCK_PERIOD)); MODULE_PARM_DESC(ivtv_first_minor, "Set device node number assigned to first card"); @@ -600,6 +610,15 @@ static void ivtv_process_options(struct ivtv *itv) itv->options.cardtype = cardtype[itv->instance]; itv->options.tuner = tuner[itv->instance]; itv->options.radio = radio[itv->instance]; + + itv->options.i2c_clock_period = i2c_clock_period[itv->instance]; + if (itv->options.i2c_clock_period == -1) + itv->options.i2c_clock_period = IVTV_DEFAULT_I2C_CLOCK_PERIOD; + else if (itv->options.i2c_clock_period < 10) + itv->options.i2c_clock_period = 10; + else if (itv->options.i2c_clock_period > 4500) + itv->options.i2c_clock_period = 4500; + itv->options.newi2c = newi2c; if (tunertype < -1 || tunertype > 1) { IVTV_WARN("Invalid tunertype argument, will autodetect instead\n"); diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 440f7328a7e..2b3db90afb7 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h @@ -176,12 +176,16 @@ extern int ivtv_debug; #define IVTV_MAX_PGM_INDEX (400) +/* Default I2C SCL period in microseconds */ +#define IVTV_DEFAULT_I2C_CLOCK_PERIOD 20 + struct ivtv_options { int kilobytes[IVTV_MAX_STREAMS]; /* size in kilobytes of each stream */ int cardtype; /* force card type on load */ int tuner; /* set tuner on load */ int radio; /* enable/disable radio */ int newi2c; /* new I2C algorithm */ + int i2c_clock_period; /* period of SCL for I2C bus */ }; /* ivtv-specific mailbox template */ diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index b9c71e61f7d..d4cc3365038 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c @@ -564,13 +564,15 @@ static struct i2c_adapter ivtv_i2c_adap_template = { .owner = THIS_MODULE, }; +#define IVTV_ALGO_BIT_TIMEOUT (2) /* seconds */ + static const struct i2c_algo_bit_data ivtv_i2c_algo_template = { .setsda = ivtv_setsda_old, .setscl = ivtv_setscl_old, .getsda = ivtv_getsda_old, .getscl = ivtv_getscl_old, - .udelay = 10, - .timeout = 200, + .udelay = IVTV_DEFAULT_I2C_CLOCK_PERIOD / 2, /* microseconds */ + .timeout = IVTV_ALGO_BIT_TIMEOUT * HZ, /* jiffies */ }; static struct i2c_client ivtv_i2c_client_template = { @@ -602,6 +604,7 @@ int init_ivtv_i2c(struct ivtv *itv) memcpy(&itv->i2c_algo, &ivtv_i2c_algo_template, sizeof(struct i2c_algo_bit_data)); } + itv->i2c_algo.udelay = itv->options.i2c_clock_period / 2; itv->i2c_algo.data = itv; itv->i2c_adap.algo_data = &itv->i2c_algo; -- cgit v1.2.3-70-g09d2 From bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 21 Nov 2009 11:41:33 -0300 Subject: V4L/DVB (13443): ivtv: Defer legacy I2C IR probing until after setup of known I2C devices This avoids collisions of legacy IR controller probing with known I2C devices in the card definitions in ivtv-cards.c. I2C driver modules for device listed explicitly in a card definition should always take precedence over a probe guessing where and IR controller may be. Reviewed-by: Jean Delvare Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-driver.c | 3 ++ drivers/media/video/ivtv/ivtv-i2c.c | 58 ++++++++++++++++++---------------- drivers/media/video/ivtv/ivtv-i2c.h | 1 + 3 files changed, 35 insertions(+), 27 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 8330fb5c7eb..d14f94e254b 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -884,6 +884,9 @@ static void ivtv_load_and_init_modules(struct ivtv *itv) itv->hw_flags |= device; } + /* probe for legacy IR controllers that aren't in card definitions */ + ivtv_i2c_new_ir_legacy(itv); + if (itv->card->hw_all & IVTV_HW_CX25840) itv->sd_video = ivtv_find_hw(itv, IVTV_HW_CX25840); else if (itv->card->hw_all & IVTV_HW_SAA717X) diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index d4cc3365038..71a8aa60b3f 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c @@ -149,6 +149,36 @@ static const char * const hw_devicenames[] = { "gpio", }; +/* Instantiate the IR receiver device using probing -- undesirable */ +struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv) +{ + struct i2c_board_info info; + /* + * The external IR receiver is at i2c address 0x34. + * The internal IR receiver is at i2c address 0x30. + * + * In theory, both can be fitted, and Hauppauge suggests an external + * overrides an internal. That's why we probe 0x1a (~0x34) first. CB + * + * Some of these addresses we probe may collide with other i2c address + * allocations, so this function must be called after all other i2c + * devices we care about are registered. + */ + const unsigned short addr_list[] = { + 0x1a, /* Hauppauge IR external - collides with WM8739 */ + 0x18, /* Hauppauge IR internal */ + 0x71, /* Hauppauge IR (PVR150) */ + 0x64, /* Pixelview IR */ + 0x30, /* KNC ONE IR */ + 0x6b, /* Adaptec IR */ + I2C_CLIENT_END + }; + + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "ir_video", I2C_NAME_SIZE); + return i2c_new_probed_device(&itv->i2c_adap, &info, addr_list); +} + int ivtv_i2c_register(struct ivtv *itv, unsigned idx) { struct v4l2_subdev *sd; @@ -579,7 +609,7 @@ static struct i2c_client ivtv_i2c_client_template = { .name = "ivtv internal", }; -/* init + register i2c adapter + instantiate IR receiver */ +/* init + register i2c adapter */ int init_ivtv_i2c(struct ivtv *itv) { int retval; @@ -626,32 +656,6 @@ int init_ivtv_i2c(struct ivtv *itv) else retval = i2c_bit_add_bus(&itv->i2c_adap); - /* Instantiate the IR receiver device, if present */ - if (retval == 0) { - struct i2c_board_info info; - /* The external IR receiver is at i2c address 0x34 (0x35 for - reads). Future Hauppauge cards will have an internal - receiver at 0x30 (0x31 for reads). In theory, both can be - fitted, and Hauppauge suggest an external overrides an - internal. - - That's why we probe 0x1a (~0x34) first. CB - */ - const unsigned short addr_list[] = { - 0x1a, /* Hauppauge IR external */ - 0x18, /* Hauppauge IR internal */ - 0x71, /* Hauppauge IR (PVR150) */ - 0x64, /* Pixelview IR */ - 0x30, /* KNC ONE IR */ - 0x6b, /* Adaptec IR */ - I2C_CLIENT_END - }; - - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "ir_video", I2C_NAME_SIZE); - i2c_new_probed_device(&itv->i2c_adap, &info, addr_list); - } - return retval; } diff --git a/drivers/media/video/ivtv/ivtv-i2c.h b/drivers/media/video/ivtv/ivtv-i2c.h index 396928a06a5..9332920ca4f 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.h +++ b/drivers/media/video/ivtv/ivtv-i2c.h @@ -21,6 +21,7 @@ #ifndef IVTV_I2C_H #define IVTV_I2C_H +struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv); int ivtv_i2c_register(struct ivtv *itv, unsigned idx); struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw); -- cgit v1.2.3-70-g09d2 From ad2fe2d48812029b0b674594f297d0723f7c6e8f Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 21 Nov 2009 12:52:34 -0300 Subject: V4L/DVB (13444): ivtv: Add explicit IR controller initialization for the AVerTV M116 Add explicit support for the AVerTV M116 for use with the ir-kbd-i2c module. This also eases future support for other AVerMedia ivtv boards with the same microcontroller program at I2C address 0x40. This is a reworked version of an earlier patch that was... Reviewed-by: Jean Delvare Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-cards.c | 3 ++- drivers/media/video/ivtv/ivtv-cards.h | 36 ++++++++++++++------------- drivers/media/video/ivtv/ivtv-driver.h | 2 ++ drivers/media/video/ivtv/ivtv-i2c.c | 45 ++++++++++++++++++++++++++++++---- 4 files changed, 63 insertions(+), 23 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c index e15c153b301..e98ecadfde2 100644 --- a/drivers/media/video/ivtv/ivtv-cards.c +++ b/drivers/media/video/ivtv/ivtv-cards.c @@ -955,7 +955,8 @@ static const struct ivtv_card ivtv_card_avertv_mce116 = { .hw_video = IVTV_HW_CX25840, .hw_audio = IVTV_HW_CX25840, .hw_audio_ctrl = IVTV_HW_CX25840, - .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739, + .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739 | + IVTV_HW_I2C_IR_RX_AVER, .video_inputs = { { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 }, { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 }, diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h index e99a0a25557..1ac09ebaa2f 100644 --- a/drivers/media/video/ivtv/ivtv-cards.h +++ b/drivers/media/video/ivtv/ivtv-cards.h @@ -87,25 +87,27 @@ #define IVTV_PCI_ID_GOTVIEW1 0xffac #define IVTV_PCI_ID_GOTVIEW2 0xffad -/* hardware flags, no gaps allowed, IVTV_HW_GPIO must always be last */ -#define IVTV_HW_CX25840 (1 << 0) -#define IVTV_HW_SAA7115 (1 << 1) -#define IVTV_HW_SAA7127 (1 << 2) -#define IVTV_HW_MSP34XX (1 << 3) -#define IVTV_HW_TUNER (1 << 4) -#define IVTV_HW_WM8775 (1 << 5) -#define IVTV_HW_CS53L32A (1 << 6) -#define IVTV_HW_TVEEPROM (1 << 7) -#define IVTV_HW_SAA7114 (1 << 8) -#define IVTV_HW_UPD64031A (1 << 9) -#define IVTV_HW_UPD6408X (1 << 10) -#define IVTV_HW_SAA717X (1 << 11) -#define IVTV_HW_WM8739 (1 << 12) -#define IVTV_HW_VP27SMPX (1 << 13) -#define IVTV_HW_M52790 (1 << 14) -#define IVTV_HW_GPIO (1 << 15) +/* hardware flags, no gaps allowed */ +#define IVTV_HW_CX25840 (1 << 0) +#define IVTV_HW_SAA7115 (1 << 1) +#define IVTV_HW_SAA7127 (1 << 2) +#define IVTV_HW_MSP34XX (1 << 3) +#define IVTV_HW_TUNER (1 << 4) +#define IVTV_HW_WM8775 (1 << 5) +#define IVTV_HW_CS53L32A (1 << 6) +#define IVTV_HW_TVEEPROM (1 << 7) +#define IVTV_HW_SAA7114 (1 << 8) +#define IVTV_HW_UPD64031A (1 << 9) +#define IVTV_HW_UPD6408X (1 << 10) +#define IVTV_HW_SAA717X (1 << 11) +#define IVTV_HW_WM8739 (1 << 12) +#define IVTV_HW_VP27SMPX (1 << 13) +#define IVTV_HW_M52790 (1 << 14) +#define IVTV_HW_GPIO (1 << 15) +#define IVTV_HW_I2C_IR_RX_AVER (1 << 16) #define IVTV_HW_SAA711X (IVTV_HW_SAA7115 | IVTV_HW_SAA7114) +#define IVTV_HW_IR_ANY (IVTV_HW_I2C_IR_RX_AVER) /* video inputs */ #define IVTV_CARD_INPUT_VID_TUNER 1 diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 2b3db90afb7..e4816da6482 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h @@ -64,6 +64,7 @@ #include #include #include +#include #include @@ -681,6 +682,7 @@ struct ivtv { int i2c_state; /* i2c bit state */ struct mutex i2c_bus_lock; /* lock i2c bus */ + struct IR_i2c_init_data ir_i2c_init_data; /* Program Index information */ u32 pgm_info_offset; /* start of pgm info in encoder memory */ diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index 71a8aa60b3f..6838683cdaa 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c @@ -88,6 +88,7 @@ #define IVTV_UPD64083_I2C_ADDR 0x5c #define IVTV_VP27SMPX_I2C_ADDR 0x5b #define IVTV_M52790_I2C_ADDR 0x48 +#define IVTV_AVERMEDIA_IR_RX_I2C_ADDR 0x40 /* This array should match the IVTV_HW_ defines */ static const u8 hw_addrs[] = { @@ -106,7 +107,8 @@ static const u8 hw_addrs[] = { IVTV_WM8739_I2C_ADDR, IVTV_VP27SMPX_I2C_ADDR, IVTV_M52790_I2C_ADDR, - 0 /* IVTV_HW_GPIO dummy driver ID */ + 0, /* IVTV_HW_GPIO dummy driver ID */ + IVTV_AVERMEDIA_IR_RX_I2C_ADDR /* IVTV_HW_I2C_IR_RX_AVER */ }; /* This array should match the IVTV_HW_ defines */ @@ -126,7 +128,8 @@ static const char *hw_modules[] = { "wm8739", "vp27smpx", "m52790", - NULL + NULL, + NULL /* IVTV_HW_I2C_IR_RX_AVER */ }; /* This array should match the IVTV_HW_ defines */ @@ -147,8 +150,34 @@ static const char * const hw_devicenames[] = { "vp27smpx", "m52790", "gpio", + "ir_video", /* IVTV_HW_I2C_IR_RX_AVER */ }; +static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr) +{ + struct i2c_board_info info; + struct i2c_adapter *adap = &itv->i2c_adap; + struct IR_i2c_init_data *init_data = &itv->ir_i2c_init_data; + unsigned short addr_list[2] = { addr, I2C_CLIENT_END }; + + /* Our default information for ir-kbd-i2c.c to use */ + switch (hw) { + case IVTV_HW_I2C_IR_RX_AVER: + init_data->ir_codes = &ir_codes_avermedia_cardbus_table; + init_data->internal_get_key_func = + IR_KBD_GET_KEY_AVERMEDIA_CARDBUS; + init_data->type = IR_TYPE_OTHER; + init_data->name = "AVerMedia AVerTV card"; + break; + } + + memset(&info, 0, sizeof(struct i2c_board_info)); + info.platform_data = init_data; + strlcpy(info.type, type, I2C_NAME_SIZE); + + return i2c_new_probed_device(adap, &info, addr_list) == NULL ? -1 : 0; +} + /* Instantiate the IR receiver device using probing -- undesirable */ struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv) { @@ -208,8 +237,15 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx) sd->grp_id = 1 << idx; return sd ? 0 : -1; } + + if (hw & IVTV_HW_IR_ANY) + return ivtv_i2c_new_ir(itv, hw, type, hw_addrs[idx]); + + /* Is it not an I2C device or one we do not wish to register? */ if (!hw_addrs[idx]) return -1; + + /* It's an I2C device other than an analog tuner or IR chip */ if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) { sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, mod, type, 0, I2C_ADDRS(hw_addrs[idx])); @@ -617,11 +653,10 @@ int init_ivtv_i2c(struct ivtv *itv) IVTV_DEBUG_I2C("i2c init\n"); /* Sanity checks for the I2C hardware arrays. They must be the - * same size and GPIO must be the last entry. + * same size. */ if (ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) || - ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_modules) || - IVTV_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 1))) { + ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_modules)) { IVTV_ERR("Mismatched I2C hardware arrays\n"); return -ENODEV; } -- cgit v1.2.3-70-g09d2 From 8352619043a04785b8d20e438629b14e556fffce Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 21 Nov 2009 13:39:28 -0300 Subject: V4L/DVB (13445): cx18: Use per cx18 instance init data for ir-kbd-i2c instead of const data This change creates per cx18 instances of IR_i2c_init_data for handing over initialization data to ir-kbd-i2c, since that module wants non-const data even though it never modifies the data. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-cards.h | 3 +++ drivers/media/video/cx18/cx18-driver.h | 3 +++ drivers/media/video/cx18/cx18-i2c.c | 25 ++++++++++--------------- 3 files changed, 16 insertions(+), 15 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h index 444e3c7c563..af3d71607dc 100644 --- a/drivers/media/video/cx18/cx18-cards.h +++ b/drivers/media/video/cx18/cx18-cards.h @@ -34,6 +34,9 @@ #define CX18_HW_Z8F0811_IR_HAUP (CX18_HW_Z8F0811_IR_RX_HAUP | \ CX18_HW_Z8F0811_IR_TX_HAUP) +#define CX18_HW_IR_ANY (CX18_HW_Z8F0811_IR_RX_HAUP | \ + CX18_HW_Z8F0811_IR_TX_HAUP) + /* video inputs */ #define CX18_CARD_INPUT_VID_TUNER 1 #define CX18_CARD_INPUT_SVIDEO1 2 diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index fe767b82c9a..e3f7911a738 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -50,6 +50,7 @@ #include #include #include +#include #include "cx18-mailbox.h" #include "cx18-av-core.h" #include "cx23418.h" @@ -606,6 +607,8 @@ struct cx18 { struct i2c_algo_bit_data i2c_algo[2]; struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2]; + struct IR_i2c_init_data ir_i2c_init_data; + /* gpio */ u32 gpio_dir; u32 gpio_val; diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c index 2477461e84d..eecf29af916 100644 --- a/drivers/media/video/cx18/cx18-i2c.c +++ b/drivers/media/video/cx18/cx18-i2c.c @@ -28,7 +28,6 @@ #include "cx18-gpio.h" #include "cx18-i2c.h" #include "cx18-irq.h" -#include #define CX18_REG_I2C_1_WR 0xf15000 #define CX18_REG_I2C_1_RD 0xf15008 @@ -97,17 +96,11 @@ static const char * const hw_devicenames[] = { "ir_rx_z8f0811_haup", }; -static const struct IR_i2c_init_data z8f0811_ir_init_data = { - .ir_codes = &ir_codes_hauppauge_new_table, - .internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR, - .type = IR_TYPE_RC5, - .name = "CX23418 Z8F0811 Hauppauge", -}; - -static int cx18_i2c_new_ir(struct i2c_adapter *adap, u32 hw, const char *type, - u8 addr) +static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw, + const char *type, u8 addr) { struct i2c_board_info info; + struct IR_i2c_init_data *init_data = &cx->ir_i2c_init_data; unsigned short addr_list[2] = { addr, I2C_CLIENT_END }; memset(&info, 0, sizeof(struct i2c_board_info)); @@ -116,9 +109,11 @@ static int cx18_i2c_new_ir(struct i2c_adapter *adap, u32 hw, const char *type, /* Our default information for ir-kbd-i2c.c to use */ switch (hw) { case CX18_HW_Z8F0811_IR_RX_HAUP: - info.platform_data = (void *) &z8f0811_ir_init_data; - break; - default: + init_data->ir_codes = &ir_codes_hauppauge_new_table; + init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; + init_data->type = IR_TYPE_RC5; + init_data->name = cx->card_name; + info.platform_data = init_data; break; } @@ -154,8 +149,8 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx) return sd != NULL ? 0 : -1; } - if (hw & CX18_HW_Z8F0811_IR_HAUP) - return cx18_i2c_new_ir(adap, hw, type, hw_addrs[idx]); + if (hw & CX18_HW_IR_ANY) + return cx18_i2c_new_ir(cx, adap, hw, type, hw_addrs[idx]); /* Is it not an I2C device or one we do not wish to register? */ if (!hw_addrs[idx]) -- cgit v1.2.3-70-g09d2 From 7ce5c41db3672c8b4419b16d9b3ac1ccf11a1445 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 21 Nov 2009 16:19:27 -0300 Subject: V4L/DVB (13446): ivtv: Add more explicit detection of known IR devices for Hauppauge cards Avoid legacy IR I2C probing for PVR-150, PVR-500, and PVR-350 cards. This still probes, but restricts the possbile addresses probed per card. Also removed legacy probe addresses for the KNC and PixelView cards which are not supported by ivtv as far as I know. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-cards.c | 7 +++-- drivers/media/video/ivtv/ivtv-cards.h | 51 ++++++++++++++++++++------------ drivers/media/video/ivtv/ivtv-driver.c | 3 +- drivers/media/video/ivtv/ivtv-i2c.c | 53 ++++++++++++++++++++++++++++++---- 4 files changed, 88 insertions(+), 26 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c index e98ecadfde2..79d0fe4990d 100644 --- a/drivers/media/video/ivtv/ivtv-cards.c +++ b/drivers/media/video/ivtv/ivtv-cards.c @@ -136,7 +136,8 @@ static const struct ivtv_card ivtv_card_pvr350 = { .hw_audio = IVTV_HW_MSP34XX, .hw_audio_ctrl = IVTV_HW_MSP34XX, .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7115 | - IVTV_HW_SAA7127 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER, + IVTV_HW_SAA7127 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER | + IVTV_HW_I2C_IR_RX_HAUP_EXT | IVTV_HW_I2C_IR_RX_HAUP_INT, .video_inputs = { { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 }, { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, @@ -199,7 +200,9 @@ static const struct ivtv_card ivtv_card_pvr150 = { .hw_audio_ctrl = IVTV_HW_CX25840, .hw_muxer = IVTV_HW_WM8775, .hw_all = IVTV_HW_WM8775 | IVTV_HW_CX25840 | - IVTV_HW_TVEEPROM | IVTV_HW_TUNER, + IVTV_HW_TVEEPROM | IVTV_HW_TUNER | + IVTV_HW_I2C_IR_RX_HAUP_EXT | IVTV_HW_I2C_IR_RX_HAUP_INT | + IVTV_HW_Z8F0811_IR_HAUP, .video_inputs = { { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE7 }, { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO1 }, diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h index 1ac09ebaa2f..6148827ec88 100644 --- a/drivers/media/video/ivtv/ivtv-cards.h +++ b/drivers/media/video/ivtv/ivtv-cards.h @@ -88,26 +88,41 @@ #define IVTV_PCI_ID_GOTVIEW2 0xffad /* hardware flags, no gaps allowed */ -#define IVTV_HW_CX25840 (1 << 0) -#define IVTV_HW_SAA7115 (1 << 1) -#define IVTV_HW_SAA7127 (1 << 2) -#define IVTV_HW_MSP34XX (1 << 3) -#define IVTV_HW_TUNER (1 << 4) -#define IVTV_HW_WM8775 (1 << 5) -#define IVTV_HW_CS53L32A (1 << 6) -#define IVTV_HW_TVEEPROM (1 << 7) -#define IVTV_HW_SAA7114 (1 << 8) -#define IVTV_HW_UPD64031A (1 << 9) -#define IVTV_HW_UPD6408X (1 << 10) -#define IVTV_HW_SAA717X (1 << 11) -#define IVTV_HW_WM8739 (1 << 12) -#define IVTV_HW_VP27SMPX (1 << 13) -#define IVTV_HW_M52790 (1 << 14) -#define IVTV_HW_GPIO (1 << 15) -#define IVTV_HW_I2C_IR_RX_AVER (1 << 16) +#define IVTV_HW_CX25840 (1 << 0) +#define IVTV_HW_SAA7115 (1 << 1) +#define IVTV_HW_SAA7127 (1 << 2) +#define IVTV_HW_MSP34XX (1 << 3) +#define IVTV_HW_TUNER (1 << 4) +#define IVTV_HW_WM8775 (1 << 5) +#define IVTV_HW_CS53L32A (1 << 6) +#define IVTV_HW_TVEEPROM (1 << 7) +#define IVTV_HW_SAA7114 (1 << 8) +#define IVTV_HW_UPD64031A (1 << 9) +#define IVTV_HW_UPD6408X (1 << 10) +#define IVTV_HW_SAA717X (1 << 11) +#define IVTV_HW_WM8739 (1 << 12) +#define IVTV_HW_VP27SMPX (1 << 13) +#define IVTV_HW_M52790 (1 << 14) +#define IVTV_HW_GPIO (1 << 15) +#define IVTV_HW_I2C_IR_RX_AVER (1 << 16) +#define IVTV_HW_I2C_IR_RX_HAUP_EXT (1 << 17) /* External before internal */ +#define IVTV_HW_I2C_IR_RX_HAUP_INT (1 << 18) +#define IVTV_HW_Z8F0811_IR_TX_HAUP (1 << 19) +#define IVTV_HW_Z8F0811_IR_RX_HAUP (1 << 20) + +#define IVTV_HW_Z8F0811_IR_HAUP (IVTV_HW_Z8F0811_IR_RX_HAUP | \ + IVTV_HW_Z8F0811_IR_TX_HAUP) #define IVTV_HW_SAA711X (IVTV_HW_SAA7115 | IVTV_HW_SAA7114) -#define IVTV_HW_IR_ANY (IVTV_HW_I2C_IR_RX_AVER) + +#define IVTV_HW_IR_RX_ANY (IVTV_HW_I2C_IR_RX_AVER | \ + IVTV_HW_I2C_IR_RX_HAUP_EXT | \ + IVTV_HW_I2C_IR_RX_HAUP_INT | \ + IVTV_HW_Z8F0811_IR_RX_HAUP) + +#define IVTV_HW_IR_TX_ANY (IVTV_HW_Z8F0811_IR_TX_HAUP) + +#define IVTV_HW_IR_ANY (IVTV_HW_IR_RX_ANY | IVTV_HW_IR_TX_ANY) /* video inputs */ #define IVTV_CARD_INPUT_VID_TUNER 1 diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index d14f94e254b..347c3344f56 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -885,7 +885,8 @@ static void ivtv_load_and_init_modules(struct ivtv *itv) } /* probe for legacy IR controllers that aren't in card definitions */ - ivtv_i2c_new_ir_legacy(itv); + if ((itv->hw_flags & IVTV_HW_IR_ANY) == 0) + ivtv_i2c_new_ir_legacy(itv); if (itv->card->hw_all & IVTV_HW_CX25840) itv->sd_video = ivtv_find_hw(itv, IVTV_HW_CX25840); diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index 6838683cdaa..2ee03c2a1b5 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c @@ -89,6 +89,10 @@ #define IVTV_VP27SMPX_I2C_ADDR 0x5b #define IVTV_M52790_I2C_ADDR 0x48 #define IVTV_AVERMEDIA_IR_RX_I2C_ADDR 0x40 +#define IVTV_HAUP_EXT_IR_RX_I2C_ADDR 0x1a +#define IVTV_HAUP_INT_IR_RX_I2C_ADDR 0x18 +#define IVTV_Z8F0811_IR_TX_I2C_ADDR 0x70 +#define IVTV_Z8F0811_IR_RX_I2C_ADDR 0x71 /* This array should match the IVTV_HW_ defines */ static const u8 hw_addrs[] = { @@ -108,7 +112,11 @@ static const u8 hw_addrs[] = { IVTV_VP27SMPX_I2C_ADDR, IVTV_M52790_I2C_ADDR, 0, /* IVTV_HW_GPIO dummy driver ID */ - IVTV_AVERMEDIA_IR_RX_I2C_ADDR /* IVTV_HW_I2C_IR_RX_AVER */ + IVTV_AVERMEDIA_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_AVER */ + IVTV_HAUP_EXT_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_HAUP_EXT */ + IVTV_HAUP_INT_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_HAUP_INT */ + IVTV_Z8F0811_IR_TX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_TX_HAUP */ + IVTV_Z8F0811_IR_RX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_RX_HAUP */ }; /* This array should match the IVTV_HW_ defines */ @@ -129,7 +137,11 @@ static const char *hw_modules[] = { "vp27smpx", "m52790", NULL, - NULL /* IVTV_HW_I2C_IR_RX_AVER */ + NULL, /* IVTV_HW_I2C_IR_RX_AVER */ + NULL, /* IVTV_HW_I2C_IR_RX_HAUP_EXT */ + NULL, /* IVTV_HW_I2C_IR_RX_HAUP_INT */ + NULL, /* IVTV_HW_Z8F0811_IR_TX_HAUP */ + NULL, /* IVTV_HW_Z8F0811_IR_RX_HAUP */ }; /* This array should match the IVTV_HW_ defines */ @@ -150,7 +162,11 @@ static const char * const hw_devicenames[] = { "vp27smpx", "m52790", "gpio", - "ir_video", /* IVTV_HW_I2C_IR_RX_AVER */ + "ir_video", /* IVTV_HW_I2C_IR_RX_AVER */ + "ir_video", /* IVTV_HW_I2C_IR_RX_HAUP_EXT */ + "ir_video", /* IVTV_HW_I2C_IR_RX_HAUP_INT */ + "ir_tx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_TX_HAUP */ + "ir_rx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_RX_HAUP */ }; static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr) @@ -160,6 +176,20 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr) struct IR_i2c_init_data *init_data = &itv->ir_i2c_init_data; unsigned short addr_list[2] = { addr, I2C_CLIENT_END }; + /* Only allow one IR transmitter to be registered per board */ + if (hw & IVTV_HW_IR_TX_ANY) { + if (itv->hw_flags & IVTV_HW_IR_TX_ANY) + return -1; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, type, I2C_NAME_SIZE); + return i2c_new_probed_device(adap, &info, addr_list) == NULL + ? -1 : 0; + } + + /* Only allow one IR receiver to be registered per board */ + if (itv->hw_flags & IVTV_HW_IR_RX_ANY) + return -1; + /* Our default information for ir-kbd-i2c.c to use */ switch (hw) { case IVTV_HW_I2C_IR_RX_AVER: @@ -169,6 +199,21 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr) init_data->type = IR_TYPE_OTHER; init_data->name = "AVerMedia AVerTV card"; break; + case IVTV_HW_I2C_IR_RX_HAUP_EXT: + case IVTV_HW_I2C_IR_RX_HAUP_INT: + /* Default to old black remote */ + init_data->ir_codes = &ir_codes_rc5_tv_table; + init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP; + init_data->type = IR_TYPE_RC5; + init_data->name = itv->card_name; + break; + case IVTV_HW_Z8F0811_IR_RX_HAUP: + /* Default to grey remote */ + init_data->ir_codes = &ir_codes_hauppauge_new_table; + init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; + init_data->type = IR_TYPE_RC5; + init_data->name = itv->card_name; + break; } memset(&info, 0, sizeof(struct i2c_board_info)); @@ -197,8 +242,6 @@ struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv) 0x1a, /* Hauppauge IR external - collides with WM8739 */ 0x18, /* Hauppauge IR internal */ 0x71, /* Hauppauge IR (PVR150) */ - 0x64, /* Pixelview IR */ - 0x30, /* KNC ONE IR */ 0x6b, /* Adaptec IR */ I2C_CLIENT_END }; -- cgit v1.2.3-70-g09d2 From 4af85668588e249d98957a41030c3a2d2acc87e5 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 12 Nov 2009 15:59:27 -0300 Subject: V4L/DVB (13448): gspca - main: Add a gspca flag for inactive controls. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 3 +++ drivers/media/video/gspca/gspca.h | 1 + 2 files changed, 4 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 6915db2d36d..369eddd352c 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -1158,10 +1158,13 @@ static int vidioc_queryctrl(struct file *file, void *priv, } } else { ctrls = get_ctrl(gspca_dev, id); + i = ctrls - gspca_dev->sd_desc->ctrls; } if (ctrls == NULL) return -EINVAL; memcpy(q_ctrl, ctrls, sizeof *q_ctrl); + if (gspca_dev->ctrl_inac & (1 << i)) + q_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; return 0; } diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 1d761d7cefc..d59a684056c 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -143,6 +143,7 @@ struct gspca_dev { struct cam cam; /* device information */ const struct sd_desc *sd_desc; /* subdriver description */ unsigned ctrl_dis; /* disabled controls (bit map) */ + unsigned ctrl_inac; /* inactive controls (bit map) */ #define USB_BUF_SZ 64 __u8 *usb_buf; /* buffer for USB exchanges */ -- cgit v1.2.3-70-g09d2 From 2d19a2c1186d86e38b51ef59e4b9678f8ad7acf4 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 12 Nov 2009 16:15:44 -0300 Subject: V4L/DVB (13449): gspca - ov534: The AWB control works only when autogain is set. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index f2f844af54c..26d98b1312e 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -101,7 +101,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls_ov772x[] = { - { + { /* 0 */ { .id = V4L2_CID_BRIGHTNESS, .type = V4L2_CTRL_TYPE_INTEGER, @@ -115,7 +115,7 @@ static struct ctrl sd_ctrls_ov772x[] = { .set = sd_setbrightness, .get = sd_getbrightness, }, - { + { /* 1 */ { .id = V4L2_CID_CONTRAST, .type = V4L2_CTRL_TYPE_INTEGER, @@ -129,7 +129,7 @@ static struct ctrl sd_ctrls_ov772x[] = { .set = sd_setcontrast, .get = sd_getcontrast, }, - { + { /* 2 */ { .id = V4L2_CID_GAIN, .type = V4L2_CTRL_TYPE_INTEGER, @@ -143,7 +143,7 @@ static struct ctrl sd_ctrls_ov772x[] = { .set = sd_setgain, .get = sd_getgain, }, - { + { /* 3 */ { .id = V4L2_CID_EXPOSURE, .type = V4L2_CTRL_TYPE_INTEGER, @@ -157,7 +157,7 @@ static struct ctrl sd_ctrls_ov772x[] = { .set = sd_setexposure, .get = sd_getexposure, }, - { + { /* 4 */ { .id = V4L2_CID_RED_BALANCE, .type = V4L2_CTRL_TYPE_INTEGER, @@ -171,7 +171,7 @@ static struct ctrl sd_ctrls_ov772x[] = { .set = sd_setredblc, .get = sd_getredblc, }, - { + { /* 5 */ { .id = V4L2_CID_BLUE_BALANCE, .type = V4L2_CTRL_TYPE_INTEGER, @@ -185,7 +185,7 @@ static struct ctrl sd_ctrls_ov772x[] = { .set = sd_setblueblc, .get = sd_getblueblc, }, - { + { /* 6 */ { .id = V4L2_CID_HUE, .type = V4L2_CTRL_TYPE_INTEGER, @@ -199,7 +199,7 @@ static struct ctrl sd_ctrls_ov772x[] = { .set = sd_sethue, .get = sd_gethue, }, - { + { /* 7 */ { .id = V4L2_CID_AUTOGAIN, .type = V4L2_CTRL_TYPE_BOOLEAN, @@ -213,7 +213,8 @@ static struct ctrl sd_ctrls_ov772x[] = { .set = sd_setautogain, .get = sd_getautogain, }, - { +#define AWB_IDX 8 + { /* 8 */ { .id = V4L2_CID_AUTO_WHITE_BALANCE, .type = V4L2_CTRL_TYPE_BOOLEAN, @@ -227,7 +228,7 @@ static struct ctrl sd_ctrls_ov772x[] = { .set = sd_setawb, .get = sd_getawb, }, - { + { /* 9 */ { .id = V4L2_CID_SHARPNESS, .type = V4L2_CTRL_TYPE_INTEGER, @@ -241,7 +242,7 @@ static struct ctrl sd_ctrls_ov772x[] = { .set = sd_setsharpness, .get = sd_getsharpness, }, - { + { /* 10 */ { .id = V4L2_CID_HFLIP, .type = V4L2_CTRL_TYPE_BOOLEAN, @@ -255,7 +256,7 @@ static struct ctrl sd_ctrls_ov772x[] = { .set = sd_sethflip, .get = sd_gethflip, }, - { + { /* 11 */ { .id = V4L2_CID_VFLIP, .type = V4L2_CTRL_TYPE_BOOLEAN, @@ -1237,6 +1238,8 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->hue = HUE_DEF; #if AUTOGAIN_DEF != 0 sd->autogain = AUTOGAIN_DEF; +#else + gspca_dev->ctrl_inac |= (1 << AWB_IDX); #endif #if AWB_DEF != 0 sd->awb = AWB_DEF @@ -1606,6 +1609,13 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) struct sd *sd = (struct sd *) gspca_dev; sd->autogain = val; + + /* the auto white balance control works only when auto gain is set */ + if (val) + gspca_dev->ctrl_inac &= ~(1 << AWB_IDX); + else + gspca_dev->ctrl_inac |= (1 << AWB_IDX); + if (gspca_dev->streaming) setautogain(gspca_dev); return 0; -- cgit v1.2.3-70-g09d2 From 8157852f73f961b28d495bfa8374263d293b106d Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 13 Nov 2009 07:15:08 -0300 Subject: V4L/DVB (13450): gspca - main: Clear the urb status before resubmit. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 369eddd352c..08433f77245 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -139,6 +139,7 @@ static void fill_frame(struct gspca_dev *gspca_dev, return; #endif PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); + urb->status = 0; goto resubmit; } pkt_scan = gspca_dev->sd_desc->pkt_scan; @@ -214,15 +215,13 @@ static void bulk_irq(struct urb *urb) break; case -ESHUTDOWN: return; /* disconnection */ - case -ECONNRESET: - urb->status = 0; - break; default: #ifdef CONFIG_PM if (gspca_dev->frozen) return; #endif PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); + urb->status = 0; goto resubmit; } -- cgit v1.2.3-70-g09d2 From 3ec342f25004c87c0d94de1bc1b5399685d58ad8 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 13 Nov 2009 07:38:16 -0300 Subject: V4L/DVB (13451): gspca - main: Memorize the current frame buffer. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 21 +++++++++++---------- drivers/media/video/gspca/gspca.h | 1 + 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 08433f77245..31ec5aa4491 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -126,7 +126,6 @@ EXPORT_SYMBOL(gspca_get_i_frame); static void fill_frame(struct gspca_dev *gspca_dev, struct urb *urb) { - struct gspca_frame *frame; u8 *data; /* address of data in the iso message */ int i, len, st; cam_pkt_op pkt_scan; @@ -146,8 +145,8 @@ static void fill_frame(struct gspca_dev *gspca_dev, for (i = 0; i < urb->number_of_packets; i++) { /* check the availability of the frame buffer */ - frame = gspca_get_i_frame(gspca_dev); - if (!frame) { + if ((gspca_dev->cur_frame->v4l2_buf.flags & BUF_ALL_FLAGS) + != V4L2_BUF_FLAG_QUEUED) { gspca_dev->last_packet_type = DISCARD_PACKET; break; } @@ -173,7 +172,7 @@ static void fill_frame(struct gspca_dev *gspca_dev, i, urb->iso_frame_desc[i].offset, len); data = (u8 *) urb->transfer_buffer + urb->iso_frame_desc[i].offset; - pkt_scan(gspca_dev, frame, data, len); + pkt_scan(gspca_dev, gspca_dev->cur_frame, data, len); } resubmit: @@ -204,7 +203,6 @@ static void isoc_irq(struct urb *urb) static void bulk_irq(struct urb *urb) { struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; - struct gspca_frame *frame; int st; PDEBUG(D_PACK, "bulk irq"); @@ -226,13 +224,13 @@ static void bulk_irq(struct urb *urb) } /* check the availability of the frame buffer */ - frame = gspca_get_i_frame(gspca_dev); - if (!frame) { + if ((gspca_dev->cur_frame->v4l2_buf.flags & BUF_ALL_FLAGS) + != V4L2_BUF_FLAG_QUEUED) { gspca_dev->last_packet_type = DISCARD_PACKET; } else { PDEBUG(D_PACK, "packet l:%d", urb->actual_length); gspca_dev->sd_desc->pkt_scan(gspca_dev, - frame, + gspca_dev->frame, urb->transfer_buffer, urb->actual_length); } @@ -260,13 +258,15 @@ resubmit: */ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, enum gspca_packet_type packet_type, - struct gspca_frame *frame, + struct gspca_frame *dummy, const __u8 *data, int len) { + struct gspca_frame *frame; int i, j; PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len); + frame = gspca_dev->cur_frame; /* when start of a new frame, if the current frame buffer * is not queued, discard the whole frame */ @@ -315,7 +315,7 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, i, gspca_dev->fr_o); j = gspca_dev->fr_queue[i]; - frame = &gspca_dev->frame[j]; + gspca_dev->cur_frame = frame = &gspca_dev->frame[j]; } return frame; } @@ -398,6 +398,7 @@ static int frame_alloc(struct gspca_dev *gspca_dev, frame->v4l2_buf.m.offset = i * frsz; } gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; + gspca_dev->cur_frame = &gspca_dev->frame[0]; gspca_dev->last_packet_type = DISCARD_PACKET; gspca_dev->sequence = 0; return 0; diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index d59a684056c..59078bbf472 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -151,6 +151,7 @@ struct gspca_dev { __u8 *frbuf; /* buffer for nframes */ struct gspca_frame frame[GSPCA_MAX_FRAMES]; + struct gspca_frame *cur_frame; /* frame beeing filled */ __u32 frsz; /* frame size */ char nframes; /* number of frames */ char fr_i; /* frame being filled */ -- cgit v1.2.3-70-g09d2 From d131c3c9e136cb5a817094c3dc4b7261b495cd6e Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 13 Nov 2009 08:16:02 -0300 Subject: V4L/DVB (13452): gspca - main: Let the driver scan URB packets when no frame buffer. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 31ec5aa4491..68ba535300f 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -144,13 +144,6 @@ static void fill_frame(struct gspca_dev *gspca_dev, pkt_scan = gspca_dev->sd_desc->pkt_scan; for (i = 0; i < urb->number_of_packets; i++) { - /* check the availability of the frame buffer */ - if ((gspca_dev->cur_frame->v4l2_buf.flags & BUF_ALL_FLAGS) - != V4L2_BUF_FLAG_QUEUED) { - gspca_dev->last_packet_type = DISCARD_PACKET; - break; - } - /* check the packet status and length */ len = urb->iso_frame_desc[i].actual_length; if (len == 0) { @@ -223,17 +216,11 @@ static void bulk_irq(struct urb *urb) goto resubmit; } - /* check the availability of the frame buffer */ - if ((gspca_dev->cur_frame->v4l2_buf.flags & BUF_ALL_FLAGS) - != V4L2_BUF_FLAG_QUEUED) { - gspca_dev->last_packet_type = DISCARD_PACKET; - } else { - PDEBUG(D_PACK, "packet l:%d", urb->actual_length); - gspca_dev->sd_desc->pkt_scan(gspca_dev, - gspca_dev->frame, - urb->transfer_buffer, - urb->actual_length); - } + PDEBUG(D_PACK, "packet l:%d", urb->actual_length); + gspca_dev->sd_desc->pkt_scan(gspca_dev, + gspca_dev->frame, + urb->transfer_buffer, + urb->actual_length); resubmit: /* resubmit the URB */ @@ -266,16 +253,18 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, int i, j; PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len); + + /* check the availability of the frame buffer */ frame = gspca_dev->cur_frame; + if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS) + != V4L2_BUF_FLAG_QUEUED) { + gspca_dev->last_packet_type = DISCARD_PACKET; + return frame; + } /* when start of a new frame, if the current frame buffer * is not queued, discard the whole frame */ if (packet_type == FIRST_PACKET) { - if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS) - != V4L2_BUF_FLAG_QUEUED) { - gspca_dev->last_packet_type = DISCARD_PACKET; - return frame; - } frame->data_end = frame->data; jiffies_to_timeval(get_jiffies_64(), &frame->v4l2_buf.timestamp); -- cgit v1.2.3-70-g09d2 From 76dd272b56cd1c7fa013ef5d7eb28c4d319e322b Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 13 Nov 2009 09:21:03 -0300 Subject: V4L/DVB (13453): gspca - all subdrivers: Remove the unused frame ptr from pkt_scan(). Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/conex.c | 12 +++---- drivers/media/video/gspca/etoms.c | 10 +++--- drivers/media/video/gspca/finepix.c | 23 ++++-------- drivers/media/video/gspca/gl860/gl860.c | 10 +++--- drivers/media/video/gspca/gspca.c | 20 +++++------ drivers/media/video/gspca/gspca.h | 12 +++---- drivers/media/video/gspca/jeilinj.c | 21 +++++------ drivers/media/video/gspca/m5602/m5602_core.c | 25 ++++++++----- drivers/media/video/gspca/mars.c | 11 +++--- drivers/media/video/gspca/mr97310a.c | 11 +++--- drivers/media/video/gspca/ov519.c | 54 +++++++++++++--------------- drivers/media/video/gspca/ov534.c | 21 ++++++----- drivers/media/video/gspca/pac207.c | 11 +++--- drivers/media/video/gspca/pac7302.c | 22 +++++++----- drivers/media/video/gspca/pac7311.c | 22 +++++++----- drivers/media/video/gspca/sn9c20x.c | 11 +++--- drivers/media/video/gspca/sonixb.c | 21 ++++++----- drivers/media/video/gspca/sonixj.c | 7 ++-- drivers/media/video/gspca/spca500.c | 11 +++--- drivers/media/video/gspca/spca501.c | 14 +++----- drivers/media/video/gspca/spca505.c | 10 ++---- drivers/media/video/gspca/spca506.c | 12 +++---- drivers/media/video/gspca/spca508.c | 10 ++---- drivers/media/video/gspca/spca561.c | 14 +++----- drivers/media/video/gspca/sq905.c | 21 +++++------ drivers/media/video/gspca/sq905c.c | 12 +++---- drivers/media/video/gspca/stk014.c | 11 +++--- drivers/media/video/gspca/stv0680.c | 7 ++-- drivers/media/video/gspca/stv06xx/stv06xx.c | 11 +++--- drivers/media/video/gspca/sunplus.c | 11 +++--- drivers/media/video/gspca/t613.c | 7 ++-- drivers/media/video/gspca/tv8532.c | 7 ++-- drivers/media/video/gspca/vc032x.c | 21 ++++++----- drivers/media/video/gspca/w996Xcf.c | 13 ++++--- drivers/media/video/gspca/zc3xx.c | 11 +++--- 35 files changed, 240 insertions(+), 287 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c index eca003566ae..2f0b8d621e0 100644 --- a/drivers/media/video/gspca/conex.c +++ b/drivers/media/video/gspca/conex.c @@ -888,8 +888,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev) } static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ + u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; @@ -897,16 +896,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, if (data[0] == 0xff && data[1] == 0xd8) { /* start of frame */ - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, - data, 0); + gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); /* put the JPEG header in the new frame */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - sd->jpeg_hdr, JPEG_HDR_SZ); + gspca_frame_add(gspca_dev, FIRST_PACKET, + sd->jpeg_hdr, JPEG_HDR_SZ); data += 2; len -= 2; } - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } static void setbrightness(struct gspca_dev*gspca_dev) diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c index c1461e63647..9de86419ae1 100644 --- a/drivers/media/video/gspca/etoms.c +++ b/drivers/media/video/gspca/etoms.c @@ -752,8 +752,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) #undef LIMIT static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ + u8 *data, /* isoc packet */ int len) /* iso packet length */ { int seqframe; @@ -767,14 +766,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, data[2], data[3], data[4], data[5]); data += 30; /* don't change datalength as the chips provided it */ - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, - data, 0); - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); + gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); return; } if (len) { data += 8; - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } else { /* Drop Packet */ gspca_dev->last_packet_type = DISCARD_PACKET; } diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c index 480ec5c87d0..5d90e744857 100644 --- a/drivers/media/video/gspca/finepix.c +++ b/drivers/media/video/gspca/finepix.c @@ -82,7 +82,6 @@ static void dostream(struct work_struct *work) struct gspca_dev *gspca_dev = &dev->gspca_dev; struct urb *urb = gspca_dev->urb[0]; u8 *data = urb->transfer_buffer; - struct gspca_frame *frame; int ret = 0; int len; @@ -118,10 +117,6 @@ again: } if (!gspca_dev->present || !gspca_dev->streaming) goto out; - frame = gspca_get_i_frame(&dev->gspca_dev); - if (frame == NULL) - gspca_dev->last_packet_type = DISCARD_PACKET; - if (len < FPIX_MAX_TRANSFER || (data[len - 2] == 0xff && data[len - 1] == 0xd9)) { @@ -132,21 +127,17 @@ again: * but there's nothing we can do. We also end * here if the the jpeg ends right at the end * of the frame. */ - if (frame) - frame = gspca_frame_add(gspca_dev, - LAST_PACKET, - frame, - data, len); + gspca_frame_add(gspca_dev, LAST_PACKET, + data, len); break; } /* got a partial image */ - if (frame) - gspca_frame_add(gspca_dev, - gspca_dev->last_packet_type - == LAST_PACKET - ? FIRST_PACKET : INTER_PACKET, - frame, data, len); + gspca_frame_add(gspca_dev, + gspca_dev->last_packet_type + == LAST_PACKET + ? FIRST_PACKET : INTER_PACKET, + data, len); } /* We must wait before trying reading the next diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c index a2108dd7105..a695e0ae13c 100644 --- a/drivers/media/video/gspca/gl860/gl860.c +++ b/drivers/media/video/gspca/gl860/gl860.c @@ -36,7 +36,7 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev); static int sd_start(struct gspca_dev *gspca_dev); static void sd_stop0(struct gspca_dev *gspca_dev); static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, u8 *data, s32 len); + u8 *data, int len); static void sd_callback(struct gspca_dev *gspca_dev); static int gl860_guess_sensor(struct gspca_dev *gspca_dev, @@ -433,7 +433,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev) /* This function is called when an image is being received */ static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, u8 *data, s32 len) + u8 *data, int len) { struct sd *sd = (struct sd *) gspca_dev; static s32 nSkipped; @@ -445,11 +445,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, /* Test only against 0202h, so endianess does not matter */ switch (*(s16 *) data) { case 0x0202: /* End of frame, start a new one */ - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); + gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); nSkipped = 0; if (sd->nbIm >= 0 && sd->nbIm < 10) sd->nbIm++; - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0); + gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); break; default: @@ -464,7 +464,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, nSkipped = nToSkip + 1; } gspca_frame_add(gspca_dev, - INTER_PACKET, frame, data, len); + INTER_PACKET, data, len); } break; } diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 68ba535300f..4076f8e5a6f 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -165,7 +165,7 @@ static void fill_frame(struct gspca_dev *gspca_dev, i, urb->iso_frame_desc[i].offset, len); data = (u8 *) urb->transfer_buffer + urb->iso_frame_desc[i].offset; - pkt_scan(gspca_dev, gspca_dev->cur_frame, data, len); + pkt_scan(gspca_dev, data, len); } resubmit: @@ -218,7 +218,6 @@ static void bulk_irq(struct urb *urb) PDEBUG(D_PACK, "packet l:%d", urb->actual_length); gspca_dev->sd_desc->pkt_scan(gspca_dev, - gspca_dev->frame, urb->transfer_buffer, urb->actual_length); @@ -243,11 +242,10 @@ resubmit: * DISCARD_PACKET invalidates the whole frame. * On LAST_PACKET, a new frame is returned. */ -struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, - enum gspca_packet_type packet_type, - struct gspca_frame *dummy, - const __u8 *data, - int len) +void gspca_frame_add(struct gspca_dev *gspca_dev, + enum gspca_packet_type packet_type, + const u8 *data, + int len) { struct gspca_frame *frame; int i, j; @@ -259,7 +257,7 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS) != V4L2_BUF_FLAG_QUEUED) { gspca_dev->last_packet_type = DISCARD_PACKET; - return frame; + return; } /* when start of a new frame, if the current frame buffer @@ -272,7 +270,7 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, } else if (gspca_dev->last_packet_type == DISCARD_PACKET) { if (packet_type == LAST_PACKET) gspca_dev->last_packet_type = packet_type; - return frame; + return; } /* append the packet to the frame buffer */ @@ -304,9 +302,9 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, i, gspca_dev->fr_o); j = gspca_dev->fr_queue[i]; - gspca_dev->cur_frame = frame = &gspca_dev->frame[j]; + gspca_dev->cur_frame = &gspca_dev->frame[j]; } - return frame; + return; } EXPORT_SYMBOL(gspca_frame_add); diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 59078bbf472..181617355ec 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -79,8 +79,7 @@ typedef int (*cam_streamparm_op) (struct gspca_dev *, typedef int (*cam_qmnu_op) (struct gspca_dev *, struct v4l2_querymenu *); typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, - struct gspca_frame *frame, - __u8 *data, + u8 *data, int len); struct ctrl { @@ -192,11 +191,10 @@ int gspca_dev_probe(struct usb_interface *intf, int dev_size, struct module *module); void gspca_disconnect(struct usb_interface *intf); -struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, - enum gspca_packet_type packet_type, - struct gspca_frame *frame, - const __u8 *data, - int len); +void gspca_frame_add(struct gspca_dev *gspca_dev, + enum gspca_packet_type packet_type, + const u8 *data, + int len); struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev); #ifdef CONFIG_PM int gspca_suspend(struct usb_interface *intf, pm_message_t message); diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c index d679970d5b3..2019b04f923 100644 --- a/drivers/media/video/gspca/jeilinj.c +++ b/drivers/media/video/gspca/jeilinj.c @@ -181,7 +181,6 @@ static void jlj_dostream(struct work_struct *work) { struct sd *dev = container_of(work, struct sd, work_struct); struct gspca_dev *gspca_dev = &dev->gspca_dev; - struct gspca_frame *frame; int blocks_left; /* 0x200-sized blocks remaining in current frame. */ int size_in_blocks; int act_len; @@ -214,15 +213,13 @@ static void jlj_dostream(struct work_struct *work) PDEBUG(D_STREAM, "blocks_left = 0x%x", blocks_left); /* Start a new frame, and add the JPEG header, first thing */ - frame = gspca_get_i_frame(gspca_dev); - if (frame) { - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - dev->jpeg_hdr, JPEG_HDR_SZ); - /* Toss line 0 of data block 0, keep the rest. */ - gspca_frame_add(gspca_dev, INTER_PACKET, - frame, buffer + FRAME_HEADER_LEN, + gspca_frame_add(gspca_dev, FIRST_PACKET, + dev->jpeg_hdr, JPEG_HDR_SZ); + /* Toss line 0 of data block 0, keep the rest. */ + gspca_frame_add(gspca_dev, INTER_PACKET, + buffer + FRAME_HEADER_LEN, JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN); - } + while (blocks_left > 0) { if (!gspca_dev->present) goto quit_stream; @@ -239,10 +236,8 @@ static void jlj_dostream(struct work_struct *work) packet_type = LAST_PACKET; else packet_type = INTER_PACKET; - if (frame) - gspca_frame_add(gspca_dev, packet_type, - frame, buffer, - JEILINJ_MAX_TRANSFER); + gspca_frame_add(gspca_dev, packet_type, + buffer, JEILINJ_MAX_TRANSFER); } } quit_stream: diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c index 7f1e5415850..844fc1d886d 100644 --- a/drivers/media/video/gspca/m5602/m5602_core.c +++ b/drivers/media/video/gspca/m5602/m5602_core.c @@ -274,8 +274,7 @@ static int m5602_start_transfer(struct gspca_dev *gspca_dev) } static void m5602_urb_complete(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, - __u8 *data, int len) + u8 *data, int len) { struct sd *sd = (struct sd *) gspca_dev; @@ -295,19 +294,27 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev, len -= 6; /* Complete the last frame (if any) */ - frame = gspca_frame_add(gspca_dev, LAST_PACKET, - frame, data, 0); + gspca_frame_add(gspca_dev, LAST_PACKET, + NULL, 0); sd->frame_count++; /* Create a new frame */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); PDEBUG(D_FRAM, "Starting new frame %d", sd->frame_count); } else { - int cur_frame_len = frame->data_end - frame->data; + struct gspca_frame *frame; + int cur_frame_len; + frame = gspca_get_i_frame(gspca_dev); + if (frame == NULL) { + gspca_dev->last_packet_type = DISCARD_PACKET; + return; + } + + cur_frame_len = frame->data_end - frame->data; /* Remove urb header */ data += 4; len -= 4; @@ -316,12 +323,12 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev, PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes", sd->frame_count, len); - gspca_frame_add(gspca_dev, INTER_PACKET, frame, + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } else if (frame->v4l2_buf.length - cur_frame_len > 0) { /* Add the remaining data up to frame size */ - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, - frame->v4l2_buf.length - cur_frame_len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, + frame->v4l2_buf.length - cur_frame_len); } } } diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c index de769caf013..9cf8d68c71b 100644 --- a/drivers/media/video/gspca/mars.c +++ b/drivers/media/video/gspca/mars.c @@ -325,8 +325,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev) } static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ + u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; @@ -348,11 +347,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, || data[5 + p] == 0x67) { PDEBUG(D_PACK, "sof offset: %d len: %d", p, len); - frame = gspca_frame_add(gspca_dev, LAST_PACKET, - frame, data, p); + gspca_frame_add(gspca_dev, LAST_PACKET, + data, p); /* put the JPEG header */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + gspca_frame_add(gspca_dev, FIRST_PACKET, sd->jpeg_hdr, JPEG_HDR_SZ); data += p + 16; len -= p + 16; @@ -360,7 +359,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, } } } - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index ffb5e6d62c0..126d968dd9e 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c @@ -1030,9 +1030,8 @@ static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val) #include "pac_common.h" static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ - int len) /* iso packet length */ + u8 *data, /* isoc packet */ + int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; unsigned char *sof; @@ -1047,15 +1046,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, n -= sizeof pac_sof_marker; else n = 0; - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + gspca_frame_add(gspca_dev, LAST_PACKET, data, n); /* Start next frame. */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + gspca_frame_add(gspca_dev, FIRST_PACKET, pac_sof_marker, sizeof pac_sof_marker); len -= sof - data; data = sof; } - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } /* sub-driver description */ diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index f88a526e216..ad9ec339981 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -3920,9 +3920,8 @@ static void sd_stop0(struct gspca_dev *gspca_dev) } static void ov511_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *in, /* isoc packet */ - int len) /* iso packet length */ + u8 *in, /* isoc packet */ + int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; @@ -3953,11 +3952,11 @@ static void ov511_pkt_scan(struct gspca_dev *gspca_dev, return; } /* Add 11 byte footer to frame, might be usefull */ - gspca_frame_add(gspca_dev, LAST_PACKET, frame, in, 11); + gspca_frame_add(gspca_dev, LAST_PACKET, in, 11); return; } else { /* Frame start */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, in, 0); + gspca_frame_add(gspca_dev, FIRST_PACKET, in, 0); sd->packet_nr = 0; } } @@ -3966,12 +3965,11 @@ static void ov511_pkt_scan(struct gspca_dev *gspca_dev, len--; /* intermediate packet */ - gspca_frame_add(gspca_dev, INTER_PACKET, frame, in, len); + gspca_frame_add(gspca_dev, INTER_PACKET, in, len); } static void ov518_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ + u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; @@ -3979,8 +3977,8 @@ static void ov518_pkt_scan(struct gspca_dev *gspca_dev, /* A false positive here is likely, until OVT gives me * the definitive SOF/EOF format */ if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) { - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0); + gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); + gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); sd->packet_nr = 0; } @@ -4004,12 +4002,11 @@ static void ov518_pkt_scan(struct gspca_dev *gspca_dev, } /* intermediate packet */ - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } static void ov519_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ + u8 *data, /* isoc packet */ int len) /* iso packet length */ { /* Header of ov519 is 16 bytes: @@ -4032,7 +4029,7 @@ static void ov519_pkt_scan(struct gspca_dev *gspca_dev, len -= HDRSZ; #undef HDRSZ if (data[0] == 0xff || data[1] == 0xd8) - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); else gspca_dev->last_packet_type = DISCARD_PACKET; @@ -4040,34 +4037,31 @@ static void ov519_pkt_scan(struct gspca_dev *gspca_dev, case 0x51: /* end of frame */ if (data[9] != 0) gspca_dev->last_packet_type = DISCARD_PACKET; - gspca_frame_add(gspca_dev, LAST_PACKET, frame, - data, 0); + gspca_frame_add(gspca_dev, LAST_PACKET, + NULL, 0); return; } } /* intermediate packet */ - gspca_frame_add(gspca_dev, INTER_PACKET, frame, - data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ + u8 *data, /* isoc packet */ int len) /* iso packet length */ { /* A short read signals EOF */ if (len < OVFX2_BULK_SIZE) { - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, len); - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0); + gspca_frame_add(gspca_dev, LAST_PACKET, data, len); + gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); return; } - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ + u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; @@ -4075,20 +4069,20 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, switch (sd->bridge) { case BRIDGE_OV511: case BRIDGE_OV511PLUS: - ov511_pkt_scan(gspca_dev, frame, data, len); + ov511_pkt_scan(gspca_dev, data, len); break; case BRIDGE_OV518: case BRIDGE_OV518PLUS: - ov518_pkt_scan(gspca_dev, frame, data, len); + ov518_pkt_scan(gspca_dev, data, len); break; case BRIDGE_OV519: - ov519_pkt_scan(gspca_dev, frame, data, len); + ov519_pkt_scan(gspca_dev, data, len); break; case BRIDGE_OVFX2: - ovfx2_pkt_scan(gspca_dev, frame, data, len); + ovfx2_pkt_scan(gspca_dev, data, len); break; case BRIDGE_W9968CF: - w9968cf_pkt_scan(gspca_dev, frame, data, len); + w9968cf_pkt_scan(gspca_dev, data, len); break; } } diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 26d98b1312e..193129a59ab 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -1403,8 +1403,8 @@ static void sd_stopN_ov965x(struct gspca_dev *gspca_dev) #define UVC_STREAM_EOF (1 << 1) #define UVC_STREAM_FID (1 << 0) -static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, - __u8 *data, int len) +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + u8 *data, int len) { struct sd *sd = (struct sd *) gspca_dev; __u32 this_pts; @@ -1445,23 +1445,22 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* If PTS or FID has changed, start a new frame. */ if (this_pts != sd->last_pts || this_fid != sd->last_fid) { if (gspca_dev->last_packet_type == INTER_PACKET) - frame = gspca_frame_add(gspca_dev, - LAST_PACKET, frame, - NULL, 0); + gspca_frame_add(gspca_dev, LAST_PACKET, + NULL, 0); sd->last_pts = this_pts; sd->last_fid = this_fid; - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + gspca_frame_add(gspca_dev, FIRST_PACKET, data + 12, len - 12); /* If this packet is marked as EOF, end the frame */ } else if (data[1] & UVC_STREAM_EOF) { sd->last_pts = 0; - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, - data + 12, len - 12); + gspca_frame_add(gspca_dev, LAST_PACKET, + data + 12, len - 12); } else { /* Add the data from this payload */ - gspca_frame_add(gspca_dev, INTER_PACKET, frame, - data + 12, len - 12); + gspca_frame_add(gspca_dev, INTER_PACKET, + data + 12, len - 12); } /* Done this payload */ @@ -1469,7 +1468,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, discard: /* Discard data until a new frame starts. */ - gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0); + gspca_dev->last_packet_type = DISCARD_PACKET; scan_next: remaining_len -= len; diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index 57e13e2d550..4706a823add 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c @@ -337,8 +337,7 @@ static void pac207_do_auto_gain(struct gspca_dev *gspca_dev) } static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, - __u8 *data, + u8 *data, int len) { struct sd *sd = (struct sd *) gspca_dev; @@ -354,10 +353,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, n -= sizeof pac_sof_marker; else n = 0; - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, - data, n); + gspca_frame_add(gspca_dev, LAST_PACKET, + data, n); sd->header_read = 0; - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0); + gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); len -= sof - data; data = sof; } @@ -381,7 +380,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, sd->header_read = 11; } - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } static void setbrightness(struct gspca_dev *gspca_dev) diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index e0fd767984b..74acceea809 100644 --- a/drivers/media/video/gspca/pac7302.c +++ b/drivers/media/video/gspca/pac7302.c @@ -855,7 +855,7 @@ static void pac_start_frame(struct gspca_dev *gspca_dev, { unsigned char tmpbuf[4]; - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + gspca_frame_add(gspca_dev, FIRST_PACKET, pac_jpeg_header1, sizeof(pac_jpeg_header1)); tmpbuf[0] = lines >> 8; @@ -863,25 +863,31 @@ static void pac_start_frame(struct gspca_dev *gspca_dev, tmpbuf[2] = samples_per_line >> 8; tmpbuf[3] = samples_per_line & 0xff; - gspca_frame_add(gspca_dev, INTER_PACKET, frame, + gspca_frame_add(gspca_dev, INTER_PACKET, tmpbuf, sizeof(tmpbuf)); - gspca_frame_add(gspca_dev, INTER_PACKET, frame, + gspca_frame_add(gspca_dev, INTER_PACKET, pac_jpeg_header2, sizeof(pac_jpeg_header2)); } /* this function is run at interrupt level */ static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ + u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; + struct gspca_frame *frame; unsigned char *sof; sof = pac_find_sof(&sd->sof_read, data, len); if (sof) { int n, lum_offset, footer_length; + frame = gspca_get_i_frame(gspca_dev); + if (frame == NULL) { + gspca_dev->last_packet_type = DISCARD_PACKET; + return; + } + /* 6 bytes after the FF D9 EOF marker a number of lumination bytes are send corresponding to different parts of the image, the 14th and 15th byte after the EOF seem to @@ -895,12 +901,12 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, frame->data_end += n; n = 0; } - frame = gspca_frame_add(gspca_dev, INTER_PACKET, frame, + gspca_frame_add(gspca_dev, INTER_PACKET, data, n); if (gspca_dev->last_packet_type != DISCARD_PACKET && frame->data_end[-2] == 0xff && frame->data_end[-1] == 0xd9) - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); n = sof - data; @@ -920,7 +926,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, pac_start_frame(gspca_dev, frame, gspca_dev->width, gspca_dev->height); } - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 1a27da00ccc..e5697a6345e 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -653,7 +653,7 @@ static void pac_start_frame(struct gspca_dev *gspca_dev, { unsigned char tmpbuf[4]; - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + gspca_frame_add(gspca_dev, FIRST_PACKET, pac_jpeg_header1, sizeof(pac_jpeg_header1)); tmpbuf[0] = lines >> 8; @@ -661,25 +661,31 @@ static void pac_start_frame(struct gspca_dev *gspca_dev, tmpbuf[2] = samples_per_line >> 8; tmpbuf[3] = samples_per_line & 0xff; - gspca_frame_add(gspca_dev, INTER_PACKET, frame, + gspca_frame_add(gspca_dev, INTER_PACKET, tmpbuf, sizeof(tmpbuf)); - gspca_frame_add(gspca_dev, INTER_PACKET, frame, + gspca_frame_add(gspca_dev, INTER_PACKET, pac_jpeg_header2, sizeof(pac_jpeg_header2)); } /* this function is run at interrupt level */ static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ + u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; unsigned char *sof; + struct gspca_frame *frame; sof = pac_find_sof(&sd->sof_read, data, len); if (sof) { int n, lum_offset, footer_length; + frame = gspca_get_i_frame(gspca_dev); + if (frame == NULL) { + gspca_dev->last_packet_type = DISCARD_PACKET; + return; + } + /* 6 bytes after the FF D9 EOF marker a number of lumination bytes are send corresponding to different parts of the image, the 14th and 15th byte after the EOF seem to @@ -693,12 +699,12 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, frame->data_end += n; n = 0; } - frame = gspca_frame_add(gspca_dev, INTER_PACKET, frame, + gspca_frame_add(gspca_dev, INTER_PACKET, data, n); if (gspca_dev->last_packet_type != DISCARD_PACKET && frame->data_end[-2] == 0xff && frame->data_end[-1] == 0xd9) - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); n = sof - data; @@ -717,7 +723,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, pac_start_frame(gspca_dev, frame, gspca_dev->height, gspca_dev->width); } - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index cdad3db3336..b1944a7cbb0 100644 --- a/drivers/media/video/gspca/sn9c20x.c +++ b/drivers/media/video/gspca/sn9c20x.c @@ -2342,7 +2342,6 @@ static void sd_dqcallback(struct gspca_dev *gspca_dev) } static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ u8 *data, /* isoc packet */ int len) /* iso packet length */ { @@ -2378,22 +2377,22 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, avg_lum >>= 9; atomic_set(&sd->avg_lum, avg_lum); gspca_frame_add(gspca_dev, LAST_PACKET, - frame, data, len); + data, len); return; } if (gspca_dev->last_packet_type == LAST_PACKET) { if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & MODE_JPEG) { - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + gspca_frame_add(gspca_dev, FIRST_PACKET, sd->jpeg_hdr, JPEG_HDR_SZ); - gspca_frame_add(gspca_dev, INTER_PACKET, frame, + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } else { - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); } } else { - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } } diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index cf3af8de6e9..a9f061063b4 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -995,8 +995,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) } static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - unsigned char *data, /* isoc packet */ + u8 *data, /* isoc packet */ int len) /* iso packet length */ { int i; @@ -1054,12 +1053,12 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, pkt_type = DISCARD_PACKET; } - frame = gspca_frame_add(gspca_dev, pkt_type, - frame, data, 0); + gspca_frame_add(gspca_dev, pkt_type, + NULL, 0); data += i + fr_h_sz; len -= i + fr_h_sz; gspca_frame_add(gspca_dev, FIRST_PACKET, - frame, data, len); + data, len); return; } } @@ -1068,15 +1067,21 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) { /* In raw mode we sometimes get some garbage after the frame ignore this */ - int used = frame->data_end - frame->data; + struct gspca_frame *frame; + int used; int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage; + frame = gspca_get_i_frame(gspca_dev); + if (frame == NULL) { + gspca_dev->last_packet_type = DISCARD_PACKET; + return; + } + used = frame->data_end - frame->data; if (used + len > size) len = size - used; } - gspca_frame_add(gspca_dev, INTER_PACKET, - frame, data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 5f82efb93d9..282c707e5e8 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -1993,7 +1993,6 @@ static void do_autogain(struct gspca_dev *gspca_dev) /* scan the URB packets */ /* This function is run at interrupt level. */ static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ u8 *data, /* isoc packet */ int len) /* iso packet length */ { @@ -2005,7 +2004,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, /* end of frame */ gspca_frame_add(gspca_dev, LAST_PACKET, - frame, data, sof + 2); + data, sof + 2); if (sd->ag_cnt < 0) return; /* w1 w2 w3 */ @@ -2028,10 +2027,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, if (gspca_dev->last_packet_type == LAST_PACKET) { /* put the JPEG 422 header */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + gspca_frame_add(gspca_dev, FIRST_PACKET, sd->jpeg_hdr, JPEG_HDR_SZ); } - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index fab7ef85a6c..8bd844d319e 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c @@ -899,8 +899,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev) } static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ + u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; @@ -913,11 +912,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, /* gspca_dev->last_packet_type = DISCARD_PACKET; */ return; } - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + gspca_frame_add(gspca_dev, LAST_PACKET, ffd9, 2); /* put the JPEG header in the new frame */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + gspca_frame_add(gspca_dev, FIRST_PACKET, sd->jpeg_hdr, JPEG_HDR_SZ); data += SPCA500_OFFSET_DATA; @@ -931,7 +930,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, i = 0; do { if (data[i] == 0xff) { - gspca_frame_add(gspca_dev, INTER_PACKET, frame, + gspca_frame_add(gspca_dev, INTER_PACKET, data, i + 1); len -= i; data += i; @@ -940,7 +939,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, } i++; } while (i < len); - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } static void setbrightness(struct gspca_dev *gspca_dev) diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c index b74a34218da..d251f145a75 100644 --- a/drivers/media/video/gspca/spca501.c +++ b/drivers/media/video/gspca/spca501.c @@ -2032,20 +2032,15 @@ static void sd_stop0(struct gspca_dev *gspca_dev) } static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ + u8 *data, /* isoc packet */ int len) /* iso packet length */ { switch (data[0]) { case 0: /* start of frame */ - frame = gspca_frame_add(gspca_dev, - LAST_PACKET, - frame, - data, 0); + gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); data += SPCA501_OFFSET_DATA; len -= SPCA501_OFFSET_DATA; - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - data, len); + gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); return; case 0xff: /* drop */ /* gspca_dev->last_packet_type = DISCARD_PACKET; */ @@ -2053,8 +2048,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, } data++; len--; - gspca_frame_add(gspca_dev, INTER_PACKET, frame, - data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index ea8c9fe2e96..0f9232ff128 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c @@ -739,26 +739,22 @@ static void sd_stop0(struct gspca_dev *gspca_dev) } static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ u8 *data, /* isoc packet */ int len) /* iso packet length */ { switch (data[0]) { case 0: /* start of frame */ - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, - data, 0); + gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); data += SPCA50X_OFFSET_DATA; len -= SPCA50X_OFFSET_DATA; - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - data, len); + gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); break; case 0xff: /* drop */ break; default: data += 1; len -= 1; - gspca_frame_add(gspca_dev, INTER_PACKET, frame, - data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); break; } } diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c index a199298a641..ab28cc23e41 100644 --- a/drivers/media/video/gspca/spca506.c +++ b/drivers/media/video/gspca/spca506.c @@ -543,18 +543,15 @@ static void sd_stopN(struct gspca_dev *gspca_dev) } static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ + u8 *data, /* isoc packet */ int len) /* iso packet length */ { switch (data[0]) { case 0: /* start of frame */ - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, - data, 0); + gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); data += SPCA50X_OFFSET_DATA; len -= SPCA50X_OFFSET_DATA; - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - data, len); + gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); break; case 0xff: /* drop */ /* gspca_dev->last_packet_type = DISCARD_PACKET; */ @@ -562,8 +559,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, default: data += 1; len -= 1; - gspca_frame_add(gspca_dev, INTER_PACKET, frame, - data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); break; } } diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index 9696c4caf5c..4d8e6cf75d5 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c @@ -1447,26 +1447,22 @@ static void sd_stopN(struct gspca_dev *gspca_dev) } static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ u8 *data, /* isoc packet */ int len) /* iso packet length */ { switch (data[0]) { case 0: /* start of frame */ - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, - data, 0); + gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); data += SPCA508_OFFSET_DATA; len -= SPCA508_OFFSET_DATA; - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - data, len); + gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); break; case 0xff: /* drop */ break; default: data += 1; len -= 1; - gspca_frame_add(gspca_dev, INTER_PACKET, frame, - data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); break; } } diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index 27e82b35f3e..58c2f0039af 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c @@ -779,8 +779,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) } static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ + u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; @@ -788,12 +787,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, len--; switch (*data++) { /* sequence number */ case 0: /* start of frame */ - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, - data, 0); + gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); if (data[1] & 0x10) { /* compressed bayer */ - gspca_frame_add(gspca_dev, FIRST_PACKET, - frame, data, len); + gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); } else { /* raw bayer (with a header, which we skip) */ if (sd->chip_revision == Rev012A) { @@ -803,14 +800,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, data += 16; len -= 16; } - gspca_frame_add(gspca_dev, FIRST_PACKET, - frame, data, len); + gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); } return; case 0xff: /* drop (empty mpackets) */ return; } - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } /* rev 72a only */ diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c index 547d1fd5191..1fcaca6a87f 100644 --- a/drivers/media/video/gspca/sq905.c +++ b/drivers/media/video/gspca/sq905.c @@ -214,7 +214,6 @@ static void sq905_dostream(struct work_struct *work) { struct sd *dev = container_of(work, struct sd, work_struct); struct gspca_dev *gspca_dev = &dev->gspca_dev; - struct gspca_frame *frame; int bytes_left; /* bytes remaining in current frame. */ int data_len; /* size to use for the next read. */ int header_read; /* true if we have already read the frame header. */ @@ -266,18 +265,14 @@ static void sq905_dostream(struct work_struct *work) } else { packet_type = INTER_PACKET; } - frame = gspca_get_i_frame(gspca_dev); - if (frame) { - frame = gspca_frame_add(gspca_dev, packet_type, - frame, data, data_len); - /* If entire frame fits in one packet we still - need to add a LAST_PACKET */ - if (packet_type == FIRST_PACKET && - bytes_left == 0) - frame = gspca_frame_add(gspca_dev, - LAST_PACKET, - frame, data, 0); - } + gspca_frame_add(gspca_dev, packet_type, + data, data_len); + /* If entire frame fits in one packet we still + need to add a LAST_PACKET */ + if (packet_type == FIRST_PACKET && + bytes_left == 0) + gspca_frame_add(gspca_dev, LAST_PACKET, + NULL, 0); } if (gspca_dev->present) { /* acknowledge the frame */ diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c index 81020f6f739..d70b156872d 100644 --- a/drivers/media/video/gspca/sq905c.c +++ b/drivers/media/video/gspca/sq905c.c @@ -115,7 +115,6 @@ static void sq905c_dostream(struct work_struct *work) { struct sd *dev = container_of(work, struct sd, work_struct); struct gspca_dev *gspca_dev = &dev->gspca_dev; - struct gspca_frame *frame; int bytes_left; /* bytes remaining in current frame. */ int data_len; /* size to use for the next read. */ int act_len; @@ -146,10 +145,8 @@ static void sq905c_dostream(struct work_struct *work) PDEBUG(D_STREAM, "bytes_left = 0x%x", bytes_left); /* We keep the header. It has other information, too. */ packet_type = FIRST_PACKET; - frame = gspca_get_i_frame(gspca_dev); - if (frame) - gspca_frame_add(gspca_dev, packet_type, - frame, buffer, FRAME_HEADER_LEN); + gspca_frame_add(gspca_dev, packet_type, + buffer, FRAME_HEADER_LEN); while (bytes_left > 0 && gspca_dev->present) { data_len = bytes_left > SQ905C_MAX_TRANSFER ? SQ905C_MAX_TRANSFER : bytes_left; @@ -167,9 +164,8 @@ static void sq905c_dostream(struct work_struct *work) packet_type = LAST_PACKET; else packet_type = INTER_PACKET; - if (frame) - gspca_frame_add(gspca_dev, packet_type, - frame, buffer, data_len); + gspca_frame_add(gspca_dev, packet_type, + buffer, data_len); } } quit_stream: diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c index 47628964801..8e23320d7ab 100644 --- a/drivers/media/video/gspca/stk014.c +++ b/drivers/media/video/gspca/stk014.c @@ -418,8 +418,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev) } static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ + u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; @@ -435,11 +434,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, * (without ending - ff d9) */ if (data[0] == 0xff && data[1] == 0xfe) { - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, - ffd9, 2); + gspca_frame_add(gspca_dev, LAST_PACKET, + ffd9, 2); /* put the JPEG 411 header */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + gspca_frame_add(gspca_dev, FIRST_PACKET, sd->jpeg_hdr, JPEG_HDR_SZ); /* beginning of the frame */ @@ -447,7 +446,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, data += STKHDRSZ; len -= STKHDRSZ; } - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) diff --git a/drivers/media/video/gspca/stv0680.c b/drivers/media/video/gspca/stv0680.c index 0981ce14235..2a69d7ccb50 100644 --- a/drivers/media/video/gspca/stv0680.c +++ b/drivers/media/video/gspca/stv0680.c @@ -281,8 +281,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev) } static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, - __u8 *data, + u8 *data, int len) { struct sd *sd = (struct sd *) gspca_dev; @@ -299,10 +298,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, /* Finish the previous frame, we do this upon reception of the next packet, even though it is already complete so that the strange 16 byte packets send after a corrupt frame can discard it. */ - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, NULL, 0); + gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); /* Store the just received frame */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); } /* sub-driver description */ diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c index bfae63f5584..5d0241bb161 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx.c @@ -312,8 +312,7 @@ out: * The 0005 and 0100 chunks seem to appear only in compressed stream. */ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ + u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; @@ -366,7 +365,7 @@ frame_data: sd->to_skip -= skip; } - gspca_frame_add(gspca_dev, INTER_PACKET, frame, + gspca_frame_add(gspca_dev, INTER_PACKET, data, chunk_len); break; @@ -378,7 +377,7 @@ frame_data: /* Create a new frame, chunk length should be zero */ gspca_frame_add(gspca_dev, FIRST_PACKET, - frame, data, 0); + NULL, 0); if (sd->bridge == BRIDGE_ST6422) sd->to_skip = gspca_dev->width * 4; @@ -394,8 +393,8 @@ frame_data: PDEBUG(D_PACK, "End of frame detected"); /* Complete the last frame (if any) */ - frame = gspca_frame_add(gspca_dev, LAST_PACKET, - frame, data, 0); + gspca_frame_add(gspca_dev, LAST_PACKET, + NULL, 0); if (chunk_len) PDEBUG(D_ERR, "Chunk length is " diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index aa8f995ce04..682652cb7fe 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c @@ -1116,7 +1116,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev) } static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ u8 *data, /* isoc packet */ int len) /* iso packet length */ { @@ -1186,11 +1185,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, break; } if (sof) { /* start of frame */ - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, - ffd9, 2); + gspca_frame_add(gspca_dev, LAST_PACKET, + ffd9, 2); /* put the JPEG header in the new frame */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + gspca_frame_add(gspca_dev, FIRST_PACKET, sd->jpeg_hdr, JPEG_HDR_SZ); } @@ -1198,7 +1197,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, i = 0; do { if (data[i] == 0xff) { - gspca_frame_add(gspca_dev, INTER_PACKET, frame, + gspca_frame_add(gspca_dev, INTER_PACKET, data, i + 1); len -= i; data += i; @@ -1207,7 +1206,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, } i++; } while (i < len); - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index 1d321c30d22..55ef6a74442 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c @@ -938,7 +938,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev) } static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ u8 *data, /* isoc packet */ int len) /* iso packet length */ { @@ -956,9 +955,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, /* extra bytes....., could be processed too but would be * a waste of time, right now leave the application and * libjpeg do it for ourserlves.. */ - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + gspca_frame_add(gspca_dev, LAST_PACKET, ffd9, 2); - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); return; } @@ -967,7 +966,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, * other's do not include it... */ len -= 2; } - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c index 4b44dde9f8b..b74a3b6489c 100644 --- a/drivers/media/video/gspca/tv8532.c +++ b/drivers/media/video/gspca/tv8532.c @@ -398,8 +398,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) } static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ + u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; @@ -424,9 +423,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, * - 4 bytes */ gspca_frame_add(gspca_dev, packet_type0, - frame, data + 2, gspca_dev->width); + data + 2, gspca_dev->width); gspca_frame_add(gspca_dev, packet_type1, - frame, data + gspca_dev->width + 5, gspca_dev->width); + data + gspca_dev->width + 5, gspca_dev->width); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index 589042f6adb..26675236fbd 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c @@ -2987,7 +2987,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev) } static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ u8 *data, /* isoc packet */ int len) /* iso pkt length */ { @@ -2996,21 +2995,25 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, if (data[0] == 0xff && data[1] == 0xd8) { PDEBUG(D_PACK, "vc032x header packet found len %d", len); - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, - data, 0); + gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); data += sd->image_offset; len -= sd->image_offset; - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - data, len); + gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); return; } /* The vc0321 sends some additional data after sending the complete * frame, we ignore this. */ - if (sd->bridge == BRIDGE_VC0321 - && len > frame->v4l2_buf.length - (frame->data_end - frame->data)) - len = frame->v4l2_buf.length - (frame->data_end - frame->data); - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + if (sd->bridge == BRIDGE_VC0321) { + struct gspca_frame *frame; + int l; + + frame = gspca_get_i_frame(gspca_dev); + l = frame->data_end - frame->data; + if (len > frame->v4l2_buf.length - l) + len = frame->v4l2_buf.length - l; + } + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c index 4f9add79ce1..2fffe203bed 100644 --- a/drivers/media/video/gspca/w996Xcf.c +++ b/drivers/media/video/gspca/w996Xcf.c @@ -576,8 +576,7 @@ static void w9968cf_stop0(struct sd *sd) to be precise it sends: SOI, SOF, DRI, SOS, Y-data, SOS, U-data, SOS, V-data, EOI. */ static void w9968cf_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ + u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; @@ -587,9 +586,9 @@ static void w9968cf_pkt_scan(struct gspca_dev *gspca_dev, if (len >= 2 && data[0] == 0xff && data[1] == 0xd8) { - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + gspca_frame_add(gspca_dev, FIRST_PACKET, sd->jpeg_hdr, JPEG_HDR_SZ); /* Strip the ff d8, our own header (which adds huffman and quantization tables) already has this */ @@ -599,12 +598,12 @@ static void w9968cf_pkt_scan(struct gspca_dev *gspca_dev, } else { /* In UYVY mode an empty packet signals EOF */ if (gspca_dev->empty_packet) { - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); gspca_dev->empty_packet = 0; } } - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 11305079224..864974b6114 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -6974,17 +6974,16 @@ static void sd_stop0(struct gspca_dev *gspca_dev) } static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, - __u8 *data, + u8 *data, int len) { struct sd *sd = (struct sd *) gspca_dev; if (data[0] == 0xff && data[1] == 0xd8) { /* start of frame */ - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, - data, 0); + gspca_frame_add(gspca_dev, LAST_PACKET, + NULL, 0); /* put the JPEG header in the new frame */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + gspca_frame_add(gspca_dev, FIRST_PACKET, sd->jpeg_hdr, JPEG_HDR_SZ); /* remove the webcam's header: @@ -6996,7 +6995,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, data += 18; len -= 18; } - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) -- cgit v1.2.3-70-g09d2 From 204e6ea981ac46974508ddf403dbb72dc804dcb3 Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Mon, 9 Nov 2009 09:07:36 -0300 Subject: V4L/DVB (13463): Davinci VPFE Capture: Specify device pointer in videobuf_queue_dma_contig_init Signed-off-by: Vaibhav Hiremath Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/davinci/vpfe_capture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c index 6b31e59f47f..c704a263768 100644 --- a/drivers/media/video/davinci/vpfe_capture.c +++ b/drivers/media/video/davinci/vpfe_capture.c @@ -1338,7 +1338,7 @@ static int vpfe_reqbufs(struct file *file, void *priv, vpfe_dev->memory = req_buf->memory; videobuf_queue_dma_contig_init(&vpfe_dev->buffer_queue, &vpfe_videobuf_qops, - NULL, + vpfe_dev->pdev, &vpfe_dev->irqlock, req_buf->type, vpfe_dev->fmt.fmt.pix.field, -- cgit v1.2.3-70-g09d2 From 14cbaafe6f8587aed632de747322cd3add421a76 Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Mon, 9 Nov 2009 09:14:16 -0300 Subject: V4L/DVB (13465): Davinci VPFE Capture: Take i2c adapter id through platform data The I2C adapter ID is actually depends on Board and may vary, Davinci uses id=1, but in case of AM3517 id=3. Signed-off-by: Vaibhav Hiremath Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/davinci/vpfe_capture.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c index c704a263768..86f7e75f12c 100644 --- a/drivers/media/video/davinci/vpfe_capture.c +++ b/drivers/media/video/davinci/vpfe_capture.c @@ -1978,8 +1978,7 @@ static __init int vpfe_probe(struct platform_device *pdev) platform_set_drvdata(pdev, vpfe_dev); /* set driver private data */ video_set_drvdata(vpfe_dev->video_dev, vpfe_dev); - i2c_adap = i2c_get_adapter(1); - vpfe_cfg = pdev->dev.platform_data; + i2c_adap = i2c_get_adapter(vpfe_cfg->i2c_adapter_id); num_subdevs = vpfe_cfg->num_subdevs; vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs, GFP_KERNEL); -- cgit v1.2.3-70-g09d2 From 1ead696b4c1b719eeae313618bca89e7b37c7d9b Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Mon, 9 Nov 2009 09:15:07 -0300 Subject: V4L/DVB (13466): Davinci VPFE Capture:Replaced IRQ_VDINT1 with vpfe_dev->ccdc_irq1 Signed-off-by: Vaibhav Hiremath Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/davinci/vpfe_capture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c index 86f7e75f12c..1c3bde7fcd5 100644 --- a/drivers/media/video/davinci/vpfe_capture.c +++ b/drivers/media/video/davinci/vpfe_capture.c @@ -660,7 +660,7 @@ static void vpfe_detach_irq(struct vpfe_device *vpfe_dev) frame_format = ccdc_dev->hw_ops.get_frame_format(); if (frame_format == CCDC_FRMFMT_PROGRESSIVE) - free_irq(IRQ_VDINT1, vpfe_dev); + free_irq(vpfe_dev->ccdc_irq1, vpfe_dev); } static int vpfe_attach_irq(struct vpfe_device *vpfe_dev) -- cgit v1.2.3-70-g09d2 From 85213630731605503c8fd4df9bf06beefb2cc7c4 Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Tue, 10 Nov 2009 13:32:53 -0300 Subject: V4L/DVB (13467): V4L2: Added CID's V4L2_CID_ROTATE/BG_COLOR Signed-off-by: Vaibhav Hiremath Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/v4l/videodev2.h.xml | 4 +++- drivers/media/video/v4l2-common.c | 9 +++++++++ include/linux/videodev2.h | 4 +++- 3 files changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/Documentation/DocBook/v4l/videodev2.h.xml b/Documentation/DocBook/v4l/videodev2.h.xml index bb6b07f9ea1..7162b9ffc2b 100644 --- a/Documentation/DocBook/v4l/videodev2.h.xml +++ b/Documentation/DocBook/v4l/videodev2.h.xml @@ -915,8 +915,10 @@ enum v4l2_colorfx { #define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) #define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33) +#define V4L2_CID_ROTATE (V4L2_CID_BASE+34) +#define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35) /* last CID + 1 */ -#define V4L2_CID_LASTP1 (V4L2_CID_BASE+34) +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+36) /* MPEG-class control IDs defined by V4L2 */ #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index f5a93ae3cdf..e8e5affbabc 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c @@ -431,6 +431,8 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_CHROMA_AGC: return "Chroma AGC"; case V4L2_CID_COLOR_KILLER: return "Color Killer"; case V4L2_CID_COLORFX: return "Color Effects"; + case V4L2_CID_ROTATE: return "Rotate"; + case V4L2_CID_BG_COLOR: return "Background color"; /* MPEG controls */ case V4L2_CID_MPEG_CLASS: return "MPEG Encoder Controls"; @@ -587,6 +589,13 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; min = max = step = def = 0; break; + case V4L2_CID_BG_COLOR: + qctrl->type = V4L2_CTRL_TYPE_INTEGER; + step = 1; + min = 0; + /* Max is calculated as RGB888 that is 2^24 */ + max = 0xFFFFFF; + break; default: qctrl->type = V4L2_CTRL_TYPE_INTEGER; break; diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index b9a799a3576..54395460a41 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -913,8 +913,10 @@ enum v4l2_colorfx { #define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) #define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33) +#define V4L2_CID_ROTATE (V4L2_CID_BASE+34) +#define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35) /* last CID + 1 */ -#define V4L2_CID_LASTP1 (V4L2_CID_BASE+34) +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+36) /* MPEG-class control IDs defined by V4L2 */ #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) -- cgit v1.2.3-70-g09d2 From d73bfc5fe625f6962d0ced84066e201249f14e53 Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Tue, 10 Nov 2009 13:12:25 -0300 Subject: V4L/DVB (13469): Davinci VPFE Capture: Add support for Control ioctls Added support for Control IOCTL, - s_ctrl - g_ctrl - queryctrl Signed-off-by: Vaibhav Hiremath Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/davinci/vpfe_capture.c | 38 ++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c index 1c3bde7fcd5..12a1b3d7132 100644 --- a/drivers/media/video/davinci/vpfe_capture.c +++ b/drivers/media/video/davinci/vpfe_capture.c @@ -1413,6 +1413,41 @@ static int vpfe_dqbuf(struct file *file, void *priv, buf, file->f_flags & O_NONBLOCK); } +static int vpfe_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *qctrl) +{ + struct vpfe_device *vpfe_dev = video_drvdata(file); + struct vpfe_subdev_info *sdinfo; + + sdinfo = vpfe_dev->current_subdev; + + return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, + core, queryctrl, qctrl); + +} + +static int vpfe_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) +{ + struct vpfe_device *vpfe_dev = video_drvdata(file); + struct vpfe_subdev_info *sdinfo; + + sdinfo = vpfe_dev->current_subdev; + + return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, + core, g_ctrl, ctrl); +} + +static int vpfe_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) +{ + struct vpfe_device *vpfe_dev = video_drvdata(file); + struct vpfe_subdev_info *sdinfo; + + sdinfo = vpfe_dev->current_subdev; + + return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, + core, s_ctrl, ctrl); +} + /* * vpfe_calculate_offsets : This function calculates buffers offset * for top and bottom field @@ -1710,6 +1745,9 @@ static const struct v4l2_ioctl_ops vpfe_ioctl_ops = { .vidioc_querystd = vpfe_querystd, .vidioc_s_std = vpfe_s_std, .vidioc_g_std = vpfe_g_std, + .vidioc_queryctrl = vpfe_queryctrl, + .vidioc_g_ctrl = vpfe_g_ctrl, + .vidioc_s_ctrl = vpfe_s_ctrl, .vidioc_reqbufs = vpfe_reqbufs, .vidioc_querybuf = vpfe_querybuf, .vidioc_qbuf = vpfe_qbuf, -- cgit v1.2.3-70-g09d2 From 7f3ea4debb8106287af87dd0ee770e97b59c1ac4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 25 Nov 2009 11:55:04 -0300 Subject: V4L/DVB (13478): cx18: remove bogus init call. The cx18 av core implemented an init call for no good reason. It's now turned into an internal function. Signed-off-by: Hans Verkuil Reviewed-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-av-core.c | 14 +++++++------- drivers/media/video/cx18/cx18-driver.c | 1 - 2 files changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c index 536dedb23ba..4392c76af5d 100644 --- a/drivers/media/video/cx18/cx18-av-core.c +++ b/drivers/media/video/cx18/cx18-av-core.c @@ -99,10 +99,8 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask, or_value); } -static int cx18_av_init(struct v4l2_subdev *sd, u32 val) +static void cx18_av_init(struct cx18 *cx) { - struct cx18 *cx = v4l2_get_subdevdata(sd); - /* * The crystal freq used in calculations in this driver will be * 28.636360 MHz. @@ -125,7 +123,6 @@ static int cx18_av_init(struct v4l2_subdev *sd, u32 val) /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */ cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56); - return 0; } static void cx18_av_initialize(struct v4l2_subdev *sd) @@ -198,7 +195,7 @@ static void cx18_av_initialize(struct v4l2_subdev *sd) cx18_av_and_or4(cx, CXADEC_CHIP_CTRL, 0xFFFBFFFF, 0x00120000); /* Setup the Video and and Aux/Audio PLLs */ - cx18_av_init(sd, 0); + cx18_av_init(cx); /* set video to auto-detect */ /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */ @@ -1355,7 +1352,6 @@ static int cx18_av_s_register(struct v4l2_subdev *sd, static const struct v4l2_subdev_core_ops cx18_av_general_ops = { .g_chip_ident = cx18_av_g_chip_ident, .log_status = cx18_av_log_status, - .init = cx18_av_init, .load_fw = cx18_av_load_fw, .reset = cx18_av_reset, .queryctrl = cx18_av_queryctrl, @@ -1399,6 +1395,7 @@ int cx18_av_probe(struct cx18 *cx) { struct cx18_av_state *state = &cx->av_state; struct v4l2_subdev *sd; + int err; state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff; state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO) @@ -1417,5 +1414,8 @@ int cx18_av_probe(struct cx18 *cx) snprintf(sd->name, sizeof(sd->name), "%s %03x", cx->v4l2_dev.name, (state->rev >> 4)); sd->grp_id = CX18_HW_418_AV; - return v4l2_device_register_subdev(&cx->v4l2_dev, sd); + err = v4l2_device_register_subdev(&cx->v4l2_dev, sd); + if (!err) + cx18_av_init(cx); + return err; } diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 1a67ad5daad..7f65a47f12e 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -912,7 +912,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, CX18_ERR("Could not register A/V decoder subdevice\n"); goto free_map; } - cx18_call_hw(cx, CX18_HW_418_AV, core, init, 0); /* Initialize GPIO Reset Controller to do chip resets during i2c init */ if (cx->card->hw_all & CX18_HW_GPIO_RESET_CTRL) { -- cgit v1.2.3-70-g09d2 From a7925eb3e4b5cf9f223cd30bbd3e93b9daa02816 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 25 Nov 2009 14:29:33 -0300 Subject: V4L/DVB (13479): cxusb: fix compile warning Fix this trivial compile warning: v4l/cxusb.c:1195: warning: unused variable 'n' Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/cxusb.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 542de171874..05fb28e9c69 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -1189,7 +1189,6 @@ static struct atbm8830_config mygica_d689_atbm8830_cfg = { static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap) { struct dvb_usb_device *d = adap->dev; - int n; /* Select required USB configuration */ if (usb_set_interface(d->udev, 0, 0) < 0) -- cgit v1.2.3-70-g09d2 From b8415f5314ce0b190b5963d2180441cd862efa26 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 25 Nov 2009 14:30:53 -0300 Subject: V4L/DVB (13480): atbm8830: fix compile warning Fix this trivial compile warning: v4l/atbm8830.c:164: warning: 'set_agc_config' defined but not used Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/atbm8830.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/atbm8830.c b/drivers/media/dvb/frontends/atbm8830.c index 87fb3c23b80..d77684893d9 100644 --- a/drivers/media/dvb/frontends/atbm8830.c +++ b/drivers/media/dvb/frontends/atbm8830.c @@ -114,7 +114,7 @@ static int set_osc_freq(struct atbm_state *priv, u32 freq /*in kHz*/) static int set_if_freq(struct atbm_state *priv, u32 freq /*in kHz*/) { - + u32 fs = priv->config->osc_clk_freq; double t; u32 val; @@ -161,15 +161,6 @@ static int is_locked(struct atbm_state *priv, u8 *locked) return 0; } -static int set_agc_config(struct atbm_state *priv, - u8 min, u8 max, u8 hold_loop) -{ - atbm8830_write_reg(priv, REG_AGC_MIN, min); - atbm8830_write_reg(priv, REG_AGC_MAX, max); - atbm8830_write_reg(priv, REG_AGC_HOLD_LOOP, hold_loop); - - return 0; -} static int set_static_channel_mode(struct atbm_state *priv) { -- cgit v1.2.3-70-g09d2 From 569691a5a0fe844e36890e49833130e665868136 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 14 Nov 2009 09:45:38 -0300 Subject: V4L/DVB (13487): gspca - ov534: Add svga, xga and sxga modes for ov965x. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 299 +++++++++++++++++++++++++++++++++----- 1 file changed, 262 insertions(+), 37 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 193129a59ab..4f0f60ebd6c 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -274,7 +274,7 @@ static struct ctrl sd_ctrls_ov772x[] = { static struct ctrl sd_ctrls_ov965x[] = { }; -static const struct v4l2_pix_format vga_yuyv_mode[] = { +static const struct v4l2_pix_format ov772x_mode[] = { {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, .bytesperline = 320 * 2, .sizeimage = 320 * 240 * 2, @@ -287,16 +287,31 @@ static const struct v4l2_pix_format vga_yuyv_mode[] = { .priv = 0}, }; -static const struct v4l2_pix_format vga_jpeg_mode[] = { +static const struct v4l2_pix_format ov965x_mode[] = { {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 320, .sizeimage = 320 * 240 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, + .priv = 4}, {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 640, .sizeimage = 640 * 480 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 3}, + {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 800, + .sizeimage = 800 * 600 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 2}, + {1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 1024, + .sizeimage = 1024 * 768 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 1}, + {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 1280, + .sizeimage = 1280 * 1024 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, .priv = 0}, }; static const u8 bridge_init_ov772x[][2] = { @@ -773,7 +788,7 @@ static const u8 sensor_init_ov965x_2[][2] = { {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ }; -static const u8 sensor_start_ov965x[][2] = { +static const u8 sensor_start_ov965x_1_vga[][2] = { /* same for qvga */ {0x12, 0x62}, /* com7 - 30fps VGA YUV */ {0x36, 0xfa}, /* aref3 */ {0x69, 0x0a}, /* hv */ @@ -797,7 +812,78 @@ static const u8 sensor_start_ov965x[][2] = { {} }; -static const u8 bridge_start_ov965x[][2] = { +static const u8 sensor_start_ov965x_1_svga[][2] = { + {0x12, 0x02}, /* com7 - YUYV - VGA 15 full resolution */ + {0x36, 0xf8}, /* aref3 */ + {0x69, 0x02}, /* hv */ + {0x8c, 0x0d}, /* com22 */ + {0x3e, 0x0c}, /* com14 */ + {0x41, 0x40}, /* com16 */ + {0x72, 0x00}, + {0x73, 0x01}, + {0x74, 0x3a}, + {0x75, 0x35}, + {0x76, 0x01}, + {0xc7, 0x80}, /* com24 */ + {0x03, 0x1b}, /* vref */ + {0x17, 0x1d}, /* hstart */ + {0x18, 0xbd}, /* hstop */ + {0x19, 0x01}, /* vstrt */ + {0x1a, 0x81}, /* vstop */ + {0x32, 0xff}, /* href */ + {0xc0, 0xe2}, + {} +}; + +static const u8 sensor_start_ov965x_1_xga[][2] = { + {0x12, 0x02}, /* com7 */ + {0x36, 0xf8}, /* aref3 */ + {0x69, 0x02}, /* hv */ + {0x8c, 0x89}, /* com22 */ + {0x14, 0x28}, /* com9 */ + {0x3e, 0x0c}, /* com14 */ + {0x41, 0x40}, /* com16 */ + {0x72, 0x00}, + {0x73, 0x01}, + {0x74, 0x3a}, + {0x75, 0x35}, + {0x76, 0x01}, + {0xc7, 0x80}, /* com24 */ + {0x03, 0x1b}, /* vref */ + {0x17, 0x1d}, /* hstart */ + {0x18, 0xbd}, /* hstop */ + {0x19, 0x01}, /* vstrt */ + {0x1a, 0x81}, /* vstop */ + {0x32, 0xff}, /* href */ + {0xc0, 0xe2}, + {} +}; + +static const u8 sensor_start_ov965x_1_sxga[][2] = { + {0x12, 0x02}, /* com7 */ + {0x36, 0xf8}, /* aref3 */ + {0x69, 0x02}, /* hv */ + {0x8c, 0x89}, /* com22 */ + {0x14, 0x28}, /* com9 */ + {0x3e, 0x0c}, /* com14 */ + {0x41, 0x40}, /* com16 */ + {0x72, 0x00}, + {0x73, 0x01}, + {0x74, 0x3a}, + {0x75, 0x35}, + {0x76, 0x01}, + {0xc7, 0x80}, /* com24 */ + {0x03, 0x1b}, /* vref */ + {0x17, 0x1d}, /* hstart */ + {0x18, 0x02}, /* hstop */ + {0x19, 0x01}, /* vstrt */ + {0x1a, 0x81}, /* vstop */ + {0x32, 0xff}, /* href */ + {0xc0, 0xe2}, + {} +}; + +static const u8 bridge_start_ov965x_qvga[][2] = { {0x94, 0xaa}, {0xf1, 0x60}, {0xe5, 0x04}, @@ -806,10 +892,35 @@ static const u8 bridge_start_ov965x[][2] = { {0x8c, 0x00}, {0x8d, 0x1c}, {0x34, 0x05}, + + {0xc2, 0x4c}, + {0xc3, 0xf9}, + {0xda, 0x00}, + {0x50, 0x00}, + {0x51, 0xa0}, + {0x52, 0x78}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x57, 0x00}, + {0x5c, 0x00}, + {0x5a, 0x50}, + {0x5b, 0x3c}, + {0x35, 0x02}, + {0xd9, 0x10}, + {0x94, 0x11}, {} }; static const u8 bridge_start_ov965x_vga[][2] = { + {0x94, 0xaa}, + {0xf1, 0x60}, + {0xe5, 0x04}, + {0xc0, 0x50}, + {0xc1, 0x3c}, + {0x8c, 0x00}, + {0x8d, 0x1c}, + {0x34, 0x05}, {0xc2, 0x0c}, {0xc3, 0xf9}, {0xda, 0x01}, @@ -829,27 +940,101 @@ static const u8 bridge_start_ov965x_vga[][2] = { {} }; -static const u8 bridge_start_ov965x_qvga[][2] = { +static const u8 bridge_start_ov965x_svga[][2] = { + {0x94, 0xaa}, + {0xf1, 0x60}, + {0xe5, 0x04}, + {0xc0, 0xa0}, + {0xc1, 0x80}, + {0x8c, 0x00}, + {0x8d, 0x1c}, + {0x34, 0x05}, + {0xc2, 0x4c}, {0xc3, 0xf9}, - {0xda, 0x00}, {0x50, 0x00}, - {0x51, 0xa0}, - {0x52, 0x78}, + {0x51, 0x40}, + {0x52, 0x00}, {0x53, 0x00}, {0x54, 0x00}, - {0x55, 0x00}, + {0x55, 0x88}, {0x57, 0x00}, {0x5c, 0x00}, - {0x5a, 0x50}, - {0x5b, 0x3c}, + {0x5a, 0xc8}, + {0x5b, 0x96}, + {0x35, 0x02}, + {0xd9, 0x10}, + {0xda, 0x00}, + {0x94, 0x11}, + {} +}; + +static const u8 bridge_start_ov965x_xga[][2] = { + {0x94, 0xaa}, + {0xf1, 0x60}, + {0xe5, 0x04}, + {0xc0, 0xa0}, + {0xc1, 0x80}, + {0x8c, 0x00}, + {0x8d, 0x1c}, + {0x34, 0x05}, + {0xc2, 0x4c}, + {0xc3, 0xf9}, + {0x50, 0x00}, + {0x51, 0x40}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x88}, + {0x57, 0x00}, + {0x5c, 0x01}, + {0x5a, 0x00}, + {0x5b, 0xc0}, {0x35, 0x02}, {0xd9, 0x10}, + {0xda, 0x01}, {0x94, 0x11}, {} }; -static const u8 sensor_start_ov965x_vga[][2] = { +static const u8 bridge_start_ov965x_sxga[][2] = { + {0x94, 0xaa}, + {0xf1, 0x60}, + {0xe5, 0x04}, + {0xc0, 0xa0}, + {0xc1, 0x80}, + {0x8c, 0x00}, + {0x8d, 0x1c}, + {0x34, 0x05}, + {0xc2, 0x0c}, + {0xc3, 0xf9}, + {0xda, 0x00}, + {0x35, 0x02}, + {0xd9, 0x10}, + {0x94, 0x11}, + {} +}; + +static const u8 sensor_start_ov965x_2_qvga[][2] = { + {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */ + {0x1e, 0x04}, /* mvfp */ + {0x13, 0xe0}, /* com8 */ + {0x00, 0x00}, + {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ + {0x11, 0x01}, /* clkrc */ + {0x6b, 0x5a}, /* dblv */ + {0x6a, 0x02}, /* 50 Hz banding filter */ + {0xc5, 0x03}, /* 60 Hz banding filter */ + {0xa2, 0x96}, /* bd50 */ + {0xa3, 0x7d}, /* bd60 */ + + {0xff, 0x13}, /* read 13, write ff 00 */ + {0x13, 0xe7}, + {0x3a, 0x80}, /* tslb - yuyv */ + {} +}; + +static const u8 sensor_start_ov965x_2_vga[][2] = { {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ {0x1e, 0x04}, /* mvfp */ {0x13, 0xe0}, /* com8 */ @@ -866,22 +1051,35 @@ static const u8 sensor_start_ov965x_vga[][2] = { {} }; -static const u8 sensor_start_ov965x_qvga[][2] = { - {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */ +static const u8 sensor_start_ov965x_2_svga[][2] = { /* same for xga */ + {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ {0x1e, 0x04}, /* mvfp */ {0x13, 0xe0}, /* com8 */ {0x00, 0x00}, {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ {0x11, 0x01}, /* clkrc */ {0x6b, 0x5a}, /* dblv */ - {0x6a, 0x02}, /* 50 Hz banding filter */ - {0xc5, 0x03}, /* 60 Hz banding filter */ - {0xa2, 0x96}, /* bd50 */ - {0xa3, 0x7d}, /* bd60 */ + {0x6a, 0x0c}, /* 50 Hz banding filter */ + {0xc5, 0x0f}, /* 60 Hz banding filter */ + {0xa2, 0x4e}, /* bd50 */ + {0xa3, 0x41}, /* bd60 */ + {0x2d, 0x00}, /* advfl */ + {} +}; - {0xff, 0x13}, /* read 13, write ff 00 */ - {0x13, 0xe7}, - {0x3a, 0x80}, /* tslb - yuyv */ +static const u8 sensor_start_ov965x_2_sxga[][2] = { + {0x13, 0xe0}, /* com8 */ + {0x00, 0x00}, + {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ + {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ + {0x1e, 0x04}, /* mvfp */ + {0x11, 0x01}, /* clkrc */ + {0x6b, 0x5a}, /* dblv */ + {0x6a, 0x0c}, /* 50 Hz banding filter */ + {0xc5, 0x0f}, /* 60 Hz banding filter */ + {0xa2, 0x4e}, /* bd50 */ + {0xa3, 0x41}, /* bd60 */ + {0x2d, 0x00}, /* advfl */ {} }; @@ -1216,15 +1414,15 @@ static int sd_config(struct gspca_dev *gspca_dev, cam = &gspca_dev->cam; if (sd->sensor == SENSOR_OV772X) { - cam->cam_mode = vga_yuyv_mode; - cam->nmodes = ARRAY_SIZE(vga_yuyv_mode); + cam->cam_mode = ov772x_mode; + cam->nmodes = ARRAY_SIZE(ov772x_mode); cam->bulk = 1; cam->bulk_size = 16384; cam->bulk_nurbs = 2; } else { /* ov965x */ - cam->cam_mode = vga_jpeg_mode; - cam->nmodes = ARRAY_SIZE(vga_jpeg_mode); + cam->cam_mode = ov965x_mode; + cam->nmodes = ARRAY_SIZE(ov965x_mode); } sd->frame_rate = 30; @@ -1355,22 +1553,49 @@ static int sd_start_ov965x(struct gspca_dev *gspca_dev) { int mode; - sccb_w_array(gspca_dev, sensor_start_ov965x, - ARRAY_SIZE(sensor_start_ov965x)); - reg_w_array(gspca_dev, bridge_start_ov965x, - ARRAY_SIZE(bridge_start_ov965x)); - mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; - if (mode != 0) { /* 320x240 */ + switch (mode) { + default: +/* case 4: * 320x240 */ + sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga, + ARRAY_SIZE(sensor_start_ov965x_1_vga)); reg_w_array(gspca_dev, bridge_start_ov965x_qvga, ARRAY_SIZE(bridge_start_ov965x_qvga)); - sccb_w_array(gspca_dev, sensor_start_ov965x_qvga, - ARRAY_SIZE(sensor_start_ov965x_qvga)); - } else { /* 640x480 */ + sccb_w_array(gspca_dev, sensor_start_ov965x_2_qvga, + ARRAY_SIZE(sensor_start_ov965x_2_qvga)); + break; + case 3: /* 640x480 */ + sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga, + ARRAY_SIZE(sensor_start_ov965x_1_vga)); reg_w_array(gspca_dev, bridge_start_ov965x_vga, ARRAY_SIZE(bridge_start_ov965x_vga)); - sccb_w_array(gspca_dev, sensor_start_ov965x_vga, - ARRAY_SIZE(sensor_start_ov965x_vga)); + sccb_w_array(gspca_dev, sensor_start_ov965x_2_vga, + ARRAY_SIZE(sensor_start_ov965x_2_vga)); + break; + case 2: /* 800x600 */ + sccb_w_array(gspca_dev, sensor_start_ov965x_1_svga, + ARRAY_SIZE(sensor_start_ov965x_1_svga)); + reg_w_array(gspca_dev, bridge_start_ov965x_svga, + ARRAY_SIZE(bridge_start_ov965x_svga)); + sccb_w_array(gspca_dev, sensor_start_ov965x_2_svga, + ARRAY_SIZE(sensor_start_ov965x_2_svga)); + break; + case 1: /* 1024x768 */ + sccb_w_array(gspca_dev, sensor_start_ov965x_1_xga, + ARRAY_SIZE(sensor_start_ov965x_1_xga)); + reg_w_array(gspca_dev, bridge_start_ov965x_xga, + ARRAY_SIZE(bridge_start_ov965x_xga)); + sccb_w_array(gspca_dev, sensor_start_ov965x_2_svga, + ARRAY_SIZE(sensor_start_ov965x_2_svga)); + break; + case 0: /* 1280x1024 */ + sccb_w_array(gspca_dev, sensor_start_ov965x_1_sxga, + ARRAY_SIZE(sensor_start_ov965x_1_sxga)); + reg_w_array(gspca_dev, bridge_start_ov965x_sxga, + ARRAY_SIZE(bridge_start_ov965x_sxga)); + sccb_w_array(gspca_dev, sensor_start_ov965x_2_sxga, + ARRAY_SIZE(sensor_start_ov965x_2_sxga)); + break; } sccb_w_array(gspca_dev, sensor_start_ov965x_2, ARRAY_SIZE(sensor_start_ov965x_2)); -- cgit v1.2.3-70-g09d2 From 4e5cf58ecf98f7cce8033d5b8249c3e9d7ada3f0 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 15 Nov 2009 05:21:09 -0300 Subject: V4L/DVB (13488): gspca - ov534: Remove extra values at end of ov965x sequences. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 4f0f60ebd6c..6817fccd6fd 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -809,7 +809,6 @@ static const u8 sensor_start_ov965x_1_vga[][2] = { /* same for qvga */ {0x1a, 0x3d}, /* vstop */ {0x32, 0xff}, /* href */ {0xc0, 0xaa}, - {} }; static const u8 sensor_start_ov965x_1_svga[][2] = { @@ -832,7 +831,6 @@ static const u8 sensor_start_ov965x_1_svga[][2] = { {0x1a, 0x81}, /* vstop */ {0x32, 0xff}, /* href */ {0xc0, 0xe2}, - {} }; static const u8 sensor_start_ov965x_1_xga[][2] = { @@ -856,7 +854,6 @@ static const u8 sensor_start_ov965x_1_xga[][2] = { {0x1a, 0x81}, /* vstop */ {0x32, 0xff}, /* href */ {0xc0, 0xe2}, - {} }; static const u8 sensor_start_ov965x_1_sxga[][2] = { @@ -880,7 +877,6 @@ static const u8 sensor_start_ov965x_1_sxga[][2] = { {0x1a, 0x81}, /* vstop */ {0x32, 0xff}, /* href */ {0xc0, 0xe2}, - {} }; static const u8 bridge_start_ov965x_qvga[][2] = { @@ -909,7 +905,6 @@ static const u8 bridge_start_ov965x_qvga[][2] = { {0x35, 0x02}, {0xd9, 0x10}, {0x94, 0x11}, - {} }; static const u8 bridge_start_ov965x_vga[][2] = { @@ -937,7 +932,6 @@ static const u8 bridge_start_ov965x_vga[][2] = { {0x35, 0x02}, {0xd9, 0x10}, {0x94, 0x11}, - {} }; static const u8 bridge_start_ov965x_svga[][2] = { @@ -966,7 +960,6 @@ static const u8 bridge_start_ov965x_svga[][2] = { {0xd9, 0x10}, {0xda, 0x00}, {0x94, 0x11}, - {} }; static const u8 bridge_start_ov965x_xga[][2] = { @@ -994,7 +987,6 @@ static const u8 bridge_start_ov965x_xga[][2] = { {0xd9, 0x10}, {0xda, 0x01}, {0x94, 0x11}, - {} }; static const u8 bridge_start_ov965x_sxga[][2] = { @@ -1012,7 +1004,6 @@ static const u8 bridge_start_ov965x_sxga[][2] = { {0x35, 0x02}, {0xd9, 0x10}, {0x94, 0x11}, - {} }; static const u8 sensor_start_ov965x_2_qvga[][2] = { @@ -1031,7 +1022,6 @@ static const u8 sensor_start_ov965x_2_qvga[][2] = { {0xff, 0x13}, /* read 13, write ff 00 */ {0x13, 0xe7}, {0x3a, 0x80}, /* tslb - yuyv */ - {} }; static const u8 sensor_start_ov965x_2_vga[][2] = { @@ -1048,7 +1038,6 @@ static const u8 sensor_start_ov965x_2_vga[][2] = { {0xa3, 0x3e}, /* bd60 */ {0x2d, 0x00}, /* advfl */ - {} }; static const u8 sensor_start_ov965x_2_svga[][2] = { /* same for xga */ @@ -1064,7 +1053,6 @@ static const u8 sensor_start_ov965x_2_svga[][2] = { /* same for xga */ {0xa2, 0x4e}, /* bd50 */ {0xa3, 0x41}, /* bd60 */ {0x2d, 0x00}, /* advfl */ - {} }; static const u8 sensor_start_ov965x_2_sxga[][2] = { @@ -1080,13 +1068,11 @@ static const u8 sensor_start_ov965x_2_sxga[][2] = { {0xa2, 0x4e}, /* bd50 */ {0xa3, 0x41}, /* bd60 */ {0x2d, 0x00}, /* advfl */ - {} }; static const u8 sensor_start_ov965x_2[][2] = { {0xff, 0x42}, /* read 42, write ff 00 */ {0x42, 0xc1}, /* com17 - 50 Hz filter */ - {} }; -- cgit v1.2.3-70-g09d2 From b8c8a5bf833db5ad80266a6a9e5ad496ab01d434 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 23 Nov 2009 06:46:35 -0300 Subject: V4L/DVB (13489): gspca - sonixj: Add the sensor po1030. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 153 ++++++++++++++++++++++++++++++++++--- 1 file changed, 141 insertions(+), 12 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 282c707e5e8..0bd36a00dd2 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -72,7 +72,8 @@ struct sd { #define SENSOR_OV7630 5 #define SENSOR_OV7648 6 #define SENSOR_OV7660 7 -#define SENSOR_SP80708 8 +#define SENSOR_PO1030 8 +#define SENSOR_SP80708 9 u8 i2c_addr; u8 *jpeg_hdr; @@ -250,7 +251,7 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ .step = 1, -#define FREQ_DEF 2 +#define FREQ_DEF 1 .default_value = FREQ_DEF, }, .set = sd_setfreq, @@ -277,7 +278,9 @@ static __u32 ctrl_dis[] = { (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), /* SENSOR_OV7660 7 */ (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | - (1 << FREQ_IDX), /* SENSOR_SP80708 8 */ + (1 << FREQ_IDX), /* SENSOR_PO1030 8 */ + (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | + (1 << FREQ_IDX), /* SENSOR_SP80708 9 */ }; static const struct v4l2_pix_format vga_mode[] = { @@ -388,6 +391,17 @@ static const u8 sn_ov7660[0x1c] = { 0x07, 0x00, 0x00, 0x00 }; +static const u8 sn_po1030[0x1c] = { +/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ + 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, +/* reg8 reg9 rega regb regc regd rege regf */ + 0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ + 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x00, +/* reg18 reg19 reg1a reg1b */ + 0x07, 0x00, 0x00, 0x00 +}; + static const u8 sn_sp80708[0x1c] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20, @@ -409,6 +423,7 @@ static const u8 *sn_tb[] = { sn_ov7630, sn_ov7648, sn_ov7660, + sn_po1030, sn_sp80708 }; @@ -832,6 +847,60 @@ static const u8 ov7660_sensor_param1[][8] = { {} }; +static const u8 po1030_sensor_init[][8] = { +/* the sensor registers are described in m5602/m5602_po1030.h */ + {0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */ + {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ + {0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10}, + {0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10}, + {0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10}, + {0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10}, + {0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */ + {0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10}, + {0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10}, + {0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10}, + {0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10}, + {0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */ + {0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10}, + {0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */ + {0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10}, + {0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10}, + {0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10}, + {0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10}, + {0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10}, + {0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10}, + {0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10}, + {0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */ + {0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10}, + + {0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10}, + {0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10}, + {} +}; +static const u8 po1030_sensor_param1[][8] = { +/* from ms-win traces - these values change with auto gain/expo/wb.. */ + {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10}, +/* mean values */ + {0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */ + {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */ + {0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */ + + {0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */ + {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */ + {0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10}, +/* {0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */ + {} +}; + static const u8 sp80708_sensor_init[][8] = { {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10}, @@ -917,7 +986,7 @@ static const u8 sp80708_sensor_param1[][8] = { {} }; -static const u8 (*sensor_init[9])[8] = { +static const u8 (*sensor_init[10])[8] = { hv7131r_sensor_init, /* HV7131R 0 */ mi0360_sensor_init, /* MI0360 1 */ mo4000_sensor_init, /* MO4000 2 */ @@ -926,7 +995,8 @@ static const u8 (*sensor_init[9])[8] = { ov7630_sensor_init, /* OV7630 5 */ ov7648_sensor_init, /* OV7648 6 */ ov7660_sensor_init, /* OV7660 7 */ - sp80708_sensor_init, /* SP80708 8 */ + po1030_sensor_init, /* PO1030 8 */ + sp80708_sensor_init, /* SP80708 9 */ }; /* read bytes to gspca_dev->usb_buf */ @@ -1033,8 +1103,8 @@ static void i2c_w8(struct gspca_dev *gspca_dev, msleep(2); } -/* read 5 bytes in gspca_dev->usb_buf */ -static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg) +/* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */ +static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len) { struct sd *sd = (struct sd *) gspca_dev; u8 mode[8]; @@ -1056,7 +1126,7 @@ static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg) mode[7] = 0x10; i2c_w8(gspca_dev, mode); msleep(2); - mode[0] = (mode[0] & 0x81) | (5 << 4) | 0x02; + mode[0] = (mode[0] & 0x81) | (len << 4) | 0x02; mode[2] = 0; i2c_w8(gspca_dev, mode); msleep(2); @@ -1081,7 +1151,7 @@ static void hv7131r_probe(struct gspca_dev *gspca_dev) msleep(10); reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */ msleep(10); - i2c_r5(gspca_dev, 0); /* read sensor id */ + i2c_r(gspca_dev, 0, 5); /* read sensor id */ if (gspca_dev->usb_buf[0] == 0x02 && gspca_dev->usb_buf[1] == 0x09 && gspca_dev->usb_buf[2] == 0x01 @@ -1144,6 +1214,41 @@ static void mi0360_probe(struct gspca_dev *gspca_dev) } } +static void ov7648_probe(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + /* check ov76xx */ + reg_w1(gspca_dev, 0x17, 0x62); + reg_w1(gspca_dev, 0x01, 0x08); + sd->i2c_addr = 0x21; + i2c_r(gspca_dev, 0x0a, 2); + if (gspca_dev->usb_buf[3] == 0x76) { /* ov76xx */ + PDEBUG(D_PROBE, "Sensor ov%02x%02x", + gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]); + return; + } + + /* reset */ + reg_w1(gspca_dev, 0x01, 0x29); + reg_w1(gspca_dev, 0x17, 0x42); + + /* check po1030 */ + reg_w1(gspca_dev, 0x17, 0x62); + reg_w1(gspca_dev, 0x01, 0x08); + sd->i2c_addr = 0x6e; + i2c_r(gspca_dev, 0x00, 2); + if (gspca_dev->usb_buf[3] == 0x10 /* po1030 */ + && gspca_dev->usb_buf[4] == 0x30) { + PDEBUG(D_PROBE, "Sensor po1030"); + sd->sensor = SENSOR_PO1030; + return; + } + + PDEBUG(D_PROBE, "Unknown sensor %02x%02x", + gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]); +} + static void bridge_init(struct gspca_dev *gspca_dev, const u8 *sn9c1xx) { @@ -1164,6 +1269,7 @@ static void bridge_init(struct gspca_dev *gspca_dev, reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); switch (sd->sensor) { case SENSOR_OV7660: + case SENSOR_PO1030: case SENSOR_SP80708: reg9a = reg9a_spec; break; @@ -1214,7 +1320,14 @@ static void bridge_init(struct gspca_dev *gspca_dev, reg_w1(gspca_dev, 0x01, 0x62); reg_w1(gspca_dev, 0x01, 0x42); break; + case SENSOR_PO1030: + reg_w1(gspca_dev, 0x01, 0x61); + reg_w1(gspca_dev, 0x17, 0x20); + reg_w1(gspca_dev, 0x01, 0x60); + reg_w1(gspca_dev, 0x01, 0x40); + break; case SENSOR_OV7660: + /* fall thru */ case SENSOR_SP80708: reg_w1(gspca_dev, 0x01, 0x63); reg_w1(gspca_dev, 0x17, 0x20); @@ -1266,7 +1379,6 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->quality = QUALITY_DEF; sd->jpegqual = 80; - gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; return 0; } @@ -1301,8 +1413,14 @@ static int sd_init(struct gspca_dev *gspca_dev) case BRIDGE_SN9C120: if (regF1 != 0x12) return -ENODEV; - if (sd->sensor == SENSOR_MI0360) + switch (sd->sensor) { + case SENSOR_MI0360: mi0360_probe(gspca_dev); + break; + case SENSOR_OV7648: + ov7648_probe(gspca_dev); + break; + } regGpio[1] = 0x70; reg_w(gspca_dev, 0x01, regGpio, 2); break; @@ -1321,6 +1439,8 @@ static int sd_init(struct gspca_dev *gspca_dev) sn9c1xx = sn_tb[sd->sensor]; sd->i2c_addr = sn9c1xx[9]; + gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; + return 0; } @@ -1742,6 +1862,9 @@ static int sd_start(struct gspca_dev *gspca_dev) case SENSOR_OV7660: reg17 = 0xa0; break; + case SENSOR_PO1030: + reg17 = 0xa0; + break; default: reg17 = 0x60; break; @@ -1839,6 +1962,11 @@ static int sd_start(struct gspca_dev *gspca_dev) * inverse power down */ } break; + case SENSOR_PO1030: + init = po1030_sensor_param1; + reg17 = 0xa2; + reg1 = 0x44; + break; default: /* case SENSOR_SP80708: */ init = sp80708_sensor_param1; @@ -1919,6 +2047,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) /* fall thru */ case SENSOR_MT9V111: case SENSOR_OV7630: + case SENSOR_PO1030: data = 0x29; break; } @@ -2325,7 +2454,7 @@ static const __devinitdata struct usb_device_id device_table[] = { /* {USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */ {USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)}, /*sn9c325?*/ /*bw600.inf:*/ - {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)}, /*sn9c110?*/ + {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)}, /*sn9c325?*/ {USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)}, {USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)}, /* {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */ -- cgit v1.2.3-70-g09d2 From c22c4a20a6ac7b10e43eab6963f941795c5e92aa Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 24 Nov 2009 05:22:05 -0300 Subject: V4L/DVB (13490): gspca - ov534: Add controls for sensor ov965x. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 479 ++++++++++++++++++++++++++++++++------ 1 file changed, 407 insertions(+), 72 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 6817fccd6fd..4dbb882c83d 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -65,9 +65,11 @@ struct sd { u8 hue; u8 autogain; u8 awb; - u8 sharpness; + s8 sharpness; u8 hflip; u8 vflip; + u8 satur; + u8 lightfreq; u8 sensor; #define SENSOR_OV772X 0 @@ -99,6 +101,10 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls_ov772x[] = { { /* 0 */ @@ -109,8 +115,8 @@ static struct ctrl sd_ctrls_ov772x[] = { .minimum = 0, .maximum = 255, .step = 1, -#define BRIGHTNESS_DEF 20 - .default_value = BRIGHTNESS_DEF, +#define BRIGHTNESS_77_DEF 20 + .default_value = BRIGHTNESS_77_DEF, }, .set = sd_setbrightness, .get = sd_getbrightness, @@ -123,8 +129,8 @@ static struct ctrl sd_ctrls_ov772x[] = { .minimum = 0, .maximum = 255, .step = 1, -#define CONTRAST_DEF 37 - .default_value = CONTRAST_DEF, +#define CONTRAST_77_DEF 37 + .default_value = CONTRAST_77_DEF, }, .set = sd_setcontrast, .get = sd_getcontrast, @@ -151,8 +157,8 @@ static struct ctrl sd_ctrls_ov772x[] = { .minimum = 0, .maximum = 255, .step = 1, -#define EXPO_DEF 120 - .default_value = EXPO_DEF, +#define EXPO_77_DEF 120 + .default_value = EXPO_77_DEF, }, .set = sd_setexposure, .get = sd_getexposure, @@ -207,13 +213,13 @@ static struct ctrl sd_ctrls_ov772x[] = { .minimum = 0, .maximum = 1, .step = 1, -#define AUTOGAIN_DEF 0 - .default_value = AUTOGAIN_DEF, +#define AUTOGAIN_77_DEF 0 + .default_value = AUTOGAIN_77_DEF, }, .set = sd_setautogain, .get = sd_getautogain, }, -#define AWB_IDX 8 +#define AWB_77_IDX 8 { /* 8 */ { .id = V4L2_CID_AUTO_WHITE_BALANCE, @@ -236,8 +242,8 @@ static struct ctrl sd_ctrls_ov772x[] = { .minimum = 0, .maximum = 63, .step = 1, -#define SHARPNESS_DEF 0 - .default_value = SHARPNESS_DEF, +#define SHARPNESS_77_DEF 0 + .default_value = SHARPNESS_77_DEF, }, .set = sd_setsharpness, .get = sd_getsharpness, @@ -272,6 +278,105 @@ static struct ctrl sd_ctrls_ov772x[] = { }, }; static struct ctrl sd_ctrls_ov965x[] = { + { /* 0 */ + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 15, + .step = 1, +#define BRIGHTNESS_96_DEF 7 + .default_value = BRIGHTNESS_96_DEF, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, + { /* 1 */ + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 15, + .step = 1, +#define CONTRAST_96_DEF 3 + .default_value = CONTRAST_96_DEF, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, + { /* 2 */ + { + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Autogain", + .minimum = 0, + .maximum = 1, + .step = 1, +#define AUTOGAIN_96_DEF 1 + .default_value = AUTOGAIN_96_DEF, + }, + .set = sd_setautogain, + .get = sd_getautogain, + }, +#define EXPO_96_IDX 3 + { /* 3 */ + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure", + .minimum = 0, + .maximum = 3, + .step = 1, +#define EXPO_96_DEF 0 + .default_value = EXPO_96_DEF, + }, + .set = sd_setexposure, + .get = sd_getexposure, + }, + { /* 4 */ + { + .id = V4L2_CID_SHARPNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Sharpness", + .minimum = -1, /* -1 = auto */ + .maximum = 4, + .step = 1, +#define SHARPNESS_96_DEF -1 + .default_value = SHARPNESS_96_DEF, + }, + .set = sd_setsharpness, + .get = sd_getsharpness, + }, + { /* 5 */ + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation", + .minimum = 0, + .maximum = 4, + .step = 1, +#define SATUR_DEF 2 + .default_value = SATUR_DEF, + }, + .set = sd_setsatur, + .get = sd_getsatur, + }, + { + { + .id = V4L2_CID_POWER_LINE_FREQUENCY, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Light frequency filter", + .minimum = 0, + .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ + .step = 1, +#define FREQ_DEF 0 + .default_value = FREQ_DEF, + }, + .set = sd_setfreq, + .get = sd_getfreq, + }, }; static const struct v4l2_pix_format ov772x_mode[] = { @@ -314,6 +419,7 @@ static const struct v4l2_pix_format ov965x_mode[] = { .colorspace = V4L2_COLORSPACE_JPEG, .priv = 0}, }; + static const u8 bridge_init_ov772x[][2] = { { 0xc2, 0x0c }, { 0x88, 0xf8 }, @@ -689,7 +795,7 @@ static const u8 sensor_init_ov965x[][2] = { {0xcb, 0xf0}, {0xcc, 0xd8}, {0xcd, 0xf1}, - {0x4f, 0x98}, + {0x4f, 0x98}, /* matrix */ {0x50, 0x98}, {0x51, 0x00}, {0x52, 0x28}, @@ -698,6 +804,7 @@ static const u8 sensor_init_ov965x[][2] = { {0x58, 0x1a}, {0xff, 0x41}, /* read 41, write ff 00 */ {0x41, 0x40}, /* com16 */ + {0xc5, 0x03}, /* 60 Hz banding filter */ {0x6a, 0x02}, /* 50 Hz banding filter */ @@ -741,8 +848,8 @@ static const u8 bridge_init_ov965x_2[][2] = { {0x52, 0x3c}, {0x53, 0x00}, {0x54, 0x00}, - {0x55, 0x00}, /* brightness */ - {0x57, 0x00}, /* contrast 2 */ + {0x55, 0x00}, + {0x57, 0x00}, {0x5c, 0x00}, {0x5a, 0xa0}, {0x5b, 0x78}, @@ -765,14 +872,16 @@ static const u8 sensor_init_ov965x_2[][2] = { {0xa3, 0x3e}, {0x2d, 0x00}, {0xff, 0x42}, /* read 42, write ff 00 */ - {0x42, 0xc0}, + {0x42, 0xc0}, /* com17 */ {0x2d, 0x00}, {0xff, 0x42}, /* read 42, write ff 00 */ - {0x42, 0xc1}, + {0x42, 0xc1}, /* com17 */ +/* sharpness */ {0x3f, 0x01}, {0xff, 0x42}, /* read 42, write ff 00 */ - {0x42, 0xc1}, - {0x4f, 0x98}, + {0x42, 0xc1}, /* com17 */ +/* saturation */ + {0x4f, 0x98}, /* matrix */ {0x50, 0x98}, {0x51, 0x00}, {0x52, 0x28}, @@ -781,8 +890,11 @@ static const u8 sensor_init_ov965x_2[][2] = { {0x58, 0x1a}, {0xff, 0x41}, /* read 41, write ff 00 */ {0x41, 0x40}, /* com16 */ +/* contrast */ {0x56, 0x40}, +/* brightness */ {0x55, 0x8f}, +/* expo */ {0x10, 0x25}, /* aech - exposure high bits */ {0xff, 0x13}, /* read 13, write ff 00 */ {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ @@ -943,7 +1055,6 @@ static const u8 bridge_start_ov965x_svga[][2] = { {0x8c, 0x00}, {0x8d, 0x1c}, {0x34, 0x05}, - {0xc2, 0x4c}, {0xc3, 0xf9}, {0x50, 0x00}, @@ -1052,7 +1163,6 @@ static const u8 sensor_start_ov965x_2_svga[][2] = { /* same for xga */ {0xc5, 0x0f}, /* 60 Hz banding filter */ {0xa2, 0x4e}, /* bd50 */ {0xa3, 0x41}, /* bd60 */ - {0x2d, 0x00}, /* advfl */ }; static const u8 sensor_start_ov965x_2_sxga[][2] = { @@ -1067,15 +1177,8 @@ static const u8 sensor_start_ov965x_2_sxga[][2] = { {0xc5, 0x0f}, /* 60 Hz banding filter */ {0xa2, 0x4e}, /* bd50 */ {0xa3, 0x41}, /* bd60 */ - {0x2d, 0x00}, /* advfl */ -}; - -static const u8 sensor_start_ov965x_2[][2] = { - {0xff, 0x42}, /* read 42, write ff 00 */ - {0x42, 0xc1}, /* com17 - 50 Hz filter */ }; - static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) { struct usb_device *udev = gspca_dev->dev; @@ -1257,14 +1360,14 @@ static void set_frame_rate(struct gspca_dev *gspca_dev) PDEBUG(D_PROBE, "frame_rate: %d", r->fps); } -static void setbrightness(struct gspca_dev *gspca_dev) +static void setbrightness_77(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; sccb_reg_write(gspca_dev, 0x9B, sd->brightness); } -static void setcontrast(struct gspca_dev *gspca_dev) +static void setcontrast_77(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1298,7 +1401,7 @@ static void setgain(struct gspca_dev *gspca_dev) sccb_reg_write(gspca_dev, 0x00, val); } -static void setexposure(struct gspca_dev *gspca_dev) +static void setexposure_77(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; u8 val; @@ -1329,7 +1432,7 @@ static void sethue(struct gspca_dev *gspca_dev) sccb_reg_write(gspca_dev, 0x01, sd->hue); } -static void setautogain(struct gspca_dev *gspca_dev) +static void setautogain_77(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1354,7 +1457,7 @@ static void setawb(struct gspca_dev *gspca_dev) sccb_reg_write(gspca_dev, 0x63, 0xaa); /* AWB off */ } -static void setsharpness(struct gspca_dev *gspca_dev) +static void setsharpness_77(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; u8 val; @@ -1388,6 +1491,132 @@ static void setvflip(struct gspca_dev *gspca_dev) sccb_reg_read(gspca_dev, 0x0c) & 0x7f); } +/* ov965x specific controls */ +static void setbrightness_96(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + u8 val; + + val = sd->brightness; + if (val < 8) + val = 15 - val; /* f .. 8 */ + else + val = val - 8; /* 0 .. 7 */ + sccb_reg_write(gspca_dev, 0x55, /* brtn - brightness adjustment */ + 0x0f | (val << 4)); +} + +static void setcontrast_96(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sccb_reg_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */ + sd->contrast << 4); +} + +static void setexposure_96(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + u8 val; + static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e}; + + sccb_reg_write(gspca_dev, 0x10, /* aec[9:2] */ + expo[sd->exposure]); + val = sccb_reg_read(gspca_dev, 0x13); /* com8 */ + sccb_reg_write(gspca_dev, 0xff, 0x00); + sccb_reg_write(gspca_dev, 0x13, val); + val = sccb_reg_read(gspca_dev, 0xa1); /* aech */ + sccb_reg_write(gspca_dev, 0xff, 0x00); + sccb_reg_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */ +} + +static void setsharpness_96(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + u8 val; + + val = sd->sharpness; + if (val < 0) { /* auto */ + val = sccb_reg_read(gspca_dev, 0x42); /* com17 */ + sccb_reg_write(gspca_dev, 0xff, 0x00); + sccb_reg_write(gspca_dev, 0x42, val | 0x40); + /* Edge enhancement strength auto adjust */ + return; + } + if (val != 0) + val = 1 << (val - 1); + sccb_reg_write(gspca_dev, 0x3f, /* edge - edge enhance. factor */ + val); + val = sccb_reg_read(gspca_dev, 0x42); /* com17 */ + sccb_reg_write(gspca_dev, 0xff, 0x00); + sccb_reg_write(gspca_dev, 0x42, val & 0xbf); +} + +static void setautogain_96(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + u8 val; + +/*fixme: should adjust agc/awb/aec by different controls */ + val = sd->autogain; + val = sccb_reg_read(gspca_dev, 0x13); /* com8 */ + sccb_reg_write(gspca_dev, 0xff, 0x00); + if (sd->autogain) + val |= 0x05; /* agc & aec */ + else + val &= 0xfa; + sccb_reg_write(gspca_dev, 0x13, val); +} + +static void setsatur(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + u8 val1, val2, val3; + static const u8 matrix[5][2] = { + {0x14, 0x38}, + {0x1e, 0x54}, + {0x28, 0x70}, + {0x32, 0x8c}, + {0x48, 0x90} + }; + + val1 = matrix[sd->satur][0]; + val2 = matrix[sd->satur][1]; + val3 = val1 + val2; + sccb_reg_write(gspca_dev, 0x4f, val3); /* matrix coeff */ + sccb_reg_write(gspca_dev, 0x50, val3); + sccb_reg_write(gspca_dev, 0x51, 0x00); + sccb_reg_write(gspca_dev, 0x52, val1); + sccb_reg_write(gspca_dev, 0x53, val2); + sccb_reg_write(gspca_dev, 0x54, val3); + sccb_reg_write(gspca_dev, 0x58, 0x1a); /* mtxs - coeff signs */ + val1 = sccb_reg_read(gspca_dev, 0x41); /* com16 */ + sccb_reg_write(gspca_dev, 0xff, 0x00); + sccb_reg_write(gspca_dev, 0x41, val1); +} + +static void setfreq(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + u8 val; + + val = sccb_reg_read(gspca_dev, 0x13); /* com8 */ + sccb_reg_write(gspca_dev, 0xff, 0x00); + if (sd->lightfreq == 0) { + sccb_reg_write(gspca_dev, 0x13, val & 0xdf); + return; + } + sccb_reg_write(gspca_dev, 0x13, val | 0x20); + + val = sccb_reg_read(gspca_dev, 0x42); /* com17 */ + sccb_reg_write(gspca_dev, 0xff, 0x00); + if (sd->lightfreq == 1) + val |= 0x01; + else + val &= 0xfe; + sccb_reg_write(gspca_dev, 0x42, val); +} + /* this function is called at probe time */ static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id) @@ -1413,28 +1642,47 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->frame_rate = 30; - sd->brightness = BRIGHTNESS_DEF; - sd->contrast = CONTRAST_DEF; - sd->gain = GAIN_DEF; - sd->exposure = EXPO_DEF; - sd->redblc = RED_BALANCE_DEF; - sd->blueblc = BLUE_BALANCE_DEF; - sd->hue = HUE_DEF; -#if AUTOGAIN_DEF != 0 - sd->autogain = AUTOGAIN_DEF; + if (sd->sensor == SENSOR_OV772X) { + sd->brightness = BRIGHTNESS_77_DEF; + sd->contrast = CONTRAST_77_DEF; + sd->gain = GAIN_DEF; + sd->exposure = EXPO_77_DEF; + sd->redblc = RED_BALANCE_DEF; + sd->blueblc = BLUE_BALANCE_DEF; + sd->hue = HUE_DEF; +#if AUTOGAIN_77_DEF != 0 + sd->autogain = AUTOGAIN_77_DEF; #else - gspca_dev->ctrl_inac |= (1 << AWB_IDX); + gspca_dev->ctrl_inac |= (1 << AWB_77_IDX); #endif #if AWB_DEF != 0 - sd->awb = AWB_DEF + sd->awb = AWB_DEF +#endif +#if SHARPNESS_77_DEF != 0 + sd->sharpness = SHARPNESS_77_DEF; #endif - sd->sharpness = SHARPNESS_DEF; #if HFLIP_DEF != 0 - sd->hflip = HFLIP_DEF; + sd->hflip = HFLIP_DEF; #endif #if VFLIP_DEF != 0 - sd->vflip = VFLIP_DEF; + sd->vflip = VFLIP_DEF; +#endif + } else { + sd->brightness = BRIGHTNESS_96_DEF; + sd->contrast = CONTRAST_96_DEF; +#if AUTOGAIN_96_DEF != 0 + sd->autogain = AUTOGAIN_96_DEF; + gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX); +#endif +#if EXPO_96_DEF != 0 + sd->exposure = EXPO_96_DEF; +#endif +#if SHARPNESS_96_DEF != 0 + sd->sharpness = SHARPNESS_96_DEF; #endif + sd->satur = SATUR_DEF; + sd->lightfreq = FREQ_DEF; + } return 0; } @@ -1517,16 +1765,16 @@ static int sd_start_ov772x(struct gspca_dev *gspca_dev) } set_frame_rate(gspca_dev); - setautogain(gspca_dev); + setautogain_77(gspca_dev); setawb(gspca_dev); setgain(gspca_dev); setredblc(gspca_dev); setblueblc(gspca_dev); sethue(gspca_dev); - setexposure(gspca_dev); - setbrightness(gspca_dev); - setcontrast(gspca_dev); - setsharpness(gspca_dev); + setexposure_77(gspca_dev); + setbrightness_77(gspca_dev); + setcontrast_77(gspca_dev); + setsharpness_77(gspca_dev); setvflip(gspca_dev); sethflip(gspca_dev); @@ -1583,8 +1831,14 @@ static int sd_start_ov965x(struct gspca_dev *gspca_dev) ARRAY_SIZE(sensor_start_ov965x_2_sxga)); break; } - sccb_w_array(gspca_dev, sensor_start_ov965x_2, - ARRAY_SIZE(sensor_start_ov965x_2)); + setfreq(gspca_dev); + setautogain_96(gspca_dev); + setbrightness_96(gspca_dev); + setcontrast_96(gspca_dev); + setexposure_96(gspca_dev); + setsharpness_96(gspca_dev); + setsatur(gspca_dev); + ov534_reg_write(gspca_dev, 0xe0, 0x00); ov534_reg_write(gspca_dev, 0xe0, 0x00); ov534_set_led(gspca_dev, 1); @@ -1687,7 +1941,7 @@ scan_next: } while (remaining_len > 0); } -/* ov772x controls */ +/* controls */ static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -1711,8 +1965,12 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) struct sd *sd = (struct sd *) gspca_dev; sd->exposure = val; - if (gspca_dev->streaming) - setexposure(gspca_dev); + if (gspca_dev->streaming) { + if (sd->sensor == SENSOR_OV772X) + setexposure_77(gspca_dev); + else + setexposure_96(gspca_dev); + } return 0; } @@ -1729,8 +1987,12 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) struct sd *sd = (struct sd *) gspca_dev; sd->brightness = val; - if (gspca_dev->streaming) - setbrightness(gspca_dev); + if (gspca_dev->streaming) { + if (sd->sensor == SENSOR_OV772X) + setbrightness_77(gspca_dev); + else + setbrightness_96(gspca_dev); + } return 0; } @@ -1747,8 +2009,12 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) struct sd *sd = (struct sd *) gspca_dev; sd->contrast = val; - if (gspca_dev->streaming) - setcontrast(gspca_dev); + if (gspca_dev->streaming) { + if (sd->sensor == SENSOR_OV772X) + setcontrast_77(gspca_dev); + else + setcontrast_96(gspca_dev); + } return 0; } @@ -1760,6 +2026,41 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->satur = val; + if (gspca_dev->streaming) + setsatur(gspca_dev); + return 0; +} + +static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->satur; + return 0; +} +static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->lightfreq = val; + if (gspca_dev->streaming) + setfreq(gspca_dev); + return 0; +} + +static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->lightfreq; + return 0; +} + static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -1820,14 +2121,24 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) sd->autogain = val; - /* the auto white balance control works only when auto gain is set */ - if (val) - gspca_dev->ctrl_inac &= ~(1 << AWB_IDX); - else - gspca_dev->ctrl_inac |= (1 << AWB_IDX); + if (gspca_dev->streaming) { + if (sd->sensor == SENSOR_OV772X) { - if (gspca_dev->streaming) - setautogain(gspca_dev); + /* the auto white balance control works only + * when auto gain is set */ + if (val) + gspca_dev->ctrl_inac &= ~(1 << AWB_77_IDX); + else + gspca_dev->ctrl_inac |= (1 << AWB_77_IDX); + setautogain_77(gspca_dev); + } else { + if (val) + gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX); + else + gspca_dev->ctrl_inac &= ~(1 << EXPO_96_IDX); + setautogain_96(gspca_dev); + } + } return 0; } @@ -1862,8 +2173,12 @@ static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) struct sd *sd = (struct sd *) gspca_dev; sd->sharpness = val; - if (gspca_dev->streaming) - setsharpness(gspca_dev); + if (gspca_dev->streaming) { + if (sd->sensor == SENSOR_OV772X) + setsharpness_77(gspca_dev); + else + setsharpness_96(gspca_dev); + } return 0; } @@ -1952,6 +2267,27 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev, return 0; } +static int sd_querymenu(struct gspca_dev *gspca_dev, + struct v4l2_querymenu *menu) +{ + switch (menu->id) { + case V4L2_CID_POWER_LINE_FREQUENCY: + switch (menu->index) { + case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ + strcpy((char *) menu->name, "NoFliker"); + return 0; + case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ + strcpy((char *) menu->name, "50 Hz"); + return 0; + case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ + strcpy((char *) menu->name, "60 Hz"); + return 0; + } + break; + } + return -EINVAL; +} + /* sub-driver description */ static const struct sd_desc sd_desc_ov772x = { .name = MODULE_NAME, @@ -1975,8 +2311,7 @@ static const struct sd_desc sd_desc_ov965x = { .start = sd_start_ov965x, .stopN = sd_stopN_ov965x, .pkt_scan = sd_pkt_scan, - .get_streamparm = sd_get_streamparm, - .set_streamparm = sd_set_streamparm, + .querymenu = sd_querymenu, }; /* -- module initialisation -- */ -- cgit v1.2.3-70-g09d2 From 6afd2aa856eba0706176cecea1f989b1081c96dc Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 24 Nov 2009 06:13:28 -0300 Subject: V4L/DVB (13491): gspca - vc032x: Avoid crash on querymenu. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/vc032x.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index 26675236fbd..c090efcd804 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c @@ -3095,6 +3095,8 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, switch (menu->id) { case V4L2_CID_POWER_LINE_FREQUENCY: + if (menu->index >= ARRAY_SIZE(freq_nm)) + break; strcpy((char *) menu->name, freq_nm[menu->index]); return 0; } -- cgit v1.2.3-70-g09d2 From 09ea33e5c696958e8b1ae6d5ab184476b16592f1 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Tue, 24 Nov 2009 20:16:04 -0300 Subject: V4L/DVB (13493): TeVii S470 and TBS 6920 fixes The new hardware design applied for this cards. Silicon Labs C8051F300 microcontroller is used for LNB power control. It connected to cx23885 GPIO pins: GPIO0 - P0.3 data GPIO1 - P0.2 reset GPIO2 - P0.1 clk GPIO3 - P0.0 busy Tevii S470 based on Montage Technology M88TS2020 digital satellite tuner and M88DS3000 advanced DVB-S/S2 demodulator. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/Kconfig | 7 + drivers/media/dvb/frontends/Makefile | 1 + drivers/media/dvb/frontends/ds3000.c | 1367 +++++++++++++++++++++++++++ drivers/media/dvb/frontends/ds3000.h | 45 + drivers/media/video/cx23885/Kconfig | 2 + drivers/media/video/cx23885/Makefile | 2 +- drivers/media/video/cx23885/cx23885-cards.c | 14 +- drivers/media/video/cx23885/cx23885-core.c | 20 + drivers/media/video/cx23885/cx23885-dvb.c | 38 +- drivers/media/video/cx23885/cx23885-f300.c | 177 ++++ drivers/media/video/cx23885/cx23885-f300.h | 2 + drivers/media/video/cx23885/cx23885.h | 1 + 12 files changed, 1647 insertions(+), 29 deletions(-) create mode 100644 drivers/media/dvb/frontends/ds3000.c create mode 100644 drivers/media/dvb/frontends/ds3000.h create mode 100644 drivers/media/video/cx23885/cx23885-f300.c create mode 100644 drivers/media/video/cx23885/cx23885-f300.h (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index fdc7926cb2d..58aac018f10 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -201,6 +201,13 @@ config DVB_SI21XX help A DVB-S tuner module. Say Y when you want to support this frontend. +config DVB_DS3000 + tristate "Montage Tehnology DS3000 based" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + A DVB-S/S2 tuner module. Say Y when you want to support this frontend. + comment "DVB-T (terrestrial) frontends" depends on DVB_CORE diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 390eec6d5d8..823482535d1 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -78,3 +78,4 @@ obj-$(CONFIG_DVB_STV090x) += stv090x.o obj-$(CONFIG_DVB_STV6110x) += stv6110x.o obj-$(CONFIG_DVB_ISL6423) += isl6423.o obj-$(CONFIG_DVB_EC100) += ec100.o +obj-$(CONFIG_DVB_DS3000) += ds3000.o diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c new file mode 100644 index 00000000000..cff3535566f --- /dev/null +++ b/drivers/media/dvb/frontends/ds3000.c @@ -0,0 +1,1367 @@ +/* + Montage Technology DS3000/TS2020 - DVBS/S2 Demodulator/Tuner driver + Copyright (C) 2009 Konstantin Dimitrov + + Copyright (C) 2009 TurboSight.com + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include "dvb_frontend.h" +#include "ds3000.h" + +static int debug; + +#define dprintk(args...) \ + do { \ + if (debug) \ + printk(args); \ + } while (0) + +/* as of March 2009 current DS3000 firmware version is 1.78 */ +/* DS3000 FW v1.78 MD5: a32d17910c4f370073f9346e71d34b80 */ +#define DS3000_DEFAULT_FIRMWARE "dvb-fe-ds3000.fw" + +#define DS3000_SAMPLE_RATE 96000 /* in kHz */ +#define DS3000_XTAL_FREQ 27000 /* in kHz */ + +/* Register values to initialise the demod in DVB-S mode */ +static u8 ds3000_dvbs_init_tab[] = { + 0x23, 0x05, + 0x08, 0x03, + 0x0c, 0x00, + 0x21, 0x54, + 0x25, 0x82, + 0x27, 0x31, + 0x30, 0x08, + 0x31, 0x40, + 0x32, 0x32, + 0x33, 0x35, + 0x35, 0xff, + 0x3a, 0x00, + 0x37, 0x10, + 0x38, 0x10, + 0x39, 0x02, + 0x42, 0x60, + 0x4a, 0x40, + 0x4b, 0x04, + 0x4d, 0x91, + 0x5d, 0xc8, + 0x50, 0x77, + 0x51, 0x77, + 0x52, 0x36, + 0x53, 0x36, + 0x56, 0x01, + 0x63, 0x43, + 0x64, 0x30, + 0x65, 0x40, + 0x68, 0x26, + 0x69, 0x4c, + 0x70, 0x20, + 0x71, 0x70, + 0x72, 0x04, + 0x73, 0x00, + 0x70, 0x40, + 0x71, 0x70, + 0x72, 0x04, + 0x73, 0x00, + 0x70, 0x60, + 0x71, 0x70, + 0x72, 0x04, + 0x73, 0x00, + 0x70, 0x80, + 0x71, 0x70, + 0x72, 0x04, + 0x73, 0x00, + 0x70, 0xa0, + 0x71, 0x70, + 0x72, 0x04, + 0x73, 0x00, + 0x70, 0x1f, + 0x76, 0x00, + 0x77, 0xd1, + 0x78, 0x0c, + 0x79, 0x80, + 0x7f, 0x04, + 0x7c, 0x00, + 0x80, 0x86, + 0x81, 0xa6, + 0x85, 0x04, + 0xcd, 0xf4, + 0x90, 0x33, + 0xa0, 0x44, + 0xc0, 0x18, + 0xc3, 0x10, + 0xc4, 0x08, + 0xc5, 0x80, + 0xc6, 0x80, + 0xc7, 0x0a, + 0xc8, 0x1a, + 0xc9, 0x80, + 0xfe, 0x92, + 0xe0, 0xf8, + 0xe6, 0x8b, + 0xd0, 0x40, + 0xf8, 0x20, + 0xfa, 0x0f, + 0xfd, 0x20, + 0xad, 0x20, + 0xae, 0x07, + 0xb8, 0x00, +}; + +/* Register values to initialise the demod in DVB-S2 mode */ +static u8 ds3000_dvbs2_init_tab[] = { + 0x23, 0x0f, + 0x08, 0x07, + 0x0c, 0x00, + 0x21, 0x54, + 0x25, 0x82, + 0x27, 0x31, + 0x30, 0x08, + 0x31, 0x32, + 0x32, 0x32, + 0x33, 0x35, + 0x35, 0xff, + 0x3a, 0x00, + 0x37, 0x10, + 0x38, 0x10, + 0x39, 0x02, + 0x42, 0x60, + 0x4a, 0x80, + 0x4b, 0x04, + 0x4d, 0x81, + 0x5d, 0x88, + 0x50, 0x36, + 0x51, 0x36, + 0x52, 0x36, + 0x53, 0x36, + 0x63, 0x60, + 0x64, 0x10, + 0x65, 0x10, + 0x68, 0x04, + 0x69, 0x29, + 0x70, 0x20, + 0x71, 0x70, + 0x72, 0x04, + 0x73, 0x00, + 0x70, 0x40, + 0x71, 0x70, + 0x72, 0x04, + 0x73, 0x00, + 0x70, 0x60, + 0x71, 0x70, + 0x72, 0x04, + 0x73, 0x00, + 0x70, 0x80, + 0x71, 0x70, + 0x72, 0x04, + 0x73, 0x00, + 0x70, 0xa0, + 0x71, 0x70, + 0x72, 0x04, + 0x73, 0x00, + 0x70, 0x1f, + 0xa0, 0x44, + 0xc0, 0x08, + 0xc1, 0x10, + 0xc2, 0x08, + 0xc3, 0x10, + 0xc4, 0x08, + 0xc5, 0xf0, + 0xc6, 0xf0, + 0xc7, 0x0a, + 0xc8, 0x1a, + 0xc9, 0x80, + 0xca, 0x23, + 0xcb, 0x24, + 0xce, 0x74, + 0x90, 0x03, + 0x76, 0x80, + 0x77, 0x42, + 0x78, 0x0a, + 0x79, 0x80, + 0xad, 0x40, + 0xae, 0x07, + 0x7f, 0xd4, + 0x7c, 0x00, + 0x80, 0xa8, + 0x81, 0xda, + 0x7c, 0x01, + 0x80, 0xda, + 0x81, 0xec, + 0x7c, 0x02, + 0x80, 0xca, + 0x81, 0xeb, + 0x7c, 0x03, + 0x80, 0xba, + 0x81, 0xdb, + 0x85, 0x08, + 0x86, 0x00, + 0x87, 0x02, + 0x89, 0x80, + 0x8b, 0x44, + 0x8c, 0xaa, + 0x8a, 0x10, + 0xba, 0x00, + 0xf5, 0x04, + 0xfe, 0x44, + 0xd2, 0x32, + 0xb8, 0x00, +}; + +/* DS3000 doesn't need some parameters as input and auto-detects them */ +/* save input from the application of those parameters */ +struct ds3000_tuning { + u32 frequency; + u32 symbol_rate; + fe_spectral_inversion_t inversion; + enum fe_code_rate fec; + + /* input values */ + u8 inversion_val; + fe_modulation_t delivery; + u8 rolloff; +}; + +struct ds3000_state { + struct i2c_adapter *i2c; + const struct ds3000_config *config; + + struct dvb_frontend frontend; + + struct ds3000_tuning dcur; + struct ds3000_tuning dnxt; + + u8 skip_fw_load; + + /* previous uncorrected block counter for DVB-S2 */ + u16 prevUCBS2; +}; + +static int ds3000_writereg(struct ds3000_state *state, int reg, int data) +{ + u8 buf[] = { reg, data }; + struct i2c_msg msg = { .addr = state->config->demod_address, + .flags = 0, .buf = buf, .len = 2 }; + int err; + + dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data); + + err = i2c_transfer(state->i2c, &msg, 1); + if (err != 1) { + printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x," + " value == 0x%02x)\n", __func__, err, reg, data); + return -EREMOTEIO; + } + + return 0; +} + +static int ds3000_tuner_writereg(struct ds3000_state *state, int reg, int data) +{ + u8 buf[] = { reg, data }; + struct i2c_msg msg = { .addr = 0x60, + .flags = 0, .buf = buf, .len = 2 }; + int err; + + dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data); + + ds3000_writereg(state, 0x03, 0x11); + err = i2c_transfer(state->i2c, &msg, 1); + if (err != 1) { + printk("%s: writereg error(err == %i, reg == 0x%02x," + " value == 0x%02x)\n", __func__, err, reg, data); + return -EREMOTEIO; + } + + return 0; +} + +/* I2C write for 8k firmware load */ +static int ds3000_writeFW(struct ds3000_state *state, int reg, + const u8 *data, u16 len) +{ + int i, ret = -EREMOTEIO; + struct i2c_msg msg; + u8 *buf; + + buf = kmalloc(3, GFP_KERNEL); + if (buf == NULL) { + printk(KERN_ERR "Unable to kmalloc\n"); + ret = -ENOMEM; + goto error; + } + + *(buf) = reg; + + msg.addr = state->config->demod_address; + msg.flags = 0; + msg.buf = buf; + msg.len = 3; + + for (i = 0; i < len; i += 2) { + memcpy(buf + 1, data + i, 2); + + dprintk("%s: write reg 0x%02x, len = %d\n", __func__, reg, len); + + ret = i2c_transfer(state->i2c, &msg, 1); + if (ret != 1) { + printk(KERN_ERR "%s: write error(err == %i, " + "reg == 0x%02x\n", __func__, ret, reg); + ret = -EREMOTEIO; + } + } + +error: + kfree(buf); + + return ret; +} + +static int ds3000_readreg(struct ds3000_state *state, u8 reg) +{ + int ret; + u8 b0[] = { reg }; + u8 b1[] = { 0 }; + struct i2c_msg msg[] = { + { + .addr = state->config->demod_address, + .flags = 0, + .buf = b0, + .len = 1 + }, { + .addr = state->config->demod_address, + .flags = I2C_M_RD, + .buf = b1, + .len = 1 + } + }; + + ret = i2c_transfer(state->i2c, msg, 2); + + if (ret != 2) { + printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret); + return ret; + } + + dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]); + + return b1[0]; +} + +static int ds3000_tuner_readreg(struct ds3000_state *state, u8 reg) +{ + int ret; + u8 b0[] = { reg }; + u8 b1[] = { 0 }; + struct i2c_msg msg[] = { + { + .addr = 0x60, + .flags = 0, + .buf = b0, + .len = 1 + }, { + .addr = 0x60, + .flags = I2C_M_RD, + .buf = b1, + .len = 1 + } + }; + + ds3000_writereg(state, 0x03, 0x12); + ret = i2c_transfer(state->i2c, msg, 2); + + if (ret != 2) { + printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret); + return ret; + } + + dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]); + + return b1[0]; +} + +static int ds3000_set_inversion(struct ds3000_state *state, + fe_spectral_inversion_t inversion) +{ + dprintk("%s(%d)\n", __func__, inversion); + + switch (inversion) { + case INVERSION_OFF: + case INVERSION_ON: + case INVERSION_AUTO: + break; + default: + return -EINVAL; + } + + state->dnxt.inversion = inversion; + + return 0; +} + +static int ds3000_set_symbolrate(struct ds3000_state *state, u32 rate) +{ + int ret = 0; + + dprintk("%s()\n", __func__); + + dprintk("%s() symbol_rate = %d\n", __func__, state->dnxt.symbol_rate); + + /* check if symbol rate is within limits */ + if ((state->dnxt.symbol_rate > + state->frontend.ops.info.symbol_rate_max) || + (state->dnxt.symbol_rate < + state->frontend.ops.info.symbol_rate_min)) + ret = -EOPNOTSUPP; + + state->dnxt.symbol_rate = rate; + + return ret; +} + +static int ds3000_load_firmware(struct dvb_frontend *fe, + const struct firmware *fw); + +static int ds3000_firmware_ondemand(struct dvb_frontend *fe) +{ + struct ds3000_state *state = fe->demodulator_priv; + const struct firmware *fw; + int ret = 0; + + dprintk("%s()\n", __func__); + + if (ds3000_readreg(state, 0xb2) <= 0) + return ret; + + if (state->skip_fw_load) + return 0; + /* Load firmware */ + /* request the firmware, this will block until someone uploads it */ + printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__, + DS3000_DEFAULT_FIRMWARE); + ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE, + state->i2c->dev.parent); + printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__); + if (ret) { + printk(KERN_ERR "%s: No firmware uploaded (timeout or file not " + "found?)\n", __func__); + return ret; + } + + /* Make sure we don't recurse back through here during loading */ + state->skip_fw_load = 1; + + ret = ds3000_load_firmware(fe, fw); + if (ret) + printk("%s: Writing firmware to device failed\n", __func__); + + release_firmware(fw); + + dprintk("%s: Firmware upload %s\n", __func__, + ret == 0 ? "complete" : "failed"); + + /* Ensure firmware is always loaded if required */ + state->skip_fw_load = 0; + + return ret; +} + +static int ds3000_load_firmware(struct dvb_frontend *fe, + const struct firmware *fw) +{ + struct ds3000_state *state = fe->demodulator_priv; + + dprintk("%s\n", __func__); + dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n", + fw->size, + fw->data[0], + fw->data[1], + fw->data[fw->size - 2], + fw->data[fw->size - 1]); + + /* Begin the firmware load process */ + ds3000_writereg(state, 0xb2, 0x01); + /* write the entire firmware */ + ds3000_writeFW(state, 0xb0, fw->data, fw->size); + ds3000_writereg(state, 0xb2, 0x00); + + return 0; +} + +static void ds3000_dump_registers(struct dvb_frontend *fe) +{ + struct ds3000_state *state = fe->demodulator_priv; + int x, y, reg = 0, val; + + for (y = 0; y < 16; y++) { + dprintk("%s: %02x: ", __func__, y); + for (x = 0; x < 16; x++) { + reg = (y << 4) + x; + val = ds3000_readreg(state, reg); + if (x != 15) + dprintk("%02x ", val); + else + dprintk("%02x\n", val); + } + } + dprintk("%s: -- DS3000 DUMP DONE --\n", __func__); +} + +static int ds3000_read_status(struct dvb_frontend *fe, fe_status_t* status) +{ + struct ds3000_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + int lock; + + *status = 0; + + switch (c->delivery_system) { + case SYS_DVBS: + lock = ds3000_readreg(state, 0xd1); + if ((lock & 0x07) == 0x07) + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC | + FE_HAS_LOCK; + + break; + case SYS_DVBS2: + lock = ds3000_readreg(state, 0x0d); + if ((lock & 0x8f) == 0x8f) + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC | + FE_HAS_LOCK; + + break; + default: + return 1; + } + + dprintk("%s: status = 0x%02x\n", __func__, lock); + + return 0; +} + +#define FE_IS_TUNED (FE_HAS_SIGNAL + FE_HAS_LOCK) +static int ds3000_is_tuned(struct dvb_frontend *fe) +{ + fe_status_t tunerstat; + + ds3000_read_status(fe, &tunerstat); + + return ((tunerstat & FE_IS_TUNED) == FE_IS_TUNED); +} + +/* read DS3000 BER value */ +static int ds3000_read_ber(struct dvb_frontend *fe, u32* ber) +{ + struct ds3000_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u8 data; + u32 ber_reading, lpdc_frames; + + dprintk("%s()\n", __func__); + + switch (c->delivery_system) { + case SYS_DVBS: + /* set the number of bytes checked during + BER estimation */ + ds3000_writereg(state, 0xf9, 0x04); + /* read BER estimation status */ + data = ds3000_readreg(state, 0xf8); + /* check if BER estimation is ready */ + if ((data & 0x10) == 0) { + /* this is the number of error bits, + to calculate the bit error rate + divide to 8388608 */ + *ber = (ds3000_readreg(state, 0xf7) << 8) | + ds3000_readreg(state, 0xf6); + /* start counting error bits */ + /* need to be set twice + otherwise it fails sometimes */ + data |= 0x10; + ds3000_writereg(state, 0xf8, data); + ds3000_writereg(state, 0xf8, data); + } else + /* used to indicate that BER estimation + is not ready, i.e. BER is unknown */ + *ber = 0xffffffff; + break; + case SYS_DVBS2: + /* read the number of LPDC decoded frames */ + lpdc_frames = (ds3000_readreg(state, 0xd7) << 16) | + (ds3000_readreg(state, 0xd6) << 8) | + ds3000_readreg(state, 0xd5); + /* read the number of packets with bad CRC */ + ber_reading = (ds3000_readreg(state, 0xf8) << 8) | + ds3000_readreg(state, 0xf7); + if (lpdc_frames > 750) { + /* clear LPDC frame counters */ + ds3000_writereg(state, 0xd1, 0x01); + /* clear bad packets counter */ + ds3000_writereg(state, 0xf9, 0x01); + /* enable bad packets counter */ + ds3000_writereg(state, 0xf9, 0x00); + /* enable LPDC frame counters */ + ds3000_writereg(state, 0xd1, 0x00); + *ber = ber_reading; + } else + /* used to indicate that BER estimation is not ready, + i.e. BER is unknown */ + *ber = 0xffffffff; + break; + default: + return 1; + } + + return 0; +} + +/* read TS2020 signal strength */ +static int ds3000_read_signal_strength(struct dvb_frontend *fe, + u16 *signal_strength) +{ + struct ds3000_state *state = fe->demodulator_priv; + u16 sig_reading, sig_strength; + u8 rfgain, bbgain; + + dprintk("%s()\n", __func__); + + rfgain = ds3000_tuner_readreg(state, 0x3d) & 0x1f; + bbgain = ds3000_tuner_readreg(state, 0x21) & 0x1f; + + if (rfgain > 15) + rfgain = 15; + if (bbgain > 13) + bbgain = 13; + + sig_reading = rfgain * 2 + bbgain * 3; + + sig_strength = 40 + (64 - sig_reading) * 50 / 64 ; + + /* cook the value to be suitable for szap-s2 human readable output */ + *signal_strength = sig_strength * 1000; + + dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", __func__, + sig_reading, *signal_strength); + + return 0; +} + +/* calculate DS3000 snr value in dB */ +static int ds3000_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + struct ds3000_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u8 snr_reading, snr_value; + u32 dvbs2_signal_reading, dvbs2_noise_reading, tmp; + static const u16 dvbs_snr_tab[] = { /* 20 x Table (rounded up) */ + 0x0000, 0x1b13, 0x2aea, 0x3627, 0x3ede, 0x45fe, 0x4c03, + 0x513a, 0x55d4, 0x59f2, 0x5dab, 0x6111, 0x6431, 0x6717, + 0x69c9, 0x6c4e, 0x6eac, 0x70e8, 0x7304, 0x7505 + }; + static const u16 dvbs2_snr_tab[] = { /* 80 x Table (rounded up) */ + 0x0000, 0x0bc2, 0x12a3, 0x1785, 0x1b4e, 0x1e65, 0x2103, + 0x2347, 0x2546, 0x2710, 0x28ae, 0x2a28, 0x2b83, 0x2cc5, + 0x2df1, 0x2f09, 0x3010, 0x3109, 0x31f4, 0x32d2, 0x33a6, + 0x3470, 0x3531, 0x35ea, 0x369b, 0x3746, 0x37ea, 0x3888, + 0x3920, 0x39b3, 0x3a42, 0x3acc, 0x3b51, 0x3bd3, 0x3c51, + 0x3ccb, 0x3d42, 0x3db6, 0x3e27, 0x3e95, 0x3f00, 0x3f68, + 0x3fcf, 0x4033, 0x4094, 0x40f4, 0x4151, 0x41ac, 0x4206, + 0x425e, 0x42b4, 0x4308, 0x435b, 0x43ac, 0x43fc, 0x444a, + 0x4497, 0x44e2, 0x452d, 0x4576, 0x45bd, 0x4604, 0x4649, + 0x468e, 0x46d1, 0x4713, 0x4755, 0x4795, 0x47d4, 0x4813, + 0x4851, 0x488d, 0x48c9, 0x4904, 0x493f, 0x4978, 0x49b1, + 0x49e9, 0x4a20, 0x4a57 + }; + + dprintk("%s()\n", __func__); + + switch (c->delivery_system) { + case SYS_DVBS: + snr_reading = ds3000_readreg(state, 0xff); + snr_reading /= 8; + if (snr_reading == 0) + *snr = 0x0000; + else { + if (snr_reading > 20) + snr_reading = 20; + snr_value = dvbs_snr_tab[snr_reading - 1] * 10 / 23026; + /* cook the value to be suitable for szap-s2 + human readable output */ + *snr = snr_value * 8 * 655; + } + dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__, + snr_reading, *snr); + break; + case SYS_DVBS2: + dvbs2_noise_reading = (ds3000_readreg(state, 0x8c) & 0x3f) + + (ds3000_readreg(state, 0x8d) << 4); + dvbs2_signal_reading = ds3000_readreg(state, 0x8e); + tmp = dvbs2_signal_reading * dvbs2_signal_reading >> 1; + if (dvbs2_signal_reading == 0) { + *snr = 0x0000; + return 0; + } + if (dvbs2_noise_reading == 0) { + snr_value = 0x0013; + /* cook the value to be suitable for szap-s2 + human readable output */ + *snr = 0xffff; + return 0; + } + if (tmp > dvbs2_noise_reading) { + snr_reading = tmp / dvbs2_noise_reading; + if (snr_reading > 80) + snr_reading = 80; + snr_value = dvbs2_snr_tab[snr_reading - 1] / 1000; + /* cook the value to be suitable for szap-s2 + human readable output */ + *snr = snr_value * 5 * 655; + } else { + snr_reading = dvbs2_noise_reading / tmp; + if (snr_reading > 80) + snr_reading = 80; + *snr = -(dvbs2_snr_tab[snr_reading] / 1000); + } + dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__, + snr_reading, *snr); + break; + default: + return 1; + } + + return 0; +} + +/* read DS3000 uncorrected blocks */ +static int ds3000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + struct ds3000_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u8 data; + u16 _ucblocks; + + dprintk("%s()\n", __func__); + + switch (c->delivery_system) { + case SYS_DVBS: + *ucblocks = (ds3000_readreg(state, 0xf5) << 8) | + ds3000_readreg(state, 0xf4); + data = ds3000_readreg(state, 0xf8); + /* clear packet counters */ + data &= ~0x20; + ds3000_writereg(state, 0xf8, data); + /* enable packet counters */ + data |= 0x20; + ds3000_writereg(state, 0xf8, data); + break; + case SYS_DVBS2: + _ucblocks = (ds3000_readreg(state, 0xe2) << 8) | + ds3000_readreg(state, 0xe1); + if (_ucblocks > state->prevUCBS2) + *ucblocks = _ucblocks - state->prevUCBS2; + else + *ucblocks = state->prevUCBS2 - _ucblocks; + state->prevUCBS2 = _ucblocks; + break; + default: + return 1; + } + + return 0; +} + +/* Overwrite the current tuning params, we are about to tune */ +static void ds3000_clone_params(struct dvb_frontend *fe) +{ + struct ds3000_state *state = fe->demodulator_priv; + memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur)); +} + +static int ds3000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +{ + struct ds3000_state *state = fe->demodulator_priv; + u8 data; + + dprintk("%s(%d)\n", __func__, tone); + if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) { + printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone); + return -EINVAL; + } + + data = ds3000_readreg(state, 0xa2); + data &= ~0xc0; + ds3000_writereg(state, 0xa2, data); + + switch (tone) { + case SEC_TONE_ON: + dprintk("%s: setting tone on\n", __func__); + data = ds3000_readreg(state, 0xa1); + data &= ~0x43; + data |= 0x04; + ds3000_writereg(state, 0xa1, data); + break; + case SEC_TONE_OFF: + dprintk("%s: setting tone off\n", __func__); + data = ds3000_readreg(state, 0xa2); + data |= 0x80; + ds3000_writereg(state, 0xa2, data); + break; + } + + return 0; +} + +static int ds3000_send_diseqc_msg(struct dvb_frontend *fe, + struct dvb_diseqc_master_cmd *d) +{ + struct ds3000_state *state = fe->demodulator_priv; + int i; + u8 data; + + /* Dump DiSEqC message */ + dprintk("%s(", __func__); + for (i = 0 ; i < d->msg_len;) { + dprintk("0x%02x", d->msg[i]); + if (++i < d->msg_len) + dprintk(", "); + } + + /* enable DiSEqC message send pin */ + data = ds3000_readreg(state, 0xa2); + data &= ~0xc0; + ds3000_writereg(state, 0xa2, data); + + /* DiSEqC message */ + for (i = 0; i < d->msg_len; i++) + ds3000_writereg(state, 0xa3 + i, d->msg[i]); + + data = ds3000_readreg(state, 0xa1); + /* clear DiSEqC message length and status, + enable DiSEqC message send */ + data &= ~0xf8; + /* set DiSEqC mode, modulation active during 33 pulses, + set DiSEqC message length */ + data |= ((d->msg_len - 1) << 3) | 0x07; + ds3000_writereg(state, 0xa1, data); + + /* wait up to 150ms for DiSEqC transmission to complete */ + for (i = 0; i < 15; i++) { + data = ds3000_readreg(state, 0xa1); + if ((data & 0x40) == 0) + break; + msleep(10); + } + + /* DiSEqC timeout after 150ms */ + if (i == 15) { + data = ds3000_readreg(state, 0xa1); + data &= ~0x80; + data |= 0x40; + ds3000_writereg(state, 0xa1, data); + + data = ds3000_readreg(state, 0xa2); + data &= ~0xc0; + data |= 0x80; + ds3000_writereg(state, 0xa2, data); + + return 1; + } + + data = ds3000_readreg(state, 0xa2); + data &= ~0xc0; + data |= 0x80; + ds3000_writereg(state, 0xa2, data); + + return 0; +} + +/* Send DiSEqC burst */ +static int ds3000_diseqc_send_burst(struct dvb_frontend *fe, + fe_sec_mini_cmd_t burst) +{ + struct ds3000_state *state = fe->demodulator_priv; + int i; + u8 data; + + dprintk("%s()\n", __func__); + + data = ds3000_readreg(state, 0xa2); + data &= ~0xc0; + ds3000_writereg(state, 0xa2, data); + + /* DiSEqC burst */ + if (burst == SEC_MINI_A) + /* Unmodulated tone burst */ + ds3000_writereg(state, 0xa1, 0x02); + else if (burst == SEC_MINI_B) + /* Modulated tone burst */ + ds3000_writereg(state, 0xa1, 0x01); + else + return -EINVAL; + + msleep(13); + for (i = 0; i < 5; i++) { + data = ds3000_readreg(state, 0xa1); + if ((data & 0x40) == 0) + break; + msleep(1); + } + + if (i == 5) { + data = ds3000_readreg(state, 0xa1); + data &= ~0x80; + data |= 0x40; + ds3000_writereg(state, 0xa1, data); + + data = ds3000_readreg(state, 0xa2); + data &= ~0xc0; + data |= 0x80; + ds3000_writereg(state, 0xa2, data); + + return 1; + } + + data = ds3000_readreg(state, 0xa2); + data &= ~0xc0; + data |= 0x80; + ds3000_writereg(state, 0xa2, data); + + return 0; +} + +static void ds3000_release(struct dvb_frontend *fe) +{ + struct ds3000_state *state = fe->demodulator_priv; + dprintk("%s\n", __func__); + kfree(state); +} + +static struct dvb_frontend_ops ds3000_ops; + +struct dvb_frontend *ds3000_attach(const struct ds3000_config *config, + struct i2c_adapter *i2c) +{ + struct ds3000_state *state = NULL; + int ret; + + dprintk("%s\n", __func__); + + /* allocate memory for the internal state */ + state = kmalloc(sizeof(struct ds3000_state), GFP_KERNEL); + if (state == NULL) { + printk(KERN_ERR "Unable to kmalloc\n"); + goto error2; + } + + /* setup the state */ + memset(state, 0, sizeof(struct ds3000_state)); + + state->config = config; + state->i2c = i2c; + state->prevUCBS2 = 0; + + /* check if the demod is present */ + ret = ds3000_readreg(state, 0x00) & 0xfe; + if (ret != 0xe0) { + printk(KERN_ERR "Invalid probe, probably not a DS3000\n"); + goto error3; + } + + printk(KERN_INFO "DS3000 chip version: %d.%d attached.\n", + ds3000_readreg(state, 0x02), + ds3000_readreg(state, 0x01)); + + memcpy(&state->frontend.ops, &ds3000_ops, + sizeof(struct dvb_frontend_ops)); + state->frontend.demodulator_priv = state; + return &state->frontend; + +error3: + kfree(state); +error2: + return NULL; +} +EXPORT_SYMBOL(ds3000_attach); + +static int ds3000_set_property(struct dvb_frontend *fe, + struct dtv_property *tvp) +{ + dprintk("%s(..)\n", __func__); + return 0; +} + +static int ds3000_get_property(struct dvb_frontend *fe, + struct dtv_property *tvp) +{ + dprintk("%s(..)\n", __func__); + return 0; +} + +static int ds3000_tune(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) +{ + struct ds3000_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + + int ret = 0, retune, i; + u8 status, mlpf, mlpf_new, mlpf_max, mlpf_min, nlpf; + u16 value, ndiv; + u32 f3db; + + dprintk("%s() ", __func__); + + /* Load the firmware if required */ + ret = ds3000_firmware_ondemand(fe); + if (ret != 0) { + printk(KERN_ERR "%s: Unable initialise the firmware\n", + __func__); + return ret; + } + + state->dnxt.delivery = c->modulation; + state->dnxt.frequency = c->frequency; + state->dnxt.rolloff = 2; /* fixme */ + state->dnxt.fec = c->fec_inner; + + ret = ds3000_set_inversion(state, p->inversion); + if (ret != 0) + return ret; + + ret = ds3000_set_symbolrate(state, c->symbol_rate); + if (ret != 0) + return ret; + + /* discard the 'current' tuning parameters and prepare to tune */ + ds3000_clone_params(fe); + + retune = 1; /* try 1 times */ + dprintk("%s: retune = %d\n", __func__, retune); + dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency); + dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate); + dprintk("%s: FEC = %d \n", __func__, + state->dcur.fec); + dprintk("%s: Inversion = %d\n", __func__, state->dcur.inversion); + + do { + /* Reset status register */ + status = 0; + /* Tune */ + /* TS2020 init */ + ds3000_tuner_writereg(state, 0x42, 0x73); + ds3000_tuner_writereg(state, 0x05, 0x01); + ds3000_tuner_writereg(state, 0x62, 0xf5); + /* unknown */ + ds3000_tuner_writereg(state, 0x07, 0x02); + ds3000_tuner_writereg(state, 0x10, 0x00); + ds3000_tuner_writereg(state, 0x60, 0x79); + ds3000_tuner_writereg(state, 0x08, 0x01); + ds3000_tuner_writereg(state, 0x00, 0x01); + /* calculate and set freq divider */ + if (state->dcur.frequency < 1146000) { + ds3000_tuner_writereg(state, 0x10, 0x11); + ndiv = ((state->dcur.frequency * (6 + 8) * 4) + + (DS3000_XTAL_FREQ / 2)) / + DS3000_XTAL_FREQ - 1024; + } else { + ds3000_tuner_writereg(state, 0x10, 0x01); + ndiv = ((state->dcur.frequency * (6 + 8) * 2) + + (DS3000_XTAL_FREQ / 2)) / + DS3000_XTAL_FREQ - 1024; + } + + ds3000_tuner_writereg(state, 0x01, (ndiv & 0x0f00) >> 8); + ds3000_tuner_writereg(state, 0x02, ndiv & 0x00ff); + + /* set pll */ + ds3000_tuner_writereg(state, 0x03, 0x06); + ds3000_tuner_writereg(state, 0x51, 0x0f); + ds3000_tuner_writereg(state, 0x51, 0x1f); + ds3000_tuner_writereg(state, 0x50, 0x10); + ds3000_tuner_writereg(state, 0x50, 0x00); + msleep(5); + + /* unknown */ + ds3000_tuner_writereg(state, 0x51, 0x17); + ds3000_tuner_writereg(state, 0x51, 0x1f); + ds3000_tuner_writereg(state, 0x50, 0x08); + ds3000_tuner_writereg(state, 0x50, 0x00); + msleep(5); + + value = ds3000_tuner_readreg(state, 0x3d); + value &= 0x0f; + if ((value > 4) && (value < 15)) { + value -= 3; + if (value < 4) + value = 4; + value = ((value << 3) | 0x01) & 0x79; + } + + ds3000_tuner_writereg(state, 0x60, value); + ds3000_tuner_writereg(state, 0x51, 0x17); + ds3000_tuner_writereg(state, 0x51, 0x1f); + ds3000_tuner_writereg(state, 0x50, 0x08); + ds3000_tuner_writereg(state, 0x50, 0x00); + + /* set low-pass filter period */ + ds3000_tuner_writereg(state, 0x04, 0x2e); + ds3000_tuner_writereg(state, 0x51, 0x1b); + ds3000_tuner_writereg(state, 0x51, 0x1f); + ds3000_tuner_writereg(state, 0x50, 0x04); + ds3000_tuner_writereg(state, 0x50, 0x00); + msleep(5); + + f3db = ((state->dcur.symbol_rate / 1000) << 2) / 5 + 2000; + if ((state->dcur.symbol_rate / 1000) < 5000) + f3db += 3000; + if (f3db < 7000) + f3db = 7000; + if (f3db > 40000) + f3db = 40000; + + /* set low-pass filter baseband */ + value = ds3000_tuner_readreg(state, 0x26); + mlpf = 0x2e * 207 / ((value << 1) + 151); + mlpf_max = mlpf * 135 / 100; + mlpf_min = mlpf * 78 / 100; + if (mlpf_max > 63) + mlpf_max = 63; + + /* rounded to the closest integer */ + nlpf = ((mlpf * f3db * 1000) + (2766 * DS3000_XTAL_FREQ / 2)) + / (2766 * DS3000_XTAL_FREQ); + if (nlpf > 23) + nlpf = 23; + if (nlpf < 1) + nlpf = 1; + + /* rounded to the closest integer */ + mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) + + (1000 * f3db / 2)) / (1000 * f3db); + + if (mlpf_new < mlpf_min) { + nlpf++; + mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) + + (1000 * f3db / 2)) / (1000 * f3db); + } + + if (mlpf_new > mlpf_max) + mlpf_new = mlpf_max; + + ds3000_tuner_writereg(state, 0x04, mlpf_new); + ds3000_tuner_writereg(state, 0x06, nlpf); + ds3000_tuner_writereg(state, 0x51, 0x1b); + ds3000_tuner_writereg(state, 0x51, 0x1f); + ds3000_tuner_writereg(state, 0x50, 0x04); + ds3000_tuner_writereg(state, 0x50, 0x00); + msleep(5); + + /* unknown */ + ds3000_tuner_writereg(state, 0x51, 0x1e); + ds3000_tuner_writereg(state, 0x51, 0x1f); + ds3000_tuner_writereg(state, 0x50, 0x01); + ds3000_tuner_writereg(state, 0x50, 0x00); + msleep(60); + + /* ds3000 global reset */ + ds3000_writereg(state, 0x07, 0x80); + ds3000_writereg(state, 0x07, 0x00); + /* ds3000 build-in uC reset */ + ds3000_writereg(state, 0xb2, 0x01); + /* ds3000 software reset */ + ds3000_writereg(state, 0x00, 0x01); + + switch (c->delivery_system) { + case SYS_DVBS: + /* initialise the demod in DVB-S mode */ + for (i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2) + ds3000_writereg(state, + ds3000_dvbs_init_tab[i], + ds3000_dvbs_init_tab[i + 1]); + value = ds3000_readreg(state, 0xfe); + value &= 0xc0; + value |= 0x1b; + ds3000_writereg(state, 0xfe, value); + break; + case SYS_DVBS2: + /* initialise the demod in DVB-S2 mode */ + for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2) + ds3000_writereg(state, + ds3000_dvbs2_init_tab[i], + ds3000_dvbs2_init_tab[i + 1]); + ds3000_writereg(state, 0xfe, 0x54); + break; + default: + return 1; + } + + /* enable 27MHz clock output */ + ds3000_writereg(state, 0x29, 0x80); + /* enable ac coupling */ + ds3000_writereg(state, 0x25, 0x8a); + + /* enhance symbol rate performance */ + if ((state->dcur.symbol_rate / 1000) <= 5000) { + value = 29777 / (state->dcur.symbol_rate / 1000) + 1; + if (value % 2 != 0) + value++; + ds3000_writereg(state, 0xc3, 0x0d); + ds3000_writereg(state, 0xc8, value); + ds3000_writereg(state, 0xc4, 0x10); + ds3000_writereg(state, 0xc7, 0x0e); + } else if ((state->dcur.symbol_rate / 1000) <= 10000) { + value = 92166 / (state->dcur.symbol_rate / 1000) + 1; + if (value % 2 != 0) + value++; + ds3000_writereg(state, 0xc3, 0x07); + ds3000_writereg(state, 0xc8, value); + ds3000_writereg(state, 0xc4, 0x09); + ds3000_writereg(state, 0xc7, 0x12); + } else if ((state->dcur.symbol_rate / 1000) <= 20000) { + value = 64516 / (state->dcur.symbol_rate / 1000) + 1; + ds3000_writereg(state, 0xc3, value); + ds3000_writereg(state, 0xc8, 0x0e); + ds3000_writereg(state, 0xc4, 0x07); + ds3000_writereg(state, 0xc7, 0x18); + } else { + value = 129032 / (state->dcur.symbol_rate / 1000) + 1; + ds3000_writereg(state, 0xc3, value); + ds3000_writereg(state, 0xc8, 0x0a); + ds3000_writereg(state, 0xc4, 0x05); + ds3000_writereg(state, 0xc7, 0x24); + } + + /* normalized symbol rate rounded to the closest integer */ + value = (((state->dcur.symbol_rate / 1000) << 16) + + (DS3000_SAMPLE_RATE / 2)) / DS3000_SAMPLE_RATE; + ds3000_writereg(state, 0x61, value & 0x00ff); + ds3000_writereg(state, 0x62, (value & 0xff00) >> 8); + + /* co-channel interference cancellation disabled */ + ds3000_writereg(state, 0x56, 0x00); + + /* equalizer disabled */ + ds3000_writereg(state, 0x76, 0x00); + + /*ds3000_writereg(state, 0x08, 0x03); + ds3000_writereg(state, 0xfd, 0x22); + ds3000_writereg(state, 0x08, 0x07); + ds3000_writereg(state, 0xfd, 0x42); + ds3000_writereg(state, 0x08, 0x07);*/ + + /* ds3000 out of software reset */ + ds3000_writereg(state, 0x00, 0x00); + /* start ds3000 build-in uC */ + ds3000_writereg(state, 0xb2, 0x00); + + /* TODO: calculate and set carrier offset */ + + /* wait before retrying */ + for (i = 0; i < 30 ; i++) { + if (ds3000_is_tuned(fe)) { + dprintk("%s: Tuned\n", __func__); + ds3000_dump_registers(fe); + goto tuned; + } + msleep(1); + } + + dprintk("%s: Not tuned\n", __func__); + ds3000_dump_registers(fe); + + } while (--retune); + +tuned: + return ret; +} + +static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe) +{ + dprintk("%s()\n", __func__); + return DVBFE_ALGO_SW; +} + +/* + * Initialise or wake up device + * + * Power config will reset and load initial firmware if required + */ +static int ds3000_initfe(struct dvb_frontend *fe) +{ + dprintk("%s()\n", __func__); + return 0; +} + +/* Put device to sleep */ +static int ds3000_sleep(struct dvb_frontend *fe) +{ + dprintk("%s()\n", __func__); + return 0; +} + +static struct dvb_frontend_ops ds3000_ops = { + + .info = { + .name = "Montage Technology DS3000/TS2020", + .type = FE_QPSK, + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_stepsize = 1011, /* kHz for QPSK frontends */ + .frequency_tolerance = 5000, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | + FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_2G_MODULATION | + FE_CAN_QPSK | FE_CAN_RECOVER + }, + + .release = ds3000_release, + + .init = ds3000_initfe, + .sleep = ds3000_sleep, + .read_status = ds3000_read_status, + .read_ber = ds3000_read_ber, + .read_signal_strength = ds3000_read_signal_strength, + .read_snr = ds3000_read_snr, + .read_ucblocks = ds3000_read_ucblocks, + .set_tone = ds3000_set_tone, + .diseqc_send_master_cmd = ds3000_send_diseqc_msg, + .diseqc_send_burst = ds3000_diseqc_send_burst, + .get_frontend_algo = ds3000_get_algo, + + .set_property = ds3000_set_property, + .get_property = ds3000_get_property, + .set_frontend = ds3000_tune, +}; + +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); + +MODULE_DESCRIPTION("DVB Frontend module for Montage Technology " + "DS3000/TS2020 hardware"); +MODULE_AUTHOR("Konstantin Dimitrov"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/ds3000.h b/drivers/media/dvb/frontends/ds3000.h new file mode 100644 index 00000000000..67f67038740 --- /dev/null +++ b/drivers/media/dvb/frontends/ds3000.h @@ -0,0 +1,45 @@ +/* + Montage Technology DS3000/TS2020 - DVBS/S2 Satellite demod/tuner driver + Copyright (C) 2009 Konstantin Dimitrov + + Copyright (C) 2009 TurboSight.com + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef DS3000_H +#define DS3000_H + +#include + +struct ds3000_config { + /* the demodulator's i2c address */ + u8 demod_address; +}; + +#if defined(CONFIG_DVB_DS3000) || \ + (defined(CONFIG_DVB_DS3000_MODULE) && defined(MODULE)) +extern struct dvb_frontend *ds3000_attach(const struct ds3000_config *config, + struct i2c_adapter *i2c); +#else +static inline +struct dvb_frontend *ds3000_attach(const struct ds3000_config *config, + struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* CONFIG_DVB_DS3000 */ +#endif /* DS3000_H */ diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig index fd3fc3e3198..bcdda9a9aa9 100644 --- a/drivers/media/video/cx23885/Kconfig +++ b/drivers/media/video/cx23885/Kconfig @@ -18,7 +18,9 @@ config VIDEO_CX23885 select DVB_TDA10048 if !DVB_FE_CUSTOMISE select DVB_LNBP21 if !DVB_FE_CUSTOMISE select DVB_STV6110 if !DVB_FE_CUSTOMISE + select DVB_CX24116 if !DVB_FE_CUSTOMISE select DVB_STV0900 if !DVB_FE_CUSTOMISE + select DVB_DS3000 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile index bb462589b53..5787ae24363 100644 --- a/drivers/media/video/cx23885/Makefile +++ b/drivers/media/video/cx23885/Makefile @@ -1,7 +1,7 @@ cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \ cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \ cx23885-ioctl.o cx23885-ir.o cx23885-input.o cx23888-ir.o \ - netup-init.o cimax2.o netup-eeprom.o + netup-init.o cimax2.o netup-eeprom.o cx23885-f300.o obj-$(CONFIG_VIDEO_CX23885) += cx23885.o diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 23302ddf418..1ec48169277 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -782,10 +782,14 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) cx_set(GP0_IO, 0x00040004); break; case CX23885_BOARD_TBS_6920: - case CX23885_BOARD_TEVII_S470: cx_write(MC417_CTL, 0x00000036); cx_write(MC417_OEN, 0x00001000); - cx_write(MC417_RWD, 0x00001800); + cx_set(MC417_RWD, 0x00000002); + mdelay(200); + cx_clear(MC417_RWD, 0x00000800); + mdelay(200); + cx_set(MC417_RWD, 0x00000800); + mdelay(200); break; case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: /* GPIO-0 INTA from CiMax1 @@ -1002,8 +1006,12 @@ void cx23885_card_setup(struct cx23885_dev *dev) ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; break; - case CX23885_BOARD_TEVII_S470: case CX23885_BOARD_TBS_6920: + ts1->gen_ctrl_val = 0x4; /* Parallel */ + ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ + ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + break; + case CX23885_BOARD_TEVII_S470: case CX23885_BOARD_DVBWORLD_2005: ts1->gen_ctrl_val = 0x5; /* Parallel */ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index e8eb4ec0c30..04b12d27bc1 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -1871,6 +1871,26 @@ void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask) printk(KERN_INFO "%s: Unsupported\n", dev->name); } +u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask) +{ + if (mask & 0x00000007) + return (cx_read(GP0_IO) >> 8) & mask & 0x7; + + if (mask & 0x0007fff8) { + if (encoder_on_portb(dev) || encoder_on_portc(dev)) + printk(KERN_ERR + "%s: Reading GPIO moving on encoder ports\n", + dev->name); + return (cx_read(MC417_RWD) & ((mask & 0x7fff8) >> 3)) << 3; + } + + /* TODO: 23-19 */ + if (mask & 0x00f80000) + printk(KERN_INFO "%s: Unsupported\n", dev->name); + + return 0; +} + void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput) { if ((mask & 0x00000007) && asoutput) diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index bf24e86293c..2607de134fa 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -56,6 +56,8 @@ #include "netup-init.h" #include "lgdt3305.h" #include "atbm8830.h" +#include "ds3000.h" +#include "cx23885-f300.h" static unsigned int debug; @@ -427,26 +429,12 @@ static struct stv6110_config netup_stv6110_tunerconfig_b = { .gain = 8, /* +16 dB - maximum gain */ }; -static int tbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - struct cx23885_tsport *port = fe->dvb->priv; - struct cx23885_dev *dev = port->dev; - - if (voltage == SEC_VOLTAGE_18) - cx_write(MC417_RWD, 0x00001e00);/* GPIO-13 high */ - else if (voltage == SEC_VOLTAGE_13) - cx_write(MC417_RWD, 0x00001a00);/* GPIO-13 low */ - else - cx_write(MC417_RWD, 0x00001800);/* GPIO-12 low */ - return 0; -} - static struct cx24116_config tbs_cx24116_config = { - .demod_address = 0x05, + .demod_address = 0x55, }; -static struct cx24116_config tevii_cx24116_config = { - .demod_address = 0x55, +static struct ds3000_config tevii_ds3000_config = { + .demod_address = 0x68, }; static struct cx24116_config dvbworld_cx24116_config = { @@ -832,23 +820,23 @@ static int dvb_register(struct cx23885_tsport *port) } break; case CX23885_BOARD_TBS_6920: - i2c_bus = &dev->i2c_bus[0]; + i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(cx24116_attach, - &tbs_cx24116_config, - &i2c_bus->i2c_adap); + &tbs_cx24116_config, + &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) - fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage; + fe0->dvb.frontend->ops.set_voltage = f300_set_voltage; break; case CX23885_BOARD_TEVII_S470: i2c_bus = &dev->i2c_bus[1]; - fe0->dvb.frontend = dvb_attach(cx24116_attach, - &tevii_cx24116_config, - &i2c_bus->i2c_adap); + fe0->dvb.frontend = dvb_attach(ds3000_attach, + &tevii_ds3000_config, + &i2c_bus->i2c_adap); if (fe0->dvb.frontend != NULL) - fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage; + fe0->dvb.frontend->ops.set_voltage = f300_set_voltage; break; case CX23885_BOARD_DVBWORLD_2005: diff --git a/drivers/media/video/cx23885/cx23885-f300.c b/drivers/media/video/cx23885/cx23885-f300.c new file mode 100644 index 00000000000..93998f22098 --- /dev/null +++ b/drivers/media/video/cx23885/cx23885-f300.c @@ -0,0 +1,177 @@ +/* + * Driver for Silicon Labs C8051F300 microcontroller. + * + * It is used for LNB power control in TeVii S470, + * TBS 6920 PCIe DVB-S2 cards. + * + * Microcontroller connected to cx23885 GPIO pins: + * GPIO0 - data - P0.3 F300 + * GPIO1 - reset - P0.2 F300 + * GPIO2 - clk - P0.1 F300 + * GPIO3 - busy - P0.0 F300 + * + * Copyright (C) 2009 Igor M. Liplianin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "cx23885.h" + +#define F300_DATA GPIO_0 +#define F300_RESET GPIO_1 +#define F300_CLK GPIO_2 +#define F300_BUSY GPIO_3 + +static void f300_set_line(struct cx23885_dev *dev, u32 line, u8 lvl) +{ + cx23885_gpio_enable(dev, line, 1); + if (lvl == 1) + cx23885_gpio_set(dev, line); + else + cx23885_gpio_clear(dev, line); +} + +static u8 f300_get_line(struct cx23885_dev *dev, u32 line) +{ + cx23885_gpio_enable(dev, line, 0); + + return cx23885_gpio_get(dev, line); +} + +static void f300_send_byte(struct cx23885_dev *dev, u8 dta) +{ + u8 i; + + for (i = 0; i < 8; i++) { + f300_set_line(dev, F300_CLK, 0); + udelay(30); + f300_set_line(dev, F300_DATA, (dta & 0x80) >> 7);/* msb first */ + udelay(30); + dta <<= 1; + f300_set_line(dev, F300_CLK, 1); + udelay(30); + } +} + +static u8 f300_get_byte(struct cx23885_dev *dev) +{ + u8 i, dta = 0; + + for (i = 0; i < 8; i++) { + f300_set_line(dev, F300_CLK, 0); + udelay(30); + dta <<= 1; + f300_set_line(dev, F300_CLK, 1); + udelay(30); + dta |= f300_get_line(dev, F300_DATA);/* msb first */ + + } + + return dta; +} + +static u8 f300_xfer(struct dvb_frontend *fe, u8 *buf) +{ + struct cx23885_tsport *port = fe->dvb->priv; + struct cx23885_dev *dev = port->dev; + u8 i, temp, ret = 0; + + temp = buf[0]; + for (i = 0; i < buf[0]; i++) + temp += buf[i + 1]; + temp = (~temp + 1);/* get check sum */ + buf[1 + buf[0]] = temp; + + f300_set_line(dev, F300_RESET, 1); + f300_set_line(dev, F300_CLK, 1); + udelay(30); + f300_set_line(dev, F300_DATA, 1); + msleep(1); + + /* question: */ + f300_set_line(dev, F300_RESET, 0);/* begin to send data */ + msleep(1); + + f300_send_byte(dev, 0xe0);/* the slave address is 0xe0, write */ + msleep(1); + + temp = buf[0]; + temp += 2; + for (i = 0; i < temp; i++) + f300_send_byte(dev, buf[i]); + + f300_set_line(dev, F300_RESET, 1);/* sent data over */ + f300_set_line(dev, F300_DATA, 1); + + /* answer: */ + temp = 0; + for (i = 0; ((i < 8) & (temp == 0)); i++) { + msleep(1); + if (f300_get_line(dev, F300_BUSY) == 0) + temp = 1; + } + + if (i > 7) { + printk(KERN_ERR "%s: timeout, the slave no response\n", + __func__); + ret = 1; /* timeout, the slave no response */ + } else { /* the slave not busy, prepare for getting data */ + f300_set_line(dev, F300_RESET, 0);/*ready...*/ + msleep(1); + f300_send_byte(dev, 0xe1);/* 0xe1 is Read */ + msleep(1); + temp = f300_get_byte(dev);/*get the data length */ + if (temp > 14) + temp = 14; + + for (i = 0; i < (temp + 1); i++) + f300_get_byte(dev);/* get data to empty buffer */ + + f300_set_line(dev, F300_RESET, 1);/* received data over */ + f300_set_line(dev, F300_DATA, 1); + } + + return ret; +} + +int f300_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +{ + u8 buf[16]; + + buf[0] = 0x05; + buf[1] = 0x38;/* write port */ + buf[2] = 0x01;/* A port, lnb power */ + + switch (voltage) { + case SEC_VOLTAGE_13: + buf[3] = 0x01;/* power on */ + buf[4] = 0x02;/* B port, H/V */ + buf[5] = 0x00;/*13V v*/ + break; + case SEC_VOLTAGE_18: + buf[3] = 0x01; + buf[4] = 0x02; + buf[5] = 0x01;/* 18V h*/ + break; + case SEC_VOLTAGE_OFF: + buf[3] = 0x00;/* power off */ + buf[4] = 0x00; + buf[5] = 0x00; + break; + } + + return f300_xfer(fe, buf); +} diff --git a/drivers/media/video/cx23885/cx23885-f300.h b/drivers/media/video/cx23885/cx23885-f300.h new file mode 100644 index 00000000000..e73344c9496 --- /dev/null +++ b/drivers/media/video/cx23885/cx23885-f300.h @@ -0,0 +1,2 @@ +extern int f300_set_voltage(struct dvb_frontend *fe, + fe_sec_voltage_t voltage); diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index 33832002552..fa744764dc8 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h @@ -471,6 +471,7 @@ extern void cx23885_wakeup(struct cx23885_tsport *port, extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask); extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask); +extern u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask); extern void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput); -- cgit v1.2.3-70-g09d2 From c21c2db414bb38086f99c586ffdf019eedb9cad8 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Wed, 25 Nov 2009 02:49:21 -0300 Subject: V4L/DVB (13495): pvrusb2: Support 16KB FX2 firmware New FX2 firmware from Hauppauge is no longer 8KB in size - it's 16KB. This is true for HVR-1950 and HVR-1900 devices. Without this change, new pvrusb2 users with that hardware are unable to use the driver (because the CD shipped with the hardware only has the 16KB firmware). Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-devattr.c | 2 ++ drivers/media/video/pvrusb2/pvrusb2-devattr.h | 1 + drivers/media/video/pvrusb2/pvrusb2-hdw.c | 15 +++++++++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c index e4d7c13cab8..ef4ff411b39 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c @@ -456,6 +456,7 @@ static const struct pvr2_device_desc pvr2_device_750xx = { .flag_has_analogtuner = !0, .flag_has_composite = !0, .flag_has_svideo = !0, + .flag_fx2_16kb = !0, .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, .default_std_mask = V4L2_STD_NTSC_M, @@ -478,6 +479,7 @@ static const struct pvr2_device_desc pvr2_device_751xx = { .flag_has_analogtuner = !0, .flag_has_composite = !0, .flag_has_svideo = !0, + .flag_fx2_16kb = !0, .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, .default_std_mask = V4L2_STD_NTSC_M, diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h index ea04ecf8aa3..e5b9594eb5f 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h @@ -176,6 +176,7 @@ struct pvr2_device_desc { unsigned int flag_has_analogtuner:1; /* Has analog tuner */ unsigned int flag_has_composite:1; /* Has composite input */ unsigned int flag_has_svideo:1; /* Has s-video input */ + unsigned int flag_fx2_16kb:1; /* 16KB FX2 firmware OK here */ }; extern struct usb_device_id pvr2_device_table[]; diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 4c1a2a53442..9be04772c72 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -1474,8 +1474,19 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw) pipe = usb_sndctrlpipe(hdw->usb_dev, 0); - if (fw_entry->size != 0x2000){ - pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size"); + if ((fw_entry->size != 0x2000) && + (!(hdw->hdw_desc->flag_fx2_16kb && (fw_entry->size == 0x4000)))) { + if (hdw->hdw_desc->flag_fx2_16kb) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "Wrong fx2 firmware size" + " (expected 8192 or 16384, got %u)", + fw_entry->size); + } else { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "Wrong fx2 firmware size" + " (expected 8192, got %u)", + fw_entry->size); + } release_firmware(fw_entry); return -ENOMEM; } -- cgit v1.2.3-70-g09d2 From 568efaa2f704f72eef9b70ac0f895e9b961f15a6 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Wed, 25 Nov 2009 02:52:06 -0300 Subject: V4L/DVB (13496): pvrusb2: Support manual extraction of 16KB FX2 firmware This pvrusb2 change is in support of an existing feature used to help identify and locate newer vendor supplied firmware. This change makes the feature work for the newer larger firmware size. Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-debugifc.c | 14 +++++++++----- drivers/media/video/pvrusb2/pvrusb2-hdw.c | 9 +++++---- drivers/media/video/pvrusb2/pvrusb2-hdw.h | 2 +- 3 files changed, 15 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c index 010018bc838..ae977668c49 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c +++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c @@ -252,11 +252,15 @@ static int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf, scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); if (scnt && wptr) { count -= scnt; buf += scnt; - if (debugifc_match_keyword(wptr,wlen,"prom")) { - pvr2_hdw_cpufw_set_enabled(hdw,!0,!0); - } else if (debugifc_match_keyword(wptr,wlen, - "ram")) { - pvr2_hdw_cpufw_set_enabled(hdw,0,!0); + if (debugifc_match_keyword(wptr, wlen, + "prom")) { + pvr2_hdw_cpufw_set_enabled(hdw, 2, !0); + } else if (debugifc_match_keyword(wptr, wlen, + "ram8k")) { + pvr2_hdw_cpufw_set_enabled(hdw, 0, !0); + } else if (debugifc_match_keyword(wptr, wlen, + "ram16k")) { + pvr2_hdw_cpufw_set_enabled(hdw, 1, !0); } else { return -EINVAL; } diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 9be04772c72..bd05ec7b1cb 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -3514,7 +3514,7 @@ static u8 *pvr2_full_eeprom_fetch(struct pvr2_hdw *hdw) void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, - int prom_flag, + int mode, int enable_flag) { int ret; @@ -3537,11 +3537,12 @@ void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, break; } - hdw->fw_cpu_flag = (prom_flag == 0); + hdw->fw_cpu_flag = (mode != 2); if (hdw->fw_cpu_flag) { + hdw->fw_size = (mode == 1) ? 0x4000 : 0x2000; pvr2_trace(PVR2_TRACE_FIRMWARE, - "Preparing to suck out CPU firmware"); - hdw->fw_size = 0x2000; + "Preparing to suck out CPU firmware" + " (size=%u)", hdw->fw_size); hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL); if (!hdw->fw_buffer) { hdw->fw_size = 0; diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h index 7b6940554e9..56e70eae20c 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h @@ -219,7 +219,7 @@ int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,struct v4l2_standard *std, this may prevent the device from running (and leaving this mode may imply a device reset). */ void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *, - int prom_flag, + int mode, /* 0=8KB FX2, 1=16KB FX2, 2=PROM */ int enable_flag); /* Return true if we're in a mode for retrieval CPU firmware */ -- cgit v1.2.3-70-g09d2 From 1d70c7fdbb78b0cd40b850a14225aed454c0a062 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Wed, 25 Nov 2009 02:55:38 -0300 Subject: V4L/DVB (13497): pvrusb2: Shorten device hardware description text to work around V4L shortcoming The device text description in pvrusb2-devattr.c get mapped into a V4L API string field that is unfortunately shorter than I expected. No sense fighting City Hall here - this change shortens the descriptions to fit the limit. Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-devattr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c index ef4ff411b39..bd3b7932f23 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c @@ -58,7 +58,7 @@ static const char *pvr2_fw1_names_29xxx[] = { }; static const struct pvr2_device_desc pvr2_device_29xxx = { - .description = "WinTV PVR USB2 Model Category 29xxx", + .description = "WinTV PVR USB2 Model 29xxx", .shortname = "29xxx", .client_table.lst = pvr2_cli_29xxx, .client_table.cnt = ARRAY_SIZE(pvr2_cli_29xxx), @@ -91,7 +91,7 @@ static const char *pvr2_fw1_names_24xxx[] = { }; static const struct pvr2_device_desc pvr2_device_24xxx = { - .description = "WinTV PVR USB2 Model Category 24xxx", + .description = "WinTV PVR USB2 Model 24xxx", .shortname = "24xxx", .client_table.lst = pvr2_cli_24xxx, .client_table.cnt = ARRAY_SIZE(pvr2_cli_24xxx), @@ -340,7 +340,7 @@ static const char *pvr2_fw1_names_73xxx[] = { }; static const struct pvr2_device_desc pvr2_device_73xxx = { - .description = "WinTV HVR-1900 Model Category 73xxx", + .description = "WinTV HVR-1900 Model 73xxx", .shortname = "73xxx", .client_table.lst = pvr2_cli_73xxx, .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx), @@ -445,7 +445,7 @@ static const char *pvr2_fw1_names_75xxx[] = { }; static const struct pvr2_device_desc pvr2_device_750xx = { - .description = "WinTV HVR-1950 Model Category 750xx", + .description = "WinTV HVR-1950 Model 750xx", .shortname = "750xx", .client_table.lst = pvr2_cli_73xxx, .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx), @@ -468,7 +468,7 @@ static const struct pvr2_device_desc pvr2_device_750xx = { }; static const struct pvr2_device_desc pvr2_device_751xx = { - .description = "WinTV HVR-1950 Model Category 751xx", + .description = "WinTV HVR-1950 Model 751xx", .shortname = "751xx", .client_table.lst = pvr2_cli_73xxx, .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx), -- cgit v1.2.3-70-g09d2 From 4b1c83cc51381c3d523452353204247398f5116c Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Wed, 25 Nov 2009 02:57:21 -0300 Subject: V4L/DVB (13498): pvrusb2: Bind I2C address 0x71 for Zilog IR devices Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index a334b1a966a..7cbe18c4ca9 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c @@ -50,6 +50,7 @@ MODULE_PARM_DESC(disable_autoload_ir_video, /* Mapping of IR schemes to known I2C addresses - if any */ static const unsigned char ir_video_addresses[] = { + [PVR2_IR_SCHEME_ZILOG] = 0x71, [PVR2_IR_SCHEME_29XXX] = 0x18, [PVR2_IR_SCHEME_24XXX] = 0x18, }; -- cgit v1.2.3-70-g09d2 From 9081d9018581e01eec9085a80c86bc07e7168f18 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Wed, 25 Nov 2009 02:59:34 -0300 Subject: V4L/DVB (13499): pvrusb2: Cosmetic tweak to minimize size_t exposure Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-hdw.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index bd05ec7b1cb..e93f3e2c25e 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -1447,6 +1447,7 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw) const struct firmware *fw_entry = NULL; void *fw_ptr; unsigned int pipe; + unsigned int fwsize; int ret; u16 address; @@ -1473,19 +1474,20 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw) usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f)); pipe = usb_sndctrlpipe(hdw->usb_dev, 0); + fwsize = fw_entry->size; - if ((fw_entry->size != 0x2000) && - (!(hdw->hdw_desc->flag_fx2_16kb && (fw_entry->size == 0x4000)))) { + if ((fwsize != 0x2000) && + (!(hdw->hdw_desc->flag_fx2_16kb && (fwsize == 0x4000)))) { if (hdw->hdw_desc->flag_fx2_16kb) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Wrong fx2 firmware size" " (expected 8192 or 16384, got %u)", - fw_entry->size); + fwsize); } else { pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Wrong fx2 firmware size" " (expected 8192, got %u)", - fw_entry->size); + fwsize); } release_firmware(fw_entry); return -ENOMEM; @@ -1504,7 +1506,7 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw) chunk. */ ret = 0; - for(address = 0; address < fw_entry->size; address += 0x800) { + for (address = 0; address < fwsize; address += 0x800) { memcpy(fw_ptr, fw_entry->data + address, 0x800); ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address, 0, fw_ptr, 0x800, HZ); -- cgit v1.2.3-70-g09d2 From 75727460a6dfa4c7fd8472a99269982ec4662e64 Mon Sep 17 00:00:00 2001 From: Gary Francis Date: Wed, 25 Nov 2009 03:03:31 -0300 Subject: V4L/DVB (13500): pvrusb2: Fix lingering 16KB FX2 Firmware issues These are additional fixes to enable proper pvrusb2 support of 16KB sized FX2 firmware. Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-devattr.c | 1 + drivers/media/video/pvrusb2/pvrusb2-hdw.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c index bd3b7932f23..6bc16c13cce 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c @@ -351,6 +351,7 @@ static const struct pvr2_device_desc pvr2_device_73xxx = { .flag_has_analogtuner = !0, .flag_has_composite = !0, .flag_has_svideo = !0, + .flag_fx2_16kb = !0, .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index e93f3e2c25e..1bbdab08fe0 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -1522,8 +1522,8 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw) trace_firmware("Upload done (%d bytes sent)",ret); - /* We should have written 8192 bytes */ - if (ret == 8192) { + /* We should have written fwsize bytes */ + if (ret == fwsize) { hdw->fw1_state = FW1_STATE_RELOAD; return 0; } -- cgit v1.2.3-70-g09d2 From bce039c099e97b07534518b5f3c0ce31b1606ff6 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 25 Nov 2009 11:15:56 -0300 Subject: V4L/DVB (13502): uvcvideo: Add support for Genius eFace 2025 webcams The Genius eFace 2025 (0458:706e) requires the MINMAX quirk. Add a corresponding entry in the device IDs list. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_driver.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 782faf6970b..b8b33a05cab 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -1912,6 +1912,15 @@ static int uvc_reset_resume(struct usb_interface *intf) * though they are compliant. */ static struct usb_device_id uvc_ids[] = { + /* Genius eFace 2025 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x0458, + .idProduct = 0x706e, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_PROBE_MINMAX }, /* Microsoft Lifecam NX-6000 */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, -- cgit v1.2.3-70-g09d2 From 6241d8ca1dc27356180011dff4d93a3c5b3cbd76 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 25 Nov 2009 12:00:22 -0300 Subject: V4L/DVB (13503): uvcvideo: Merge iterms, oterms and units linked lists All terminals and units are now added to a single linked list of entities per chain. This makes terminals and units handling code more generic. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_ctrl.c | 29 ++++------------------ drivers/media/video/uvc/uvc_driver.c | 48 +++++++++++++++++------------------- drivers/media/video/uvc/uvc_v4l2.c | 10 +++++--- drivers/media/video/uvc/uvcvideo.h | 5 ++-- 4 files changed, 36 insertions(+), 56 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index 6f1487fc3d7..0469d7a876a 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c @@ -742,17 +742,7 @@ struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, v4l2_id &= V4L2_CTRL_ID_MASK; /* Find the control. */ - __uvc_find_control(chain->processing, v4l2_id, mapping, &ctrl, next); - if (ctrl && !next) - return ctrl; - - list_for_each_entry(entity, &chain->iterms, chain) { - __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next); - if (ctrl && !next) - return ctrl; - } - - list_for_each_entry(entity, &chain->extensions, chain) { + list_for_each_entry(entity, &chain->entities, chain) { __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next); if (ctrl && !next) return ctrl; @@ -951,17 +941,7 @@ int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback) int ret = 0; /* Find the control. */ - ret = uvc_ctrl_commit_entity(chain->dev, chain->processing, rollback); - if (ret < 0) - goto done; - - list_for_each_entry(entity, &chain->iterms, chain) { - ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback); - if (ret < 0) - goto done; - } - - list_for_each_entry(entity, &chain->extensions, chain) { + list_for_each_entry(entity, &chain->entities, chain) { ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback); if (ret < 0) goto done; @@ -1075,8 +1055,9 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain, int ret; /* Find the extension unit. */ - list_for_each_entry(entity, &chain->extensions, chain) { - if (entity->id == xctrl->unit) + list_for_each_entry(entity, &chain->entities, chain) { + if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT && + entity->id == xctrl->unit) break; } diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index b8b33a05cab..db28311d6ec 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -1224,7 +1224,6 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain, return -1; } - list_add_tail(&entity->chain, &chain->extensions); break; case UVC_VC_PROCESSING_UNIT: @@ -1263,7 +1262,6 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain, if (uvc_trace_param & UVC_TRACE_PROBE) printk(" <- IT %d\n", entity->id); - list_add_tail(&entity->chain, &chain->iterms); break; case UVC_TT_STREAMING: @@ -1276,7 +1274,6 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain, return -1; } - list_add_tail(&entity->chain, &chain->iterms); break; default: @@ -1285,6 +1282,7 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain, return -1; } + list_add_tail(&entity->chain, &chain->entities); return 0; } @@ -1315,7 +1313,7 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain, return -EINVAL; } - list_add_tail(&forward->chain, &chain->extensions); + list_add_tail(&forward->chain, &chain->entities); if (uvc_trace_param & UVC_TRACE_PROBE) { if (!found) printk(" (->"); @@ -1335,7 +1333,7 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain, return -EINVAL; } - list_add_tail(&forward->chain, &chain->oterms); + list_add_tail(&forward->chain, &chain->entities); if (uvc_trace_param & UVC_TRACE_PROBE) { if (!found) printk(" (->"); @@ -1391,7 +1389,7 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain, if (uvc_trace_param & UVC_TRACE_PROBE) printk(" %d", term->id); - list_add_tail(&term->chain, &chain->iterms); + list_add_tail(&term->chain, &chain->entities); uvc_scan_chain_forward(chain, term, entity); } @@ -1412,7 +1410,7 @@ static int uvc_scan_chain(struct uvc_video_chain *chain, int id; entity = oterm; - list_add_tail(&entity->chain, &chain->oterms); + list_add_tail(&entity->chain, &chain->entities); uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id); id = entity->output.bSourceID; @@ -1452,21 +1450,25 @@ static int uvc_scan_chain(struct uvc_video_chain *chain, return 0; } -static unsigned int uvc_print_terms(struct list_head *terms, char *buffer) +static unsigned int uvc_print_terms(struct list_head *terms, u16 dir, + char *buffer) { struct uvc_entity *term; unsigned int nterms = 0; char *p = buffer; list_for_each_entry(term, terms, chain) { - p += sprintf(p, "%u", term->id); - if (term->chain.next != terms) { + if (!UVC_ENTITY_IS_TERM(term) || + UVC_TERM_DIRECTION(term) != dir) + continue; + + if (nterms) p += sprintf(p, ","); - if (++nterms >= 4) { - p += sprintf(p, "..."); - break; - } + if (++nterms >= 4) { + p += sprintf(p, "..."); + break; } + p += sprintf(p, "%u", term->id); } return p - buffer; @@ -1477,9 +1479,9 @@ static const char *uvc_print_chain(struct uvc_video_chain *chain) static char buffer[43]; char *p = buffer; - p += uvc_print_terms(&chain->iterms, p); + p += uvc_print_terms(&chain->entities, UVC_TERM_INPUT, p); p += sprintf(p, " -> "); - uvc_print_terms(&chain->oterms, p); + uvc_print_terms(&chain->entities, UVC_TERM_OUTPUT, p); return buffer; } @@ -1510,9 +1512,7 @@ static int uvc_scan_device(struct uvc_device *dev) if (chain == NULL) return -ENOMEM; - INIT_LIST_HEAD(&chain->iterms); - INIT_LIST_HEAD(&chain->oterms); - INIT_LIST_HEAD(&chain->extensions); + INIT_LIST_HEAD(&chain->entities); mutex_init(&chain->ctrl_mutex); chain->dev = dev; @@ -1685,13 +1685,13 @@ static int uvc_register_video(struct uvc_device *dev, * Register all video devices in all chains. */ static int uvc_register_terms(struct uvc_device *dev, - struct uvc_video_chain *chain, struct list_head *terms) + struct uvc_video_chain *chain) { struct uvc_streaming *stream; struct uvc_entity *term; int ret; - list_for_each_entry(term, terms, chain) { + list_for_each_entry(term, &chain->entities, chain) { if (UVC_ENTITY_TYPE(term) != UVC_TT_STREAMING) continue; @@ -1717,11 +1717,7 @@ static int uvc_register_chains(struct uvc_device *dev) int ret; list_for_each_entry(chain, &dev->chains, list) { - ret = uvc_register_terms(dev, chain, &chain->iterms); - if (ret < 0) - return ret; - - ret = uvc_register_terms(dev, chain, &chain->oterms); + ret = uvc_register_terms(dev, chain); if (ret < 0) return ret; } diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index be3da56d4db..9e1f2c208ed 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c @@ -620,12 +620,16 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { if (index != 0) return -EINVAL; - iterm = list_first_entry(&chain->iterms, - struct uvc_entity, chain); + list_for_each_entry(iterm, &chain->entities, chain) { + if (UVC_ENTITY_IS_ITERM(iterm)) + break; + } pin = iterm->id; } else if (pin < selector->selector.bNrInPins) { pin = selector->selector.baSourceID[index]; - list_for_each_entry(iterm, chain->iterms.next, chain) { + list_for_each_entry(iterm, &chain->entities, chain) { + if (!UVC_ENTITY_IS_ITERM(iterm)) + continue; if (iterm->id == pin) break; } diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index fb3342ae6d7..9e6948fb3e6 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -75,6 +75,7 @@ struct uvc_xu_control { #define UVC_TERM_INPUT 0x0000 #define UVC_TERM_OUTPUT 0x8000 +#define UVC_TERM_DIRECTION(term) ((term)->type & 0x8000) #define UVC_ENTITY_TYPE(entity) ((entity)->type & 0x7fff) #define UVC_ENTITY_IS_UNIT(entity) (((entity)->type & 0xff00) == 0) @@ -408,11 +409,9 @@ struct uvc_video_chain { struct uvc_device *dev; struct list_head list; - struct list_head iterms; /* Input terminals */ - struct list_head oterms; /* Output terminals */ + struct list_head entities; /* All entities */ struct uvc_entity *processing; /* Processing unit */ struct uvc_entity *selector; /* Selector unit */ - struct list_head extensions; /* Extension units */ struct mutex ctrl_mutex; }; -- cgit v1.2.3-70-g09d2 From fd3e921739aff709bbaae6d75d9f64542f47c850 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 25 Nov 2009 12:00:27 -0300 Subject: V4L/DVB (13504): uvcvideo: Fix extension units parsing The bNrInPins field is an 8 bit integer, not a 16 bit integer. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_driver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index db28311d6ec..8d51a6a130b 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -844,7 +844,7 @@ static int uvc_parse_vendor_control(struct uvc_device *dev, unit->type = UVC_VC_EXTENSION_UNIT; memcpy(unit->extension.guidExtensionCode, &buffer[4], 16); unit->extension.bNumControls = buffer[20]; - unit->extension.bNrInPins = get_unaligned_le16(&buffer[21]); + unit->extension.bNrInPins = buffer[21]; unit->extension.baSourceID = (__u8 *)unit + sizeof *unit; memcpy(unit->extension.baSourceID, &buffer[22], p); unit->extension.bControlSize = buffer[22+p]; @@ -1108,7 +1108,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev, unit->type = buffer[2]; memcpy(unit->extension.guidExtensionCode, &buffer[4], 16); unit->extension.bNumControls = buffer[20]; - unit->extension.bNrInPins = get_unaligned_le16(&buffer[21]); + unit->extension.bNrInPins = buffer[21]; unit->extension.baSourceID = (__u8 *)unit + sizeof *unit; memcpy(unit->extension.baSourceID, &buffer[22], p); unit->extension.bControlSize = buffer[22+p]; -- cgit v1.2.3-70-g09d2 From 4057ac6ca9a77c4275b34b5925ab5c99557913b1 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 25 Nov 2009 12:00:29 -0300 Subject: V4L/DVB (13505): uvcvideo: Refactor chain scan Don't handle the first output terminal in a chain in a special way. Use uvc_scan_chain_entity() like for all other entities, making the chain scan code more generic. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_driver.c | 75 +++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 32 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 8d51a6a130b..e7ce898ad70 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -1265,13 +1265,12 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain, break; case UVC_TT_STREAMING: - if (uvc_trace_param & UVC_TRACE_PROBE) - printk(" <- IT %d\n", entity->id); - - if (!UVC_ENTITY_IS_ITERM(entity)) { - uvc_trace(UVC_TRACE_DESCR, "Unsupported input " - "terminal %u.\n", entity->id); - return -1; + if (UVC_ENTITY_IS_ITERM(entity)) { + if (uvc_trace_param & UVC_TRACE_PROBE) + printk(" <- IT %d\n", entity->id); + } else { + if (uvc_trace_param & UVC_TRACE_PROBE) + printk(" OT %d", entity->id); } break; @@ -1351,10 +1350,11 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain, } static int uvc_scan_chain_backward(struct uvc_video_chain *chain, - struct uvc_entity *entity) + struct uvc_entity **_entity) { + struct uvc_entity *entity = *_entity; struct uvc_entity *term; - int id = -1, i; + int id = -EINVAL, i; switch (UVC_ENTITY_TYPE(entity)) { case UVC_VC_EXTENSION_UNIT: @@ -1398,34 +1398,49 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain, id = 0; break; + + case UVC_ITT_VENDOR_SPECIFIC: + case UVC_ITT_CAMERA: + case UVC_ITT_MEDIA_TRANSPORT_INPUT: + case UVC_OTT_VENDOR_SPECIFIC: + case UVC_OTT_DISPLAY: + case UVC_OTT_MEDIA_TRANSPORT_OUTPUT: + case UVC_TT_STREAMING: + id = UVC_ENTITY_IS_OTERM(entity) ? entity->output.bSourceID : 0; + break; } - return id; + if (id <= 0) { + *_entity = NULL; + return id; + } + + entity = uvc_entity_by_id(chain->dev, id); + if (entity == NULL) { + uvc_trace(UVC_TRACE_DESCR, "Found reference to " + "unknown entity %d.\n", id); + return -EINVAL; + } + + *_entity = entity; + return 0; } static int uvc_scan_chain(struct uvc_video_chain *chain, - struct uvc_entity *oterm) + struct uvc_entity *term) { struct uvc_entity *entity, *prev; - int id; - entity = oterm; - list_add_tail(&entity->chain, &chain->entities); - uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id); + uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain:"); - id = entity->output.bSourceID; - while (id != 0) { - prev = entity; - entity = uvc_entity_by_id(chain->dev, id); - if (entity == NULL) { - uvc_trace(UVC_TRACE_DESCR, "Found reference to " - "unknown entity %d.\n", id); - return -EINVAL; - } + entity = term; + prev = NULL; + while (entity != NULL) { + /* Entity must not be part of an existing chain */ if (entity->chain.next || entity->chain.prev) { uvc_trace(UVC_TRACE_DESCR, "Found reference to " - "entity %d already in chain.\n", id); + "entity %d already in chain.\n", entity->id); return -EINVAL; } @@ -1437,14 +1452,10 @@ static int uvc_scan_chain(struct uvc_video_chain *chain, if (uvc_scan_chain_forward(chain, entity, prev) < 0) return -EINVAL; - /* Stop when a terminal is found. */ - if (UVC_ENTITY_IS_TERM(entity)) - break; - /* Backward scan */ - id = uvc_scan_chain_backward(chain, entity); - if (id < 0) - return id; + prev = entity; + if (uvc_scan_chain_backward(chain, &entity) < 0) + return -EINVAL; } return 0; -- cgit v1.2.3-70-g09d2 From 8ca5a639f4f3eb8958a7e270fcff7516374637a5 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 25 Nov 2009 12:00:30 -0300 Subject: V4L/DVB (13506): uvcvideo: Factorize common field in uvc_entity structure The bNrInPins and baSourceID fields are common among all entities (some of use bSourceID but this is conceptually the same). Move those two fields out of entity type-specific unions into the uvc_entity structure top level. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_driver.c | 119 +++++++++++++++-------------------- drivers/media/video/uvc/uvc_v4l2.c | 6 +- drivers/media/video/uvc/uvcvideo.h | 9 +-- 3 files changed, 57 insertions(+), 77 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index e7ce898ad70..c31bc50113b 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -249,29 +249,9 @@ static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev, entity = list_entry(&dev->entities, struct uvc_entity, list); list_for_each_entry_continue(entity, &dev->entities, list) { - switch (UVC_ENTITY_TYPE(entity)) { - case UVC_TT_STREAMING: - if (entity->output.bSourceID == id) - return entity; - break; - - case UVC_VC_PROCESSING_UNIT: - if (entity->processing.bSourceID == id) + for (i = 0; i < entity->bNrInPins; ++i) + if (entity->baSourceID[i] == id) return entity; - break; - - case UVC_VC_SELECTOR_UNIT: - for (i = 0; i < entity->selector.bNrInPins; ++i) - if (entity->selector.baSourceID[i] == id) - return entity; - break; - - case UVC_VC_EXTENSION_UNIT: - for (i = 0; i < entity->extension.bNrInPins; ++i) - if (entity->extension.baSourceID[i] == id) - return entity; - break; - } } return NULL; @@ -785,6 +765,28 @@ error: return ret; } +static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id, + unsigned int num_pads, unsigned int extra_size) +{ + struct uvc_entity *entity; + unsigned int num_inputs; + unsigned int size; + + num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1; + size = sizeof(*entity) + extra_size + num_inputs; + entity = kzalloc(size, GFP_KERNEL); + if (entity == NULL) + return NULL; + + entity->id = id; + entity->type = type; + + entity->bNrInPins = num_inputs; + entity->baSourceID = ((__u8 *)entity) + sizeof(*entity) + extra_size; + + return entity; +} + /* Parse vendor-specific extensions. */ static int uvc_parse_vendor_control(struct uvc_device *dev, const unsigned char *buffer, int buflen) @@ -836,21 +838,18 @@ static int uvc_parse_vendor_control(struct uvc_device *dev, break; } - unit = kzalloc(sizeof *unit + p + 2*n, GFP_KERNEL); + unit = uvc_alloc_entity(UVC_VC_EXTENSION_UNIT, buffer[3], + p + 1, 2*n); if (unit == NULL) return -ENOMEM; - unit->id = buffer[3]; - unit->type = UVC_VC_EXTENSION_UNIT; memcpy(unit->extension.guidExtensionCode, &buffer[4], 16); unit->extension.bNumControls = buffer[20]; - unit->extension.bNrInPins = buffer[21]; - unit->extension.baSourceID = (__u8 *)unit + sizeof *unit; - memcpy(unit->extension.baSourceID, &buffer[22], p); + memcpy(unit->baSourceID, &buffer[22], p); unit->extension.bControlSize = buffer[22+p]; - unit->extension.bmControls = (__u8 *)unit + sizeof *unit + p; - unit->extension.bmControlsType = (__u8 *)unit + sizeof *unit - + p + n; + unit->extension.bmControls = (__u8 *)unit + sizeof(*unit); + unit->extension.bmControlsType = (__u8 *)unit + sizeof(*unit) + + n; memcpy(unit->extension.bmControls, &buffer[23+p], 2*n); if (buffer[24+p+2*n] != 0) @@ -947,13 +946,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev, return -EINVAL; } - term = kzalloc(sizeof *term + n + p, GFP_KERNEL); + term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3], + 1, n + p); if (term == NULL) return -ENOMEM; - term->id = buffer[3]; - term->type = type | UVC_TERM_INPUT; - if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) { term->camera.bControlSize = n; term->camera.bmControls = (__u8 *)term + sizeof *term; @@ -1008,13 +1005,12 @@ static int uvc_parse_standard_control(struct uvc_device *dev, return 0; } - term = kzalloc(sizeof *term, GFP_KERNEL); + term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3], + 1, 0); if (term == NULL) return -ENOMEM; - term->id = buffer[3]; - term->type = type | UVC_TERM_OUTPUT; - term->output.bSourceID = buffer[7]; + memcpy(term->baSourceID, &buffer[7], 1); if (buffer[8] != 0) usb_string(udev, buffer[8], term->name, @@ -1035,15 +1031,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev, return -EINVAL; } - unit = kzalloc(sizeof *unit + p, GFP_KERNEL); + unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0); if (unit == NULL) return -ENOMEM; - unit->id = buffer[3]; - unit->type = buffer[2]; - unit->selector.bNrInPins = buffer[4]; - unit->selector.baSourceID = (__u8 *)unit + sizeof *unit; - memcpy(unit->selector.baSourceID, &buffer[5], p); + memcpy(unit->baSourceID, &buffer[5], p); if (buffer[5+p] != 0) usb_string(udev, buffer[5+p], unit->name, @@ -1065,13 +1057,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev, return -EINVAL; } - unit = kzalloc(sizeof *unit + n, GFP_KERNEL); + unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n); if (unit == NULL) return -ENOMEM; - unit->id = buffer[3]; - unit->type = buffer[2]; - unit->processing.bSourceID = buffer[4]; + memcpy(unit->baSourceID, &buffer[4], 1); unit->processing.wMaxMultiplier = get_unaligned_le16(&buffer[5]); unit->processing.bControlSize = buffer[7]; @@ -1100,19 +1090,15 @@ static int uvc_parse_standard_control(struct uvc_device *dev, return -EINVAL; } - unit = kzalloc(sizeof *unit + p + n, GFP_KERNEL); + unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n); if (unit == NULL) return -ENOMEM; - unit->id = buffer[3]; - unit->type = buffer[2]; memcpy(unit->extension.guidExtensionCode, &buffer[4], 16); unit->extension.bNumControls = buffer[20]; - unit->extension.bNrInPins = buffer[21]; - unit->extension.baSourceID = (__u8 *)unit + sizeof *unit; - memcpy(unit->extension.baSourceID, &buffer[22], p); + memcpy(unit->baSourceID, &buffer[22], p); unit->extension.bControlSize = buffer[22+p]; - unit->extension.bmControls = (__u8 *)unit + sizeof *unit + p; + unit->extension.bmControls = (__u8 *)unit + sizeof *unit; memcpy(unit->extension.bmControls, &buffer[23+p], n); if (buffer[23+p+n] != 0) @@ -1218,7 +1204,7 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain, if (uvc_trace_param & UVC_TRACE_PROBE) printk(" <- XU %d", entity->id); - if (entity->extension.bNrInPins != 1) { + if (entity->bNrInPins != 1) { uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has more " "than 1 input pin.\n", entity->id); return -1; @@ -1244,7 +1230,7 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain, printk(" <- SU %d", entity->id); /* Single-input selector units are ignored. */ - if (entity->selector.bNrInPins == 1) + if (entity->bNrInPins == 1) break; if (chain->selector != NULL) { @@ -1305,7 +1291,7 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain, switch (UVC_ENTITY_TYPE(forward)) { case UVC_VC_EXTENSION_UNIT: - if (forward->extension.bNrInPins != 1) { + if (forward->bNrInPins != 1) { uvc_trace(UVC_TRACE_DESCR, "Extension unit %d " "has more than 1 input pin.\n", entity->id); @@ -1358,17 +1344,14 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain, switch (UVC_ENTITY_TYPE(entity)) { case UVC_VC_EXTENSION_UNIT: - id = entity->extension.baSourceID[0]; - break; - case UVC_VC_PROCESSING_UNIT: - id = entity->processing.bSourceID; + id = entity->baSourceID[0]; break; case UVC_VC_SELECTOR_UNIT: /* Single-input selector units are ignored. */ - if (entity->selector.bNrInPins == 1) { - id = entity->selector.baSourceID[0]; + if (entity->bNrInPins == 1) { + id = entity->baSourceID[0]; break; } @@ -1376,8 +1359,8 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain, printk(" <- IT"); chain->selector = entity; - for (i = 0; i < entity->selector.bNrInPins; ++i) { - id = entity->selector.baSourceID[i]; + for (i = 0; i < entity->bNrInPins; ++i) { + id = entity->baSourceID[i]; term = uvc_entity_by_id(chain->dev, id); if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) { uvc_trace(UVC_TRACE_DESCR, "Selector unit %d " @@ -1406,7 +1389,7 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain, case UVC_OTT_DISPLAY: case UVC_OTT_MEDIA_TRANSPORT_OUTPUT: case UVC_TT_STREAMING: - id = UVC_ENTITY_IS_OTERM(entity) ? entity->output.bSourceID : 0; + id = UVC_ENTITY_IS_OTERM(entity) ? entity->baSourceID[0] : 0; break; } diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 9e1f2c208ed..23239a4adef 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c @@ -625,8 +625,8 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) break; } pin = iterm->id; - } else if (pin < selector->selector.bNrInPins) { - pin = selector->selector.baSourceID[index]; + } else if (pin < selector->bNrInPins) { + pin = selector->baSourceID[index]; list_for_each_entry(iterm, &chain->entities, chain) { if (!UVC_ENTITY_IS_ITERM(iterm)) continue; @@ -680,7 +680,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) break; } - if (input == 0 || input > chain->selector->selector.bNrInPins) + if (input == 0 || input > chain->selector->bNrInPins) return -EINVAL; return uvc_query_ctrl(chain->dev, UVC_SET_CUR, diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index 9e6948fb3e6..7ec9a04ced5 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -293,11 +293,9 @@ struct uvc_entity { } media; struct { - __u8 bSourceID; } output; struct { - __u8 bSourceID; __u16 wMaxMultiplier; __u8 bControlSize; __u8 *bmControls; @@ -305,21 +303,20 @@ struct uvc_entity { } processing; struct { - __u8 bNrInPins; - __u8 *baSourceID; } selector; struct { __u8 guidExtensionCode[16]; __u8 bNumControls; - __u8 bNrInPins; - __u8 *baSourceID; __u8 bControlSize; __u8 *bmControls; __u8 *bmControlsType; } extension; }; + __u8 bNrInPins; + __u8 *baSourceID; + unsigned int ncontrols; struct uvc_control *controls; }; -- cgit v1.2.3-70-g09d2 From 1ce7981be36e05216df64ffeceb8230d9b569b87 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 25 Nov 2009 12:37:00 -0300 Subject: V4L/DVB (13508): pms: source code cleanup, use struct v4l2_device. This prepares the pms driver for the v4l1 -> v4l2 conversion. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pms.c | 1297 ++++++++++++++++++++++----------------------- 1 file changed, 636 insertions(+), 661 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index a1ad38fc49c..2919aa42c94 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c @@ -31,171 +31,175 @@ #include #include #include +#include #include #include +MODULE_LICENSE("GPL"); + #define MOTOROLA 1 #define PHILIPS2 2 #define PHILIPS1 3 #define MVVMEMORYWIDTH 0x40 /* 512 bytes */ -struct pms_device -{ - struct video_device v; - struct video_picture picture; - int height; - int width; - unsigned long in_use; - struct mutex lock; -}; - -struct i2c_info -{ +struct i2c_info { u8 slave; u8 sub; u8 data; u8 hits; }; -static int i2c_count; -static struct i2c_info i2cinfo[64]; +struct pms { + struct v4l2_device v4l2_dev; + struct video_device vdev; + struct video_picture picture; + int height; + int width; + unsigned long in_use; + struct mutex lock; + int i2c_count; + struct i2c_info i2cinfo[64]; + + int decoder; + int standard; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */ + int io; + int data; + void __iomem *mem; +}; -static int decoder = PHILIPS2; -static int standard; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */ +static struct pms pms_card; /* * I/O ports and Shared Memory */ -static int io_port = 0x250; -static int data_port = 0x251; -static int mem_base = 0xC8000; -static void __iomem *mem; -static int video_nr = -1; +static int io_port = 0x250; +module_param(io_port, int, 0); + +static int mem_base = 0xc8000; +module_param(mem_base, int, 0); +static int video_nr = -1; +module_param(video_nr, int, 0); -static inline void mvv_write(u8 index, u8 value) +static inline void mvv_write(struct pms *dev, u8 index, u8 value) { - outw(index|(value<<8), io_port); + outw(index | (value << 8), dev->io); } -static inline u8 mvv_read(u8 index) +static inline u8 mvv_read(struct pms *dev, u8 index) { - outb(index, io_port); - return inb(data_port); + outb(index, dev->io); + return inb(dev->data); } -static int pms_i2c_stat(u8 slave) +static int pms_i2c_stat(struct pms *dev, u8 slave) { - int counter; + int counter = 0; int i; - outb(0x28, io_port); + outb(0x28, dev->io); - counter=0; - while((inb(data_port)&0x01)==0) - if(counter++==256) + while ((inb(dev->data) & 0x01) == 0) + if (counter++ == 256) break; - while((inb(data_port)&0x01)!=0) - if(counter++==256) + while ((inb(dev->data) & 0x01) != 0) + if (counter++ == 256) break; - outb(slave, io_port); + outb(slave, dev->io); - counter=0; - while((inb(data_port)&0x01)==0) - if(counter++==256) + counter = 0; + while ((inb(dev->data) & 0x01) == 0) + if (counter++ == 256) break; - while((inb(data_port)&0x01)!=0) - if(counter++==256) + while ((inb(dev->data) & 0x01) != 0) + if (counter++ == 256) break; - for(i=0;i<12;i++) - { - char st=inb(data_port); - if((st&2)!=0) + for (i = 0; i < 12; i++) { + char st = inb(dev->data); + + if ((st & 2) != 0) return -1; - if((st&1)==0) + if ((st & 1) == 0) break; } - outb(0x29, io_port); - return inb(data_port); + outb(0x29, dev->io); + return inb(dev->data); } -static int pms_i2c_write(u16 slave, u16 sub, u16 data) +static int pms_i2c_write(struct pms *dev, u16 slave, u16 sub, u16 data) { - int skip=0; + int skip = 0; int count; int i; - for(i=0;ii2c_count; i++) { + if ((dev->i2cinfo[i].slave == slave) && + (dev->i2cinfo[i].sub == sub)) { + if (dev->i2cinfo[i].data == data) + skip = 1; + dev->i2cinfo[i].data = data; + i = dev->i2c_count + 1; } } - if(i==i2c_count && i2c_count<64) - { - i2cinfo[i2c_count].slave=slave; - i2cinfo[i2c_count].sub=sub; - i2cinfo[i2c_count].data=data; - i2c_count++; + if (i == dev->i2c_count && dev->i2c_count < 64) { + dev->i2cinfo[dev->i2c_count].slave = slave; + dev->i2cinfo[dev->i2c_count].sub = sub; + dev->i2cinfo[dev->i2c_count].data = data; + dev->i2c_count++; } - if(skip) + if (skip) return 0; - mvv_write(0x29, sub); - mvv_write(0x2A, data); - mvv_write(0x28, slave); + mvv_write(dev, 0x29, sub); + mvv_write(dev, 0x2A, data); + mvv_write(dev, 0x28, slave); - outb(0x28, io_port); + outb(0x28, dev->io); - count=0; - while((inb(data_port)&1)==0) - if(count>255) + count = 0; + while ((inb(dev->data) & 1) == 0) + if (count > 255) break; - while((inb(data_port)&1)!=0) - if(count>255) + while ((inb(dev->data) & 1) != 0) + if (count > 255) break; - count=inb(data_port); + count = inb(dev->data); - if(count&2) + if (count & 2) return -1; return count; } -static int pms_i2c_read(int slave, int sub) +static int pms_i2c_read(struct pms *dev, int slave, int sub) { - int i=0; - for(i=0;ii2c_count; i++) { + if (dev->i2cinfo[i].slave == slave && dev->i2cinfo[i].sub == sub) + return dev->i2cinfo[i].data; } return 0; } -static void pms_i2c_andor(int slave, int sub, int and, int or) +static void pms_i2c_andor(struct pms *dev, int slave, int sub, int and, int or) { u8 tmp; - tmp=pms_i2c_read(slave, sub); - tmp = (tmp&and)|or; - pms_i2c_write(slave, sub, tmp); + tmp = pms_i2c_read(dev, slave, sub); + tmp = (tmp & and) | or; + pms_i2c_write(dev, slave, sub, tmp); } /* @@ -203,100 +207,96 @@ static void pms_i2c_andor(int slave, int sub, int and, int or) */ -static void pms_videosource(short source) +static void pms_videosource(struct pms *dev, short source) { - mvv_write(0x2E, source?0x31:0x30); + mvv_write(dev, 0x2E, source ? 0x31 : 0x30); } -static void pms_hue(short hue) +static void pms_hue(struct pms *dev, short hue) { - switch(decoder) - { - case MOTOROLA: - pms_i2c_write(0x8A, 0x00, hue); - break; - case PHILIPS2: - pms_i2c_write(0x8A, 0x07, hue); - break; - case PHILIPS1: - pms_i2c_write(0x42, 0x07, hue); - break; + switch (dev->decoder) { + case MOTOROLA: + pms_i2c_write(dev, 0x8a, 0x00, hue); + break; + case PHILIPS2: + pms_i2c_write(dev, 0x8a, 0x07, hue); + break; + case PHILIPS1: + pms_i2c_write(dev, 0x42, 0x07, hue); + break; } } -static void pms_colour(short colour) +static void pms_colour(struct pms *dev, short colour) { - switch(decoder) - { - case MOTOROLA: - pms_i2c_write(0x8A, 0x00, colour); - break; - case PHILIPS1: - pms_i2c_write(0x42, 0x12, colour); - break; + switch (dev->decoder) { + case MOTOROLA: + pms_i2c_write(dev, 0x8a, 0x00, colour); + break; + case PHILIPS1: + pms_i2c_write(dev, 0x42, 0x12, colour); + break; } } -static void pms_contrast(short contrast) +static void pms_contrast(struct pms *dev, short contrast) { - switch(decoder) - { - case MOTOROLA: - pms_i2c_write(0x8A, 0x00, contrast); - break; - case PHILIPS1: - pms_i2c_write(0x42, 0x13, contrast); - break; + switch (dev->decoder) { + case MOTOROLA: + pms_i2c_write(dev, 0x8a, 0x00, contrast); + break; + case PHILIPS1: + pms_i2c_write(dev, 0x42, 0x13, contrast); + break; } } -static void pms_brightness(short brightness) +static void pms_brightness(struct pms *dev, short brightness) { - switch(decoder) - { - case MOTOROLA: - pms_i2c_write(0x8A, 0x00, brightness); - pms_i2c_write(0x8A, 0x00, brightness); - pms_i2c_write(0x8A, 0x00, brightness); - break; - case PHILIPS1: - pms_i2c_write(0x42, 0x19, brightness); - break; + switch (dev->decoder) { + case MOTOROLA: + pms_i2c_write(dev, 0x8a, 0x00, brightness); + pms_i2c_write(dev, 0x8a, 0x00, brightness); + pms_i2c_write(dev, 0x8a, 0x00, brightness); + break; + case PHILIPS1: + pms_i2c_write(dev, 0x42, 0x19, brightness); + break; } } -static void pms_format(short format) +static void pms_format(struct pms *dev, short format) { int target; - standard = format; - if(decoder==PHILIPS1) - target=0x42; - else if(decoder==PHILIPS2) - target=0x8A; + dev->standard = format; + + if (dev->decoder == PHILIPS1) + target = 0x42; + else if (dev->decoder == PHILIPS2) + target = 0x8a; else return; - switch(format) - { - case 0: /* Auto */ - pms_i2c_andor(target, 0x0D, 0xFE,0x00); - pms_i2c_andor(target, 0x0F, 0x3F,0x80); - break; - case 1: /* NTSC */ - pms_i2c_andor(target, 0x0D, 0xFE, 0x00); - pms_i2c_andor(target, 0x0F, 0x3F, 0x40); - break; - case 2: /* PAL */ - pms_i2c_andor(target, 0x0D, 0xFE, 0x00); - pms_i2c_andor(target, 0x0F, 0x3F, 0x00); - break; - case 3: /* SECAM */ - pms_i2c_andor(target, 0x0D, 0xFE, 0x01); - pms_i2c_andor(target, 0x0F, 0x3F, 0x00); - break; + switch (format) { + case 0: /* Auto */ + pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00); + pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x80); + break; + case 1: /* NTSC */ + pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00); + pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x40); + break; + case 2: /* PAL */ + pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00); + pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x00); + break; + case 3: /* SECAM */ + pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x01); + pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x00); + break; } } @@ -308,18 +308,17 @@ static void pms_format(short format) * people need it. We also don't yet use the PMS interrupt. */ -static void pms_hstart(short start) +static void pms_hstart(struct pms *dev, short start) { - switch(decoder) - { - case PHILIPS1: - pms_i2c_write(0x8A, 0x05, start); - pms_i2c_write(0x8A, 0x18, start); - break; - case PHILIPS2: - pms_i2c_write(0x42, 0x05, start); - pms_i2c_write(0x42, 0x18, start); - break; + switch (dev->decoder) { + case PHILIPS1: + pms_i2c_write(dev, 0x8a, 0x05, start); + pms_i2c_write(dev, 0x8a, 0x18, start); + break; + case PHILIPS2: + pms_i2c_write(dev, 0x42, 0x05, start); + pms_i2c_write(dev, 0x42, 0x18, start); + break; } } @@ -327,293 +326,271 @@ static void pms_hstart(short start) * Bandpass filters */ -static void pms_bandpass(short pass) +static void pms_bandpass(struct pms *dev, short pass) { - if(decoder==PHILIPS2) - pms_i2c_andor(0x8A, 0x06, 0xCF, (pass&0x03)<<4); - else if(decoder==PHILIPS1) - pms_i2c_andor(0x42, 0x06, 0xCF, (pass&0x03)<<4); + if (dev->decoder == PHILIPS2) + pms_i2c_andor(dev, 0x8a, 0x06, 0xcf, (pass & 0x03) << 4); + else if (dev->decoder == PHILIPS1) + pms_i2c_andor(dev, 0x42, 0x06, 0xcf, (pass & 0x03) << 4); } -static void pms_antisnow(short snow) +static void pms_antisnow(struct pms *dev, short snow) { - if(decoder==PHILIPS2) - pms_i2c_andor(0x8A, 0x06, 0xF3, (snow&0x03)<<2); - else if(decoder==PHILIPS1) - pms_i2c_andor(0x42, 0x06, 0xF3, (snow&0x03)<<2); + if (dev->decoder == PHILIPS2) + pms_i2c_andor(dev, 0x8a, 0x06, 0xf3, (snow & 0x03) << 2); + else if (dev->decoder == PHILIPS1) + pms_i2c_andor(dev, 0x42, 0x06, 0xf3, (snow & 0x03) << 2); } -static void pms_sharpness(short sharp) +static void pms_sharpness(struct pms *dev, short sharp) { - if(decoder==PHILIPS2) - pms_i2c_andor(0x8A, 0x06, 0xFC, sharp&0x03); - else if(decoder==PHILIPS1) - pms_i2c_andor(0x42, 0x06, 0xFC, sharp&0x03); + if (dev->decoder == PHILIPS2) + pms_i2c_andor(dev, 0x8a, 0x06, 0xfc, sharp & 0x03); + else if (dev->decoder == PHILIPS1) + pms_i2c_andor(dev, 0x42, 0x06, 0xfc, sharp & 0x03); } -static void pms_chromaagc(short agc) +static void pms_chromaagc(struct pms *dev, short agc) { - if(decoder==PHILIPS2) - pms_i2c_andor(0x8A, 0x0C, 0x9F, (agc&0x03)<<5); - else if(decoder==PHILIPS1) - pms_i2c_andor(0x42, 0x0C, 0x9F, (agc&0x03)<<5); + if (dev->decoder == PHILIPS2) + pms_i2c_andor(dev, 0x8a, 0x0c, 0x9f, (agc & 0x03) << 5); + else if (dev->decoder == PHILIPS1) + pms_i2c_andor(dev, 0x42, 0x0c, 0x9f, (agc & 0x03) << 5); } -static void pms_vertnoise(short noise) +static void pms_vertnoise(struct pms *dev, short noise) { - if(decoder==PHILIPS2) - pms_i2c_andor(0x8A, 0x10, 0xFC, noise&3); - else if(decoder==PHILIPS1) - pms_i2c_andor(0x42, 0x10, 0xFC, noise&3); + if (dev->decoder == PHILIPS2) + pms_i2c_andor(dev, 0x8a, 0x10, 0xfc, noise & 3); + else if (dev->decoder == PHILIPS1) + pms_i2c_andor(dev, 0x42, 0x10, 0xfc, noise & 3); } -static void pms_forcecolour(short colour) +static void pms_forcecolour(struct pms *dev, short colour) { - if(decoder==PHILIPS2) - pms_i2c_andor(0x8A, 0x0C, 0x7F, (colour&1)<<7); - else if(decoder==PHILIPS1) - pms_i2c_andor(0x42, 0x0C, 0x7, (colour&1)<<7); + if (dev->decoder == PHILIPS2) + pms_i2c_andor(dev, 0x8a, 0x0c, 0x7f, (colour & 1) << 7); + else if (dev->decoder == PHILIPS1) + pms_i2c_andor(dev, 0x42, 0x0c, 0x7, (colour & 1) << 7); } -static void pms_antigamma(short gamma) +static void pms_antigamma(struct pms *dev, short gamma) { - if(decoder==PHILIPS2) - pms_i2c_andor(0xB8, 0x00, 0x7F, (gamma&1)<<7); - else if(decoder==PHILIPS1) - pms_i2c_andor(0x42, 0x20, 0x7, (gamma&1)<<7); + if (dev->decoder == PHILIPS2) + pms_i2c_andor(dev, 0xb8, 0x00, 0x7f, (gamma & 1) << 7); + else if (dev->decoder == PHILIPS1) + pms_i2c_andor(dev, 0x42, 0x20, 0x7, (gamma & 1) << 7); } -static void pms_prefilter(short filter) +static void pms_prefilter(struct pms *dev, short filter) { - if(decoder==PHILIPS2) - pms_i2c_andor(0x8A, 0x06, 0xBF, (filter&1)<<6); - else if(decoder==PHILIPS1) - pms_i2c_andor(0x42, 0x06, 0xBF, (filter&1)<<6); + if (dev->decoder == PHILIPS2) + pms_i2c_andor(dev, 0x8a, 0x06, 0xbf, (filter & 1) << 6); + else if (dev->decoder == PHILIPS1) + pms_i2c_andor(dev, 0x42, 0x06, 0xbf, (filter & 1) << 6); } -static void pms_hfilter(short filter) +static void pms_hfilter(struct pms *dev, short filter) { - if(decoder==PHILIPS2) - pms_i2c_andor(0xB8, 0x04, 0x1F, (filter&7)<<5); - else if(decoder==PHILIPS1) - pms_i2c_andor(0x42, 0x24, 0x1F, (filter&7)<<5); + if (dev->decoder == PHILIPS2) + pms_i2c_andor(dev, 0xb8, 0x04, 0x1f, (filter & 7) << 5); + else if (dev->decoder == PHILIPS1) + pms_i2c_andor(dev, 0x42, 0x24, 0x1f, (filter & 7) << 5); } -static void pms_vfilter(short filter) +static void pms_vfilter(struct pms *dev, short filter) { - if(decoder==PHILIPS2) - pms_i2c_andor(0xB8, 0x08, 0x9F, (filter&3)<<5); - else if(decoder==PHILIPS1) - pms_i2c_andor(0x42, 0x28, 0x9F, (filter&3)<<5); + if (dev->decoder == PHILIPS2) + pms_i2c_andor(dev, 0xb8, 0x08, 0x9f, (filter & 3) << 5); + else if (dev->decoder == PHILIPS1) + pms_i2c_andor(dev, 0x42, 0x28, 0x9f, (filter & 3) << 5); } -static void pms_killcolour(short colour) +static void pms_killcolour(struct pms *dev, short colour) { - if(decoder==PHILIPS2) - { - pms_i2c_andor(0x8A, 0x08, 0x07, (colour&0x1F)<<3); - pms_i2c_andor(0x8A, 0x09, 0x07, (colour&0x1F)<<3); - } - else if(decoder==PHILIPS1) - { - pms_i2c_andor(0x42, 0x08, 0x07, (colour&0x1F)<<3); - pms_i2c_andor(0x42, 0x09, 0x07, (colour&0x1F)<<3); + if (dev->decoder == PHILIPS2) { + pms_i2c_andor(dev, 0x8a, 0x08, 0x07, (colour & 0x1f) << 3); + pms_i2c_andor(dev, 0x8a, 0x09, 0x07, (colour & 0x1f) << 3); + } else if (dev->decoder == PHILIPS1) { + pms_i2c_andor(dev, 0x42, 0x08, 0x07, (colour & 0x1f) << 3); + pms_i2c_andor(dev, 0x42, 0x09, 0x07, (colour & 0x1f) << 3); } } -static void pms_chromagain(short chroma) +static void pms_chromagain(struct pms *dev, short chroma) { - if(decoder==PHILIPS2) - { - pms_i2c_write(0x8A, 0x11, chroma); - } - else if(decoder==PHILIPS1) - { - pms_i2c_write(0x42, 0x11, chroma); - } + if (dev->decoder == PHILIPS2) + pms_i2c_write(dev, 0x8a, 0x11, chroma); + else if (dev->decoder == PHILIPS1) + pms_i2c_write(dev, 0x42, 0x11, chroma); } -static void pms_spacialcompl(short data) +static void pms_spacialcompl(struct pms *dev, short data) { - mvv_write(0x3B, data); + mvv_write(dev, 0x3b, data); } -static void pms_spacialcomph(short data) +static void pms_spacialcomph(struct pms *dev, short data) { - mvv_write(0x3A, data); + mvv_write(dev, 0x3a, data); } -static void pms_vstart(short start) +static void pms_vstart(struct pms *dev, short start) { - mvv_write(0x16, start); - mvv_write(0x17, (start>>8)&0x01); + mvv_write(dev, 0x16, start); + mvv_write(dev, 0x17, (start >> 8) & 0x01); } #endif -static void pms_secamcross(short cross) +static void pms_secamcross(struct pms *dev, short cross) { - if(decoder==PHILIPS2) - pms_i2c_andor(0x8A, 0x0F, 0xDF, (cross&1)<<5); - else if(decoder==PHILIPS1) - pms_i2c_andor(0x42, 0x0F, 0xDF, (cross&1)<<5); + if (dev->decoder == PHILIPS2) + pms_i2c_andor(dev, 0x8a, 0x0f, 0xdf, (cross & 1) << 5); + else if (dev->decoder == PHILIPS1) + pms_i2c_andor(dev, 0x42, 0x0f, 0xdf, (cross & 1) << 5); } -static void pms_swsense(short sense) +static void pms_swsense(struct pms *dev, short sense) { - if(decoder==PHILIPS2) - { - pms_i2c_write(0x8A, 0x0A, sense); - pms_i2c_write(0x8A, 0x0B, sense); - } - else if(decoder==PHILIPS1) - { - pms_i2c_write(0x42, 0x0A, sense); - pms_i2c_write(0x42, 0x0B, sense); + if (dev->decoder == PHILIPS2) { + pms_i2c_write(dev, 0x8a, 0x0a, sense); + pms_i2c_write(dev, 0x8a, 0x0b, sense); + } else if (dev->decoder == PHILIPS1) { + pms_i2c_write(dev, 0x42, 0x0a, sense); + pms_i2c_write(dev, 0x42, 0x0b, sense); } } -static void pms_framerate(short frr) +static void pms_framerate(struct pms *dev, short frr) { - int fps=(standard==1)?30:25; - if(frr==0) + int fps = (dev->standard == 1) ? 30 : 25; + + if (frr == 0) return; - fps=fps/frr; - mvv_write(0x14,0x80|fps); - mvv_write(0x15,1); + fps = fps/frr; + mvv_write(dev, 0x14, 0x80 | fps); + mvv_write(dev, 0x15, 1); } -static void pms_vert(u8 deciden, u8 decinum) +static void pms_vert(struct pms *dev, u8 deciden, u8 decinum) { - mvv_write(0x1C, deciden); /* Denominator */ - mvv_write(0x1D, decinum); /* Numerator */ + mvv_write(dev, 0x1c, deciden); /* Denominator */ + mvv_write(dev, 0x1d, decinum); /* Numerator */ } /* * Turn 16bit ratios into best small ratio the chipset can grok */ -static void pms_vertdeci(unsigned short decinum, unsigned short deciden) +static void pms_vertdeci(struct pms *dev, unsigned short decinum, unsigned short deciden) { - /* Knock it down by /5 once */ - if(decinum%5==0) - { - deciden/=5; - decinum/=5; + /* Knock it down by / 5 once */ + if (decinum % 5 == 0) { + deciden /= 5; + decinum /= 5; } /* * 3's */ - while(decinum%3==0 && deciden%3==0) - { - deciden/=3; - decinum/=3; + while (decinum % 3 == 0 && deciden % 3 == 0) { + deciden /= 3; + decinum /= 3; } /* * 2's */ - while(decinum%2==0 && deciden%2==0) - { - decinum/=2; - deciden/=2; + while (decinum % 2 == 0 && deciden % 2 == 0) { + decinum /= 2; + deciden /= 2; } /* * Fudgyify */ - while(deciden>32) - { - deciden/=2; - decinum=(decinum+1)/2; + while (deciden > 32) { + deciden /= 2; + decinum = (decinum + 1) / 2; } - if(deciden==32) + if (deciden == 32) deciden--; - pms_vert(deciden,decinum); + pms_vert(dev, deciden, decinum); } -static void pms_horzdeci(short decinum, short deciden) +static void pms_horzdeci(struct pms *dev, short decinum, short deciden) { - if(decinum<=512) - { - if(decinum%5==0) - { - decinum/=5; - deciden/=5; + if (decinum <= 512) { + if (decinum % 5 == 0) { + decinum /= 5; + deciden /= 5; } - } - else - { - decinum=512; - deciden=640; /* 768 would be ideal */ + } else { + decinum = 512; + deciden = 640; /* 768 would be ideal */ } - while(((decinum|deciden)&1)==0) - { - decinum>>=1; - deciden>>=1; + while (((decinum | deciden) & 1) == 0) { + decinum >>= 1; + deciden >>= 1; } - while(deciden>32) - { - deciden>>=1; - decinum=(decinum+1)>>1; + while (deciden > 32) { + deciden >>= 1; + decinum = (decinum + 1) >> 1; } - if(deciden==32) + if (deciden == 32) deciden--; - mvv_write(0x24, 0x80|deciden); - mvv_write(0x25, decinum); + mvv_write(dev, 0x24, 0x80 | deciden); + mvv_write(dev, 0x25, decinum); } -static void pms_resolution(short width, short height) +static void pms_resolution(struct pms *dev, short width, short height) { int fg_height; - fg_height=height; - if(fg_height>280) - fg_height=280; + fg_height = height; + if (fg_height > 280) + fg_height = 280; - mvv_write(0x18, fg_height); - mvv_write(0x19, fg_height>>8); + mvv_write(dev, 0x18, fg_height); + mvv_write(dev, 0x19, fg_height >> 8); - if(standard==1) - { - mvv_write(0x1A, 0xFC); - mvv_write(0x1B, 0x00); - if(height>fg_height) - pms_vertdeci(240,240); + if (dev->standard == 1) { + mvv_write(dev, 0x1a, 0xfc); + mvv_write(dev, 0x1b, 0x00); + if (height > fg_height) + pms_vertdeci(dev, 240, 240); else - pms_vertdeci(fg_height,240); - } - else - { - mvv_write(0x1A, 0x1A); - mvv_write(0x1B, 0x01); - if(fg_height>256) - pms_vertdeci(270,270); + pms_vertdeci(dev, fg_height, 240); + } else { + mvv_write(dev, 0x1a, 0x1a); + mvv_write(dev, 0x1b, 0x01); + if (fg_height > 256) + pms_vertdeci(dev, 270, 270); else - pms_vertdeci(fg_height, 270); + pms_vertdeci(dev, fg_height, 270); } - mvv_write(0x12,0); - mvv_write(0x13, MVVMEMORYWIDTH); - mvv_write(0x42, 0x00); - mvv_write(0x43, 0x00); - mvv_write(0x44, MVVMEMORYWIDTH); + mvv_write(dev, 0x12, 0); + mvv_write(dev, 0x13, MVVMEMORYWIDTH); + mvv_write(dev, 0x42, 0x00); + mvv_write(dev, 0x43, 0x00); + mvv_write(dev, 0x44, MVVMEMORYWIDTH); - mvv_write(0x22, width+8); - mvv_write(0x23, (width+8)>> 8); + mvv_write(dev, 0x22, width + 8); + mvv_write(dev, 0x23, (width + 8) >> 8); - if(standard==1) - pms_horzdeci(width,640); + if (dev->standard == 1) + pms_horzdeci(dev, width, 640); else - pms_horzdeci(width+8, 768); + pms_horzdeci(dev, width + 8, 768); - mvv_write(0x30, mvv_read(0x30)&0xFE); - mvv_write(0x08, mvv_read(0x08)|0x01); - mvv_write(0x01, mvv_read(0x01)&0xFD); - mvv_write(0x32, 0x00); - mvv_write(0x33, MVVMEMORYWIDTH); + mvv_write(dev, 0x30, mvv_read(dev, 0x30) & 0xfe); + mvv_write(dev, 0x08, mvv_read(dev, 0x08) | 0x01); + mvv_write(dev, 0x01, mvv_read(dev, 0x01) & 0xfd); + mvv_write(dev, 0x32, 0x00); + mvv_write(dev, 0x33, MVVMEMORYWIDTH); } @@ -621,52 +598,49 @@ static void pms_resolution(short width, short height) * Set Input */ -static void pms_vcrinput(short input) +static void pms_vcrinput(struct pms *dev, short input) { - if(decoder==PHILIPS2) - pms_i2c_andor(0x8A,0x0D,0x7F,(input&1)<<7); - else if(decoder==PHILIPS1) - pms_i2c_andor(0x42,0x0D,0x7F,(input&1)<<7); + if (dev->decoder == PHILIPS2) + pms_i2c_andor(dev, 0x8a, 0x0d, 0x7f, (input & 1) << 7); + else if (dev->decoder == PHILIPS1) + pms_i2c_andor(dev, 0x42, 0x0d, 0x7f, (input & 1) << 7); } -static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int count) +static int pms_capture(struct pms *dev, char __user *buf, int rgb555, int count) { int y; - int dw = 2*dev->width; - - char tmp[dw+32]; /* using a temp buffer is faster than direct */ + int dw = 2 * dev->width; + char tmp[dw + 32]; /* using a temp buffer is faster than direct */ int cnt = 0; - int len=0; + int len = 0; unsigned char r8 = 0x5; /* value for reg8 */ if (rgb555) r8 |= 0x20; /* else use untranslated rgb = 565 */ - mvv_write(0x08,r8); /* capture rgb555/565, init DRAM, PC enable */ + mvv_write(dev, 0x08, r8); /* capture rgb555/565, init DRAM, PC enable */ /* printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */ - for (y = 0; y < dev->height; y++ ) - { - writeb(0, mem); /* synchronisiert neue Zeile */ + for (y = 0; y < dev->height; y++) { + writeb(0, dev->mem); /* synchronisiert neue Zeile */ /* * This is in truth a fifo, be very careful as if you * forgot this odd things will occur 8) */ - memcpy_fromio(tmp, mem, dw+32); /* discard 16 word */ + memcpy_fromio(tmp, dev->mem, dw + 32); /* discard 16 word */ cnt -= dev->height; - while (cnt <= 0) - { + while (cnt <= 0) { /* * Don't copy too far */ - int dt=dw; - if(dt+len>count) - dt=count-len; + int dt = dw; + if (dt + len > count) + dt = count - len; cnt += dev->height; - if (copy_to_user(buf, tmp+32, dt)) + if (copy_to_user(buf, tmp + 32, dt)) return len ? len : -EFAULT; buf += dt; len += dt; @@ -682,182 +656,182 @@ static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int static long pms_do_ioctl(struct file *file, unsigned int cmd, void *arg) { - struct video_device *dev = video_devdata(file); - struct pms_device *pd=(struct pms_device *)dev; - - switch(cmd) - { - case VIDIOCGCAP: - { - struct video_capability *b = arg; - strcpy(b->name, "Mediavision PMS"); - b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES; - b->channels = 4; - b->audios = 0; - b->maxwidth = 640; - b->maxheight = 480; - b->minwidth = 16; - b->minheight = 16; - return 0; - } - case VIDIOCGCHAN: - { - struct video_channel *v = arg; - if(v->channel<0 || v->channel>3) - return -EINVAL; - v->flags=0; - v->tuners=1; - /* Good question.. its composite or SVHS so.. */ - v->type = VIDEO_TYPE_CAMERA; - switch(v->channel) - { - case 0: - strcpy(v->name, "Composite");break; - case 1: - strcpy(v->name, "SVideo");break; - case 2: - strcpy(v->name, "Composite(VCR)");break; - case 3: - strcpy(v->name, "SVideo(VCR)");break; - } - return 0; - } - case VIDIOCSCHAN: - { - struct video_channel *v = arg; - if(v->channel<0 || v->channel>3) - return -EINVAL; - mutex_lock(&pd->lock); - pms_videosource(v->channel&1); - pms_vcrinput(v->channel>>1); - mutex_unlock(&pd->lock); - return 0; - } - case VIDIOCGTUNER: - { - struct video_tuner *v = arg; - if(v->tuner) - return -EINVAL; - strcpy(v->name, "Format"); - v->rangelow=0; - v->rangehigh=0; - v->flags= VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM; - switch(standard) - { - case 0: - v->mode = VIDEO_MODE_AUTO; - break; - case 1: - v->mode = VIDEO_MODE_NTSC; - break; - case 2: - v->mode = VIDEO_MODE_PAL; - break; - case 3: - v->mode = VIDEO_MODE_SECAM; - break; - } - return 0; - } - case VIDIOCSTUNER: - { - struct video_tuner *v = arg; - if(v->tuner) - return -EINVAL; - mutex_lock(&pd->lock); - switch(v->mode) - { - case VIDEO_MODE_AUTO: - pms_framerate(25); - pms_secamcross(0); - pms_format(0); - break; - case VIDEO_MODE_NTSC: - pms_framerate(30); - pms_secamcross(0); - pms_format(1); - break; - case VIDEO_MODE_PAL: - pms_framerate(25); - pms_secamcross(0); - pms_format(2); - break; - case VIDEO_MODE_SECAM: - pms_framerate(25); - pms_secamcross(1); - pms_format(2); - break; - default: - mutex_unlock(&pd->lock); - return -EINVAL; - } - mutex_unlock(&pd->lock); - return 0; - } - case VIDIOCGPICT: - { - struct video_picture *p = arg; - *p = pd->picture; - return 0; + struct pms *dev = video_drvdata(file); + + switch (cmd) { + case VIDIOCGCAP: { + struct video_capability *b = arg; + + strcpy(b->name, "Mediavision PMS"); + b->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; + b->channels = 4; + b->audios = 0; + b->maxwidth = 640; + b->maxheight = 480; + b->minwidth = 16; + b->minheight = 16; + return 0; + } + case VIDIOCGCHAN: { + struct video_channel *v = arg; + + if (v->channel < 0 || v->channel > 3) + return -EINVAL; + v->flags = 0; + v->tuners = 1; + /* Good question.. its composite or SVHS so.. */ + v->type = VIDEO_TYPE_CAMERA; + switch (v->channel) { + case 0: + strcpy(v->name, "Composite"); + break; + case 1: + strcpy(v->name, "SVideo"); + break; + case 2: + strcpy(v->name, "Composite(VCR)"); + break; + case 3: + strcpy(v->name, "SVideo(VCR)"); + break; } - case VIDIOCSPICT: - { - struct video_picture *p = arg; - if(!((p->palette==VIDEO_PALETTE_RGB565 && p->depth==16) - ||(p->palette==VIDEO_PALETTE_RGB555 && p->depth==15))) - return -EINVAL; - pd->picture= *p; + return 0; + } + case VIDIOCSCHAN: { + struct video_channel *v = arg; - /* - * Now load the card. - */ + if (v->channel < 0 || v->channel > 3) + return -EINVAL; + mutex_lock(&dev->lock); + pms_videosource(dev, v->channel & 1); + pms_vcrinput(dev, v->channel >> 1); + mutex_unlock(&dev->lock); + return 0; + } + case VIDIOCGTUNER: { + struct video_tuner *v = arg; - mutex_lock(&pd->lock); - pms_brightness(p->brightness>>8); - pms_hue(p->hue>>8); - pms_colour(p->colour>>8); - pms_contrast(p->contrast>>8); - mutex_unlock(&pd->lock); - return 0; - } - case VIDIOCSWIN: - { - struct video_window *vw = arg; - if(vw->flags) - return -EINVAL; - if(vw->clipcount) - return -EINVAL; - if(vw->height<16||vw->height>480) - return -EINVAL; - if(vw->width<16||vw->width>640) - return -EINVAL; - pd->width=vw->width; - pd->height=vw->height; - mutex_lock(&pd->lock); - pms_resolution(pd->width, pd->height); - mutex_unlock(&pd->lock); /* Ok we figured out what to use from our wide choice */ - return 0; - } - case VIDIOCGWIN: - { - struct video_window *vw = arg; - memset(vw,0,sizeof(*vw)); - vw->width=pd->width; - vw->height=pd->height; - return 0; + if (v->tuner) + return -EINVAL; + strcpy(v->name, "Format"); + v->rangelow = 0; + v->rangehigh = 0; + v->flags = VIDEO_TUNER_PAL | VIDEO_TUNER_NTSC | VIDEO_TUNER_SECAM; + switch (dev->standard) { + case 0: + v->mode = VIDEO_MODE_AUTO; + break; + case 1: + v->mode = VIDEO_MODE_NTSC; + break; + case 2: + v->mode = VIDEO_MODE_PAL; + break; + case 3: + v->mode = VIDEO_MODE_SECAM; + break; } - case VIDIOCKEY: - return 0; - case VIDIOCCAPTURE: - case VIDIOCGFBUF: - case VIDIOCSFBUF: - case VIDIOCGFREQ: - case VIDIOCSFREQ: - case VIDIOCGAUDIO: - case VIDIOCSAUDIO: + return 0; + } + case VIDIOCSTUNER: { + struct video_tuner *v = arg; + + if (v->tuner) return -EINVAL; + mutex_lock(&dev->lock); + switch (v->mode) { + case VIDEO_MODE_AUTO: + pms_framerate(dev, 25); + pms_secamcross(dev, 0); + pms_format(dev, 0); + break; + case VIDEO_MODE_NTSC: + pms_framerate(dev, 30); + pms_secamcross(dev, 0); + pms_format(dev, 1); + break; + case VIDEO_MODE_PAL: + pms_framerate(dev, 25); + pms_secamcross(dev, 0); + pms_format(dev, 2); + break; + case VIDEO_MODE_SECAM: + pms_framerate(dev, 25); + pms_secamcross(dev, 1); + pms_format(dev, 2); + break; default: - return -ENOIOCTLCMD; + mutex_unlock(&dev->lock); + return -EINVAL; + } + mutex_unlock(&dev->lock); + return 0; + } + case VIDIOCGPICT: { + struct video_picture *p = arg; + + *p = dev->picture; + return 0; + } + case VIDIOCSPICT: { + struct video_picture *p = arg; + + if (!((p->palette == VIDEO_PALETTE_RGB565 && p->depth == 16) || + (p->palette == VIDEO_PALETTE_RGB555 && p->depth == 15))) + return -EINVAL; + dev->picture = *p; + + /* + * Now load the card. + */ + + mutex_lock(&dev->lock); + pms_brightness(dev, p->brightness >> 8); + pms_hue(dev, p->hue >> 8); + pms_colour(dev, p->colour >> 8); + pms_contrast(dev, p->contrast >> 8); + mutex_unlock(&dev->lock); + return 0; + } + case VIDIOCSWIN: { + struct video_window *vw = arg; + + if (vw->flags) + return -EINVAL; + if (vw->clipcount) + return -EINVAL; + if (vw->height < 16 || vw->height > 480) + return -EINVAL; + if (vw->width < 16 || vw->width > 640) + return -EINVAL; + dev->width = vw->width; + dev->height = vw->height; + mutex_lock(&dev->lock); + pms_resolution(dev, dev->width, dev->height); + /* Ok we figured out what to use from our wide choice */ + mutex_unlock(&dev->lock); + return 0; + } + case VIDIOCGWIN: { + struct video_window *vw = arg; + + memset(vw, 0, sizeof(*vw)); + vw->width = dev->width; + vw->height = dev->height; + return 0; + } + case VIDIOCKEY: + return 0; + case VIDIOCCAPTURE: + case VIDIOCGFBUF: + case VIDIOCSFBUF: + case VIDIOCGFREQ: + case VIDIOCSFREQ: + case VIDIOCGAUDIO: + case VIDIOCSAUDIO: + return -EINVAL; + default: + return -ENOIOCTLCMD; } return 0; } @@ -871,30 +845,27 @@ static long pms_ioctl(struct file *file, static ssize_t pms_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct video_device *v = video_devdata(file); - struct pms_device *pd=(struct pms_device *)v; + struct pms *dev = video_drvdata(file); int len; - mutex_lock(&pd->lock); - len=pms_capture(pd, buf, (pd->picture.depth==16)?0:1,count); - mutex_unlock(&pd->lock); + mutex_lock(&dev->lock); + len = pms_capture(dev, buf, (dev->picture.depth == 16) ? 0 : 1, count); + mutex_unlock(&dev->lock); return len; } static int pms_exclusive_open(struct file *file) { - struct video_device *v = video_devdata(file); - struct pms_device *pd = (struct pms_device *)v; + struct pms *dev = video_drvdata(file); - return test_and_set_bit(0, &pd->in_use) ? -EBUSY : 0; + return test_and_set_bit(0, &dev->in_use) ? -EBUSY : 0; } static int pms_exclusive_release(struct file *file) { - struct video_device *v = video_devdata(file); - struct pms_device *pd = (struct pms_device *)v; + struct pms *dev = video_drvdata(file); - clear_bit(0, &pd->in_use); + clear_bit(0, &dev->in_use); return 0; } @@ -906,74 +877,62 @@ static const struct v4l2_file_operations pms_fops = { .read = pms_read, }; -static struct video_device pms_template= -{ - .name = "Mediavision PMS", - .fops = &pms_fops, - .release = video_device_release_empty, -}; - -static struct pms_device pms_device; - /* * Probe for and initialise the Mediavision PMS */ -static int init_mediavision(void) +static int init_mediavision(struct pms *dev) { int id; int idec, decst; int i; - - unsigned char i2c_defs[]={ - 0x4C,0x30,0x00,0xE8, - 0xB6,0xE2,0x00,0x00, - 0xFF,0xFF,0x00,0x00, - 0x00,0x00,0x78,0x98, - 0x00,0x00,0x00,0x00, - 0x34,0x0A,0xF4,0xCE, - 0xE4 + static const unsigned char i2c_defs[] = { + 0x4c, 0x30, 0x00, 0xe8, + 0xb6, 0xe2, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x78, 0x98, + 0x00, 0x00, 0x00, 0x00, + 0x34, 0x0a, 0xf4, 0xce, + 0xe4 }; - mem = ioremap(mem_base, 0x800); - if (!mem) + dev->mem = ioremap(mem_base, 0x800); + if (!dev->mem) return -ENOMEM; - if (!request_region(0x9A01, 1, "Mediavision PMS config")) - { - printk(KERN_WARNING "mediavision: unable to detect: 0x9A01 in use.\n"); - iounmap(mem); + if (!request_region(0x9a01, 1, "Mediavision PMS config")) { + printk(KERN_WARNING "mediavision: unable to detect: 0x9a01 in use.\n"); + iounmap(dev->mem); return -EBUSY; } - if (!request_region(io_port, 3, "Mediavision PMS")) - { - printk(KERN_WARNING "mediavision: I/O port %d in use.\n", io_port); - release_region(0x9A01, 1); - iounmap(mem); + if (!request_region(dev->io, 3, "Mediavision PMS")) { + printk(KERN_WARNING "mediavision: I/O port %d in use.\n", dev->io); + release_region(0x9a01, 1); + iounmap(dev->mem); return -EBUSY; } - outb(0xB8, 0x9A01); /* Unlock */ - outb(io_port>>4, 0x9A01); /* Set IO port */ + outb(0xb8, 0x9a01); /* Unlock */ + outb(dev->io >> 4, 0x9a01); /* Set IO port */ - id=mvv_read(3); - decst=pms_i2c_stat(0x43); + id = mvv_read(dev, 3); + decst = pms_i2c_stat(dev, 0x43); - if(decst!=-1) - idec=2; - else if(pms_i2c_stat(0xb9)!=-1) - idec=3; - else if(pms_i2c_stat(0x8b)!=-1) - idec=1; + if (decst != -1) + idec = 2; + else if (pms_i2c_stat(dev, 0xb9) != -1) + idec = 3; + else if (pms_i2c_stat(dev, 0x8b) != -1) + idec = 1; else - idec=0; + idec = 0; printk(KERN_INFO "PMS type is %d\n", idec); - if(idec == 0) { - release_region(io_port, 3); - release_region(0x9A01, 1); - iounmap(mem); + if (idec == 0) { + release_region(dev->io, 3); + release_region(0x9a01, 1); + iounmap(dev->mem); return -ENODEV; } @@ -981,51 +940,50 @@ static int init_mediavision(void) * Ok we have a PMS of some sort */ - mvv_write(0x04, mem_base>>12); /* Set the memory area */ + mvv_write(dev, 0x04, mem_base >> 12); /* Set the memory area */ /* Ok now load the defaults */ - for(i=0;i<0x19;i++) - { - if(i2c_defs[i]==0xFF) - pms_i2c_andor(0x8A, i, 0x07,0x00); + for (i = 0; i < 0x19; i++) { + if (i2c_defs[i] == 0xff) + pms_i2c_andor(dev, 0x8a, i, 0x07, 0x00); else - pms_i2c_write(0x8A, i, i2c_defs[i]); + pms_i2c_write(dev, 0x8a, i, i2c_defs[i]); } - pms_i2c_write(0xB8,0x00,0x12); - pms_i2c_write(0xB8,0x04,0x00); - pms_i2c_write(0xB8,0x07,0x00); - pms_i2c_write(0xB8,0x08,0x00); - pms_i2c_write(0xB8,0x09,0xFF); - pms_i2c_write(0xB8,0x0A,0x00); - pms_i2c_write(0xB8,0x0B,0x10); - pms_i2c_write(0xB8,0x10,0x03); - - mvv_write(0x01, 0x00); - mvv_write(0x05, 0xA0); - mvv_write(0x08, 0x25); - mvv_write(0x09, 0x00); - mvv_write(0x0A, 0x20|MVVMEMORYWIDTH); - - mvv_write(0x10, 0x02); - mvv_write(0x1E, 0x0C); - mvv_write(0x1F, 0x03); - mvv_write(0x26, 0x06); - - mvv_write(0x2B, 0x00); - mvv_write(0x2C, 0x20); - mvv_write(0x2D, 0x00); - mvv_write(0x2F, 0x70); - mvv_write(0x32, 0x00); - mvv_write(0x33, MVVMEMORYWIDTH); - mvv_write(0x34, 0x00); - mvv_write(0x35, 0x00); - mvv_write(0x3A, 0x80); - mvv_write(0x3B, 0x10); - mvv_write(0x20, 0x00); - mvv_write(0x21, 0x00); - mvv_write(0x30, 0x22); + pms_i2c_write(dev, 0xb8, 0x00, 0x12); + pms_i2c_write(dev, 0xb8, 0x04, 0x00); + pms_i2c_write(dev, 0xb8, 0x07, 0x00); + pms_i2c_write(dev, 0xb8, 0x08, 0x00); + pms_i2c_write(dev, 0xb8, 0x09, 0xff); + pms_i2c_write(dev, 0xb8, 0x0a, 0x00); + pms_i2c_write(dev, 0xb8, 0x0b, 0x10); + pms_i2c_write(dev, 0xb8, 0x10, 0x03); + + mvv_write(dev, 0x01, 0x00); + mvv_write(dev, 0x05, 0xa0); + mvv_write(dev, 0x08, 0x25); + mvv_write(dev, 0x09, 0x00); + mvv_write(dev, 0x0a, 0x20 | MVVMEMORYWIDTH); + + mvv_write(dev, 0x10, 0x02); + mvv_write(dev, 0x1e, 0x0c); + mvv_write(dev, 0x1f, 0x03); + mvv_write(dev, 0x26, 0x06); + + mvv_write(dev, 0x2b, 0x00); + mvv_write(dev, 0x2c, 0x20); + mvv_write(dev, 0x2d, 0x00); + mvv_write(dev, 0x2f, 0x70); + mvv_write(dev, 0x32, 0x00); + mvv_write(dev, 0x33, MVVMEMORYWIDTH); + mvv_write(dev, 0x34, 0x00); + mvv_write(dev, 0x35, 0x00); + mvv_write(dev, 0x3a, 0x80); + mvv_write(dev, 0x3b, 0x10); + mvv_write(dev, 0x20, 0x00); + mvv_write(dev, 0x21, 0x00); + mvv_write(dev, 0x30, 0x22); return 0; } @@ -1038,53 +996,70 @@ static int enable; module_param(enable, int, 0); #endif -static int __init init_pms_cards(void) +static int __init pms_init(void) { - printk(KERN_INFO "Mediavision Pro Movie Studio driver 0.02\n"); + struct pms *dev = &pms_card; + struct v4l2_device *v4l2_dev = &dev->v4l2_dev; + int res; + + strlcpy(v4l2_dev->name, "pms", sizeof(v4l2_dev->name)); + + v4l2_info(v4l2_dev, "Mediavision Pro Movie Studio driver 0.03\n"); #ifndef MODULE if (!enable) { - printk(KERN_INFO "PMS: not enabled, use pms.enable=1 to " - "probe\n"); + v4l2_err(v4l2_dev, + "PMS: not enabled, use pms.enable=1 to probe\n"); return -ENODEV; } #endif - data_port = io_port +1; + dev->decoder = PHILIPS2; + dev->io = io_port; + dev->data = io_port + 1; - if(init_mediavision()) - { - printk(KERN_INFO "Board not found.\n"); + if (init_mediavision(dev)) { + v4l2_err(v4l2_dev, "Board not found.\n"); return -ENODEV; } - memcpy(&pms_device, &pms_template, sizeof(pms_template)); - mutex_init(&pms_device.lock); - pms_device.height=240; - pms_device.width=320; - pms_swsense(75); - pms_resolution(320,240); - return video_register_device((struct video_device *)&pms_device, VFL_TYPE_GRABBER, video_nr); -} - -module_param(io_port, int, 0); -module_param(mem_base, int, 0); -module_param(video_nr, int, 0); -MODULE_LICENSE("GPL"); + res = v4l2_device_register(NULL, v4l2_dev); + if (res < 0) { + v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); + return res; + } -static void __exit shutdown_mediavision(void) -{ - release_region(io_port,3); - release_region(0x9A01, 1); + strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); + dev->vdev.v4l2_dev = v4l2_dev; + dev->vdev.fops = &pms_fops; + dev->vdev.release = video_device_release_empty; + video_set_drvdata(&dev->vdev, dev); + mutex_init(&dev->lock); + dev->height = 240; + dev->width = 320; + pms_swsense(dev, 75); + pms_resolution(dev, 320, 240); + pms_videosource(dev, 0); + pms_vcrinput(dev, 0); + if (video_register_device(&dev->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { + v4l2_device_unregister(&dev->v4l2_dev); + release_region(dev->io, 3); + release_region(0x9a01, 1); + iounmap(dev->mem); + return -EINVAL; + } + return 0; } -static void __exit cleanup_pms_module(void) +static void __exit pms_exit(void) { - shutdown_mediavision(); - video_unregister_device((struct video_device *)&pms_device); - iounmap(mem); -} + struct pms *dev = &pms_card; -module_init(init_pms_cards); -module_exit(cleanup_pms_module); + video_unregister_device(&dev->vdev); + release_region(dev->io, 3); + release_region(0x9a01, 1); + iounmap(dev->mem); +} +module_init(pms_init); +module_exit(pms_exit); -- cgit v1.2.3-70-g09d2 From feba2f817d87891c002739ecdb54eef56740b882 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 25 Nov 2009 12:47:02 -0300 Subject: V4L/DVB (13509): pms: convert from V4L1 to V4L2. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 2 +- drivers/media/video/pms.c | 472 +++++++++++++++++++++++++++----------------- 2 files changed, 287 insertions(+), 187 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 82ae85c975f..9dc74c93bf2 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -600,7 +600,7 @@ source "drivers/media/video/bt8xx/Kconfig" config VIDEO_PMS tristate "Mediavision Pro Movie Studio Video For Linux" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_V4L2 help Say Y if you have such a thing. diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 2919aa42c94..73ec970ca5c 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c @@ -14,8 +14,10 @@ * unless the userspace driver also doesn't work for you... * * Changes: - * 08/07/2003 Daniele Bellucci - * - pms_capture: report back -EFAULT + * 25-11-2009 Hans Verkuil + * - converted to version 2 of the V4L API. + * 08/07/2003 Daniele Bellucci + * - pms_capture: report back -EFAULT */ #include @@ -27,20 +29,21 @@ #include #include #include +#include +#include +#include #include -#include + +#include #include #include #include -#include - -#include MODULE_LICENSE("GPL"); #define MOTOROLA 1 -#define PHILIPS2 2 +#define PHILIPS2 2 /* SAA7191 */ #define PHILIPS1 3 #define MVVMEMORYWIDTH 0x40 /* 512 bytes */ @@ -54,9 +57,11 @@ struct i2c_info { struct pms { struct v4l2_device v4l2_dev; struct video_device vdev; - struct video_picture picture; int height; int width; + int depth; + int input; + s32 brightness, saturation, hue, contrast; unsigned long in_use; struct mutex lock; int i2c_count; @@ -64,6 +69,7 @@ struct pms { int decoder; int standard; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */ + v4l2_std_id std; int io; int data; void __iomem *mem; @@ -209,7 +215,19 @@ static void pms_i2c_andor(struct pms *dev, int slave, int sub, int and, int or) static void pms_videosource(struct pms *dev, short source) { - mvv_write(dev, 0x2E, source ? 0x31 : 0x30); + switch (dev->decoder) { + case MOTOROLA: + break; + case PHILIPS2: + pms_i2c_andor(dev, 0x8a, 0x06, 0x7f, source ? 0x80 : 0); + break; + case PHILIPS1: + break; + } + mvv_write(dev, 0x2E, 0x31); + /* Was: mvv_write(dev, 0x2E, source ? 0x31 : 0x30); + But could not make this work correctly. Only Composite input + worked for me. */ } static void pms_hue(struct pms *dev, short hue) @@ -227,14 +245,14 @@ static void pms_hue(struct pms *dev, short hue) } } -static void pms_colour(struct pms *dev, short colour) +static void pms_saturation(struct pms *dev, short sat) { switch (dev->decoder) { case MOTOROLA: - pms_i2c_write(dev, 0x8a, 0x00, colour); + pms_i2c_write(dev, 0x8a, 0x00, sat); break; case PHILIPS1: - pms_i2c_write(dev, 0x42, 0x12, colour); + pms_i2c_write(dev, 0x42, 0x12, sat); break; } } @@ -467,7 +485,7 @@ static void pms_swsense(struct pms *dev, short sense) static void pms_framerate(struct pms *dev, short frr) { - int fps = (dev->standard == 1) ? 30 : 25; + int fps = (dev->std & V4L2_STD_525_60) ? 30 : 25; if (frr == 0) return; @@ -557,7 +575,7 @@ static void pms_resolution(struct pms *dev, short width, short height) mvv_write(dev, 0x18, fg_height); mvv_write(dev, 0x19, fg_height >> 8); - if (dev->standard == 1) { + if (dev->std & V4L2_STD_525_60) { mvv_write(dev, 0x1a, 0xfc); mvv_write(dev, 0x1b, 0x00); if (height > fg_height) @@ -581,7 +599,7 @@ static void pms_resolution(struct pms *dev, short width, short height) mvv_write(dev, 0x22, width + 8); mvv_write(dev, 0x23, (width + 8) >> 8); - if (dev->standard == 1) + if (dev->std & V4L2_STD_525_60) pms_horzdeci(dev, width, 640); else pms_horzdeci(dev, width + 8, 768); @@ -654,192 +672,252 @@ static int pms_capture(struct pms *dev, char __user *buf, int rgb555, int count) * Video4linux interfacing */ -static long pms_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static int pms_querycap(struct file *file, void *priv, + struct v4l2_capability *vcap) { struct pms *dev = video_drvdata(file); - switch (cmd) { - case VIDIOCGCAP: { - struct video_capability *b = arg; - - strcpy(b->name, "Mediavision PMS"); - b->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; - b->channels = 4; - b->audios = 0; - b->maxwidth = 640; - b->maxheight = 480; - b->minwidth = 16; - b->minheight = 16; - return 0; - } - case VIDIOCGCHAN: { - struct video_channel *v = arg; - - if (v->channel < 0 || v->channel > 3) - return -EINVAL; - v->flags = 0; - v->tuners = 1; - /* Good question.. its composite or SVHS so.. */ - v->type = VIDEO_TYPE_CAMERA; - switch (v->channel) { - case 0: - strcpy(v->name, "Composite"); - break; - case 1: - strcpy(v->name, "SVideo"); - break; - case 2: - strcpy(v->name, "Composite(VCR)"); - break; - case 3: - strcpy(v->name, "SVideo(VCR)"); - break; - } - return 0; - } - case VIDIOCSCHAN: { - struct video_channel *v = arg; - - if (v->channel < 0 || v->channel > 3) - return -EINVAL; - mutex_lock(&dev->lock); - pms_videosource(dev, v->channel & 1); - pms_vcrinput(dev, v->channel >> 1); - mutex_unlock(&dev->lock); - return 0; - } - case VIDIOCGTUNER: { - struct video_tuner *v = arg; - - if (v->tuner) - return -EINVAL; - strcpy(v->name, "Format"); - v->rangelow = 0; - v->rangehigh = 0; - v->flags = VIDEO_TUNER_PAL | VIDEO_TUNER_NTSC | VIDEO_TUNER_SECAM; - switch (dev->standard) { - case 0: - v->mode = VIDEO_MODE_AUTO; - break; - case 1: - v->mode = VIDEO_MODE_NTSC; - break; - case 2: - v->mode = VIDEO_MODE_PAL; - break; - case 3: - v->mode = VIDEO_MODE_SECAM; - break; - } - return 0; - } - case VIDIOCSTUNER: { - struct video_tuner *v = arg; - - if (v->tuner) - return -EINVAL; - mutex_lock(&dev->lock); - switch (v->mode) { - case VIDEO_MODE_AUTO: - pms_framerate(dev, 25); - pms_secamcross(dev, 0); - pms_format(dev, 0); - break; - case VIDEO_MODE_NTSC: - pms_framerate(dev, 30); - pms_secamcross(dev, 0); - pms_format(dev, 1); - break; - case VIDEO_MODE_PAL: - pms_framerate(dev, 25); - pms_secamcross(dev, 0); - pms_format(dev, 2); - break; - case VIDEO_MODE_SECAM: - pms_framerate(dev, 25); - pms_secamcross(dev, 1); - pms_format(dev, 2); - break; - default: - mutex_unlock(&dev->lock); - return -EINVAL; - } - mutex_unlock(&dev->lock); - return 0; - } - case VIDIOCGPICT: { - struct video_picture *p = arg; + strlcpy(vcap->driver, dev->v4l2_dev.name, sizeof(vcap->driver)); + strlcpy(vcap->card, "Mediavision PMS", sizeof(vcap->card)); + strlcpy(vcap->bus_info, "ISA", sizeof(vcap->bus_info)); + vcap->version = KERNEL_VERSION(0, 0, 3); + vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; + return 0; +} - *p = dev->picture; - return 0; - } - case VIDIOCSPICT: { - struct video_picture *p = arg; +static int pms_enum_input(struct file *file, void *fh, struct v4l2_input *vin) +{ + static const char *inputs[4] = { + "Composite", + "S-Video", + "Composite (VCR)", + "S-Video (VCR)" + }; - if (!((p->palette == VIDEO_PALETTE_RGB565 && p->depth == 16) || - (p->palette == VIDEO_PALETTE_RGB555 && p->depth == 15))) - return -EINVAL; - dev->picture = *p; + if (vin->index > 3) + return -EINVAL; + strlcpy(vin->name, inputs[vin->index], sizeof(vin->name)); + vin->type = V4L2_INPUT_TYPE_CAMERA; + vin->audioset = 0; + vin->tuner = 0; + vin->std = V4L2_STD_ALL; + vin->status = 0; + return 0; +} - /* - * Now load the card. - */ +static int pms_g_input(struct file *file, void *fh, unsigned int *inp) +{ + struct pms *dev = video_drvdata(file); - mutex_lock(&dev->lock); - pms_brightness(dev, p->brightness >> 8); - pms_hue(dev, p->hue >> 8); - pms_colour(dev, p->colour >> 8); - pms_contrast(dev, p->contrast >> 8); - mutex_unlock(&dev->lock); - return 0; + *inp = dev->input; + return 0; +} + +static int pms_s_input(struct file *file, void *fh, unsigned int inp) +{ + struct pms *dev = video_drvdata(file); + + if (inp > 3) + return -EINVAL; + + mutex_lock(&dev->lock); + dev->input = inp; + pms_videosource(dev, inp & 1); + pms_vcrinput(dev, inp >> 1); + mutex_unlock(&dev->lock); + return 0; +} + +static int pms_g_std(struct file *file, void *fh, v4l2_std_id *std) +{ + struct pms *dev = video_drvdata(file); + + *std = dev->std; + return 0; +} + +static int pms_s_std(struct file *file, void *fh, v4l2_std_id *std) +{ + struct pms *dev = video_drvdata(file); + int ret = 0; + + dev->std = *std; + mutex_lock(&dev->lock); + if (dev->std & V4L2_STD_NTSC) { + pms_framerate(dev, 30); + pms_secamcross(dev, 0); + pms_format(dev, 1); + } else if (dev->std & V4L2_STD_PAL) { + pms_framerate(dev, 25); + pms_secamcross(dev, 0); + pms_format(dev, 2); + } else if (dev->std & V4L2_STD_SECAM) { + pms_framerate(dev, 25); + pms_secamcross(dev, 1); + pms_format(dev, 2); + } else { + ret = -EINVAL; } - case VIDIOCSWIN: { - struct video_window *vw = arg; - - if (vw->flags) - return -EINVAL; - if (vw->clipcount) - return -EINVAL; - if (vw->height < 16 || vw->height > 480) - return -EINVAL; - if (vw->width < 16 || vw->width > 640) - return -EINVAL; - dev->width = vw->width; - dev->height = vw->height; - mutex_lock(&dev->lock); - pms_resolution(dev, dev->width, dev->height); - /* Ok we figured out what to use from our wide choice */ - mutex_unlock(&dev->lock); - return 0; + /* + switch (v->mode) { + case VIDEO_MODE_AUTO: + pms_framerate(dev, 25); + pms_secamcross(dev, 0); + pms_format(dev, 0); + break; + }*/ + mutex_unlock(&dev->lock); + return 0; +} + +static int pms_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *qc) +{ + switch (qc->id) { + case V4L2_CID_BRIGHTNESS: + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 139); + case V4L2_CID_CONTRAST: + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 70); + case V4L2_CID_SATURATION: + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 64); + case V4L2_CID_HUE: + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 0); } - case VIDIOCGWIN: { - struct video_window *vw = arg; + return -EINVAL; +} - memset(vw, 0, sizeof(*vw)); - vw->width = dev->width; - vw->height = dev->height; - return 0; +static int pms_g_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct pms *dev = video_drvdata(file); + int ret = 0; + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + ctrl->value = dev->brightness; + break; + case V4L2_CID_CONTRAST: + ctrl->value = dev->contrast; + break; + case V4L2_CID_SATURATION: + ctrl->value = dev->saturation; + break; + case V4L2_CID_HUE: + ctrl->value = dev->hue; + break; + default: + ret = -EINVAL; + break; } - case VIDIOCKEY: - return 0; - case VIDIOCCAPTURE: - case VIDIOCGFBUF: - case VIDIOCSFBUF: - case VIDIOCGFREQ: - case VIDIOCSFREQ: - case VIDIOCGAUDIO: - case VIDIOCSAUDIO: - return -EINVAL; + return ret; +} + +static int pms_s_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct pms *dev = video_drvdata(file); + int ret = 0; + + mutex_lock(&dev->lock); + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + dev->brightness = ctrl->value; + pms_brightness(dev, dev->brightness); + break; + case V4L2_CID_CONTRAST: + dev->contrast = ctrl->value; + pms_contrast(dev, dev->contrast); + break; + case V4L2_CID_SATURATION: + dev->saturation = ctrl->value; + pms_saturation(dev, dev->saturation); + break; + case V4L2_CID_HUE: + dev->hue = ctrl->value; + pms_hue(dev, dev->hue); + break; default: - return -ENOIOCTLCMD; + ret = -EINVAL; + break; } + mutex_unlock(&dev->lock); + return ret; +} + +static int pms_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) +{ + struct pms *dev = video_drvdata(file); + struct v4l2_pix_format *pix = &fmt->fmt.pix; + + pix->width = dev->width; + pix->height = dev->height; + pix->pixelformat = dev->width == 15 ? + V4L2_PIX_FMT_RGB555 : V4L2_PIX_FMT_RGB565; + pix->field = V4L2_FIELD_NONE; + pix->bytesperline = 2 * dev->width; + pix->sizeimage = 2 * dev->width * dev->height; + /* Just a guess */ + pix->colorspace = V4L2_COLORSPACE_SRGB; + return 0; +} + +static int pms_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) +{ + struct v4l2_pix_format *pix = &fmt->fmt.pix; + + if (pix->height < 16 || pix->height > 480) + return -EINVAL; + if (pix->width < 16 || pix->width > 640) + return -EINVAL; + if (pix->pixelformat != V4L2_PIX_FMT_RGB555 && + pix->pixelformat != V4L2_PIX_FMT_RGB565) + return -EINVAL; + pix->field = V4L2_FIELD_NONE; + pix->bytesperline = 2 * pix->width; + pix->sizeimage = 2 * pix->width * pix->height; + /* Just a guess */ + pix->colorspace = V4L2_COLORSPACE_SRGB; return 0; } -static long pms_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) +static int pms_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) { - return video_usercopy(file, cmd, arg, pms_do_ioctl); + struct pms *dev = video_drvdata(file); + struct v4l2_pix_format *pix = &fmt->fmt.pix; + int ret = pms_try_fmt_vid_cap(file, fh, fmt); + + if (ret) + return ret; + mutex_lock(&dev->lock); + dev->width = pix->width; + dev->height = pix->height; + dev->depth = (pix->pixelformat == V4L2_PIX_FMT_RGB555) ? 15 : 16; + pms_resolution(dev, dev->width, dev->height); + /* Ok we figured out what to use from our wide choice */ + mutex_unlock(&dev->lock); + return 0; +} + +static int pms_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) +{ + static struct v4l2_fmtdesc formats[] = { + { 0, 0, 0, + "RGB 5:5:5", V4L2_PIX_FMT_RGB555, + { 0, 0, 0, 0 } + }, + { 0, 0, 0, + "RGB 5:6:5", V4L2_PIX_FMT_RGB565, + { 0, 0, 0, 0 } + }, + }; + enum v4l2_buf_type type = fmt->type; + + if (fmt->index > 1) + return -EINVAL; + + *fmt = formats[fmt->index]; + fmt->type = type; + return 0; } static ssize_t pms_read(struct file *file, char __user *buf, @@ -849,7 +927,7 @@ static ssize_t pms_read(struct file *file, char __user *buf, int len; mutex_lock(&dev->lock); - len = pms_capture(dev, buf, (dev->picture.depth == 16) ? 0 : 1, count); + len = pms_capture(dev, buf, (dev->depth == 15), count); mutex_unlock(&dev->lock); return len; } @@ -873,10 +951,25 @@ static const struct v4l2_file_operations pms_fops = { .owner = THIS_MODULE, .open = pms_exclusive_open, .release = pms_exclusive_release, - .ioctl = pms_ioctl, + .ioctl = video_ioctl2, .read = pms_read, }; +static const struct v4l2_ioctl_ops pms_ioctl_ops = { + .vidioc_querycap = pms_querycap, + .vidioc_g_input = pms_g_input, + .vidioc_s_input = pms_s_input, + .vidioc_enum_input = pms_enum_input, + .vidioc_g_std = pms_g_std, + .vidioc_s_std = pms_s_std, + .vidioc_queryctrl = pms_queryctrl, + .vidioc_g_ctrl = pms_g_ctrl, + .vidioc_s_ctrl = pms_s_ctrl, + .vidioc_enum_fmt_vid_cap = pms_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = pms_g_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = pms_s_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = pms_try_fmt_vid_cap, +}; /* * Probe for and initialise the Mediavision PMS @@ -1032,11 +1125,18 @@ static int __init pms_init(void) strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); dev->vdev.v4l2_dev = v4l2_dev; dev->vdev.fops = &pms_fops; + dev->vdev.ioctl_ops = &pms_ioctl_ops; dev->vdev.release = video_device_release_empty; video_set_drvdata(&dev->vdev, dev); mutex_init(&dev->lock); + dev->std = V4L2_STD_NTSC_M; dev->height = 240; dev->width = 320; + dev->depth = 15; + dev->brightness = 139; + dev->contrast = 70; + dev->hue = 0; + dev->saturation = 64; pms_swsense(dev, 75); pms_resolution(dev, 320, 240); pms_videosource(dev, 0); -- cgit v1.2.3-70-g09d2 From 516e24d78feb4dded16df0053bd0e7c7f68fafa2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 25 Nov 2009 18:39:31 -0300 Subject: V4L/DVB (13521): dib8000: fix compile warning Trivial fix for this bogus compile warning: v4l/dib8000.c:958: warning: 'ncoeff' may be used uninitialized in this function Note: ncoeff is never used uninitialized, but the compiler couldn't figure that out. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/dib8000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c index 44c2dc9b4f1..898400d331a 100644 --- a/drivers/media/dvb/frontends/dib8000.c +++ b/drivers/media/dvb/frontends/dib8000.c @@ -954,7 +954,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear u8 guard, crate, constellation, timeI; u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 }; u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled - const s16 *ncoeff, *ana_fe; + const s16 *ncoeff = NULL, *ana_fe; u16 tmcc_pow = 0; u16 coff_pow = 0x2800; u16 init_prbs = 0xfff; -- cgit v1.2.3-70-g09d2 From 289a774bf53b366393e51b4f512b610bfb5fdd9d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 25 Nov 2009 18:42:42 -0300 Subject: V4L/DVB (13522): valj5jf8007s/t: fix compile warnings Trivial fix for these bogus compile warnings: v4l/va1j5jf8007s.c: In function 'va1j5jf8007s_tune': v4l/va1j5jf8007s.c:394: warning: 'lock' may be used uninitialized in this function v4l/va1j5jf8007t.c: In function 'va1j5jf8007t_tune': v4l/va1j5jf8007t.c:273: warning: 'lock' may be used uninitialized in this function v4l/va1j5jf8007t.c:273: warning: 'retry' may be used uninitialized in this function These variables are never used uninitialized, but the compiler couldn't figure that out unfortunately. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/pt1/va1j5jf8007s.c | 2 +- drivers/media/dvb/pt1/va1j5jf8007t.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.c b/drivers/media/dvb/pt1/va1j5jf8007s.c index a20927e10d7..fc6594996e7 100644 --- a/drivers/media/dvb/pt1/va1j5jf8007s.c +++ b/drivers/media/dvb/pt1/va1j5jf8007s.c @@ -391,7 +391,7 @@ va1j5jf8007s_tune(struct dvb_frontend *fe, { struct va1j5jf8007s_state *state; int ret; - int lock; + int lock = 0; state = fe->demodulator_priv; diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.c b/drivers/media/dvb/pt1/va1j5jf8007t.c index fe897343f4f..3db4f3e34e8 100644 --- a/drivers/media/dvb/pt1/va1j5jf8007t.c +++ b/drivers/media/dvb/pt1/va1j5jf8007t.c @@ -270,7 +270,7 @@ va1j5jf8007t_tune(struct dvb_frontend *fe, { struct va1j5jf8007t_state *state; int ret; - int lock, retry; + int lock = 0, retry = 0; state = fe->demodulator_priv; -- cgit v1.2.3-70-g09d2 From 491aa96a8c37260d2466735ecd3c662db8c0a7af Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 25 Nov 2009 18:48:54 -0300 Subject: V4L/DVB (13523): dvb-bt8xx: fix compile warning Fix this compile warning: v4l/dvb-bt8xx.c: In function 'cx24108_tuner_set_params': v4l/dvb-bt8xx.c:221: warning: array subscript is above array bounds Make sure that we never get past the last element in the array. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/bt8xx/dvb-bt8xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c index b1857c19bbd..78fc469f0f6 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c @@ -215,7 +215,7 @@ static int cx24108_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend freq = 2150000; /* satellite IF is 950..2150MHz */ /* decide which VCO to use for the input frequency */ - for(i = 1; (i < ARRAY_SIZE(osci)) && (osci[i] < freq); i++); + for(i = 1; (i < ARRAY_SIZE(osci) - 1) && (osci[i] < freq); i++); printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq); band=bandsel[i]; /* the gain values must be set by SetSymbolrate */ -- cgit v1.2.3-70-g09d2 From 1ca31892e3af05ad3a72769e3c922cca3cde4f9d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 27 Nov 2009 13:49:48 -0200 Subject: em28xx: em2800 chips support max width of 640 Due to hardware limitation, em2800 chips can't work at resolutions higher than 640x576, since the URB packet size is not enough. The effect is that the image looses packages and shows a distortion along the vertical axes. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index bca5cbb7931..166d4a6e6ea 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -796,7 +796,7 @@ static inline unsigned int norm_maxw(struct em28xx *dev) if (dev->board.is_webcam) return dev->sensor_xres; - if (dev->board.max_range_640_480) + if (dev->board.max_range_640_480 || dev->board.is_em2800) return 640; return 720; -- cgit v1.2.3-70-g09d2 From 0731160aca15df5882387e07d61671e6746c658f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 27 Nov 2009 13:52:54 -0200 Subject: em28xx: don't load audio modules when AC97 is mis-detected With em2800 hardware, AC97 hardware can be detected even when it doesn't exist. If, after probing for AC97, the driver won't find a companion chip, simply prevents the load of the audio modules. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 33586004eb4..3f86d36dff2 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -533,8 +533,15 @@ int em28xx_audio_setup(struct em28xx *dev) vid1 = em28xx_read_ac97(dev, AC97_VENDOR_ID1); if (vid1 < 0) { - /* Device likely doesn't support AC97 */ + /* + * Device likely doesn't support AC97 + * Note: (some) em2800 devices without eeprom reports 0x91 on + * CHIPCFG register, even not having an AC97 chip + */ em28xx_warn("AC97 chip type couldn't be determined\n"); + dev->audio_mode.ac97 = EM28XX_NO_AC97; + dev->has_alsa_audio = 0; + dev->audio_mode.has_audio = 0; goto init_audio; } -- cgit v1.2.3-70-g09d2 From fb3de0398ab1bf270bc55f66945f82e61e50f6b6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 27 Nov 2009 13:55:21 -0200 Subject: em28xx: don't reduce scale to half size for em2800 Since em2800 can't support 720x480 / 720x576, the driver used to reduce the scale to half the size on those chips. As the proper fix were applied, reducing the maximum horizontal resolution to 640, this hack can be removed. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-video.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index fbe536f092f..7ad65370f27 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -1060,12 +1060,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, /* the em2800 can only scale down to 50% */ height = height > (3 * maxh / 4) ? maxh : maxh / 2; width = width > (3 * maxw / 4) ? maxw : maxw / 2; - /* According to empiatech support the MaxPacketSize is too small - * to support framesizes larger than 640x480 @ 30 fps or 640x576 - * @ 25 fps. As this would cut of a part of the image we prefer - * 360x576 or 360x480 for now */ - if (width == maxw && height == maxh) - width /= 2; } else { /* width must even because of the YUYV format height must be even because of interlacing */ -- cgit v1.2.3-70-g09d2 From 694a101e6acb865f5405a95c358eea43c813cf24 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 26 Nov 2009 21:26:13 -0300 Subject: V4L/DVB (13528): em28xx: add support for em2800 VC211A card Adds support to VC211A em2800 card. As this board doesn't have eeprom, and uses a common set of i2c address, it has no way to add any autodetection for it. The patch were tested by me and by Raimundo on his board. Thanks to those tests, several bugs related to em2800 support were corrected. for producing the usbsnoop dump, used to get the gpio's and allowing me to remotelly access his machine and to the needed tests. Thanks-to: Raimundo Eduvirgnes de Oliveira Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.em28xx | 1 + drivers/media/video/em28xx/em28xx-cards.c | 25 +++++++++++++++++++++++++ drivers/media/video/em28xx/em28xx.h | 1 + 3 files changed, 27 insertions(+) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index f8ea8acdd89..0c166ff003a 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx @@ -69,3 +69,4 @@ 71 -> Silvercrest Webcam 1.3mpix (em2820/em2840) 72 -> Gadmei UTV330+ (em2861) 73 -> Reddo DVB-C USB TV Box (em2870) + 74 -> Actionmaster/LinXcel/Digitus VC211A (em2800) diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 00bceb865a7..ed5acc3a2b5 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -225,6 +225,14 @@ static struct em28xx_reg_seq silvercrest_reg_seq[] = { { -1, -1, -1, -1}, }; +static struct em28xx_reg_seq vc211a_enable[] = { + {EM28XX_R08_GPIO, 0xff, 0x07, 10}, + {EM28XX_R08_GPIO, 0xff, 0x0f, 10}, + {EM28XX_R08_GPIO, 0xff, 0x0b, 10}, + { -1, -1, -1, -1}, +}; + + /* * Board definitions */ @@ -1009,6 +1017,23 @@ struct em28xx_board em28xx_boards[] = { .amux = EM28XX_AMUX_LINE_IN, } }, }, + [EM2800_BOARD_VC211A] = { + .name = "Actionmaster/LinXcel/Digitus VC211A", + .is_em2800 = 1, + .tuner_type = TUNER_ABSENT, /* Capture-only board */ + .decoder = EM28XX_SAA711X, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = EM28XX_AMUX_LINE_IN, + .gpio = vc211a_enable, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = EM28XX_AMUX_LINE_IN, + .gpio = vc211a_enable, + } }, + }, [EM2800_BOARD_LEADTEK_WINFAST_USBII] = { .name = "Leadtek Winfast USB II", .is_em2800 = 1, diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 166d4a6e6ea..441df644ddb 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -110,6 +110,7 @@ #define EM2820_BOARD_SILVERCREST_WEBCAM 71 #define EM2861_BOARD_GADMEI_UTV330PLUS 72 #define EM2870_BOARD_REDDO_DVB_C_USB_BOX 73 +#define EM2800_BOARD_VC211A 74 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v1.2.3-70-g09d2 From 4e89217b943cfb26f88f04920d44f2077931f0e7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 27 Nov 2009 21:54:41 -0300 Subject: V4L/DVB (13531): ir-common: rename the debug routine to allow exporting it As newer IR common code will be added on other files, we need a global debug var inside the module. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-functions.c | 23 ++++++++++------------- include/media/ir-common.h | 4 ++++ 2 files changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c index fc2d8941459..b111a0d9409 100644 --- a/drivers/media/common/ir-functions.c +++ b/drivers/media/common/ir-functions.c @@ -34,11 +34,8 @@ static int repeat = 1; module_param(repeat, int, 0444); MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)"); -static int debug; /* debug level (0,1,2) */ -module_param(debug, int, 0644); - -#define dprintk(level, fmt, arg...) if (debug >= level) \ - printk(KERN_DEBUG fmt , ## arg) +int media_ir_debug; /* media_ir_debug level (0,1,2) */ +module_param_named(debug, media_ir_debug, int, 0644); /* -------------------------------------------------------------------------- */ @@ -49,7 +46,7 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) dev->name,ir->ir_key,ir->ir_raw,ir->keypressed); return; } - dprintk(1,"%s: key event code=%d down=%d\n", + IR_dprintk(1,"%s: key event code=%d down=%d\n", dev->name,ir->keycode,ir->keypressed); input_report_key(dev,ir->keycode,ir->keypressed); input_sync(dev); @@ -295,11 +292,11 @@ u32 ir_rc5_decode(unsigned int code) rc5 |= 1; break; case 3: - dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code); + IR_dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code); return 0; } } - dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " + IR_dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " "instr=%x\n", rc5, org_code, RC5_START(rc5), RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); return rc5; @@ -331,20 +328,20 @@ void ir_rc5_timer_end(unsigned long data) /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */ if (gap < 28000) { - dprintk(1, "ir-common: spurious timer_end\n"); + IR_dprintk(1, "ir-common: spurious timer_end\n"); return; } if (ir->last_bit < 20) { /* ignore spurious codes (caused by light/other remotes) */ - dprintk(1, "ir-common: short code: %x\n", ir->code); + IR_dprintk(1, "ir-common: short code: %x\n", ir->code); } else { ir->code = (ir->code << ir->shift_by) | 1; rc5 = ir_rc5_decode(ir->code); /* two start bits? */ if (RC5_START(rc5) != ir->start) { - dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5)); + IR_dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5)); /* right address? */ } else if (RC5_ADDR(rc5) == ir->addr) { @@ -354,7 +351,7 @@ void ir_rc5_timer_end(unsigned long data) /* Good code, decide if repeat/repress */ if (toggle != RC5_TOGGLE(ir->last_rc5) || instr != RC5_INSTR(ir->last_rc5)) { - dprintk(1, "ir-common: instruction %x, toggle %x\n", instr, + IR_dprintk(1, "ir-common: instruction %x, toggle %x\n", instr, toggle); ir_input_nokey(ir->dev, &ir->ir); ir_input_keydown(ir->dev, &ir->ir, instr, @@ -377,7 +374,7 @@ void ir_rc5_timer_keyup(unsigned long data) { struct card_ir *ir = (struct card_ir *)data; - dprintk(1, "ir-common: key released\n"); + IR_dprintk(1, "ir-common: key released\n"); ir_input_nokey(ir->dev, &ir->ir); } EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup); diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 5921776929e..5964145d65e 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -27,6 +27,10 @@ #include #include +extern int media_ir_debug; /* media_ir_debug level (0,1,2) */ +#define IR_dprintk(level, fmt, arg...) if (media_ir_debug >= level) \ + printk(KERN_DEBUG fmt , ## arg) + #define IR_TYPE_RC5 1 #define IR_TYPE_PD 2 /* Pulse distance encoded IR */ #define IR_TYPE_OTHER 99 -- cgit v1.2.3-70-g09d2 From ef53a1159dfcdc1fecf5adb5b8d26803f194c09b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 27 Nov 2009 22:01:23 -0300 Subject: V4L/DVB (13532): ir-common: Add infrastructure to use a dynamic keycode table V4L drivers use an static keycode vector with 128 entries, where the scancode indexes the keycode. While this works, it limits the scancodes to have only 7 bits, not allowing for example full RC5 codes. Instead of implementing the same code on every V4L driver, provide a common infrastructure to handle the bigger tables, minimizing the changes inside each driver. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/Makefile | 2 +- drivers/media/common/ir-keytable.c | 156 +++++++++++++++++++++++++++++++++++++ include/media/ir-common.h | 12 ++- 3 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 drivers/media/common/ir-keytable.c (limited to 'drivers/media') diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile index 351b98b9b30..169b337b7c9 100644 --- a/drivers/media/common/Makefile +++ b/drivers/media/common/Makefile @@ -1,6 +1,6 @@ saa7146-objs := saa7146_i2c.o saa7146_core.o saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o -ir-common-objs := ir-functions.o ir-keymaps.o +ir-common-objs := ir-functions.o ir-keymaps.o ir-keytable.o obj-y += tuners/ obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o diff --git a/drivers/media/common/ir-keytable.c b/drivers/media/common/ir-keytable.c new file mode 100644 index 00000000000..2de7caeef43 --- /dev/null +++ b/drivers/media/common/ir-keytable.c @@ -0,0 +1,156 @@ +/* ir-register.c - handle IR scancode->keycode tables + * + * Copyright (C) 2009 by Mauro Carvalho Chehab + */ + +#include + +#include + +/** + * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table + * @dev: the struct input_dev device descriptor + * @scancode: the desired scancode + * @keycode: the keycode to be retorned. + * + * This routine is used to handle evdev EVIOCGKEY ioctl. + * If the key is not found, returns -EINVAL, otherwise, returns 0. + */ +static int ir_getkeycode(struct input_dev *dev, + int scancode, int *keycode) +{ + int i; + struct ir_scancode_table *rc_tab = input_get_drvdata(dev); + struct ir_scancode *keymap = rc_tab->scan; + + /* See if we can match the raw key code. */ + for (i = 0; i < rc_tab->size; i++) + if (keymap[i].scancode == scancode) { + *keycode = keymap[i].keycode; + return 0; + } + + /* + * If is there extra space, returns KEY_RESERVED, + * otherwise, input core won't let ir_setkeycode + * to work + */ + for (i = 0; i < rc_tab->size; i++) + if (keymap[i].keycode == KEY_RESERVED || + keymap[i].keycode == KEY_UNKNOWN) { + *keycode = KEY_RESERVED; + return 0; + } + + return -EINVAL; +} + +/** + * ir_setkeycode() - set a keycode at the evdev scancode ->keycode table + * @dev: the struct input_dev device descriptor + * @scancode: the desired scancode + * @keycode: the keycode to be retorned. + * + * This routine is used to handle evdev EVIOCSKEY ioctl. + * There's one caveat here: how can we increase the size of the table? + * If the key is not found, returns -EINVAL, otherwise, returns 0. + */ +static int ir_setkeycode(struct input_dev *dev, + int scancode, int keycode) +{ + int i; + struct ir_scancode_table *rc_tab = input_get_drvdata(dev); + struct ir_scancode *keymap = rc_tab->scan; + + /* Search if it is replacing an existing keycode */ + for (i = 0; i < rc_tab->size; i++) + if (keymap[i].scancode == scancode) { + keymap[i].keycode = keycode; + return 0; + } + + /* Search if is there a clean entry. If so, use it */ + for (i = 0; i < rc_tab->size; i++) + if (keymap[i].keycode == KEY_RESERVED || + keymap[i].keycode == KEY_UNKNOWN) { + keymap[i].scancode = scancode; + keymap[i].keycode = keycode; + return 0; + } + + /* + * FIXME: Currently, it is not possible to increase the size of + * scancode table. For it to happen, one possibility + * would be to allocate a table with key_map_size + 1, + * copying data, appending the new key on it, and freeing + * the old one - or maybe just allocating some spare space + */ + + return -EINVAL; +} + +/** + * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode + * @rc_tab: the ir_scancode_table with the keymap to be used + * @scancode: the scancode that we're seeking + * + * This routine is used by the input routines when a key is pressed at the + * IR. The scancode is received and needs to be converted into a keycode. + * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the + * corresponding keycode from the table. + */ +u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) +{ + int i; + struct ir_scancode_table *rc_tab = input_get_drvdata(dev); + struct ir_scancode *keymap = rc_tab->scan; + + for (i = 0; i < rc_tab->size; i++) + if (keymap[i].scancode == scancode) { + IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", + dev->name, scancode, keymap[i].keycode); + + return keymap[i].keycode; + } + + printk(KERN_INFO "%s: unknown key for scancode 0x%04x\n", + dev->name, scancode); + + return KEY_UNKNOWN; +} +EXPORT_SYMBOL_GPL(ir_g_keycode_from_table); + +/** + * ir_set_keycode_table() - sets the IR keycode table and add the handlers + * for keymap table get/set + * @input_dev: the struct input_dev descriptor of the device + * @rc_tab: the struct ir_scancode_table table of scancode/keymap + * + * This routine is used to initialize the input infrastructure to work with + * an IR. It requires that the caller initializes the input_dev struct with + * some fields: name, + */ +int ir_set_keycode_table(struct input_dev *input_dev, + struct ir_scancode_table *rc_tab) +{ + struct ir_scancode *keymap = rc_tab->scan; + int i; + + if (rc_tab->scan == NULL || !rc_tab->size) + return -EINVAL; + + /* set the bits for the keys */ + IR_dprintk(1, "key map size: %d\n", rc_tab->size); + for (i = 0; i < rc_tab->size; i++) { + IR_dprintk(1, "#%d: setting bit for keycode 0x%04x\n", + i, keymap[i].keycode); + set_bit(keymap[i].keycode, input_dev->keybit); + } + + input_dev->getkeycode = ir_getkeycode; + input_dev->setkeycode = ir_setkeycode; + input_set_drvdata(input_dev, rc_tab); + + return 0; +} +EXPORT_SYMBOL_GPL(ir_set_keycode_table); diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 5964145d65e..805f1e09770 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -106,6 +106,8 @@ struct card_ir { struct tasklet_struct tlet; }; +/* Routines from ir-functions.c */ + void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, int ir_type, struct ir_scancode_table *ir_codes); void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir); @@ -120,7 +122,15 @@ u32 ir_rc5_decode(unsigned int code); void ir_rc5_timer_end(unsigned long data); void ir_rc5_timer_keyup(unsigned long data); -/* Keymaps to be used by other modules */ +/* Routines from ir-keytable.c */ + +u32 ir_g_keycode_from_table(struct input_dev *input_dev, + u32 scancode); + +int ir_set_keycode_table(struct input_dev *input_dev, + struct ir_scancode_table *rc_tab); + +/* scancode->keycode map tables from ir-keymaps.c */ extern struct ir_scancode_table ir_codes_empty_table; extern struct ir_scancode_table ir_codes_avermedia_table; -- cgit v1.2.3-70-g09d2 From 8573b74af25c279de3e309beddcba984bee9ec15 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 27 Nov 2009 22:40:22 -0300 Subject: V4L/DVB (13533): ir: use dynamic tables, instead of static ones Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-functions.c | 32 ++++++----------------------- drivers/media/common/ir-keytable.c | 2 -- drivers/media/dvb/dm1105/dm1105.c | 2 +- drivers/media/dvb/ttpci/budget-ci.c | 2 +- drivers/media/video/bt8xx/bttv-input.c | 8 ++++---- drivers/media/video/cx231xx/cx231xx-input.c | 3 +-- drivers/media/video/cx23885/cx23885-input.c | 3 +-- drivers/media/video/cx88/cx88-input.c | 14 ++++++------- drivers/media/video/em28xx/em28xx-input.c | 3 +-- drivers/media/video/ir-kbd-i2c.c | 2 +- drivers/media/video/saa7134/saa7134-input.c | 8 ++++---- include/media/ir-common.h | 5 ++--- 12 files changed, 29 insertions(+), 55 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c index b111a0d9409..29885c2893d 100644 --- a/drivers/media/common/ir-functions.c +++ b/drivers/media/common/ir-functions.c @@ -42,8 +42,8 @@ module_param_named(debug, media_ir_debug, int, 0644); static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) { if (KEY_RESERVED == ir->keycode) { - printk(KERN_INFO "%s: unknown key: key=0x%02x raw=0x%02x down=%d\n", - dev->name,ir->ir_key,ir->ir_raw,ir->keypressed); + printk(KERN_INFO "%s: unknown key: key=0x%02x down=%d\n", + dev->name, ir->ir_key, ir->keypressed); return; } IR_dprintk(1,"%s: key event code=%d down=%d\n", @@ -57,28 +57,10 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, int ir_type, struct ir_scancode_table *ir_codes) { - int i; - ir->ir_type = ir_type; - memset(ir->ir_codes, 0, sizeof(ir->ir_codes)); - - /* - * FIXME: This is a temporary workaround to use the new IR tables - * with the old approach. Later patches will replace this to a - * proper method - */ - - if (ir_codes) - for (i = 0; i < ir_codes->size; i++) - if (ir_codes->scan[i].scancode < IR_KEYTAB_SIZE) - ir->ir_codes[ir_codes->scan[i].scancode] = ir_codes->scan[i].keycode; + ir_set_keycode_table(dev, ir_codes); - dev->keycode = ir->ir_codes; - dev->keycodesize = sizeof(IR_KEYTAB_TYPE); - dev->keycodemax = IR_KEYTAB_SIZE; - for (i = 0; i < IR_KEYTAB_SIZE; i++) - set_bit(ir->ir_codes[i], dev->keybit); clear_bit(0, dev->keybit); set_bit(EV_KEY, dev->evbit); @@ -97,9 +79,9 @@ void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir) EXPORT_SYMBOL_GPL(ir_input_nokey); void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, - u32 ir_key, u32 ir_raw) + u32 ir_key) { - u32 keycode = IR_KEYCODE(ir->ir_codes, ir_key); + u32 keycode = ir_g_keycode_from_table(dev, ir_key); if (ir->keypressed && ir->keycode != keycode) { ir->keypressed = 0; @@ -107,7 +89,6 @@ void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, } if (!ir->keypressed) { ir->ir_key = ir_key; - ir->ir_raw = ir_raw; ir->keycode = keycode; ir->keypressed = 1; ir_input_key_event(dev,ir); @@ -354,8 +335,7 @@ void ir_rc5_timer_end(unsigned long data) IR_dprintk(1, "ir-common: instruction %x, toggle %x\n", instr, toggle); ir_input_nokey(ir->dev, &ir->ir); - ir_input_keydown(ir->dev, &ir->ir, instr, - instr); + ir_input_keydown(ir->dev, &ir->ir, instr); } /* Set/reset key-up timer */ diff --git a/drivers/media/common/ir-keytable.c b/drivers/media/common/ir-keytable.c index 2de7caeef43..65e352389b2 100644 --- a/drivers/media/common/ir-keytable.c +++ b/drivers/media/common/ir-keytable.c @@ -118,7 +118,6 @@ u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) return KEY_UNKNOWN; } -EXPORT_SYMBOL_GPL(ir_g_keycode_from_table); /** * ir_set_keycode_table() - sets the IR keycode table and add the handlers @@ -153,4 +152,3 @@ int ir_set_keycode_table(struct input_dev *input_dev, return 0; } -EXPORT_SYMBOL_GPL(ir_set_keycode_table); diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index 2d099e27175..4c28632f94c 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/drivers/media/dvb/dm1105/dm1105.c @@ -510,7 +510,7 @@ static void dm1105_emit_key(struct work_struct *work) data = (ircom >> 8) & 0x7f; - ir_input_keydown(ir->input_dev, &ir->ir, data, data); + ir_input_keydown(ir->input_dev, &ir->ir, data); ir_input_nokey(ir->input_dev, &ir->ir); } diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 88a0a5670cc..adc4b954e5a 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -178,7 +178,7 @@ static void msp430_ir_interrupt(unsigned long data) if (budget_ci->ir.last_raw != raw || !timer_pending(&budget_ci->ir.timer_keyup)) { ir_input_nokey(dev, &budget_ci->ir.state); ir_input_keydown(dev, &budget_ci->ir.state, - budget_ci->ir.ir_key, raw); + budget_ci->ir.ir_key); budget_ci->ir.last_raw = raw; } diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c index ebd51afe876..62408ccf34c 100644 --- a/drivers/media/video/bt8xx/bttv-input.c +++ b/drivers/media/video/bt8xx/bttv-input.c @@ -73,12 +73,12 @@ static void ir_handle_key(struct bttv *btv) if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { - ir_input_keydown(ir->dev,&ir->ir,data,data); + ir_input_keydown(ir->dev, &ir->ir, data); } else { /* HACK: Probably, ir->mask_keydown is missing for this board */ if (btv->c.type == BTTV_BOARD_WINFAST2000) - ir_input_keydown(ir->dev, &ir->ir, data, data); + ir_input_keydown(ir->dev, &ir->ir, data); ir_input_nokey(ir->dev,&ir->ir); } @@ -104,7 +104,7 @@ static void ir_enltv_handle_key(struct bttv *btv) gpio, data, (gpio & ir->mask_keyup) ? " up" : "up/down"); - ir_input_keydown(ir->dev, &ir->ir, data, data); + ir_input_keydown(ir->dev, &ir->ir, data); if (keyup) ir_input_nokey(ir->dev, &ir->ir); } else { @@ -118,7 +118,7 @@ static void ir_enltv_handle_key(struct bttv *btv) if (keyup) ir_input_nokey(ir->dev, &ir->ir); else - ir_input_keydown(ir->dev, &ir->ir, data, data); + ir_input_keydown(ir->dev, &ir->ir, data); } ir->last_gpio = data | keyup; diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c index 48f22fa38e6..58dd39bc678 100644 --- a/drivers/media/video/cx231xx/cx231xx-input.c +++ b/drivers/media/video/cx231xx/cx231xx-input.c @@ -126,8 +126,7 @@ static void cx231xx_ir_handle_key(struct cx231xx_IR *ir) if (do_sendkey) { dprintk("sending keypress\n"); - ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0], - poll_result.rc_data[0]); + ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0]); ir_input_nokey(ir->input, &ir->ir); } diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c index f000ed787d4..fea882d1fbc 100644 --- a/drivers/media/video/cx23885/cx23885-input.c +++ b/drivers/media/video/cx23885/cx23885-input.c @@ -94,8 +94,7 @@ static void cx23885_input_process_raw_rc5(struct cx23885_dev *dev) RC5_START(ir_input->last_rc5) == 0) { /* This keypress is differnet: not an auto repeat */ ir_input_nokey(ir_input->dev, &ir_input->ir); - ir_input_keydown(ir_input->dev, &ir_input->ir, - command, ir_input->code); + ir_input_keydown(ir_input->dev, &ir_input->ir, command); } ir_input->last_rc5 = rc5; diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index 47c03019357..7b2066415d7 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c @@ -118,13 +118,13 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) data = (data << 4) | ((gpio_key & 0xf0) >> 4); - ir_input_keydown(ir->input, &ir->ir, data, data); + ir_input_keydown(ir->input, &ir->ir, data); ir_input_nokey(ir->input, &ir->ir); } else if (ir->mask_keydown) { /* bit set on keydown */ if (gpio & ir->mask_keydown) { - ir_input_keydown(ir->input, &ir->ir, data, data); + ir_input_keydown(ir->input, &ir->ir, data); } else { ir_input_nokey(ir->input, &ir->ir); } @@ -132,14 +132,14 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) } else if (ir->mask_keyup) { /* bit cleared on keydown */ if (0 == (gpio & ir->mask_keyup)) { - ir_input_keydown(ir->input, &ir->ir, data, data); + ir_input_keydown(ir->input, &ir->ir, data); } else { ir_input_nokey(ir->input, &ir->ir); } } else { /* can't distinguish keydown/up :-/ */ - ir_input_keydown(ir->input, &ir->ir, data, data); + ir_input_keydown(ir->input, &ir->ir, data); ir_input_nokey(ir->input, &ir->ir); } } @@ -487,7 +487,7 @@ void cx88_ir_irq(struct cx88_core *core) ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0x7f); - ir_input_keydown(ir->input, &ir->ir, (ircode >> 16) & 0x7f, (ircode >> 16) & 0xff); + ir_input_keydown(ir->input, &ir->ir, (ircode >> 16) & 0x7f); ir->release = jiffies + msecs_to_jiffies(120); break; case CX88_BOARD_HAUPPAUGE: @@ -524,7 +524,7 @@ void cx88_ir_irq(struct cx88_core *core) if ( dev != 0x1e && dev != 0x1f ) /* not a hauppauge remote */ break; - ir_input_keydown(ir->input, &ir->ir, code, ircode); + ir_input_keydown(ir->input, &ir->ir, code); ir->release = jiffies + msecs_to_jiffies(120); break; case CX88_BOARD_PINNACLE_PCTV_HD_800i: @@ -532,7 +532,7 @@ void cx88_ir_irq(struct cx88_core *core) ir_dprintk("biphase decoded: %x\n", ircode); if ((ircode & 0xfffff000) != 0x3000) break; - ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f, ircode); + ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f); ir->release = jiffies + msecs_to_jiffies(120); break; } diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index 7a0fe3816e3..990ee04bbd5 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c @@ -282,8 +282,7 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir) if (do_sendkey) { dprintk("sending keypress\n"); - ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0], - poll_result.rc_data[0]); + ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0]); ir_input_nokey(ir->input, &ir->ir); } diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index aec36660987..9c6d0ae58b1 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -275,7 +275,7 @@ static void ir_key_poll(struct IR_i2c *ir) if (0 == rc) { ir_input_nokey(ir->input, &ir->ir); } else { - ir_input_keydown(ir->input, &ir->ir, ir_key, ir_raw); + ir_input_keydown(ir->input, &ir->ir, ir_key); } } diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index f658f251399..439f3d54d00 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -102,14 +102,14 @@ static int build_key(struct saa7134_dev *dev) if (data == ir->mask_keycode) ir_input_nokey(ir->dev, &ir->ir); else - ir_input_keydown(ir->dev, &ir->ir, data, data); + ir_input_keydown(ir->dev, &ir->ir, data); return 0; } if (ir->polling) { if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { - ir_input_keydown(ir->dev, &ir->ir, data, data); + ir_input_keydown(ir->dev, &ir->ir, data); } else { ir_input_nokey(ir->dev, &ir->ir); } @@ -117,7 +117,7 @@ static int build_key(struct saa7134_dev *dev) else { /* IRQ driven mode - handle key press and release in one go */ if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { - ir_input_keydown(ir->dev, &ir->ir, data, data); + ir_input_keydown(ir->dev, &ir->ir, data); ir_input_nokey(ir->dev, &ir->ir); } } @@ -938,7 +938,7 @@ static void nec_task(unsigned long data) dprintk("scancode = 0x%02x (code = 0x%02x, notcode= 0x%02x)\n", ir->code, ircode, not_code); - ir_input_keydown(ir->dev, &ir->ir, ir->code, ir->code); + ir_input_keydown(ir->dev, &ir->ir, ir->code); } else dprintk("Repeat last key\n"); diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 805f1e09770..262347b6150 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -62,8 +62,7 @@ struct ir_input_state { IR_KEYTAB_TYPE ir_codes[IR_KEYTAB_SIZE]; /* key info */ - u32 ir_raw; /* raw data */ - u32 ir_key; /* ir key code */ + u32 ir_key; /* ir scancode */ u32 keycode; /* linux key code */ int keypressed; /* current state */ }; @@ -112,7 +111,7 @@ void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, int ir_type, struct ir_scancode_table *ir_codes); void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir); void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, - u32 ir_key, u32 ir_raw); + u32 ir_key); u32 ir_extract_bits(u32 data, u32 mask); int ir_dump_samples(u32 *samples, int count); int ir_decode_biphase(u32 *samples, int count, int low, int high); -- cgit v1.2.3-70-g09d2 From 35d1988c6e19db3d4240e2a60c71b3a13abf0781 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 27 Nov 2009 23:25:13 -0300 Subject: V4L/DVB (13535): ir-common: Add a hauppauge new table with the complete RC5 code Now that V4L drivers can support more than 7 bits for scan code, let's add a modified version for the Hauppauge Grey IR containing the full IR scancode. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-keymaps.c | 71 +++++++++++++++++++++++++++++++++++++++ include/media/ir-common.h | 1 + 2 files changed, 72 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c index e353dffe696..328c973a083 100644 --- a/drivers/media/common/ir-keymaps.c +++ b/drivers/media/common/ir-keymaps.c @@ -1847,6 +1847,76 @@ struct ir_scancode_table ir_codes_hauppauge_new_table = { }; EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table); +/* + * Hauppauge:the newer, gray remotes (seems there are multiple + * slightly different versions), shipped with cx88+ivtv cards. + * + * This table contains the complete RC5 code, instead of just the data part + */ +static struct ir_scancode ir_codes_rc5_hauppauge_new[] = { + /* Keys 0 to 9 */ + { 0x1e00, KEY_0 }, + { 0x1e01, KEY_1 }, + { 0x1e02, KEY_2 }, + { 0x1e03, KEY_3 }, + { 0x1e04, KEY_4 }, + { 0x1e05, KEY_5 }, + { 0x1e06, KEY_6 }, + { 0x1e07, KEY_7 }, + { 0x1e08, KEY_8 }, + { 0x1e09, KEY_9 }, + + { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */ + { 0x1e0b, KEY_RED }, /* red button */ + { 0x1e0c, KEY_RADIO }, + { 0x1e0d, KEY_MENU }, + { 0x1e0e, KEY_SUBTITLE }, /* also the # key */ + { 0x1e0f, KEY_MUTE }, + { 0x1e10, KEY_VOLUMEUP }, + { 0x1e11, KEY_VOLUMEDOWN }, + { 0x1e12, KEY_PREVIOUS }, /* previous channel */ + { 0x1e14, KEY_UP }, + { 0x1e15, KEY_DOWN }, + { 0x1e16, KEY_LEFT }, + { 0x1e17, KEY_RIGHT }, + { 0x1e18, KEY_VIDEO }, /* Videos */ + { 0x1e19, KEY_AUDIO }, /* Music */ + /* 0x1e1a: Pictures - presume this means + "Multimedia Home Platform" - + no "PICTURES" key in input.h + */ + { 0x1e1a, KEY_MHP }, + + { 0x1e1b, KEY_EPG }, /* Guide */ + { 0x1e1c, KEY_TV }, + { 0x1e1e, KEY_NEXTSONG }, /* skip >| */ + { 0x1e1f, KEY_EXIT }, /* back/exit */ + { 0x1e20, KEY_CHANNELUP }, /* channel / program + */ + { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */ + { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */ + { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */ + { 0x1e25, KEY_ENTER }, /* OK */ + { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */ + { 0x1e29, KEY_BLUE }, /* blue key */ + { 0x1e2e, KEY_GREEN }, /* green button */ + { 0x1e30, KEY_PAUSE }, /* pause */ + { 0x1e32, KEY_REWIND }, /* backward << */ + { 0x1e34, KEY_FASTFORWARD }, /* forward >> */ + { 0x1e35, KEY_PLAY }, + { 0x1e36, KEY_STOP }, + { 0x1e37, KEY_RECORD }, /* recording */ + { 0x1e38, KEY_YELLOW }, /* yellow key */ + { 0x1e3b, KEY_SELECT }, /* top right button */ + { 0x1e3c, KEY_ZOOM }, /* full */ + { 0x1e3d, KEY_POWER }, /* system power (green button) */ +}; + +struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = { + .scan = ir_codes_rc5_hauppauge_new, + .size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new), +}; +EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table); + static struct ir_scancode ir_codes_npgtech[] = { { 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */ { 0x2a, KEY_FRONT }, @@ -3243,3 +3313,4 @@ struct ir_scancode_table ir_codes_gadmei_rm008z_table = { .size = ARRAY_SIZE(ir_codes_gadmei_rm008z), }; EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table); + diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 1a619a4ec5c..cd21cb55d5d 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -157,6 +157,7 @@ extern struct ir_scancode_table ir_codes_rc5_tv_table; extern struct ir_scancode_table ir_codes_winfast_table; extern struct ir_scancode_table ir_codes_pinnacle_color_table; extern struct ir_scancode_table ir_codes_hauppauge_new_table; +extern struct ir_scancode_table ir_codes_rc5_hauppauge_new_table; extern struct ir_scancode_table ir_codes_npgtech_table; extern struct ir_scancode_table ir_codes_norwood_table; extern struct ir_scancode_table ir_codes_proteus_2309_table; -- cgit v1.2.3-70-g09d2 From 0278155c84af42d78785731263b69fb49f945ea7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 27 Nov 2009 23:28:40 -0300 Subject: V4L/DVB (13536): em28xx: Use the full RC5 code on HVR-950 Remote Controller Modifies the IR table for HVR-950 to use the newer Hauppauge RC5 table, and adds the RC5 address to the functions that get the scancode for this device. It is easy to add support for all other RC5 IR's on em2880 boards, but the scancode table needs to be re-generated. So, keep using the old 7bits tables while we don't have all tables converted. Also, the 7bits tables are still used on other drivers, so this small patch needs to be ported to all drivers. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-cards.c | 2 +- drivers/media/video/em28xx/em28xx-input.c | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index ed5acc3a2b5..82da205047b 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -837,7 +837,7 @@ struct em28xx_board em28xx_boards[] = { .mts_firmware = 1, .has_dvb = 1, .dvb_gpio = hauppauge_wintv_hvr_900_digital, - .ir_codes = &ir_codes_hauppauge_new_table, + .ir_codes = &ir_codes_rc5_hauppauge_new_table, .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index 990ee04bbd5..5550de9c669 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c @@ -70,6 +70,7 @@ struct em28xx_IR { int polling; struct delayed_work work; unsigned int last_toggle:1; + unsigned int full_code:1; unsigned int last_readcount; unsigned int repeat_interval; @@ -246,9 +247,10 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir) return; } - dprintk("ir->get_key result tb=%02x rc=%02x lr=%02x data=%02x\n", + dprintk("ir->get_key result tb=%02x rc=%02x lr=%02x data=%02x%02x\n", poll_result.toggle_bit, poll_result.read_count, - ir->last_readcount, poll_result.rc_data[0]); + ir->last_readcount, poll_result.rc_address, + poll_result.rc_data[0]); if (ir->dev->chip_id == CHIP_ID_EM2874) { /* The em2874 clears the readcount field every time the @@ -282,7 +284,15 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir) if (do_sendkey) { dprintk("sending keypress\n"); - ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0]); + + if (ir->full_code) + ir_input_keydown(ir->input, &ir->ir, + poll_result.rc_address << 8 | + poll_result.rc_data[0]); + else + ir_input_keydown(ir->input, &ir->ir, + poll_result.rc_data[0]); + ir_input_nokey(ir->input, &ir->ir); } @@ -332,6 +342,8 @@ int em28xx_ir_init(struct em28xx *dev) switch (dev->chip_id) { case CHIP_ID_EM2860: case CHIP_ID_EM2883: + if (dev->model == EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950) + ir->full_code = 1; ir->get_key = default_polling_getkey; break; case CHIP_ID_EM2874: -- cgit v1.2.3-70-g09d2 From 055cd55601f948675006ca90362fc2bfaae90a86 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 29 Nov 2009 08:19:59 -0300 Subject: V4L/DVB (13537): ir: Prepare the code for dynamic keycode table allocation Currently, the IR table is initialized by calling ir_input_init(). However, this function doesn't return any error code, nor has a function to be called when de-initializing the IR's. Change the return argment to integer and make sure that each driver will handle the error code. Also adds a function to free any resources that may be allocating there: ir_input_free(). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-functions.c | 12 +++++++++++- drivers/media/dvb/dm1105/dm1105.c | 10 ++++++++-- drivers/media/dvb/ttpci/budget-ci.c | 14 +++++++++++--- drivers/media/video/bt8xx/bttv-input.c | 7 ++++++- drivers/media/video/cx231xx/cx231xx-input.c | 8 +++++++- drivers/media/video/cx23885/cx23885-input.c | 7 ++++++- drivers/media/video/cx88/cx88-input.c | 7 ++++++- drivers/media/video/em28xx/em28xx-input.c | 8 +++++++- drivers/media/video/ir-kbd-i2c.c | 7 ++++++- drivers/media/video/saa7134/saa7134-input.c | 7 ++++++- include/media/ir-common.h | 3 ++- 11 files changed, 76 insertions(+), 14 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c index 29885c2893d..b31bd27da37 100644 --- a/drivers/media/common/ir-functions.c +++ b/drivers/media/common/ir-functions.c @@ -54,11 +54,13 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) /* -------------------------------------------------------------------------- */ -void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, +int ir_input_init(struct input_dev *dev, struct ir_input_state *ir, int ir_type, struct ir_scancode_table *ir_codes) { ir->ir_type = ir_type; + /* FIXME: Add the proper code to dynamically allocate IR table */ + ir_set_keycode_table(dev, ir_codes); clear_bit(0, dev->keybit); @@ -66,9 +68,17 @@ void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, set_bit(EV_KEY, dev->evbit); if (repeat) set_bit(EV_REP, dev->evbit); + + return 0; } EXPORT_SYMBOL_GPL(ir_input_init); +void ir_input_free(struct input_dev *input_dev) +{ + /* FIXME: Add the proper code to free allocated resources */ +} +EXPORT_SYMBOL_GPL(ir_input_free); + void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir) { if (ir->keypressed) { diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index 4c28632f94c..53e3f2a7d31 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/drivers/media/dvb/dm1105/dm1105.c @@ -589,7 +589,12 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys), "pci-%s/ir0", pci_name(dm1105->pdev)); - ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes); + err = ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes); + if (err < 0) { + input_free_device(input_dev); + return err; + } + input_dev->name = "DVB on-card IR receiver"; input_dev->phys = dm1105->ir.input_phys; input_dev->id.bustype = BUS_PCI; @@ -608,6 +613,7 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) err = input_register_device(input_dev); if (err) { + ir_input_free(input_dev); input_free_device(input_dev); return err; } @@ -617,8 +623,8 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105) { + ir_input_free(dm1105->ir.input_dev); input_unregister_device(dm1105->ir.input_dev); - } static int __devinit dm1105dvb_hw_init(struct dm1105dvb *dm1105dvb) diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index adc4b954e5a..7d193ebc0ae 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -224,8 +224,10 @@ static int msp430_ir_init(struct budget_ci *budget_ci) case 0x1011: case 0x1012: /* The hauppauge keymap is a superset of these remotes */ - ir_input_init(input_dev, &budget_ci->ir.state, + error = ir_input_init(input_dev, &budget_ci->ir.state, IR_TYPE_RC5, &ir_codes_hauppauge_new_table); + if (error < 0) + goto out2; if (rc5_device < 0) budget_ci->ir.rc5_device = 0x1f; @@ -236,8 +238,10 @@ static int msp430_ir_init(struct budget_ci *budget_ci) case 0x1017: case 0x101a: /* for the Technotrend 1500 bundled remote */ - ir_input_init(input_dev, &budget_ci->ir.state, + error = ir_input_init(input_dev, &budget_ci->ir.state, IR_TYPE_RC5, &ir_codes_tt_1500_table); + if (error < 0) + goto out2; if (rc5_device < 0) budget_ci->ir.rc5_device = IR_DEVICE_ANY; @@ -246,8 +250,10 @@ static int msp430_ir_init(struct budget_ci *budget_ci) break; default: /* unknown remote */ - ir_input_init(input_dev, &budget_ci->ir.state, + error = ir_input_init(input_dev, &budget_ci->ir.state, IR_TYPE_RC5, &ir_codes_budget_ci_old_table); + if (error < 0) + goto out2; if (rc5_device < 0) budget_ci->ir.rc5_device = IR_DEVICE_ANY; @@ -280,6 +286,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci) return 0; out2: + ir_input_free(input_dev); input_free_device(input_dev); out1: return error; @@ -297,6 +304,7 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci) del_timer_sync(&dev->timer); ir_input_nokey(dev, &budget_ci->ir.state); + ir_input_free(dev); input_unregister_device(dev); } diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c index 62408ccf34c..84a957e52c4 100644 --- a/drivers/media/video/bt8xx/bttv-input.c +++ b/drivers/media/video/bt8xx/bttv-input.c @@ -368,7 +368,10 @@ int bttv_input_init(struct bttv *btv) snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(btv->c.pci)); - ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); + err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); + if (err < 0) + goto err_out_free; + input_dev->name = ir->name; input_dev->phys = ir->phys; input_dev->id.bustype = BUS_PCI; @@ -400,6 +403,7 @@ int bttv_input_init(struct bttv *btv) bttv_ir_stop(btv); btv->remote = NULL; err_out_free: + ir_input_free(input_dev); input_free_device(input_dev); kfree(ir); return err; @@ -411,6 +415,7 @@ void bttv_input_fini(struct bttv *btv) return; bttv_ir_stop(btv); + ir_input_free(btv->remote->dev); input_unregister_device(btv->remote->dev); kfree(btv->remote); btv->remote = NULL; diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c index 58dd39bc678..cd135f01b9c 100644 --- a/drivers/media/video/cx231xx/cx231xx-input.c +++ b/drivers/media/video/cx231xx/cx231xx-input.c @@ -197,7 +197,11 @@ int cx231xx_ir_init(struct cx231xx *dev) usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); strlcat(ir->phys, "/input0", sizeof(ir->phys)); - ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER, dev->board.ir_codes); + err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER, + dev->board.ir_codes); + if (err < 0) + goto err_out_free; + input_dev->name = ir->name; input_dev->phys = ir->phys; input_dev->id.bustype = BUS_USB; @@ -222,6 +226,7 @@ err_out_stop: cx231xx_ir_stop(ir); dev->ir = NULL; err_out_free: + ir_input_free(input_dev); input_free_device(input_dev); kfree(ir); return err; @@ -236,6 +241,7 @@ int cx231xx_ir_fini(struct cx231xx *dev) return 0; cx231xx_ir_stop(ir); + ir_input_free(ir->input); input_unregister_device(ir->input); kfree(ir); diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c index fea882d1fbc..469e083dd5f 100644 --- a/drivers/media/video/cx23885/cx23885-input.c +++ b/drivers/media/video/cx23885/cx23885-input.c @@ -377,7 +377,10 @@ int cx23885_input_init(struct cx23885_dev *dev) cx23885_boards[dev->board].name); snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(dev->pci)); - ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); + ret = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); + if (ret < 0) + goto err_out_free; + input_dev->name = ir->name; input_dev->phys = ir->phys; input_dev->id.bustype = BUS_PCI; @@ -404,6 +407,7 @@ err_out_stop: cx23885_input_ir_stop(dev); dev->ir_input = NULL; err_out_free: + ir_input_free(input_dev); input_free_device(input_dev); kfree(ir); return ret; @@ -416,6 +420,7 @@ void cx23885_input_fini(struct cx23885_dev *dev) if (dev->ir_input == NULL) return; + ir_input_free(dev->ir_input->dev); input_unregister_device(dev->ir_input->dev); kfree(dev->ir_input); dev->ir_input = NULL; diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index 7b2066415d7..92b8cdf9fb8 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c @@ -360,7 +360,10 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name); snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci)); - ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); + err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); + if (err < 0) + goto err_out_free; + input_dev->name = ir->name; input_dev->phys = ir->phys; input_dev->id.bustype = BUS_PCI; @@ -390,6 +393,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) cx88_ir_stop(core, ir); core->ir = NULL; err_out_free: + ir_input_free(input_dev); input_free_device(input_dev); kfree(ir); return err; @@ -404,6 +408,7 @@ int cx88_ir_fini(struct cx88_core *core) return 0; cx88_ir_stop(core, ir); + ir_input_free(ir->input); input_unregister_device(ir->input); kfree(ir); diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index 5550de9c669..d96ec7c09dc 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c @@ -367,7 +367,11 @@ int em28xx_ir_init(struct em28xx *dev) usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); strlcat(ir->phys, "/input0", sizeof(ir->phys)); - ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER, dev->board.ir_codes); + err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER, + dev->board.ir_codes); + if (err < 0) + goto err_out_free; + input_dev->name = ir->name; input_dev->phys = ir->phys; input_dev->id.bustype = BUS_USB; @@ -392,6 +396,7 @@ int em28xx_ir_init(struct em28xx *dev) em28xx_ir_stop(ir); dev->ir = NULL; err_out_free: + ir_input_free(input_dev); input_free_device(input_dev); kfree(ir); return err; @@ -406,6 +411,7 @@ int em28xx_ir_fini(struct em28xx *dev) return 0; em28xx_ir_stop(ir); + ir_input_free(ir->input); input_unregister_device(ir->input); kfree(ir); diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 9c6d0ae58b1..64360d26b32 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -437,7 +437,10 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) dev_name(&client->dev)); /* init + register input device */ - ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes); + err = ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes); + if (err < 0) + goto err_out_free; + input_dev->id.bustype = BUS_I2C; input_dev->name = ir->name; input_dev->phys = ir->phys; @@ -456,6 +459,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) return 0; err_out_free: + ir_input_free(input_dev); input_free_device(input_dev); kfree(ir); return err; @@ -469,6 +473,7 @@ static int ir_remove(struct i2c_client *client) cancel_delayed_work_sync(&ir->work); /* unregister device */ + ir_input_free(ir->input); input_unregister_device(ir->input); /* free memory */ diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 439f3d54d00..744918b1cd4 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -652,7 +652,10 @@ int saa7134_input_init1(struct saa7134_dev *dev) snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(dev->pci)); - ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); + err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); + if (err < 0) + goto err_out_free; + input_dev->name = ir->name; input_dev->phys = ir->phys; input_dev->id.bustype = BUS_PCI; @@ -683,6 +686,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) saa7134_ir_stop(dev); dev->remote = NULL; err_out_free: + ir_input_free(input_dev); input_free_device(input_dev); kfree(ir); return err; @@ -694,6 +698,7 @@ void saa7134_input_fini(struct saa7134_dev *dev) return; saa7134_ir_stop(dev); + ir_input_free(dev->remote->dev); input_unregister_device(dev->remote->dev); kfree(dev->remote); dev->remote = NULL; diff --git a/include/media/ir-common.h b/include/media/ir-common.h index cd21cb55d5d..16b8f17bcfe 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -100,7 +100,7 @@ struct card_ir { /* Routines from ir-functions.c */ -void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, +int ir_input_init(struct input_dev *dev, struct ir_input_state *ir, int ir_type, struct ir_scancode_table *ir_codes); void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir); void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, @@ -121,6 +121,7 @@ u32 ir_g_keycode_from_table(struct input_dev *input_dev, int ir_set_keycode_table(struct input_dev *input_dev, struct ir_scancode_table *rc_tab); +void ir_input_free(struct input_dev *input_dev); /* scancode->keycode map tables from ir-keymaps.c */ -- cgit v1.2.3-70-g09d2 From f6fc50494027e913ff0159e43c593cd75f35ec7a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 29 Nov 2009 11:08:02 -0300 Subject: V4L/DVB (13538): ir-common: Use a dynamic keycode table Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-functions.c | 19 ++++++---- drivers/media/common/ir-keytable.c | 75 +++++++++++++++++++++++++++++++++++++ include/media/ir-common.h | 6 +++ 3 files changed, 92 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c index b31bd27da37..e616f624cea 100644 --- a/drivers/media/common/ir-functions.c +++ b/drivers/media/common/ir-functions.c @@ -59,12 +59,20 @@ int ir_input_init(struct input_dev *dev, struct ir_input_state *ir, { ir->ir_type = ir_type; - /* FIXME: Add the proper code to dynamically allocate IR table */ + ir->keytable.size = ir_roundup_tablesize(ir_codes->size); + ir->keytable.scan = kzalloc(ir->keytable.size * + sizeof(struct ir_scancode), GFP_KERNEL); + if (!ir->keytable.scan) + return -ENOMEM; - ir_set_keycode_table(dev, ir_codes); + IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n", + ir->keytable.size, + ir->keytable.size * sizeof(ir->keytable.scan)); - clear_bit(0, dev->keybit); + ir_copy_table(&ir->keytable, ir_codes); + ir_set_keycode_table(dev, &ir->keytable); + clear_bit(0, dev->keybit); set_bit(EV_KEY, dev->evbit); if (repeat) set_bit(EV_REP, dev->evbit); @@ -73,11 +81,6 @@ int ir_input_init(struct input_dev *dev, struct ir_input_state *ir, } EXPORT_SYMBOL_GPL(ir_input_init); -void ir_input_free(struct input_dev *input_dev) -{ - /* FIXME: Add the proper code to free allocated resources */ -} -EXPORT_SYMBOL_GPL(ir_input_free); void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir) { diff --git a/drivers/media/common/ir-keytable.c b/drivers/media/common/ir-keytable.c index 65e352389b2..6e3cc78c33b 100644 --- a/drivers/media/common/ir-keytable.c +++ b/drivers/media/common/ir-keytable.c @@ -7,6 +7,68 @@ #include +#define IR_TAB_MIN_SIZE 32 + +/** + * ir_roundup_tablesize() - gets an optimum value for the table size + * @n_elems: minimum number of entries to store keycodes + * + * This routine is used to choose the keycode table size. + * + * In order to have some empty space for new keycodes, + * and knowing in advance that kmalloc allocates only power of two + * segments, it optimizes the allocated space to have some spare space + * for those new keycodes by using the maximum number of entries that + * will be effectively be allocated by kmalloc. + * In order to reduce the quantity of table resizes, it has a minimum + * table size of IR_TAB_MIN_SIZE. + */ +int ir_roundup_tablesize(int n_elems) +{ + size_t size; + + if (n_elems < IR_TAB_MIN_SIZE) + n_elems = IR_TAB_MIN_SIZE; + + /* + * As kmalloc only allocates sizes of power of two, get as + * much entries as possible for the allocated memory segment + */ + size = roundup_pow_of_two(n_elems * sizeof(struct ir_scancode)); + n_elems = size / sizeof(struct ir_scancode); + + return n_elems; +} + +/** + * ir_copy_table() - copies a keytable, discarding the unused entries + * @destin: destin table + * @origin: origin table + * + * Copies all entries where the keycode is not KEY_UNKNOWN/KEY_RESERVED + */ + +int ir_copy_table(struct ir_scancode_table *destin, + const struct ir_scancode_table *origin) +{ + int i, j = 0; + + for (i = 0; i < origin->size; i++) { + if (origin->scan[i].keycode != KEY_UNKNOWN && + origin->scan[i].keycode != KEY_RESERVED) { + memcpy(&destin->scan[j], &origin->scan[i], + sizeof(struct ir_scancode)); + j++; + } + } + destin->size = j; + + IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", j); + + return 0; +} + + /** * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table * @dev: the struct input_dev device descriptor @@ -152,3 +214,16 @@ int ir_set_keycode_table(struct input_dev *input_dev, return 0; } + +void ir_input_free(struct input_dev *dev) +{ + struct ir_scancode_table *rc_tab = input_get_drvdata(dev); + + IR_dprintk(1, "Freed keycode table\n"); + + rc_tab->size = 0; + kfree(rc_tab->scan); + rc_tab->scan = NULL; +} +EXPORT_SYMBOL_GPL(ir_input_free); + diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 16b8f17bcfe..72df0467d2b 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -54,6 +54,8 @@ struct ir_input_state { /* configuration */ int ir_type; + struct ir_scancode_table keytable; + /* key info */ u32 ir_key; /* ir scancode */ u32 keycode; /* linux key code */ @@ -121,6 +123,10 @@ u32 ir_g_keycode_from_table(struct input_dev *input_dev, int ir_set_keycode_table(struct input_dev *input_dev, struct ir_scancode_table *rc_tab); + +int ir_roundup_tablesize(int n_elems); +int ir_copy_table(struct ir_scancode_table *destin, + const struct ir_scancode_table *origin); void ir_input_free(struct input_dev *input_dev); /* scancode->keycode map tables from ir-keymaps.c */ -- cgit v1.2.3-70-g09d2 From 7fee03e487e87a196deb5602ee3c7676511995c9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 2 Dec 2009 15:56:47 -0300 Subject: V4L/DVB (13540): ir-common: Cleanup get key evdev code The same loop to seek for a key were used on different places. Also, no spinlock were protecting it to avoid the risk of replacing a keycode while seeking for a new code. This cleanup does: - create an unique function to seek for a code; - adds an spinlock to protect the table lookup; - remove some unused code; - simplifies to code to make it easier to understand. Basically no change in behavior should be noticed after this patch. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-keytable.c | 137 ++++++++++++++++++++----------------- include/media/ir-common.h | 2 + 2 files changed, 77 insertions(+), 62 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/ir-keytable.c b/drivers/media/common/ir-keytable.c index 6e3cc78c33b..b06f023ca76 100644 --- a/drivers/media/common/ir-keytable.c +++ b/drivers/media/common/ir-keytable.c @@ -9,6 +9,38 @@ #define IR_TAB_MIN_SIZE 32 +/** + * ir_seek_table() - returns the element order on the table + * @rc_tab: the ir_scancode_table with the keymap to be used + * @scancode: the scancode that we're seeking + * + * This routine is used by the input routines when a key is pressed at the + * IR. The scancode is received and needs to be converted into a keycode. + * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the + * corresponding keycode from the table. + */ +static int ir_seek_table(struct ir_scancode_table *rc_tab, u32 scancode) +{ + int rc; + unsigned long flags; + struct ir_scancode *keymap = rc_tab->scan; + + spin_lock_irqsave(&rc_tab->lock, flags); + + /* FIXME: replace it by a binary search */ + + for (rc = 0; rc < rc_tab->size; rc++) + if (keymap[rc].scancode == scancode) + goto exit; + + /* Not found */ + rc = -EINVAL; + +exit: + spin_unlock_irqrestore(&rc_tab->lock, flags); + return rc; +} + /** * ir_roundup_tablesize() - gets an optimum value for the table size * @n_elems: minimum number of entries to store keycodes @@ -54,21 +86,20 @@ int ir_copy_table(struct ir_scancode_table *destin, int i, j = 0; for (i = 0; i < origin->size; i++) { - if (origin->scan[i].keycode != KEY_UNKNOWN && - origin->scan[i].keycode != KEY_RESERVED) { - memcpy(&destin->scan[j], &origin->scan[i], - sizeof(struct ir_scancode)); - j++; - } + if (origin->scan[i].keycode == KEY_UNKNOWN || + origin->scan[i].keycode == KEY_RESERVED) + continue; + + memcpy(&destin->scan[j], &origin->scan[i], sizeof(struct ir_scancode)); + j++; } destin->size = j; - IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", j); + IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", destin->size); return 0; } - /** * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table * @dev: the struct input_dev device descriptor @@ -81,28 +112,14 @@ int ir_copy_table(struct ir_scancode_table *destin, static int ir_getkeycode(struct input_dev *dev, int scancode, int *keycode) { - int i; + int elem; struct ir_scancode_table *rc_tab = input_get_drvdata(dev); - struct ir_scancode *keymap = rc_tab->scan; - - /* See if we can match the raw key code. */ - for (i = 0; i < rc_tab->size; i++) - if (keymap[i].scancode == scancode) { - *keycode = keymap[i].keycode; - return 0; - } - /* - * If is there extra space, returns KEY_RESERVED, - * otherwise, input core won't let ir_setkeycode - * to work - */ - for (i = 0; i < rc_tab->size; i++) - if (keymap[i].keycode == KEY_RESERVED || - keymap[i].keycode == KEY_UNKNOWN) { - *keycode = KEY_RESERVED; - return 0; - } + elem = ir_seek_table(rc_tab, scancode); + if (elem >= 0) { + *keycode = rc_tab->scan[elem].keycode; + return 0; + } return -EINVAL; } @@ -120,40 +137,33 @@ static int ir_getkeycode(struct input_dev *dev, static int ir_setkeycode(struct input_dev *dev, int scancode, int keycode) { - int i; + int rc = 0; struct ir_scancode_table *rc_tab = input_get_drvdata(dev); struct ir_scancode *keymap = rc_tab->scan; + unsigned long flags; /* Search if it is replacing an existing keycode */ - for (i = 0; i < rc_tab->size; i++) - if (keymap[i].scancode == scancode) { - keymap[i].keycode = keycode; - return 0; - } - - /* Search if is there a clean entry. If so, use it */ - for (i = 0; i < rc_tab->size; i++) - if (keymap[i].keycode == KEY_RESERVED || - keymap[i].keycode == KEY_UNKNOWN) { - keymap[i].scancode = scancode; - keymap[i].keycode = keycode; - return 0; - } + rc = ir_seek_table(rc_tab, scancode); + if (rc <0) + return rc; - /* - * FIXME: Currently, it is not possible to increase the size of - * scancode table. For it to happen, one possibility - * would be to allocate a table with key_map_size + 1, - * copying data, appending the new key on it, and freeing - * the old one - or maybe just allocating some spare space - */ + IR_dprintk(1, "#%d: Replacing scan 0x%04x with key 0x%04x\n", + rc, scancode, keycode); - return -EINVAL; + clear_bit(keymap[rc].keycode, dev->keybit); + + spin_lock_irqsave(&rc_tab->lock, flags); + keymap[rc].keycode = keycode; + spin_unlock_irqrestore(&rc_tab->lock, flags); + + set_bit(keycode, dev->keybit); + + return 0; } /** * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode - * @rc_tab: the ir_scancode_table with the keymap to be used + * @input_dev: the struct input_dev descriptor of the device * @scancode: the scancode that we're seeking * * This routine is used by the input routines when a key is pressed at the @@ -163,22 +173,23 @@ static int ir_setkeycode(struct input_dev *dev, */ u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) { - int i; struct ir_scancode_table *rc_tab = input_get_drvdata(dev); struct ir_scancode *keymap = rc_tab->scan; + int elem; - for (i = 0; i < rc_tab->size; i++) - if (keymap[i].scancode == scancode) { - IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", - dev->name, scancode, keymap[i].keycode); + elem = ir_seek_table(rc_tab, scancode); + if (elem >= 0) { + IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", + dev->name, scancode, keymap[elem].keycode); - return keymap[i].keycode; - } + return rc_tab->scan[elem].keycode; + } printk(KERN_INFO "%s: unknown key for scancode 0x%04x\n", dev->name, scancode); - return KEY_UNKNOWN; + /* Reports userspace that an unknown keycode were got */ + return KEY_RESERVED; } /** @@ -188,8 +199,8 @@ u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) * @rc_tab: the struct ir_scancode_table table of scancode/keymap * * This routine is used to initialize the input infrastructure to work with - * an IR. It requires that the caller initializes the input_dev struct with - * some fields: name, + * an IR. + * It should be called before registering the IR device. */ int ir_set_keycode_table(struct input_dev *input_dev, struct ir_scancode_table *rc_tab) @@ -197,6 +208,8 @@ int ir_set_keycode_table(struct input_dev *input_dev, struct ir_scancode *keymap = rc_tab->scan; int i; + spin_lock_init(&rc_tab->lock); + if (rc_tab->scan == NULL || !rc_tab->size) return -EINVAL; diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 452f6e86084..e41a99ee353 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -26,6 +26,7 @@ #include #include #include +#include extern int media_ir_debug; /* media_ir_debug level (0,1,2) */ #define IR_dprintk(level, fmt, arg...) if (media_ir_debug >= level) \ @@ -43,6 +44,7 @@ struct ir_scancode { struct ir_scancode_table { struct ir_scancode *scan; int size; + spinlock_t lock; }; #define RC5_START(x) (((x)>>12)&3) -- cgit v1.2.3-70-g09d2 From 92fda216b439932bf7511e6381bbe1d42ba98875 Mon Sep 17 00:00:00 2001 From: David Wong Date: Thu, 3 Dec 2009 10:57:02 -0300 Subject: V4L/DVB (13541): atbm8830: replace 64-bit division and floating point usage Randy Dunlap wrote: > On Mon, 30 Nov 2009 10:07:21 -0800 Randy Dunlap wrote: > >> Stephen Rothwell wrote: >>> Hi all, >>> >>> Changes since 20091127: >>> >>> The v4l-dvb tree lost its conflict. >> >> on i386 (X86_32): >> >> a 'double' variable is used, causing: >> >> ERROR: "__floatunsidf" [drivers/media/common/tuners/max2165.ko] undefined! >> ERROR: "__adddf3" [drivers/media/common/tuners/max2165.ko] undefined! >> ERROR: "__fixunsdfsi" [drivers/media/common/tuners/max2165.ko] undefined! > > > linux-next-20091202: > > still have this one (above) and similar with > drivers/media/dvb/frontends/atbm8830.c: > > drivers/built-in.o: In function `atbm8830_init': > atbm8830.c:(.text+0x9012f9): undefined reference to `__udivdi3' > atbm8830.c:(.text+0x901384): undefined reference to `__floatunsidf' > atbm8830.c:(.text+0x901395): undefined reference to `__muldf3' > atbm8830.c:(.text+0x9013a5): undefined reference to `__floatunsidf' > atbm8830.c:(.text+0x9013b2): undefined reference to `__divdf3' > atbm8830.c:(.text+0x9013c3): undefined reference to `__muldf3' > atbm8830.c:(.text+0x9013cd): undefined reference to `__fixunsdfsi' > > --- > ~Randy > -- > To unsubscribe from this list: send the line "unsubscribe linux-media" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html This patch replace 64-bit division by do_div() macro and remove usage of floating point variable Signed-off-by: David T. L. Wong Acked-by: Randy Dunlap Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/atbm8830.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/atbm8830.c b/drivers/media/dvb/frontends/atbm8830.c index d77684893d9..59881a5944e 100644 --- a/drivers/media/dvb/frontends/atbm8830.c +++ b/drivers/media/dvb/frontends/atbm8830.c @@ -19,6 +19,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include "dvb_frontend.h" #include "atbm8830.h" @@ -102,8 +103,12 @@ static inline int atbm8830_reglatch_lock(struct atbm_state *priv, int lock) static int set_osc_freq(struct atbm_state *priv, u32 freq /*in kHz*/) { u32 val; + u64 t; - val = (u64)0x100000 * freq / 30400; + /* 0x100000 * freq / 30.4MHz */ + t = (u64)0x100000 * freq; + do_div(t, 30400); + val = t; atbm8830_write_reg(priv, REG_OSC_CLK, val); atbm8830_write_reg(priv, REG_OSC_CLK + 1, val >> 8); @@ -116,14 +121,18 @@ static int set_if_freq(struct atbm_state *priv, u32 freq /*in kHz*/) { u32 fs = priv->config->osc_clk_freq; - double t; + u64 t; u32 val; u8 dat; - t = 2 * 3.141593 * (freq - fs) / fs * (1 << 22); - val = t; - if (freq != 0) { + /* 2 * PI * (freq - fs) / fs * (2 ^ 22) */ + t = (u64) 2 * 31416 * (freq - fs); + t <<= 22; + do_div(t, fs); + do_div(t, 1000); + val = t; + atbm8830_write_reg(priv, REG_TUNER_BASEBAND, 1); atbm8830_write_reg(priv, REG_IF_FREQ, val); atbm8830_write_reg(priv, REG_IF_FREQ+1, val >> 8); -- cgit v1.2.3-70-g09d2 From e97f4677961f68e29bd906022ebf60a6df7f530a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 4 Dec 2009 17:17:47 -0300 Subject: V4L/DVB (13542): ir-keytable: Allow dynamic table change Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-keytable.c | 207 +++++++++++++++++++++++++++++++++++-- 1 file changed, 197 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/ir-keytable.c b/drivers/media/common/ir-keytable.c index b06f023ca76..26ce5bc2fdd 100644 --- a/drivers/media/common/ir-keytable.c +++ b/drivers/media/common/ir-keytable.c @@ -8,6 +8,7 @@ #include #define IR_TAB_MIN_SIZE 32 +#define IR_TAB_MAX_SIZE 1024 /** * ir_seek_table() - returns the element order on the table @@ -121,7 +122,154 @@ static int ir_getkeycode(struct input_dev *dev, return 0; } - return -EINVAL; + /* + * Scancode not found and table can't be expanded + */ + if (elem < 0 && rc_tab->size == IR_TAB_MAX_SIZE) + return -EINVAL; + + /* + * If is there extra space, returns KEY_RESERVED, + * otherwise, input core won't let ir_setkeycode to work + */ + *keycode = KEY_RESERVED; + return 0; +} + + +/** + * ir_is_resize_needed() - Check if the table needs rezise + * @table: keycode table that may need to resize + * @n_elems: minimum number of entries to store keycodes + * + * Considering that kmalloc uses power of two storage areas, this + * routine detects if the real alloced size will change. If not, it + * just returns without doing nothing. Otherwise, it will extend or + * reduce the table size to meet the new needs. + * + * It returns 0 if no resize is needed, 1 otherwise. + */ +static int ir_is_resize_needed(struct ir_scancode_table *table, int n_elems) +{ + int cur_size = ir_roundup_tablesize(table->size); + int new_size = ir_roundup_tablesize(n_elems); + + if (cur_size == new_size) + return 0; + + /* Resize is needed */ + return 1; +} + +/** + * ir_delete_key() - remove a keycode from the table + * @rc_tab: keycode table + * @elem: element to be removed + * + */ +static void ir_delete_key(struct ir_scancode_table *rc_tab, int elem) +{ + unsigned long flags = 0; + int newsize = rc_tab->size - 1; + int resize = ir_is_resize_needed(rc_tab, newsize); + struct ir_scancode *oldkeymap = rc_tab->scan; + struct ir_scancode *newkeymap; + + if (resize) { + newkeymap = kzalloc(ir_roundup_tablesize(newsize) * + sizeof(*newkeymap), GFP_ATOMIC); + + /* There's no memory for resize. Keep the old table */ + if (!newkeymap) + resize = 0; + } + + if (!resize) { + newkeymap = oldkeymap; + + /* We'll modify the live table. Lock it */ + spin_lock_irqsave(&rc_tab->lock, flags); + } + + /* + * Copy the elements before the one that will be deleted + * if (!resize), both oldkeymap and newkeymap points + * to the same place, so, there's no need to copy + */ + if (resize && elem > 0) + memcpy(newkeymap, oldkeymap, + elem * sizeof(*newkeymap)); + + /* + * Copy the other elements overwriting the element to be removed + * This operation applies to both resize and non-resize case + */ + if (elem < newsize) + memcpy(&newkeymap[elem], &oldkeymap[elem + 1], + (newsize - elem) * sizeof(*newkeymap)); + + if (resize) { + /* + * As the copy happened to a temporary table, only here + * it needs to lock while replacing the table pointers + * to use the new table + */ + spin_lock_irqsave(&rc_tab->lock, flags); + rc_tab->size = newsize; + rc_tab->scan = newkeymap; + spin_unlock_irqrestore(&rc_tab->lock, flags); + + /* Frees the old keytable */ + kfree(oldkeymap); + } else { + rc_tab->size = newsize; + spin_unlock_irqrestore(&rc_tab->lock, flags); + } +} + +/** + * ir_insert_key() - insert a keycode at the table + * @rc_tab: keycode table + * @scancode: the desired scancode + * @keycode: the keycode to be retorned. + * + */ +static int ir_insert_key(struct ir_scancode_table *rc_tab, + int scancode, int keycode) +{ + unsigned long flags; + int elem = rc_tab->size; + int newsize = rc_tab->size + 1; + int resize = ir_is_resize_needed(rc_tab, newsize); + struct ir_scancode *oldkeymap = rc_tab->scan; + struct ir_scancode *newkeymap; + + if (resize) { + newkeymap = kzalloc(ir_roundup_tablesize(newsize) * + sizeof(*newkeymap), GFP_ATOMIC); + if (!newkeymap) + return -ENOMEM; + + memcpy(newkeymap, oldkeymap, + rc_tab->size * sizeof(*newkeymap)); + } else + newkeymap = oldkeymap; + + /* Stores the new code at the table */ + IR_dprintk(1, "#%d: New scan 0x%04x with key 0x%04x\n", + rc_tab->size, scancode, keycode); + + spin_lock_irqsave(&rc_tab->lock, flags); + rc_tab->size = newsize; + if (resize) { + rc_tab->scan = newkeymap; + kfree(oldkeymap); + } + newkeymap[elem].scancode = scancode; + newkeymap[elem].keycode = keycode; + spin_unlock_irqrestore(&rc_tab->lock, flags); + + return 0; } /** @@ -142,20 +290,59 @@ static int ir_setkeycode(struct input_dev *dev, struct ir_scancode *keymap = rc_tab->scan; unsigned long flags; - /* Search if it is replacing an existing keycode */ + /* + * Handle keycode table deletions + * + * If userspace is adding a KEY_UNKNOWN or KEY_RESERVED, + * deal as a trial to remove an existing scancode attribution + * if table become too big, reduce it to save space + */ + if (keycode == KEY_UNKNOWN || keycode == KEY_RESERVED) { + rc = ir_seek_table(rc_tab, scancode); + if (rc < 0) + return 0; + + IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", rc, scancode); + clear_bit(keymap[rc].keycode, dev->keybit); + ir_delete_key(rc_tab, rc); + + return 0; + } + + /* + * Handle keycode replacements + * + * If the scancode exists, just replace by the new value + */ rc = ir_seek_table(rc_tab, scancode); - if (rc <0) - return rc; + if (rc >= 0) { + IR_dprintk(1, "#%d: Replacing scan 0x%04x with key 0x%04x\n", + rc, scancode, keycode); - IR_dprintk(1, "#%d: Replacing scan 0x%04x with key 0x%04x\n", - rc, scancode, keycode); + clear_bit(keymap[rc].keycode, dev->keybit); - clear_bit(keymap[rc].keycode, dev->keybit); + spin_lock_irqsave(&rc_tab->lock, flags); + keymap[rc].keycode = keycode; + spin_unlock_irqrestore(&rc_tab->lock, flags); - spin_lock_irqsave(&rc_tab->lock, flags); - keymap[rc].keycode = keycode; - spin_unlock_irqrestore(&rc_tab->lock, flags); + set_bit(keycode, dev->keybit); + return 0; + } + + /* + * Handle new scancode inserts + * + * reallocate table if needed and insert a new keycode + */ + + /* Avoid growing the table indefinitely */ + if (rc_tab->size + 1 > IR_TAB_MAX_SIZE) + return -EINVAL; + + rc = ir_insert_key(rc_tab, scancode, keycode); + if (rc < 0) + return rc; set_bit(keycode, dev->keybit); return 0; -- cgit v1.2.3-70-g09d2 From dd7cdb883b1000cb2be537c44612ade3c9c39a7b Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 8 Dec 2009 09:13:07 -0800 Subject: ALSA: radio/sound/miro: fix build, cleanup depends/selects miropcm20 uses ALSA (snd_) interfaces from the SND_MIRO driver, so it should depend on SND. (selecting SND_MIRO when CONFIG_SND is not enabled is a problem.) drivers/built-in.o: In function `vidioc_s_ctrl': radio-miropcm20.c:(.text+0x227499): undefined reference to `snd_aci_cmd' drivers/built-in.o: In function `vidioc_s_frequency': radio-miropcm20.c:(.text+0x227574): undefined reference to `snd_aci_cmd' radio-miropcm20.c:(.text+0x227588): undefined reference to `snd_aci_cmd' drivers/built-in.o: In function `pcm20_init': radio-miropcm20.c:(.init.text+0x2a784): undefined reference to `snd_aci_get_aci' miropcm20 selects SND_MIRO but SND_ISA may be not enabled, so also select SND_ISA so that the snd-miro driver will be built. Otherwise there are missing symbols: ERROR: "snd_opl4_create" [sound/isa/opti9xx/snd-miro.ko] undefined! ERROR: "snd_wss_pcm" [sound/isa/opti9xx/snd-miro.ko] undefined! ERROR: "snd_wss_timer" [sound/isa/opti9xx/snd-miro.ko] undefined! ERROR: "snd_wss_create" [sound/isa/opti9xx/snd-miro.ko] undefined! ERROR: "snd_wss_mixer" [sound/isa/opti9xx/snd-miro.ko] undefined! Signed-off-by: Randy Dunlap Acked-by: Mauro Carvalho Chehab Cc: Krzysztof Helt Signed-off-by: Takashi Iwai --- drivers/media/radio/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index b134553eb3b..dcc7af2f331 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -197,7 +197,8 @@ config RADIO_MAESTRO config RADIO_MIROPCM20 tristate "miroSOUND PCM20 radio" - depends on ISA && VIDEO_V4L2 + depends on ISA && VIDEO_V4L2 && SND + select SND_ISA select SND_MIRO ---help--- Choose Y here if you have this FM radio card. You also need to enable -- cgit v1.2.3-70-g09d2 From 5476ffd2b78f06cce31a57f8611162918fe1ae3a Mon Sep 17 00:00:00 2001 From: David Wong Date: Thu, 3 Dec 2009 10:54:25 -0300 Subject: V4L/DVB (13592): max2165: 32bit build patch This patch drops usage of floating point variable for 32bit build Signed-off-by: David T. L. Wong Acked-by: Randy Dunlap Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/max2165.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/max2165.c b/drivers/media/common/tuners/max2165.c index 1b486cfb8ed..3d03640cf1f 100644 --- a/drivers/media/common/tuners/max2165.c +++ b/drivers/media/common/tuners/max2165.c @@ -193,7 +193,7 @@ static int max2165_set_rf(struct max2165_priv *priv, u32 freq) { u8 tf; u8 tf_ntch; - double t; + u32 t; u32 quotient, fraction; /* Set PLL divider according to RF frequency */ -- cgit v1.2.3-70-g09d2 From 471452104b8520337ae2fb48c4e61cd4896e025d Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 14 Dec 2009 18:00:08 -0800 Subject: const: constify remaining dev_pm_ops Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/plat-omap/debug-leds.c | 2 +- arch/arm/plat-omap/gpio.c | 2 +- arch/s390/appldata/appldata_base.c | 2 +- drivers/block/floppy.c | 2 +- drivers/char/hvc_iucv.c | 2 +- drivers/dma/at_hdmac.c | 2 +- drivers/dma/dw_dmac.c | 2 +- drivers/dma/txx9dmac.c | 2 +- drivers/hwmon/applesmc.c | 2 +- drivers/i2c/busses/i2c-pxa.c | 2 +- drivers/i2c/busses/i2c-s3c2410.c | 2 +- drivers/i2c/busses/i2c-sh_mobile.c | 2 +- drivers/input/keyboard/adp5588-keys.c | 2 +- drivers/input/keyboard/sh_keysc.c | 2 +- drivers/input/misc/bfin_rotary.c | 2 +- drivers/input/misc/pcspkr.c | 2 +- drivers/input/touchscreen/pcap_ts.c | 2 +- drivers/media/video/davinci/vpfe_capture.c | 2 +- drivers/media/video/davinci/vpif_capture.c | 2 +- drivers/media/video/sh_mobile_ceu_camera.c | 2 +- drivers/mmc/host/pxamci.c | 2 +- drivers/mmc/host/s3cmci.c | 2 +- drivers/mtd/nand/nomadik_nand.c | 2 +- drivers/net/3c59x.c | 2 +- drivers/net/dm9000.c | 2 +- drivers/net/r8169.c | 2 +- drivers/net/smsc911x.c | 2 +- drivers/net/vmxnet3/vmxnet3_drv.c | 2 +- drivers/pci/pcie/portdrv_pci.c | 2 +- drivers/pcmcia/pxa2xx_base.c | 2 +- drivers/pcmcia/yenta_socket.c | 2 +- drivers/platform/x86/acerhdf.c | 2 +- drivers/platform/x86/eeepc-laptop.c | 2 +- drivers/platform/x86/hp-wmi.c | 2 +- drivers/power/wm97xx_battery.c | 2 +- drivers/rtc/rtc-pxa.c | 2 +- drivers/rtc/rtc-sa1100.c | 2 +- drivers/rtc/rtc-sh.c | 2 +- drivers/rtc/rtc-wm831x.c | 2 +- drivers/s390/block/dcssblk.c | 2 +- drivers/s390/block/xpram.c | 2 +- drivers/s390/char/monreader.c | 2 +- drivers/s390/char/monwriter.c | 2 +- drivers/s390/char/sclp.c | 2 +- drivers/s390/char/sclp_cmd.c | 2 +- drivers/s390/char/vmlogrdr.c | 2 +- drivers/s390/cio/ccwgroup.c | 2 +- drivers/s390/cio/css.c | 2 +- drivers/s390/cio/device.c | 2 +- drivers/s390/net/netiucv.c | 2 +- drivers/s390/net/smsgiucv.c | 2 +- drivers/serial/pxa.c | 2 +- drivers/serial/sh-sci.c | 2 +- drivers/spi/pxa2xx_spi.c | 2 +- drivers/spi/spi_s3c24xx.c | 2 +- drivers/uio/uio_pdrv_genirq.c | 2 +- drivers/usb/core/hcd-pci.c | 2 +- drivers/usb/core/hcd.h | 2 +- drivers/usb/core/usb.c | 2 +- drivers/usb/host/ehci-au1xxx.c | 2 +- drivers/usb/host/ohci-au1xxx.c | 2 +- drivers/usb/host/ohci-pxa27x.c | 2 +- drivers/usb/host/r8a66597-hcd.c | 2 +- drivers/usb/musb/musb_core.c | 2 +- drivers/video/backlight/da903x_bl.c | 2 +- drivers/video/hitfb.c | 2 +- drivers/video/pxafb.c | 2 +- drivers/video/sh_mobile_lcdcfb.c | 2 +- drivers/watchdog/adx_wdt.c | 2 +- include/linux/pm.h | 2 +- net/iucv/af_iucv.c | 2 +- net/iucv/iucv.c | 2 +- sound/arm/pxa2xx-ac97.c | 2 +- sound/soc/s3c24xx/s3c24xx_simtec.c | 2 +- sound/soc/s3c24xx/s3c24xx_simtec.h | 2 +- sound/soc/soc-core.c | 2 +- 76 files changed, 76 insertions(+), 76 deletions(-) (limited to 'drivers/media') diff --git a/arch/arm/plat-omap/debug-leds.c b/arch/arm/plat-omap/debug-leds.c index 6c768b71ad6..53fcef7c520 100644 --- a/arch/arm/plat-omap/debug-leds.c +++ b/arch/arm/plat-omap/debug-leds.c @@ -293,7 +293,7 @@ static int fpga_resume_noirq(struct device *dev) return 0; } -static struct dev_pm_ops fpga_dev_pm_ops = { +static const struct dev_pm_ops fpga_dev_pm_ops = { .suspend_noirq = fpga_suspend_noirq, .resume_noirq = fpga_resume_noirq, }; diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 055160e0620..04846811d0a 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -1431,7 +1431,7 @@ static int omap_mpuio_resume_noirq(struct device *dev) return 0; } -static struct dev_pm_ops omap_mpuio_dev_pm_ops = { +static const struct dev_pm_ops omap_mpuio_dev_pm_ops = { .suspend_noirq = omap_mpuio_suspend_noirq, .resume_noirq = omap_mpuio_resume_noirq, }; diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 495589950dc..5c91995b74e 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -551,7 +551,7 @@ static int appldata_thaw(struct device *dev) return appldata_restore(dev); } -static struct dev_pm_ops appldata_pm_ops = { +static const struct dev_pm_ops appldata_pm_ops = { .freeze = appldata_freeze, .thaw = appldata_thaw, .restore = appldata_restore, diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 5c01f747571..d41d7f01854 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -4162,7 +4162,7 @@ static int floppy_resume(struct device *dev) return 0; } -static struct dev_pm_ops floppy_pm_ops = { +static const struct dev_pm_ops floppy_pm_ops = { .resume = floppy_resume, .restore = floppy_resume, }; diff --git a/drivers/char/hvc_iucv.c b/drivers/char/hvc_iucv.c index b8a5d654d3d..fe62bd0e17b 100644 --- a/drivers/char/hvc_iucv.c +++ b/drivers/char/hvc_iucv.c @@ -931,7 +931,7 @@ static struct hv_ops hvc_iucv_ops = { }; /* Suspend / resume device operations */ -static struct dev_pm_ops hvc_iucv_pm_ops = { +static const struct dev_pm_ops hvc_iucv_pm_ops = { .freeze = hvc_iucv_pm_freeze, .thaw = hvc_iucv_pm_restore_thaw, .restore = hvc_iucv_pm_restore_thaw, diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index c52ac9efd0b..f15112569c1 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -1188,7 +1188,7 @@ static int at_dma_resume_noirq(struct device *dev) return 0; } -static struct dev_pm_ops at_dma_dev_pm_ops = { +static const struct dev_pm_ops at_dma_dev_pm_ops = { .suspend_noirq = at_dma_suspend_noirq, .resume_noirq = at_dma_resume_noirq, }; diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 2eea823516a..285bed0fe17 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -1427,7 +1427,7 @@ static int dw_resume_noirq(struct device *dev) return 0; } -static struct dev_pm_ops dw_dev_pm_ops = { +static const struct dev_pm_ops dw_dev_pm_ops = { .suspend_noirq = dw_suspend_noirq, .resume_noirq = dw_resume_noirq, }; diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c index fb6bb64e886..3ebc61067e5 100644 --- a/drivers/dma/txx9dmac.c +++ b/drivers/dma/txx9dmac.c @@ -1313,7 +1313,7 @@ static int txx9dmac_resume_noirq(struct device *dev) } -static struct dev_pm_ops txx9dmac_dev_pm_ops = { +static const struct dev_pm_ops txx9dmac_dev_pm_ops = { .suspend_noirq = txx9dmac_suspend_noirq, .resume_noirq = txx9dmac_resume_noirq, }; diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 7ea6a8f6605..c1605b528e8 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -518,7 +518,7 @@ static int applesmc_pm_restore(struct device *dev) return applesmc_pm_resume(dev); } -static struct dev_pm_ops applesmc_pm_ops = { +static const struct dev_pm_ops applesmc_pm_ops = { .resume = applesmc_pm_resume, .restore = applesmc_pm_restore, }; diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 049555777f6..7647a20523a 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -1155,7 +1155,7 @@ static int i2c_pxa_resume_noirq(struct device *dev) return 0; } -static struct dev_pm_ops i2c_pxa_dev_pm_ops = { +static const struct dev_pm_ops i2c_pxa_dev_pm_ops = { .suspend_noirq = i2c_pxa_suspend_noirq, .resume_noirq = i2c_pxa_resume_noirq, }; diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 96aafb91b69..1d8c98613fa 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -967,7 +967,7 @@ static int s3c24xx_i2c_resume(struct device *dev) return 0; } -static struct dev_pm_ops s3c24xx_i2c_dev_pm_ops = { +static const struct dev_pm_ops s3c24xx_i2c_dev_pm_ops = { .suspend_noirq = s3c24xx_i2c_suspend_noirq, .resume = s3c24xx_i2c_resume, }; diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 86a9d4e8147..ccc46418ef7 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c @@ -647,7 +647,7 @@ static int sh_mobile_i2c_runtime_nop(struct device *dev) return 0; } -static struct dev_pm_ops sh_mobile_i2c_dev_pm_ops = { +static const struct dev_pm_ops sh_mobile_i2c_dev_pm_ops = { .runtime_suspend = sh_mobile_i2c_runtime_nop, .runtime_resume = sh_mobile_i2c_runtime_nop, }; diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index d48c808d592..1edb596d927 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -319,7 +319,7 @@ static int adp5588_resume(struct device *dev) return 0; } -static struct dev_pm_ops adp5588_dev_pm_ops = { +static const struct dev_pm_ops adp5588_dev_pm_ops = { .suspend = adp5588_suspend, .resume = adp5588_resume, }; diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index 076111fc72d..8e9380bfed4 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c @@ -295,7 +295,7 @@ static int sh_keysc_resume(struct device *dev) return 0; } -static struct dev_pm_ops sh_keysc_dev_pm_ops = { +static const struct dev_pm_ops sh_keysc_dev_pm_ops = { .suspend = sh_keysc_suspend, .resume = sh_keysc_resume, }; diff --git a/drivers/input/misc/bfin_rotary.c b/drivers/input/misc/bfin_rotary.c index 690f3fafa03..61d10177fa8 100644 --- a/drivers/input/misc/bfin_rotary.c +++ b/drivers/input/misc/bfin_rotary.c @@ -247,7 +247,7 @@ static int bfin_rotary_resume(struct device *dev) return 0; } -static struct dev_pm_ops bfin_rotary_pm_ops = { +static const struct dev_pm_ops bfin_rotary_pm_ops = { .suspend = bfin_rotary_suspend, .resume = bfin_rotary_resume, }; diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c index 21cb755a54f..ea4e1fd1265 100644 --- a/drivers/input/misc/pcspkr.c +++ b/drivers/input/misc/pcspkr.c @@ -127,7 +127,7 @@ static void pcspkr_shutdown(struct platform_device *dev) pcspkr_event(NULL, EV_SND, SND_BELL, 0); } -static struct dev_pm_ops pcspkr_pm_ops = { +static const struct dev_pm_ops pcspkr_pm_ops = { .suspend = pcspkr_suspend, }; diff --git a/drivers/input/touchscreen/pcap_ts.c b/drivers/input/touchscreen/pcap_ts.c index 67fcd33595d..b79097e3028 100644 --- a/drivers/input/touchscreen/pcap_ts.c +++ b/drivers/input/touchscreen/pcap_ts.c @@ -233,7 +233,7 @@ static int pcap_ts_resume(struct device *dev) return 0; } -static struct dev_pm_ops pcap_ts_pm_ops = { +static const struct dev_pm_ops pcap_ts_pm_ops = { .suspend = pcap_ts_suspend, .resume = pcap_ts_resume, }; diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c index 12a1b3d7132..c3916a42668 100644 --- a/drivers/media/video/davinci/vpfe_capture.c +++ b/drivers/media/video/davinci/vpfe_capture.c @@ -2127,7 +2127,7 @@ vpfe_resume(struct device *dev) return -1; } -static struct dev_pm_ops vpfe_dev_pm_ops = { +static const struct dev_pm_ops vpfe_dev_pm_ops = { .suspend = vpfe_suspend, .resume = vpfe_resume, }; diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/video/davinci/vpif_capture.c index d947ee5e4eb..78130721f57 100644 --- a/drivers/media/video/davinci/vpif_capture.c +++ b/drivers/media/video/davinci/vpif_capture.c @@ -2107,7 +2107,7 @@ vpif_resume(struct device *dev) return -1; } -static struct dev_pm_ops vpif_dev_pm_ops = { +static const struct dev_pm_ops vpif_dev_pm_ops = { .suspend = vpif_suspend, .resume = vpif_resume, }; diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index a4f3472d4db..961e4484d72 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -1825,7 +1825,7 @@ static int sh_mobile_ceu_runtime_nop(struct device *dev) return 0; } -static struct dev_pm_ops sh_mobile_ceu_dev_pm_ops = { +static const struct dev_pm_ops sh_mobile_ceu_dev_pm_ops = { .runtime_suspend = sh_mobile_ceu_runtime_nop, .runtime_resume = sh_mobile_ceu_runtime_nop, }; diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index bb47ff465c0..0d783f3e79e 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -828,7 +828,7 @@ static int pxamci_resume(struct device *dev) return ret; } -static struct dev_pm_ops pxamci_pm_ops = { +static const struct dev_pm_ops pxamci_pm_ops = { .suspend = pxamci_suspend, .resume = pxamci_resume, }; diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 941a4d35ef8..ec15f1bbf8b 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -1892,7 +1892,7 @@ static int s3cmci_resume(struct device *dev) return mmc_resume_host(mmc); } -static struct dev_pm_ops s3cmci_pm = { +static const struct dev_pm_ops s3cmci_pm = { .suspend = s3cmci_suspend, .resume = s3cmci_resume, }; diff --git a/drivers/mtd/nand/nomadik_nand.c b/drivers/mtd/nand/nomadik_nand.c index 7c302d55910..66123419f65 100644 --- a/drivers/mtd/nand/nomadik_nand.c +++ b/drivers/mtd/nand/nomadik_nand.c @@ -216,7 +216,7 @@ static int nomadik_nand_resume(struct device *dev) return 0; } -static struct dev_pm_ops nomadik_nand_pm_ops = { +static const struct dev_pm_ops nomadik_nand_pm_ops = { .suspend = nomadik_nand_suspend, .resume = nomadik_nand_resume, }; diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 78b7167a8ce..39db0e96815 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -837,7 +837,7 @@ static int vortex_resume(struct device *dev) return 0; } -static struct dev_pm_ops vortex_pm_ops = { +static const struct dev_pm_ops vortex_pm_ops = { .suspend = vortex_suspend, .resume = vortex_resume, .freeze = vortex_suspend, diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 0cbe3c0e7c0..b3773006568 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -1646,7 +1646,7 @@ dm9000_drv_resume(struct device *dev) return 0; } -static struct dev_pm_ops dm9000_drv_pm_ops = { +static const struct dev_pm_ops dm9000_drv_pm_ops = { .suspend = dm9000_drv_suspend, .resume = dm9000_drv_resume, }; diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index acfc5a3aa49..60f96c468a2 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -4859,7 +4859,7 @@ out: return 0; } -static struct dev_pm_ops rtl8169_pm_ops = { +static const struct dev_pm_ops rtl8169_pm_ops = { .suspend = rtl8169_suspend, .resume = rtl8169_resume, .freeze = rtl8169_suspend, diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 20d6095cf41..494cd91ea39 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -2154,7 +2154,7 @@ static int smsc911x_resume(struct device *dev) return (to == 0) ? -EIO : 0; } -static struct dev_pm_ops smsc911x_pm_ops = { +static const struct dev_pm_ops smsc911x_pm_ops = { .suspend = smsc911x_suspend, .resume = smsc911x_resume, }; diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 1ceb9d0f8b9..9cc438282d7 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -2689,7 +2689,7 @@ vmxnet3_resume(struct device *device) return 0; } -static struct dev_pm_ops vmxnet3_pm_ops = { +static const struct dev_pm_ops vmxnet3_pm_ops = { .suspend = vmxnet3_suspend, .resume = vmxnet3_resume, }; diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index ce52ea34fee..a49452e2aed 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -43,7 +43,7 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev) } #ifdef CONFIG_PM -static struct dev_pm_ops pcie_portdrv_pm_ops = { +static const struct dev_pm_ops pcie_portdrv_pm_ops = { .suspend = pcie_port_device_suspend, .resume = pcie_port_device_resume, .freeze = pcie_port_device_suspend, diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index da346eb7e77..3aabf1e3798 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -336,7 +336,7 @@ static int pxa2xx_drv_pcmcia_resume(struct device *dev) return pcmcia_socket_dev_resume(dev); } -static struct dev_pm_ops pxa2xx_drv_pcmcia_pm_ops = { +static const struct dev_pm_ops pxa2xx_drv_pcmcia_pm_ops = { .suspend = pxa2xx_drv_pcmcia_suspend, .resume = pxa2xx_drv_pcmcia_resume, }; diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index fe02cfd4b5e..e4d12acdd52 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -1330,7 +1330,7 @@ static int yenta_dev_resume(struct device *dev) return 0; } -static struct dev_pm_ops yenta_pm_ops = { +static const struct dev_pm_ops yenta_pm_ops = { .suspend_noirq = yenta_dev_suspend_noirq, .resume_noirq = yenta_dev_resume_noirq, .resume = yenta_dev_resume, diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index ab64522aaa6..be27aa47e81 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c @@ -460,7 +460,7 @@ static int acerhdf_remove(struct platform_device *device) return 0; } -static struct dev_pm_ops acerhdf_pm_ops = { +static const struct dev_pm_ops acerhdf_pm_ops = { .suspend = acerhdf_suspend, .freeze = acerhdf_suspend, }; diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 4226e535273..e647a856b9b 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -154,7 +154,7 @@ static struct eeepc_hotk *ehotk; static int eeepc_hotk_thaw(struct device *device); static int eeepc_hotk_restore(struct device *device); -static struct dev_pm_ops eeepc_pm_ops = { +static const struct dev_pm_ops eeepc_pm_ops = { .thaw = eeepc_hotk_thaw, .restore = eeepc_hotk_restore, }; diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index c2842171cec..f00a71c58e6 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -94,7 +94,7 @@ static struct rfkill *wifi_rfkill; static struct rfkill *bluetooth_rfkill; static struct rfkill *wwan_rfkill; -static struct dev_pm_ops hp_wmi_pm_ops = { +static const struct dev_pm_ops hp_wmi_pm_ops = { .resume = hp_wmi_resume_handler, .restore = hp_wmi_resume_handler, }; diff --git a/drivers/power/wm97xx_battery.c b/drivers/power/wm97xx_battery.c index f2bfd296dba..fa39e759a27 100644 --- a/drivers/power/wm97xx_battery.c +++ b/drivers/power/wm97xx_battery.c @@ -157,7 +157,7 @@ static int wm97xx_bat_resume(struct device *dev) return 0; } -static struct dev_pm_ops wm97xx_bat_pm_ops = { +static const struct dev_pm_ops wm97xx_bat_pm_ops = { .suspend = wm97xx_bat_suspend, .resume = wm97xx_bat_resume, }; diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c index 747ca194fad..e6351b743da 100644 --- a/drivers/rtc/rtc-pxa.c +++ b/drivers/rtc/rtc-pxa.c @@ -456,7 +456,7 @@ static int pxa_rtc_resume(struct device *dev) return 0; } -static struct dev_pm_ops pxa_rtc_pm_ops = { +static const struct dev_pm_ops pxa_rtc_pm_ops = { .suspend = pxa_rtc_suspend, .resume = pxa_rtc_resume, }; diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 29f98a70586..e4a44b64170 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c @@ -407,7 +407,7 @@ static int sa1100_rtc_resume(struct device *dev) return 0; } -static struct dev_pm_ops sa1100_rtc_pm_ops = { +static const struct dev_pm_ops sa1100_rtc_pm_ops = { .suspend = sa1100_rtc_suspend, .resume = sa1100_rtc_resume, }; diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index e6ed5404bca..e95cc6f8d61 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -826,7 +826,7 @@ static int sh_rtc_resume(struct device *dev) return 0; } -static struct dev_pm_ops sh_rtc_dev_pm_ops = { +static const struct dev_pm_ops sh_rtc_dev_pm_ops = { .suspend = sh_rtc_suspend, .resume = sh_rtc_resume, }; diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c index 79795cdf6ed..000c7e481e5 100644 --- a/drivers/rtc/rtc-wm831x.c +++ b/drivers/rtc/rtc-wm831x.c @@ -485,7 +485,7 @@ static int __devexit wm831x_rtc_remove(struct platform_device *pdev) return 0; } -static struct dev_pm_ops wm831x_rtc_pm_ops = { +static const struct dev_pm_ops wm831x_rtc_pm_ops = { .suspend = wm831x_rtc_suspend, .resume = wm831x_rtc_resume, diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index f76f4bd82b9..9b43ae94beb 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -1005,7 +1005,7 @@ static int dcssblk_thaw(struct device *dev) return 0; } -static struct dev_pm_ops dcssblk_pm_ops = { +static const struct dev_pm_ops dcssblk_pm_ops = { .freeze = dcssblk_freeze, .thaw = dcssblk_thaw, .restore = dcssblk_restore, diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index 116d1b3eeb1..118de392af6 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c @@ -407,7 +407,7 @@ static int xpram_restore(struct device *dev) return 0; } -static struct dev_pm_ops xpram_pm_ops = { +static const struct dev_pm_ops xpram_pm_ops = { .restore = xpram_restore, }; diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c index 60473f86e1f..33e96484d54 100644 --- a/drivers/s390/char/monreader.c +++ b/drivers/s390/char/monreader.c @@ -529,7 +529,7 @@ static int monreader_restore(struct device *dev) return monreader_thaw(dev); } -static struct dev_pm_ops monreader_pm_ops = { +static const struct dev_pm_ops monreader_pm_ops = { .freeze = monreader_freeze, .thaw = monreader_thaw, .restore = monreader_restore, diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c index 6532ed8b4af..668a0579b26 100644 --- a/drivers/s390/char/monwriter.c +++ b/drivers/s390/char/monwriter.c @@ -323,7 +323,7 @@ static int monwriter_thaw(struct device *dev) return monwriter_restore(dev); } -static struct dev_pm_ops monwriter_pm_ops = { +static const struct dev_pm_ops monwriter_pm_ops = { .freeze = monwriter_freeze, .thaw = monwriter_thaw, .restore = monwriter_restore, diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index a983f508678..ec88c59842e 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -1019,7 +1019,7 @@ static int sclp_restore(struct device *dev) return sclp_undo_suspend(SCLP_PM_EVENT_RESTORE); } -static struct dev_pm_ops sclp_pm_ops = { +static const struct dev_pm_ops sclp_pm_ops = { .freeze = sclp_freeze, .thaw = sclp_thaw, .restore = sclp_restore, diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 28b5afc129c..b3beab610da 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -547,7 +547,7 @@ struct read_storage_sccb { u32 entries[0]; } __packed; -static struct dev_pm_ops sclp_mem_pm_ops = { +static const struct dev_pm_ops sclp_mem_pm_ops = { .freeze = sclp_mem_freeze, }; diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index 899aa795bf3..7dfa5412d5a 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -675,7 +675,7 @@ static int vmlogrdr_pm_prepare(struct device *dev) } -static struct dev_pm_ops vmlogrdr_pm_ops = { +static const struct dev_pm_ops vmlogrdr_pm_ops = { .prepare = vmlogrdr_pm_prepare, }; diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index a5a62f1f774..5f97ea2ee6b 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -560,7 +560,7 @@ static int ccwgroup_pm_restore(struct device *dev) return gdrv->restore ? gdrv->restore(gdev) : 0; } -static struct dev_pm_ops ccwgroup_pm_ops = { +static const struct dev_pm_ops ccwgroup_pm_ops = { .prepare = ccwgroup_pm_prepare, .complete = ccwgroup_pm_complete, .freeze = ccwgroup_pm_freeze, diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 92ff88ac110..7679aee6fa1 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -1148,7 +1148,7 @@ static int css_pm_restore(struct device *dev) return drv->restore ? drv->restore(sch) : 0; } -static struct dev_pm_ops css_pm_ops = { +static const struct dev_pm_ops css_pm_ops = { .prepare = css_pm_prepare, .complete = css_pm_complete, .freeze = css_pm_freeze, diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 9fecfb4223a..73901c9e260 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -1904,7 +1904,7 @@ out_unlock: return ret; } -static struct dev_pm_ops ccw_pm_ops = { +static const struct dev_pm_ops ccw_pm_ops = { .prepare = ccw_device_pm_prepare, .complete = ccw_device_pm_complete, .freeze = ccw_device_pm_freeze, diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 98c04cac43c..65ebee0a326 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -159,7 +159,7 @@ static void netiucv_pm_complete(struct device *); static int netiucv_pm_freeze(struct device *); static int netiucv_pm_restore_thaw(struct device *); -static struct dev_pm_ops netiucv_pm_ops = { +static const struct dev_pm_ops netiucv_pm_ops = { .prepare = netiucv_pm_prepare, .complete = netiucv_pm_complete, .freeze = netiucv_pm_freeze, diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index 3012355f830..67f2485d237 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c @@ -168,7 +168,7 @@ static int smsg_pm_restore_thaw(struct device *dev) return 0; } -static struct dev_pm_ops smsg_pm_ops = { +static const struct dev_pm_ops smsg_pm_ops = { .freeze = smsg_pm_freeze, .thaw = smsg_pm_restore_thaw, .restore = smsg_pm_restore_thaw, diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index 4a821046baa..56ee082157a 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c @@ -756,7 +756,7 @@ static int serial_pxa_resume(struct device *dev) return 0; } -static struct dev_pm_ops serial_pxa_pm_ops = { +static const struct dev_pm_ops serial_pxa_pm_ops = { .suspend = serial_pxa_suspend, .resume = serial_pxa_resume, }; diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index ff38dbdb5c6..7e3f4ff58cf 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -1312,7 +1312,7 @@ static int sci_resume(struct device *dev) return 0; } -static struct dev_pm_ops sci_dev_pm_ops = { +static const struct dev_pm_ops sci_dev_pm_ops = { .suspend = sci_suspend, .resume = sci_resume, }; diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index c8c2b693ffa..c2f707e5ce7 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -1709,7 +1709,7 @@ static int pxa2xx_spi_resume(struct device *dev) return 0; } -static struct dev_pm_ops pxa2xx_spi_pm_ops = { +static const struct dev_pm_ops pxa2xx_spi_pm_ops = { .suspend = pxa2xx_spi_suspend, .resume = pxa2xx_spi_resume, }; diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c index 33d94f76b9e..276591569c8 100644 --- a/drivers/spi/spi_s3c24xx.c +++ b/drivers/spi/spi_s3c24xx.c @@ -489,7 +489,7 @@ static int s3c24xx_spi_resume(struct device *dev) return 0; } -static struct dev_pm_ops s3c24xx_spi_pmops = { +static const struct dev_pm_ops s3c24xx_spi_pmops = { .suspend = s3c24xx_spi_suspend, .resume = s3c24xx_spi_resume, }; diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c index aa53db9f2e8..1ef3b8fc50b 100644 --- a/drivers/uio/uio_pdrv_genirq.c +++ b/drivers/uio/uio_pdrv_genirq.c @@ -210,7 +210,7 @@ static int uio_pdrv_genirq_runtime_nop(struct device *dev) return 0; } -static struct dev_pm_ops uio_pdrv_genirq_dev_pm_ops = { +static const struct dev_pm_ops uio_pdrv_genirq_dev_pm_ops = { .runtime_suspend = uio_pdrv_genirq_runtime_nop, .runtime_resume = uio_pdrv_genirq_runtime_nop, }; diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 91f2885b6ee..2dcf906df56 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -363,7 +363,7 @@ static int hcd_pci_restore(struct device *dev) return resume_common(dev, true); } -struct dev_pm_ops usb_hcd_pci_pm_ops = { +const struct dev_pm_ops usb_hcd_pci_pm_ops = { .suspend = hcd_pci_suspend, .suspend_noirq = hcd_pci_suspend_noirq, .resume_noirq = hcd_pci_resume_noirq, diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index d8b43aee581..bbe2b924aae 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -330,7 +330,7 @@ extern void usb_hcd_pci_remove(struct pci_dev *dev); extern void usb_hcd_pci_shutdown(struct pci_dev *dev); #ifdef CONFIG_PM_SLEEP -extern struct dev_pm_ops usb_hcd_pci_pm_ops; +extern const struct dev_pm_ops usb_hcd_pci_pm_ops; #endif #endif /* CONFIG_PCI */ diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 4e2c6df8d3c..043fa833eec 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -320,7 +320,7 @@ static int usb_dev_restore(struct device *dev) return usb_resume(dev, PMSG_RESTORE); } -static struct dev_pm_ops usb_device_pm_ops = { +static const struct dev_pm_ops usb_device_pm_ops = { .prepare = usb_dev_prepare, .complete = usb_dev_complete, .suspend = usb_dev_suspend, diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index ed77be76d6b..dbfb482a94e 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c @@ -297,7 +297,7 @@ static int ehci_hcd_au1xxx_drv_resume(struct device *dev) return 0; } -static struct dev_pm_ops au1xxx_ehci_pmops = { +static const struct dev_pm_ops au1xxx_ehci_pmops = { .suspend = ehci_hcd_au1xxx_drv_suspend, .resume = ehci_hcd_au1xxx_drv_resume, }; diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index e4380082ebb..17a6043c1fa 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c @@ -294,7 +294,7 @@ static int ohci_hcd_au1xxx_drv_resume(struct device *dev) return 0; } -static struct dev_pm_ops au1xxx_ohci_pmops = { +static const struct dev_pm_ops au1xxx_ohci_pmops = { .suspend = ohci_hcd_au1xxx_drv_suspend, .resume = ohci_hcd_au1xxx_drv_resume, }; diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index f1c06202fdf..a18debdd79b 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -518,7 +518,7 @@ static int ohci_hcd_pxa27x_drv_resume(struct device *dev) return 0; } -static struct dev_pm_ops ohci_hcd_pxa27x_pm_ops = { +static const struct dev_pm_ops ohci_hcd_pxa27x_pm_ops = { .suspend = ohci_hcd_pxa27x_drv_suspend, .resume = ohci_hcd_pxa27x_drv_resume, }; diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 41dbc70ae75..b7a661c02bc 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -2353,7 +2353,7 @@ static int r8a66597_resume(struct device *dev) return 0; } -static struct dev_pm_ops r8a66597_dev_pm_ops = { +static const struct dev_pm_ops r8a66597_dev_pm_ops = { .suspend = r8a66597_suspend, .resume = r8a66597_resume, .poweroff = r8a66597_suspend, diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 49f2346afad..bfe08f4975a 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2214,7 +2214,7 @@ static int musb_resume_noirq(struct device *dev) return 0; } -static struct dev_pm_ops musb_dev_pm_ops = { +static const struct dev_pm_ops musb_dev_pm_ops = { .suspend = musb_suspend, .resume_noirq = musb_resume_noirq, }; diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c index 7fcb0eb54c6..f2d76dae1eb 100644 --- a/drivers/video/backlight/da903x_bl.c +++ b/drivers/video/backlight/da903x_bl.c @@ -177,7 +177,7 @@ static int da903x_backlight_resume(struct device *dev) return 0; } -static struct dev_pm_ops da903x_backlight_pm_ops = { +static const struct dev_pm_ops da903x_backlight_pm_ops = { .suspend = da903x_backlight_suspend, .resume = da903x_backlight_resume, }; diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c index e7116a6d82d..73c83a8de2d 100644 --- a/drivers/video/hitfb.c +++ b/drivers/video/hitfb.c @@ -456,7 +456,7 @@ static int hitfb_resume(struct device *dev) return 0; } -static struct dev_pm_ops hitfb_dev_pm_ops = { +static const struct dev_pm_ops hitfb_dev_pm_ops = { .suspend = hitfb_suspend, .resume = hitfb_resume, }; diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index f58a3aae6ea..b7e58059b59 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -1667,7 +1667,7 @@ static int pxafb_resume(struct device *dev) return 0; } -static struct dev_pm_ops pxafb_pm_ops = { +static const struct dev_pm_ops pxafb_pm_ops = { .suspend = pxafb_suspend, .resume = pxafb_resume, }; diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index b4b5de930cf..8a65fb6648a 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -890,7 +890,7 @@ static int sh_mobile_lcdc_runtime_resume(struct device *dev) return 0; } -static struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = { +static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = { .suspend = sh_mobile_lcdc_suspend, .resume = sh_mobile_lcdc_resume, .runtime_suspend = sh_mobile_lcdc_runtime_suspend, diff --git a/drivers/watchdog/adx_wdt.c b/drivers/watchdog/adx_wdt.c index 77afb0acc50..9c6594473d3 100644 --- a/drivers/watchdog/adx_wdt.c +++ b/drivers/watchdog/adx_wdt.c @@ -314,7 +314,7 @@ static int adx_wdt_resume(struct device *dev) return 0; } -static struct dev_pm_ops adx_wdt_pm_ops = { +static const struct dev_pm_ops adx_wdt_pm_ops = { .suspend = adx_wdt_suspend, .resume = adx_wdt_resume, }; diff --git a/include/linux/pm.h b/include/linux/pm.h index 0d65934246a..198b8f9fe05 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -219,7 +219,7 @@ struct dev_pm_ops { * to RAM and hibernation. */ #define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ -struct dev_pm_ops name = { \ +const struct dev_pm_ops name = { \ .suspend = suspend_fn, \ .resume = resume_fn, \ .freeze = suspend_fn, \ diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 1e428863574..c18286a2167 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -221,7 +221,7 @@ static int afiucv_pm_restore_thaw(struct device *dev) return 0; } -static struct dev_pm_ops afiucv_pm_ops = { +static const struct dev_pm_ops afiucv_pm_ops = { .prepare = afiucv_pm_prepare, .complete = afiucv_pm_complete, .freeze = afiucv_pm_freeze, diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c index 3b1f5f5f8de..fd8b28361a6 100644 --- a/net/iucv/iucv.c +++ b/net/iucv/iucv.c @@ -93,7 +93,7 @@ static int iucv_pm_freeze(struct device *); static int iucv_pm_thaw(struct device *); static int iucv_pm_restore(struct device *); -static struct dev_pm_ops iucv_pm_ops = { +static const struct dev_pm_ops iucv_pm_ops = { .prepare = iucv_pm_prepare, .complete = iucv_pm_complete, .freeze = iucv_pm_freeze, diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index b4b48afb6de..5d9411839cd 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c @@ -159,7 +159,7 @@ static int pxa2xx_ac97_resume(struct device *dev) return ret; } -static struct dev_pm_ops pxa2xx_ac97_pm_ops = { +static const struct dev_pm_ops pxa2xx_ac97_pm_ops = { .suspend = pxa2xx_ac97_suspend, .resume = pxa2xx_ac97_resume, }; diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.c b/sound/soc/s3c24xx/s3c24xx_simtec.c index d441c3b6463..4984754f329 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec.c +++ b/sound/soc/s3c24xx/s3c24xx_simtec.c @@ -312,7 +312,7 @@ int simtec_audio_resume(struct device *dev) return 0; } -struct dev_pm_ops simtec_audio_pmops = { +const struct dev_pm_ops simtec_audio_pmops = { .resume = simtec_audio_resume, }; EXPORT_SYMBOL_GPL(simtec_audio_pmops); diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.h b/sound/soc/s3c24xx/s3c24xx_simtec.h index 2714203af16..e18faee30cc 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec.h +++ b/sound/soc/s3c24xx/s3c24xx_simtec.h @@ -15,7 +15,7 @@ extern int simtec_audio_core_probe(struct platform_device *pdev, extern int simtec_audio_remove(struct platform_device *pdev); #ifdef CONFIG_PM -extern struct dev_pm_ops simtec_audio_pmops; +extern const struct dev_pm_ops simtec_audio_pmops; #define simtec_audio_pm &simtec_audio_pmops #else #define simtec_audio_pm NULL diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index ef8f28284cb..0a6440c6f54 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1236,7 +1236,7 @@ static int soc_poweroff(struct device *dev) return 0; } -static struct dev_pm_ops soc_pm_ops = { +static const struct dev_pm_ops soc_pm_ops = { .suspend = soc_suspend, .resume = soc_resume, .poweroff = soc_poweroff, -- cgit v1.2.3-70-g09d2 From 4039ff28a501cf6b9fc2b6a2c2b28476d7fa14cd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 5 Dec 2009 01:20:54 -0300 Subject: V4L/DVB (13544): ir-keymaps: mark the new rc5 hauppauge with IR_TYPE_RC5 While here, move the table to a better place inside the file Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-keymaps.c | 146 ++++++++++++++++++++------------------ 1 file changed, 76 insertions(+), 70 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c index 328c973a083..abb5c73fbd1 100644 --- a/drivers/media/common/ir-keymaps.c +++ b/drivers/media/common/ir-keymaps.c @@ -1847,76 +1847,6 @@ struct ir_scancode_table ir_codes_hauppauge_new_table = { }; EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table); -/* - * Hauppauge:the newer, gray remotes (seems there are multiple - * slightly different versions), shipped with cx88+ivtv cards. - * - * This table contains the complete RC5 code, instead of just the data part - */ -static struct ir_scancode ir_codes_rc5_hauppauge_new[] = { - /* Keys 0 to 9 */ - { 0x1e00, KEY_0 }, - { 0x1e01, KEY_1 }, - { 0x1e02, KEY_2 }, - { 0x1e03, KEY_3 }, - { 0x1e04, KEY_4 }, - { 0x1e05, KEY_5 }, - { 0x1e06, KEY_6 }, - { 0x1e07, KEY_7 }, - { 0x1e08, KEY_8 }, - { 0x1e09, KEY_9 }, - - { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */ - { 0x1e0b, KEY_RED }, /* red button */ - { 0x1e0c, KEY_RADIO }, - { 0x1e0d, KEY_MENU }, - { 0x1e0e, KEY_SUBTITLE }, /* also the # key */ - { 0x1e0f, KEY_MUTE }, - { 0x1e10, KEY_VOLUMEUP }, - { 0x1e11, KEY_VOLUMEDOWN }, - { 0x1e12, KEY_PREVIOUS }, /* previous channel */ - { 0x1e14, KEY_UP }, - { 0x1e15, KEY_DOWN }, - { 0x1e16, KEY_LEFT }, - { 0x1e17, KEY_RIGHT }, - { 0x1e18, KEY_VIDEO }, /* Videos */ - { 0x1e19, KEY_AUDIO }, /* Music */ - /* 0x1e1a: Pictures - presume this means - "Multimedia Home Platform" - - no "PICTURES" key in input.h - */ - { 0x1e1a, KEY_MHP }, - - { 0x1e1b, KEY_EPG }, /* Guide */ - { 0x1e1c, KEY_TV }, - { 0x1e1e, KEY_NEXTSONG }, /* skip >| */ - { 0x1e1f, KEY_EXIT }, /* back/exit */ - { 0x1e20, KEY_CHANNELUP }, /* channel / program + */ - { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */ - { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */ - { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */ - { 0x1e25, KEY_ENTER }, /* OK */ - { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */ - { 0x1e29, KEY_BLUE }, /* blue key */ - { 0x1e2e, KEY_GREEN }, /* green button */ - { 0x1e30, KEY_PAUSE }, /* pause */ - { 0x1e32, KEY_REWIND }, /* backward << */ - { 0x1e34, KEY_FASTFORWARD }, /* forward >> */ - { 0x1e35, KEY_PLAY }, - { 0x1e36, KEY_STOP }, - { 0x1e37, KEY_RECORD }, /* recording */ - { 0x1e38, KEY_YELLOW }, /* yellow key */ - { 0x1e3b, KEY_SELECT }, /* top right button */ - { 0x1e3c, KEY_ZOOM }, /* full */ - { 0x1e3d, KEY_POWER }, /* system power (green button) */ -}; - -struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = { - .scan = ir_codes_rc5_hauppauge_new, - .size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new), -}; -EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table); - static struct ir_scancode ir_codes_npgtech[] = { { 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */ { 0x2a, KEY_FRONT }, @@ -3314,3 +3244,79 @@ struct ir_scancode_table ir_codes_gadmei_rm008z_table = { }; EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table); +/************************************************************* + * COMPLETE SCANCODE TABLES + * Instead of just a partial scancode, the tables bellow + * contains the complete scancode and the receiver protocol + *************************************************************/ + +/* + * Hauppauge:the newer, gray remotes (seems there are multiple + * slightly different versions), shipped with cx88+ivtv cards. + * + * This table contains the complete RC5 code, instead of just the data part + */ +static struct ir_scancode ir_codes_rc5_hauppauge_new[] = { + /* Keys 0 to 9 */ + { 0x1e00, KEY_0 }, + { 0x1e01, KEY_1 }, + { 0x1e02, KEY_2 }, + { 0x1e03, KEY_3 }, + { 0x1e04, KEY_4 }, + { 0x1e05, KEY_5 }, + { 0x1e06, KEY_6 }, + { 0x1e07, KEY_7 }, + { 0x1e08, KEY_8 }, + { 0x1e09, KEY_9 }, + + { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */ + { 0x1e0b, KEY_RED }, /* red button */ + { 0x1e0c, KEY_RADIO }, + { 0x1e0d, KEY_MENU }, + { 0x1e0e, KEY_SUBTITLE }, /* also the # key */ + { 0x1e0f, KEY_MUTE }, + { 0x1e10, KEY_VOLUMEUP }, + { 0x1e11, KEY_VOLUMEDOWN }, + { 0x1e12, KEY_PREVIOUS }, /* previous channel */ + { 0x1e14, KEY_UP }, + { 0x1e15, KEY_DOWN }, + { 0x1e16, KEY_LEFT }, + { 0x1e17, KEY_RIGHT }, + { 0x1e18, KEY_VIDEO }, /* Videos */ + { 0x1e19, KEY_AUDIO }, /* Music */ + /* 0x1e1a: Pictures - presume this means + "Multimedia Home Platform" - + no "PICTURES" key in input.h + */ + { 0x1e1a, KEY_MHP }, + + { 0x1e1b, KEY_EPG }, /* Guide */ + { 0x1e1c, KEY_TV }, + { 0x1e1e, KEY_NEXTSONG }, /* skip >| */ + { 0x1e1f, KEY_EXIT }, /* back/exit */ + { 0x1e20, KEY_CHANNELUP }, /* channel / program + */ + { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */ + { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */ + { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */ + { 0x1e25, KEY_ENTER }, /* OK */ + { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */ + { 0x1e29, KEY_BLUE }, /* blue key */ + { 0x1e2e, KEY_GREEN }, /* green button */ + { 0x1e30, KEY_PAUSE }, /* pause */ + { 0x1e32, KEY_REWIND }, /* backward << */ + { 0x1e34, KEY_FASTFORWARD }, /* forward >> */ + { 0x1e35, KEY_PLAY }, + { 0x1e36, KEY_STOP }, + { 0x1e37, KEY_RECORD }, /* recording */ + { 0x1e38, KEY_YELLOW }, /* yellow key */ + { 0x1e3b, KEY_SELECT }, /* top right button */ + { 0x1e3c, KEY_ZOOM }, /* full */ + { 0x1e3d, KEY_POWER }, /* system power (green button) */ +}; + +struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = { + .scan = ir_codes_rc5_hauppauge_new, + .size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new), + .ir_type = IR_TYPE_RC5, +}; +EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table); -- cgit v1.2.3-70-g09d2 From 1bad429e81f9a9ffa01c4158e6d1b1a3e06d9886 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 5 Dec 2009 08:27:49 -0300 Subject: V4L/DVB (13545): em28xx: properly select IR protocol based on the IR table Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-core.c | 2 +- drivers/media/video/em28xx/em28xx-input.c | 17 +++++++++++++---- drivers/media/video/em28xx/em28xx.h | 2 ++ 3 files changed, 16 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 3f86d36dff2..4f61e05d30b 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -216,7 +216,7 @@ int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val) * sets only some bits (specified by bitmask) of a register, by first reading * the actual value */ -static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, +int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, u8 bitmask) { int oldval; diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index d96ec7c09dc..3f5cf02f314 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c @@ -337,19 +337,28 @@ int em28xx_ir_init(struct em28xx *dev) goto err_out_free; ir->input = input_dev; + ir_config = EM2874_IR_RC5; + + /* Adjust xclk based o IR table for RC5/NEC tables */ + if (dev->board.ir_codes->ir_type == IR_TYPE_RC5) { + dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; + ir->full_code = 1; + } else if (dev->board.ir_codes->ir_type == IR_TYPE_NEC) { + dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE; + ir_config = EM2874_IR_NEC; + ir->full_code = 1; + } + em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, + EM28XX_XCLK_IR_RC5_MODE); /* Setup the proper handler based on the chip */ switch (dev->chip_id) { case CHIP_ID_EM2860: case CHIP_ID_EM2883: - if (dev->model == EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950) - ir->full_code = 1; ir->get_key = default_polling_getkey; break; case CHIP_ID_EM2874: ir->get_key = em2874_polling_getkey; - /* For now we only support RC5, so enable it */ - ir_config = EM2874_IR_RC5; em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1); break; default: diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 441df644ddb..48977832316 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -643,6 +643,8 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, int len); int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len); int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val); +int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, + u8 bitmask); int em28xx_read_ac97(struct em28xx *dev, u8 reg); int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val); -- cgit v1.2.3-70-g09d2 From cda4303f555316930a219cd7c03a1925526145f0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 5 Dec 2009 09:34:21 -0300 Subject: V4L/DVB (13546): ir-keymaps: Add table for Terratec Cinergy XS FM This IR uses NEC protocol, with address=0x14. This keymap is similar to the existing Terratec Cinergy XS, except that: - it contains the full address/command code; - the Music button were mapped as KEY_RADIO; - some keycodes from the previous entry were wrong, IMHO. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-keymaps.c | 73 +++++++++++++++++++++++++++++++++++++++ include/media/ir-common.h | 1 + 2 files changed, 74 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c index abb5c73fbd1..9bbe6b1e987 100644 --- a/drivers/media/common/ir-keymaps.c +++ b/drivers/media/common/ir-keymaps.c @@ -3320,3 +3320,76 @@ struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = { .ir_type = IR_TYPE_RC5, }; EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table); + +/* Terratec Cinergy Hybrid T USB XS FM + Mauro Carvalho Chehab + */ +static struct ir_scancode ir_codes_nec_terratec_cinergy_xs[] = { + { 0x1441, KEY_HOME}, + { 0x1401, KEY_POWER2}, + + { 0x1442, KEY_MENU}, /* DVD menu */ + { 0x1443, KEY_SUBTITLE}, + { 0x1444, KEY_TEXT}, /* Teletext */ + { 0x1445, KEY_DELETE}, + + { 0x1402, KEY_1}, + { 0x1403, KEY_2}, + { 0x1404, KEY_3}, + { 0x1405, KEY_4}, + { 0x1406, KEY_5}, + { 0x1407, KEY_6}, + { 0x1408, KEY_7}, + { 0x1409, KEY_8}, + { 0x140a, KEY_9}, + { 0x140c, KEY_0}, + + { 0x140b, KEY_TUNER}, /* AV */ + { 0x140d, KEY_MODE}, /* A.B */ + + { 0x1446, KEY_TV}, + { 0x1447, KEY_DVD}, + { 0x1449, KEY_VIDEO}, + { 0x144a, KEY_RADIO}, /* Music */ + { 0x144b, KEY_CAMERA}, /* PIC */ + + { 0x1410, KEY_UP}, + { 0x1411, KEY_LEFT}, + { 0x1412, KEY_OK}, + { 0x1413, KEY_RIGHT}, + { 0x1414, KEY_DOWN}, + + { 0x140f, KEY_EPG}, + { 0x1416, KEY_INFO}, + { 0x144d, KEY_BACKSPACE}, + + { 0x141c, KEY_VOLUMEUP}, + { 0x141e, KEY_VOLUMEDOWN}, + + { 0x144c, KEY_PLAY}, + { 0x141d, KEY_MUTE}, + + { 0x141b, KEY_CHANNELUP}, + { 0x141f, KEY_CHANNELDOWN}, + + { 0x1417, KEY_RED}, + { 0x1418, KEY_GREEN}, + { 0x1419, KEY_YELLOW}, + { 0x141a, KEY_BLUE}, + + { 0x1458, KEY_RECORD}, + { 0x1448, KEY_STOP}, + { 0x1440, KEY_PAUSE}, + + { 0x1454, KEY_LAST}, + { 0x144e, KEY_REWIND}, + { 0x144f, KEY_FASTFORWARD}, + { 0x145c, KEY_NEXT}, +}; +struct ir_scancode_table ir_codes_nec_terratec_cinergy_xs_table = { + .scan = ir_codes_nec_terratec_cinergy_xs, + .size = ARRAY_SIZE(ir_codes_nec_terratec_cinergy_xs), + .ir_type = IR_TYPE_NEC, +}; +EXPORT_SYMBOL_GPL(ir_codes_nec_terratec_cinergy_xs_table); + diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 28d1b9c65f2..45bf5cf5945 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -200,4 +200,5 @@ extern struct ir_scancode_table ir_codes_evga_indtube_table; extern struct ir_scancode_table ir_codes_terratec_cinergy_xs_table; extern struct ir_scancode_table ir_codes_videomate_s350_table; extern struct ir_scancode_table ir_codes_gadmei_rm008z_table; +extern struct ir_scancode_table ir_codes_nec_terratec_cinergy_xs_table; #endif -- cgit v1.2.3-70-g09d2 From a3a9e287daa1f299e318161b790b1c5902b1d869 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 27 Nov 2009 04:33:25 -0300 Subject: V4L/DVB (13547): radio: add trivial checks on the tuner and type args. Many radio drivers did not check the tuner and type field correctly for g/s_frequency. These checks have now been added. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-aimslab.c | 4 ++++ drivers/media/radio/radio-aztech.c | 4 ++++ drivers/media/radio/radio-gemtek-pci.c | 4 ++++ drivers/media/radio/radio-maestro.c | 4 ++++ drivers/media/radio/radio-maxiradio.c | 4 ++++ drivers/media/radio/radio-mr800.c | 4 ++++ drivers/media/radio/radio-rtrack2.c | 4 ++++ drivers/media/radio/radio-sf16fmi.c | 4 ++++ drivers/media/radio/radio-sf16fmr2.c | 4 ++++ drivers/media/radio/radio-tea5764.c | 4 +++- drivers/media/radio/radio-terratec.c | 4 ++++ drivers/media/radio/radio-trust.c | 4 ++++ drivers/media/radio/radio-typhoon.c | 4 ++++ drivers/media/radio/radio-zoltrix.c | 4 ++++ 14 files changed, 55 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index 35edee009ba..5bf4985daed 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c @@ -268,6 +268,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, { struct rtrack *rt = video_drvdata(file); + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) + return -EINVAL; rt_setfreq(rt, f->frequency); return 0; } @@ -277,6 +279,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, { struct rtrack *rt = video_drvdata(file); + if (f->tuner != 0) + return -EINVAL; f->type = V4L2_TUNER_RADIO; f->frequency = rt->curfreq; return 0; diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index 8daf809eb01..c2231139362 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c @@ -254,6 +254,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, { struct aztech *az = video_drvdata(file); + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) + return -EINVAL; az_setfreq(az, f->frequency); return 0; } @@ -263,6 +265,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, { struct aztech *az = video_drvdata(file); + if (f->tuner != 0) + return -EINVAL; f->type = V4L2_TUNER_RADIO; f->frequency = az->curfreq; return 0; diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index c6cf1166186..000f4d34087 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c @@ -240,6 +240,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, { struct gemtek_pci *card = video_drvdata(file); + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) + return -EINVAL; if (f->frequency < GEMTEK_PCI_RANGE_LOW || f->frequency > GEMTEK_PCI_RANGE_HIGH) return -EINVAL; @@ -253,6 +255,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, { struct gemtek_pci *card = video_drvdata(file); + if (f->tuner != 0) + return -EINVAL; f->type = V4L2_TUNER_RADIO; f->frequency = card->current_frequency; return 0; diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index 64d737c35ac..f8213b7c8dd 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c @@ -200,6 +200,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, { struct maestro *dev = video_drvdata(file); + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) + return -EINVAL; if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) return -EINVAL; mutex_lock(&dev->lock); @@ -213,6 +215,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, { struct maestro *dev = video_drvdata(file); + if (f->tuner != 0) + return -EINVAL; f->type = V4L2_TUNER_RADIO; mutex_lock(&dev->lock); f->frequency = BITS2FREQ(radio_bits_get(dev)); diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 3da51fe8fb9..44b4dbedb32 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c @@ -262,6 +262,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, { struct maxiradio *dev = video_drvdata(file); + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) + return -EINVAL; if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) { dprintk(dev, 1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n", f->frequency / 16000, @@ -285,6 +287,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, { struct maxiradio *dev = video_drvdata(file); + if (f->tuner != 0) + return -EINVAL; f->type = V4L2_TUNER_RADIO; f->frequency = dev->freq; diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 949f60513d9..02a9cefc9a0 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -374,6 +374,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, { struct amradio_device *radio = file->private_data; + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) + return -EINVAL; return amradio_setfreq(radio, f->frequency); } @@ -383,6 +385,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, { struct amradio_device *radio = file->private_data; + if (f->tuner != 0) + return -EINVAL; f->type = V4L2_TUNER_RADIO; f->frequency = radio->curfreq; diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index 9cb193fa6e3..a79296aac9a 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c @@ -167,6 +167,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, { struct rtrack2 *rt = video_drvdata(file); + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) + return -EINVAL; rt_setfreq(rt, f->frequency); return 0; } @@ -176,6 +178,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, { struct rtrack2 *rt = video_drvdata(file); + if (f->tuner != 0) + return -EINVAL; f->type = V4L2_TUNER_RADIO; f->frequency = rt->curfreq; return 0; diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 49c4aab95da..93990b7899e 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c @@ -168,6 +168,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, { struct fmi *fmi = video_drvdata(file); + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) + return -EINVAL; if (f->frequency < RSF16_MINFREQ || f->frequency > RSF16_MAXFREQ) return -EINVAL; @@ -182,6 +184,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, { struct fmi *fmi = video_drvdata(file); + if (f->tuner != 0) + return -EINVAL; f->type = V4L2_TUNER_RADIO; f->frequency = fmi->curfreq; return 0; diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index a11414f648d..52c7bbb32b8 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c @@ -251,6 +251,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, { struct fmr2 *fmr2 = video_drvdata(file); + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) + return -EINVAL; if (f->frequency < RSF16_MINFREQ || f->frequency > RSF16_MAXFREQ) return -EINVAL; @@ -272,6 +274,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, { struct fmr2 *fmr2 = video_drvdata(file); + if (f->tuner != 0) + return -EINVAL; f->type = V4L2_TUNER_RADIO; f->frequency = fmr2->curfreq; return 0; diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c index 3cd76dddb6a..730ffd9cdd3 100644 --- a/drivers/media/radio/radio-tea5764.c +++ b/drivers/media/radio/radio-tea5764.c @@ -349,7 +349,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, { struct tea5764_device *radio = video_drvdata(file); - if (f->tuner != 0) + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) return -EINVAL; if (f->frequency == 0) { /* We special case this as a power down control. */ @@ -370,6 +370,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, struct tea5764_device *radio = video_drvdata(file); struct tea5764_regs *r = &radio->regs; + if (f->tuner != 0) + return -EINVAL; tea5764_i2c_read(radio); memset(f, 0, sizeof(f)); f->type = V4L2_TUNER_RADIO; diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index 699db9acaaf..fc1c860fd43 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c @@ -240,6 +240,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, { struct terratec *tt = video_drvdata(file); + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) + return -EINVAL; tt_setfreq(tt, f->frequency); return 0; } @@ -249,6 +251,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, { struct terratec *tt = video_drvdata(file); + if (f->tuner != 0) + return -EINVAL; f->type = V4L2_TUNER_RADIO; f->frequency = tt->curfreq; return 0; diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index 6f9ecc35935..9d6dcf8af5b 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c @@ -239,6 +239,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, { struct trust *tr = video_drvdata(file); + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) + return -EINVAL; tr_setfreq(tr, f->frequency); return 0; } @@ -248,6 +250,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, { struct trust *tr = video_drvdata(file); + if (f->tuner != 0) + return -EINVAL; f->type = V4L2_TUNER_RADIO; f->frequency = tr->curfreq; return 0; diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index 3a98f139949..03439282dfc 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c @@ -207,6 +207,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, { struct typhoon *dev = video_drvdata(file); + if (f->tuner != 0) + return -EINVAL; f->type = V4L2_TUNER_RADIO; f->frequency = dev->curfreq; return 0; @@ -217,6 +219,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, { struct typhoon *dev = video_drvdata(file); + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) + return -EINVAL; dev->curfreq = f->frequency; typhoon_setfreq(dev, dev->curfreq); return 0; diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index 80e98b6422f..f31eab99c94 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c @@ -266,6 +266,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, { struct zoltrix *zol = video_drvdata(file); + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) + return -EINVAL; if (zol_setfreq(zol, f->frequency) != 0) return -EINVAL; return 0; @@ -276,6 +278,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, { struct zoltrix *zol = video_drvdata(file); + if (f->tuner != 0) + return -EINVAL; f->type = V4L2_TUNER_RADIO; f->frequency = zol->curfreq; return 0; -- cgit v1.2.3-70-g09d2 From eac8ea536aded07004bde917f05a2329902c64b0 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 27 Nov 2009 13:56:50 -0300 Subject: V4L/DVB (13549): v4l: Add video_device_node_name function Many drivers access the device number (video_device::v4l2_devnode::num) in order to print the video device node name. Add and use a helper function to retrieve the video_device node name. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/v4l2-framework.txt | 16 ++++++++++++++-- drivers/media/video/v4l2-dev.c | 4 ++-- include/media/v4l2-dev.h | 5 +++++ 3 files changed, 21 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt index b806edaf3e7..74d677c8b03 100644 --- a/Documentation/video4linux/v4l2-framework.txt +++ b/Documentation/video4linux/v4l2-framework.txt @@ -561,6 +561,8 @@ video_device helper functions There are a few useful helper functions: +- file/video_device private data + You can set/get driver private data in the video_device struct using: void *video_get_drvdata(struct video_device *vdev); @@ -575,8 +577,7 @@ struct video_device *video_devdata(struct file *file); returns the video_device belonging to the file struct. -The final helper function combines video_get_drvdata with -video_devdata: +The video_drvdata function combines video_get_drvdata with video_devdata: void *video_drvdata(struct file *file); @@ -584,6 +585,17 @@ You can go from a video_device struct to the v4l2_device struct using: struct v4l2_device *v4l2_dev = vdev->v4l2_dev; +- Device node name + +The video_device node kernel name can be retrieved using + +const char *video_device_node_name(struct video_device *vdev); + +The name is used as a hint by userspace tools such as udev. The function +should be used where possible instead of accessing the video_device::num and +video_device::minor fields. + + video buffer helper functions ----------------------------- diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 500cbe9891a..aa3e0f9aa3b 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -551,8 +551,8 @@ static int __video_register_device(struct video_device *vdev, int type, int nr, vdev->dev.release = v4l2_device_release; if (nr != -1 && nr != vdev->num && warn_if_nr_in_use) - printk(KERN_WARNING "%s: requested %s%d, got %s%d\n", - __func__, name_base, nr, name_base, vdev->num); + printk(KERN_WARNING "%s: requested %s%d, got %s\n", __func__, + name_base, nr, video_device_node_name(vdev)); /* Part 5: Activate this minor. The char device can now be used. */ mutex_lock(&videodev_lock); diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 73c9867d744..9135f57351f 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -141,6 +141,11 @@ static inline void *video_drvdata(struct file *file) return video_get_drvdata(video_devdata(file)); } +static inline const char *video_device_node_name(struct video_device *vdev) +{ + return dev_name(&vdev->dev); +} + static inline int video_is_unregistered(struct video_device *vdev) { return test_bit(V4L2_FL_UNREGISTERED, &vdev->flags); -- cgit v1.2.3-70-g09d2 From 38c7c036036c6260606a2a833aaad3794ca22499 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 27 Nov 2009 13:57:15 -0300 Subject: V4L/DVB (13550): v4l: Use the new video_device_node_name function Fix all device drivers to use the new video_device_node_name function. This also strips kernel log messages from the "/dev/" prefix, has the device node location is a userspace policy decision unknown to the kernel. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/saa7146_fops.c | 12 +++---- drivers/media/video/arv.c | 4 +-- drivers/media/video/bt8xx/bttv-driver.c | 12 +++---- drivers/media/video/c-qcam.c | 4 +-- drivers/media/video/cpia.c | 13 +++---- drivers/media/video/cpia2/cpia2_v4l.c | 6 ++-- drivers/media/video/cx18/cx18-streams.c | 20 +++++------ drivers/media/video/cx231xx/cx231xx-cards.c | 5 +-- drivers/media/video/cx231xx/cx231xx-video.c | 25 +++++++------- drivers/media/video/cx23885/cx23885-417.c | 4 +-- drivers/media/video/cx23885/cx23885-video.c | 4 +-- drivers/media/video/cx88/cx88-blackbird.c | 4 +-- drivers/media/video/cx88/cx88-video.c | 12 +++---- drivers/media/video/em28xx/em28xx-cards.c | 4 +-- drivers/media/video/em28xx/em28xx-video.c | 20 +++++------ drivers/media/video/et61x251/et61x251_core.c | 44 ++++++++++++----------- drivers/media/video/gspca/gl860/gl860.c | 4 +-- drivers/media/video/gspca/gspca.c | 8 +++-- drivers/media/video/hdpvr/hdpvr-core.c | 10 +++--- drivers/media/video/ivtv/ivtv-streams.c | 19 +++++----- drivers/media/video/omap24xxcam.c | 3 +- drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 21 +++-------- drivers/media/video/pwc/pwc-if.c | 2 +- drivers/media/video/saa7134/saa7134-core.c | 12 +++---- drivers/media/video/saa7134/saa7134-empress.c | 4 +-- drivers/media/video/se401.c | 4 +-- drivers/media/video/sn9c102/sn9c102_core.c | 46 +++++++++++++------------ drivers/media/video/stk-webcam.c | 8 ++--- drivers/media/video/stv680.c | 4 +-- drivers/media/video/usbvideo/usbvideo.c | 4 +-- drivers/media/video/usbvideo/vicam.c | 4 +-- drivers/media/video/usbvision/usbvision-video.c | 24 ++++++------- drivers/media/video/vivi.c | 11 +++--- drivers/media/video/w9968cf.c | 30 +++++++++------- drivers/media/video/zc0301/zc0301_core.c | 43 +++++++++++++---------- drivers/media/video/zr364xx.c | 4 +-- drivers/staging/go7007/go7007-v4l2.c | 4 +-- 37 files changed, 231 insertions(+), 231 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index 620f655fa9c..f279a644041 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c @@ -543,15 +543,13 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, return err; } - if( VFL_TYPE_GRABBER == type ) { + if (VFL_TYPE_GRABBER == type) vv->video_minor = vfd->minor; - INFO(("%s: registered device video%d [v4l2]\n", - dev->name, vfd->num)); - } else { + else vv->vbi_minor = vfd->minor; - INFO(("%s: registered device vbi%d [v4l2]\n", - dev->name, vfd->num)); - } + + INFO(("%s: registered device %s [v4l2]\n", + dev->name, video_device_node_name(vfd))); *vid = vfd; return 0; diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index d137bac8451..0ec807d8279 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c @@ -860,8 +860,8 @@ static int __init ar_init(void) goto out_dev; } - printk("video%d: Found M64278 VGA (IRQ %d, Freq %dMHz).\n", - ar->vdev->num, M32R_IRQ_INT3, freq); + printk("%s: Found M64278 VGA (IRQ %d, Freq %dMHz).\n", + video_device_node_name(ar->vdev), M32R_IRQ_INT3, freq); return 0; diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index a6724019c66..d5761831989 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -4244,8 +4244,8 @@ static int __devinit bttv_register_video(struct bttv *btv) if (video_register_device(btv->video_dev, VFL_TYPE_GRABBER, video_nr[btv->c.nr]) < 0) goto err; - printk(KERN_INFO "bttv%d: registered device video%d\n", - btv->c.nr, btv->video_dev->num); + printk(KERN_INFO "bttv%d: registered device %s\n", + btv->c.nr, video_device_node_name(btv->video_dev)); if (device_create_file(&btv->video_dev->dev, &dev_attr_card)<0) { printk(KERN_ERR "bttv%d: device_create_file 'card' " @@ -4261,8 +4261,8 @@ static int __devinit bttv_register_video(struct bttv *btv) if (video_register_device(btv->vbi_dev, VFL_TYPE_VBI, vbi_nr[btv->c.nr]) < 0) goto err; - printk(KERN_INFO "bttv%d: registered device vbi%d\n", - btv->c.nr, btv->vbi_dev->num); + printk(KERN_INFO "bttv%d: registered device %s\n", + btv->c.nr, video_device_node_name(btv->vbi_dev)); if (!btv->has_radio) return 0; @@ -4273,8 +4273,8 @@ static int __devinit bttv_register_video(struct bttv *btv) if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO, radio_nr[btv->c.nr]) < 0) goto err; - printk(KERN_INFO "bttv%d: registered device radio%d\n", - btv->c.nr, btv->radio_dev->num); + printk(KERN_INFO "bttv%d: registered device %s\n", + btv->c.nr, video_device_node_name(btv->radio_dev)); /* all done */ return 0; diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index 85cf1778827..e2cbebab959 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c @@ -809,8 +809,8 @@ static int init_cqcam(struct parport *port) return -ENODEV; } - printk(KERN_INFO "video%d: Colour QuickCam found on %s\n", - qcam->vdev.num, qcam->pport->name); + printk(KERN_INFO "%s: Colour QuickCam found on %s\n", + video_device_node_name(&qcam->vdev), qcam->pport->name); qcams[num_cams++] = qcam; diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c index 2377313c041..d6f2653afb6 100644 --- a/drivers/media/video/cpia.c +++ b/drivers/media/video/cpia.c @@ -1342,15 +1342,13 @@ out: static void create_proc_cpia_cam(struct cam_data *cam) { - char name[5 + 1 + 10 + 1]; struct proc_dir_entry *ent; if (!cpia_proc_root || !cam) return; - snprintf(name, sizeof(name), "video%d", cam->vdev.num); - - ent = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, cpia_proc_root); + ent = create_proc_entry(video_device_node_name(&cam->vdev), + S_IFREG|S_IRUGO|S_IWUSR, cpia_proc_root); if (!ent) return; @@ -1368,13 +1366,10 @@ static void create_proc_cpia_cam(struct cam_data *cam) static void destroy_proc_cpia_cam(struct cam_data *cam) { - char name[5 + 1 + 10 + 1]; - if (!cam || !cam->proc_entry) return; - snprintf(name, sizeof(name), "video%d", cam->vdev.num); - remove_proc_entry(name, cpia_proc_root); + remove_proc_entry(video_device_node_name(&cam->vdev), cpia_proc_root); cam->proc_entry = NULL; } @@ -3999,7 +3994,7 @@ void cpia_unregister_camera(struct cam_data *cam) } #ifdef CONFIG_PROC_FS - DBG("destroying /proc/cpia/video%d\n", cam->vdev.num); + DBG("destroying /proc/cpia/%s\n", video_device_node_name(&cam->vdev)); destroy_proc_cpia_cam(cam); #endif if (!cam->open_count) { diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c index 0b4a8f309cf..f8952af30a3 100644 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ b/drivers/media/video/cpia2/cpia2_v4l.c @@ -1967,9 +1967,9 @@ void cpia2_unregister_camera(struct camera_data *cam) if (!cam->open_count) { video_unregister_device(cam->vdev); } else { - LOG("/dev/video%d removed while open, " - "deferring video_unregister_device\n", - cam->vdev->num); + LOG("%s removed while open, deferring " + "video_unregister_device\n", + video_device_node_name(cam->vdev)); } } diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index c398651dd74..987a9308d93 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c @@ -219,6 +219,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type) { struct cx18_stream *s = &cx->streams[type]; int vfl_type = cx18_stream_info[type].vfl_type; + const char *name; int num, ret; /* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something? @@ -258,31 +259,30 @@ static int cx18_reg_dev(struct cx18 *cx, int type) s->video_dev = NULL; return ret; } - num = s->video_dev->num; + + name = video_device_node_name(s->video_dev); switch (vfl_type) { case VFL_TYPE_GRABBER: - CX18_INFO("Registered device video%d for %s " - "(%d x %d.%02d kB)\n", - num, s->name, cx->stream_buffers[type], + CX18_INFO("Registered device %s for %s (%d x %d.%02d kB)\n", + name, s->name, cx->stream_buffers[type], cx->stream_buf_size[type] / 1024, (cx->stream_buf_size[type] * 100 / 1024) % 100); break; case VFL_TYPE_RADIO: - CX18_INFO("Registered device radio%d for %s\n", - num, s->name); + CX18_INFO("Registered device %s for %s\n", name, s->name); break; case VFL_TYPE_VBI: if (cx->stream_buffers[type]) - CX18_INFO("Registered device vbi%d for %s " + CX18_INFO("Registered device %s for %s " "(%d x %d bytes)\n", - num, s->name, cx->stream_buffers[type], + name, s->name, cx->stream_buffers[type], cx->stream_buf_size[type]); else - CX18_INFO("Registered device vbi%d for %s\n", - num, s->name); + CX18_INFO("Registered device %s for %s\n", + name, s->name); break; } diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c index 319c459459e..ff534fe7f4a 100644 --- a/drivers/media/video/cx231xx/cx231xx-cards.c +++ b/drivers/media/video/cx231xx/cx231xx-cards.c @@ -856,8 +856,9 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface) if (dev->users) { cx231xx_warn - ("device /dev/video%d is open! Deregistration and memory " - "deallocation are deferred on close.\n", dev->vdev->num); + ("device %s is open! Deregistration and memory " + "deallocation are deferred on close.\n", + video_device_node_name(dev->vdev)); dev->state |= DEV_MISCONFIGURED; cx231xx_uninit_isoc(dev); diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c index d095aa0d6d1..1c7f84e203e 100644 --- a/drivers/media/video/cx231xx/cx231xx-video.c +++ b/drivers/media/video/cx231xx/cx231xx-video.c @@ -2027,8 +2027,8 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) dev->radio_dev = NULL; } if (dev->vbi_dev) { - cx231xx_info("V4L2 device /dev/vbi%d deregistered\n", - dev->vbi_dev->num); + cx231xx_info("V4L2 device %s deregistered\n", + video_device_node_name(dev->vbi_dev)); if (-1 != dev->vbi_dev->minor) video_unregister_device(dev->vbi_dev); else @@ -2036,8 +2036,8 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) dev->vbi_dev = NULL; } if (dev->vdev) { - cx231xx_info("V4L2 device /dev/video%d deregistered\n", - dev->vdev->num); + cx231xx_info("V4L2 device %s deregistered\n", + video_device_node_name(dev->vdev)); if (-1 != dev->vdev->minor) video_unregister_device(dev->vdev); else @@ -2374,8 +2374,8 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) return ret; } - cx231xx_info("%s/0: registered device video%d [v4l2]\n", - dev->name, dev->vdev->num); + cx231xx_info("%s/0: registered device %s [v4l2]\n", + dev->name, video_device_node_name(dev->vdev)); /* Initialize VBI template */ memcpy(&cx231xx_vbi_template, &cx231xx_video_template, @@ -2393,8 +2393,8 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) return ret; } - cx231xx_info("%s/0: registered device vbi%d\n", - dev->name, dev->vbi_dev->num); + cx231xx_info("%s/0: registered device %s\n", + dev->name, video_device_node_name(dev->vbi_dev)); if (cx231xx_boards[dev->model].radio.type == CX231XX_RADIO) { dev->radio_dev = cx231xx_vdev_init(dev, &cx231xx_radio_template, @@ -2409,12 +2409,13 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) cx231xx_errdev("can't register radio device\n"); return ret; } - cx231xx_info("Registered radio device as /dev/radio%d\n", - dev->radio_dev->num); + cx231xx_info("Registered radio device as %s\n", + video_device_node_name(dev->radio_dev)); } - cx231xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n", - dev->vdev->num, dev->vbi_dev->num); + cx231xx_info("V4L2 device registered as %s and %s\n", + video_device_node_name(dev->vdev), + video_device_node_name(dev->vbi_dev)); return 0; } diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 0eed852c61e..8084e13dd10 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c @@ -1810,8 +1810,8 @@ int cx23885_417_register(struct cx23885_dev *dev) return err; } - printk(KERN_INFO "%s: registered device video%d [mpeg]\n", - dev->name, dev->v4l_device->num); + printk(KERN_INFO "%s: registered device %s [mpeg]\n", + dev->name, video_device_node_name(dev->v4l_device)); return 0; } diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 8b372b4f0de..5570383fa33 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -1532,8 +1532,8 @@ int cx23885_video_register(struct cx23885_dev *dev) dev->name); goto fail_unreg; } - printk(KERN_INFO "%s/0: registered device video%d [v4l2]\n", - dev->name, dev->video_dev->num); + printk(KERN_INFO "%s/0: registered device %s [v4l2]\n", + dev->name, video_device_node_name(dev->video_dev)); /* initial device configuration */ mutex_lock(&dev->lock); cx23885_set_tvnorm(dev, dev->tvnorm); diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index fbdc1cde56a..9f02715b4e1 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -1296,8 +1296,8 @@ static int blackbird_register_video(struct cx8802_dev *dev) dev->core->name); return err; } - printk(KERN_INFO "%s/2: registered device video%d [mpeg]\n", - dev->core->name, dev->mpeg_dev->num); + printk(KERN_INFO "%s/2: registered device %s [mpeg]\n", + dev->core->name, video_device_node_name(dev->mpeg_dev)); return 0; } diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index d7e8fcee559..55063a76a43 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -1916,8 +1916,8 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, core->name); goto fail_unreg; } - printk(KERN_INFO "%s/0: registered device video%d [v4l2]\n", - core->name, dev->video_dev->num); + printk(KERN_INFO "%s/0: registered device %s [v4l2]\n", + core->name, video_device_node_name(dev->video_dev)); dev->vbi_dev = cx88_vdev_init(core,dev->pci,&cx8800_vbi_template,"vbi"); err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI, @@ -1927,8 +1927,8 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, core->name); goto fail_unreg; } - printk(KERN_INFO "%s/0: registered device vbi%d\n", - core->name, dev->vbi_dev->num); + printk(KERN_INFO "%s/0: registered device %s\n", + core->name, video_device_node_name(dev->vbi_dev)); if (core->board.radio.type == CX88_RADIO) { dev->radio_dev = cx88_vdev_init(core,dev->pci, @@ -1940,8 +1940,8 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, core->name); goto fail_unreg; } - printk(KERN_INFO "%s/0: registered device radio%d\n", - core->name, dev->radio_dev->num); + printk(KERN_INFO "%s/0: registered device %s\n", + core->name, video_device_node_name(dev->radio_dev)); } /* everything worked */ diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 82da205047b..4ace70946d3 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -2923,9 +2923,9 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) if (dev->users) { em28xx_warn - ("device /dev/video%d is open! Deregistration and memory " + ("device %s is open! Deregistration and memory " "deallocation are deferred on close.\n", - dev->vdev->num); + video_device_node_name(dev->vdev)); dev->state |= DEV_MISCONFIGURED; em28xx_uninit_isoc(dev); diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 7ad65370f27..5cc4fff04cd 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -2167,8 +2167,8 @@ void em28xx_release_analog_resources(struct em28xx *dev) dev->radio_dev = NULL; } if (dev->vbi_dev) { - em28xx_info("V4L2 device /dev/vbi%d deregistered\n", - dev->vbi_dev->num); + em28xx_info("V4L2 device %s deregistered\n", + video_device_node_name(dev->vbi_dev)); if (-1 != dev->vbi_dev->minor) video_unregister_device(dev->vbi_dev); else @@ -2176,8 +2176,8 @@ void em28xx_release_analog_resources(struct em28xx *dev) dev->vbi_dev = NULL; } if (dev->vdev) { - em28xx_info("V4L2 device /dev/video%d deregistered\n", - dev->vdev->num); + em28xx_info("V4L2 device %s deregistered\n", + video_device_node_name(dev->vdev)); if (-1 != dev->vdev->minor) video_unregister_device(dev->vdev); else @@ -2540,16 +2540,16 @@ int em28xx_register_analog_devices(struct em28xx *dev) em28xx_errdev("can't register radio device\n"); return ret; } - em28xx_info("Registered radio device as /dev/radio%d\n", - dev->radio_dev->num); + em28xx_info("Registered radio device as %s\n", + video_device_node_name(dev->radio_dev)); } - em28xx_info("V4L2 video device registered as /dev/video%d\n", - dev->vdev->num); + em28xx_info("V4L2 video device registered as %s\n", + video_device_node_name(dev->vdev)); if (dev->vbi_dev) - em28xx_info("V4L2 VBI device registered as /dev/vbi%d\n", - dev->vbi_dev->num); + em28xx_info("V4L2 VBI device registered as %s\n", + video_device_node_name(dev->vbi_dev)); return 0; } diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index 88987a57cf7..f561a1c8679 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c @@ -587,8 +587,8 @@ static int et61x251_stream_interrupt(struct et61x251_device* cam) else if (cam->stream != STREAM_OFF) { cam->state |= DEV_MISCONFIGURED; DBG(1, "URB timeout reached. The camera is misconfigured. To " - "use it, close and open /dev/video%d again.", - cam->v4ldev->num); + "use it, close and open %s again.", + video_device_node_name(cam->v4ldev)); return -EIO; } @@ -1195,7 +1195,8 @@ static void et61x251_release_resources(struct kref *kref) cam = container_of(kref, struct et61x251_device, kref); - DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->num); + DBG(2, "V4L2 device %s deregistered", + video_device_node_name(cam->v4ldev)); video_set_drvdata(cam->v4ldev, NULL); video_unregister_device(cam->v4ldev); usb_put_dev(cam->usbdev); @@ -1236,8 +1237,8 @@ static int et61x251_open(struct file *filp) } if (cam->users) { - DBG(2, "Device /dev/video%d is already in use", - cam->v4ldev->num); + DBG(2, "Device %s is already in use", + video_device_node_name(cam->v4ldev)); DBG(3, "Simultaneous opens are not supported"); if ((filp->f_flags & O_NONBLOCK) || (filp->f_flags & O_NDELAY)) { @@ -1280,7 +1281,8 @@ static int et61x251_open(struct file *filp) cam->frame_count = 0; et61x251_empty_framequeues(cam); - DBG(3, "Video device /dev/video%d is open", cam->v4ldev->num); + DBG(3, "Video device %s is open", + video_device_node_name(cam->v4ldev)); out: mutex_unlock(&cam->open_mutex); @@ -1304,7 +1306,8 @@ static int et61x251_release(struct file *filp) cam->users--; wake_up_interruptible_nr(&cam->wait_open, 1); - DBG(3, "Video device /dev/video%d closed", cam->v4ldev->num); + DBG(3, "Video device %s closed", + video_device_node_name(cam->v4ldev)); kref_put(&cam->kref, et61x251_release_resources); @@ -1846,8 +1849,8 @@ et61x251_vidioc_s_crop(struct et61x251_device* cam, void __user * arg) if (err) { /* atomic, no rollback in ioctl() */ cam->state |= DEV_MISCONFIGURED; DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->num); + "use the camera, close and open %s again.", + video_device_node_name(cam->v4ldev)); return -EIO; } @@ -1859,8 +1862,8 @@ et61x251_vidioc_s_crop(struct et61x251_device* cam, void __user * arg) nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) { cam->state |= DEV_MISCONFIGURED; DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->num); + "use the camera, close and open %s again.", + video_device_node_name(cam->v4ldev)); return -ENOMEM; } @@ -2069,8 +2072,8 @@ et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd, if (err) { /* atomic, no rollback in ioctl() */ cam->state |= DEV_MISCONFIGURED; DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->num); + "use the camera, close and open %s again.", + video_device_node_name(cam->v4ldev)); return -EIO; } @@ -2081,8 +2084,8 @@ et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd, nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) { cam->state |= DEV_MISCONFIGURED; DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->num); + "use the camera, close and open %s again.", + video_device_node_name(cam->v4ldev)); return -ENOMEM; } @@ -2130,7 +2133,7 @@ et61x251_vidioc_s_jpegcomp(struct et61x251_device* cam, void __user * arg) cam->state |= DEV_MISCONFIGURED; DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware " "problems. To use the camera, close and open " - "/dev/video%d again.", cam->v4ldev->num); + "%s again.", video_device_node_name(cam->v4ldev)); return -EIO; } @@ -2603,7 +2606,8 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) goto fail; } - DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->num); + DBG(2, "V4L2 device registered as %s", + video_device_node_name(cam->v4ldev)); cam->module_param.force_munmap = force_munmap[dev_nr]; cam->module_param.frame_timeout = frame_timeout[dev_nr]; @@ -2654,9 +2658,9 @@ static void et61x251_usb_disconnect(struct usb_interface* intf) DBG(2, "Disconnecting %s...", cam->v4ldev->name); if (cam->users) { - DBG(2, "Device /dev/video%d is open! Deregistration and " - "memory deallocation are deferred.", - cam->v4ldev->num); + DBG(2, "Device %s is open! Deregistration and memory " + "deallocation are deferred.", + video_device_node_name(cam->v4ldev)); cam->state |= DEV_MISCONFIGURED; et61x251_stop_transfer(cam); cam->state |= DEV_DISCONNECTED; diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c index a695e0ae13c..bd3c21a37be 100644 --- a/drivers/media/video/gspca/gl860/gl860.c +++ b/drivers/media/video/gspca/gl860/gl860.c @@ -534,8 +534,8 @@ static int sd_probe(struct usb_interface *intf, gspca_dev = usb_get_intfdata(intf); PDEBUG(D_PROBE, - "Camera is now controlling video device /dev/video%d", - gspca_dev->vdev.minor); + "Camera is now controlling video device %s", + video_device_node_name(&gspca_dev->vdev)); } return ret; diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 4076f8e5a6f..6af4f233bf5 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -987,7 +987,8 @@ static void gspca_release(struct video_device *vfd) { struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev); - PDEBUG(D_PROBE, "/dev/video%d released", gspca_dev->vdev.num); + PDEBUG(D_PROBE, "%s released", + video_device_node_name(&gspca_dev->vdev)); kfree(gspca_dev->usb_buf); kfree(gspca_dev); @@ -2073,7 +2074,7 @@ int gspca_dev_probe(struct usb_interface *intf, } usb_set_intfdata(intf, gspca_dev); - PDEBUG(D_PROBE, "/dev/video%d created", gspca_dev->vdev.num); + PDEBUG(D_PROBE, "%s created", video_device_node_name(&gspca_dev->vdev)); return 0; out: kfree(gspca_dev->usb_buf); @@ -2092,7 +2093,8 @@ void gspca_disconnect(struct usb_interface *intf) { struct gspca_dev *gspca_dev = usb_get_intfdata(intf); - PDEBUG(D_PROBE, "/dev/video%d disconnect", gspca_dev->vdev.num); + PDEBUG(D_PROBE, "%s disconnect", + video_device_node_name(&gspca_dev->vdev)); mutex_lock(&gspca_dev->usb_lock); gspca_dev->present = 0; diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c index 1c9bc94c905..e280eb178fe 100644 --- a/drivers/media/video/hdpvr/hdpvr-core.c +++ b/drivers/media/video/hdpvr/hdpvr-core.c @@ -376,8 +376,8 @@ static int hdpvr_probe(struct usb_interface *interface, usb_set_intfdata(interface, dev); /* let the user know what node this device is now attached to */ - v4l2_info(&dev->v4l2_dev, "device now attached to /dev/video%d\n", - dev->video_dev->minor); + v4l2_info(&dev->v4l2_dev, "device now attached to %s\n", + video_device_node_name(dev->video_dev)); return 0; error: @@ -391,13 +391,10 @@ error: static void hdpvr_disconnect(struct usb_interface *interface) { struct hdpvr_device *dev; - int minor; dev = usb_get_intfdata(interface); usb_set_intfdata(interface, NULL); - minor = dev->video_dev->minor; - /* prevent more I/O from starting and stop any ongoing */ mutex_lock(&dev->io_mutex); dev->status = STATUS_DISCONNECTED; @@ -425,7 +422,8 @@ static void hdpvr_disconnect(struct usb_interface *interface) atomic_dec(&dev_nr); - v4l2_info(&dev->v4l2_dev, "device /dev/video%d disconnected\n", minor); + v4l2_info(&dev->v4l2_dev, "device %s disconnected\n", + video_device_node_name(dev->video_dev)); v4l2_device_unregister(&dev->v4l2_dev); kfree(dev->usbc_buf); diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index 67699e3f2aa..e12c6022373 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c @@ -245,6 +245,7 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) { struct ivtv_stream *s = &itv->streams[type]; int vfl_type = ivtv_stream_info[type].vfl_type; + const char *name; int num; if (s->vdev == NULL) @@ -268,24 +269,24 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) s->vdev = NULL; return -ENOMEM; } - num = s->vdev->num; + name = video_device_node_name(s->vdev); switch (vfl_type) { case VFL_TYPE_GRABBER: - IVTV_INFO("Registered device video%d for %s (%d kB)\n", - num, s->name, itv->options.kilobytes[type]); + IVTV_INFO("Registered device %s for %s (%d kB)\n", + name, s->name, itv->options.kilobytes[type]); break; case VFL_TYPE_RADIO: - IVTV_INFO("Registered device radio%d for %s\n", - num, s->name); + IVTV_INFO("Registered device %s for %s\n", + name, s->name); break; case VFL_TYPE_VBI: if (itv->options.kilobytes[type]) - IVTV_INFO("Registered device vbi%d for %s (%d kB)\n", - num, s->name, itv->options.kilobytes[type]); + IVTV_INFO("Registered device %s for %s (%d kB)\n", + name, s->name, itv->options.kilobytes[type]); else - IVTV_INFO("Registered device vbi%d for %s\n", - num, s->name); + IVTV_INFO("Registered device %s for %s\n", + name, s->name); break; } return 0; diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c index 5fc4ac0d88f..e2f137b0dae 100644 --- a/drivers/media/video/omap24xxcam.c +++ b/drivers/media/video/omap24xxcam.c @@ -1678,7 +1678,8 @@ static int omap24xxcam_device_register(struct v4l2_int_device *s) omap24xxcam_poweron_reset(cam); - dev_info(cam->dev, "registered device video%d\n", vfd->minor); + dev_info(cam->dev, "registered device %s\n", + video_device_node_name(vfd)); return 0; diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 6aa48e0ae73..cc8ddb2d238 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -151,17 +151,6 @@ static struct v4l2_format pvr_format [] = { }; -static const char *get_v4l_name(int v4l_type) -{ - switch (v4l_type) { - case VFL_TYPE_GRABBER: return "video"; - case VFL_TYPE_RADIO: return "radio"; - case VFL_TYPE_VBI: return "vbi"; - default: return "?"; - } -} - - /* * pvr_ioctl() * @@ -891,10 +880,8 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) { - int num = dip->devbase.num; struct pvr2_hdw *hdw = dip->v4lp->channel.mc_head->hdw; enum pvr2_config cfg = dip->config; - int v4l_type = dip->v4l_type; pvr2_hdw_v4l_store_minor_number(hdw,dip->minor_type,-1); @@ -906,8 +893,8 @@ static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) are gone. */ video_unregister_device(&dip->devbase); - printk(KERN_INFO "pvrusb2: unregistered device %s%u [%s]\n", - get_v4l_name(v4l_type), num, + printk(KERN_INFO "pvrusb2: unregistered device %s [%s]\n", + video_device_node_name(&dip->devbase), pvr2_config_get_name(cfg)); } @@ -1317,8 +1304,8 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, ": Failed to register pvrusb2 v4l device\n"); } - printk(KERN_INFO "pvrusb2: registered device %s%u [%s]\n", - get_v4l_name(dip->v4l_type), dip->devbase.num, + printk(KERN_INFO "pvrusb2: registered device %s [%s]\n", + video_device_node_name(&dip->devbase), pvr2_config_get_name(dip->config)); pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw, diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 89b620f6db7..819cf4e7c58 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -1807,7 +1807,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id goto err_video_release; } - PWC_INFO("Registered as /dev/video%d.\n", pdev->vdev->num); + PWC_INFO("Registered as %s.\n", video_device_node_name(pdev->vdev)); /* occupy slot */ if (hint < MAX_DEV_HINTS) diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 0ba7f5af0fc..c07f0727781 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -1046,8 +1046,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, dev->name); goto fail4; } - printk(KERN_INFO "%s: registered device video%d [v4l2]\n", - dev->name, dev->video_dev->num); + printk(KERN_INFO "%s: registered device %s [v4l2]\n", + dev->name, video_device_node_name(dev->video_dev)); dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi"); @@ -1055,8 +1055,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, vbi_nr[dev->nr]); if (err < 0) goto fail4; - printk(KERN_INFO "%s: registered device vbi%d\n", - dev->name, dev->vbi_dev->num); + printk(KERN_INFO "%s: registered device %s\n", + dev->name, video_device_node_name(dev->vbi_dev)); if (card_has_radio(dev)) { dev->radio_dev = vdev_init(dev,&saa7134_radio_template,"radio"); @@ -1064,8 +1064,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, radio_nr[dev->nr]); if (err < 0) goto fail4; - printk(KERN_INFO "%s: registered device radio%d\n", - dev->name, dev->radio_dev->num); + printk(KERN_INFO "%s: registered device %s\n", + dev->name, video_device_node_name(dev->radio_dev)); } /* everything worked */ diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 296788c3bf0..abc1d0bf583 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -540,8 +540,8 @@ static int empress_init(struct saa7134_dev *dev) dev->empress_dev = NULL; return err; } - printk(KERN_INFO "%s: registered device video%d [mpeg]\n", - dev->name, dev->empress_dev->num); + printk(KERN_INFO "%s: registered device %s [mpeg]\n", + dev->name, video_device_node_name(dev->empress_dev)); videobuf_queue_sg_init(&dev->empress_tsq, &saa7134_ts_qops, &dev->pci->dev, &dev->slock, diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c index 85ffc2cba03..41d0166c0f9 100644 --- a/drivers/media/video/se401.c +++ b/drivers/media/video/se401.c @@ -1428,8 +1428,8 @@ static int se401_probe(struct usb_interface *intf, err("video_register_device failed"); return -EIO; } - dev_info(&intf->dev, "registered new video device: video%d\n", - se401->vdev.num); + dev_info(&intf->dev, "registered new video device: %s\n", + video_device_node_name(&se401->vdev)); usb_set_intfdata(intf, se401); return 0; diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index 4a7711c3e74..4cf41a8d44e 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c @@ -1007,8 +1007,8 @@ static int sn9c102_stream_interrupt(struct sn9c102_device* cam) else if (cam->stream != STREAM_OFF) { cam->state |= DEV_MISCONFIGURED; DBG(1, "URB timeout reached. The camera is misconfigured. " - "To use it, close and open /dev/video%d again.", - cam->v4ldev->num); + "To use it, close and open %s again.", + video_device_node_name(cam->v4ldev)); return -EIO; } @@ -1734,7 +1734,8 @@ static void sn9c102_release_resources(struct kref *kref) cam = container_of(kref, struct sn9c102_device, kref); - DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->num); + DBG(2, "V4L2 device %s deregistered", + video_device_node_name(cam->v4ldev)); video_set_drvdata(cam->v4ldev, NULL); video_unregister_device(cam->v4ldev); usb_put_dev(cam->usbdev); @@ -1791,8 +1792,8 @@ static int sn9c102_open(struct file *filp) } if (cam->users) { - DBG(2, "Device /dev/video%d is already in use", - cam->v4ldev->num); + DBG(2, "Device %s is already in use", + video_device_node_name(cam->v4ldev)); DBG(3, "Simultaneous opens are not supported"); /* open() must follow the open flags and should block @@ -1845,7 +1846,7 @@ static int sn9c102_open(struct file *filp) cam->frame_count = 0; sn9c102_empty_framequeues(cam); - DBG(3, "Video device /dev/video%d is open", cam->v4ldev->num); + DBG(3, "Video device %s is open", video_device_node_name(cam->v4ldev)); out: mutex_unlock(&cam->open_mutex); @@ -1870,7 +1871,7 @@ static int sn9c102_release(struct file *filp) cam->users--; wake_up_interruptible_nr(&cam->wait_open, 1); - DBG(3, "Video device /dev/video%d closed", cam->v4ldev->num); + DBG(3, "Video device %s closed", video_device_node_name(cam->v4ldev)); kref_put(&cam->kref, sn9c102_release_resources); @@ -2433,8 +2434,8 @@ sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg) if (err) { /* atomic, no rollback in ioctl() */ cam->state |= DEV_MISCONFIGURED; DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->num); + "use the camera, close and open %s again.", + video_device_node_name(cam->v4ldev)); return -EIO; } @@ -2446,8 +2447,8 @@ sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg) nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) { cam->state |= DEV_MISCONFIGURED; DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->num); + "use the camera, close and open %s again.", + video_device_node_name(cam->v4ldev)); return -ENOMEM; } @@ -2690,8 +2691,8 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd, if (err) { /* atomic, no rollback in ioctl() */ cam->state |= DEV_MISCONFIGURED; DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->num); + "use the camera, close and open %s again.", + video_device_node_name(cam->v4ldev)); return -EIO; } @@ -2702,8 +2703,8 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd, nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) { cam->state |= DEV_MISCONFIGURED; DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->num); + "use the camera, close and open %s again.", + video_device_node_name(cam->v4ldev)); return -ENOMEM; } @@ -2748,9 +2749,9 @@ sn9c102_vidioc_s_jpegcomp(struct sn9c102_device* cam, void __user * arg) err += sn9c102_set_compression(cam, &jc); if (err) { /* atomic, no rollback in ioctl() */ cam->state |= DEV_MISCONFIGURED; - DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware " - "problems. To use the camera, close and open " - "/dev/video%d again.", cam->v4ldev->num); + DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware problems. " + "To use the camera, close and open %s again.", + video_device_node_name(cam->v4ldev)); return -EIO; } @@ -3346,7 +3347,8 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) goto fail; } - DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->num); + DBG(2, "V4L2 device registered as %s", + video_device_node_name(cam->v4ldev)); video_set_drvdata(cam->v4ldev, cam); cam->module_param.force_munmap = force_munmap[dev_nr]; @@ -3398,9 +3400,9 @@ static void sn9c102_usb_disconnect(struct usb_interface* intf) DBG(2, "Disconnecting %s...", cam->v4ldev->name); if (cam->users) { - DBG(2, "Device /dev/video%d is open! Deregistration and " - "memory deallocation are deferred.", - cam->v4ldev->num); + DBG(2, "Device %s is open! Deregistration and memory " + "deallocation are deferred.", + video_device_node_name(cam->v4ldev)); cam->state |= DEV_MISCONFIGURED; sn9c102_stop_transfer(cam); cam->state |= DEV_DISCONNECTED; diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index 6b41865f42b..6590b929931 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c @@ -1327,8 +1327,8 @@ static int stk_register_video_device(struct stk_camera *dev) if (err) STK_ERROR("v4l registration failed\n"); else - STK_INFO("Syntek USB2.0 Camera is now controlling video device" - " /dev/video%d\n", dev->vdev.num); + STK_INFO("Syntek USB2.0 Camera is now controlling device %s\n", + video_device_node_name(&dev->vdev)); return err; } @@ -1418,8 +1418,8 @@ static void stk_camera_disconnect(struct usb_interface *interface) wake_up_interruptible(&dev->wait_frame); stk_remove_sysfs_files(&dev->vdev); - STK_INFO("Syntek USB2.0 Camera release resources " - "video device /dev/video%d\n", dev->vdev.num); + STK_INFO("Syntek USB2.0 Camera release resources device %s\n", + video_device_node_name(&dev->vdev)); video_unregister_device(&dev->vdev); } diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c index 6a91714125d..b54222232cd 100644 --- a/drivers/media/video/stv680.c +++ b/drivers/media/video/stv680.c @@ -1467,8 +1467,8 @@ static int stv680_probe (struct usb_interface *intf, const struct usb_device_id retval = -EIO; goto error_vdev; } - PDEBUG(0, "STV(i): registered new video device: video%d", - stv680->vdev->num); + PDEBUG(0, "STV(i): registered new video device: %s", + video_device_node_name(stv680->vdev)); usb_set_intfdata (intf, stv680); retval = stv680_create_sysfs_files(stv680->vdev); diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c index dea8b321fb4..5ac37c6c431 100644 --- a/drivers/media/video/usbvideo/usbvideo.c +++ b/drivers/media/video/usbvideo/usbvideo.c @@ -1053,9 +1053,9 @@ int usbvideo_RegisterVideoDevice(struct uvd *uvd) "%s: video_register_device() successful\n", __func__); } - dev_info(&uvd->dev->dev, "%s on /dev/video%d: canvas=%s videosize=%s\n", + dev_info(&uvd->dev->dev, "%s on %s: canvas=%s videosize=%s\n", (uvd->handle != NULL) ? uvd->handle->drvName : "???", - uvd->vdev.num, tmp2, tmp1); + video_device_node_name(&uvd->vdev), tmp2, tmp1); usb_get_dev(uvd->dev); return 0; diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c index 45fce39ec9a..b75143ee5dd 100644 --- a/drivers/media/video/usbvideo/vicam.c +++ b/drivers/media/video/usbvideo/vicam.c @@ -873,8 +873,8 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id) return -EIO; } - printk(KERN_INFO "ViCam webcam driver now controlling video device %d\n", - cam->vdev.num); + printk(KERN_INFO "ViCam webcam driver now controlling device %s\n", + video_device_node_name(&cam->vdev)); usb_set_intfdata (intf, cam); diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index c07b0ac452a..639c3396ae7 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -1416,8 +1416,8 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision) { // vbi Device: if (usbvision->vbi) { - PDEBUG(DBG_PROBE, "unregister /dev/vbi%d [v4l2]", - usbvision->vbi->num); + PDEBUG(DBG_PROBE, "unregister %s [v4l2]", + video_device_node_name(usbvision->vbi)); if (usbvision->vbi->minor != -1) { video_unregister_device(usbvision->vbi); } else { @@ -1428,8 +1428,8 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision) // Radio Device: if (usbvision->rdev) { - PDEBUG(DBG_PROBE, "unregister /dev/radio%d [v4l2]", - usbvision->rdev->num); + PDEBUG(DBG_PROBE, "unregister %s [v4l2]", + video_device_node_name(usbvision->rdev)); if (usbvision->rdev->minor != -1) { video_unregister_device(usbvision->rdev); } else { @@ -1440,8 +1440,8 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision) // Video Device: if (usbvision->vdev) { - PDEBUG(DBG_PROBE, "unregister /dev/video%d [v4l2]", - usbvision->vdev->num); + PDEBUG(DBG_PROBE, "unregister %s [v4l2]", + video_device_node_name(usbvision->vdev)); if (usbvision->vdev->minor != -1) { video_unregister_device(usbvision->vdev); } else { @@ -1466,8 +1466,8 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision) video_nr)<0) { goto err_exit; } - printk(KERN_INFO "USBVision[%d]: registered USBVision Video device /dev/video%d [v4l2]\n", - usbvision->nr, usbvision->vdev->num); + printk(KERN_INFO "USBVision[%d]: registered USBVision Video device %s [v4l2]\n", + usbvision->nr, video_device_node_name(usbvision->vdev)); // Radio Device: if (usbvision_device_data[usbvision->DevModel].Radio) { @@ -1483,8 +1483,8 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision) radio_nr)<0) { goto err_exit; } - printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device /dev/radio%d [v4l2]\n", - usbvision->nr, usbvision->rdev->num); + printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device %s [v4l2]\n", + usbvision->nr, video_device_node_name(usbvision->rdev)); } // vbi Device: if (usbvision_device_data[usbvision->DevModel].vbi) { @@ -1499,8 +1499,8 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision) vbi_nr)<0) { goto err_exit; } - printk(KERN_INFO "USBVision[%d]: registered USBVision VBI device /dev/vbi%d [v4l2] (Not Working Yet!)\n", - usbvision->nr, usbvision->vbi->num); + printk(KERN_INFO "USBVision[%d]: registered USBVision VBI device %s [v4l2] (Not Working Yet!)\n", + usbvision->nr, video_device_node_name(usbvision->vbi)); } // all done return 0; diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 7705fc6baf0..48f5a628c06 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -1148,7 +1148,8 @@ static int vivi_open(struct file *file) return -EBUSY; } - dprintk(dev, 1, "open /dev/video%d type=%s users=%d\n", dev->vfd->num, + dprintk(dev, 1, "open %s type=%s users=%d\n", + video_device_node_name(dev->vfd), v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users); /* allocate + initialize per filehandle data */ @@ -1317,8 +1318,8 @@ static int vivi_release(void) list_del(list); dev = list_entry(list, struct vivi_dev, vivi_devlist); - v4l2_info(&dev->v4l2_dev, "unregistering /dev/video%d\n", - dev->vfd->num); + v4l2_info(&dev->v4l2_dev, "unregistering %s\n", + video_device_node_name(dev->vfd)); video_unregister_device(dev->vfd); v4l2_device_unregister(&dev->v4l2_dev); kfree(dev); @@ -1379,8 +1380,8 @@ static int __init vivi_create_instance(int inst) video_nr++; dev->vfd = vfd; - v4l2_info(&dev->v4l2_dev, "V4L2 device registered as /dev/video%d\n", - vfd->num); + v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n", + video_device_node_name(vfd)); return 0; rel_vdev: diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c index 37fcdc447db..695ad2f4609 100644 --- a/drivers/media/video/w9968cf.c +++ b/drivers/media/video/w9968cf.c @@ -2323,9 +2323,9 @@ static int w9968cf_sensor_init(struct w9968cf_device* cam) error: cam->sensor_initialized = 0; cam->sensor = CC_UNKNOWN; - DBG(1, "Image sensor initialization failed for %s (/dev/video%d). " + DBG(1, "Image sensor initialization failed for %s (%s). " "Try to detach and attach this device again", - symbolic(camlist, cam->id), cam->v4ldev->num) + symbolic(camlist, cam->id), video_device_node_name(cam->v4ldev)) return err; } @@ -2571,7 +2571,8 @@ static void w9968cf_release_resources(struct w9968cf_device* cam) { mutex_lock(&w9968cf_devlist_mutex); - DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->num) + DBG(2, "V4L device deregistered: %s", + video_device_node_name(cam->v4ldev)) video_unregister_device(cam->v4ldev); list_del(&cam->v4llist); @@ -2605,17 +2606,19 @@ static int w9968cf_open(struct file *filp) if (cam->sensor == CC_UNKNOWN) { DBG(2, "No supported image sensor has been detected by the " - "'ovcamchip' module for the %s (/dev/video%d). Make " - "sure it is loaded *before* (re)connecting the camera.", - symbolic(camlist, cam->id), cam->v4ldev->num) + "'ovcamchip' module for the %s (%s). Make sure " + "it is loaded *before* (re)connecting the camera.", + symbolic(camlist, cam->id), + video_device_node_name(cam->v4ldev)) mutex_unlock(&cam->dev_mutex); up_read(&w9968cf_disconnect); return -ENODEV; } if (cam->users) { - DBG(2, "%s (/dev/video%d) has been already occupied by '%s'", - symbolic(camlist, cam->id), cam->v4ldev->num, cam->command) + DBG(2, "%s (%s) has been already occupied by '%s'", + symbolic(camlist, cam->id), + video_device_node_name(cam->v4ldev), cam->command) if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) { mutex_unlock(&cam->dev_mutex); up_read(&w9968cf_disconnect); @@ -2636,8 +2639,8 @@ static int w9968cf_open(struct file *filp) mutex_lock(&cam->dev_mutex); } - DBG(5, "Opening '%s', /dev/video%d ...", - symbolic(camlist, cam->id), cam->v4ldev->num) + DBG(5, "Opening '%s', %s ...", + symbolic(camlist, cam->id), video_device_node_name(cam->v4ldev)) cam->streaming = 0; cam->misconfigured = 0; @@ -3501,7 +3504,8 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) goto fail; } - DBG(2, "V4L device registered as /dev/video%d", cam->v4ldev->num) + DBG(2, "V4L device registered as %s", + video_device_node_name(cam->v4ldev)) /* Set some basic constants */ w9968cf_configure_camera(cam, udev, mod_id, dev_nr); @@ -3557,10 +3561,10 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf) wake_up_interruptible_all(&cam->open); if (cam->users) { - DBG(2, "The device is open (/dev/video%d)! " + DBG(2, "The device is open (%s)! " "Process name: %s. Deregistration and memory " "deallocation are deferred on close.", - cam->v4ldev->num, cam->command) + video_device_node_name(cam->v4ldev), cam->command) cam->misconfigured = 1; w9968cf_stop_transfer(cam); wake_up_interruptible(&cam->wait_queue); diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c index 312a71336fd..524eb754c97 100644 --- a/drivers/media/video/zc0301/zc0301_core.c +++ b/drivers/media/video/zc0301/zc0301_core.c @@ -538,8 +538,8 @@ static int zc0301_stream_interrupt(struct zc0301_device* cam) else if (cam->stream != STREAM_OFF) { cam->state |= DEV_MISCONFIGURED; DBG(1, "URB timeout reached. The camera is misconfigured. To " - "use it, close and open /dev/video%d again.", - cam->v4ldev->num); + "use it, close and open %s again.", + video_device_node_name(cam->v4ldev)); return -EIO; } @@ -640,7 +640,8 @@ static void zc0301_release_resources(struct kref *kref) { struct zc0301_device *cam = container_of(kref, struct zc0301_device, kref); - DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->num); + DBG(2, "V4L2 device %s deregistered", + video_device_node_name(cam->v4ldev)); video_set_drvdata(cam->v4ldev, NULL); video_unregister_device(cam->v4ldev); usb_put_dev(cam->usbdev); @@ -679,7 +680,8 @@ static int zc0301_open(struct file *filp) } if (cam->users) { - DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->num); + DBG(2, "Device %s is busy...", + video_device_node_name(cam->v4ldev)); DBG(3, "Simultaneous opens are not supported"); if ((filp->f_flags & O_NONBLOCK) || (filp->f_flags & O_NDELAY)) { @@ -722,7 +724,8 @@ static int zc0301_open(struct file *filp) cam->frame_count = 0; zc0301_empty_framequeues(cam); - DBG(3, "Video device /dev/video%d is open", cam->v4ldev->num); + DBG(3, "Video device %s is open", + video_device_node_name(cam->v4ldev)); out: mutex_unlock(&cam->open_mutex); @@ -746,7 +749,8 @@ static int zc0301_release(struct file *filp) cam->users--; wake_up_interruptible_nr(&cam->wait_open, 1); - DBG(3, "Video device /dev/video%d closed", cam->v4ldev->num); + DBG(3, "Video device %s closed", + video_device_node_name(cam->v4ldev)); kref_put(&cam->kref, zc0301_release_resources); @@ -1276,8 +1280,8 @@ zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg) if (err) { /* atomic, no rollback in ioctl() */ cam->state |= DEV_MISCONFIGURED; DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->num); + "use the camera, close and open %s again.", + video_device_node_name(cam->v4ldev)); return -EIO; } @@ -1289,8 +1293,8 @@ zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg) nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) { cam->state |= DEV_MISCONFIGURED; DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->num); + "use the camera, close and open %s again.", + video_device_node_name(cam->v4ldev)); return -ENOMEM; } @@ -1471,8 +1475,8 @@ zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd, if (err) { /* atomic, no rollback in ioctl() */ cam->state |= DEV_MISCONFIGURED; DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->num); + "use the camera, close and open %s again.", + video_device_node_name(cam->v4ldev)); return -EIO; } @@ -1483,8 +1487,8 @@ zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd, nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) { cam->state |= DEV_MISCONFIGURED; DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To " - "use the camera, close and open /dev/video%d again.", - cam->v4ldev->num); + "use the camera, close and open %s again.", + video_device_node_name(cam->v4ldev)); return -ENOMEM; } @@ -1530,8 +1534,8 @@ zc0301_vidioc_s_jpegcomp(struct zc0301_device* cam, void __user * arg) if (err) { /* atomic, no rollback in ioctl() */ cam->state |= DEV_MISCONFIGURED; DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware " - "problems. To use the camera, close and open " - "/dev/video%d again.", cam->v4ldev->num); + "problems. To use the camera, close and open %s again.", + video_device_node_name(cam->v4ldev)); return -EIO; } @@ -2003,7 +2007,8 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) goto fail; } - DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->num); + DBG(2, "V4L2 device registered as %s", + video_device_node_name(cam->v4ldev)); cam->module_param.force_munmap = force_munmap[dev_nr]; cam->module_param.frame_timeout = frame_timeout[dev_nr]; @@ -2040,9 +2045,9 @@ static void zc0301_usb_disconnect(struct usb_interface* intf) DBG(2, "Disconnecting %s...", cam->v4ldev->name); if (cam->users) { - DBG(2, "Device /dev/video%d is open! Deregistration and " + DBG(2, "Device %s is open! Deregistration and " "memory deallocation are deferred.", - cam->v4ldev->num); + video_device_node_name(cam->v4ldev)); cam->state |= DEV_MISCONFIGURED; zc0301_stop_transfer(cam); cam->state |= DEV_DISCONNECTED; diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c index 2ef110b5221..69ea6df62ab 100644 --- a/drivers/media/video/zr364xx.c +++ b/drivers/media/video/zr364xx.c @@ -1635,8 +1635,8 @@ static int zr364xx_probe(struct usb_interface *intf, spin_lock_init(&cam->slock); - dev_info(&udev->dev, DRIVER_DESC " controlling video device %d\n", - cam->vdev->num); + dev_info(&udev->dev, DRIVER_DESC " controlling device %s\n", + video_device_node_name(cam->vdev)); return 0; } diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c index b18d8e2d4c5..fe739752c92 100644 --- a/drivers/staging/go7007/go7007-v4l2.c +++ b/drivers/staging/go7007/go7007-v4l2.c @@ -1817,8 +1817,8 @@ int go7007_v4l2_init(struct go7007 *go) } video_set_drvdata(go->video_dev, go); ++go->ref_count; - printk(KERN_INFO "%s: registered device video%d [v4l2]\n", - go->video_dev->name, go->video_dev->num); + printk(KERN_INFO "%s: registered device %s [v4l2]\n", + go->video_dev->name, video_device_node_name(go->video_dev)); return 0; } -- cgit v1.2.3-70-g09d2 From 0fda5d4420fe1d6a19189386b6bc6532c97a7e0e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 27 Nov 2009 13:57:18 -0300 Subject: V4L/DVB (13551): v4l: Remove video_device::num usage from device drivers Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/usbvision/usbvision-i2c.c | 4 ++-- drivers/media/video/vivi.c | 3 --- drivers/media/video/w9968cf.c | 3 +-- 3 files changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c index c19f51dba2e..0613922997e 100644 --- a/drivers/media/video/usbvision/usbvision-i2c.c +++ b/drivers/media/video/usbvision/usbvision-i2c.c @@ -215,8 +215,8 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision) memcpy(&usbvision->i2c_adap, &i2c_adap_template, sizeof(struct i2c_adapter)); - sprintf(usbvision->i2c_adap.name + strlen(usbvision->i2c_adap.name), - " #%d", usbvision->vdev->num); + sprintf(usbvision->i2c_adap.name, "%s-%d-%s", i2c_adap_template.name, + usbvision->dev->bus->busnum, usbvision->dev->devpath); PDEBUG(DBG_I2C,"Adaptername: %s", usbvision->i2c_adap.name); usbvision->i2c_adap.dev.parent = &usbvision->dev->dev; diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 48f5a628c06..93e0a258080 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -1373,9 +1373,6 @@ static int __init vivi_create_instance(int inst) /* Now that everything is fine, let's add it to device list */ list_add_tail(&dev->vivi_devlist, &vivi_devlist); - snprintf(vfd->name, sizeof(vfd->name), "%s (%i)", - vivi_template.name, vfd->num); - if (video_nr >= 0) video_nr++; diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c index 695ad2f4609..3af6d6b3186 100644 --- a/drivers/media/video/w9968cf.c +++ b/drivers/media/video/w9968cf.c @@ -2877,8 +2877,7 @@ static long w9968cf_v4l_ioctl(struct file *filp, .minwidth = cam->minwidth, .minheight = cam->minheight, }; - sprintf(cap.name, "W996[87]CF USB Camera #%d", - cam->v4ldev->num); + sprintf(cap.name, "W996[87]CF USB Camera"); cap.maxwidth = (cam->upscaling && w9968cf_vpp) ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth) : cam->maxwidth; -- cgit v1.2.3-70-g09d2 From 957b4aa9f786cf04585a690a2e4c3dc867ce80e9 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 27 Nov 2009 13:57:22 -0300 Subject: V4L/DVB (13552): v4l: Replace video_is_unregistered with video_is_registered Replace the video_is_unregistered function by a video_is_registered function. The V4L2_FL_UNREGISTERED flag is replaced by a V4L2_FL_REGISTERED flag. This change makes the video_is_registered function return coherent results when called on an initialize but not yet registered video_device instance. The function can now be used instead of checking video_device::minor. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/hdpvr/hdpvr-video.c | 2 +- drivers/media/video/v4l2-dev.c | 18 +++++++++--------- include/media/v4l2-dev.h | 18 ++++++++---------- 3 files changed, 18 insertions(+), 20 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c index b5439cabb38..fdd782039e9 100644 --- a/drivers/media/video/hdpvr/hdpvr-video.c +++ b/drivers/media/video/hdpvr/hdpvr-video.c @@ -523,7 +523,7 @@ static unsigned int hdpvr_poll(struct file *filp, poll_table *wait) mutex_lock(&dev->io_mutex); - if (video_is_unregistered(dev->video_dev)) { + if (!video_is_registered(dev->video_dev)) { mutex_unlock(&dev->io_mutex); return -EIO; } diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index aa3e0f9aa3b..70906991606 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -189,7 +189,7 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf, if (!vdev->fops->read) return -EINVAL; - if (video_is_unregistered(vdev)) + if (!video_is_registered(vdev)) return -EIO; return vdev->fops->read(filp, buf, sz, off); } @@ -201,7 +201,7 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf, if (!vdev->fops->write) return -EINVAL; - if (video_is_unregistered(vdev)) + if (!video_is_registered(vdev)) return -EIO; return vdev->fops->write(filp, buf, sz, off); } @@ -210,7 +210,7 @@ static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) { struct video_device *vdev = video_devdata(filp); - if (!vdev->fops->poll || video_is_unregistered(vdev)) + if (!vdev->fops->poll || !video_is_registered(vdev)) return DEFAULT_POLLMASK; return vdev->fops->poll(filp, poll); } @@ -250,7 +250,7 @@ static unsigned long v4l2_get_unmapped_area(struct file *filp, if (!vdev->fops->get_unmapped_area) return -ENOSYS; - if (video_is_unregistered(vdev)) + if (!video_is_registered(vdev)) return -ENODEV; return vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags); } @@ -260,8 +260,7 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) { struct video_device *vdev = video_devdata(filp); - if (!vdev->fops->mmap || - video_is_unregistered(vdev)) + if (!vdev->fops->mmap || !video_is_registered(vdev)) return -ENODEV; return vdev->fops->mmap(filp, vm); } @@ -277,7 +276,7 @@ static int v4l2_open(struct inode *inode, struct file *filp) vdev = video_devdata(filp); /* return ENODEV if the video device has been removed already or if it is not registered anymore. */ - if (vdev == NULL || video_is_unregistered(vdev)) { + if (vdev == NULL || !video_is_registered(vdev)) { mutex_unlock(&videodev_lock); return -ENODEV; } @@ -555,6 +554,7 @@ static int __video_register_device(struct video_device *vdev, int type, int nr, name_base, nr, video_device_node_name(vdev)); /* Part 5: Activate this minor. The char device can now be used. */ + set_bit(V4L2_FL_REGISTERED, &vdev->flags); mutex_lock(&videodev_lock); video_device[vdev->minor] = vdev; mutex_unlock(&videodev_lock); @@ -593,11 +593,11 @@ EXPORT_SYMBOL(video_register_device_no_warn); void video_unregister_device(struct video_device *vdev) { /* Check if vdev was ever registered at all */ - if (!vdev || vdev->minor < 0) + if (!vdev || !video_is_registered(vdev)) return; mutex_lock(&videodev_lock); - set_bit(V4L2_FL_UNREGISTERED, &vdev->flags); + clear_bit(V4L2_FL_REGISTERED, &vdev->flags); mutex_unlock(&videodev_lock); device_unregister(&vdev->dev); } diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 9135f57351f..2dee93892ea 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -28,10 +28,10 @@ struct v4l2_ioctl_callbacks; struct video_device; struct v4l2_device; -/* Flag to mark the video_device struct as unregistered. - Drivers can set this flag if they want to block all future - device access. It is set by video_unregister_device. */ -#define V4L2_FL_UNREGISTERED (0) +/* Flag to mark the video_device struct as registered. + Drivers can clear this flag if they want to block all future + device access. It is cleared by video_unregister_device. */ +#define V4L2_FL_REGISTERED (0) struct v4l2_file_operations { struct module *owner; @@ -96,9 +96,7 @@ struct video_device /* Register video devices. Note that if video_register_device fails, the release() callback of the video_device structure is *not* called, so the caller is responsible for freeing any data. Usually that means that - you call video_device_release() on failure. - - Also note that vdev->minor is set to -1 if the registration failed. */ + you call video_device_release() on failure. */ int __must_check video_register_device(struct video_device *vdev, int type, int nr); /* Same as video_register_device, but no warning is issued if the desired @@ -106,7 +104,7 @@ int __must_check video_register_device(struct video_device *vdev, int type, int int __must_check video_register_device_no_warn(struct video_device *vdev, int type, int nr); /* Unregister video devices. Will do nothing if vdev == NULL or - vdev->minor < 0. */ + video_is_registered() returns false. */ void video_unregister_device(struct video_device *vdev); /* helper functions to alloc/release struct video_device, the @@ -146,9 +144,9 @@ static inline const char *video_device_node_name(struct video_device *vdev) return dev_name(&vdev->dev); } -static inline int video_is_unregistered(struct video_device *vdev) +static inline int video_is_registered(struct video_device *vdev) { - return test_bit(V4L2_FL_UNREGISTERED, &vdev->flags); + return test_bit(V4L2_FL_REGISTERED, &vdev->flags); } #endif /* _V4L2_DEV_H */ -- cgit v1.2.3-70-g09d2 From f0813b4c9f7ffbeaddcba1c08a1812f7ff30e1b7 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 27 Nov 2009 13:57:30 -0300 Subject: V4L/DVB (13553): v4l: Use the video_is_registered function in device drivers Fix all device drivers to use the video_is_registered function instead of checking video_device::minor. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bt8xx/bttv-driver.c | 6 +++--- drivers/media/video/cx231xx/cx231xx-video.c | 6 +++--- drivers/media/video/cx23885/cx23885-417.c | 2 +- drivers/media/video/cx23885/cx23885-video.c | 2 +- drivers/media/video/cx88/cx88-blackbird.c | 2 +- drivers/media/video/cx88/cx88-video.c | 6 +++--- drivers/media/video/davinci/vpfe_capture.c | 2 +- drivers/media/video/em28xx/em28xx-video.c | 6 +++--- drivers/media/video/omap24xxcam.c | 2 +- drivers/media/video/ov511.c | 2 +- drivers/media/video/s2255drv.c | 2 +- drivers/media/video/saa7134/saa7134-core.c | 6 +++--- drivers/media/video/stradis.c | 2 +- drivers/media/video/usbvision/usbvision-video.c | 6 +++--- drivers/staging/cx25821/cx25821-video.c | 4 ++-- 15 files changed, 28 insertions(+), 28 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index d5761831989..a2336915ca7 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -4208,21 +4208,21 @@ static struct video_device *vdev_init(struct bttv *btv, static void bttv_unregister_video(struct bttv *btv) { if (btv->video_dev) { - if (-1 != btv->video_dev->minor) + if (video_is_registered(btv->video_dev)) video_unregister_device(btv->video_dev); else video_device_release(btv->video_dev); btv->video_dev = NULL; } if (btv->vbi_dev) { - if (-1 != btv->vbi_dev->minor) + if (video_is_registered(btv->vbi_dev)) video_unregister_device(btv->vbi_dev); else video_device_release(btv->vbi_dev); btv->vbi_dev = NULL; } if (btv->radio_dev) { - if (-1 != btv->radio_dev->minor) + if (video_is_registered(btv->radio_dev)) video_unregister_device(btv->radio_dev); else video_device_release(btv->radio_dev); diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c index 1c7f84e203e..71e152dc279 100644 --- a/drivers/media/video/cx231xx/cx231xx-video.c +++ b/drivers/media/video/cx231xx/cx231xx-video.c @@ -2020,7 +2020,7 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) /*FIXME: I2C IR should be disconnected */ if (dev->radio_dev) { - if (-1 != dev->radio_dev->minor) + if (video_is_registered(dev->radio_dev)) video_unregister_device(dev->radio_dev); else video_device_release(dev->radio_dev); @@ -2029,7 +2029,7 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) if (dev->vbi_dev) { cx231xx_info("V4L2 device %s deregistered\n", video_device_node_name(dev->vbi_dev)); - if (-1 != dev->vbi_dev->minor) + if (video_is_registered(dev->vbi_dev)) video_unregister_device(dev->vbi_dev); else video_device_release(dev->vbi_dev); @@ -2038,7 +2038,7 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) if (dev->vdev) { cx231xx_info("V4L2 device %s deregistered\n", video_device_node_name(dev->vdev)); - if (-1 != dev->vdev->minor) + if (video_is_registered(dev->vdev)) video_unregister_device(dev->vdev); else video_device_release(dev->vdev); diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 8084e13dd10..a7bfe7c3a44 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c @@ -1746,7 +1746,7 @@ void cx23885_417_unregister(struct cx23885_dev *dev) dprintk(1, "%s()\n", __func__); if (dev->v4l_device) { - if (-1 != dev->v4l_device->minor) + if (video_is_registered(dev->v4l_device)) video_unregister_device(dev->v4l_device); else video_device_release(dev->v4l_device); diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 5570383fa33..fd98121361f 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -1461,7 +1461,7 @@ void cx23885_video_unregister(struct cx23885_dev *dev) cx_clear(PCI_INT_MSK, 1); if (dev->video_dev) { - if (-1 != dev->video_dev->minor) + if (video_is_registered(dev->video_dev)) video_unregister_device(dev->video_dev); else video_device_release(dev->video_dev); diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 9f02715b4e1..5186f87b4ec 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -1276,7 +1276,7 @@ static int cx8802_blackbird_advise_release(struct cx8802_driver *drv) static void blackbird_unregister_video(struct cx8802_dev *dev) { if (dev->mpeg_dev) { - if (-1 != dev->mpeg_dev->minor) + if (video_is_registered(dev->mpeg_dev)) video_unregister_device(dev->mpeg_dev); else video_device_release(dev->mpeg_dev); diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 55063a76a43..0259ac6d814 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -1778,21 +1778,21 @@ static struct video_device cx8800_radio_template = { static void cx8800_unregister_video(struct cx8800_dev *dev) { if (dev->radio_dev) { - if (-1 != dev->radio_dev->minor) + if (video_is_registered(dev->radio_dev)) video_unregister_device(dev->radio_dev); else video_device_release(dev->radio_dev); dev->radio_dev = NULL; } if (dev->vbi_dev) { - if (-1 != dev->vbi_dev->minor) + if (video_is_registered(dev->vbi_dev)) video_unregister_device(dev->vbi_dev); else video_device_release(dev->vbi_dev); dev->vbi_dev = NULL; } if (dev->video_dev) { - if (-1 != dev->video_dev->minor) + if (video_is_registered(dev->video_dev)) video_unregister_device(dev->video_dev); else video_device_release(dev->video_dev); diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c index c3916a42668..1e8579438ef 100644 --- a/drivers/media/video/davinci/vpfe_capture.c +++ b/drivers/media/video/davinci/vpfe_capture.c @@ -2071,7 +2071,7 @@ probe_out_video_unregister: probe_out_v4l2_unregister: v4l2_device_unregister(&vpfe_dev->v4l2_dev); probe_out_video_release: - if (vpfe_dev->video_dev->minor == -1) + if (!video_is_registered(vpfe_dev->video_dev)) video_device_release(vpfe_dev->video_dev); probe_out_release_irq: free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 5cc4fff04cd..9a8ff32cb31 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -2160,7 +2160,7 @@ void em28xx_release_analog_resources(struct em28xx *dev) /*FIXME: I2C IR should be disconnected */ if (dev->radio_dev) { - if (-1 != dev->radio_dev->minor) + if (video_is_registered(dev->radio_dev)) video_unregister_device(dev->radio_dev); else video_device_release(dev->radio_dev); @@ -2169,7 +2169,7 @@ void em28xx_release_analog_resources(struct em28xx *dev) if (dev->vbi_dev) { em28xx_info("V4L2 device %s deregistered\n", video_device_node_name(dev->vbi_dev)); - if (-1 != dev->vbi_dev->minor) + if (video_is_registered(dev->vbi_dev)) video_unregister_device(dev->vbi_dev); else video_device_release(dev->vbi_dev); @@ -2178,7 +2178,7 @@ void em28xx_release_analog_resources(struct em28xx *dev) if (dev->vdev) { em28xx_info("V4L2 device %s deregistered\n", video_device_node_name(dev->vdev)); - if (-1 != dev->vdev->minor) + if (video_is_registered(dev->vdev)) video_unregister_device(dev->vdev); else video_device_release(dev->vdev); diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c index e2f137b0dae..34eb9659433 100644 --- a/drivers/media/video/omap24xxcam.c +++ b/drivers/media/video/omap24xxcam.c @@ -1696,7 +1696,7 @@ static void omap24xxcam_device_unregister(struct v4l2_int_device *s) omap24xxcam_sensor_exit(cam); if (cam->vfd) { - if (cam->vfd->minor == -1) { + if (!video_is_registered(cam->vfd)) { /* * The device was never registered, so release the * video_device struct directly. diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index 0bc2cf573c7..b636160fd51 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c @@ -5884,7 +5884,7 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) error: if (ov->vdev) { - if (-1 == ov->vdev->minor) + if (!video_is_registered(ov->vdev)) video_device_release(ov->vdev); else video_unregister_device(ov->vdev); diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 41765f3c7c2..4201abcf8f6 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c @@ -1880,7 +1880,7 @@ static void s2255_exit_v4l(struct s2255_dev *dev) int i; for (i = 0; i < MAX_CHANNELS; i++) { - if (-1 != dev->vdev[i]->minor) { + if (video_is_registered(dev->vdev[i])) { video_unregister_device(dev->vdev[i]); printk(KERN_INFO "s2255 unregistered\n"); } else { diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index c07f0727781..b910df94ed7 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -803,21 +803,21 @@ static struct video_device *vdev_init(struct saa7134_dev *dev, static void saa7134_unregister_video(struct saa7134_dev *dev) { if (dev->video_dev) { - if (-1 != dev->video_dev->minor) + if (video_is_registered(dev->video_dev)) video_unregister_device(dev->video_dev); else video_device_release(dev->video_dev); dev->video_dev = NULL; } if (dev->vbi_dev) { - if (-1 != dev->vbi_dev->minor) + if (video_is_registered(dev->vbi_dev)) video_unregister_device(dev->vbi_dev); else video_device_release(dev->vbi_dev); dev->vbi_dev = NULL; } if (dev->radio_dev) { - if (-1 != dev->radio_dev->minor) + if (video_is_registered(dev->radio_dev)) video_unregister_device(dev->radio_dev); else video_device_release(dev->radio_dev); diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index eaada39c76f..c8909056215 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c @@ -2134,7 +2134,7 @@ static void stradis_release_saa(struct pci_dev *pdev) free_irq(saa->irq, saa); if (saa->saa7146_mem) iounmap(saa->saa7146_mem); - if (saa->video_dev.minor != -1) + if (video_is_registered(&saa->video_dev)) video_unregister_device(&saa->video_dev); } diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 639c3396ae7..e89b855fd28 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -1418,7 +1418,7 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision) if (usbvision->vbi) { PDEBUG(DBG_PROBE, "unregister %s [v4l2]", video_device_node_name(usbvision->vbi)); - if (usbvision->vbi->minor != -1) { + if (video_is_registered(usbvision->vbi)) { video_unregister_device(usbvision->vbi); } else { video_device_release(usbvision->vbi); @@ -1430,7 +1430,7 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision) if (usbvision->rdev) { PDEBUG(DBG_PROBE, "unregister %s [v4l2]", video_device_node_name(usbvision->rdev)); - if (usbvision->rdev->minor != -1) { + if (video_is_registered(usbvision->rdev)) { video_unregister_device(usbvision->rdev); } else { video_device_release(usbvision->rdev); @@ -1442,7 +1442,7 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision) if (usbvision->vdev) { PDEBUG(DBG_PROBE, "unregister %s [v4l2]", video_device_node_name(usbvision->vdev)); - if (usbvision->vdev->minor != -1) { + if (video_is_registered(usbvision->vdev)) { video_unregister_device(usbvision->vdev); } else { video_device_release(usbvision->vdev); diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c index 8834bc80a5a..156e332ce00 100644 --- a/drivers/staging/cx25821/cx25821-video.c +++ b/drivers/staging/cx25821/cx25821-video.c @@ -424,7 +424,7 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status) void cx25821_videoioctl_unregister(struct cx25821_dev *dev) { if (dev->ioctl_dev) { - if (dev->ioctl_dev->minor != -1) + if (video_is_registered(dev->ioctl_dev)) video_unregister_device(dev->ioctl_dev); else video_device_release(dev->ioctl_dev); @@ -438,7 +438,7 @@ void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num) cx_clear(PCI_INT_MSK, 1); if (dev->video_dev[chan_num]) { - if (-1 != dev->video_dev[chan_num]->minor) + if (video_is_registered(dev->video_dev[chan_num])) video_unregister_device(dev->video_dev[chan_num]); else video_device_release(dev->video_dev[chan_num]); -- cgit v1.2.3-70-g09d2 From 63b0d5ad20365edf8baf96cdbb8e7faf62501286 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 10 Dec 2009 11:44:04 -0200 Subject: V4L/DVB (13554a): v4l: Use the video_drvdata function in drivers Fix all device drivers to use the video_drvdata function instead of maintaining a local list of minor to private data mappings. Call video_set_drvdata to register the driver private pointer when not already done. Where applicable, the local list of mappings is completely removed when it becomes unused. [mchehab.redhat.com: removed tm6000 changes as tm6000 is not ready yet for submission even on staging] Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/saa7146_fops.c | 32 +++++-------------- drivers/media/video/au0828/au0828-video.c | 35 +++++---------------- drivers/media/video/au0828/au0828.h | 1 - drivers/media/video/cx231xx/cx231xx-core.c | 26 ---------------- drivers/media/video/cx231xx/cx231xx-video.c | 18 ++++++++--- drivers/media/video/cx231xx/cx231xx.h | 2 -- drivers/media/video/cx23885/cx23885-417.c | 22 +++----------- drivers/media/video/cx23885/cx23885-core.c | 11 ------- drivers/media/video/cx23885/cx23885-video.c | 44 +++++++++++---------------- drivers/media/video/cx23885/cx23885.h | 3 -- drivers/media/video/cx88/cx88-blackbird.c | 15 ++------- drivers/media/video/cx88/cx88-mpeg.c | 15 --------- drivers/media/video/cx88/cx88-video.c | 43 +++++++++++--------------- drivers/media/video/cx88/cx88.h | 2 -- drivers/media/video/em28xx/em28xx-cards.c | 1 - drivers/media/video/em28xx/em28xx-core.c | 28 ----------------- drivers/media/video/em28xx/em28xx-video.c | 23 +++++++++----- drivers/media/video/em28xx/em28xx.h | 3 -- drivers/media/video/s2255drv.c | 35 ++++++--------------- drivers/media/video/saa7134/saa7134-core.c | 1 + drivers/media/video/saa7134/saa7134-empress.c | 11 ++----- drivers/media/video/saa7134/saa7134-video.c | 32 ++++++++----------- drivers/staging/cx25821/cx25821-audups11.c | 27 +++------------- drivers/staging/cx25821/cx25821-video.c | 1 + drivers/staging/cx25821/cx25821-video0.c | 27 +++------------- drivers/staging/cx25821/cx25821-video1.c | 27 +++------------- drivers/staging/cx25821/cx25821-video2.c | 28 ++++------------- drivers/staging/cx25821/cx25821-video3.c | 28 ++++------------- drivers/staging/cx25821/cx25821-video4.c | 28 ++++------------- drivers/staging/cx25821/cx25821-video5.c | 28 ++++------------- drivers/staging/cx25821/cx25821-video6.c | 28 ++++------------- drivers/staging/cx25821/cx25821-video7.c | 28 ++++------------- drivers/staging/cx25821/cx25821-videoioctl.c | 26 +++------------- drivers/staging/cx25821/cx25821-vidups10.c | 27 +++------------- drivers/staging/cx25821/cx25821-vidups9.c | 27 +++------------- 35 files changed, 178 insertions(+), 555 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index f279a644041..2d9fc2435f2 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c @@ -195,42 +195,24 @@ void saa7146_buffer_timeout(unsigned long data) static int fops_open(struct file *file) { unsigned int minor = video_devdata(file)->minor; - struct saa7146_dev *h = NULL, *dev = NULL; - struct list_head *list; + struct video_device *vdev = video_devdata(file); + struct saa7146_dev *dev = video_drvdata(file); struct saa7146_fh *fh = NULL; int result = 0; - enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + enum v4l2_buf_type type; DEB_EE(("file:%p, minor:%d\n", file, minor)); if (mutex_lock_interruptible(&saa7146_devices_lock)) return -ERESTARTSYS; - list_for_each(list,&saa7146_devices) { - h = list_entry(list, struct saa7146_dev, item); - if( NULL == h->vv_data ) { - DEB_D(("device %p has not registered video devices.\n",h)); - continue; - } - DEB_D(("trying: %p @ major %d,%d\n",h,h->vv_data->video_minor,h->vv_data->vbi_minor)); - - if (h->vv_data->video_minor == minor) { - dev = h; - } - if (h->vv_data->vbi_minor == minor) { - type = V4L2_BUF_TYPE_VBI_CAPTURE; - dev = h; - } - } - if (NULL == dev) { - DEB_S(("no such video device.\n")); - result = -ENODEV; - goto out; - } - DEB_D(("using: %p\n",dev)); + type = vdev->vfl_type == VFL_TYPE_GRABBER + ? V4L2_BUF_TYPE_VIDEO_CAPTURE + : V4L2_BUF_TYPE_VBI_CAPTURE; + /* check if an extension is registered */ if( NULL == dev->ext ) { DEB_S(("no extension registered for this device.\n")); diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c index 1485aee18d5..13a8a1db534 100644 --- a/drivers/media/video/au0828/au0828-video.c +++ b/drivers/media/video/au0828/au0828-video.c @@ -40,7 +40,6 @@ #include "au0828.h" #include "au0828-reg.h" -static LIST_HEAD(au0828_devlist); static DEFINE_MUTEX(au0828_sysfs_lock); #define AU0828_VERSION_CODE KERNEL_VERSION(0, 0, 1) @@ -693,10 +692,8 @@ void au0828_analog_unregister(struct au0828_dev *dev) dprintk(1, "au0828_release_resources called\n"); mutex_lock(&au0828_sysfs_lock); - if (dev->vdev) { - list_del(&dev->au0828list); + if (dev->vdev) video_unregister_device(dev->vdev); - } if (dev->vbi_dev) video_unregister_device(dev->vbi_dev); @@ -737,29 +734,15 @@ static void res_free(struct au0828_fh *fh) static int au0828_v4l2_open(struct file *filp) { - int minor = video_devdata(filp)->minor; int ret = 0; - struct au0828_dev *h, *dev = NULL; + struct au0828_dev *dev = video_drvdata(filp); struct au0828_fh *fh; - int type = 0; - struct list_head *list; - - list_for_each(list, &au0828_devlist) { - h = list_entry(list, struct au0828_dev, au0828list); - if (h->vdev->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } + int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + #ifdef VBI_IS_WORKING - if (h->vbi_dev->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VBI_CAPTURE; - } + if (video_devdata(filp)->vfl_type == VFL_TYPE_GRABBER) + type = V4L2_BUF_TYPE_VBI_CAPTURE; #endif - } - - if (NULL == dev) - return -ENODEV; fh = kzalloc(sizeof(struct au0828_fh), GFP_KERNEL); if (NULL == fh) { @@ -1676,25 +1659,23 @@ int au0828_analog_register(struct au0828_dev *dev, strcpy(dev->vbi_dev->name, "au0828a vbi"); #endif - list_add_tail(&dev->au0828list, &au0828_devlist); - /* Register the v4l2 device */ + video_set_drvdata(dev->vdev, dev); retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1); if (retval != 0) { dprintk(1, "unable to register video device (error = %d).\n", retval); - list_del(&dev->au0828list); video_device_release(dev->vdev); return -ENODEV; } #ifdef VBI_IS_WORKING /* Register the vbi device */ + video_set_drvdata(dev->vbi_dev, dev); retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1); if (retval != 0) { dprintk(1, "unable to register vbi device (error = %d).\n", retval); - list_del(&dev->au0828list); video_device_release(dev->vbi_dev); video_device_release(dev->vdev); return -ENODEV; diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h index b977915efbd..207f32dec6a 100644 --- a/drivers/media/video/au0828/au0828.h +++ b/drivers/media/video/au0828/au0828.h @@ -192,7 +192,6 @@ struct au0828_dev { struct au0828_dvb dvb; /* Analog */ - struct list_head au0828list; struct v4l2_device v4l2_dev; int users; unsigned int stream_on:1; /* Locks streams */ diff --git a/drivers/media/video/cx231xx/cx231xx-core.c b/drivers/media/video/cx231xx/cx231xx-core.c index 0d333e679f7..4a60dfbc347 100644 --- a/drivers/media/video/cx231xx/cx231xx-core.c +++ b/drivers/media/video/cx231xx/cx231xx-core.c @@ -66,32 +66,6 @@ MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); static LIST_HEAD(cx231xx_devlist); static DEFINE_MUTEX(cx231xx_devlist_mutex); -struct cx231xx *cx231xx_get_device(int minor, - enum v4l2_buf_type *fh_type, int *has_radio) -{ - struct cx231xx *h, *dev = NULL; - - *fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - *has_radio = 0; - - mutex_lock(&cx231xx_devlist_mutex); - list_for_each_entry(h, &cx231xx_devlist, devlist) { - if (h->vdev->minor == minor) - dev = h; - if (h->vbi_dev->minor == minor) { - dev = h; - *fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; - } - if (h->radio_dev && h->radio_dev->minor == minor) { - dev = h; - *has_radio = 1; - } - } - mutex_unlock(&cx231xx_devlist_mutex); - - return dev; -} - /* * cx231xx_realease_resources() * unregisters the v4l2,i2c and usb devices diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c index 71e152dc279..3fc7a6fe855 100644 --- a/drivers/media/video/cx231xx/cx231xx-video.c +++ b/drivers/media/video/cx231xx/cx231xx-video.c @@ -1918,13 +1918,22 @@ static int cx231xx_v4l2_open(struct file *filp) { int minor = video_devdata(filp)->minor; int errCode = 0, radio = 0; - struct cx231xx *dev = NULL; + struct video_device *vdev = video_devdata(filp); + struct cx231xx *dev = video_drvdata(filp); struct cx231xx_fh *fh; enum v4l2_buf_type fh_type = 0; - dev = cx231xx_get_device(minor, &fh_type, &radio); - if (NULL == dev) - return -ENODEV; + switch (vdev->vfl_type) { + case VFL_TYPE_GRABBER: + fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + break; + case VFL_TYPE_VBI: + fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; + break; + case VFL_TYPE_RADIO: + radio = 1; + break; + } mutex_lock(&dev->lock); @@ -2326,6 +2335,7 @@ static struct video_device *cx231xx_vdev_init(struct cx231xx *dev, snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); + video_set_drvdata(vfd, dev); return vfd; } diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h index 64e2ddd3c40..17d4d1a800c 100644 --- a/drivers/media/video/cx231xx/cx231xx.h +++ b/drivers/media/video/cx231xx/cx231xx.h @@ -689,8 +689,6 @@ void cx231xx_release_analog_resources(struct cx231xx *dev); int cx231xx_register_analog_devices(struct cx231xx *dev); void cx231xx_remove_from_devlist(struct cx231xx *dev); void cx231xx_add_into_devlist(struct cx231xx *dev); -struct cx231xx *cx231xx_get_device(int minor, - enum v4l2_buf_type *fh_type, int *has_radio); void cx231xx_init_extension(struct cx231xx *dev); void cx231xx_close_extension(struct cx231xx *dev); diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index a7bfe7c3a44..272c60a993b 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c @@ -1568,28 +1568,11 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int mpeg_open(struct file *file) { - int minor = video_devdata(file)->minor; - struct cx23885_dev *h, *dev = NULL; - struct list_head *list; + struct cx23885_dev *dev = video_drvdata(file); struct cx23885_fh *fh; dprintk(2, "%s()\n", __func__); - lock_kernel(); - list_for_each(list, &cx23885_devlist) { - h = list_entry(list, struct cx23885_dev, devlist); - if (h->v4l_device && - h->v4l_device->minor == minor) { - dev = h; - break; - } - } - - if (dev == NULL) { - unlock_kernel(); - return -ENODEV; - } - /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); if (NULL == fh) { @@ -1597,6 +1580,8 @@ static int mpeg_open(struct file *file) return -ENOMEM; } + lock_kernel(); + file->private_data = fh; fh->dev = dev; @@ -1803,6 +1788,7 @@ int cx23885_417_register(struct cx23885_dev *dev) /* Allocate and initialize V4L video device */ dev->v4l_device = cx23885_video_dev_alloc(tsport, dev->pci, &cx23885_mpeg_template, "mpeg"); + video_set_drvdata(dev->v4l_device, dev); err = video_register_device(dev->v4l_device, VFL_TYPE_GRABBER, -1); if (err < 0) { diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index 04b12d27bc1..0dde57e96d3 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -55,9 +55,6 @@ MODULE_PARM_DESC(card, "card type"); static unsigned int cx23885_devcount; -static DEFINE_MUTEX(devlist); -LIST_HEAD(cx23885_devlist); - #define NO_SYNC_LINE (-1U) /* FIXME, these allocations will change when @@ -785,10 +782,6 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) dev->nr = cx23885_devcount++; sprintf(dev->name, "cx23885[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &cx23885_devlist); - mutex_unlock(&devlist); - /* Configure the internal memory */ if (dev->pci->device == 0x8880) { /* Could be 887 or 888, assume a default */ @@ -2008,10 +2001,6 @@ static void __devexit cx23885_finidev(struct pci_dev *pci_dev) /* unregister stuff */ free_irq(pci_dev->irq, dev); - mutex_lock(&devlist); - list_del(&dev->devlist); - mutex_unlock(&devlist); - cx23885_dev_unregister(dev); v4l2_device_unregister(v4l2_dev); kfree(dev); diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index fd98121361f..e10f28cfef5 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -323,6 +323,7 @@ static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev, vfd->release = video_device_release; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, cx23885_boards[dev->board].name); + video_set_drvdata(vfd, dev); return vfd; } @@ -717,34 +718,22 @@ static int get_resource(struct cx23885_fh *fh) static int video_open(struct file *file) { int minor = video_devdata(file)->minor; - struct cx23885_dev *h, *dev = NULL; + struct video_device *vdev = video_devdata(file); + struct cx23885_dev *dev = video_drvdata(file); struct cx23885_fh *fh; - struct list_head *list; enum v4l2_buf_type type = 0; int radio = 0; - lock_kernel(); - list_for_each(list, &cx23885_devlist) { - h = list_entry(list, struct cx23885_dev, devlist); - if (h->video_dev && - h->video_dev->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - if (h->vbi_dev && - h->vbi_dev->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VBI_CAPTURE; - } - if (h->radio_dev && - h->radio_dev->minor == minor) { - radio = 1; - dev = h; - } - } - if (NULL == dev) { - unlock_kernel(); - return -ENODEV; + switch (vdev->vfl_type) { + case VFL_TYPE_GRABBER: + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + break; + case VFL_TYPE_VBI: + type = V4L2_BUF_TYPE_VBI_CAPTURE; + break; + case VFL_TYPE_RADIO: + radio = 1; + break; } dprintk(1, "open minor=%d radio=%d type=%s\n", @@ -752,10 +741,11 @@ static int video_open(struct file *file) /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); + if (NULL == fh) return -ENOMEM; - } + + lock_kernel(); + file->private_data = fh; fh->dev = dev; fh->radio = radio; diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index fa744764dc8..08b3f6b136a 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h @@ -303,7 +303,6 @@ struct cx23885_tsport { }; struct cx23885_dev { - struct list_head devlist; atomic_t refcount; struct v4l2_device v4l2_dev; @@ -399,8 +398,6 @@ static inline struct cx23885_dev *to_cx23885(struct v4l2_device *v4l2_dev) extern struct v4l2_subdev *cx23885_find_hw(struct cx23885_dev *dev, u32 hw); -extern struct list_head cx23885_devlist; - #define SRAM_CH01 0 /* Video A */ #define SRAM_CH02 1 /* VBI A */ #define SRAM_CH03 2 /* Video B */ diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 5186f87b4ec..f0ef94150d1 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -1049,20 +1049,14 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id) static int mpeg_open(struct file *file) { int minor = video_devdata(file)->minor; - struct cx8802_dev *dev = NULL; + struct cx8802_dev *dev = video_drvdata(file); struct cx8802_fh *fh; struct cx8802_driver *drv = NULL; int err; - lock_kernel(); - dev = cx8802_get_device(minor); - dprintk( 1, "%s\n", __func__); - if (dev == NULL) { - unlock_kernel(); - return -ENODEV; - } + lock_kernel(); /* Make sure we can acquire the hardware */ drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); @@ -1129,10 +1123,6 @@ static int mpeg_release(struct file *file) kfree(fh); /* Make sure we release the hardware */ - dev = cx8802_get_device(video_devdata(file)->minor); - if (dev == NULL) - return -ENODEV; - drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); if (drv) drv->request_release(drv); @@ -1290,6 +1280,7 @@ static int blackbird_register_video(struct cx8802_dev *dev) dev->mpeg_dev = cx88_vdev_init(dev->core,dev->pci, &cx8802_mpeg_template,"mpeg"); + video_set_drvdata(dev->mpeg_dev, dev); err = video_register_device(dev->mpeg_dev,VFL_TYPE_GRABBER, -1); if (err < 0) { printk(KERN_INFO "%s/2: can't register mpeg device\n", diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index de9ff0fc741..bb510489341 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c @@ -580,21 +580,6 @@ static int cx8802_resume_common(struct pci_dev *pci_dev) return 0; } -#if defined(CONFIG_VIDEO_CX88_BLACKBIRD) || \ - defined(CONFIG_VIDEO_CX88_BLACKBIRD_MODULE) -struct cx8802_dev *cx8802_get_device(int minor) -{ - struct cx8802_dev *dev; - - list_for_each_entry(dev, &cx8802_devlist, devlist) - if (dev->mpeg_dev && dev->mpeg_dev->minor == minor) - return dev; - - return NULL; -} -EXPORT_SYMBOL(cx8802_get_device); -#endif - struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype) { struct cx8802_driver *d; diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 0259ac6d814..758399173a5 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -75,10 +75,6 @@ MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes"); #define dprintk(level,fmt, arg...) if (video_debug >= level) \ printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg) -/* ------------------------------------------------------------------ */ - -static LIST_HEAD(cx8800_devlist); - /* ------------------------------------------------------------------- */ /* static data */ @@ -754,33 +750,27 @@ static int get_ressource(struct cx8800_fh *fh) static int video_open(struct file *file) { int minor = video_devdata(file)->minor; - struct cx8800_dev *h,*dev = NULL; + struct video_device *vdev = video_devdata(file); + struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core; struct cx8800_fh *fh; enum v4l2_buf_type type = 0; int radio = 0; - lock_kernel(); - list_for_each_entry(h, &cx8800_devlist, devlist) { - if (h->video_dev->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - if (h->vbi_dev->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VBI_CAPTURE; - } - if (h->radio_dev && - h->radio_dev->minor == minor) { - radio = 1; - dev = h; - } - } - if (NULL == dev) { - unlock_kernel(); - return -ENODEV; + switch (vdev->vfl_type) { + case VFL_TYPE_GRABBER: + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + break; + case VFL_TYPE_VBI: + type = V4L2_BUF_TYPE_VBI_CAPTURE; + break; + case VFL_TYPE_RADIO: + radio = 1; + break; } + lock_kernel(); + core = dev->core; dprintk(1,"open minor=%d radio=%d type=%s\n", @@ -1909,6 +1899,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, /* register v4l devices */ dev->video_dev = cx88_vdev_init(core,dev->pci, &cx8800_video_template,"video"); + video_set_drvdata(dev->video_dev, dev); err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER, video_nr[core->nr]); if (err < 0) { @@ -1920,6 +1911,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, core->name, video_device_node_name(dev->video_dev)); dev->vbi_dev = cx88_vdev_init(core,dev->pci,&cx8800_vbi_template,"vbi"); + video_set_drvdata(dev->vbi_dev, dev); err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI, vbi_nr[core->nr]); if (err < 0) { @@ -1933,6 +1925,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, if (core->board.radio.type == CX88_RADIO) { dev->radio_dev = cx88_vdev_init(core,dev->pci, &cx8800_radio_template,"radio"); + video_set_drvdata(dev->radio_dev, dev); err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO, radio_nr[core->nr]); if (err < 0) { @@ -1945,7 +1938,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, } /* everything worked */ - list_add_tail(&dev->devlist,&cx8800_devlist); pci_set_drvdata(pci_dev,dev); /* initial device configuration */ @@ -2001,7 +1993,6 @@ static void __devexit cx8800_finidev(struct pci_dev *pci_dev) /* free memory */ btcx_riscmem_free(dev->pci,&dev->vidq.stopper); - list_del(&dev->devlist); cx88_core_put(core,dev->pci); kfree(dev); } diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index e1c52171010..b1499bf604e 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -423,7 +423,6 @@ struct cx8800_suspend_state { struct cx8800_dev { struct cx88_core *core; - struct list_head devlist; spinlock_t slock; /* various device info */ @@ -670,7 +669,6 @@ int cx88_audio_thread(void *data); int cx8802_register_driver(struct cx8802_driver *drv); int cx8802_unregister_driver(struct cx8802_driver *drv); -struct cx8802_dev *cx8802_get_device(int minor); struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype); /* ----------------------------------------------------------- */ diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 4ace70946d3..e7a68e2507d 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -2653,7 +2653,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, INIT_LIST_HEAD(&dev->vbiq.active); INIT_LIST_HEAD(&dev->vbiq.queued); - if (dev->board.has_msp34xx) { /* Send a reset to other chips via gpio */ errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7); diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 4f61e05d30b..b311d4514bd 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -1136,34 +1136,6 @@ void em28xx_wake_i2c(struct em28xx *dev) static LIST_HEAD(em28xx_devlist); static DEFINE_MUTEX(em28xx_devlist_mutex); -struct em28xx *em28xx_get_device(int minor, - enum v4l2_buf_type *fh_type, - int *has_radio) -{ - struct em28xx *h, *dev = NULL; - - *fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - *has_radio = 0; - - mutex_lock(&em28xx_devlist_mutex); - list_for_each_entry(h, &em28xx_devlist, devlist) { - if (h->vdev->minor == minor) - dev = h; - if (h->vbi_dev && h->vbi_dev->minor == minor) { - dev = h; - *fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; - } - if (h->radio_dev && - h->radio_dev->minor == minor) { - dev = h; - *has_radio = 1; - } - } - mutex_unlock(&em28xx_devlist_mutex); - - return dev; -} - /* * em28xx_realease_resources() * unregisters the v4l2,i2c and usb devices diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 9a8ff32cb31..dd9bbe88c60 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -2082,16 +2082,24 @@ static int radio_queryctrl(struct file *file, void *priv, static int em28xx_v4l2_open(struct file *filp) { int minor = video_devdata(filp)->minor; - int errCode = 0, radio; - struct em28xx *dev; - enum v4l2_buf_type fh_type; + int errCode = 0, radio = 0; + struct video_device *vdev = video_devdata(filp); + struct em28xx *dev = video_drvdata(filp); + enum v4l2_buf_type fh_type = 0; struct em28xx_fh *fh; enum v4l2_field field; - dev = em28xx_get_device(minor, &fh_type, &radio); - - if (NULL == dev) - return -ENODEV; + switch (vdev->vfl_type) { + case VFL_TYPE_GRABBER: + fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + break; + case VFL_TYPE_VBI: + fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; + break; + case VFL_TYPE_RADIO: + radio = 1; + break; + } mutex_lock(&dev->lock); @@ -2459,6 +2467,7 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); + video_set_drvdata(vfd, dev); return vfd; } diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 48977832316..80d9b4fa1b9 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -668,9 +668,6 @@ int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); void em28xx_wake_i2c(struct em28xx *dev); void em28xx_remove_from_devlist(struct em28xx *dev); void em28xx_add_into_devlist(struct em28xx *dev); -struct em28xx *em28xx_get_device(int minor, - enum v4l2_buf_type *fh_type, - int *has_radio); int em28xx_register_extension(struct em28xx_ops *dev); void em28xx_unregister_extension(struct em28xx_ops *dev); void em28xx_init_extension(struct em28xx *dev); diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 4201abcf8f6..0a77108ee06 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c @@ -233,7 +233,6 @@ struct s2255_dev { struct s2255_dmaqueue vidq[MAX_CHANNELS]; struct video_device *vdev[MAX_CHANNELS]; - struct list_head s2255_devlist; struct timer_list timer; struct s2255_fw *fw_data; struct s2255_pipeinfo pipes[MAX_PIPE_BUFFERS]; @@ -313,8 +312,6 @@ struct s2255_fh { /* Channels on box are in reverse order */ static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0}; -static LIST_HEAD(s2255_devlist); - static int debug; static int *s2255_debug = &debug; @@ -1534,31 +1531,22 @@ static int vidioc_s_parm(struct file *file, void *priv, static int s2255_open(struct file *file) { int minor = video_devdata(file)->minor; - struct s2255_dev *h, *dev = NULL; + struct video_device *vdev = video_devdata(file); + struct s2255_dev *dev = video_drvdata(file); struct s2255_fh *fh; - struct list_head *list; - enum v4l2_buf_type type = 0; + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; int i = 0; int cur_channel = -1; int state; dprintk(1, "s2255: open called (minor=%d)\n", minor); lock_kernel(); - list_for_each(list, &s2255_devlist) { - h = list_entry(list, struct s2255_dev, s2255_devlist); - for (i = 0; i < MAX_CHANNELS; i++) { - if (h->vdev[i]->minor == minor) { - cur_channel = i; - dev = h; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - } - } - if ((NULL == dev) || (cur_channel == -1)) { - unlock_kernel(); - printk(KERN_INFO "s2255: openv4l no dev\n"); - return -ENODEV; + for (i = 0; i < MAX_CHANNELS; i++) { + if (dev->vdev[i] == vdev) { + cur_channel = i; + break; + } } if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_DISCONNECTING) { @@ -1699,7 +1687,6 @@ static unsigned int s2255_poll(struct file *file, static void s2255_destroy(struct kref *kref) { struct s2255_dev *dev = to_s2255_dev(kref); - struct list_head *list; int i; if (!dev) { printk(KERN_ERR "s2255drv: kref problem\n"); @@ -1733,10 +1720,6 @@ static void s2255_destroy(struct kref *kref) usb_put_dev(dev->udev); dprintk(1, "%s", __func__); - while (!list_empty(&s2255_devlist)) { - list = s2255_devlist.next; - list_del(list); - } mutex_unlock(&dev->open_lock); kfree(dev); } @@ -1843,7 +1826,6 @@ static int s2255_probe_v4l(struct s2255_dev *dev) int cur_nr = video_nr; /* initialize all video 4 linux */ - list_add_tail(&dev->s2255_devlist, &s2255_devlist); /* register 4 video devices */ for (i = 0; i < MAX_CHANNELS; i++) { INIT_LIST_HEAD(&dev->vidq[i].active); @@ -1853,6 +1835,7 @@ static int s2255_probe_v4l(struct s2255_dev *dev) dev->vdev[i] = video_device_alloc(); memcpy(dev->vdev[i], &template, sizeof(struct video_device)); dev->vdev[i]->parent = &dev->interface->dev; + video_set_drvdata(dev->vdev[i], dev); if (video_nr == -1) ret = video_register_device(dev->vdev[i], VFL_TYPE_GRABBER, diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index b910df94ed7..9f85e917f9f 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -797,6 +797,7 @@ static struct video_device *vdev_init(struct saa7134_dev *dev, vfd->debug = video_debug; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, saa7134_boards[dev->board].name); + video_set_drvdata(vfd, dev); return vfd; } diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index abc1d0bf583..1de27af5459 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -87,17 +87,9 @@ static int ts_init_encoder(struct saa7134_dev* dev) static int ts_open(struct file *file) { int minor = video_devdata(file)->minor; - struct saa7134_dev *dev; + struct saa7134_dev *dev = video_drvdata(file); int err; - lock_kernel(); - list_for_each_entry(dev, &saa7134_devlist, devlist) - if (dev->empress_dev && dev->empress_dev->minor == minor) - goto found; - unlock_kernel(); - return -ENODEV; - found: - dprintk("open minor=%d\n",minor); err = -EBUSY; if (!mutex_trylock(&dev->empress_tsq.vb_lock)) @@ -531,6 +523,7 @@ static int empress_init(struct saa7134_dev *dev) INIT_WORK(&dev->empress_workqueue, empress_signal_update); + video_set_drvdata(dev->empress_dev, dev); err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER, empress_nr[dev->nr]); if (err < 0) { diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 35f8daa3a35..bcca5a47981 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -1327,29 +1327,23 @@ static int saa7134_resource(struct saa7134_fh *fh) static int video_open(struct file *file) { int minor = video_devdata(file)->minor; - struct saa7134_dev *dev; + struct video_device *vdev = video_devdata(file); + struct saa7134_dev *dev = video_drvdata(file); struct saa7134_fh *fh; - enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + enum v4l2_buf_type type = 0; int radio = 0; - mutex_lock(&saa7134_devlist_lock); - list_for_each_entry(dev, &saa7134_devlist, devlist) { - if (dev->video_dev && (dev->video_dev->minor == minor)) - goto found; - if (dev->radio_dev && (dev->radio_dev->minor == minor)) { - radio = 1; - goto found; - } - if (dev->vbi_dev && (dev->vbi_dev->minor == minor)) { - type = V4L2_BUF_TYPE_VBI_CAPTURE; - goto found; - } + switch (vdev->vfl_type) { + case VFL_TYPE_GRABBER: + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + break; + case VFL_TYPE_VBI: + type = V4L2_BUF_TYPE_VBI_CAPTURE; + break; + case VFL_TYPE_RADIO: + radio = 1; + break; } - mutex_unlock(&saa7134_devlist_lock); - return -ENODEV; - -found: - mutex_unlock(&saa7134_devlist_lock); dprintk("open minor=%d radio=%d type=%s\n",minor,radio, v4l2_type_names[type]); diff --git a/drivers/staging/cx25821/cx25821-audups11.c b/drivers/staging/cx25821/cx25821-audups11.c index f78b8912d90..e1364d1c976 100644 --- a/drivers/staging/cx25821/cx25821-audups11.c +++ b/drivers/staging/cx25821/cx25821-audups11.c @@ -95,35 +95,18 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { int minor = video_devdata(file)->minor; - struct cx25821_dev *h, *dev = NULL; + struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; - struct list_head *list; - enum v4l2_buf_type type = 0; - - lock_kernel(); - list_for_each(list, &cx25821_devlist) { - h = list_entry(list, struct cx25821_dev, devlist); - - if (h->video_dev[SRAM_CH11] - && h->video_dev[SRAM_CH11]->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - } - - if (NULL == dev) { - unlock_kernel(); - return -ENODEV; - } + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); + if (NULL == fh) return -ENOMEM; - } + + lock_kernel(); file->private_data = fh; fh->dev = dev; diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c index 156e332ce00..c0c99c0fd43 100644 --- a/drivers/staging/cx25821/cx25821-video.c +++ b/drivers/staging/cx25821/cx25821-video.c @@ -189,6 +189,7 @@ struct video_device *cx25821_vdev_init(struct cx25821_dev *dev, vfd->release = video_device_release; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, cx25821_boards[dev->board].name); + video_set_drvdata(vfd, dev); return vfd; } diff --git a/drivers/staging/cx25821/cx25821-video0.c b/drivers/staging/cx25821/cx25821-video0.c index 950fac1d700..eb0fe817551 100644 --- a/drivers/staging/cx25821/cx25821-video0.c +++ b/drivers/staging/cx25821/cx25821-video0.c @@ -95,36 +95,19 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { int minor = video_devdata(file)->minor; - struct cx25821_dev *h, *dev = NULL; + struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; - struct list_head *list; - enum v4l2_buf_type type = 0; + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; - lock_kernel(); - list_for_each(list, &cx25821_devlist) { - h = list_entry(list, struct cx25821_dev, devlist); - - if (h->video_dev[SRAM_CH00] - && h->video_dev[SRAM_CH00]->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - } - - if (NULL == dev) { - unlock_kernel(); - return -ENODEV; - } - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); + if (NULL == fh) return -ENOMEM; - } + + lock_kernel(); file->private_data = fh; fh->dev = dev; diff --git a/drivers/staging/cx25821/cx25821-video1.c b/drivers/staging/cx25821/cx25821-video1.c index a4dddc684ad..96ec2385bcd 100644 --- a/drivers/staging/cx25821/cx25821-video1.c +++ b/drivers/staging/cx25821/cx25821-video1.c @@ -95,36 +95,19 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { int minor = video_devdata(file)->minor; - struct cx25821_dev *h, *dev = NULL; + struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; - struct list_head *list; - enum v4l2_buf_type type = 0; + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; - lock_kernel(); - list_for_each(list, &cx25821_devlist) { - h = list_entry(list, struct cx25821_dev, devlist); - - if (h->video_dev[SRAM_CH01] - && h->video_dev[SRAM_CH01]->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - } - - if (NULL == dev) { - unlock_kernel(); - return -ENODEV; - } - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); + if (NULL == fh) return -ENOMEM; - } + + lock_kernel(); file->private_data = fh; fh->dev = dev; diff --git a/drivers/staging/cx25821/cx25821-video2.c b/drivers/staging/cx25821/cx25821-video2.c index 8e04e253f5d..e659603c3fb 100644 --- a/drivers/staging/cx25821/cx25821-video2.c +++ b/drivers/staging/cx25821/cx25821-video2.c @@ -95,36 +95,20 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { int minor = video_devdata(file)->minor; - struct cx25821_dev *h, *dev = NULL; + struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; - struct list_head *list; - enum v4l2_buf_type type = 0; + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; - lock_kernel(); - list_for_each(list, &cx25821_devlist) { - h = list_entry(list, struct cx25821_dev, devlist); - - if (h->video_dev[SRAM_CH02] - && h->video_dev[SRAM_CH02]->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - } - - if (NULL == dev) { - unlock_kernel(); - return -ENODEV; - } - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); + if (NULL == fh) return -ENOMEM; - } + + lock_kernel(); + file->private_data = fh; fh->dev = dev; fh->type = type; diff --git a/drivers/staging/cx25821/cx25821-video3.c b/drivers/staging/cx25821/cx25821-video3.c index 8801a8ead90..873f0f83a89 100644 --- a/drivers/staging/cx25821/cx25821-video3.c +++ b/drivers/staging/cx25821/cx25821-video3.c @@ -95,36 +95,20 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { int minor = video_devdata(file)->minor; - struct cx25821_dev *h, *dev = NULL; + struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; - struct list_head *list; - enum v4l2_buf_type type = 0; + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; - lock_kernel(); - list_for_each(list, &cx25821_devlist) { - h = list_entry(list, struct cx25821_dev, devlist); - - if (h->video_dev[SRAM_CH03] - && h->video_dev[SRAM_CH03]->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - } - - if (NULL == dev) { - unlock_kernel(); - return -ENODEV; - } - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); + if (NULL == fh) return -ENOMEM; - } + + lock_kernel(); + file->private_data = fh; fh->dev = dev; fh->type = type; diff --git a/drivers/staging/cx25821/cx25821-video4.c b/drivers/staging/cx25821/cx25821-video4.c index ab0d747138a..c00e3f84e8e 100644 --- a/drivers/staging/cx25821/cx25821-video4.c +++ b/drivers/staging/cx25821/cx25821-video4.c @@ -95,36 +95,20 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { int minor = video_devdata(file)->minor; - struct cx25821_dev *h, *dev = NULL; + struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; - struct list_head *list; - enum v4l2_buf_type type = 0; + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; - lock_kernel(); - list_for_each(list, &cx25821_devlist) { - h = list_entry(list, struct cx25821_dev, devlist); - - if (h->video_dev[SRAM_CH04] - && h->video_dev[SRAM_CH04]->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - } - - if (NULL == dev) { - unlock_kernel(); - return -ENODEV; - } - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); + if (NULL == fh) return -ENOMEM; - } + + lock_kernel(); + file->private_data = fh; fh->dev = dev; fh->type = type; diff --git a/drivers/staging/cx25821/cx25821-video5.c b/drivers/staging/cx25821/cx25821-video5.c index 7ef0b971f5c..06396b86e98 100644 --- a/drivers/staging/cx25821/cx25821-video5.c +++ b/drivers/staging/cx25821/cx25821-video5.c @@ -95,36 +95,20 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { int minor = video_devdata(file)->minor; - struct cx25821_dev *h, *dev = NULL; + struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; - struct list_head *list; - enum v4l2_buf_type type = 0; + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; - lock_kernel(); - list_for_each(list, &cx25821_devlist) { - h = list_entry(list, struct cx25821_dev, devlist); - - if (h->video_dev[SRAM_CH05] - && h->video_dev[SRAM_CH05]->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - } - - if (NULL == dev) { - unlock_kernel(); - return -ENODEV; - } - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); + if (NULL == fh) return -ENOMEM; - } + + lock_kernel(); + file->private_data = fh; fh->dev = dev; fh->type = type; diff --git a/drivers/staging/cx25821/cx25821-video6.c b/drivers/staging/cx25821/cx25821-video6.c index 3c41b49e2ea..c5410c1558e 100644 --- a/drivers/staging/cx25821/cx25821-video6.c +++ b/drivers/staging/cx25821/cx25821-video6.c @@ -95,36 +95,20 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { int minor = video_devdata(file)->minor; - struct cx25821_dev *h, *dev = NULL; + struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; - struct list_head *list; - enum v4l2_buf_type type = 0; + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; - lock_kernel(); - list_for_each(list, &cx25821_devlist) { - h = list_entry(list, struct cx25821_dev, devlist); - - if (h->video_dev[SRAM_CH06] - && h->video_dev[SRAM_CH06]->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - } - - if (NULL == dev) { - unlock_kernel(); - return -ENODEV; - } - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); + if (NULL == fh) return -ENOMEM; - } + + lock_kernel(); + file->private_data = fh; fh->dev = dev; fh->type = type; diff --git a/drivers/staging/cx25821/cx25821-video7.c b/drivers/staging/cx25821/cx25821-video7.c index 625c9b78a9c..274977eefca 100644 --- a/drivers/staging/cx25821/cx25821-video7.c +++ b/drivers/staging/cx25821/cx25821-video7.c @@ -94,36 +94,20 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { int minor = video_devdata(file)->minor; - struct cx25821_dev *h, *dev = NULL; + struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; - struct list_head *list; - enum v4l2_buf_type type = 0; + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; - lock_kernel(); - list_for_each(list, &cx25821_devlist) { - h = list_entry(list, struct cx25821_dev, devlist); - - if (h->video_dev[SRAM_CH07] - && h->video_dev[SRAM_CH07]->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - } - - if (NULL == dev) { - unlock_kernel(); - return -ENODEV; - } - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); + if (NULL == fh) return -ENOMEM; - } + + lock_kernel(); + file->private_data = fh; fh->dev = dev; fh->type = type; diff --git a/drivers/staging/cx25821/cx25821-videoioctl.c b/drivers/staging/cx25821/cx25821-videoioctl.c index 2a312ce78c6..42ea8bfa9ed 100644 --- a/drivers/staging/cx25821/cx25821-videoioctl.c +++ b/drivers/staging/cx25821/cx25821-videoioctl.c @@ -95,35 +95,19 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { int minor = video_devdata(file)->minor; - struct cx25821_dev *h, *dev = NULL; + struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; - struct list_head *list; - enum v4l2_buf_type type = 0; + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; - lock_kernel(); - list_for_each(list, &cx25821_devlist) { - h = list_entry(list, struct cx25821_dev, devlist); - - if (h->ioctl_dev && h->ioctl_dev->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - } - - if (NULL == dev) { - unlock_kernel(); - return -ENODEV; - } - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); + if (NULL == fh) return -ENOMEM; - } + + lock_kernel(); file->private_data = fh; fh->dev = dev; diff --git a/drivers/staging/cx25821/cx25821-vidups10.c b/drivers/staging/cx25821/cx25821-vidups10.c index 77b63b06040..4e0033fa205 100644 --- a/drivers/staging/cx25821/cx25821-vidups10.c +++ b/drivers/staging/cx25821/cx25821-vidups10.c @@ -95,35 +95,18 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { int minor = video_devdata(file)->minor; - struct cx25821_dev *h, *dev = NULL; + struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; - struct list_head *list; - enum v4l2_buf_type type = 0; - - lock_kernel(); - list_for_each(list, &cx25821_devlist) { - h = list_entry(list, struct cx25821_dev, devlist); - - if (h->video_dev[SRAM_CH10] - && h->video_dev[SRAM_CH10]->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - } - - if (NULL == dev) { - unlock_kernel(); - return -ENODEV; - } + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); + if (NULL == fh) return -ENOMEM; - } + + lock_kernel(); file->private_data = fh; fh->dev = dev; diff --git a/drivers/staging/cx25821/cx25821-vidups9.c b/drivers/staging/cx25821/cx25821-vidups9.c index 75c8c1eed2d..67fc082e308 100644 --- a/drivers/staging/cx25821/cx25821-vidups9.c +++ b/drivers/staging/cx25821/cx25821-vidups9.c @@ -95,35 +95,18 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { int minor = video_devdata(file)->minor; - struct cx25821_dev *h, *dev = NULL; + struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; - struct list_head *list; - enum v4l2_buf_type type = 0; - - lock_kernel(); - list_for_each(list, &cx25821_devlist) { - h = list_entry(list, struct cx25821_dev, devlist); - - if (h->video_dev[SRAM_CH09] - && h->video_dev[SRAM_CH09]->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - } - - if (NULL == dev) { - unlock_kernel(); - return -ENODEV; - } + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); + if (NULL == fh) return -ENOMEM; - } + + lock_kernel(); file->private_data = fh; fh->dev = dev; -- cgit v1.2.3-70-g09d2 From 50462eb065e12f45851a9959a90d46b758944552 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 10 Dec 2009 11:47:13 -0200 Subject: V4L/DVB (13555): v4l: Use video_device_node_name() instead of the minor number Instead of using the minor number in kernel log messages, use the device node name as returned by the video_device_node_name() function. This makes debug, informational and error messages easier to understand for end users. [mchehab.redhat.com: removed tm6000 changes as tm6000 is not ready yet for submission even on staging] Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/saa7146_fops.c | 3 +-- drivers/media/video/bt8xx/bttv-driver.c | 6 ++++-- drivers/media/video/cx18/cx18-fileops.c | 4 ++-- drivers/media/video/cx231xx/cx231xx-video.c | 6 +++--- drivers/media/video/cx23885/cx23885-video.c | 5 ++--- drivers/media/video/cx88/cx88-blackbird.c | 4 ++-- drivers/media/video/cx88/cx88-video.c | 5 ++--- drivers/media/video/em28xx/em28xx-video.c | 6 +++--- drivers/media/video/ivtv/ivtv-fileops.c | 4 ++-- drivers/media/video/ov511.c | 4 ++-- drivers/media/video/s2255drv.c | 17 ++++++++++------- drivers/media/video/saa7134/saa7134-empress.c | 4 ++-- drivers/media/video/saa7134/saa7134-video.c | 5 ++--- drivers/media/video/vivi.c | 7 +++---- drivers/staging/cx25821/cx25821-audups11.c | 5 +++-- drivers/staging/cx25821/cx25821-video0.c | 5 +++-- drivers/staging/cx25821/cx25821-video1.c | 5 +++-- drivers/staging/cx25821/cx25821-video2.c | 5 +++-- drivers/staging/cx25821/cx25821-video3.c | 5 +++-- drivers/staging/cx25821/cx25821-video4.c | 5 +++-- drivers/staging/cx25821/cx25821-video5.c | 5 +++-- drivers/staging/cx25821/cx25821-video6.c | 5 +++-- drivers/staging/cx25821/cx25821-video7.c | 5 +++-- drivers/staging/cx25821/cx25821-videoioctl.c | 5 +++-- drivers/staging/cx25821/cx25821-vidups10.c | 5 +++-- drivers/staging/cx25821/cx25821-vidups9.c | 5 +++-- 26 files changed, 76 insertions(+), 64 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index 2d9fc2435f2..3c11cff0047 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c @@ -194,7 +194,6 @@ void saa7146_buffer_timeout(unsigned long data) static int fops_open(struct file *file) { - unsigned int minor = video_devdata(file)->minor; struct video_device *vdev = video_devdata(file); struct saa7146_dev *dev = video_drvdata(file); struct saa7146_fh *fh = NULL; @@ -202,7 +201,7 @@ static int fops_open(struct file *file) enum v4l2_buf_type type; - DEB_EE(("file:%p, minor:%d\n", file, minor)); + DEB_EE(("file:%p, dev:%s\n", file, video_device_node_name(vdev))); if (mutex_lock_interruptible(&saa7146_devices_lock)) return -ERESTARTSYS; diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index a2336915ca7..dcad2f7a995 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -3207,11 +3207,12 @@ err: static int bttv_open(struct file *file) { int minor = video_devdata(file)->minor; + struct video_device *vdev = video_devdata(file); struct bttv *btv = video_drvdata(file); struct bttv_fh *fh; enum v4l2_buf_type type = 0; - dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor); + dprintk(KERN_DEBUG "bttv: open dev=%s\n", video_device_node_name(vdev)); lock_kernel(); if (btv->video_dev->minor == minor) { @@ -3409,10 +3410,11 @@ static struct video_device bttv_video_template = { static int radio_open(struct file *file) { int minor = video_devdata(file)->minor; + struct video_device *vdev = video_devdata(file); struct bttv *btv = video_drvdata(file); struct bttv_fh *fh; - dprintk("bttv: open minor=%d\n",minor); + dprintk("bttv: open dev=%s\n", video_device_node_name(vdev)); lock_kernel(); WARN_ON(btv->radio_dev && btv->radio_dev->minor != minor); diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c index 4e278db31cc..c0885c69fd8 100644 --- a/drivers/media/video/cx18/cx18-fileops.c +++ b/drivers/media/video/cx18/cx18-fileops.c @@ -758,8 +758,8 @@ int cx18_v4l2_open(struct file *filp) mutex_lock(&cx->serialize_lock); if (cx18_init_on_first_open(cx)) { - CX18_ERR("Failed to initialize on minor %d\n", - video_dev->minor); + CX18_ERR("Failed to initialize on %s\n", + video_device_node_name(video_dev)); mutex_unlock(&cx->serialize_lock); return -ENXIO; } diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c index 3fc7a6fe855..552dff5d6f1 100644 --- a/drivers/media/video/cx231xx/cx231xx-video.c +++ b/drivers/media/video/cx231xx/cx231xx-video.c @@ -1916,7 +1916,6 @@ static int radio_queryctrl(struct file *file, void *priv, */ static int cx231xx_v4l2_open(struct file *filp) { - int minor = video_devdata(filp)->minor; int errCode = 0, radio = 0; struct video_device *vdev = video_devdata(filp); struct cx231xx *dev = video_drvdata(filp); @@ -1937,8 +1936,9 @@ static int cx231xx_v4l2_open(struct file *filp) mutex_lock(&dev->lock); - cx231xx_videodbg("open minor=%d type=%s users=%d\n", - minor, v4l2_type_names[fh_type], dev->users); + cx231xx_videodbg("open dev=%s type=%s users=%d\n", + video_device_node_name(vdev), v4l2_type_names[fh_type], + dev->users); #if 0 errCode = cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index e10f28cfef5..e8ca8bb384d 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -717,7 +717,6 @@ static int get_resource(struct cx23885_fh *fh) static int video_open(struct file *file) { - int minor = video_devdata(file)->minor; struct video_device *vdev = video_devdata(file); struct cx23885_dev *dev = video_drvdata(file); struct cx23885_fh *fh; @@ -736,8 +735,8 @@ static int video_open(struct file *file) break; } - dprintk(1, "open minor=%d radio=%d type=%s\n", - minor, radio, v4l2_type_names[type]); + dprintk(1, "open dev=%s radio=%d type=%s\n", + video_device_node_name(vdev), radio, v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index f0ef94150d1..03e592e016f 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -1048,7 +1048,7 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id) static int mpeg_open(struct file *file) { - int minor = video_devdata(file)->minor; + struct video_device *vdev = video_devdata(file); struct cx8802_dev *dev = video_drvdata(file); struct cx8802_fh *fh; struct cx8802_driver *drv = NULL; @@ -1075,7 +1075,7 @@ static int mpeg_open(struct file *file) unlock_kernel(); return -EINVAL; } - dprintk(1,"open minor=%d\n",minor); + dprintk(1, "open dev=%s\n", video_device_node_name(vdev)); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh),GFP_KERNEL); diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 758399173a5..0013cb4d756 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -749,7 +749,6 @@ static int get_ressource(struct cx8800_fh *fh) static int video_open(struct file *file) { - int minor = video_devdata(file)->minor; struct video_device *vdev = video_devdata(file); struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core; @@ -773,8 +772,8 @@ static int video_open(struct file *file) core = dev->core; - dprintk(1,"open minor=%d radio=%d type=%s\n", - minor,radio,v4l2_type_names[type]); + dprintk(1, "open dev=%s radio=%d type=%s\n", + video_device_node_name(vdev), radio, v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh),GFP_KERNEL); diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index dd9bbe88c60..0408727b79c 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -2081,7 +2081,6 @@ static int radio_queryctrl(struct file *file, void *priv, */ static int em28xx_v4l2_open(struct file *filp) { - int minor = video_devdata(filp)->minor; int errCode = 0, radio = 0; struct video_device *vdev = video_devdata(filp); struct em28xx *dev = video_drvdata(filp); @@ -2103,8 +2102,9 @@ static int em28xx_v4l2_open(struct file *filp) mutex_lock(&dev->lock); - em28xx_videodbg("open minor=%d type=%s users=%d\n", - minor, v4l2_type_names[fh_type], dev->users); + em28xx_videodbg("open dev=%s type=%s users=%d\n", + video_device_node_name(vdev), v4l2_type_names[fh_type], + dev->users); fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index e707ef3086b..babcabd73c0 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c @@ -985,8 +985,8 @@ int ivtv_v4l2_open(struct file *filp) mutex_lock(&itv->serialize_lock); if (ivtv_init_on_first_open(itv)) { - IVTV_ERR("Failed to initialize on minor %d\n", - vdev->minor); + IVTV_ERR("Failed to initialize on device %s\n", + video_device_node_name(vdev)); mutex_unlock(&itv->serialize_lock); return -ENXIO; } diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index b636160fd51..939ae8bf58d 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c @@ -5867,8 +5867,8 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) ov511_devused |= 1 << nr; ov->nr = nr; - dev_info(&intf->dev, "Device at %s registered to minor %d\n", - ov->usb_path, ov->vdev->minor); + dev_info(&intf->dev, "Device at %s registered to %s\n", + ov->usb_path, video_device_node_name(ov->vdev)); usb_set_intfdata(intf, ov); if (ov_create_sysfs(ov->vdev)) { diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 0a77108ee06..f6a4929867d 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c @@ -1530,7 +1530,6 @@ static int vidioc_s_parm(struct file *file, void *priv, } static int s2255_open(struct file *file) { - int minor = video_devdata(file)->minor; struct video_device *vdev = video_devdata(file); struct s2255_dev *dev = video_drvdata(file); struct s2255_fh *fh; @@ -1538,7 +1537,9 @@ static int s2255_open(struct file *file) int i = 0; int cur_channel = -1; int state; - dprintk(1, "s2255: open called (minor=%d)\n", minor); + + dprintk(1, "s2255: open called (dev=%s)\n", + video_device_node_name(vdev)); lock_kernel(); @@ -1650,8 +1651,9 @@ static int s2255_open(struct file *file) for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) qctl_regs[i] = s2255_qctrl[i].default_value; - dprintk(1, "s2255drv: open minor=%d type=%s users=%d\n", - minor, v4l2_type_names[type], dev->users[cur_channel]); + dprintk(1, "s2255drv: open dev=%s type=%s users=%d\n", + video_device_node_name(vdev), v4l2_type_names[type], + dev->users[cur_channel]); dprintk(2, "s2255drv: open: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", (unsigned long)fh, (unsigned long)dev, (unsigned long)&dev->vidq[cur_channel]); @@ -1728,7 +1730,8 @@ static int s2255_close(struct file *file) { struct s2255_fh *fh = file->private_data; struct s2255_dev *dev = fh->dev; - int minor = video_devdata(file)->minor; + struct video_device *vdev = video_devdata(file); + if (!dev) return -ENODEV; @@ -1748,8 +1751,8 @@ static int s2255_close(struct file *file) mutex_unlock(&dev->open_lock); kref_put(&dev->kref, s2255_destroy); - dprintk(1, "s2255: close called (minor=%d, users=%d)\n", - minor, dev->users[fh->channel]); + dprintk(1, "s2255: close called (dev=%s, users=%d)\n", + video_device_node_name(vdev), dev->users[fh->channel]); kfree(fh); return 0; } diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 1de27af5459..df56241b30a 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -86,11 +86,11 @@ static int ts_init_encoder(struct saa7134_dev* dev) static int ts_open(struct file *file) { - int minor = video_devdata(file)->minor; + struct video_device *vdev = video_devdata(file); struct saa7134_dev *dev = video_drvdata(file); int err; - dprintk("open minor=%d\n",minor); + dprintk("open dev=%s\n", video_device_node_name(vdev)); err = -EBUSY; if (!mutex_trylock(&dev->empress_tsq.vb_lock)) goto done; diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index bcca5a47981..9d26b1bd732 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -1326,7 +1326,6 @@ static int saa7134_resource(struct saa7134_fh *fh) static int video_open(struct file *file) { - int minor = video_devdata(file)->minor; struct video_device *vdev = video_devdata(file); struct saa7134_dev *dev = video_drvdata(file); struct saa7134_fh *fh; @@ -1345,8 +1344,8 @@ static int video_open(struct file *file) break; } - dprintk("open minor=%d radio=%d type=%s\n",minor,radio, - v4l2_type_names[type]); + dprintk("open dev=%s radio=%d type=%s\n", video_device_node_name(vdev), + radio, v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh),GFP_KERNEL); diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 93e0a258080..ce197e4cc58 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -1222,8 +1222,7 @@ static int vivi_close(struct file *file) struct vivi_fh *fh = file->private_data; struct vivi_dev *dev = fh->dev; struct vivi_dmaqueue *vidq = &dev->vidq; - - int minor = video_devdata(file)->minor; + struct video_device *vdev = video_devdata(file); vivi_stop_thread(vidq); videobuf_stop(&fh->vb_vidq); @@ -1235,8 +1234,8 @@ static int vivi_close(struct file *file) dev->users--; mutex_unlock(&dev->mutex); - dprintk(dev, 1, "close called (minor=%d, users=%d)\n", - minor, dev->users); + dprintk(dev, 1, "close called (dev=%s, users=%d)\n", + video_device_node_name(vdev), dev->users); return 0; } diff --git a/drivers/staging/cx25821/cx25821-audups11.c b/drivers/staging/cx25821/cx25821-audups11.c index e1364d1c976..a2fcbf055ba 100644 --- a/drivers/staging/cx25821/cx25821-audups11.c +++ b/drivers/staging/cx25821/cx25821-audups11.c @@ -94,12 +94,13 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { - int minor = video_devdata(file)->minor; + struct video_device *vdev = video_devdata(file); struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); + printk("open dev=%s type=%s\n", video_device_node_name(vdev), + v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); diff --git a/drivers/staging/cx25821/cx25821-video0.c b/drivers/staging/cx25821/cx25821-video0.c index eb0fe817551..9a474209cce 100644 --- a/drivers/staging/cx25821/cx25821-video0.c +++ b/drivers/staging/cx25821/cx25821-video0.c @@ -94,13 +94,14 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { - int minor = video_devdata(file)->minor; + struct video_device *vdev = video_devdata(file); struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); + printk("open dev=%s type=%s\n", video_device_node_name(vdev), + v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); diff --git a/drivers/staging/cx25821/cx25821-video1.c b/drivers/staging/cx25821/cx25821-video1.c index 96ec2385bcd..fc9c118d9bd 100644 --- a/drivers/staging/cx25821/cx25821-video1.c +++ b/drivers/staging/cx25821/cx25821-video1.c @@ -94,13 +94,14 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { - int minor = video_devdata(file)->minor; + struct video_device *vdev = video_devdata(file); struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); + printk("open dev=%s type=%s\n", video_device_node_name(vdev), + v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); diff --git a/drivers/staging/cx25821/cx25821-video2.c b/drivers/staging/cx25821/cx25821-video2.c index e659603c3fb..746682945eb 100644 --- a/drivers/staging/cx25821/cx25821-video2.c +++ b/drivers/staging/cx25821/cx25821-video2.c @@ -94,13 +94,14 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { - int minor = video_devdata(file)->minor; + struct video_device *vdev = video_devdata(file); struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); + printk("open dev=%s type=%s\n", video_device_node_name(vdev), + v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); diff --git a/drivers/staging/cx25821/cx25821-video3.c b/drivers/staging/cx25821/cx25821-video3.c index 873f0f83a89..0806e40e220 100644 --- a/drivers/staging/cx25821/cx25821-video3.c +++ b/drivers/staging/cx25821/cx25821-video3.c @@ -94,13 +94,14 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { - int minor = video_devdata(file)->minor; + struct video_device *vdev = video_devdata(file); struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); + printk("open dev=%s type=%s\n", video_device_node_name(vdev), + v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); diff --git a/drivers/staging/cx25821/cx25821-video4.c b/drivers/staging/cx25821/cx25821-video4.c index c00e3f84e8e..f44e1d47c35 100644 --- a/drivers/staging/cx25821/cx25821-video4.c +++ b/drivers/staging/cx25821/cx25821-video4.c @@ -94,13 +94,14 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { - int minor = video_devdata(file)->minor; + struct video_device *vdev = video_devdata(file); struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); + printk("open dev=%s type=%s\n", video_device_node_name(vdev), + v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); diff --git a/drivers/staging/cx25821/cx25821-video5.c b/drivers/staging/cx25821/cx25821-video5.c index 06396b86e98..85028ea5484 100644 --- a/drivers/staging/cx25821/cx25821-video5.c +++ b/drivers/staging/cx25821/cx25821-video5.c @@ -94,13 +94,14 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { - int minor = video_devdata(file)->minor; + struct video_device *vdev = video_devdata(file); struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); + printk("open dev=%s type=%s\n", video_device_node_name(vdev), + v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); diff --git a/drivers/staging/cx25821/cx25821-video6.c b/drivers/staging/cx25821/cx25821-video6.c index c5410c1558e..27afa03f14b 100644 --- a/drivers/staging/cx25821/cx25821-video6.c +++ b/drivers/staging/cx25821/cx25821-video6.c @@ -94,13 +94,14 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { - int minor = video_devdata(file)->minor; + struct video_device *vdev = video_devdata(file); struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); + printk("open dev=%s type=%s\n", video_device_node_name(vdev), + v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); diff --git a/drivers/staging/cx25821/cx25821-video7.c b/drivers/staging/cx25821/cx25821-video7.c index 274977eefca..055a7efa0b6 100644 --- a/drivers/staging/cx25821/cx25821-video7.c +++ b/drivers/staging/cx25821/cx25821-video7.c @@ -93,13 +93,14 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { - int minor = video_devdata(file)->minor; + struct video_device *vdev = video_devdata(file); struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); + printk("open dev=%s type=%s\n", video_device_node_name(vdev), + v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); diff --git a/drivers/staging/cx25821/cx25821-videoioctl.c b/drivers/staging/cx25821/cx25821-videoioctl.c index 42ea8bfa9ed..ae33355eb0d 100644 --- a/drivers/staging/cx25821/cx25821-videoioctl.c +++ b/drivers/staging/cx25821/cx25821-videoioctl.c @@ -94,13 +94,14 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { - int minor = video_devdata(file)->minor; + struct video_device *vdev = video_devdata(file); struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); + printk("open dev=%s type=%s\n", video_device_node_name(vdev), + v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); diff --git a/drivers/staging/cx25821/cx25821-vidups10.c b/drivers/staging/cx25821/cx25821-vidups10.c index 4e0033fa205..97db6cd4378 100644 --- a/drivers/staging/cx25821/cx25821-vidups10.c +++ b/drivers/staging/cx25821/cx25821-vidups10.c @@ -94,12 +94,13 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { - int minor = video_devdata(file)->minor; + struct video_device *vdev = video_devdata(file); struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); + printk("open dev=%s type=%s\n", video_device_node_name(vdev), + v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); diff --git a/drivers/staging/cx25821/cx25821-vidups9.c b/drivers/staging/cx25821/cx25821-vidups9.c index 67fc082e308..d06054f7e5a 100644 --- a/drivers/staging/cx25821/cx25821-vidups9.c +++ b/drivers/staging/cx25821/cx25821-vidups9.c @@ -94,12 +94,13 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { - int minor = video_devdata(file)->minor; + struct video_device *vdev = video_devdata(file); struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); + printk("open dev=%s type=%s\n", video_device_node_name(vdev), + v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); -- cgit v1.2.3-70-g09d2 From 46b21094cee16bc7e531d7d6cd66fb5ea05065d4 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 10 Dec 2009 11:51:38 -0200 Subject: V4L/DVB (13556): v4l: Remove unneeded video_device::minor assignments Now that the video_device registration is tested using video_is_registered(), drivers don't need to initialize the video_device::minor field to -1 anymore. Remove those unneeded assignments. [mchehab.redhat.com: removed tm6000 changes as tm6000 is not ready yet for submission even on staging] Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/arv.c | 1 - drivers/media/video/au0828/au0828-video.c | 1 - drivers/media/video/bt8xx/bttv-driver.c | 2 -- drivers/media/video/cafe_ccic.c | 1 - drivers/media/video/cpia2/cpia2_v4l.c | 1 - drivers/media/video/cx231xx/cx231xx-video.c | 3 --- drivers/media/video/cx23885/cx23885-417.c | 1 - drivers/media/video/cx23885/cx23885-video.c | 2 -- drivers/media/video/cx88/cx88-blackbird.c | 1 - drivers/media/video/cx88/cx88-video.c | 2 -- drivers/media/video/davinci/vpfe_capture.c | 1 - drivers/media/video/davinci/vpif_display.c | 1 - drivers/media/video/em28xx/em28xx-video.c | 4 ---- drivers/media/video/et61x251/et61x251_core.c | 1 - drivers/media/video/gspca/gspca.c | 1 - drivers/media/video/meye.c | 1 - drivers/media/video/omap24xxcam.c | 2 -- drivers/media/video/ov511.c | 1 - drivers/media/video/pwc/pwc-if.c | 1 - drivers/media/video/s2255drv.c | 1 - drivers/media/video/saa5246a.c | 1 - drivers/media/video/saa7134/saa7134-empress.c | 1 - drivers/media/video/saa7134/saa7134-video.c | 2 -- drivers/media/video/sn9c102/sn9c102_core.c | 1 - drivers/media/video/soc_camera.c | 4 +--- drivers/media/video/stk-webcam.c | 1 - drivers/media/video/stradis.c | 2 -- drivers/media/video/stv680.c | 1 - drivers/media/video/usbvideo/vicam.c | 1 - drivers/media/video/usbvision/usbvision-video.c | 4 ---- drivers/media/video/uvc/uvc_driver.c | 1 - drivers/media/video/vino.c | 1 - drivers/media/video/vivi.c | 1 - drivers/media/video/w9968cf.c | 1 - drivers/media/video/zc0301/zc0301_core.c | 1 - drivers/media/video/zoran/zoran_driver.c | 1 - drivers/media/video/zr364xx.c | 1 - drivers/staging/cx25821/cx25821-audups11.c | 1 - drivers/staging/cx25821/cx25821-video.c | 1 - drivers/staging/cx25821/cx25821-video0.c | 1 - drivers/staging/cx25821/cx25821-video1.c | 1 - drivers/staging/cx25821/cx25821-video2.c | 1 - drivers/staging/cx25821/cx25821-video3.c | 1 - drivers/staging/cx25821/cx25821-video4.c | 1 - drivers/staging/cx25821/cx25821-video5.c | 1 - drivers/staging/cx25821/cx25821-video6.c | 1 - drivers/staging/cx25821/cx25821-video7.c | 1 - drivers/staging/cx25821/cx25821-videoioctl.c | 1 - drivers/staging/cx25821/cx25821-vidups10.c | 1 - drivers/staging/cx25821/cx25821-vidups9.c | 1 - drivers/staging/go7007/go7007-v4l2.c | 1 - 51 files changed, 1 insertion(+), 67 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index 0ec807d8279..a356d6bd313 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c @@ -767,7 +767,6 @@ static struct video_device ar_template = { .name = "Colour AR VGA", .fops = &ar_fops, .release = ar_release, - .minor = -1, }; #define ALIGN4(x) ((((int)(x)) & 0x3) == 0) diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c index 13a8a1db534..dc67bc40f36 100644 --- a/drivers/media/video/au0828/au0828-video.c +++ b/drivers/media/video/au0828/au0828-video.c @@ -1570,7 +1570,6 @@ static const struct video_device au0828_video_template = { .fops = &au0828_v4l_fops, .release = video_device_release, .ioctl_ops = &video_ioctl_ops, - .minor = -1, .tvnorms = V4L2_STD_NTSC_M, .current_norm = V4L2_STD_NTSC_M, }; diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index dcad2f7a995..410260a1c36 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -3398,7 +3398,6 @@ static const struct v4l2_ioctl_ops bttv_ioctl_ops = { static struct video_device bttv_video_template = { .fops = &bttv_fops, - .minor = -1, .ioctl_ops = &bttv_ioctl_ops, .tvnorms = BTTV_NORMS, .current_norm = V4L2_STD_PAL, @@ -3642,7 +3641,6 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { static struct video_device radio_template = { .fops = &radio_fops, - .minor = -1, .ioctl_ops = &radio_ioctl_ops, }; diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 10230cb3d21..7bb9c1ec781 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -1723,7 +1723,6 @@ static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { static struct video_device cafe_v4l_template = { .name = "cafe", - .minor = -1, /* Get one dynamically */ .tvnorms = V4L2_STD_NTSC_M, .current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */ diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c index f8952af30a3..30d39b15fd4 100644 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ b/drivers/media/video/cpia2/cpia2_v4l.c @@ -1926,7 +1926,6 @@ static const struct v4l2_file_operations fops_template = { static struct video_device cpia2_template = { /* I could not find any place for the old .initialize initializer?? */ .name= "CPiA2 Camera", - .minor= -1, .fops= &fops_template, .release= video_device_release, }; diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c index 552dff5d6f1..d4f546f11d7 100644 --- a/drivers/media/video/cx231xx/cx231xx-video.c +++ b/drivers/media/video/cx231xx/cx231xx-video.c @@ -2277,7 +2277,6 @@ static const struct video_device cx231xx_video_template = { .fops = &cx231xx_v4l_fops, .release = video_device_release, .ioctl_ops = &video_ioctl_ops, - .minor = -1, .tvnorms = V4L2_STD_ALL, .current_norm = V4L2_STD_PAL, }; @@ -2312,7 +2311,6 @@ static struct video_device cx231xx_radio_template = { .name = "cx231xx-radio", .fops = &radio_fops, .ioctl_ops = &radio_ioctl_ops, - .minor = -1, }; /******************************** usb interface ******************************/ @@ -2328,7 +2326,6 @@ static struct video_device *cx231xx_vdev_init(struct cx231xx *dev, return NULL; *vfd = *template; - vfd->minor = -1; vfd->v4l2_dev = &dev->v4l2_dev; vfd->release = video_device_release; vfd->debug = video_debug; diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 272c60a993b..88c0d248111 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c @@ -1721,7 +1721,6 @@ static struct video_device cx23885_mpeg_template = { .name = "cx23885", .fops = &mpeg_fops, .ioctl_ops = &mpeg_ioctl_ops, - .minor = -1, .tvnorms = CX23885_NORMS, .current_norm = V4L2_STD_NTSC_M, }; diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index e8ca8bb384d..8934d61cf66 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -318,7 +318,6 @@ static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev, if (NULL == vfd) return NULL; *vfd = *template; - vfd->minor = -1; vfd->v4l2_dev = &dev->v4l2_dev; vfd->release = video_device_release; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", @@ -1430,7 +1429,6 @@ static struct video_device cx23885_vbi_template; static struct video_device cx23885_video_template = { .name = "cx23885-video", .fops = &video_fops, - .minor = -1, .ioctl_ops = &video_ioctl_ops, .tvnorms = CX23885_NORMS, .current_norm = V4L2_STD_NTSC_M, diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 03e592e016f..6fe30e6c426 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -1210,7 +1210,6 @@ static struct video_device cx8802_mpeg_template = { .name = "cx8802", .fops = &mpeg_fops, .ioctl_ops = &mpeg_ioctl_ops, - .minor = -1, .tvnorms = CX88_NORMS, .current_norm = V4L2_STD_NTSC_M, }; diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 0013cb4d756..48c450f4a85 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -1722,7 +1722,6 @@ static struct video_device cx8800_vbi_template; static struct video_device cx8800_video_template = { .name = "cx8800-video", .fops = &video_fops, - .minor = -1, .ioctl_ops = &video_ioctl_ops, .tvnorms = CX88_NORMS, .current_norm = V4L2_STD_NTSC_M, @@ -1758,7 +1757,6 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { static struct video_device cx8800_radio_template = { .name = "cx8800-radio", .fops = &radio_fops, - .minor = -1, .ioctl_ops = &radio_ioctl_ops, }; diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c index 1e8579438ef..f2d3c9b6df1 100644 --- a/drivers/media/video/davinci/vpfe_capture.c +++ b/drivers/media/video/davinci/vpfe_capture.c @@ -1967,7 +1967,6 @@ static __init int vpfe_probe(struct platform_device *pdev) vfd->release = video_device_release; vfd->fops = &vpfe_fops; vfd->ioctl_ops = &vpfe_ioctl_ops; - vfd->minor = -1; vfd->tvnorms = 0; vfd->current_norm = V4L2_STD_PAL; vfd->v4l2_dev = &vpfe_dev->v4l2_dev; diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c index d14cfb200ed..dfddef7228d 100644 --- a/drivers/media/video/davinci/vpif_display.c +++ b/drivers/media/video/davinci/vpif_display.c @@ -1347,7 +1347,6 @@ static const struct v4l2_file_operations vpif_fops = { static struct video_device vpif_video_template = { .name = "vpif", .fops = &vpif_fops, - .minor = -1, .ioctl_ops = &vpif_ioctl_ops, .tvnorms = DM646X_V4L2_STD, .current_norm = V4L2_STD_625_50, diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 0408727b79c..849b18c9403 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -2405,8 +2405,6 @@ static const struct video_device em28xx_video_template = { .release = video_device_release, .ioctl_ops = &video_ioctl_ops, - .minor = -1, - .tvnorms = V4L2_STD_ALL, .current_norm = V4L2_STD_PAL, }; @@ -2441,7 +2439,6 @@ static struct video_device em28xx_radio_template = { .name = "em28xx-radio", .fops = &radio_fops, .ioctl_ops = &radio_ioctl_ops, - .minor = -1, }; /******************************** usb interface ******************************/ @@ -2459,7 +2456,6 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, return NULL; *vfd = *template; - vfd->minor = -1; vfd->v4l2_dev = &dev->v4l2_dev; vfd->release = video_device_release; vfd->debug = video_debug; diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index f561a1c8679..e6c23d50986 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c @@ -2587,7 +2587,6 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera"); cam->v4ldev->fops = &et61x251_fops; - cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; cam->v4ldev->parent = &udev->dev; video_set_drvdata(cam->v4ldev, cam); diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 6af4f233bf5..9724e65d648 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -1989,7 +1989,6 @@ static struct video_device gspca_template = { .fops = &dev_fops, .ioctl_ops = &dev_ioctl_ops, .release = gspca_release, - .minor = -1, }; /* diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 01e1eefcf1e..6ffa64cd1c6 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -1681,7 +1681,6 @@ static struct video_device meye_template = { .fops = &meye_fops, .ioctl_ops = &meye_ioctl_ops, .release = video_device_release, - .minor = -1, }; #ifdef CONFIG_PM diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c index 34eb9659433..71e08be7960 100644 --- a/drivers/media/video/omap24xxcam.c +++ b/drivers/media/video/omap24xxcam.c @@ -1660,7 +1660,6 @@ static int omap24xxcam_device_register(struct v4l2_int_device *s) strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name)); vfd->fops = &omap24xxcam_fops; - vfd->minor = -1; vfd->ioctl_ops = &omap24xxcam_ioctl_fops; omap24xxcam_hwinit(cam); @@ -1671,7 +1670,6 @@ static int omap24xxcam_device_register(struct v4l2_int_device *s) if (video_register_device(vfd, VFL_TYPE_GRABBER, video_nr) < 0) { dev_err(cam->dev, "could not register V4L device\n"); - vfd->minor = -1; rval = -EBUSY; goto err; } diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index 939ae8bf58d..c71865dcf48 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c @@ -4674,7 +4674,6 @@ static struct video_device vdev_template = { .name = "OV511 USB Camera", .fops = &ov511_fops, .release = video_device_release, - .minor = -1, }; /**************************************************************************** diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 819cf4e7c58..d0e2b57f174 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -169,7 +169,6 @@ static struct video_device pwc_template = { .name = "Philips Webcam", /* Filled in later */ .release = video_device_release, .fops = &pwc_fops, - .minor = -1, }; /***************************************************************************/ diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index f6a4929867d..fb742f1ae71 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c @@ -1816,7 +1816,6 @@ static struct video_device template = { .name = "s2255v", .fops = &s2255_fops_v4l, .ioctl_ops = &s2255_ioctl_ops, - .minor = -1, .release = video_device_release, .tvnorms = S2255_NORMS, .current_norm = V4L2_STD_NTSC_M, diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c index b624a4c01fd..5ab6a0f901c 100644 --- a/drivers/media/video/saa5246a.c +++ b/drivers/media/video/saa5246a.c @@ -1036,7 +1036,6 @@ static struct video_device saa_template = .name = "saa5246a", .fops = &saa_fops, .release = video_device_release, - .minor = -1, }; static int saa5246a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index df56241b30a..7dfecfc6017 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -481,7 +481,6 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = { static struct video_device saa7134_empress_template = { .name = "saa7134-empress", .fops = &ts_fops, - .minor = -1, .ioctl_ops = &ts_ioctl_ops, .tvnorms = SAA7134_NORMS, diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 9d26b1bd732..cb732640ac4 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -2495,7 +2495,6 @@ struct video_device saa7134_video_template = { .name = "saa7134-video", .fops = &video_fops, .ioctl_ops = &video_ioctl_ops, - .minor = -1, .tvnorms = SAA7134_NORMS, .current_norm = V4L2_STD_PAL, }; @@ -2504,7 +2503,6 @@ struct video_device saa7134_radio_template = { .name = "saa7134-radio", .fops = &radio_fops, .ioctl_ops = &radio_ioctl_ops, - .minor = -1, }; int saa7134_video_init1(struct saa7134_dev *dev) diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index 4cf41a8d44e..cbf8087b286 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c @@ -3329,7 +3329,6 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) strcpy(cam->v4ldev->name, "SN9C1xx PC Camera"); cam->v4ldev->fops = &sn9c102_fops; - cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; cam->v4ldev->parent = &udev->dev; diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 95fdeb23c2c..804c675f2cb 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -1268,7 +1268,6 @@ static int video_dev_create(struct soc_camera_device *icd) vdev->fops = &soc_camera_fops; vdev->ioctl_ops = &soc_camera_ioctl_ops; vdev->release = video_device_release; - vdev->minor = -1; vdev->tvnorms = V4L2_STD_UNKNOWN; icd->vdev = vdev; @@ -1291,8 +1290,7 @@ static int soc_camera_video_start(struct soc_camera_device *icd) !icd->ops->set_bus_param) return -EINVAL; - ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, - icd->vdev->minor); + ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, -1); if (ret < 0) { dev_err(&icd->dev, "video_register_device failed: %d\n", ret); return ret; diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index 6590b929931..f07a0f6b71c 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c @@ -1307,7 +1307,6 @@ static void stk_v4l_dev_release(struct video_device *vd) static struct video_device stk_v4l_data = { .name = "stkwebcam", - .minor = -1, .tvnorms = V4L2_STD_UNKNOWN, .current_norm = V4L2_STD_UNKNOWN, .fops = &v4l_stk_fops, diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index c8909056215..a057824e7eb 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c @@ -1921,7 +1921,6 @@ static const struct v4l2_file_operations saa_fops = { static struct video_device saa_template = { .name = "SAA7146A", .fops = &saa_fops, - .minor = -1, .release = video_device_release_empty, }; @@ -1972,7 +1971,6 @@ static int __devinit configure_saa7146(struct pci_dev *pdev, int num) saa->id = pdev->device; saa->irq = pdev->irq; - saa->video_dev.minor = -1; saa->saa7146_adr = pci_resource_start(pdev, 0); pci_read_config_byte(pdev, PCI_CLASS_REVISION, &saa->revision); diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c index b54222232cd..5938ad8702e 100644 --- a/drivers/media/video/stv680.c +++ b/drivers/media/video/stv680.c @@ -1405,7 +1405,6 @@ static struct video_device stv680_template = { .name = "STV0680 USB camera", .fops = &stv680_fops, .release = video_device_release, - .minor = -1, }; static int stv680_probe (struct usb_interface *intf, const struct usb_device_id *id) diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c index b75143ee5dd..6030410c667 100644 --- a/drivers/media/video/usbvideo/vicam.c +++ b/drivers/media/video/usbvideo/vicam.c @@ -796,7 +796,6 @@ static const struct v4l2_file_operations vicam_fops = { static struct video_device vicam_template = { .name = "ViCam-based USB Camera", .fops = &vicam_fops, - .minor = -1, .release = video_device_release_empty, }; diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index e89b855fd28..1054546db90 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -1328,7 +1328,6 @@ static struct video_device usbvision_video_template = { .ioctl_ops = &usbvision_ioctl_ops, .name = "usbvision-video", .release = video_device_release, - .minor = -1, .tvnorms = USBVISION_NORMS, .current_norm = V4L2_STD_PAL }; @@ -1362,7 +1361,6 @@ static struct video_device usbvision_radio_template = { .fops = &usbvision_radio_fops, .name = "usbvision-radio", .release = video_device_release, - .minor = -1, .ioctl_ops = &usbvision_radio_ioctl_ops, .tvnorms = USBVISION_NORMS, @@ -1382,7 +1380,6 @@ static struct video_device usbvision_vbi_template= .fops = &usbvision_vbi_fops, .release = video_device_release, .name = "usbvision-vbi", - .minor = -1, }; @@ -1404,7 +1401,6 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision, return NULL; } *vdev = *vdev_template; -// vdev->minor = -1; vdev->v4l2_dev = &usbvision->v4l2_dev; snprintf(vdev->name, sizeof(vdev->name), "%s", name); video_set_drvdata(vdev, usbvision); diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index c31bc50113b..391cccca7ff 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -1651,7 +1651,6 @@ static int uvc_register_video(struct uvc_device *dev, * get another one. */ vdev->parent = &dev->intf->dev; - vdev->minor = -1; vdev->fops = &uvc_fops; vdev->release = uvc_release; strlcpy(vdev->name, dev->name, sizeof vdev->name); diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index b034a81d2b1..a15d1e7cbed 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c @@ -4068,7 +4068,6 @@ static struct video_device vdev_template = { .fops = &vino_fops, .ioctl_ops = &vino_ioctl_ops, .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, - .minor = -1, }; static void vino_module_cleanup(int stage) diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index ce197e4cc58..37632a06496 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -1296,7 +1296,6 @@ static struct video_device vivi_template = { .name = "vivi", .fops = &vivi_fops, .ioctl_ops = &vivi_ioctl_ops, - .minor = -1, .release = video_device_release, .tvnorms = V4L2_STD_525_60, diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c index 3af6d6b3186..d807eea9175 100644 --- a/drivers/media/video/w9968cf.c +++ b/drivers/media/video/w9968cf.c @@ -3487,7 +3487,6 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) strcpy(cam->v4ldev->name, symbolic(camlist, mod_id)); cam->v4ldev->fops = &w9968cf_fops; - cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; video_set_drvdata(cam->v4ldev, cam); cam->v4ldev->v4l2_dev = &cam->v4l2_dev; diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c index 524eb754c97..e44e4b5f3e5 100644 --- a/drivers/media/video/zc0301/zc0301_core.c +++ b/drivers/media/video/zc0301/zc0301_core.c @@ -1988,7 +1988,6 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) strcpy(cam->v4ldev->name, "ZC0301[P] PC Camera"); cam->v4ldev->fops = &zc0301_fops; - cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; cam->v4ldev->parent = &udev->dev; video_set_drvdata(cam->v4ldev, cam); diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index e9f72ca458f..2ddffed019e 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c @@ -3387,6 +3387,5 @@ struct video_device zoran_template __devinitdata = { .ioctl_ops = &zoran_ioctl_ops, .release = &zoran_vdev_release, .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, - .minor = -1 }; diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c index 69ea6df62ab..f0eae83e3d8 100644 --- a/drivers/media/video/zr364xx.c +++ b/drivers/media/video/zr364xx.c @@ -1455,7 +1455,6 @@ static struct video_device zr364xx_template = { .fops = &zr364xx_fops, .ioctl_ops = &zr364xx_ioctl_ops, .release = video_device_release, - .minor = -1, }; diff --git a/drivers/staging/cx25821/cx25821-audups11.c b/drivers/staging/cx25821/cx25821-audups11.c index a2fcbf055ba..89c8fe2997f 100644 --- a/drivers/staging/cx25821/cx25821-audups11.c +++ b/drivers/staging/cx25821/cx25821-audups11.c @@ -411,7 +411,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { struct video_device cx25821_video_template11 = { .name = "cx25821-audioupstream", .fops = &video_fops, - .minor = -1, .ioctl_ops = &video_ioctl_ops, .tvnorms = CX25821_NORMS, .current_norm = V4L2_STD_NTSC_M, diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c index c0c99c0fd43..c7c14c7698a 100644 --- a/drivers/staging/cx25821/cx25821-video.c +++ b/drivers/staging/cx25821/cx25821-video.c @@ -184,7 +184,6 @@ struct video_device *cx25821_vdev_init(struct cx25821_dev *dev, if (NULL == vfd) return NULL; *vfd = *template; - vfd->minor = -1; vfd->v4l2_dev = &dev->v4l2_dev; vfd->release = video_device_release; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, diff --git a/drivers/staging/cx25821/cx25821-video0.c b/drivers/staging/cx25821/cx25821-video0.c index 9a474209cce..ad7a6912911 100644 --- a/drivers/staging/cx25821/cx25821-video0.c +++ b/drivers/staging/cx25821/cx25821-video0.c @@ -428,7 +428,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { struct video_device cx25821_video_template0 = { .name = "cx25821-video", .fops = &video_fops, - .minor = -1, .ioctl_ops = &video_ioctl_ops, .tvnorms = CX25821_NORMS, .current_norm = V4L2_STD_NTSC_M, diff --git a/drivers/staging/cx25821/cx25821-video1.c b/drivers/staging/cx25821/cx25821-video1.c index fc9c118d9bd..e3f3c4ac790 100644 --- a/drivers/staging/cx25821/cx25821-video1.c +++ b/drivers/staging/cx25821/cx25821-video1.c @@ -428,7 +428,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { struct video_device cx25821_video_template1 = { .name = "cx25821-video", .fops = &video_fops, - .minor = -1, .ioctl_ops = &video_ioctl_ops, .tvnorms = CX25821_NORMS, .current_norm = V4L2_STD_NTSC_M, diff --git a/drivers/staging/cx25821/cx25821-video2.c b/drivers/staging/cx25821/cx25821-video2.c index 746682945eb..36fb855a497 100644 --- a/drivers/staging/cx25821/cx25821-video2.c +++ b/drivers/staging/cx25821/cx25821-video2.c @@ -430,7 +430,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { struct video_device cx25821_video_template2 = { .name = "cx25821-video", .fops = &video_fops, - .minor = -1, .ioctl_ops = &video_ioctl_ops, .tvnorms = CX25821_NORMS, .current_norm = V4L2_STD_NTSC_M, diff --git a/drivers/staging/cx25821/cx25821-video3.c b/drivers/staging/cx25821/cx25821-video3.c index 0806e40e220..1e0f10abdbc 100644 --- a/drivers/staging/cx25821/cx25821-video3.c +++ b/drivers/staging/cx25821/cx25821-video3.c @@ -429,7 +429,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { struct video_device cx25821_video_template3 = { .name = "cx25821-video", .fops = &video_fops, - .minor = -1, .ioctl_ops = &video_ioctl_ops, .tvnorms = CX25821_NORMS, .current_norm = V4L2_STD_NTSC_M, diff --git a/drivers/staging/cx25821/cx25821-video4.c b/drivers/staging/cx25821/cx25821-video4.c index f44e1d47c35..0cbe7a79d8c 100644 --- a/drivers/staging/cx25821/cx25821-video4.c +++ b/drivers/staging/cx25821/cx25821-video4.c @@ -428,7 +428,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { struct video_device cx25821_video_template4 = { .name = "cx25821-video", .fops = &video_fops, - .minor = -1, .ioctl_ops = &video_ioctl_ops, .tvnorms = CX25821_NORMS, .current_norm = V4L2_STD_NTSC_M, diff --git a/drivers/staging/cx25821/cx25821-video5.c b/drivers/staging/cx25821/cx25821-video5.c index 85028ea5484..5dc08adc12e 100644 --- a/drivers/staging/cx25821/cx25821-video5.c +++ b/drivers/staging/cx25821/cx25821-video5.c @@ -428,7 +428,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { struct video_device cx25821_video_template5 = { .name = "cx25821-video", .fops = &video_fops, - .minor = -1, .ioctl_ops = &video_ioctl_ops, .tvnorms = CX25821_NORMS, .current_norm = V4L2_STD_NTSC_M, diff --git a/drivers/staging/cx25821/cx25821-video6.c b/drivers/staging/cx25821/cx25821-video6.c index 27afa03f14b..2938ad3ad3c 100644 --- a/drivers/staging/cx25821/cx25821-video6.c +++ b/drivers/staging/cx25821/cx25821-video6.c @@ -428,7 +428,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { struct video_device cx25821_video_template6 = { .name = "cx25821-video", .fops = &video_fops, - .minor = -1, .ioctl_ops = &video_ioctl_ops, .tvnorms = CX25821_NORMS, .current_norm = V4L2_STD_NTSC_M, diff --git a/drivers/staging/cx25821/cx25821-video7.c b/drivers/staging/cx25821/cx25821-video7.c index 055a7efa0b6..458e525d72a 100644 --- a/drivers/staging/cx25821/cx25821-video7.c +++ b/drivers/staging/cx25821/cx25821-video7.c @@ -427,7 +427,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { struct video_device cx25821_video_template7 = { .name = "cx25821-video", .fops = &video_fops, - .minor = -1, .ioctl_ops = &video_ioctl_ops, .tvnorms = CX25821_NORMS, .current_norm = V4L2_STD_NTSC_M, diff --git a/drivers/staging/cx25821/cx25821-videoioctl.c b/drivers/staging/cx25821/cx25821-videoioctl.c index ae33355eb0d..1da52b54a45 100644 --- a/drivers/staging/cx25821/cx25821-videoioctl.c +++ b/drivers/staging/cx25821/cx25821-videoioctl.c @@ -474,7 +474,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { struct video_device cx25821_videoioctl_template = { .name = "cx25821-videoioctl", .fops = &video_fops, - .minor = -1, .ioctl_ops = &video_ioctl_ops, .tvnorms = CX25821_NORMS, .current_norm = V4L2_STD_NTSC_M, diff --git a/drivers/staging/cx25821/cx25821-vidups10.c b/drivers/staging/cx25821/cx25821-vidups10.c index 97db6cd4378..b76d9f62c3d 100644 --- a/drivers/staging/cx25821/cx25821-vidups10.c +++ b/drivers/staging/cx25821/cx25821-vidups10.c @@ -412,7 +412,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { struct video_device cx25821_video_template10 = { .name = "cx25821-upstream10", .fops = &video_fops, - .minor = -1, .ioctl_ops = &video_ioctl_ops, .tvnorms = CX25821_NORMS, .current_norm = V4L2_STD_NTSC_M, diff --git a/drivers/staging/cx25821/cx25821-vidups9.c b/drivers/staging/cx25821/cx25821-vidups9.c index d06054f7e5a..1580da3b29a 100644 --- a/drivers/staging/cx25821/cx25821-vidups9.c +++ b/drivers/staging/cx25821/cx25821-vidups9.c @@ -410,7 +410,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { struct video_device cx25821_video_template9 = { .name = "cx25821-upstream9", .fops = &video_fops, - .minor = -1, .ioctl_ops = &video_ioctl_ops, .tvnorms = CX25821_NORMS, .current_norm = V4L2_STD_NTSC_M, diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c index fe739752c92..3af79242313 100644 --- a/drivers/staging/go7007/go7007-v4l2.c +++ b/drivers/staging/go7007/go7007-v4l2.c @@ -1787,7 +1787,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { static struct video_device go7007_template = { .name = "go7007", .fops = &go7007_fops, - .minor = -1, .release = go7007_vfl_release, .ioctl_ops = &video_ioctl_ops, .tvnorms = V4L2_STD_ALL, -- cgit v1.2.3-70-g09d2 From 327ae59757f2e56fd3fc2b11acbd0a7c4070f4e8 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 27 Nov 2009 13:57:55 -0300 Subject: V4L/DVB (13557): v4l: Remove unneeded video_device::minor usage in drivers The video_device::minor field is used where it shouldn't, either to - test for error conditions that can't happen anymore with the current v4l-dvb core, - store the value in a driver private field that isn't used anymore, - check the video device type where video_device::vfl_type should be used, or - create the name of a kernel thread that should get a stable name. Remove or fix those use cases. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/saa7146_fops.c | 19 ------------------- drivers/media/radio/radio-tea5764.c | 4 ---- drivers/media/video/bt8xx/bttv-driver.c | 15 ++++----------- drivers/media/video/gspca/sn9c20x.c | 5 +++-- drivers/media/video/omap24xxcam.c | 3 +-- include/media/saa7146_vv.h | 4 ---- 6 files changed, 8 insertions(+), 42 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index 3c11cff0047..7364b9642d0 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c @@ -1,7 +1,5 @@ #include -#define BOARD_CAN_DO_VBI(dev) (dev->revision != 0 && dev->vv_data->vbi_minor != -1) - /****************************************************************************/ /* resource management functions, shamelessly stolen from saa7134 driver */ @@ -455,9 +453,6 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) configuration data) */ dev->ext_vv_data = ext_vv; - vv->video_minor = -1; - vv->vbi_minor = -1; - vv->d_clipping.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_CLIPPING_MEM, &vv->d_clipping.dma_handle); if( NULL == vv->d_clipping.cpu_addr ) { ERR(("out of memory. aborting.\n")); @@ -496,7 +491,6 @@ EXPORT_SYMBOL_GPL(saa7146_vv_release); int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, char *name, int type) { - struct saa7146_vv *vv = dev->vv_data; struct video_device *vfd; int err; int i; @@ -524,11 +518,6 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, return err; } - if (VFL_TYPE_GRABBER == type) - vv->video_minor = vfd->minor; - else - vv->vbi_minor = vfd->minor; - INFO(("%s: registered device %s [v4l2]\n", dev->name, video_device_node_name(vfd))); @@ -539,16 +528,8 @@ EXPORT_SYMBOL_GPL(saa7146_register_device); int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev) { - struct saa7146_vv *vv = dev->vv_data; - DEB_EE(("dev:%p\n",dev)); - if ((*vid)->vfl_type == VFL_TYPE_GRABBER) { - vv->video_minor = -1; - } else { - vv->vbi_minor = -1; - } - video_unregister_device(*vid); *vid = NULL; diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c index 730ffd9cdd3..1d357b79b2f 100644 --- a/drivers/media/radio/radio-tea5764.c +++ b/drivers/media/radio/radio-tea5764.c @@ -460,12 +460,8 @@ static int vidioc_s_audio(struct file *file, void *priv, static int tea5764_open(struct file *file) { /* Currently we support only one device */ - int minor = video_devdata(file)->minor; struct tea5764_device *radio = video_drvdata(file); - if (radio->videodev->minor != minor) - return -ENODEV; - mutex_lock(&radio->mutex); /* Only exclusive access */ if (radio->users) { diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 410260a1c36..3182a406bdd 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -3206,7 +3206,6 @@ err: static int bttv_open(struct file *file) { - int minor = video_devdata(file)->minor; struct video_device *vdev = video_devdata(file); struct bttv *btv = video_drvdata(file); struct bttv_fh *fh; @@ -3214,17 +3213,17 @@ static int bttv_open(struct file *file) dprintk(KERN_DEBUG "bttv: open dev=%s\n", video_device_node_name(vdev)); - lock_kernel(); - if (btv->video_dev->minor == minor) { + if (vdev->vfl_type == VFL_TYPE_GRABBER) { type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } else if (btv->vbi_dev->minor == minor) { + } else if (vdev->vfl_type == VFL_TYPE_VBI) { type = V4L2_BUF_TYPE_VBI_CAPTURE; } else { WARN_ON(1); - unlock_kernel(); return -ENODEV; } + lock_kernel(); + dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n", btv->c.nr,v4l2_type_names[type]); @@ -3408,7 +3407,6 @@ static struct video_device bttv_video_template = { static int radio_open(struct file *file) { - int minor = video_devdata(file)->minor; struct video_device *vdev = video_devdata(file); struct bttv *btv = video_drvdata(file); struct bttv_fh *fh; @@ -3416,11 +3414,6 @@ static int radio_open(struct file *file) dprintk("bttv: open dev=%s\n", video_device_node_name(vdev)); lock_kernel(); - WARN_ON(btv->radio_dev && btv->radio_dev->minor != minor); - if (!btv->radio_dev || btv->radio_dev->minor != minor) { - unlock_kernel(); - return -ENODEV; - } dprintk("bttv%d: open called (radio)\n",btv->c.nr); diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index b1944a7cbb0..a3d8f4675c0 100644 --- a/drivers/media/video/gspca/sn9c20x.c +++ b/drivers/media/video/gspca/sn9c20x.c @@ -1476,8 +1476,9 @@ static int sn9c20x_input_init(struct gspca_dev *gspca_dev) if (input_register_device(sd->input_dev)) return -EINVAL; - sd->input_task = kthread_run(input_kthread, gspca_dev, "sn9c20x/%d", - gspca_dev->vdev.minor); + sd->input_task = kthread_run(input_kthread, gspca_dev, "sn9c20x/%s-%s", + gspca_dev->dev->bus->bus_name, + gspca_dev->dev->devpath); if (IS_ERR(sd->input_task)) return -EINVAL; diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c index 71e08be7960..7400eacb4d6 100644 --- a/drivers/media/video/omap24xxcam.c +++ b/drivers/media/video/omap24xxcam.c @@ -1450,12 +1450,11 @@ static int omap24xxcam_mmap(struct file *file, struct vm_area_struct *vma) static int omap24xxcam_open(struct file *file) { - int minor = video_devdata(file)->minor; struct omap24xxcam_device *cam = omap24xxcam.priv; struct omap24xxcam_fh *fh; struct v4l2_format format; - if (!cam || !cam->vfd || (cam->vfd->minor != minor)) + if (!cam || !cam->vfd) return -ENODEV; fh = kzalloc(sizeof(*fh), GFP_KERNEL); diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h index eed5fccc83f..4aeff96ff7d 100644 --- a/include/media/saa7146_vv.h +++ b/include/media/saa7146_vv.h @@ -108,8 +108,6 @@ struct saa7146_fh { struct saa7146_vv { - int vbi_minor; - /* vbi capture */ struct saa7146_dmaqueue vbi_q; /* vbi workaround interrupt queue */ @@ -117,8 +115,6 @@ struct saa7146_vv int vbi_fieldcount; struct saa7146_fh *vbi_streaming; - int video_minor; - int video_status; struct saa7146_fh *video_fh; -- cgit v1.2.3-70-g09d2 From fe2b6032513099b82cd19ef8da5050f02a18d3ec Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 26 Nov 2009 14:28:48 -0300 Subject: V4L/DVB (13559): gspca - pac7302: Some webcams are upside-down by default. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac7302.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index 74acceea809..b4049c0c687 100644 --- a/drivers/media/video/gspca/pac7302.c +++ b/drivers/media/video/gspca/pac7302.c @@ -90,6 +90,9 @@ struct sd { unsigned char autogain; __u8 hflip; __u8 vflip; + u8 flags; +#define FL_HFLIP 0x01 /* mirrored by default */ +#define FL_VFLIP 0x02 /* vertical flipped by default */ u8 sof_read; u8 autogain_ignore_frames; @@ -552,6 +555,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->autogain = AUTOGAIN_DEF; sd->hflip = HFLIP_DEF; sd->vflip = VFLIP_DEF; + sd->flags = id->driver_info; return 0; } @@ -708,10 +712,17 @@ static int sethvflip(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int ret; - __u8 data; + u8 data, hflip, vflip; + + hflip = sd->hflip; + if (sd->flags & FL_HFLIP) + hflip = !hflip; + vflip = sd->vflip; + if (sd->flags & FL_VFLIP) + vflip = !vflip; ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ - data = (sd->hflip ? 0x08 : 0x00) | (sd->vflip ? 0x04 : 0x00); + data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00); if (0 <= ret) ret = reg_w(gspca_dev, 0x21, data); /* load registers to sensor (Bit 0, auto clear) */ @@ -1222,8 +1233,8 @@ static __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x06f8, 0x3009)}, {USB_DEVICE(0x093a, 0x2620)}, {USB_DEVICE(0x093a, 0x2621)}, - {USB_DEVICE(0x093a, 0x2622)}, - {USB_DEVICE(0x093a, 0x2624)}, + {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP}, + {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP}, {USB_DEVICE(0x093a, 0x2626)}, {USB_DEVICE(0x093a, 0x2628)}, {USB_DEVICE(0x093a, 0x2629)}, -- cgit v1.2.3-70-g09d2 From d50e257ee8d1a16ca91f9286120f222d34853c49 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 26 Nov 2009 15:36:40 -0300 Subject: V4L/DVB (13560): gspca - main: Cleanup source. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 9724e65d648..92ed4d968cb 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -304,7 +304,6 @@ void gspca_frame_add(struct gspca_dev *gspca_dev, j = gspca_dev->fr_queue[i]; gspca_dev->cur_frame = &gspca_dev->frame[j]; } - return; } EXPORT_SYMBOL(gspca_frame_add); @@ -321,7 +320,7 @@ static int gspca_is_compressed(__u32 format) return 0; } -static void *rvmalloc(unsigned long size) +static void *rvmalloc(long size) { void *mem; unsigned long adr; @@ -329,7 +328,7 @@ static void *rvmalloc(unsigned long size) mem = vmalloc_32(size); if (mem != NULL) { adr = (unsigned long) mem; - while ((long) size > 0) { + while (size > 0) { SetPageReserved(vmalloc_to_page((void *) adr)); adr += PAGE_SIZE; size -= PAGE_SIZE; @@ -1614,7 +1613,7 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma) size -= PAGE_SIZE; } - vma->vm_ops = (struct vm_operations_struct *) &gspca_vm_ops; + vma->vm_ops = &gspca_vm_ops; vma->vm_private_data = frame; gspca_vm_open(vma); ret = 0; -- cgit v1.2.3-70-g09d2 From 747c710098101fb2f2766171c5fc069289b56ed6 Mon Sep 17 00:00:00 2001 From: Márton Németh Date: Sun, 29 Nov 2009 08:25:20 -0300 Subject: V4L/DVB (13561): gspca - main: Remove unnecessary set to alternate 0. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calling gspca_set_alt0() in gspca_dev_probe() is not needed as gspca_set_alt0() will do nothing because gspca_dev->alt is always zero at that time. Signed-off-by: Márton Németh Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 92ed4d968cb..0a99a21f265 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -2046,9 +2046,6 @@ int gspca_dev_probe(struct usb_interface *intf, if (ret < 0) goto out; ret = sd_desc->init(gspca_dev); - if (ret < 0) - goto out; - ret = gspca_set_alt0(gspca_dev); if (ret < 0) goto out; gspca_set_default_mode(gspca_dev); -- cgit v1.2.3-70-g09d2 From 7bd330b44eb92b8e5ae265ab447cd317290c7aee Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 2 Dec 2009 06:06:03 -0300 Subject: V4L/DVB (13563): gspca - zc3xx: Bad sensor probe of the webcam 0ac8:305b. - probe the webcam (probe sequence from ms-win trace) - update tax5130c init sequences from ms-win newer driver - update tas5130c sequences from ms-win trace - add some comments in the probe code Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/zc3xx.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 69e5dc4fc9d..1d525c4d63c 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -5345,9 +5345,6 @@ static const struct usb_action tas5130cxx_InitialScale[] = { /* 320x240 */ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN}, - {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, @@ -5364,27 +5361,27 @@ static const struct usb_action tas5130cxx_InitialScale[] = { /* 320x240 */ {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x95, ZC3XX_R18D_YTARGET}, + {0xa0, 0x70, ZC3XX_R18D_YTARGET}, {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, {0xa0, 0x00, 0x01ad}, {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, + {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN}, + {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL}, {} }; static const struct usb_action tas5130cxx_Initial[] = { /* 640x480 */ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, {0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT}, {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, {0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING}, {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN}, - {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL}, {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, @@ -5400,13 +5397,15 @@ static const struct usb_action tas5130cxx_Initial[] = { /* 640x480 */ {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x95, ZC3XX_R18D_YTARGET}, + {0xa0, 0x70, ZC3XX_R18D_YTARGET}, {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, {0xa0, 0x00, 0x01ad}, {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, + {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN}, + {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL}, {} }; static const struct usb_action tas5130cxx_50HZ[] = { @@ -6424,11 +6423,11 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev) if (retword != 0) return 0x0e; /* PAS202BCB */ - start_2wr_probe(dev, 0x02); /* ?? */ + start_2wr_probe(dev, 0x02); /* TAS5130C */ i2c_write(gspca_dev, 0x01, 0xaa, 0x00); retword = i2c_read(gspca_dev, 0x01); if (retword != 0) - return 0x02; /* ?? */ + return 0x02; /* TAS5130C */ ov_check: reg_r(gspca_dev, 0x0010); /* ?? */ reg_r(gspca_dev, 0x0010); @@ -6505,6 +6504,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) reg_r(gspca_dev, 0x0010); /* value 0x4001 is meaningless */ if (retword != 0x4001) { + if ((retword & 0xff00) == 0x6400) + return 0x02; /* TAS5130C */ for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) { if (chipset_revision_sensor[i].revision == retword) { sd->chip_revision = retword; @@ -6515,7 +6516,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) } } - reg_w(dev, 0x01, 0x0000); /* check ?? */ + reg_w(dev, 0x01, 0x0000); /* check PB0330 */ reg_w(dev, 0x01, 0x0001); reg_w(dev, 0xdd, 0x008b); reg_w(dev, 0x0a, 0x0010); @@ -6524,7 +6525,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) retword = i2c_read(gspca_dev, 0x00); if (retword != 0) { PDEBUG(D_PROBE, "probe 3wr vga type 0a ?"); - return 0x0a; /* ?? */ + return 0x0a; /* PB0330 */ } reg_w(dev, 0x01, 0x0000); @@ -6673,6 +6674,10 @@ static int sd_config(struct gspca_dev *gspca_dev, PDEBUG(D_PROBE, "Find Sensor HV7131B"); sd->sensor = SENSOR_HV7131B; break; + case 0x02: + PDEBUG(D_PROBE, "Sensor TAS5130C"); + sd->sensor = SENSOR_TAS5130CXX; + break; case 0x04: PDEBUG(D_PROBE, "Find Sensor CS2102"); sd->sensor = SENSOR_CS2102; @@ -6866,11 +6871,14 @@ static int sd_start(struct gspca_dev *gspca_dev) case SENSOR_GC0305: case SENSOR_OV7620: case SENSOR_PO2030: + case SENSOR_TAS5130CXX: case SENSOR_TAS5130C_VF0250: /* msleep(100); * ?? */ reg_r(gspca_dev, 0x0002); /* --> 0x40 */ reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ reg_w(dev, 0x15, 0x01ae); + if (sd->sensor == SENSOR_TAS5130CXX) + break; reg_w(dev, 0x0d, 0x003a); reg_w(dev, 0x02, 0x003b); reg_w(dev, 0x00, 0x0038); @@ -6887,6 +6895,7 @@ static int sd_start(struct gspca_dev *gspca_dev) break; case SENSOR_PAS202B: case SENSOR_GC0305: + case SENSOR_TAS5130CXX: reg_r(gspca_dev, 0x0008); /* fall thru */ case SENSOR_PO2030: @@ -6910,6 +6919,7 @@ static int sd_start(struct gspca_dev *gspca_dev) switch (sd->sensor) { case SENSOR_OV7620: case SENSOR_PAS202B: + case SENSOR_TAS5130CXX: reg_r(gspca_dev, 0x0180); /* from win */ reg_w(dev, 0x00, 0x0180); break; @@ -6928,6 +6938,7 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w(dev, 0x40, 0x0117); break; case SENSOR_GC0305: + case SENSOR_TAS5130CXX: reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ reg_w(dev, 0x15, 0x01ae); /* fall thru */ @@ -7220,7 +7231,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0ac8, 0x0302), .driver_info = SENSOR_PAS106}, {USB_DEVICE(0x0ac8, 0x301b)}, {USB_DEVICE(0x0ac8, 0x303b)}, - {USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250}, + {USB_DEVICE(0x0ac8, 0x305b)}, {USB_DEVICE(0x0ac8, 0x307b)}, {USB_DEVICE(0x10fd, 0x0128)}, {USB_DEVICE(0x10fd, 0x804d)}, -- cgit v1.2.3-70-g09d2 From 28ffe77fe2faea6658870818fd0593f1a03cc018 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Wed, 2 Dec 2009 06:18:46 -0300 Subject: V4L/DVB (13564): gspca - main: Implement vidioc_enum_frameintervals. Some drivers support multiple frameintervals (framerates), make gspca able to enumerate them. Signed-off-by: Antonio Ospite Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 29 +++++++++++++++++++++++++++++ drivers/media/video/gspca/gspca.h | 9 +++++++++ 2 files changed, 38 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 0a99a21f265..e6e8df48485 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -982,6 +982,34 @@ static int vidioc_enum_framesizes(struct file *file, void *priv, return -EINVAL; } +static int vidioc_enum_frameintervals(struct file *filp, void *priv, + struct v4l2_frmivalenum *fival) +{ + struct gspca_dev *gspca_dev = priv; + int mode = wxh_to_mode(gspca_dev, fival->width, fival->height); + __u32 i; + + if (gspca_dev->cam.mode_framerates == NULL || + gspca_dev->cam.mode_framerates[mode].nrates == 0) + return -EINVAL; + + if (fival->pixel_format != + gspca_dev->cam.cam_mode[mode].pixelformat) + return -EINVAL; + + for (i = 0; i < gspca_dev->cam.mode_framerates[mode].nrates; i++) { + if (fival->index == i) { + fival->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fival->discrete.numerator = 1; + fival->discrete.denominator = + gspca_dev->cam.mode_framerates[mode].rates[i]; + return 0; + } + } + + return -EINVAL; +} + static void gspca_release(struct video_device *vfd) { struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev); @@ -1973,6 +2001,7 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = { .vidioc_g_parm = vidioc_g_parm, .vidioc_s_parm = vidioc_s_parm, .vidioc_enum_framesizes = vidioc_enum_framesizes, + .vidioc_enum_frameintervals = vidioc_enum_frameintervals, #ifdef CONFIG_VIDEO_ADV_DEBUG .vidioc_g_register = vidioc_g_register, .vidioc_s_register = vidioc_s_register, diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 181617355ec..a55c0a04ecf 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -45,11 +45,20 @@ extern int gspca_debug; /* image transfers */ #define MAX_NURBS 4 /* max number of URBs */ + +/* used to list framerates supported by a camera mode (resolution) */ +struct framerates { + int *rates; + int nrates; +}; + /* device information - set at probe time */ struct cam { int bulk_size; /* buffer size when image transfer by bulk */ const struct v4l2_pix_format *cam_mode; /* size nmodes */ char nmodes; + const struct framerates *mode_framerates; /* must have size nmode, + * just like cam_mode */ __u8 bulk_nurbs; /* number of URBs in bulk mode * - cannot be > MAX_NURBS * - when 0 and bulk_size != 0 means -- cgit v1.2.3-70-g09d2 From c4322bfca8907109689eb6b244258bf52277f7dc Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 2 Dec 2009 07:04:35 -0300 Subject: V4L/DVB (13565): gspca - pac7302: One more webcam is upside-down by default. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac7302.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index b4049c0c687..e128514733d 100644 --- a/drivers/media/video/gspca/pac7302.c +++ b/drivers/media/video/gspca/pac7302.c @@ -1237,7 +1237,7 @@ static __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP}, {USB_DEVICE(0x093a, 0x2626)}, {USB_DEVICE(0x093a, 0x2628)}, - {USB_DEVICE(0x093a, 0x2629)}, + {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP}, {USB_DEVICE(0x093a, 0x262a)}, {USB_DEVICE(0x093a, 0x262c)}, {} -- cgit v1.2.3-70-g09d2 From 8c4ebae45f8fa189746656a71d8a0ed21d569344 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 2 Dec 2009 07:14:33 -0300 Subject: V4L/DVB (13566): gspca - main: New variable usb_err for USB exchanges. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 13 +++++++++++++ drivers/media/video/gspca/gspca.h | 1 + 2 files changed, 14 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index e6e8df48485..95a8b84d4cf 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -767,6 +767,7 @@ static int vidioc_g_register(struct file *file, void *priv, if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; + gspca_dev->usb_err = 0; if (gspca_dev->present) ret = gspca_dev->sd_desc->get_register(gspca_dev, reg); else @@ -790,6 +791,7 @@ static int vidioc_s_register(struct file *file, void *priv, if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; + gspca_dev->usb_err = 0; if (gspca_dev->present) ret = gspca_dev->sd_desc->set_register(gspca_dev, reg); else @@ -811,6 +813,7 @@ static int vidioc_g_chip_ident(struct file *file, void *priv, if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; + gspca_dev->usb_err = 0; if (gspca_dev->present) ret = gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip); else @@ -1081,6 +1084,7 @@ static int dev_close(struct file *file) if (gspca_dev->capt_file == file) { if (gspca_dev->streaming) { mutex_lock(&gspca_dev->usb_lock); + gspca_dev->usb_err = 0; gspca_stream_off(gspca_dev); mutex_unlock(&gspca_dev->usb_lock); } @@ -1200,6 +1204,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; + gspca_dev->usb_err = 0; if (gspca_dev->present) ret = ctrls->set(gspca_dev, ctrl->value); else @@ -1221,6 +1226,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv, if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; + gspca_dev->usb_err = 0; if (gspca_dev->present) ret = ctrls->get(gspca_dev, &ctrl->value); else @@ -1335,6 +1341,7 @@ static int vidioc_reqbufs(struct file *file, void *priv, /* stop streaming */ if (gspca_dev->streaming) { mutex_lock(&gspca_dev->usb_lock); + gspca_dev->usb_err = 0; gspca_stream_off(gspca_dev); mutex_unlock(&gspca_dev->usb_lock); } @@ -1426,6 +1433,7 @@ static int vidioc_streamoff(struct file *file, void *priv, ret = -ERESTARTSYS; goto out; } + gspca_dev->usb_err = 0; gspca_stream_off(gspca_dev); mutex_unlock(&gspca_dev->usb_lock); @@ -1451,6 +1459,7 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv, return -EINVAL; if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; + gspca_dev->usb_err = 0; if (gspca_dev->present) ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp); else @@ -1469,6 +1478,7 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv, return -EINVAL; if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; + gspca_dev->usb_err = 0; if (gspca_dev->present) ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp); else @@ -1489,6 +1499,7 @@ static int vidioc_g_parm(struct file *filp, void *priv, if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; + gspca_dev->usb_err = 0; if (gspca_dev->present) ret = gspca_dev->sd_desc->get_streamparm(gspca_dev, parm); @@ -1518,6 +1529,7 @@ static int vidioc_s_parm(struct file *filp, void *priv, if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; + gspca_dev->usb_err = 0; if (gspca_dev->present) ret = gspca_dev->sd_desc->set_streamparm(gspca_dev, parm); @@ -1689,6 +1701,7 @@ static int frame_wait(struct gspca_dev *gspca_dev, if (gspca_dev->sd_desc->dq_callback) { mutex_lock(&gspca_dev->usb_lock); + gspca_dev->usb_err = 0; if (gspca_dev->present) gspca_dev->sd_desc->dq_callback(gspca_dev); mutex_unlock(&gspca_dev->usb_lock); diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index a55c0a04ecf..59c7941da99 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -180,6 +180,7 @@ struct gspca_dev { struct mutex usb_lock; /* usb exchange protection */ struct mutex read_lock; /* read protection */ struct mutex queue_lock; /* ISOC queue protection */ + int usb_err; /* USB error - protected by usb_lock */ #ifdef CONFIG_PM char frozen; /* suspend - resume */ #endif -- cgit v1.2.3-70-g09d2 From ecb776868624751dd86e69c3e6704af35890f953 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 2 Dec 2009 14:39:53 -0300 Subject: V4L/DVB (13567): gspca - sunplus/stk014: Propagate errors to higher level. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/stk014.c | 106 ++++++++-------- drivers/media/video/gspca/sunplus.c | 237 +++++++++++++++++------------------- 2 files changed, 168 insertions(+), 175 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c index 8e23320d7ab..2e2935532d9 100644 --- a/drivers/media/video/gspca/stk014.c +++ b/drivers/media/video/gspca/stk014.c @@ -126,12 +126,14 @@ static const struct v4l2_pix_format vga_mode[] = { }; /* -- read a register -- */ -static int reg_r(struct gspca_dev *gspca_dev, +static u8 reg_r(struct gspca_dev *gspca_dev, __u16 index) { struct usb_device *dev = gspca_dev->dev; int ret; + if (gspca_dev->usb_err < 0) + return 0; ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0x00, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, @@ -141,18 +143,21 @@ static int reg_r(struct gspca_dev *gspca_dev, 500); if (ret < 0) { PDEBUG(D_ERR, "reg_r err %d", ret); - return ret; + gspca_dev->usb_err = ret; + return 0; } return gspca_dev->usb_buf[0]; } /* -- write a register -- */ -static int reg_w(struct gspca_dev *gspca_dev, +static void reg_w(struct gspca_dev *gspca_dev, __u16 index, __u16 value) { struct usb_device *dev = gspca_dev->dev; int ret; + if (gspca_dev->usb_err < 0) + return; ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0x01, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, @@ -161,13 +166,14 @@ static int reg_w(struct gspca_dev *gspca_dev, NULL, 0, 500); - if (ret < 0) + if (ret < 0) { PDEBUG(D_ERR, "reg_w err %d", ret); - return ret; + gspca_dev->usb_err = ret; + } } /* -- get a bulk value (4 bytes) -- */ -static int rcv_val(struct gspca_dev *gspca_dev, +static void rcv_val(struct gspca_dev *gspca_dev, int ads) { struct usb_device *dev = gspca_dev->dev; @@ -182,17 +188,22 @@ static int rcv_val(struct gspca_dev *gspca_dev, reg_w(gspca_dev, 0x63a, 0); reg_w(gspca_dev, 0x63b, 0); reg_w(gspca_dev, 0x630, 5); + if (gspca_dev->usb_err < 0) + return; ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, 0x05), gspca_dev->usb_buf, 4, /* length */ &alen, 500); /* timeout in milliseconds */ - return ret; + if (ret < 0) { + PDEBUG(D_ERR, "rcv_val err %d", ret); + gspca_dev->usb_err = ret; + } } /* -- send a bulk value -- */ -static int snd_val(struct gspca_dev *gspca_dev, +static void snd_val(struct gspca_dev *gspca_dev, int ads, unsigned int val) { @@ -201,16 +212,9 @@ static int snd_val(struct gspca_dev *gspca_dev, __u8 seq = 0; if (ads == 0x003f08) { - ret = reg_r(gspca_dev, 0x0704); - if (ret < 0) - goto ko; - ret = reg_r(gspca_dev, 0x0705); - if (ret < 0) - goto ko; - seq = ret; /* keep the sequence number */ - ret = reg_r(gspca_dev, 0x0650); - if (ret < 0) - goto ko; + reg_r(gspca_dev, 0x0704); + seq = reg_r(gspca_dev, 0x0705); + reg_r(gspca_dev, 0x0650); reg_w(gspca_dev, 0x654, seq); } else { reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff); @@ -223,6 +227,8 @@ static int snd_val(struct gspca_dev *gspca_dev, reg_w(gspca_dev, 0x65a, 0); reg_w(gspca_dev, 0x65b, 0); reg_w(gspca_dev, 0x650, 5); + if (gspca_dev->usb_err < 0) + return; gspca_dev->usb_buf[0] = val >> 24; gspca_dev->usb_buf[1] = val >> 16; gspca_dev->usb_buf[2] = val >> 8; @@ -233,24 +239,23 @@ static int snd_val(struct gspca_dev *gspca_dev, 4, &alen, 500); /* timeout in milliseconds */ - if (ret < 0) - goto ko; - if (ads == 0x003f08) { - seq += 4; - seq &= 0x3f; - reg_w(gspca_dev, 0x705, seq); + if (ret < 0) { + PDEBUG(D_ERR, "snd_val err %d", ret); + gspca_dev->usb_err = ret; + } else { + if (ads == 0x003f08) { + seq += 4; + seq &= 0x3f; + reg_w(gspca_dev, 0x705, seq); + } } - return ret; -ko: - PDEBUG(D_ERR, "snd_val err %d", ret); - return ret; } /* set a camera parameter */ -static int set_par(struct gspca_dev *gspca_dev, +static void set_par(struct gspca_dev *gspca_dev, int parval) { - return snd_val(gspca_dev, 0x003f08, parval); + snd_val(gspca_dev, 0x003f08, parval); } static void setbrightness(struct gspca_dev *gspca_dev) @@ -311,18 +316,18 @@ static int sd_config(struct gspca_dev *gspca_dev, /* this function is called at probe and resume time */ static int sd_init(struct gspca_dev *gspca_dev) { - int ret; + u8 ret; /* check if the device responds */ usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); ret = reg_r(gspca_dev, 0x0740); - if (ret < 0) - return ret; - if (ret != 0xff) { - PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", ret); - return -1; + if (gspca_dev->usb_err >= 0) { + if (ret != 0xff) { + PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", ret); + gspca_dev->usb_err = -EIO; + } } - return 0; + return gspca_dev->usb_err; } /* -- start the camera -- */ @@ -357,15 +362,12 @@ static int sd_start(struct gspca_dev *gspca_dev) if (ret < 0) { PDEBUG(D_ERR|D_STREAM, "set intf %d %d failed", gspca_dev->iface, gspca_dev->alt); + gspca_dev->usb_err = ret; goto out; } - ret = reg_r(gspca_dev, 0x0630); - if (ret < 0) - goto out; + reg_r(gspca_dev, 0x0630); rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */ - ret = reg_r(gspca_dev, 0x0650); - if (ret < 0) - goto out; + reg_r(gspca_dev, 0x0650); snd_val(gspca_dev, 0x000020, 0xffffffff); reg_w(gspca_dev, 0x0620, 0); reg_w(gspca_dev, 0x0630, 0); @@ -384,11 +386,11 @@ static int sd_start(struct gspca_dev *gspca_dev) /* start the video flow */ set_par(gspca_dev, 0x01000000); set_par(gspca_dev, 0x01000000); - PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); - return 0; + if (gspca_dev->usb_err >= 0) + PDEBUG(D_STREAM, "camera started alt: 0x%02x", + gspca_dev->alt); out: - PDEBUG(D_ERR|D_STREAM, "camera start err %d", ret); - return ret; + return gspca_dev->usb_err; } static void sd_stopN(struct gspca_dev *gspca_dev) @@ -456,7 +458,7 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) sd->brightness = val; if (gspca_dev->streaming) setbrightness(gspca_dev); - return 0; + return gspca_dev->usb_err; } static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) @@ -474,7 +476,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) sd->contrast = val; if (gspca_dev->streaming) setcontrast(gspca_dev); - return 0; + return gspca_dev->usb_err; } static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) @@ -492,7 +494,7 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) sd->colors = val; if (gspca_dev->streaming) setcolors(gspca_dev); - return 0; + return gspca_dev->usb_err; } static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) @@ -510,7 +512,7 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) sd->lightfreq = val; if (gspca_dev->streaming) setfreq(gspca_dev); - return 0; + return gspca_dev->usb_err; } static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) @@ -552,7 +554,7 @@ static int sd_set_jcomp(struct gspca_dev *gspca_dev, sd->quality = jcomp->quality; if (gspca_dev->streaming) jpeg_set_qual(sd->jpeg_hdr, sd->quality); - return 0; + return gspca_dev->usb_err; } static int sd_get_jcomp(struct gspca_dev *gspca_dev, diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index 72bf3b4f0a3..716df6b15fc 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c @@ -460,13 +460,17 @@ static void reg_r(struct gspca_dev *gspca_dev, u16 index, u16 len) { + int ret; + #ifdef GSPCA_DEBUG if (len > USB_BUF_SZ) { err("reg_r: buffer overflow"); return; } #endif - usb_control_msg(gspca_dev->dev, + if (gspca_dev->usb_err < 0) + return; + ret = usb_control_msg(gspca_dev->dev, usb_rcvctrlpipe(gspca_dev->dev, 0), req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, @@ -474,6 +478,10 @@ static void reg_r(struct gspca_dev *gspca_dev, index, len ? gspca_dev->usb_buf : NULL, len, 500); + if (ret < 0) { + PDEBUG(D_ERR, "reg_r err %d", ret); + gspca_dev->usb_err = ret; + } } /* write one byte */ @@ -483,40 +491,55 @@ static void reg_w_1(struct gspca_dev *gspca_dev, u16 index, u16 byte) { + int ret; + + if (gspca_dev->usb_err < 0) + return; gspca_dev->usb_buf[0] = byte; - usb_control_msg(gspca_dev->dev, + ret = usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), req, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, gspca_dev->usb_buf, 1, 500); + if (ret < 0) { + PDEBUG(D_ERR, "reg_w_1 err %d", ret); + gspca_dev->usb_err = ret; + } } /* write req / index / value */ -static int reg_w_riv(struct usb_device *dev, +static void reg_w_riv(struct gspca_dev *gspca_dev, u8 req, u16 index, u16 value) { + struct usb_device *dev = gspca_dev->dev; int ret; + if (gspca_dev->usb_err < 0) + return; ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), req, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, NULL, 0, 500); - PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d", - req, index, value, ret); - if (ret < 0) - PDEBUG(D_ERR, "reg write: error %d", ret); - return ret; + if (ret < 0) { + PDEBUG(D_ERR, "reg_w_riv err %d", ret); + gspca_dev->usb_err = ret; + return; + } + PDEBUG(D_USBO, "reg_w_riv: 0x%02x,0x%04x:0x%04x", + req, index, value); } /* read 1 byte */ -static int reg_r_1(struct gspca_dev *gspca_dev, +static u8 reg_r_1(struct gspca_dev *gspca_dev, u16 value) /* wValue */ { int ret; + if (gspca_dev->usb_err < 0) + return 0; ret = usb_control_msg(gspca_dev->dev, usb_rcvctrlpipe(gspca_dev->dev, 0), 0x20, /* request */ @@ -527,19 +550,22 @@ static int reg_r_1(struct gspca_dev *gspca_dev, 500); /* timeout */ if (ret < 0) { PDEBUG(D_ERR, "reg_r_1 err %d", ret); + gspca_dev->usb_err = ret; return 0; } return gspca_dev->usb_buf[0]; } -/* read 1 or 2 bytes - returns < 0 if error */ -static int reg_r_12(struct gspca_dev *gspca_dev, +/* read 1 or 2 bytes */ +static u16 reg_r_12(struct gspca_dev *gspca_dev, u8 req, /* bRequest */ u16 index, /* wIndex */ u16 length) /* wLength (1 or 2 only) */ { int ret; + if (gspca_dev->usb_err < 0) + return 0; gspca_dev->usb_buf[1] = 0; ret = usb_control_msg(gspca_dev->dev, usb_rcvctrlpipe(gspca_dev->dev, 0), @@ -550,62 +576,44 @@ static int reg_r_12(struct gspca_dev *gspca_dev, gspca_dev->usb_buf, length, 500); if (ret < 0) { - PDEBUG(D_ERR, "reg_read err %d", ret); - return -1; + PDEBUG(D_ERR, "reg_r_12 err %d", ret); + gspca_dev->usb_err = ret; + return 0; } return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; } -static int write_vector(struct gspca_dev *gspca_dev, +static void write_vector(struct gspca_dev *gspca_dev, const struct cmd *data, int ncmds) { - struct usb_device *dev = gspca_dev->dev; - int ret; - while (--ncmds >= 0) { - ret = reg_w_riv(dev, data->req, data->idx, data->val); - if (ret < 0) { - PDEBUG(D_ERR, - "Register write failed for 0x%02x, 0x%04x, 0x%04x", - data->req, data->val, data->idx); - return ret; - } + reg_w_riv(gspca_dev, data->req, data->idx, data->val); data++; } - return 0; } -static int spca50x_setup_qtable(struct gspca_dev *gspca_dev, - const u8 qtable[2][64]) +static void setup_qtable(struct gspca_dev *gspca_dev, + const u8 qtable[2][64]) { - struct usb_device *dev = gspca_dev->dev; - int i, err; + int i; /* loop over y components */ - for (i = 0; i < 64; i++) { - err = reg_w_riv(dev, 0x00, 0x2800 + i, qtable[0][i]); - if (err < 0) - return err; - } + for (i = 0; i < 64; i++) + reg_w_riv(gspca_dev, 0x00, 0x2800 + i, qtable[0][i]); /* loop over c components */ - for (i = 0; i < 64; i++) { - err = reg_w_riv(dev, 0x00, 0x2840 + i, qtable[1][i]); - if (err < 0) - return err; - } - return 0; + for (i = 0; i < 64; i++) + reg_w_riv(gspca_dev, 0x00, 0x2840 + i, qtable[1][i]); } static void spca504_acknowledged_command(struct gspca_dev *gspca_dev, u8 req, u16 idx, u16 val) { - struct usb_device *dev = gspca_dev->dev; - int notdone; + u16 notdone; - reg_w_riv(dev, req, idx, val); + reg_w_riv(gspca_dev, req, idx, val); notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1); - reg_w_riv(dev, req, idx, val); + reg_w_riv(gspca_dev, req, idx, val); PDEBUG(D_FRAM, "before wait 0x%04x", notdone); @@ -616,23 +624,22 @@ static void spca504_acknowledged_command(struct gspca_dev *gspca_dev, static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, u8 req, - u16 idx, u16 val, u8 stat, u8 count) + u16 idx, u16 val, u16 endcode, u8 count) { - struct usb_device *dev = gspca_dev->dev; - int status; - u8 endcode; + u16 status; - reg_w_riv(dev, req, idx, val); + reg_w_riv(gspca_dev, req, idx, val); status = reg_r_12(gspca_dev, 0x01, 0x0001, 1); - endcode = stat; - PDEBUG(D_FRAM, "Status 0x%x Need 0x%04x", status, stat); + if (gspca_dev->usb_err < 0) + return; + PDEBUG(D_FRAM, "Status 0x%04x Need 0x%04x", status, endcode); if (!count) return; count = 200; while (--count > 0) { msleep(10); /* gsmart mini2 write a each wait setting 1 ms is enough */ -/* reg_w_riv(dev, req, idx, val); */ +/* reg_w_riv(gspca_dev, req, idx, val); */ status = reg_r_12(gspca_dev, 0x01, 0x0001, 1); if (status == endcode) { PDEBUG(D_FRAM, "status 0x%04x after wait %d", @@ -642,7 +649,7 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, } } -static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev) +static void spca504B_PollingDataReady(struct gspca_dev *gspca_dev) { int count = 10; @@ -652,7 +659,6 @@ static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev) break; msleep(10); } - return gspca_dev->usb_buf[0]; } static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev) @@ -686,28 +692,26 @@ static void spca50x_GetFirmware(struct gspca_dev *gspca_dev) static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; u8 Size; - int rc; Size = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; switch (sd->bridge) { case BRIDGE_SPCA533: - reg_w_riv(dev, 0x31, 0, 0); + reg_w_riv(gspca_dev, 0x31, 0, 0); spca504B_WaitCmdStatus(gspca_dev); - rc = spca504B_PollingDataReady(gspca_dev); + spca504B_PollingDataReady(gspca_dev); spca50x_GetFirmware(gspca_dev); reg_w_1(gspca_dev, 0x24, 0, 8, 2); /* type */ reg_r(gspca_dev, 0x24, 8, 1); reg_w_1(gspca_dev, 0x25, 0, 4, Size); reg_r(gspca_dev, 0x25, 4, 1); /* size */ - rc = spca504B_PollingDataReady(gspca_dev); + spca504B_PollingDataReady(gspca_dev); /* Init the cam width height with some values get on init ? */ - reg_w_riv(dev, 0x31, 0, 0x04); + reg_w_riv(gspca_dev, 0x31, 0, 0x04); spca504B_WaitCmdStatus(gspca_dev); - rc = spca504B_PollingDataReady(gspca_dev); + spca504B_PollingDataReady(gspca_dev); break; default: /* case BRIDGE_SPCA504B: */ @@ -716,7 +720,7 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) reg_r(gspca_dev, 0x25, 4, 1); /* size */ reg_w_1(gspca_dev, 0x27, 0, 0, 6); reg_r(gspca_dev, 0x27, 0, 1); /* type */ - rc = spca504B_PollingDataReady(gspca_dev); + spca504B_PollingDataReady(gspca_dev); break; case BRIDGE_SPCA504: Size += 3; @@ -733,8 +737,8 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) break; case BRIDGE_SPCA504C: /* capture mode */ - reg_w_riv(dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00); - reg_w_riv(dev, 0x20, 0x01, 0x0500 | (Size & 0x0f)); + reg_w_riv(gspca_dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00); + reg_w_riv(gspca_dev, 0x20, 0x01, 0x0500 | (Size & 0x0f)); break; } } @@ -762,37 +766,33 @@ static void spca504B_setQtable(struct gspca_dev *gspca_dev) static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; u16 reg; reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7; - reg_w_riv(dev, 0x00, reg, sd->brightness); + reg_w_riv(gspca_dev, 0x00, reg, sd->brightness); } static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; u16 reg; reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8; - reg_w_riv(dev, 0x00, reg, sd->contrast); + reg_w_riv(gspca_dev, 0x00, reg, sd->contrast); } static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; u16 reg; reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae; - reg_w_riv(dev, 0x00, reg, sd->colors); + reg_w_riv(gspca_dev, 0x00, reg, sd->colors); } static void init_ctl_reg(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; int pollreg = 1; setbrightness(gspca_dev); @@ -807,14 +807,14 @@ static void init_ctl_reg(struct gspca_dev *gspca_dev) default: /* case BRIDGE_SPCA533: */ /* case BRIDGE_SPCA504B: */ - reg_w_riv(dev, 0, 0x00, 0x21ad); /* hue */ - reg_w_riv(dev, 0, 0x01, 0x21ac); /* sat/hue */ - reg_w_riv(dev, 0, 0x00, 0x21a3); /* gamma */ + reg_w_riv(gspca_dev, 0, 0x00, 0x21ad); /* hue */ + reg_w_riv(gspca_dev, 0, 0x01, 0x21ac); /* sat/hue */ + reg_w_riv(gspca_dev, 0, 0x00, 0x21a3); /* gamma */ break; case BRIDGE_SPCA536: - reg_w_riv(dev, 0, 0x40, 0x20f5); - reg_w_riv(dev, 0, 0x01, 0x20f4); - reg_w_riv(dev, 0, 0x00, 0x2089); + reg_w_riv(gspca_dev, 0, 0x40, 0x20f5); + reg_w_riv(gspca_dev, 0, 0x01, 0x20f4); + reg_w_riv(gspca_dev, 0, 0x00, 0x2089); break; } if (pollreg) @@ -881,18 +881,17 @@ static int sd_config(struct gspca_dev *gspca_dev, static int sd_init(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; - int i, err_code; + int i; u8 info[6]; switch (sd->bridge) { case BRIDGE_SPCA504B: - reg_w_riv(dev, 0x1d, 0x00, 0); - reg_w_riv(dev, 0, 0x01, 0x2306); - reg_w_riv(dev, 0, 0x00, 0x0d04); - reg_w_riv(dev, 0, 0x00, 0x2000); - reg_w_riv(dev, 0, 0x13, 0x2301); - reg_w_riv(dev, 0, 0x00, 0x2306); + reg_w_riv(gspca_dev, 0x1d, 0x00, 0); + reg_w_riv(gspca_dev, 0, 0x01, 0x2306); + reg_w_riv(gspca_dev, 0, 0x00, 0x0d04); + reg_w_riv(gspca_dev, 0, 0x00, 0x2000); + reg_w_riv(gspca_dev, 0, 0x13, 0x2301); + reg_w_riv(gspca_dev, 0, 0x00, 0x2306); /* fall thru */ case BRIDGE_SPCA533: spca504B_PollingDataReady(gspca_dev); @@ -904,13 +903,13 @@ static int sd_init(struct gspca_dev *gspca_dev) reg_w_1(gspca_dev, 0x24, 0, 0, 0); reg_r(gspca_dev, 0x24, 0, 1); spca504B_PollingDataReady(gspca_dev); - reg_w_riv(dev, 0x34, 0, 0); + reg_w_riv(gspca_dev, 0x34, 0, 0); spca504B_WaitCmdStatus(gspca_dev); break; case BRIDGE_SPCA504C: /* pccam600 */ PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)"); - reg_w_riv(dev, 0xe0, 0x0000, 0x0000); - reg_w_riv(dev, 0xe0, 0x0000, 0x0001); /* reset */ + reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0000); + reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0001); /* reset */ spca504_wait_status(gspca_dev); if (sd->subtype == LogitechClickSmart420) write_vector(gspca_dev, @@ -919,12 +918,7 @@ static int sd_init(struct gspca_dev *gspca_dev) else write_vector(gspca_dev, spca504_pccam600_open_data, ARRAY_SIZE(spca504_pccam600_open_data)); - err_code = spca50x_setup_qtable(gspca_dev, - qtable_creative_pccam); - if (err_code < 0) { - PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed"); - return err_code; - } + setup_qtable(gspca_dev, qtable_creative_pccam); break; default: /* case BRIDGE_SPCA504: */ @@ -958,29 +952,24 @@ static int sd_init(struct gspca_dev *gspca_dev) 6, 0, 0x86, 1); */ /* spca504A_acknowledged_command (gspca_dev, 0x24, 0, 0, 0x9D, 1); */ - reg_w_riv(dev, 0x00, 0x270c, 0x05); /* L92 sno1t.txt */ - reg_w_riv(dev, 0x00, 0x2310, 0x05); + reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05); + /* L92 sno1t.txt */ + reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05); spca504A_acknowledged_command(gspca_dev, 0x01, 0x0f, 0, 0xff, 0); } /* setup qtable */ - reg_w_riv(dev, 0, 0x2000, 0); - reg_w_riv(dev, 0, 0x2883, 1); - err_code = spca50x_setup_qtable(gspca_dev, - qtable_spca504_default); - if (err_code < 0) { - PDEBUG(D_ERR, "spca50x_setup_qtable failed"); - return err_code; - } + reg_w_riv(gspca_dev, 0, 0x2000, 0); + reg_w_riv(gspca_dev, 0, 0x2883, 1); + setup_qtable(gspca_dev, qtable_spca504_default); break; } - return 0; + return gspca_dev->usb_err; } static int sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; int enable; int i; u8 info[6]; @@ -1005,13 +994,13 @@ static int sd_start(struct gspca_dev *gspca_dev) case MegapixV4: case LogitechClickSmart820: case MegaImageVI: - reg_w_riv(dev, 0xf0, 0, 0); + reg_w_riv(gspca_dev, 0xf0, 0, 0); spca504B_WaitCmdStatus(gspca_dev); reg_r(gspca_dev, 0xf0, 4, 0); spca504B_WaitCmdStatus(gspca_dev); break; default: - reg_w_riv(dev, 0x31, 0, 0x04); + reg_w_riv(gspca_dev, 0x31, 0, 0x04); spca504B_WaitCmdStatus(gspca_dev); spca504B_PollingDataReady(gspca_dev); break; @@ -1048,8 +1037,9 @@ static int sd_start(struct gspca_dev *gspca_dev) spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); } spca504B_SetSizeType(gspca_dev); - reg_w_riv(dev, 0x00, 0x270c, 0x05); /* L92 sno1t.txt */ - reg_w_riv(dev, 0x00, 0x2310, 0x05); + reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05); + /* L92 sno1t.txt */ + reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05); break; case BRIDGE_SPCA504C: if (sd->subtype == LogitechClickSmart420) { @@ -1061,36 +1051,37 @@ static int sd_start(struct gspca_dev *gspca_dev) ARRAY_SIZE(spca504_pccam600_init_data)); } enable = (sd->autogain ? 0x04 : 0x01); - reg_w_riv(dev, 0x0c, 0x0000, enable); /* auto exposure */ - reg_w_riv(dev, 0xb0, 0x0000, enable); /* auto whiteness */ + reg_w_riv(gspca_dev, 0x0c, 0x0000, enable); + /* auto exposure */ + reg_w_riv(gspca_dev, 0xb0, 0x0000, enable); + /* auto whiteness */ /* set default exposure compensation and whiteness balance */ - reg_w_riv(dev, 0x30, 0x0001, 800); /* ~ 20 fps */ - reg_w_riv(dev, 0x30, 0x0002, 1600); + reg_w_riv(gspca_dev, 0x30, 0x0001, 800); /* ~ 20 fps */ + reg_w_riv(gspca_dev, 0x30, 0x0002, 1600); spca504B_SetSizeType(gspca_dev); break; } init_ctl_reg(gspca_dev); - return 0; + return gspca_dev->usb_err; } static void sd_stopN(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; switch (sd->bridge) { default: /* case BRIDGE_SPCA533: */ /* case BRIDGE_SPCA536: */ /* case BRIDGE_SPCA504B: */ - reg_w_riv(dev, 0x31, 0, 0); + reg_w_riv(gspca_dev, 0x31, 0, 0); spca504B_WaitCmdStatus(gspca_dev); spca504B_PollingDataReady(gspca_dev); break; case BRIDGE_SPCA504: case BRIDGE_SPCA504C: - reg_w_riv(dev, 0x00, 0x2000, 0x0000); + reg_w_riv(gspca_dev, 0x00, 0x2000, 0x0000); if (sd->subtype == AiptekMiniPenCam13) { /* spca504a aiptek */ @@ -1102,7 +1093,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) 0x0f, 0x00, 0xff, 1); } else { spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); - reg_w_riv(dev, 0x01, 0x000f, 0x0000); + reg_w_riv(gspca_dev, 0x01, 0x000f, 0x0000); } break; } @@ -1216,7 +1207,7 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) sd->brightness = val; if (gspca_dev->streaming) setbrightness(gspca_dev); - return 0; + return gspca_dev->usb_err; } static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) @@ -1234,7 +1225,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) sd->contrast = val; if (gspca_dev->streaming) setcontrast(gspca_dev); - return 0; + return gspca_dev->usb_err; } static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) @@ -1252,7 +1243,7 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) sd->colors = val; if (gspca_dev->streaming) setcolors(gspca_dev); - return 0; + return gspca_dev->usb_err; } static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) @@ -1292,7 +1283,7 @@ static int sd_set_jcomp(struct gspca_dev *gspca_dev, sd->quality = jcomp->quality; if (gspca_dev->streaming) jpeg_set_qual(sd->jpeg_hdr, sd->quality); - return 0; + return gspca_dev->usb_err; } static int sd_get_jcomp(struct gspca_dev *gspca_dev, -- cgit v1.2.3-70-g09d2 From 20d15a200d34cfb7141fb4558895d7d5233db84b Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 30 Nov 2009 18:22:10 -0300 Subject: V4L/DVB (13569): smsusb: add autodetection support for five additional Hauppauge USB IDs Add support for five new Hauppauge Device USB IDs: 2040:b980 2040:b990 2040:c010 2040:c080 2040:c090 Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsusb.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 8f88a586b0d..6b03dbf3635 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -533,8 +533,18 @@ struct usb_device_id smsusb_id_table[] = { .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { USB_DEVICE(0x2040, 0xb910), .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0xb980), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0xb990), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { USB_DEVICE(0x2040, 0xc000), .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0xc010), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0xc080), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0xc090), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { } /* Terminating entry */ }; -- cgit v1.2.3-70-g09d2 From b6456c0cfe9d94e6d2bf684e6e6c031fc0b10031 Mon Sep 17 00:00:00 2001 From: Muralidharan Karicheri Date: Thu, 19 Nov 2009 12:00:31 -0300 Subject: V4L/DVB (13571): v4l: Adding Digital Video Timings APIs This adds the above APIs to the v4l2 core. This is based on version v1.2 of the RFC titled "V4L - Support for video timings at the input/output interface" Following new ioctls are added:- - VIDIOC_ENUM_DV_PRESETS - VIDIOC_S_DV_PRESET - VIDIOC_G_DV_PRESET - VIDIOC_QUERY_DV_PRESET - VIDIOC_S_DV_TIMINGS - VIDIOC_G_DV_TIMINGS Please refer to the RFC for the details. This code was tested using vpfe capture driver on TI's DM365. Following is the test configuration used :- Blu-Ray HD DVD source -> TVP7002 -> DM365 (VPFE) ->DDR A draft version of the TVP7002 driver (currently being reviewed in the mailing list) was used that supports V4L2_DV_1080I60 & V4L2_DV_720P60 presets. A loopback video capture application was used for testing these APIs. This calls following IOCTLS :- - verify the new v4l2_input capabilities flag added - Enumerate available presets using VIDIOC_ENUM_DV_PRESETS - Set one of the supported preset using VIDIOC_S_DV_PRESET - Get current preset using VIDIOC_G_DV_PRESET - Detect current preset using VIDIOC_QUERY_DV_PRESET - Using stub functions in tvp7002, verify VIDIOC_S_DV_TIMINGS and VIDIOC_G_DV_TIMINGS ioctls are received at the sub device. - Tested on 64bit platform by Hans Verkuil Signed-off-by: Muralidharan Karicheri Signed-off-by: Hans Verkuil Reviewed-by: Randy Dunlap Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-compat-ioctl32.c | 6 ++ drivers/media/video/v4l2-ioctl.c | 147 ++++++++++++++++++++++++++++++ include/linux/videodev2.h | 116 ++++++++++++++++++++++- include/media/v4l2-ioctl.h | 15 +++ include/media/v4l2-subdev.h | 21 +++++ 5 files changed, 303 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c index 997975d5e02..c4150bd2633 100644 --- a/drivers/media/video/v4l2-compat-ioctl32.c +++ b/drivers/media/video/v4l2-compat-ioctl32.c @@ -1077,6 +1077,12 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) case VIDIOC_DBG_G_REGISTER: case VIDIOC_DBG_G_CHIP_IDENT: case VIDIOC_S_HW_FREQ_SEEK: + case VIDIOC_ENUM_DV_PRESETS: + case VIDIOC_S_DV_PRESET: + case VIDIOC_G_DV_PRESET: + case VIDIOC_QUERY_DV_PRESET: + case VIDIOC_S_DV_TIMINGS: + case VIDIOC_G_DV_TIMINGS: ret = do_video_ioctl(file, cmd, arg); break; diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 30cc3347ae5..4b11257c318 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -284,6 +284,12 @@ static const char *v4l2_ioctls[] = { [_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT", [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK", #endif + [_IOC_NR(VIDIOC_ENUM_DV_PRESETS)] = "VIDIOC_ENUM_DV_PRESETS", + [_IOC_NR(VIDIOC_S_DV_PRESET)] = "VIDIOC_S_DV_PRESET", + [_IOC_NR(VIDIOC_G_DV_PRESET)] = "VIDIOC_G_DV_PRESET", + [_IOC_NR(VIDIOC_QUERY_DV_PRESET)] = "VIDIOC_QUERY_DV_PRESET", + [_IOC_NR(VIDIOC_S_DV_TIMINGS)] = "VIDIOC_S_DV_TIMINGS", + [_IOC_NR(VIDIOC_G_DV_TIMINGS)] = "VIDIOC_G_DV_TIMINGS", }; #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) @@ -1135,6 +1141,19 @@ static long __video_do_ioctl(struct file *file, { struct v4l2_input *p = arg; + /* + * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS & + * CAP_STD here based on ioctl handler provided by the + * driver. If the driver doesn't support these + * for a specific input, it must override these flags. + */ + if (ops->vidioc_s_std) + p->capabilities |= V4L2_IN_CAP_STD; + if (ops->vidioc_s_dv_preset) + p->capabilities |= V4L2_IN_CAP_PRESETS; + if (ops->vidioc_s_dv_timings) + p->capabilities |= V4L2_IN_CAP_CUSTOM_TIMINGS; + if (!ops->vidioc_enum_input) break; @@ -1179,6 +1198,19 @@ static long __video_do_ioctl(struct file *file, if (!ops->vidioc_enum_output) break; + /* + * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS & + * CAP_STD here based on ioctl handler provided by the + * driver. If the driver doesn't support these + * for a specific output, it must override these flags. + */ + if (ops->vidioc_s_std) + p->capabilities |= V4L2_OUT_CAP_STD; + if (ops->vidioc_s_dv_preset) + p->capabilities |= V4L2_OUT_CAP_PRESETS; + if (ops->vidioc_s_dv_timings) + p->capabilities |= V4L2_OUT_CAP_CUSTOM_TIMINGS; + ret = ops->vidioc_enum_output(file, fh, p); if (!ret) dbgarg(cmd, "index=%d, name=%s, type=%d, " @@ -1794,6 +1826,121 @@ static long __video_do_ioctl(struct file *file, } break; } + case VIDIOC_ENUM_DV_PRESETS: + { + struct v4l2_dv_enum_preset *p = arg; + + if (!ops->vidioc_enum_dv_presets) + break; + + ret = ops->vidioc_enum_dv_presets(file, fh, p); + if (!ret) + dbgarg(cmd, + "index=%d, preset=%d, name=%s, width=%d," + " height=%d ", + p->index, p->preset, p->name, p->width, + p->height); + break; + } + case VIDIOC_S_DV_PRESET: + { + struct v4l2_dv_preset *p = arg; + + if (!ops->vidioc_s_dv_preset) + break; + + dbgarg(cmd, "preset=%d\n", p->preset); + ret = ops->vidioc_s_dv_preset(file, fh, p); + break; + } + case VIDIOC_G_DV_PRESET: + { + struct v4l2_dv_preset *p = arg; + + if (!ops->vidioc_g_dv_preset) + break; + + ret = ops->vidioc_g_dv_preset(file, fh, p); + if (!ret) + dbgarg(cmd, "preset=%d\n", p->preset); + break; + } + case VIDIOC_QUERY_DV_PRESET: + { + struct v4l2_dv_preset *p = arg; + + if (!ops->vidioc_query_dv_preset) + break; + + ret = ops->vidioc_query_dv_preset(file, fh, p); + if (!ret) + dbgarg(cmd, "preset=%d\n", p->preset); + break; + } + case VIDIOC_S_DV_TIMINGS: + { + struct v4l2_dv_timings *p = arg; + + if (!ops->vidioc_s_dv_timings) + break; + + switch (p->type) { + case V4L2_DV_BT_656_1120: + dbgarg2("bt-656/1120:interlaced=%d, pixelclock=%lld," + " width=%d, height=%d, polarities=%x," + " hfrontporch=%d, hsync=%d, hbackporch=%d," + " vfrontporch=%d, vsync=%d, vbackporch=%d," + " il_vfrontporch=%d, il_vsync=%d," + " il_vbackporch=%d\n", + p->bt.interlaced, p->bt.pixelclock, + p->bt.width, p->bt.height, p->bt.polarities, + p->bt.hfrontporch, p->bt.hsync, + p->bt.hbackporch, p->bt.vfrontporch, + p->bt.vsync, p->bt.vbackporch, + p->bt.il_vfrontporch, p->bt.il_vsync, + p->bt.il_vbackporch); + ret = ops->vidioc_s_dv_timings(file, fh, p); + break; + default: + dbgarg2("Unknown type %d!\n", p->type); + break; + } + break; + } + case VIDIOC_G_DV_TIMINGS: + { + struct v4l2_dv_timings *p = arg; + + if (!ops->vidioc_g_dv_timings) + break; + + ret = ops->vidioc_g_dv_timings(file, fh, p); + if (!ret) { + switch (p->type) { + case V4L2_DV_BT_656_1120: + dbgarg2("bt-656/1120:interlaced=%d," + " pixelclock=%lld," + " width=%d, height=%d, polarities=%x," + " hfrontporch=%d, hsync=%d," + " hbackporch=%d, vfrontporch=%d," + " vsync=%d, vbackporch=%d," + " il_vfrontporch=%d, il_vsync=%d," + " il_vbackporch=%d\n", + p->bt.interlaced, p->bt.pixelclock, + p->bt.width, p->bt.height, + p->bt.polarities, p->bt.hfrontporch, + p->bt.hsync, p->bt.hbackporch, + p->bt.vfrontporch, p->bt.vsync, + p->bt.vbackporch, p->bt.il_vfrontporch, + p->bt.il_vsync, p->bt.il_vbackporch); + break; + default: + dbgarg2("Unknown type %d!\n", p->type); + break; + } + } + break; + } default: { diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 32b92298fd7..59047ebf452 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -731,6 +731,99 @@ struct v4l2_standard { __u32 reserved[4]; }; +/* + * V I D E O T I M I N G S D V P R E S E T + */ +struct v4l2_dv_preset { + __u32 preset; + __u32 reserved[4]; +}; + +/* + * D V P R E S E T S E N U M E R A T I O N + */ +struct v4l2_dv_enum_preset { + __u32 index; + __u32 preset; + __u8 name[32]; /* Name of the preset timing */ + __u32 width; + __u32 height; + __u32 reserved[4]; +}; + +/* + * D V P R E S E T V A L U E S + */ +#define V4L2_DV_INVALID 0 +#define V4L2_DV_480P59_94 1 /* BT.1362 */ +#define V4L2_DV_576P50 2 /* BT.1362 */ +#define V4L2_DV_720P24 3 /* SMPTE 296M */ +#define V4L2_DV_720P25 4 /* SMPTE 296M */ +#define V4L2_DV_720P30 5 /* SMPTE 296M */ +#define V4L2_DV_720P50 6 /* SMPTE 296M */ +#define V4L2_DV_720P59_94 7 /* SMPTE 274M */ +#define V4L2_DV_720P60 8 /* SMPTE 274M/296M */ +#define V4L2_DV_1080I29_97 9 /* BT.1120/ SMPTE 274M */ +#define V4L2_DV_1080I30 10 /* BT.1120/ SMPTE 274M */ +#define V4L2_DV_1080I25 11 /* BT.1120 */ +#define V4L2_DV_1080I50 12 /* SMPTE 296M */ +#define V4L2_DV_1080I60 13 /* SMPTE 296M */ +#define V4L2_DV_1080P24 14 /* SMPTE 296M */ +#define V4L2_DV_1080P25 15 /* SMPTE 296M */ +#define V4L2_DV_1080P30 16 /* SMPTE 296M */ +#define V4L2_DV_1080P50 17 /* BT.1120 */ +#define V4L2_DV_1080P60 18 /* BT.1120 */ + +/* + * D V B T T I M I N G S + */ + +/* BT.656/BT.1120 timing data */ +struct v4l2_bt_timings { + __u32 width; /* width in pixels */ + __u32 height; /* height in lines */ + __u32 interlaced; /* Interlaced or progressive */ + __u32 polarities; /* Positive or negative polarity */ + __u64 pixelclock; /* Pixel clock in HZ. Ex. 74.25MHz->74250000 */ + __u32 hfrontporch; /* Horizpontal front porch in pixels */ + __u32 hsync; /* Horizontal Sync length in pixels */ + __u32 hbackporch; /* Horizontal back porch in pixels */ + __u32 vfrontporch; /* Vertical front porch in pixels */ + __u32 vsync; /* Vertical Sync length in lines */ + __u32 vbackporch; /* Vertical back porch in lines */ + __u32 il_vfrontporch; /* Vertical front porch for bottom field of + * interlaced field formats + */ + __u32 il_vsync; /* Vertical sync length for bottom field of + * interlaced field formats + */ + __u32 il_vbackporch; /* Vertical back porch for bottom field of + * interlaced field formats + */ + __u32 reserved[16]; +} __attribute__ ((packed)); + +/* Interlaced or progressive format */ +#define V4L2_DV_PROGRESSIVE 0 +#define V4L2_DV_INTERLACED 1 + +/* Polarities. If bit is not set, it is assumed to be negative polarity */ +#define V4L2_DV_VSYNC_POS_POL 0x00000001 +#define V4L2_DV_HSYNC_POS_POL 0x00000002 + + +/* DV timings */ +struct v4l2_dv_timings { + __u32 type; + union { + struct v4l2_bt_timings bt; + __u32 reserved[32]; + }; +} __attribute__ ((packed)); + +/* Values for the type field */ +#define V4L2_DV_BT_656_1120 0 /* BT.656/1120 timing type */ + /* * V I D E O I N P U T S */ @@ -742,7 +835,8 @@ struct v4l2_input { __u32 tuner; /* Associated tuner */ v4l2_std_id std; __u32 status; - __u32 reserved[4]; + __u32 capabilities; + __u32 reserved[3]; }; /* Values for the 'type' field */ @@ -773,6 +867,11 @@ struct v4l2_input { #define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */ #define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */ +/* capabilities flags */ +#define V4L2_IN_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */ +#define V4L2_IN_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ +#define V4L2_IN_CAP_STD 0x00000004 /* Supports S_STD */ + /* * V I D E O O U T P U T S */ @@ -783,13 +882,19 @@ struct v4l2_output { __u32 audioset; /* Associated audios (bitfield) */ __u32 modulator; /* Associated modulator */ v4l2_std_id std; - __u32 reserved[4]; + __u32 capabilities; + __u32 reserved[3]; }; /* Values for the 'type' field */ #define V4L2_OUTPUT_TYPE_MODULATOR 1 #define V4L2_OUTPUT_TYPE_ANALOG 2 #define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 +/* capabilities flags */ +#define V4L2_OUT_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */ +#define V4L2_OUT_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ +#define V4L2_OUT_CAP_STD 0x00000004 /* Supports S_STD */ + /* * C O N T R O L S */ @@ -1624,6 +1729,13 @@ struct v4l2_dbg_chip_ident { #endif #define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) +#define VIDIOC_ENUM_DV_PRESETS _IOWR('V', 83, struct v4l2_dv_enum_preset) +#define VIDIOC_S_DV_PRESET _IOWR('V', 84, struct v4l2_dv_preset) +#define VIDIOC_G_DV_PRESET _IOWR('V', 85, struct v4l2_dv_preset) +#define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct v4l2_dv_preset) +#define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings) +#define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings) + /* Reminder: when adding new ioctls please add support for them to drivers/media/video/v4l2-compat-ioctl32.c as well! */ diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index 7a4529defa8..e8ba0f2efba 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h @@ -239,6 +239,21 @@ struct v4l2_ioctl_ops { int (*vidioc_enum_frameintervals) (struct file *file, void *fh, struct v4l2_frmivalenum *fival); + /* DV Timings IOCTLs */ + int (*vidioc_enum_dv_presets) (struct file *file, void *fh, + struct v4l2_dv_enum_preset *preset); + + int (*vidioc_s_dv_preset) (struct file *file, void *fh, + struct v4l2_dv_preset *preset); + int (*vidioc_g_dv_preset) (struct file *file, void *fh, + struct v4l2_dv_preset *preset); + int (*vidioc_query_dv_preset) (struct file *file, void *fh, + struct v4l2_dv_preset *qpreset); + int (*vidioc_s_dv_timings) (struct file *file, void *fh, + struct v4l2_dv_timings *timings); + int (*vidioc_g_dv_timings) (struct file *file, void *fh, + struct v4l2_dv_timings *timings); + /* For other private ioctls */ long (*vidioc_default) (struct file *file, void *fh, int cmd, void *arg); diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 00bf1760845..7a3408f9d0f 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -217,6 +217,19 @@ struct v4l2_subdev_audio_ops { s_routing: see s_routing in audio_ops, except this version is for video devices. + + s_dv_preset: set dv (Digital Video) preset in the sub device. Similar to + s_std() + + query_dv_preset: query dv preset in the sub device. This is similar to + querystd() + + s_dv_timings(): Set custom dv timings in the sub device. This is used + when sub device is capable of setting detailed timing information + in the hardware to generate/detect the video signal. + + g_dv_timings(): Get custom dv timings in the sub device. + */ struct v4l2_subdev_video_ops { int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config); @@ -240,6 +253,14 @@ struct v4l2_subdev_video_ops { int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); int (*enum_framesizes)(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize); int (*enum_frameintervals)(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival); + int (*s_dv_preset)(struct v4l2_subdev *sd, + struct v4l2_dv_preset *preset); + int (*query_dv_preset)(struct v4l2_subdev *sd, + struct v4l2_dv_preset *preset); + int (*s_dv_timings)(struct v4l2_subdev *sd, + struct v4l2_dv_timings *timings); + int (*g_dv_timings)(struct v4l2_subdev *sd, + struct v4l2_dv_timings *timings); }; /* -- cgit v1.2.3-70-g09d2 From b779974bdfcaec2a0eb13e44405baca07e0e92a3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 5 Dec 2009 23:24:50 -0300 Subject: V4L/DVB (13575): em28xx: Use the complete address/command RC5 code for WinTV USB2 This device uses an i2c chip to retrieve the keycode from a RC5 remote. Instead of just getting 6 bits, improve the routine to get 11 bits. This means that the complete RC5 table for Hauppauge Grey IR can be used with this device. Unfortunately, it seems that this IR receiver is not capable of getting the full 14 (or 13 bits) from the RC5 protocol. At lest now, with the new code, it is possible to replace this IR table by another RC5 table. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-cards.c | 2 +- drivers/media/video/em28xx/em28xx-input.c | 41 ++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 13 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index e7a68e2507d..25100001fff 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -2285,7 +2285,7 @@ void em28xx_register_i2c_ir(struct em28xx *dev) dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)"; break; case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: - dev->init_data.ir_codes = &ir_codes_hauppauge_new_table; + dev->init_data.ir_codes = &ir_codes_rc5_hauppauge_new_table; dev->init_data.get_key = em28xx_get_key_em_haup; dev->init_data.name = "i2c IR (EM2840 Hauppauge)"; break; diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index 3f5cf02f314..5ddeb421ed5 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c @@ -112,10 +112,13 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) { unsigned char buf[2]; - unsigned char code; + u16 code; + int size; /* poll IR chip */ - if (2 != i2c_master_recv(ir->c, buf, 2)) + size = i2c_master_recv(ir->c, buf, sizeof(buf)); + + if (size != 2) return -EIO; /* Does eliminate repeated parity code */ @@ -124,16 +127,30 @@ int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) ir->old = buf[1]; - /* Rearranges bits to the right order */ - code = ((buf[0]&0x01)<<5) | /* 0010 0000 */ - ((buf[0]&0x02)<<3) | /* 0001 0000 */ - ((buf[0]&0x04)<<1) | /* 0000 1000 */ - ((buf[0]&0x08)>>1) | /* 0000 0100 */ - ((buf[0]&0x10)>>3) | /* 0000 0010 */ - ((buf[0]&0x20)>>5); /* 0000 0001 */ - - i2cdprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n", - code, buf[0]); + /* + * Rearranges bits to the right order. + * The bit order were determined experimentally by using + * The original Hauppauge Grey IR and another RC5 that uses addr=0x08 + * The RC5 code has 14 bits, but we've experimentally determined + * the meaning for only 11 bits. + * So, the code translation is not complete. Yet, it is enough to + * work with the provided RC5 IR. + */ + code = + ((buf[0] & 0x01) ? 0x0020 : 0) | /* 0010 0000 */ + ((buf[0] & 0x02) ? 0x0010 : 0) | /* 0001 0000 */ + ((buf[0] & 0x04) ? 0x0008 : 0) | /* 0000 1000 */ + ((buf[0] & 0x08) ? 0x0004 : 0) | /* 0000 0100 */ + ((buf[0] & 0x10) ? 0x0002 : 0) | /* 0000 0010 */ + ((buf[0] & 0x20) ? 0x0001 : 0) | /* 0000 0001 */ + ((buf[1] & 0x08) ? 0x1000 : 0) | /* 0001 0000 */ + ((buf[1] & 0x10) ? 0x0800 : 0) | /* 0000 1000 */ + ((buf[1] & 0x20) ? 0x0400 : 0) | /* 0000 0100 */ + ((buf[1] & 0x40) ? 0x0200 : 0) | /* 0000 0010 */ + ((buf[1] & 0x80) ? 0x0100 : 0); /* 0000 0001 */ + + i2cdprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x%02x)\n", + code, buf[1], buf[0]); /* return key */ *ir_key = code; -- cgit v1.2.3-70-g09d2 From 05395a3d86a928d374c970a0b35a6a711072f86c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 6 Dec 2009 08:32:49 -0300 Subject: V4L/DVB (13576): ir-common: fix an oops caused by the usage of an initialized drvdata As reported by Sander Eikelenboom : > Tried to update my v4l-dvb modules today, but got a bug with my pinnacle > card, seems to be related to the recent changes in the ir code. > > Dec 5 23:30:25 security kernel: [ 5.735698] BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 > Dec 5 23:30:25 security kernel: [ 5.735716] IP: [] :ir_common:ir_input_free+0x26/0x3e Thanks-to: Sander Eikelenboom for reporting and testing the fix. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-keytable.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/common/ir-keytable.c b/drivers/media/common/ir-keytable.c index 26ce5bc2fdd..ceef0e82fb4 100644 --- a/drivers/media/common/ir-keytable.c +++ b/drivers/media/common/ir-keytable.c @@ -419,6 +419,9 @@ void ir_input_free(struct input_dev *dev) { struct ir_scancode_table *rc_tab = input_get_drvdata(dev); + if (!rc_tab) + return; + IR_dprintk(1, "Freed keycode table\n"); rc_tab->size = 0; -- cgit v1.2.3-70-g09d2 From 0e2f0d348a65b48a8af52d7fd64d77b5759413fa Mon Sep 17 00:00:00 2001 From: Akihiro Tsukada Date: Thu, 19 Nov 2009 12:19:50 -0300 Subject: V4L/DVB (13577): [PATCH] dvb-usb-friio: accept center-shifted frequency This patch adds a fix to accept frequency with its center shifted. The driver used to accept center frequencies of the normal UHF band channels, but in ISDB-T, center frequency is shifted with 1/7MHz. It was shifted internally in the driver, but this patch enables to accept both types of frequency. Signed-off-by: Akihiro Tsukada Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/friio-fe.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/dvb/dvb-usb/friio-fe.c index 9cbbe42ca44..ebb7b9fd115 100644 --- a/drivers/media/dvb/dvb-usb/friio-fe.c +++ b/drivers/media/dvb/dvb-usb/friio-fe.c @@ -134,11 +134,13 @@ static int jdvbt90502_pll_set_freq(struct jdvbt90502_state *state, u32 freq) deb_fe("%s: freq=%d, step=%d\n", __func__, freq, state->frontend.ops.info.frequency_stepsize); /* freq -> oscilator frequency conversion. */ - /* freq: 473,000,000 + n*6,000,000 (no 1/7MHz shift to center freq) */ - /* add 400[1/7 MHZ] = 57.142857MHz. 57MHz for the IF, */ - /* 1/7MHz for center freq shift */ + /* freq: 473,000,000 + n*6,000,000 [+ 142857 (center freq. shift)] */ f = freq / state->frontend.ops.info.frequency_stepsize; - f += 400; + /* add 399[1/7 MHZ] = 57MHz for the IF */ + f += 399; + /* add center frequency shift if necessary */ + if (f % 7 == 0) + f++; pll_freq_cmd[DEMOD_REDIRECT_REG] = JDVBT90502_2ND_I2C_REG; /* 0xFE */ pll_freq_cmd[ADDRESS_BYTE] = state->config.pll_address << 1; pll_freq_cmd[DIVIDER_BYTE1] = (f >> 8) & 0x7F; -- cgit v1.2.3-70-g09d2 From 81afda5182667dcc89374cb5bb94fd6db01c9263 Mon Sep 17 00:00:00 2001 From: Derek Date: Thu, 19 Nov 2009 13:07:12 -0300 Subject: V4L/DVB (13578): [PATCH] fix genpix driver (no 8psk lock). Genpix is demodulating DVB-S-like signal with 8PSK modulation used) - this non-standard behaviour was broken by rejecting 8PSK in a standard DVB-S tune request. This problem is fixed by simply reverting back to the drivers original behavior with this patch. Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/gp8psk-fe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c index 20eadf9318e..7a7f1b2b681 100644 --- a/drivers/media/dvb/dvb-usb/gp8psk-fe.c +++ b/drivers/media/dvb/dvb-usb/gp8psk-fe.c @@ -146,8 +146,8 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend* fe, switch (c->delivery_system) { case SYS_DVBS: - /* Only QPSK is supported for DVB-S */ - if (c->modulation != QPSK) { + /* Allow QPSK and 8PSK (even for DVB-S) */ + if (c->modulation != QPSK && c->modulation != PSK_8) { deb_fe("%s: unsupported modulation selected (%d)\n", __func__, c->modulation); return -EOPNOTSUPP; -- cgit v1.2.3-70-g09d2 From 4bf2c5c30eb50e4d9d9afb4565829ed0e0582d91 Mon Sep 17 00:00:00 2001 From: Pedro Andres Aranda Gutierrez Date: Thu, 19 Nov 2009 13:15:37 -0300 Subject: V4L/DVB (13579): PATCH: better support for INTUIX DVB stick boot The device is bootingcorrectly, but no frontend is attached. This patch corrects this behaviour. Signed-off-by: Pedro Andres Aranda Gutierrez Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dibusb-common.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c index da34979b533..b395e852e47 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/drivers/media/dvb/dvb-usb/dibusb-common.c @@ -243,6 +243,12 @@ static struct dib3000mc_config mod3000p_dib3000p_config = { int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap) { + if (adap->dev->udev->descriptor.idVendor == USB_VID_LITEON && + adap->dev->udev->descriptor.idProduct == + USB_PID_LITEON_DVB_T_WARM) { + msleep(1000); + } + if ((adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000P_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL || (adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000MC_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL) { if (adap->priv != NULL) { -- cgit v1.2.3-70-g09d2 From e414753c8ce5fb0bd81155406efaefe57f374571 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Mon, 30 Nov 2009 13:52:57 -0300 Subject: V4L/DVB (13580): Add support for PCTV 74e (Pinnacle) + fix USB vendor IDs This patch adds support for PCTV 74e (Pinnacle) and it fixes the USB vendor IDs for PCTV (f.k.a Pinnacle). For convenience all new PCTV USB product IDs are also existing with Pinnacle's USB vendor ID. Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 18 +++++++++++++----- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 2 ++ 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 684146f98eb..ad80b939a40 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1929,14 +1929,18 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D) }, /* 55 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D_2) }, { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73A) }, - { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) }, - { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) }, + { USB_DEVICE(USB_VID_PCTV, USB_PID_PINNACLE_PCTV73ESE) }, + { USB_DEVICE(USB_VID_PCTV, USB_PID_PINNACLE_PCTV282E) }, { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7770P) }, /* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) }, { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) }, { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) }, { USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) }, { USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) }, +/* 65 */{ USB_DEVICE(USB_VID_PCTV, USB_PID_PINNACLE_PCTV74E) }, + { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) }, + { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) }, + { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV74E) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -2231,18 +2235,22 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .num_device_descs = 3, + .num_device_descs = 4, .devices = { { "Pinnacle PCTV 73A", { &dib0700_usb_id_table[56], NULL }, { NULL }, }, { "Pinnacle PCTV 73e SE", - { &dib0700_usb_id_table[57], NULL }, + { &dib0700_usb_id_table[57], &dib0700_usb_id_table[66], NULL }, { NULL }, }, { "Pinnacle PCTV 282e", - { &dib0700_usb_id_table[58], NULL }, + { &dib0700_usb_id_table[58], &dib0700_usb_id_table[67], NULL }, + { NULL }, + }, + { "Pinnacle PCTV 74e", + { &dib0700_usb_id_table[65], &dib0700_usb_id_table[68], NULL }, { NULL }, }, }, diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index f1602d4ace6..cf7f2b4b75e 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -47,6 +47,7 @@ #define USB_VID_MSI_2 0x1462 #define USB_VID_OPERA1 0x695c #define USB_VID_PINNACLE 0x2304 +#define USB_VID_PCTV 0x2013 #define USB_VID_PIXELVIEW 0x1554 #define USB_VID_TECHNOTREND 0x0b48 #define USB_VID_TERRATEC 0x0ccd @@ -211,6 +212,7 @@ #define USB_PID_PINNACLE_PCTV801E_SE 0x023b #define USB_PID_PINNACLE_PCTV73A 0x0243 #define USB_PID_PINNACLE_PCTV73ESE 0x0245 +#define USB_PID_PINNACLE_PCTV74E 0x0246 #define USB_PID_PINNACLE_PCTV282E 0x0248 #define USB_PID_PIXELVIEW_SBTVD 0x5010 #define USB_PID_PCTV_200E 0x020e -- cgit v1.2.3-70-g09d2 From 20232c4791507189d4e9499f81632a1ce434f2a4 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Tue, 1 Dec 2009 12:08:56 -0300 Subject: V4L/DVB (13582): DiB0700: remove USB IDs of PCTV 74e from the driver The PCTV 74e is not a design based on the dib0700-USB-device controller thus we should not have its USB IDs inside. This reverts partly: Add support for PCTV 74e (Pinnacle) + fix USB vendor IDs Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index ad80b939a40..923fa157aa5 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1937,10 +1937,8 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) }, { USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) }, { USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) }, -/* 65 */{ USB_DEVICE(USB_VID_PCTV, USB_PID_PINNACLE_PCTV74E) }, - { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) }, +/* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) }, { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) }, - { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV74E) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -2235,22 +2233,18 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .num_device_descs = 4, + .num_device_descs = 3, .devices = { { "Pinnacle PCTV 73A", { &dib0700_usb_id_table[56], NULL }, { NULL }, }, { "Pinnacle PCTV 73e SE", - { &dib0700_usb_id_table[57], &dib0700_usb_id_table[66], NULL }, + { &dib0700_usb_id_table[57], &dib0700_usb_id_table[65], NULL }, { NULL }, }, { "Pinnacle PCTV 282e", - { &dib0700_usb_id_table[58], &dib0700_usb_id_table[67], NULL }, - { NULL }, - }, - { "Pinnacle PCTV 74e", - { &dib0700_usb_id_table[65], &dib0700_usb_id_table[68], NULL }, + { &dib0700_usb_id_table[58], &dib0700_usb_id_table[66], NULL }, { NULL }, }, }, -- cgit v1.2.3-70-g09d2 From 03245a5ee69a5faa99b020fe1aca9bafe10c46a9 Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Fri, 4 Dec 2009 13:27:57 -0300 Subject: V4L/DVB (13583): DiB8090: Add the DiB0090 tuner driver and STK8096GP-board This patchs adds support for the DiBcom DiB0090 RF tuner and for DiBcom's reference design STK8096GP. Small extracts of the DiB0070 and the DiB8000-driver into a common codebase. Signed-off-by: Patrick Boettcher Signed-off-by: Olivier Grenie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 325 +++++- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + drivers/media/dvb/frontends/Kconfig | 9 + drivers/media/dvb/frontends/Makefile | 1 + drivers/media/dvb/frontends/dib0070.c | 654 +++++------ drivers/media/dvb/frontends/dib0070.h | 4 +- drivers/media/dvb/frontends/dib0090.c | 1525 ++++++++++++++++++++++++++ drivers/media/dvb/frontends/dib0090.h | 114 ++ drivers/media/dvb/frontends/dib8000.c | 64 +- drivers/media/dvb/frontends/dib8000.h | 32 +- drivers/media/dvb/frontends/dibx000_common.c | 15 +- drivers/media/dvb/frontends/dibx000_common.h | 71 +- 12 files changed, 2450 insertions(+), 365 deletions(-) create mode 100644 drivers/media/dvb/frontends/dib0090.c create mode 100644 drivers/media/dvb/frontends/dib0090.h (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 923fa157aa5..80a12635447 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -18,6 +18,7 @@ #include "xc5000.h" #include "s5h1411.h" #include "dib0070.h" +#include "dib0090.h" #include "lgdt3305.h" #include "mxl5007t.h" @@ -605,17 +606,17 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event, } break; default: - if (actlen != sizeof(buf)) { - /* We didn't get back the 6 byte message we expected */ - err("Unexpected RC response size [%d]", actlen); - return -1; - } + if (actlen != sizeof(buf)) { + /* We didn't get back the 6 byte message we expected */ + err("Unexpected RC response size [%d]", actlen); + return -1; + } - poll_reply.report_id = buf[0]; - poll_reply.data_state = buf[1]; + poll_reply.report_id = buf[0]; + poll_reply.data_state = buf[1]; poll_reply.system = (buf[2] << 8) | buf[3]; - poll_reply.data = buf[4]; - poll_reply.not_data = buf[5]; + poll_reply.data = buf[4]; + poll_reply.not_data = buf[5]; break; } @@ -632,7 +633,7 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event, /* Find the key in the map */ for (i = 0; i < d->props.rc_key_map_size; i++) { if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) && - rc5_data(&keymap[i]) == poll_reply.data) { + rc5_data(&keymap[i]) == poll_reply.data) { *event = keymap[i].event; found = 1; break; @@ -641,8 +642,8 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event, if (found == 0) { err("Unknown remote controller key: %04x %02x %02x", - poll_reply.system, - poll_reply.data, poll_reply.not_data); + poll_reply.system, + poll_reply.data, poll_reply.not_data); d->last_event = 0; return 0; } @@ -1476,12 +1477,12 @@ static struct dib8000_config dib807x_dib8000_config[2] = { } }; -static int dib807x_tuner_reset(struct dvb_frontend *fe, int onoff) +static int dib80xx_tuner_reset(struct dvb_frontend *fe, int onoff) { return dib8000_set_gpio(fe, 5, 0, !onoff); } -static int dib807x_tuner_sleep(struct dvb_frontend *fe, int onoff) +static int dib80xx_tuner_sleep(struct dvb_frontend *fe, int onoff) { return dib8000_set_gpio(fe, 0, 0, onoff); } @@ -1494,8 +1495,8 @@ static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = { static struct dib0070_config dib807x_dib0070_config[2] = { { .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS, - .reset = dib807x_tuner_reset, - .sleep = dib807x_tuner_sleep, + .reset = dib80xx_tuner_reset, + .sleep = dib80xx_tuner_sleep, .clock_khz = 12000, .clock_pad_drive = 4, .vga_filter = 1, @@ -1508,8 +1509,8 @@ static struct dib0070_config dib807x_dib0070_config[2] = { .freq_offset_khz_vhf = -100, }, { .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS, - .reset = dib807x_tuner_reset, - .sleep = dib807x_tuner_sleep, + .reset = dib80xx_tuner_reset, + .sleep = dib80xx_tuner_sleep, .clock_khz = 12000, .clock_pad_drive = 2, .vga_filter = 1, @@ -1566,12 +1567,12 @@ static int dib807x_tuner_attach(struct dvb_usb_adapter *adap) return 0; } -static int stk807x_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) +static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) { return dib8000_pid_filter(adapter->fe, index, pid, onoff); } -static int stk807x_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) +static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) { return dib8000_pid_filter_ctrl(adapter->fe, onoff); } @@ -1643,6 +1644,246 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) return adap->fe == NULL ? -ENODEV : 0; } +/* STK8096GP */ +struct dibx000_agc_config dib8090_agc_config[2] = { + { + BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, + /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, + * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ + (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup + + 787,// inv_gain = 1/ 90.4dB // no boost, lower gain due to ramp quantification + 10, // time_stabiliz + + 0, // alpha_level + 118, // thlock + + 0, // wbd_inv + 3530, // wbd_ref + 1, // wbd_sel + 5, // wbd_alpha + + 65535, // agc1_max + 0, // agc1_min + + 65535, // agc2_max + 0, // agc2_min + + 0, // agc1_pt1 + 32, // agc1_pt2 + 114, // agc1_pt3 // 40.4dB + 143, // agc1_slope1 + 144, // agc1_slope2 + 114, // agc2_pt1 + 227, // agc2_pt2 + 116, // agc2_slope1 + 117, // agc2_slope2 + + 28, // alpha_mant // 5Hz with 90.2dB + 26, // alpha_exp + 31, // beta_mant + 51, // beta_exp + + 0, // perform_agc_softsplit + }, + { + BAND_CBAND, + /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, + * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ + (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup + + 787,// inv_gain = 1/ 90.4dB // no boost, lower gain due to ramp quantification + 10, // time_stabiliz + + 0, // alpha_level + 118, // thlock + + 0, // wbd_inv + 3530, // wbd_ref + 1, // wbd_sel + 5, // wbd_alpha + + 0, // agc1_max + 0, // agc1_min + + 65535, // agc2_max + 0, // agc2_min + + 0, // agc1_pt1 + 32, // agc1_pt2 + 114, // agc1_pt3 // 40.4dB + 143, // agc1_slope1 + 144, // agc1_slope2 + 114, // agc2_pt1 + 227, // agc2_pt2 + 116, // agc2_slope1 + 117, // agc2_slope2 + + 28, // alpha_mant // 5Hz with 90.2dB + 26, // alpha_exp + 31, // beta_mant + 51, // beta_exp + + 0, // perform_agc_softsplit + } +}; + +static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = { + 54000, 13500, // internal, sampling + 1, 18, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass + 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo + (3 << 14) | (1 << 12) | (599 << 0), // sad_cfg: refsel, sel, freq_15k + (0 << 25) | 0, // ifreq = 0 MHz + 20199727, // timf + 12000000, // xtal_hz +}; + +static int dib8090_get_adc_power(struct dvb_frontend *fe) +{ + return dib8000_get_adc_power(fe, 1); +} + +static struct dib8000_config dib809x_dib8000_config = { + .output_mpeg2_in_188_bytes = 1, + + .agc_config_count = 2, + .agc = dib8090_agc_config, + .agc_control = dib0090_dcc_freq, + .pll = &dib8090_pll_config_12mhz, + .tuner_is_baseband = 1, + + .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB8000_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS, + + .hostbus_diversity = 1, + .div_cfg = 0x31, + .output_mode = OUTMODE_MPEG2_FIFO, + .drives = 0x2d98, + .diversity_delay = 144, + .refclksel = 3, +}; + +static struct dib0090_config dib809x_dib0090_config = { + .io.pll_bypass = 1, + .io.pll_range = 1, + .io.pll_prediv = 1, + .io.pll_loopdiv = 20, + .io.adc_clock_ratio = 8, + .io.pll_int_loop_filt = 0, + .io.clock_khz = 12000, + .reset = dib80xx_tuner_reset, + .sleep = dib80xx_tuner_sleep, + .clkouttobamse = 1, + .analog_output = 1, + .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS, + .wbd_vhf_offset = 100, + .wbd_cband_offset = 450, + .use_pwm_agc = 1, + .clkoutdrive = 1, + .get_adc_power = dib8090_get_adc_power, + .freq_offset_khz_uhf = 0, + .freq_offset_khz_vhf = -143, +}; + +static int dib8096_set_param_override(struct dvb_frontend *fe, + struct dvb_frontend_parameters *fep) +{ + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); + u16 offset; + int ret = 0; + enum frontend_tune_state tune_state = CT_SHUTDOWN; + u16 ltgain, rf_gain_limit; + + ret = state->set_param_save(fe, fep); + if (ret < 0) + return ret; + + switch (band) { + case BAND_VHF: + offset = 100; + break; + case BAND_UHF: + offset = 550; + break; + default: + offset = 0; + break; + } + offset += (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2; + dib8000_set_wbd_ref(fe, offset); + + + if (band == BAND_CBAND) + { + deb_info("tuning in CBAND - soft-AGC startup\n"); + /* TODO specific wbd target for dib0090 - needed for startup ? */ + dib0090_set_tune_state(fe, CT_AGC_START); + do + { + ret = dib0090_gain_control(fe); + msleep(ret); + tune_state = dib0090_get_tune_state(fe); + if (tune_state == CT_AGC_STEP_0) + dib8000_set_gpio(fe, 6, 0, 1); + else if (tune_state == CT_AGC_STEP_1) + { + dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, <gain); + if (rf_gain_limit == 0) + dib8000_set_gpio(fe, 6, 0, 0); + } + } + while(tune_statepriv; + struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); + + if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL) + return -ENODEV; + + st->set_param_save = adap->fe->ops.tuner_ops.set_params; + adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override; + return 0; +} + +static int stk809x_frontend_attach(struct dvb_usb_adapter *adap) +{ + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + + dib0700_ctrl_clock(adap->dev, 72, 1); + + msleep(10); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80); + + adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config); + + return adap->fe == NULL ? -ENODEV : 0; +} /* STK7070PD */ static struct dib7000p_config stk7070pd_dib7000p_config[2] = { @@ -1939,6 +2180,7 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) }, /* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) }, { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) }, + { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096GP) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -2473,8 +2715,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { { .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, - .pid_filter = stk807x_pid_filter, - .pid_filter_ctrl = stk807x_pid_filter_ctrl, + .pid_filter = stk80xx_pid_filter, + .pid_filter_ctrl = stk80xx_pid_filter_ctrl, .frontend_attach = stk807x_frontend_attach, .tuner_attach = dib807x_tuner_attach, @@ -2512,8 +2754,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { { .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, - .pid_filter = stk807x_pid_filter, - .pid_filter_ctrl = stk807x_pid_filter_ctrl, + .pid_filter = stk80xx_pid_filter, + .pid_filter_ctrl = stk80xx_pid_filter_ctrl, .frontend_attach = stk807xpvr_frontend_attach0, .tuner_attach = dib807x_tuner_attach, @@ -2525,8 +2767,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { { .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, - .pid_filter = stk807x_pid_filter, - .pid_filter_ctrl = stk807x_pid_filter_ctrl, + .pid_filter = stk80xx_pid_filter, + .pid_filter_ctrl = stk80xx_pid_filter_ctrl, .frontend_attach = stk807xpvr_frontend_attach1, .tuner_attach = dib807x_tuner_attach, @@ -2545,6 +2787,37 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = dib0700_rc_keys, + .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), + .rc_query = dib0700_rc_query + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + .num_adapters = 1, + .adapter = { + { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk80xx_pid_filter, + .pid_filter_ctrl = stk80xx_pid_filter_ctrl, + .frontend_attach = stk809x_frontend_attach, + .tuner_attach = dib809x_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + + .size_of_priv = + sizeof(struct dib0700_adapter_state), + }, + }, + + .num_device_descs = 1, + .devices = { + { "DiBcom STK8096GP reference design", + { &dib0700_usb_id_table[67], NULL }, + { NULL }, + }, + }, + .rc_interval = DEFAULT_RC_INTERVAL, .rc_key_map = dib0700_rc_keys, .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index cf7f2b4b75e..bc3581d58ce 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -102,6 +102,7 @@ #define USB_PID_DIBCOM_STK7070PD 0x1ebe #define USB_PID_DIBCOM_STK807XP 0x1f90 #define USB_PID_DIBCOM_STK807XPVR 0x1f98 +#define USB_PID_DIBCOM_STK8096GP 0x1fa0 #define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 #define USB_PID_DIBCOM_STK7770P 0x1e80 #define USB_PID_DPOSH_M9206_COLD 0x9206 diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 58aac018f10..a3b8b697349 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -526,6 +526,15 @@ config DVB_TUNER_DIB0070 This device is only used inside a SiP called together with a demodulator for now. +config DVB_TUNER_DIB0090 + tristate "DiBcom DiB0090 silicon base-band tuner" + depends on I2C + default m if DVB_FE_CUSTOMISE + help + A driver for the silicon baseband tuner DiB0090 from DiBcom. + This device is only used inside a SiP called together with a + demodulator for now. + comment "SEC control devices for DVB-S" depends on DVB_CORE diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 823482535d1..47575cc7b69 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_DVB_TDA10086) += tda10086.o obj-$(CONFIG_DVB_TDA826X) += tda826x.o obj-$(CONFIG_DVB_TDA8261) += tda8261.o obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o +obj-$(CONFIG_DVB_TUNER_DIB0090) += dib0090.o obj-$(CONFIG_DVB_TUA6100) += tua6100.o obj-$(CONFIG_DVB_S5H1409) += s5h1409.o obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c index 2be17b93e0b..81860b2cfe9 100644 --- a/drivers/media/dvb/frontends/dib0070.c +++ b/drivers/media/dvb/frontends/dib0070.c @@ -49,21 +49,6 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); #define DIB0070_P1G 0x03 #define DIB0070S_P1A 0x02 -enum frontend_tune_state { - CT_TUNER_START = 10, - CT_TUNER_STEP_0, - CT_TUNER_STEP_1, - CT_TUNER_STEP_2, - CT_TUNER_STEP_3, - CT_TUNER_STEP_4, - CT_TUNER_STEP_5, - CT_TUNER_STEP_6, - CT_TUNER_STEP_7, - CT_TUNER_STOP, -}; - -#define FE_CALLBACK_TIME_NEVER 0xffffffff - struct dib0070_state { struct i2c_adapter *i2c; struct dvb_frontend *fe; @@ -71,10 +56,10 @@ struct dib0070_state { u16 wbd_ff_offset; u8 revision; - enum frontend_tune_state tune_state; - u32 current_rf; + enum frontend_tune_state tune_state; + u32 current_rf; - /* for the captrim binary search */ + /* for the captrim binary search */ s8 step; u16 adc_diff; @@ -85,7 +70,7 @@ struct dib0070_state { const struct dib0070_tuning *current_tune_table_index; const struct dib0070_lna_match *lna_match; - u8 wbd_gain_current; + u8 wbd_gain_current; u16 wbd_offset_3_3[2]; }; @@ -93,8 +78,8 @@ static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg) { u8 b[2]; struct i2c_msg msg[2] = { - {.addr = state->cfg->i2c_address,.flags = 0,.buf = ®,.len = 1}, - {.addr = state->cfg->i2c_address,.flags = I2C_M_RD,.buf = b,.len = 2}, + { .addr = state->cfg->i2c_address, .flags = 0, .buf = ®, .len = 1 }, + { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2 }, }; if (i2c_transfer(state->i2c, msg, 2) != 2) { printk(KERN_WARNING "DiB0070 I2C read failed\n"); @@ -106,7 +91,7 @@ static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg) static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) { u8 b[3] = { reg, val >> 8, val & 0xff }; - struct i2c_msg msg = {.addr = state->cfg->i2c_address,.flags = 0,.buf = b,.len = 3 }; + struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 }; if (i2c_transfer(state->i2c, &msg, 1) != 1) { printk(KERN_WARNING "DiB0070 I2C write failed\n"); return -EREMOTEIO; @@ -124,30 +109,30 @@ static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) { - struct dib0070_state *state = fe->tuner_priv; - u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff; - - if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 7000) - tmp |= (0 << 14); - else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 6000) - tmp |= (1 << 14); - else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 5000) - tmp |= (2 << 14); - else - tmp |= (3 << 14); - - dib0070_write_reg(state, 0x02, tmp); - - /* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */ - if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) { - u16 value = dib0070_read_reg(state, 0x17); - - dib0070_write_reg(state, 0x17, value & 0xfffc); - tmp = dib0070_read_reg(state, 0x01) & 0x01ff; - dib0070_write_reg(state, 0x01, tmp | (60 << 9)); - - dib0070_write_reg(state, 0x17, value); - } + struct dib0070_state *state = fe->tuner_priv; + u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff; + + if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 7000) + tmp |= (0 << 14); + else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 6000) + tmp |= (1 << 14); + else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 5000) + tmp |= (2 << 14); + else + tmp |= (3 << 14); + + dib0070_write_reg(state, 0x02, tmp); + + /* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */ + if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) { + u16 value = dib0070_read_reg(state, 0x17); + + dib0070_write_reg(state, 0x17, value & 0xfffc); + tmp = dib0070_read_reg(state, 0x01) & 0x01ff; + dib0070_write_reg(state, 0x01, tmp | (60 << 9)); + + dib0070_write_reg(state, 0x17, value); + } return 0; } @@ -160,14 +145,14 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state if (*tune_state == CT_TUNER_STEP_0) { dib0070_write_reg(state, 0x0f, 0xed10); - dib0070_write_reg(state, 0x17, 0x0034); + dib0070_write_reg(state, 0x17, 0x0034); dib0070_write_reg(state, 0x18, 0x0032); state->step = state->captrim = state->fcaptrim = 64; state->adc_diff = 3000; ret = 20; - *tune_state = CT_TUNER_STEP_1; + *tune_state = CT_TUNER_STEP_1; } else if (*tune_state == CT_TUNER_STEP_1) { state->step /= 2; dib0070_write_reg(state, 0x14, state->lo4 | state->captrim); @@ -178,7 +163,7 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state adc = dib0070_read_reg(state, 0x19); - dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc * (u32) 1800 / (u32) 1024); + dprintk( "CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc*(u32)1800/(u32)1024); if (adc >= 400) { adc -= 400; @@ -189,10 +174,12 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state } if (adc < state->adc_diff) { - dprintk("CAPTRIM=%hd is closer to target (%hd/%hd)", state->captrim, adc, state->adc_diff); + dprintk( "CAPTRIM=%hd is closer to target (%hd/%hd)", state->captrim, adc, state->adc_diff); state->adc_diff = adc; state->fcaptrim = state->captrim; + + } state->captrim += (step_sign * state->step); @@ -213,8 +200,8 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt) { struct dib0070_state *state = fe->tuner_priv; - u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0); - dprintk("CTRL_LO5: 0x%x", lo5); + u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0); + dprintk( "CTRL_LO5: 0x%x", lo5); return dib0070_write_reg(state, 0x15, lo5); } @@ -227,171 +214,175 @@ void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open) dib0070_write_reg(state, 0x1a, 0x0000); } else { dib0070_write_reg(state, 0x1b, 0x4112); - if (state->cfg->vga_filter != 0) { - dib0070_write_reg(state, 0x1a, state->cfg->vga_filter); - dprintk("vga filter register is set to %x", state->cfg->vga_filter); - } else - dib0070_write_reg(state, 0x1a, 0x0009); + if (state->cfg->vga_filter != 0) { + dib0070_write_reg(state, 0x1a, state->cfg->vga_filter); + dprintk( "vga filter register is set to %x", state->cfg->vga_filter); + } else + dib0070_write_reg(state, 0x1a, 0x0009); } } EXPORT_SYMBOL(dib0070_ctrl_agc_filter); struct dib0070_tuning { - u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ - u8 switch_trim; - u8 vco_band; - u8 hfdiv; - u8 vco_multi; - u8 presc; - u8 wbdmux; - u16 tuner_enable; + u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ + u8 switch_trim; + u8 vco_band; + u8 hfdiv; + u8 vco_multi; + u8 presc; + u8 wbdmux; + u16 tuner_enable; }; struct dib0070_lna_match { - u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ - u8 lna_band; + u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ + u8 lna_band; }; static const struct dib0070_tuning dib0070s_tuning_table[] = { - {570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800}, /* UHF */ - {700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800}, - {863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800}, - {1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400}, /* LBAND */ - {1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400}, - {2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400}, - {0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000}, /* SBAND */ + { 570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800 }, /* UHF */ + { 700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800 }, + { 863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800 }, + { 1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND */ + { 1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, + { 2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, + { 0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000 }, /* SBAND */ }; static const struct dib0070_tuning dib0070_tuning_table[] = { - {115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000}, /* FM below 92MHz cannot be tuned */ - {179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000}, /* VHF */ - {189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000}, - {250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000}, - {569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800}, /* UHF */ - {699999, 2, 0, 1, 4, 2, 2, 0x4000 | 0x0800}, - {863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800}, - {0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400}, /* LBAND or everything higher than UHF */ + { 115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000 }, /* FM below 92MHz cannot be tuned */ + { 179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000 }, /* VHF */ + { 189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000 }, + { 250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000 }, + { 569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800 }, /* UHF */ + { 699999, 2, 0 ,1, 4, 2, 2, 0x4000 | 0x0800 }, + { 863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800 }, + { 0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND or everything higher than UHF */ }; static const struct dib0070_lna_match dib0070_lna_flip_chip[] = { - {180000, 0}, /* VHF */ - {188000, 1}, - {196400, 2}, - {250000, 3}, - {550000, 0}, /* UHF */ - {590000, 1}, - {666000, 3}, - {864000, 5}, - {1500000, 0}, /* LBAND or everything higher than UHF */ - {1600000, 1}, - {2000000, 3}, - {0xffffffff, 7}, + { 180000, 0 }, /* VHF */ + { 188000, 1 }, + { 196400, 2 }, + { 250000, 3 }, + { 550000, 0 }, /* UHF */ + { 590000, 1 }, + { 666000, 3 }, + { 864000, 5 }, + { 1500000, 0 }, /* LBAND or everything higher than UHF */ + { 1600000, 1 }, + { 2000000, 3 }, + { 0xffffffff, 7 }, }; static const struct dib0070_lna_match dib0070_lna[] = { - {180000, 0}, /* VHF */ - {188000, 1}, - {196400, 2}, - {250000, 3}, - {550000, 2}, /* UHF */ - {650000, 3}, - {750000, 5}, - {850000, 6}, - {864000, 7}, - {1500000, 0}, /* LBAND or everything higher than UHF */ - {1600000, 1}, - {2000000, 3}, - {0xffffffff, 7}, + { 180000, 0 }, /* VHF */ + { 188000, 1 }, + { 196400, 2 }, + { 250000, 3 }, + { 550000, 2 }, /* UHF */ + { 650000, 3 }, + { 750000, 5 }, + { 850000, 6 }, + { 864000, 7 }, + { 1500000, 0 }, /* LBAND or everything higher than UHF */ + { 1600000, 1 }, + { 2000000, 3 }, + { 0xffffffff, 7 }, }; -#define LPF 100 // define for the loop filter 100kHz by default 16-07-06 +#define LPF 100 // define for the loop filter 100kHz by default 16-07-06 static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) { - struct dib0070_state *state = fe->tuner_priv; + struct dib0070_state *state = fe->tuner_priv; - const struct dib0070_tuning *tune; - const struct dib0070_lna_match *lna_match; + const struct dib0070_tuning *tune; + const struct dib0070_lna_match *lna_match; - enum frontend_tune_state *tune_state = &state->tune_state; - int ret = 10; /* 1ms is the default delay most of the time */ + enum frontend_tune_state *tune_state = &state->tune_state; + int ret = 10; /* 1ms is the default delay most of the time */ - u8 band = (u8) BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000); - u32 freq = fe->dtv_property_cache.frequency / 1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf); + u8 band = (u8)BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency/1000); + u32 freq = fe->dtv_property_cache.frequency/1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf); #ifdef CONFIG_SYS_ISDBT - if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1) + if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1) if (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == (state->fe->dtv_property_cache.isdbt_sb_segment_count / 2))) || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))) - freq += 850; + freq += 850; #endif + if (state->current_rf != freq) { + + switch (state->revision) { + case DIB0070S_P1A: + tune = dib0070s_tuning_table; + lna_match = dib0070_lna; + break; + default: + tune = dib0070_tuning_table; + if (state->cfg->flip_chip) + lna_match = dib0070_lna_flip_chip; + else + lna_match = dib0070_lna; + break; + } + while (freq > tune->max_freq) /* find the right one */ + tune++; + while (freq > lna_match->max_freq) /* find the right one */ + lna_match++; + + state->current_tune_table_index = tune; + state->lna_match = lna_match; + } + + if (*tune_state == CT_TUNER_START) { + dprintk( "Tuning for Band: %hd (%d kHz)", band, freq); if (state->current_rf != freq) { + u8 REFDIV; + u32 FBDiv, Rest, FREF, VCOF_kHz; + u8 Den; - switch (state->revision) { - case DIB0070S_P1A: - tune = dib0070s_tuning_table; - lna_match = dib0070_lna; - break; - default: - tune = dib0070_tuning_table; - if (state->cfg->flip_chip) - lna_match = dib0070_lna_flip_chip; - else - lna_match = dib0070_lna; - break; - } - while (freq > tune->max_freq) /* find the right one */ - tune++; - while (freq > lna_match->max_freq) /* find the right one */ - lna_match++; + state->current_rf = freq; + state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7); - state->current_tune_table_index = tune; - state->lna_match = lna_match; - } - if (*tune_state == CT_TUNER_START) { - dprintk("Tuning for Band: %hd (%d kHz)", band, freq); - if (state->current_rf != freq) { - u8 REFDIV; - u32 FBDiv, Rest, FREF, VCOF_kHz; - u8 Den; - - state->current_rf = freq; - state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7); - - dib0070_write_reg(state, 0x17, 0x30); - - VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2; - - switch (band) { - case BAND_VHF: - REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000); - break; - case BAND_FM: - REFDIV = (u8) ((state->cfg->clock_khz) / 1000); - break; - default: - REFDIV = (u8) (state->cfg->clock_khz / 10000); - break; - } - FREF = state->cfg->clock_khz / REFDIV; - - switch (state->revision) { - case DIB0070S_P1A: - FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF); - Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF; - break; - - case DIB0070_P1G: - case DIB0070_P1F: - default: - FBDiv = (freq / (FREF / 2)); - Rest = 2 * freq - FBDiv * FREF; - break; - } + dib0070_write_reg(state, 0x17, 0x30); + + + VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2; + + switch (band) { + case BAND_VHF: + REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000); + break; + case BAND_FM: + REFDIV = (u8) ((state->cfg->clock_khz) / 1000); + break; + default: + REFDIV = (u8) ( state->cfg->clock_khz / 10000); + break; + } + FREF = state->cfg->clock_khz / REFDIV; + + + + switch (state->revision) { + case DIB0070S_P1A: + FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF); + Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF; + break; + + case DIB0070_P1G: + case DIB0070_P1F: + default: + FBDiv = (freq / (FREF / 2)); + Rest = 2 * freq - FBDiv * FREF; + break; + } if (Rest < LPF) Rest = 0; @@ -402,98 +393,102 @@ static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_par FBDiv += 1; } else if (Rest > (FREF - 2 * LPF)) Rest = FREF - 2 * LPF; - Rest = (Rest * 6528) / (FREF / 10); + Rest = (Rest * 6528) / (FREF / 10); - Den = 1; - if (Rest > 0) { - state->lo4 |= (1 << 14) | (1 << 12); - Den = 255; - } + Den = 1; + if (Rest > 0) { + state->lo4 |= (1 << 14) | (1 << 12); + Den = 255; + } - dib0070_write_reg(state, 0x11, (u16) FBDiv); - dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV); - dib0070_write_reg(state, 0x13, (u16) Rest); - if (state->revision == DIB0070S_P1A) { + dib0070_write_reg(state, 0x11, (u16)FBDiv); + dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV); + dib0070_write_reg(state, 0x13, (u16) Rest); - if (band == BAND_SBAND) { - dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0); - dib0070_write_reg(state, 0x1d, 0xFFFF); - } else - dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1); - } + if (state->revision == DIB0070S_P1A) { + + if (band == BAND_SBAND) { + dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0); + dib0070_write_reg(state, 0x1d,0xFFFF); + } else + dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1); + } dib0070_write_reg(state, 0x20, 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable); - dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF); - dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest); - dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1); - dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv); - dprintk("VCO = %hd", state->current_tune_table_index->vco_band); - dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq); - - *tune_state = CT_TUNER_STEP_0; - } else { /* we are already tuned to this frequency - the configuration is correct */ - ret = 50; /* wakeup time */ - *tune_state = CT_TUNER_STEP_5; - } - } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) { + dprintk( "REFDIV: %hd, FREF: %d", REFDIV, FREF); + dprintk( "FBDIV: %d, Rest: %d", FBDiv, Rest); + dprintk( "Num: %hd, Den: %hd, SD: %hd",(u16) Rest, Den, (state->lo4 >> 12) & 0x1); + dprintk( "HFDIV code: %hd", state->current_tune_table_index->hfdiv); + dprintk( "VCO = %hd", state->current_tune_table_index->vco_band); + dprintk( "VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq); + + *tune_state = CT_TUNER_STEP_0; + } else { /* we are already tuned to this frequency - the configuration is correct */ + ret = 50; /* wakeup time */ + *tune_state = CT_TUNER_STEP_5; + } + } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) { - ret = dib0070_captrim(state, tune_state); + ret = dib0070_captrim(state, tune_state); - } else if (*tune_state == CT_TUNER_STEP_4) { - const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain; - if (tmp != NULL) { - while (freq / 1000 > tmp->freq) /* find the right one */ - tmp++; + } else if (*tune_state == CT_TUNER_STEP_4) { + const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain; + if (tmp != NULL) { + while (freq/1000 > tmp->freq) /* find the right one */ + tmp++; dib0070_write_reg(state, 0x0f, (0 << 15) | (1 << 14) | (3 << 12) | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7) | (state-> current_tune_table_index-> wbdmux << 0)); - state->wbd_gain_current = tmp->wbd_gain_val; - } else { + state->wbd_gain_current = tmp->wbd_gain_val; + } else { dib0070_write_reg(state, 0x0f, (0 << 15) | (1 << 14) | (3 << 12) | (6 << 9) | (0 << 8) | (1 << 7) | (state->current_tune_table_index-> wbdmux << 0)); - state->wbd_gain_current = 6; - } + state->wbd_gain_current = 6; + } - dib0070_write_reg(state, 0x06, 0x3fff); + dib0070_write_reg(state, 0x06, 0x3fff); dib0070_write_reg(state, 0x07, (state->current_tune_table_index->switch_trim << 11) | (7 << 8) | (state->lna_match->lna_band << 3) | (3 << 0)); - dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127)); - dib0070_write_reg(state, 0x0d, 0x0d80); + dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127)); + dib0070_write_reg(state, 0x0d, 0x0d80); - dib0070_write_reg(state, 0x18, 0x07ff); - dib0070_write_reg(state, 0x17, 0x0033); - *tune_state = CT_TUNER_STEP_5; - } else if (*tune_state == CT_TUNER_STEP_5) { - dib0070_set_bandwidth(fe, ch); - *tune_state = CT_TUNER_STOP; - } else { - ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */ - } - return ret; + dib0070_write_reg(state, 0x18, 0x07ff); + dib0070_write_reg(state, 0x17, 0x0033); + + + *tune_state = CT_TUNER_STEP_5; + } else if (*tune_state == CT_TUNER_STEP_5) { + dib0070_set_bandwidth(fe, ch); + *tune_state = CT_TUNER_STOP; + } else { + ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */ + } + return ret; } + static int dib0070_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) { - struct dib0070_state *state = fe->tuner_priv; - uint32_t ret; + struct dib0070_state *state = fe->tuner_priv; + uint32_t ret; - state->tune_state = CT_TUNER_START; + state->tune_state = CT_TUNER_START; - do { - ret = dib0070_tune_digital(fe, p); - if (ret != FE_CALLBACK_TIME_NEVER) - msleep(ret / 10); - else - break; - } while (state->tune_state != CT_TUNER_STOP); + do { + ret = dib0070_tune_digital(fe, p); + if (ret != FE_CALLBACK_TIME_NEVER) + msleep(ret/10); + else + break; + } while (state->tune_state != CT_TUNER_STOP); - return 0; + return 0; } static int dib0070_wakeup(struct dvb_frontend *fe) @@ -512,92 +507,111 @@ static int dib0070_sleep(struct dvb_frontend *fe) return 0; } -static const u16 dib0070_p1f_defaults[] = { +u8 dib0070_get_rf_output(struct dvb_frontend *fe) +{ + struct dib0070_state *state = fe->tuner_priv; + return (dib0070_read_reg(state, 0x07) >> 11) & 0x3; +} + +EXPORT_SYMBOL(dib0070_get_rf_output); +int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no) +{ + struct dib0070_state *state = fe->tuner_priv; + u16 rxrf2 = dib0070_read_reg(state, 0x07) & 0xfe7ff; + if (no > 3) no = 3; + if (no < 1) no = 1; + return dib0070_write_reg(state, 0x07, rxrf2 | (no << 11)); +} + +EXPORT_SYMBOL(dib0070_set_rf_output); +static const u16 dib0070_p1f_defaults[] = + +{ 7, 0x02, - 0x0008, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0002, - 0x0100, + 0x0008, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0002, + 0x0100, 3, 0x0d, - 0x0d80, - 0x0001, - 0x0000, + 0x0d80, + 0x0001, + 0x0000, 4, 0x11, - 0x0000, - 0x0103, - 0x0000, - 0x0000, + 0x0000, + 0x0103, + 0x0000, + 0x0000, 3, 0x16, - 0x0004 | 0x0040, - 0x0030, - 0x07ff, + 0x0004 | 0x0040, + 0x0030, + 0x07ff, 6, 0x1b, - 0x4112, - 0xff00, - 0xc07f, - 0x0000, - 0x0180, - 0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001, + 0x4112, + 0xff00, + 0xc07f, + 0x0000, + 0x0180, + 0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001, 0, }; static u16 dib0070_read_wbd_offset(struct dib0070_state *state, u8 gain) { - u16 tuner_en = dib0070_read_reg(state, 0x20); - u16 offset; - - dib0070_write_reg(state, 0x18, 0x07ff); - dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001); - dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0)); - msleep(9); - offset = dib0070_read_reg(state, 0x19); - dib0070_write_reg(state, 0x20, tuner_en); - return offset; + u16 tuner_en = dib0070_read_reg(state, 0x20); + u16 offset; + + dib0070_write_reg(state, 0x18, 0x07ff); + dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001); + dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0)); + msleep(9); + offset = dib0070_read_reg(state, 0x19); + dib0070_write_reg(state, 0x20, tuner_en); + return offset; } static void dib0070_wbd_offset_calibration(struct dib0070_state *state) { - u8 gain; - for (gain = 6; gain < 8; gain++) { - state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2); - dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain - 6]); - } + u8 gain; + for (gain = 6; gain < 8; gain++) { + state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2); + dprintk( "Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain-6]); + } } u16 dib0070_wbd_offset(struct dvb_frontend *fe) { - struct dib0070_state *state = fe->tuner_priv; - const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain; - u32 freq = fe->dtv_property_cache.frequency / 1000; - - if (tmp != NULL) { - while (freq / 1000 > tmp->freq) /* find the right one */ - tmp++; - state->wbd_gain_current = tmp->wbd_gain_val; + struct dib0070_state *state = fe->tuner_priv; + const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain; + u32 freq = fe->dtv_property_cache.frequency/1000; + + if (tmp != NULL) { + while (freq/1000 > tmp->freq) /* find the right one */ + tmp++; + state->wbd_gain_current = tmp->wbd_gain_val; } else - state->wbd_gain_current = 6; + state->wbd_gain_current = 6; - return state->wbd_offset_3_3[state->wbd_gain_current - 6]; + return state->wbd_offset_3_3[state->wbd_gain_current - 6]; } - EXPORT_SYMBOL(dib0070_wbd_offset); #define pgm_read_word(w) (*w) static int dib0070_reset(struct dvb_frontend *fe) { - struct dib0070_state *state = fe->tuner_priv; + struct dib0070_state *state = fe->tuner_priv; u16 l, r, *n; HARD_RESET(state); + #ifndef FORCE_SBAND_TUNER if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1) state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff; @@ -605,13 +619,13 @@ static int dib0070_reset(struct dvb_frontend *fe) #else #warning forcing SBAND #endif - state->revision = DIB0070S_P1A; + state->revision = DIB0070S_P1A; /* P1F or not */ - dprintk("Revision: %x", state->revision); + dprintk( "Revision: %x", state->revision); if (state->revision == DIB0070_P1D) { - dprintk("Error: this driver is not to be used meant for P1D or earlier"); + dprintk( "Error: this driver is not to be used meant for P1D or earlier"); return -EINVAL; } @@ -620,7 +634,7 @@ static int dib0070_reset(struct dvb_frontend *fe) while (l) { r = pgm_read_word(n++); do { - dib0070_write_reg(state, (u8) r, pgm_read_word(n++)); + dib0070_write_reg(state, (u8)r, pgm_read_word(n++)); r++; } while (--l); l = pgm_read_word(n++); @@ -633,6 +647,7 @@ static int dib0070_reset(struct dvb_frontend *fe) else r = 2; + r |= state->cfg->osc_buffer_state << 3; dib0070_write_reg(state, 0x10, r); @@ -643,16 +658,24 @@ static int dib0070_reset(struct dvb_frontend *fe) dib0070_write_reg(state, 0x02, r | (1 << 5)); } - if (state->revision == DIB0070S_P1A) - dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0); - else + if (state->revision == DIB0070S_P1A) + dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0); + else dib0070_set_ctrl_lo5(fe, 5, 4, state->cfg->charge_pump, state->cfg->enable_third_order_filter); dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8); - dib0070_wbd_offset_calibration(state); + dib0070_wbd_offset_calibration(state); - return 0; + return 0; +} + +static int dib0070_get_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct dib0070_state *state = fe->tuner_priv; + + *frequency = 1000 * state->current_rf; + return 0; } static int dib0070_release(struct dvb_frontend *fe) @@ -664,22 +687,22 @@ static int dib0070_release(struct dvb_frontend *fe) static const struct dvb_tuner_ops dib0070_ops = { .info = { - .name = "DiBcom DiB0070", - .frequency_min = 45000000, - .frequency_max = 860000000, - .frequency_step = 1000, - }, - .release = dib0070_release, - - .init = dib0070_wakeup, - .sleep = dib0070_sleep, - .set_params = dib0070_tune, - -// .get_frequency = dib0070_get_frequency, + .name = "DiBcom DiB0070", + .frequency_min = 45000000, + .frequency_max = 860000000, + .frequency_step = 1000, + }, + .release = dib0070_release, + + .init = dib0070_wakeup, + .sleep = dib0070_sleep, + .set_params = dib0070_tune, + + .get_frequency = dib0070_get_frequency, // .get_bandwidth = dib0070_get_bandwidth }; -struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg) +struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg) { struct dib0070_state *state = kzalloc(sizeof(struct dib0070_state), GFP_KERNEL); if (state == NULL) @@ -687,7 +710,7 @@ struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter state->cfg = cfg; state->i2c = i2c; - state->fe = fe; + state->fe = fe; fe->tuner_priv = state; if (dib0070_reset(fe) != 0) @@ -699,12 +722,11 @@ struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter fe->tuner_priv = state; return fe; - free_mem: +free_mem: kfree(state); fe->tuner_priv = NULL; return NULL; } - EXPORT_SYMBOL(dib0070_attach); MODULE_AUTHOR("Patrick Boettcher "); diff --git a/drivers/media/dvb/frontends/dib0070.h b/drivers/media/dvb/frontends/dib0070.h index eec9e52ffa7..45c31fae396 100644 --- a/drivers/media/dvb/frontends/dib0070.h +++ b/drivers/media/dvb/frontends/dib0070.h @@ -52,6 +52,8 @@ struct dib0070_config { extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg); extern u16 dib0070_wbd_offset(struct dvb_frontend *); extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open); +extern u8 dib0070_get_rf_output(struct dvb_frontend *fe); +extern int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no); #else static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg) { @@ -62,7 +64,7 @@ static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struc static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return -ENODEV; + return 0; } static inline void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open) diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c new file mode 100644 index 00000000000..e37d32dbd5c --- /dev/null +++ b/drivers/media/dvb/frontends/dib0090.c @@ -0,0 +1,1525 @@ +/* + * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner. + * + * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * This code is more or less generated from another driver, please + * excuse some codingstyle oddities. + * + */ + +#include +#include + +#include "dvb_frontend.h" + +#include "dib0090.h" +#include "dibx000_common.h" + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); + +#define dprintk(args...) do { \ + if (debug) { \ + printk(KERN_DEBUG "DiB0090: "); \ + printk(args); \ + printk("\n"); \ + } \ +} while (0) + +#define CONFIG_SYS_ISDBT +#define CONFIG_BAND_CBAND +#define CONFIG_BAND_VHF +#define CONFIG_BAND_UHF +#define CONFIG_DIB0090_USE_PWM_AGC + +#define EN_LNA0 0x8000 +#define EN_LNA1 0x4000 +#define EN_LNA2 0x2000 +#define EN_LNA3 0x1000 +#define EN_MIX0 0x0800 +#define EN_MIX1 0x0400 +#define EN_MIX2 0x0200 +#define EN_MIX3 0x0100 +#define EN_IQADC 0x0040 +#define EN_PLL 0x0020 +#define EN_TX 0x0010 +#define EN_BB 0x0008 +#define EN_LO 0x0004 +#define EN_BIAS 0x0001 + +#define EN_IQANA 0x0002 +#define EN_DIGCLK 0x0080 /* not in the 0x24 reg, only in 0x1b */ +#define EN_CRYSTAL 0x0002 + +#define EN_UHF 0x22E9 +#define EN_VHF 0x44E9 +#define EN_LBD 0x11E9 +#define EN_SBD 0x44E9 +#define EN_CAB 0x88E9 + +#define pgm_read_word(w) (*w) + +struct dc_calibration; + +struct dib0090_tuning { + u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ + u8 switch_trim; + u8 lna_tune; + u8 lna_bias; + u16 v2i; + u16 mix; + u16 load; + u16 tuner_enable; +}; + +struct dib0090_pll { + u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ + u8 vco_band; + u8 hfdiv_code; + u8 hfdiv; + u8 topresc; +}; + +struct dib0090_state { + struct i2c_adapter *i2c; + struct dvb_frontend *fe; + const struct dib0090_config *config; + + u8 current_band; + u16 revision; + enum frontend_tune_state tune_state; + u32 current_rf; + + u16 wbd_offset; + s16 wbd_target; /* in dB */ + + s16 rf_gain_limit; /* take-over-point: where to split between bb and rf gain */ + s16 current_gain; /* keeps the currently programmed gain */ + u8 agc_step; /* new binary search */ + + u16 gain[2]; /* for channel monitoring */ + + const u16 *rf_ramp; + const u16 *bb_ramp; + + /* for the software AGC ramps */ + u16 bb_1_def; + u16 rf_lt_def; + u16 gain_reg[4]; + + /* for the captrim/dc-offset search */ + s8 step; + s16 adc_diff; + s16 min_adc_diff; + + s8 captrim; + s8 fcaptrim; + + const struct dc_calibration *dc; + u16 bb6, bb7; + + const struct dib0090_tuning *current_tune_table_index; + const struct dib0090_pll *current_pll_table_index; + + u8 tuner_is_tuned; + u8 agc_freeze; + + u8 reset; +}; + +static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) +{ + u8 b[2]; + struct i2c_msg msg[2] = { + {.addr = state->config->i2c_address,.flags = 0,.buf = ®,.len = 1}, + {.addr = state->config->i2c_address,.flags = I2C_M_RD,.buf = b,.len = 2}, + }; + if (i2c_transfer(state->i2c, msg, 2) != 2) { + printk(KERN_WARNING "DiB0090 I2C read failed\n"); + return 0; + } + return (b[0] << 8) | b[1]; +} + +static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) +{ + u8 b[3] = { reg & 0xff, val >> 8, val & 0xff }; + struct i2c_msg msg = {.addr = state->config->i2c_address,.flags = 0,.buf = b,.len = 3 }; + if (i2c_transfer(state->i2c, &msg, 1) != 1) { + printk(KERN_WARNING "DiB0090 I2C write failed\n"); + return -EREMOTEIO; + } + return 0; +} + +#define HARD_RESET(state) do { if (cfg->reset) { if (cfg->sleep) cfg->sleep(fe, 0); msleep(10); cfg->reset(fe, 1); msleep(10); cfg->reset(fe, 0); msleep(10); } } while (0) +#define ADC_TARGET -220 +#define GAIN_ALPHA 5 +#define WBD_ALPHA 6 +#define LPF 100 +static void dib0090_write_regs(struct dib0090_state *state, u8 r, const u16 * b, u8 c) +{ + do { + dib0090_write_reg(state, r++, *b++); + } while (--c); +} + +static u16 dib0090_identify(struct dvb_frontend *fe) +{ + struct dib0090_state *state = fe->tuner_priv; + u16 v; + + v = dib0090_read_reg(state, 0x1a); + +#ifdef FIRMWARE_FIREFLY + /* pll is not locked locked */ + if (!(v & 0x800)) + dprintk("FE%d : Identification : pll is not yet locked", fe->id); +#endif + + /* without PLL lock info */ + v &= 0x3ff; + dprintk("P/V: %04x:", v); + + if ((v >> 8) & 0xf) + dprintk("FE%d : Product ID = 0x%x : KROSUS", fe->id, (v >> 8) & 0xf); + else + return 0xff; + + v &= 0xff; + if (((v >> 5) & 0x7) == 0x1) + dprintk("FE%d : MP001 : 9090/8096", fe->id); + else if (((v >> 5) & 0x7) == 0x4) + dprintk("FE%d : MP005 : Single Sband", fe->id); + else if (((v >> 5) & 0x7) == 0x6) + dprintk("FE%d : MP008 : diversity VHF-UHF-LBAND", fe->id); + else if (((v >> 5) & 0x7) == 0x7) + dprintk("FE%d : MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND", fe->id); + else + return 0xff; + + /* revision only */ + if ((v & 0x1f) == 0x3) + dprintk("FE%d : P1-D/E/F detected", fe->id); + else if ((v & 0x1f) == 0x1) + dprintk("FE%d : P1C detected", fe->id); + else if ((v & 0x1f) == 0x0) { +#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT + dprintk("FE%d : P1-A/B detected: using previous driver - support will be removed soon", fe->id); + dib0090_p1b_register(fe); +#else + dprintk("FE%d : P1-A/B detected: driver is deactivated - not available", fe->id); + return 0xff; +#endif + } + + return v; +} + +static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg) +{ + struct dib0090_state *state = fe->tuner_priv; + + HARD_RESET(state); + + dib0090_write_reg(state, 0x24, EN_PLL); + dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */ + + /* adcClkOutRatio=8->7, release reset */ + dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0); + if (cfg->clkoutdrive != 0) + dib0090_write_reg(state, 0x23, + (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 10) | (1 << 9) | (0 << 8) | (cfg->clkoutdrive << 5) | (cfg-> + clkouttobamse + << 4) | (0 + << + 2) + | (0)); + else + dib0090_write_reg(state, 0x23, + (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 10) | (1 << 9) | (0 << 8) | (7 << 5) | (cfg-> + clkouttobamse << 4) | (0 + << + 2) + | (0)); + + /* enable pll, de-activate reset, ratio: 2/1 = 60MHz */ + dib0090_write_reg(state, 0x21, + (cfg->io.pll_bypass << 15) | (1 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)); + +} + +static int dib0090_wakeup(struct dvb_frontend *fe) +{ + struct dib0090_state *state = fe->tuner_priv; + if (state->config->sleep) + state->config->sleep(fe, 0); + return 0; +} + +static int dib0090_sleep(struct dvb_frontend *fe) +{ + struct dib0090_state *state = fe->tuner_priv; + if (state->config->sleep) + state->config->sleep(fe, 1); + return 0; +} + +extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast) +{ + struct dib0090_state *state = fe->tuner_priv; + if (fast) + dib0090_write_reg(state, 0x04, 0); //1kHz + else + dib0090_write_reg(state, 0x04, 1); //almost frozen +} + +EXPORT_SYMBOL(dib0090_dcc_freq); +static const u16 rf_ramp_pwm_cband[] = { + 0, /* max RF gain in 10th of dB */ + 0, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */ + 0, /* ramp_max = maximum X used on the ramp */ + (0 << 10) | 0, /* 0x2c, LNA 1 = 0dB */ + (0 << 10) | 0, /* 0x2d, LNA 1 */ + (0 << 10) | 0, /* 0x2e, LNA 2 = 0dB */ + (0 << 10) | 0, /* 0x2f, LNA 2 */ + (0 << 10) | 0, /* 0x30, LNA 3 = 0dB */ + (0 << 10) | 0, /* 0x31, LNA 3 */ + (0 << 10) | 0, /* GAIN_4_1, LNA 4 = 0dB */ + (0 << 10) | 0, /* GAIN_4_2, LNA 4 */ +}; + +static const u16 rf_ramp_vhf[] = { + 412, /* max RF gain in 10th of dB */ + 132, 307, 127, /* LNA1, 13.2dB */ + 105, 412, 255, /* LNA2, 10.5dB */ + 50, 50, 127, /* LNA3, 5dB */ + 125, 175, 127, /* LNA4, 12.5dB */ + 0, 0, 127, /* CBAND, 0dB */ +}; + +static const u16 rf_ramp_uhf[] = { + 412, /* max RF gain in 10th of dB */ + 132, 307, 127, /* LNA1 : total gain = 13.2dB, point on the ramp where this amp is full gain, value to write to get full gain */ + 105, 412, 255, /* LNA2 : 10.5 dB */ + 50, 50, 127, /* LNA3 : 5.0 dB */ + 125, 175, 127, /* LNA4 : 12.5 dB */ + 0, 0, 127, /* CBAND : 0.0 dB */ +}; + +static const u16 rf_ramp_cband[] = { + 332, /* max RF gain in 10th of dB */ + 132, 252, 127, /* LNA1, dB */ + 80, 332, 255, /* LNA2, dB */ + 0, 0, 127, /* LNA3, dB */ + 0, 0, 127, /* LNA4, dB */ + 120, 120, 127, /* LT1 CBAND */ +}; + +static const u16 rf_ramp_pwm_vhf[] = { + 404, /* max RF gain in 10th of dB */ + 25, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */ + 1011, /* ramp_max = maximum X used on the ramp */ + (6 << 10) | 417, /* 0x2c, LNA 1 = 13.2dB */ + (0 << 10) | 756, /* 0x2d, LNA 1 */ + (16 << 10) | 756, /* 0x2e, LNA 2 = 10.5dB */ + (0 << 10) | 1011, /* 0x2f, LNA 2 */ + (16 << 10) | 290, /* 0x30, LNA 3 = 5dB */ + (0 << 10) | 417, /* 0x31, LNA 3 */ + (7 << 10) | 0, /* GAIN_4_1, LNA 4 = 12.5dB */ + (0 << 10) | 290, /* GAIN_4_2, LNA 4 */ +}; + +static const u16 rf_ramp_pwm_uhf[] = { + 404, /* max RF gain in 10th of dB */ + 25, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */ + 1011, /* ramp_max = maximum X used on the ramp */ + (6 << 10) | 417, /* 0x2c, LNA 1 = 13.2dB */ + (0 << 10) | 756, /* 0x2d, LNA 1 */ + (16 << 10) | 756, /* 0x2e, LNA 2 = 10.5dB */ + (0 << 10) | 1011, /* 0x2f, LNA 2 */ + (16 << 10) | 0, /* 0x30, LNA 3 = 5dB */ + (0 << 10) | 127, /* 0x31, LNA 3 */ + (7 << 10) | 127, /* GAIN_4_1, LNA 4 = 12.5dB */ + (0 << 10) | 417, /* GAIN_4_2, LNA 4 */ +}; + +static const u16 bb_ramp_boost[] = { + 550, /* max BB gain in 10th of dB */ + 260, 260, 26, /* BB1, 26dB */ + 290, 550, 29, /* BB2, 29dB */ +}; + +static const u16 bb_ramp_pwm_normal[] = { + 500, /* max RF gain in 10th of dB */ + 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x34 */ + 400, + (2 << 9) | 0, /* 0x35 = 21dB */ + (0 << 9) | 168, /* 0x36 */ + (2 << 9) | 168, /* 0x37 = 29dB */ + (0 << 9) | 400, /* 0x38 */ +}; + +struct slope { + int16_t range; + int16_t slope; +}; +static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val) +{ + u8 i; + u16 rest; + u16 ret = 0; + for (i = 0; i < num; i++) { + if (val > slopes[i].range) + rest = slopes[i].range; + else + rest = val; + ret += (rest * slopes[i].slope) / slopes[i].range; + val -= rest; + } + return ret; +} + +static const struct slope dib0090_wbd_slopes[3] = { + {66, 120}, /* -64,-52: offset - 65 */ + {600, 170}, /* -52,-35: 65 - 665 */ + {170, 250}, /* -45,-10: 665 - 835 */ +}; + +static s16 dib0090_wbd_to_db(struct dib0090_state *state, u16 wbd) +{ + wbd &= 0x3ff; + if (wbd < state->wbd_offset) + wbd = 0; + else + wbd -= state->wbd_offset; + /* -64dB is the floor */ + return -640 + (s16) slopes_to_scale(dib0090_wbd_slopes, ARRAY_SIZE(dib0090_wbd_slopes), wbd); +} + +static void dib0090_wbd_target(struct dib0090_state *state, u32 rf) +{ + u16 offset = 250; + + /* TODO : DAB digital N+/-1 interferer perfs : offset = 10 */ + + if (state->current_band == BAND_VHF) + offset = 650; +#ifndef FIRMWARE_FIREFLY + if (state->current_band == BAND_VHF) + offset = state->config->wbd_vhf_offset; + if (state->current_band == BAND_CBAND) + offset = state->config->wbd_cband_offset; +#endif + + state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + offset); + dprintk("wbd-target: %d dB", (u32) state->wbd_target); +} + +static const int gain_reg_addr[4] = { + 0x08, 0x0a, 0x0f, 0x01 +}; + +static void dib0090_gain_apply(struct dib0090_state *state, s16 gain_delta, s16 top_delta, u8 force) +{ + u16 rf, bb, ref; + u16 i, v, gain_reg[4] = { 0 }, gain; + const u16 *g; + + if (top_delta < -511) + top_delta = -511; + if (top_delta > 511) + top_delta = 511; + + if (force) { + top_delta *= (1 << WBD_ALPHA); + gain_delta *= (1 << GAIN_ALPHA); + } + + if (top_delta >= ((s16) (state->rf_ramp[0] << WBD_ALPHA) - state->rf_gain_limit)) /* overflow */ + state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA; + else + state->rf_gain_limit += top_delta; + + if (state->rf_gain_limit < 0) /*underflow */ + state->rf_gain_limit = 0; + + /* use gain as a temporary variable and correct current_gain */ + gain = ((state->rf_gain_limit >> WBD_ALPHA) + state->bb_ramp[0]) << GAIN_ALPHA; + if (gain_delta >= ((s16) gain - state->current_gain)) /* overflow */ + state->current_gain = gain; + else + state->current_gain += gain_delta; + /* cannot be less than 0 (only if gain_delta is less than 0 we can have current_gain < 0) */ + if (state->current_gain < 0) + state->current_gain = 0; + + /* now split total gain to rf and bb gain */ + gain = state->current_gain >> GAIN_ALPHA; + + /* requested gain is bigger than rf gain limit - ACI/WBD adjustment */ + if (gain > (state->rf_gain_limit >> WBD_ALPHA)) { + rf = state->rf_gain_limit >> WBD_ALPHA; + bb = gain - rf; + if (bb > state->bb_ramp[0]) + bb = state->bb_ramp[0]; + } else { /* high signal level -> all gains put on RF */ + rf = gain; + bb = 0; + } + + state->gain[0] = rf; + state->gain[1] = bb; + + /* software ramp */ + /* Start with RF gains */ + g = state->rf_ramp + 1; /* point on RF LNA1 max gain */ + ref = rf; + for (i = 0; i < 7; i++) { /* Go over all amplifiers => 5RF amps + 2 BB amps = 7 amps */ + if (g[0] == 0 || ref < (g[1] - g[0])) /* if total gain of the current amp is null or this amp is not concerned because it starts to work from an higher gain value */ + v = 0; /* force the gain to write for the current amp to be null */ + else if (ref >= g[1]) /* Gain to set is higher than the high working point of this amp */ + v = g[2]; /* force this amp to be full gain */ + else /* compute the value to set to this amp because we are somewhere in his range */ + v = ((ref - (g[1] - g[0])) * g[2]) / g[0]; + + if (i == 0) /* LNA 1 reg mapping */ + gain_reg[0] = v; + else if (i == 1) /* LNA 2 reg mapping */ + gain_reg[0] |= v << 7; + else if (i == 2) /* LNA 3 reg mapping */ + gain_reg[1] = v; + else if (i == 3) /* LNA 4 reg mapping */ + gain_reg[1] |= v << 7; + else if (i == 4) /* CBAND LNA reg mapping */ + gain_reg[2] = v | state->rf_lt_def; + else if (i == 5) /* BB gain 1 reg mapping */ + gain_reg[3] = v << 3; + else if (i == 6) /* BB gain 2 reg mapping */ + gain_reg[3] |= v << 8; + + g += 3; /* go to next gain bloc */ + + /* When RF is finished, start with BB */ + if (i == 4) { + g = state->bb_ramp + 1; /* point on BB gain 1 max gain */ + ref = bb; + } + } + gain_reg[3] |= state->bb_1_def; + gain_reg[3] |= ((bb % 10) * 100) / 125; + +#ifdef DEBUG_AGC + dprintk("GA CALC: DB: %3d(rf) + %3d(bb) = %3d gain_reg[0]=%04x gain_reg[1]=%04x gain_reg[2]=%04x gain_reg[0]=%04x", rf, bb, rf + bb, + gain_reg[0], gain_reg[1], gain_reg[2], gain_reg[3]); +#endif + + /* Write the amplifier regs */ + for (i = 0; i < 4; i++) { + v = gain_reg[i]; + if (force || state->gain_reg[i] != v) { + state->gain_reg[i] = v; + dib0090_write_reg(state, gain_reg_addr[i], v); + } + } +} + +static void dib0090_set_boost(struct dib0090_state *state, int onoff) +{ + state->bb_1_def &= 0xdfff; + state->bb_1_def |= onoff << 13; +} + +static void dib0090_set_rframp(struct dib0090_state *state, const u16 * cfg) +{ + state->rf_ramp = cfg; +} + +static void dib0090_set_rframp_pwm(struct dib0090_state *state, const u16 * cfg) +{ + state->rf_ramp = cfg; + + dib0090_write_reg(state, 0x2a, 0xffff); + + dprintk("total RF gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x2a)); + + dib0090_write_regs(state, 0x2c, cfg + 3, 6); + dib0090_write_regs(state, 0x3e, cfg + 9, 2); +} + +static void dib0090_set_bbramp(struct dib0090_state *state, const u16 * cfg) +{ + state->bb_ramp = cfg; + dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */ +} + +static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg) +{ + state->bb_ramp = cfg; + + dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */ + + dib0090_write_reg(state, 0x33, 0xffff); + dprintk("total BB gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x33)); + dib0090_write_regs(state, 0x35, cfg + 3, 4); +} + +void dib0090_pwm_gain_reset(struct dvb_frontend *fe) +{ + struct dib0090_state *state = fe->tuner_priv; + /* reset the AGC */ + + if (state->config->use_pwm_agc) { +#ifdef CONFIG_BAND_SBAND + if (state->current_band == BAND_SBAND) { + dib0090_set_rframp_pwm(state, rf_ramp_pwm_sband); + dib0090_set_bbramp_pwm(state, bb_ramp_pwm_boost); + } else +#endif +#ifdef CONFIG_BAND_CBAND + if (state->current_band == BAND_CBAND) { + dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband); + dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); + } else +#endif +#ifdef CONFIG_BAND_VHF + if (state->current_band == BAND_VHF) { + dib0090_set_rframp_pwm(state, rf_ramp_pwm_vhf); + dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); + } else +#endif + { + dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf); + dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); + } + + if (state->rf_ramp[0] != 0) + dib0090_write_reg(state, 0x32, (3 << 11)); + else + dib0090_write_reg(state, 0x32, (0 << 11)); + + dib0090_write_reg(state, 0x39, (1 << 10)); // 0 gain by default + } +} + +EXPORT_SYMBOL(dib0090_pwm_gain_reset); +int dib0090_gain_control(struct dvb_frontend *fe) +{ + struct dib0090_state *state = fe->tuner_priv; + enum frontend_tune_state *tune_state = &state->tune_state; + int ret = 10; + + u16 wbd_val = 0; + u8 apply_gain_immediatly = 1; + s16 wbd_error = 0, adc_error = 0; + + if (*tune_state == CT_AGC_START) { + state->agc_freeze = 0; + dib0090_write_reg(state, 0x04, 0x0); + +#ifdef CONFIG_BAND_SBAND + if (state->current_band == BAND_SBAND) { + dib0090_set_rframp(state, rf_ramp_sband); + dib0090_set_bbramp(state, bb_ramp_boost); + } else +#endif +#ifdef CONFIG_BAND_VHF + if (state->current_band == BAND_VHF) { + dib0090_set_rframp(state, rf_ramp_vhf); + dib0090_set_bbramp(state, bb_ramp_boost); + } else +#endif +#ifdef CONFIG_BAND_CBAND + if (state->current_band == BAND_CBAND) { + dib0090_set_rframp(state, rf_ramp_cband); + dib0090_set_bbramp(state, bb_ramp_boost); + } else +#endif + { + dib0090_set_rframp(state, rf_ramp_uhf); + dib0090_set_bbramp(state, bb_ramp_boost); + } + + dib0090_write_reg(state, 0x32, 0); + dib0090_write_reg(state, 0x39, 0); + + dib0090_wbd_target(state, state->current_rf); + + state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA; + state->current_gain = ((state->rf_ramp[0] + state->bb_ramp[0]) / 2) << GAIN_ALPHA; + + *tune_state = CT_AGC_STEP_0; + } else if (!state->agc_freeze) { + s16 wbd; + + int adc; + wbd_val = dib0090_read_reg(state, 0x1d); + + /* read and calc the wbd power */ + wbd = dib0090_wbd_to_db(state, wbd_val); + wbd_error = state->wbd_target - wbd; + + if (*tune_state == CT_AGC_STEP_0) { + if (wbd_error < 0 && state->rf_gain_limit > 0) { +#ifdef CONFIG_BAND_CBAND + /* in case of CBAND tune reduce first the lt_gain2 before adjusting the RF gain */ + u8 ltg2 = (state->rf_lt_def >> 10) & 0x7; + if (state->current_band == BAND_CBAND && ltg2) { + ltg2 >>= 1; + state->rf_lt_def &= ltg2 << 10; /* reduce in 3 steps from 7 to 0 */ + } +#endif + } else { + state->agc_step = 0; + *tune_state = CT_AGC_STEP_1; + } + } else { + /* calc the adc power */ + adc = state->config->get_adc_power(fe); + adc = (adc * ((s32) 355774) + (((s32) 1) << 20)) >> 21; /* included in [0:-700] */ + + adc_error = (s16) (((s32) ADC_TARGET) - adc); +#ifdef CONFIG_STANDARD_DAB + if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) + adc_error += 130; +#endif +#ifdef CONFIG_STANDARD_DVBT + if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT && + (state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16)) + adc_error += 60; +#endif +#ifdef CONFIG_SYS_ISDBT + if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count > + 0) + && + ((state->fe->dtv_property_cache.layer[0].modulation == + QAM_64) + || (state->fe->dtv_property_cache.layer[0]. + modulation == QAM_16))) + || + ((state->fe->dtv_property_cache.layer[1].segment_count > + 0) + && + ((state->fe->dtv_property_cache.layer[1].modulation == + QAM_64) + || (state->fe->dtv_property_cache.layer[1]. + modulation == QAM_16))) + || + ((state->fe->dtv_property_cache.layer[2].segment_count > + 0) + && + ((state->fe->dtv_property_cache.layer[2].modulation == + QAM_64) + || (state->fe->dtv_property_cache.layer[2]. + modulation == QAM_16))) + ) + ) + adc_error += 60; +#endif + + if (*tune_state == CT_AGC_STEP_1) { /* quickly go to the correct range of the ADC power */ + if (ABS(adc_error) < 50 || state->agc_step++ > 5) { + +#ifdef CONFIG_STANDARD_DAB + if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) { + dib0090_write_reg(state, 0x02, (1 << 15) | (15 << 11) | (31 << 6) | (63)); /* cap value = 63 : narrow BB filter : Fc = 1.8MHz */ + dib0090_write_reg(state, 0x04, 0x0); + } else +#endif + { + dib0090_write_reg(state, 0x02, (1 << 15) | (3 << 11) | (6 << 6) | (32)); + dib0090_write_reg(state, 0x04, 0x01); /*0 = 1KHz ; 1 = 150Hz ; 2 = 50Hz ; 3 = 50KHz ; 4 = servo fast */ + } + + *tune_state = CT_AGC_STOP; + } + } else { + /* everything higher than or equal to CT_AGC_STOP means tracking */ + ret = 100; /* 10ms interval */ + apply_gain_immediatly = 0; + } + } +#ifdef DEBUG_AGC + dprintk + ("FE: %d, tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm", + (u32) fe->id, (u32) * tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val, + (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA)); +#endif + } + + /* apply gain */ + if (!state->agc_freeze) + dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly); + return ret; +} + +EXPORT_SYMBOL(dib0090_gain_control); +void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt) +{ + struct dib0090_state *state = fe->tuner_priv; + if (rf) + *rf = state->gain[0]; + if (bb) + *bb = state->gain[1]; + if (rf_gain_limit) + *rf_gain_limit = state->rf_gain_limit; + if (rflt) + *rflt = (state->rf_lt_def >> 10) & 0x7; +} + +EXPORT_SYMBOL(dib0090_get_current_gain); +u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner) +{ + struct dib0090_state *st = tuner->tuner_priv; + return st->wbd_offset; +} + +EXPORT_SYMBOL(dib0090_get_wbd_offset); +static const u16 dib0090_defaults[] = { + + 25, 0x01, + 0x0000, + 0x99a0, + 0x6008, + 0x0000, + 0x8acb, + 0x0000, + 0x0405, + 0x0000, + 0x0000, + 0x0000, + 0xb802, + 0x0300, + 0x2d12, + 0xbac0, + 0x7c00, + 0xdbb9, + 0x0954, + 0x0743, + 0x8000, + 0x0001, + 0x0040, + 0x0100, + 0x0000, + 0xe910, + 0x149e, + + 1, 0x1c, + 0xff2d, + + 1, 0x39, + 0x0000, + + 1, 0x1b, + EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL, + 2, 0x1e, + 0x07FF, + 0x0007, + + 1, 0x24, + EN_UHF | EN_CRYSTAL, + + 2, 0x3c, + 0x3ff, + 0x111, + 0 +}; + +static int dib0090_reset(struct dvb_frontend *fe) +{ + struct dib0090_state *state = fe->tuner_priv; + u16 l, r, *n; + + dib0090_reset_digital(fe, state->config); + state->revision = dib0090_identify(fe); + + /* Revision definition */ + if (state->revision == 0xff) + return -EINVAL; +#ifdef EFUSE + else if ((state->revision & 0x1f) >= 3) /* Update the efuse : Only available for KROSUS > P1C */ + dib0090_set_EFUSE(state); +#endif + +#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT + if (!(state->revision & 0x1)) /* it is P1B - reset is already done */ + return 0; +#endif + + /* Upload the default values */ + n = (u16 *) dib0090_defaults; + l = pgm_read_word(n++); + while (l) { + r = pgm_read_word(n++); + do { + /* DEBUG_TUNER */ + /* dprintk("%d, %d, %d", l, r, pgm_read_word(n)); */ + dib0090_write_reg(state, r, pgm_read_word(n++)); + r++; + } while (--l); + l = pgm_read_word(n++); + } + + /* Congigure in function of the crystal */ + if (state->config->io.clock_khz >= 24000) + l = 1; + else + l = 2; + dib0090_write_reg(state, 0x14, l); + dprintk("Pll lock : %d", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1); + + state->reset = 3; /* enable iq-offset-calibration and wbd-calibration when tuning next time */ + + return 0; +} + +#define steps(u) (((u)>15)?((u)-16):(u)) +#define INTERN_WAIT 10 +static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_state *tune_state) +{ + int ret = INTERN_WAIT * 10; + + switch (*tune_state) { + case CT_TUNER_STEP_2: + /* Turns to positive */ + dib0090_write_reg(state, 0x1f, 0x7); + *tune_state = CT_TUNER_STEP_3; + break; + + case CT_TUNER_STEP_3: + state->adc_diff = dib0090_read_reg(state, 0x1d); + + /* Turns to negative */ + dib0090_write_reg(state, 0x1f, 0x4); + *tune_state = CT_TUNER_STEP_4; + break; + + case CT_TUNER_STEP_4: + state->adc_diff -= dib0090_read_reg(state, 0x1d); + *tune_state = CT_TUNER_STEP_5; + ret = 0; + break; + + default: + break; + } + + return ret; +} + +struct dc_calibration { + uint8_t addr; + uint8_t offset; + uint8_t pga:1; + uint16_t bb1; + uint8_t i:1; +}; + +static const struct dc_calibration dc_table[] = { + /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */ + {0x06, 5, 1, (1 << 13) | (0 << 8) | (26 << 3), 1}, + {0x07, 11, 1, (1 << 13) | (0 << 8) | (26 << 3), 0}, + /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */ + {0x06, 0, 0, (1 << 13) | (29 << 8) | (26 << 3), 1}, + {0x06, 10, 0, (1 << 13) | (29 << 8) | (26 << 3), 0}, + {0}, +}; + +static void dib0090_set_trim(struct dib0090_state *state) +{ + u16 *val; + + if (state->dc->addr == 0x07) + val = &state->bb7; + else + val = &state->bb6; + + *val &= ~(0x1f << state->dc->offset); + *val |= state->step << state->dc->offset; + + dib0090_write_reg(state, state->dc->addr, *val); +} + +static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state) +{ + int ret = 0; + + switch (*tune_state) { + + case CT_TUNER_START: + /* init */ + dprintk("Internal DC calibration"); + + /* the LNA is off */ + dib0090_write_reg(state, 0x24, 0x02ed); + + /* force vcm2 = 0.8V */ + state->bb6 = 0; + state->bb7 = 0x040d; + + state->dc = dc_table; + + *tune_state = CT_TUNER_STEP_0; + + /* fall through */ + + case CT_TUNER_STEP_0: + dib0090_write_reg(state, 0x01, state->dc->bb1); + dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7)); + + state->step = 0; + + state->min_adc_diff = 1023; + + *tune_state = CT_TUNER_STEP_1; + ret = 50; + break; + + case CT_TUNER_STEP_1: + dib0090_set_trim(state); + + *tune_state = CT_TUNER_STEP_2; + break; + + case CT_TUNER_STEP_2: + case CT_TUNER_STEP_3: + case CT_TUNER_STEP_4: + ret = dib0090_get_offset(state, tune_state); + break; + + case CT_TUNER_STEP_5: /* found an offset */ + dprintk("FE%d: IQC read=%d, current=%x", state->fe->id, (u32) state->adc_diff, state->step); + + /* first turn for this frequency */ + if (state->step == 0) { + if (state->dc->pga && state->adc_diff < 0) + state->step = 0x10; + if (state->dc->pga == 0 && state->adc_diff > 0) + state->step = 0x10; + } + + state->adc_diff = ABS(state->adc_diff); + + if (state->adc_diff < state->min_adc_diff && steps(state->step) < 15) { /* stop search when the delta to 0 is increasing */ + state->step++; + state->min_adc_diff = state->adc_diff; + *tune_state = CT_TUNER_STEP_1; + } else { + + /* the minimum was what we have seen in the step before */ + state->step--; + dib0090_set_trim(state); + + dprintk("FE%d: BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd", state->fe->id, state->dc->addr, state->adc_diff, + state->step); + + state->dc++; + if (state->dc->addr == 0) /* done */ + *tune_state = CT_TUNER_STEP_6; + else + *tune_state = CT_TUNER_STEP_0; + + } + break; + + case CT_TUNER_STEP_6: + dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008); + dib0090_write_reg(state, 0x1f, 0x7); + *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */ + state->reset &= ~0x1; + default: + break; + } + return ret; +} + +static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state) +{ + switch (*tune_state) { + case CT_TUNER_START: + /* WBD-mode=log, Bias=2, Gain=6, Testmode=1, en=1, WBDMUX=1 */ + dib0090_write_reg(state, 0x10, 0xdb09 | (1 << 10)); + dib0090_write_reg(state, 0x24, EN_UHF & 0x0fff); + + *tune_state = CT_TUNER_STEP_0; + return 90; /* wait for the WBDMUX to switch and for the ADC to sample */ + case CT_TUNER_STEP_0: + state->wbd_offset = dib0090_read_reg(state, 0x1d); + dprintk("WBD calibration offset = %d", state->wbd_offset); + + *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */ + state->reset &= ~0x2; + break; + default: + break; + } + return 0; +} + +static void dib0090_set_bandwidth(struct dib0090_state *state) +{ + u16 tmp; + + if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000) + tmp = (3 << 14); + else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000) + tmp = (2 << 14); + else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000) + tmp = (1 << 14); + else + tmp = (0 << 14); + + state->bb_1_def &= 0x3fff; + state->bb_1_def |= tmp; + + dib0090_write_reg(state, 0x01, state->bb_1_def); /* be sure that we have the right bb-filter */ +} + +static const struct dib0090_pll dib0090_pll_table[] = { +#ifdef CONFIG_BAND_CBAND + {56000, 0, 9, 48, 6}, + {70000, 1, 9, 48, 6}, + {87000, 0, 8, 32, 4}, + {105000, 1, 8, 32, 4}, + {115000, 0, 7, 24, 6}, + {140000, 1, 7, 24, 6}, + {170000, 0, 6, 16, 4}, +#endif +#ifdef CONFIG_BAND_VHF + {200000, 1, 6, 16, 4}, + {230000, 0, 5, 12, 6}, + {280000, 1, 5, 12, 6}, + {340000, 0, 4, 8, 4}, + {380000, 1, 4, 8, 4}, + {450000, 0, 3, 6, 6}, +#endif +#ifdef CONFIG_BAND_UHF + {580000, 1, 3, 6, 6}, + {700000, 0, 2, 4, 4}, + {860000, 1, 2, 4, 4}, +#endif +#ifdef CONFIG_BAND_LBAND + {1800000, 1, 0, 2, 4}, +#endif +#ifdef CONFIG_BAND_SBAND + {2900000, 0, 14, 1, 4}, +#endif +}; + +static const struct dib0090_tuning dib0090_tuning_table_fm_vhf_on_cband[] = { + +#ifdef CONFIG_BAND_CBAND + {184000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB}, + {227000, 4, 3, 15, 0x280, 0x2912, 0xb94e, EN_CAB}, + {380000, 4, 7, 15, 0x280, 0x2912, 0xb94e, EN_CAB}, +#endif +#ifdef CONFIG_BAND_UHF + {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, +#endif +#ifdef CONFIG_BAND_LBAND + {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, + {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, + {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, +#endif +#ifdef CONFIG_BAND_SBAND + {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD}, + {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD}, +#endif +}; + +static const struct dib0090_tuning dib0090_tuning_table[] = { + +#ifdef CONFIG_BAND_CBAND + {170000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB}, +#endif +#ifdef CONFIG_BAND_VHF + {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, + {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, + {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, +#endif +#ifdef CONFIG_BAND_UHF + {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, + {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, +#endif +#ifdef CONFIG_BAND_LBAND + {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, + {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, + {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, +#endif +#ifdef CONFIG_BAND_SBAND + {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD}, + {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD}, +#endif +}; + +#define WBD 0x781 /* 1 1 1 1 0000 0 0 1 */ +static int dib0090_tune(struct dvb_frontend *fe) +{ + struct dib0090_state *state = fe->tuner_priv; + const struct dib0090_tuning *tune = state->current_tune_table_index; + const struct dib0090_pll *pll = state->current_pll_table_index; + enum frontend_tune_state *tune_state = &state->tune_state; + + u32 rf; + u16 lo4 = 0xe900, lo5, lo6, Den; + u32 FBDiv, Rest, FREF, VCOF_kHz = 0; + u16 tmp, adc; + int8_t step_sign; + int ret = 10; /* 1ms is the default delay most of the time */ + u8 c, i; + + state->current_band = (u8) BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000); + rf = fe->dtv_property_cache.frequency / 1000 + (state->current_band == + BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->freq_offset_khz_vhf); + /* in any case we first need to do a reset if needed */ + if (state->reset & 0x1) + return dib0090_dc_offset_calibration(state, tune_state); + else if (state->reset & 0x2) + return dib0090_wbd_calibration(state, tune_state); + + /************************* VCO ***************************/ + /* Default values for FG */ + /* from these are needed : */ + /* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv */ + +#ifdef CONFIG_SYS_ISDBT + if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1) + rf += 850; +#endif + + if (state->current_rf != rf) { + state->tuner_is_tuned = 0; + + tune = dib0090_tuning_table; + + tmp = (state->revision >> 5) & 0x7; + if (tmp == 0x4 || tmp == 0x7) { + /* CBAND tuner version for VHF */ + if (state->current_band == BAND_FM || state->current_band == BAND_VHF) { + /* Force CBAND */ + state->current_band = BAND_CBAND; + tune = dib0090_tuning_table_fm_vhf_on_cband; + } + } + + pll = dib0090_pll_table; + /* Look for the interval */ + while (rf > tune->max_freq) + tune++; + while (rf > pll->max_freq) + pll++; + state->current_tune_table_index = tune; + state->current_pll_table_index = pll; + } + + if (*tune_state == CT_TUNER_START) { + + if (state->tuner_is_tuned == 0) + state->current_rf = 0; + + if (state->current_rf != rf) { + + dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim)); + + /* external loop filter, otherwise: + * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4; + * lo6 = 0x0e34 */ + if (pll->vco_band) + lo5 = 0x049e; + else if (state->config->analog_output) + lo5 = 0x041d; + else + lo5 = 0x041c; + + lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7); /* bit 15 is the split to the slave, we do not do it here */ + + if (!state->config->io.pll_int_loop_filt) + lo6 = 0xff28; + else + lo6 = (state->config->io.pll_int_loop_filt << 3); + + VCOF_kHz = (pll->hfdiv * rf) * 2; + + FREF = state->config->io.clock_khz; + + FBDiv = (VCOF_kHz / pll->topresc / FREF); + Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF; + + if (Rest < LPF) + Rest = 0; + else if (Rest < 2 * LPF) + Rest = 2 * LPF; + else if (Rest > (FREF - LPF)) { + Rest = 0; + FBDiv += 1; + } else if (Rest > (FREF - 2 * LPF)) + Rest = FREF - 2 * LPF; + Rest = (Rest * 6528) / (FREF / 10); + + Den = 1; + + dprintk(" ***** ******* Rest value = %d", Rest); + + if (Rest > 0) { + if (state->config->analog_output) + lo6 |= (1 << 2) | 2; + else + lo6 |= (1 << 2) | 1; + Den = 255; + } +#ifdef CONFIG_BAND_SBAND + if (state->current_band == BAND_SBAND) + lo6 &= 0xfffb; +#endif + + dib0090_write_reg(state, 0x15, (u16) FBDiv); + + dib0090_write_reg(state, 0x16, (Den << 8) | 1); + + dib0090_write_reg(state, 0x17, (u16) Rest); + + dib0090_write_reg(state, 0x19, lo5); + + dib0090_write_reg(state, 0x1c, lo6); + + lo6 = tune->tuner_enable; + if (state->config->analog_output) + lo6 = (lo6 & 0xff9f) | 0x2; + + dib0090_write_reg(state, 0x24, lo6 | EN_LO +#ifdef CONFIG_DIB0090_USE_PWM_AGC + | state->config->use_pwm_agc * EN_CRYSTAL +#endif + ); + + state->current_rf = rf; + + /* prepare a complete captrim */ + state->step = state->captrim = state->fcaptrim = 64; + + } else { /* we are already tuned to this frequency - the configuration is correct */ + + /* do a minimal captrim even if the frequency has not changed */ + state->step = 4; + state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f; + } + state->adc_diff = 3000; + + dib0090_write_reg(state, 0x10, 0x2B1); + + dib0090_write_reg(state, 0x1e, 0x0032); + + ret = 20; + *tune_state = CT_TUNER_STEP_1; + } else if (*tune_state == CT_TUNER_STEP_0) { + /* nothing */ + } else if (*tune_state == CT_TUNER_STEP_1) { + state->step /= 2; + dib0090_write_reg(state, 0x18, lo4 | state->captrim); + *tune_state = CT_TUNER_STEP_2; + } else if (*tune_state == CT_TUNER_STEP_2) { + + adc = dib0090_read_reg(state, 0x1d); + dprintk("FE %d CAPTRIM=%d; ADC = %d (ADC) & %dmV", (u32) fe->id, (u32) state->captrim, (u32) adc, + (u32) (adc) * (u32) 1800 / (u32) 1024); + + if (adc >= 400) { + adc -= 400; + step_sign = -1; + } else { + adc = 400 - adc; + step_sign = 1; + } + + if (adc < state->adc_diff) { + dprintk("FE %d CAPTRIM=%d is closer to target (%d/%d)", (u32) fe->id, (u32) state->captrim, (u32) adc, (u32) state->adc_diff); + state->adc_diff = adc; + state->fcaptrim = state->captrim; + + } + + state->captrim += step_sign * state->step; + if (state->step >= 1) + *tune_state = CT_TUNER_STEP_1; + else + *tune_state = CT_TUNER_STEP_3; + + ret = 15; + } else if (*tune_state == CT_TUNER_STEP_3) { + /*write the final cptrim config */ + dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim); + +#ifdef CONFIG_TUNER_DIB0090_CAPTRIM_MEMORY + state->memory[state->memory_index].cap = state->fcaptrim; +#endif + + *tune_state = CT_TUNER_STEP_4; + } else if (*tune_state == CT_TUNER_STEP_4) { + dib0090_write_reg(state, 0x1e, 0x07ff); + + dprintk("FE %d Final Captrim: %d", (u32) fe->id, (u32) state->fcaptrim); + dprintk("FE %d HFDIV code: %d", (u32) fe->id, (u32) pll->hfdiv_code); + dprintk("FE %d VCO = %d", (u32) fe->id, (u32) pll->vco_band); + dprintk("FE %d VCOF in kHz: %d ((%d*%d) << 1))", (u32) fe->id, (u32) ((pll->hfdiv * rf) * 2), (u32) pll->hfdiv, (u32) rf); + dprintk("FE %d REFDIV: %d, FREF: %d", (u32) fe->id, (u32) 1, (u32) state->config->io.clock_khz); + dprintk("FE %d FBDIV: %d, Rest: %d", (u32) fe->id, (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17)); + dprintk("FE %d Num: %d, Den: %d, SD: %d", (u32) fe->id, (u32) dib0090_read_reg(state, 0x17), + (u32) (dib0090_read_reg(state, 0x16) >> 8), (u32) dib0090_read_reg(state, 0x1c) & 0x3); + + c = 4; + i = 3; +#if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND) + if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND)) { + c = 2; + i = 2; + } +#endif + dib0090_write_reg(state, 0x10, (c << 13) | (i << 11) | (WBD +#ifdef CONFIG_DIB0090_USE_PWM_AGC + | (state->config->use_pwm_agc << 1) +#endif + )); + dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | (tune->lna_bias << 0)); + dib0090_write_reg(state, 0x0c, tune->v2i); + dib0090_write_reg(state, 0x0d, tune->mix); + dib0090_write_reg(state, 0x0e, tune->load); + + *tune_state = CT_TUNER_STEP_5; + } else if (*tune_state == CT_TUNER_STEP_5) { + + /* initialize the lt gain register */ + state->rf_lt_def = 0x7c00; + dib0090_write_reg(state, 0x0f, state->rf_lt_def); + + dib0090_set_bandwidth(state); + state->tuner_is_tuned = 1; + *tune_state = CT_TUNER_STOP; + } else + ret = FE_CALLBACK_TIME_NEVER; + return ret; +} + +static int dib0090_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; + return 0; +} + +enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe) +{ + struct dib0090_state *state = fe->tuner_priv; + + return state->tune_state; +} + +EXPORT_SYMBOL(dib0090_get_tune_state); + +int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state) +{ + struct dib0090_state *state = fe->tuner_priv; + + state->tune_state = tune_state; + return 0; +} + +EXPORT_SYMBOL(dib0090_set_tune_state); + +static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency) +{ + struct dib0090_state *state = fe->tuner_priv; + + *frequency = 1000 * state->current_rf; + return 0; +} + +static int dib0090_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) +{ + struct dib0090_state *state = fe->tuner_priv; + uint32_t ret; + + state->tune_state = CT_TUNER_START; + + do { + ret = dib0090_tune(fe); + if (ret != FE_CALLBACK_TIME_NEVER) + msleep(ret / 10); + else + break; + } while (state->tune_state != CT_TUNER_STOP); + + return 0; +} + +static const struct dvb_tuner_ops dib0090_ops = { + .info = { + .name = "DiBcom DiB0090", + .frequency_min = 45000000, + .frequency_max = 860000000, + .frequency_step = 1000, + }, + .release = dib0090_release, + + .init = dib0090_wakeup, + .sleep = dib0090_sleep, + .set_params = dib0090_set_params, + .get_frequency = dib0090_get_frequency, +}; + +struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config) +{ + struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL); + if (st == NULL) + return NULL; + + st->config = config; + st->i2c = i2c; + st->fe = fe; + fe->tuner_priv = st; + + if (dib0090_reset(fe) != 0) + goto free_mem; + + printk(KERN_INFO "DiB0090: successfully identified\n"); + memcpy(&fe->ops.tuner_ops, &dib0090_ops, sizeof(struct dvb_tuner_ops)); + + return fe; + free_mem: + kfree(st); + fe->tuner_priv = NULL; + return NULL; +} + +EXPORT_SYMBOL(dib0090_register); + +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_AUTHOR("Olivier Grenie "); +MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/dib0090.h b/drivers/media/dvb/frontends/dib0090.h new file mode 100644 index 00000000000..d72b7d758aa --- /dev/null +++ b/drivers/media/dvb/frontends/dib0090.h @@ -0,0 +1,114 @@ +/* + * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner. + * + * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2. + */ +#ifndef DIB0090_H +#define DIB0090_H + +struct dvb_frontend; +struct i2c_adapter; + +#define DEFAULT_DIB0090_I2C_ADDRESS 0x60 + +struct dib0090_io_config { + u32 clock_khz; + + u8 pll_bypass:1; + u8 pll_range:1; + u8 pll_prediv:6; + u8 pll_loopdiv:6; + + u8 adc_clock_ratio; /* valid is 8, 7 ,6 */ + u16 pll_int_loop_filt; // internal loop filt value. If not fill in , default is 8165 +}; + +struct dib0090_config { + struct dib0090_io_config io; + int (*reset) (struct dvb_frontend *, int); + int (*sleep) (struct dvb_frontend *, int); + + /* offset in kHz */ + int freq_offset_khz_uhf; + int freq_offset_khz_vhf; + + int (*get_adc_power) (struct dvb_frontend *); + + u8 clkouttobamse:1; /* activate or deactivate clock output */ + u8 analog_output; + + u8 i2c_address; + /* add drives and other things if necessary */ + u16 wbd_vhf_offset; + u16 wbd_cband_offset; + u8 use_pwm_agc; + u8 clkoutdrive; +}; + +#if defined(CONFIG_DVB_TUNER_DIB0090) || (defined(CONFIG_DVB_TUNER_DIB0090_MODULE) && defined(MODULE)) +extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config); +extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast); +extern void dib0090_pwm_gain_reset(struct dvb_frontend *fe); +extern u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner); +extern int dib0090_gain_control(struct dvb_frontend *fe); +extern enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe); +extern int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state); +extern enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe); +extern void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt); +#else +static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0090_config *config) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} + +static inline void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); +} + +static inline void dib0090_pwm_gain_reset(struct dvb_frontend *fe) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); +} + +static inline u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return 0; +} + +static inline int dib0090_gain_control(struct dvb_frontend *fe) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} + +static inline enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return CT_DONE; +} + +static inline int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} + +static inline num frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); +return CT_SHUTDOWN,} + +static inline void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); +} +#endif + +#endif diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c index 898400d331a..b924e7eec5a 100644 --- a/drivers/media/dvb/frontends/dib8000.c +++ b/drivers/media/dvb/frontends/dib8000.c @@ -28,18 +28,6 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0) -enum frontend_tune_state { - CT_AGC_START = 20, - CT_AGC_STEP_0, - CT_AGC_STEP_1, - CT_AGC_STEP_2, - CT_AGC_STEP_3, - CT_AGC_STEP_4, - CT_AGC_STOP, - - CT_DEMOD_START = 30, -}; - #define FE_STATUS_TUNE_FAILED 0 struct i2c_device { @@ -852,6 +840,14 @@ static int dib8000_set_agc_config(struct dib8000_state *state, u8 band) return 0; } +void dib8000_pwm_agc_reset(struct dvb_frontend *fe) +{ + struct dib8000_state *state = fe->demodulator_priv; + dib8000_set_adc_state(state, DIBX000_ADC_ON); + dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))); +} +EXPORT_SYMBOL(dib8000_pwm_agc_reset); + static int dib8000_agc_soft_split(struct dib8000_state *state) { u16 agc, split_offset; @@ -939,6 +935,32 @@ static int dib8000_agc_startup(struct dvb_frontend *fe) } +static const int32_t lut_1000ln_mant[] = +{ + 908,7003,7090,7170,7244,7313,7377,7438,7495,7549,7600 +}; + +int32_t dib8000_get_adc_power(struct dvb_frontend *fe, uint8_t mode) +{ + struct dib8000_state *state = fe->demodulator_priv; + uint32_t ix =0, tmp_val =0, exp = 0, mant = 0; + int32_t val; + + val = dib8000_read32(state, 384); + /* mode = 1 : ln_agcpower calc using mant-exp conversion and mantis look up table */ + if(mode) { + tmp_val = val; + while(tmp_val>>=1) + exp++; + mant = (val * 1000 / (1<timf = dib8000_read32(state, 435); @@ -1854,6 +1876,24 @@ static int dib8000_sleep(struct dvb_frontend *fe) } } +enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend* fe) +{ + struct dib8000_state *state = fe->demodulator_priv; + return state->tune_state; +} +EXPORT_SYMBOL(dib8000_get_tune_state); + +int dib8000_set_tune_state(struct dvb_frontend* fe, enum frontend_tune_state tune_state) +{ + struct dib8000_state *state = fe->demodulator_priv; + state->tune_state = tune_state; + return 0; +} +EXPORT_SYMBOL(dib8000_set_tune_state); + + + + static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) { struct dib8000_state *state = fe->demodulator_priv; diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h index 8c89482b738..de05a0ae9d9 100644 --- a/drivers/media/dvb/frontends/dib8000.h +++ b/drivers/media/dvb/frontends/dib8000.h @@ -46,6 +46,10 @@ extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value); extern int dib8000_pid_filter_ctrl(struct dvb_frontend *, u8 onoff); extern int dib8000_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff); +extern int dib8000_set_tune_state(struct dvb_frontend* fe, enum frontend_tune_state tune_state); +extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend* fe); +extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe); +extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode); #else static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg) { @@ -59,35 +63,53 @@ static inline struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe return NULL; } -int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) +static inline int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; } -int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val) +static inline int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; } -int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value) +static inline int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; } -int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) +static inline int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; } -int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) +static inline int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; } +static inline int dib8000_set_tune_state(struct dvb_frontend* fe, enum frontend_tune_state tune_state) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} +static inline enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend* fe) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return CT_SHUTDOWN, +} +static inline void dib8000_pwm_agc_reset(struct dvb_frontend *fe) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); +} +static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); +} #endif #endif diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c index 4efca30d212..e6f3d73db9d 100644 --- a/drivers/media/dvb/frontends/dibx000_common.c +++ b/drivers/media/dvb/frontends/dibx000_common.c @@ -6,7 +6,7 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); -#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); } } while (0) +#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); printk("\n"); } } while (0) static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val) { @@ -25,7 +25,7 @@ static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf) { if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) { - dprintk("selecting interface: %d\n", intf); + dprintk("selecting interface: %d", intf); mst->selected_interface = intf; return dibx000_write_word(mst, mst->base_reg + 4, intf); } @@ -171,9 +171,18 @@ void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst) { i2c_del_adapter(&mst->gated_tuner_i2c_adap); } - EXPORT_SYMBOL(dibx000_exit_i2c_master); + +u32 systime() +{ + struct timespec t; + + t = current_kernel_time(); + return (t.tv_sec * 10000) + (t.tv_nsec / 100000); +} +EXPORT_SYMBOL(systime); + MODULE_AUTHOR("Patrick Boettcher "); MODULE_DESCRIPTION("Common function the DiBcom demodulator family"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h index 5be10eca07c..06328d8742f 100644 --- a/drivers/media/dvb/frontends/dibx000_common.h +++ b/drivers/media/dvb/frontends/dibx000_common.h @@ -36,13 +36,17 @@ extern struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst); extern void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst); +extern u32 systime(void); + #define BAND_LBAND 0x01 #define BAND_UHF 0x02 #define BAND_VHF 0x04 #define BAND_SBAND 0x08 -#define BAND_FM 0x10 +#define BAND_FM 0x10 +#define BAND_CBAND 0x20 -#define BAND_OF_FREQUENCY(freq_kHz) ( (freq_kHz) <= 115000 ? BAND_FM : \ +#define BAND_OF_FREQUENCY(freq_kHz) ( (freq_kHz) <= 170000 ? BAND_CBAND : \ + (freq_kHz) <= 115000 ? BAND_FM : \ (freq_kHz) <= 250000 ? BAND_VHF : \ (freq_kHz) <= 863000 ? BAND_UHF : \ (freq_kHz) <= 2000000 ? BAND_LBAND : BAND_SBAND ) @@ -149,4 +153,67 @@ enum dibx000_adc_states { #define OUTMODE_MPEG2_FIFO 5 #define OUTMODE_ANALOG_ADC 6 +enum frontend_tune_state { + CT_TUNER_START = 10, + CT_TUNER_STEP_0, + CT_TUNER_STEP_1, + CT_TUNER_STEP_2, + CT_TUNER_STEP_3, + CT_TUNER_STEP_4, + CT_TUNER_STEP_5, + CT_TUNER_STEP_6, + CT_TUNER_STEP_7, + CT_TUNER_STOP, + + CT_AGC_START = 20, + CT_AGC_STEP_0, + CT_AGC_STEP_1, + CT_AGC_STEP_2, + CT_AGC_STEP_3, + CT_AGC_STEP_4, + CT_AGC_STOP, + + CT_DEMOD_START = 30, + CT_DEMOD_STEP_1, + CT_DEMOD_STEP_2, + CT_DEMOD_STEP_3, + CT_DEMOD_STEP_4, + CT_DEMOD_STEP_5, + CT_DEMOD_STEP_6, + CT_DEMOD_STEP_7, + CT_DEMOD_STEP_8, + CT_DEMOD_STEP_9, + CT_DEMOD_STEP_10, + CT_DEMOD_SEARCH_NEXT = 41, + CT_DEMOD_STEP_LOCKED, + CT_DEMOD_STOP, + + CT_DONE = 100, + CT_SHUTDOWN, + +}; + +struct dvb_frontend_parametersContext { +#define CHANNEL_STATUS_PARAMETERS_UNKNOWN 0x01 +#define CHANNEL_STATUS_PARAMETERS_SET 0x02 + u8 status; + u32 tune_time_estimation[2]; + s32 tps_available; + u16 tps[9]; +}; + +#define FE_STATUS_TUNE_FAILED 0 +#define FE_STATUS_TUNE_TIMED_OUT -1 +#define FE_STATUS_TUNE_TIME_TOO_SHORT -2 +#define FE_STATUS_TUNE_PENDING -3 +#define FE_STATUS_STD_SUCCESS -4 +#define FE_STATUS_FFT_SUCCESS -5 +#define FE_STATUS_DEMOD_SUCCESS -6 +#define FE_STATUS_LOCKED -7 +#define FE_STATUS_DATA_LOCKED -8 + +#define FE_CALLBACK_TIME_NEVER 0xffffffff + +#define ABS(x) ((x<0)?(-x):(x)) + #endif -- cgit v1.2.3-70-g09d2 From 9c78303681278b983fac3c6c3c0aa3f93cf2ffa8 Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Mon, 7 Dec 2009 07:49:40 -0300 Subject: V4L/DVB (13584): DiBXXX0: fix most of the Codingstyle violations from the previous patch This patch changes most of the Codingstyle violations which were introduced by the previous patch. Line length less that 80 chars are not corrected. Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 596 ++++++++++++++------------- drivers/media/dvb/frontends/dib0070.c | 226 +++++----- drivers/media/dvb/frontends/dib0090.c | 29 +- drivers/media/dvb/frontends/dib0090.h | 2 +- drivers/media/dvb/frontends/dib8000.c | 14 +- drivers/media/dvb/frontends/dib8000.h | 8 +- drivers/media/dvb/frontends/dibx000_common.h | 4 +- 7 files changed, 442 insertions(+), 437 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 80a12635447..d4673c71dff 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -131,93 +131,95 @@ static int bristol_tuner_attach(struct dvb_usb_adapter *adap) /* MT226x */ static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = { { - BAND_UHF, // band_caps + BAND_UHF, /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1, * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup - - 1130, // inv_gain - 21, // time_stabiliz - - 0, // alpha_level - 118, // thlock - - 0, // wbd_inv - 3530, // wbd_ref - 1, // wbd_sel - 0, // wbd_alpha - - 65535, // agc1_max - 33770, // agc1_min - 65535, // agc2_max - 23592, // agc2_min - - 0, // agc1_pt1 - 62, // agc1_pt2 - 255, // agc1_pt3 - 64, // agc1_slope1 - 64, // agc1_slope2 - 132, // agc2_pt1 - 192, // agc2_pt2 - 80, // agc2_slope1 - 80, // agc2_slope2 - - 17, // alpha_mant - 27, // alpha_exp - 23, // beta_mant - 51, // beta_exp - - 1, // perform_agc_softsplit + (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) + | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), + + 1130, + 21, + + 0, + 118, + + 0, + 3530, + 1, + 0, + + 65535, + 33770, + 65535, + 23592, + + 0, + 62, + 255, + 64, + 64, + 132, + 192, + 80, + 80, + + 17, + 27, + 23, + 51, + + 1, }, { - BAND_VHF | BAND_LBAND, // band_caps + BAND_VHF | BAND_LBAND, /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1, * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup - - 2372, // inv_gain - 21, // time_stabiliz - - 0, // alpha_level - 118, // thlock - - 0, // wbd_inv - 3530, // wbd_ref - 1, // wbd_sel - 0, // wbd_alpha - - 65535, // agc1_max - 0, // agc1_min - 65535, // agc2_max - 23592, // agc2_min - - 0, // agc1_pt1 - 128, // agc1_pt2 - 128, // agc1_pt3 - 128, // agc1_slope1 - 0, // agc1_slope2 - 128, // agc2_pt1 - 253, // agc2_pt2 - 81, // agc2_slope1 - 0, // agc2_slope2 - - 17, // alpha_mant - 27, // alpha_exp - 23, // beta_mant - 51, // beta_exp - - 1, // perform_agc_softsplit + (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) + | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), + + 2372, + 21, + + 0, + 118, + + 0, + 3530, + 1, + 0, + + 65535, + 0, + 65535, + 23592, + + 0, + 128, + 128, + 128, + 0, + 128, + 253, + 81, + 0, + + 17, + 27, + 23, + 51, + + 1, } }; static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = { - 60000, 30000, // internal, sampling - 1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass - 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo - (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k - 0, // ifreq - 20452225, // timf + 60000, 30000, + 1, 8, 3, 1, 0, + 0, 0, 1, 1, 2, + (3 << 14) | (1 << 12) | (524 << 0), + 0, + 20452225, }; static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = { @@ -934,47 +936,48 @@ static struct dvb_usb_rc_key dib0700_rc_keys[] = { /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */ static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = { - BAND_UHF | BAND_VHF, // band_caps + BAND_UHF | BAND_VHF, /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup - - 712, // inv_gain - 41, // time_stabiliz - - 0, // alpha_level - 118, // thlock - - 0, // wbd_inv - 4095, // wbd_ref - 0, // wbd_sel - 0, // wbd_alpha - - 42598, // agc1_max - 17694, // agc1_min - 45875, // agc2_max - 2621, // agc2_min - 0, // agc1_pt1 - 76, // agc1_pt2 - 139, // agc1_pt3 - 52, // agc1_slope1 - 59, // agc1_slope2 - 107, // agc2_pt1 - 172, // agc2_pt2 - 57, // agc2_slope1 - 70, // agc2_slope2 - - 21, // alpha_mant - 25, // alpha_exp - 28, // beta_mant - 48, // beta_exp - - 1, // perform_agc_softsplit - { 0, // split_min - 107, // split_max - 51800, // global_split_min - 24700 // global_split_max + (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) + | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), + + 712, + 41, + + 0, + 118, + + 0, + 4095, + 0, + 0, + + 42598, + 17694, + 45875, + 2621, + 0, + 76, + 139, + 52, + 59, + 107, + 172, + 57, + 70, + + 21, + 25, + 28, + 48, + + 1, + { 0, + 107, + 51800, + 24700 }, }; @@ -983,54 +986,55 @@ static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = { /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup + (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) + | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), - 712, // inv_gain - 41, // time_stabiliz + 712, + 41, - 0, // alpha_level - 118, // thlock + 0, + 118, - 0, // wbd_inv - 4095, // wbd_ref - 0, // wbd_sel - 0, // wbd_alpha + 0, + 4095, + 0, + 0, - 42598, // agc1_max - 16384, // agc1_min - 42598, // agc2_max - 0, // agc2_min + 42598, + 16384, + 42598, + 0, - 0, // agc1_pt1 - 137, // agc1_pt2 - 255, // agc1_pt3 + 0, + 137, + 255, - 0, // agc1_slope1 - 255, // agc1_slope2 + 0, + 255, - 0, // agc2_pt1 - 0, // agc2_pt2 + 0, + 0, - 0, // agc2_slope1 - 41, // agc2_slope2 + 0, + 41, - 15, // alpha_mant - 25, // alpha_exp + 15, + 25, - 28, // beta_mant - 48, // beta_exp + 28, + 48, - 0, // perform_agc_softsplit + 0, }; static struct dibx000_bandwidth_config stk7700p_pll_config = { - 60000, 30000, // internal, sampling - 1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass - 0, 0, 1, 1, 0, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo - (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k - 60258167, // ifreq - 20452225, // timf - 30000000, // xtal + 60000, 30000, + 1, 8, 3, 1, 0, + 0, 0, 1, 1, 0, + (3 << 14) | (1 << 12) | (524 << 0), + 60258167, + 20452225, + 30000000, }; static struct dib7000m_config stk7700p_dib7000m_config = { @@ -1116,41 +1120,42 @@ static struct dibx000_agc_config dib7070_agc_config = { BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup - - 600, // inv_gain - 10, // time_stabiliz - - 0, // alpha_level - 118, // thlock - - 0, // wbd_inv - 3530, // wbd_ref - 1, // wbd_sel - 5, // wbd_alpha - - 65535, // agc1_max - 0, // agc1_min - - 65535, // agc2_max - 0, // agc2_min - - 0, // agc1_pt1 - 40, // agc1_pt2 - 183, // agc1_pt3 - 206, // agc1_slope1 - 255, // agc1_slope2 - 72, // agc2_pt1 - 152, // agc2_pt2 - 88, // agc2_slope1 - 90, // agc2_slope2 - - 17, // alpha_mant - 27, // alpha_exp - 23, // beta_mant - 51, // beta_exp - - 0, // perform_agc_softsplit + (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) + | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), + + 600, + 10, + + 0, + 118, + + 0, + 3530, + 1, + 5, + + 65535, + 0, + + 65535, + 0, + + 0, + 40, + 183, + 206, + 255, + 72, + 152, + 88, + 90, + + 17, + 27, + 23, + 51, + + 0, }; static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff) @@ -1277,13 +1282,13 @@ static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) } static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = { - 60000, 15000, // internal, sampling - 1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass - 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo - (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k - (0 << 25) | 0, // ifreq = 0.000000 MHz - 20452225, // timf - 12000000, // xtal_hz + 60000, 15000, + 1, 20, 3, 1, 0, + 0, 0, 1, 1, 2, + (3 << 14) | (1 << 12) | (524 << 0), + (0 << 25) | 0, + 20452225, + 12000000, }; static struct dib7000p_config dib7070p_dib7000p_config = { @@ -1567,12 +1572,14 @@ static int dib807x_tuner_attach(struct dvb_usb_adapter *adap) return 0; } -static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) +static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index, + u16 pid, int onoff) { return dib8000_pid_filter(adapter->fe, index, pid, onoff); } -static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) +static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter, + int onoff) { return dib8000_pid_filter_ctrl(adapter->fe, onoff); } @@ -1648,94 +1655,98 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) struct dibx000_agc_config dib8090_agc_config[2] = { { BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, - /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, - * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup - - 787,// inv_gain = 1/ 90.4dB // no boost, lower gain due to ramp quantification - 10, // time_stabiliz - - 0, // alpha_level - 118, // thlock - - 0, // wbd_inv - 3530, // wbd_ref - 1, // wbd_sel - 5, // wbd_alpha - - 65535, // agc1_max - 0, // agc1_min - - 65535, // agc2_max - 0, // agc2_min - - 0, // agc1_pt1 - 32, // agc1_pt2 - 114, // agc1_pt3 // 40.4dB - 143, // agc1_slope1 - 144, // agc1_slope2 - 114, // agc2_pt1 - 227, // agc2_pt2 - 116, // agc2_slope1 - 117, // agc2_slope2 - - 28, // alpha_mant // 5Hz with 90.2dB - 26, // alpha_exp - 31, // beta_mant - 51, // beta_exp - - 0, // perform_agc_softsplit + /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, + * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, + * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ + (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) + | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), + + 787, + 10, + + 0, + 118, + + 0, + 3530, + 1, + 5, + + 65535, + 0, + + 65535, + 0, + + 0, + 32, + 114, + 143, + 144, + 114, + 227, + 116, + 117, + + 28, + 26, + 31, + 51, + + 0, }, { BAND_CBAND, - /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, - * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup - - 787,// inv_gain = 1/ 90.4dB // no boost, lower gain due to ramp quantification - 10, // time_stabiliz - - 0, // alpha_level - 118, // thlock - - 0, // wbd_inv - 3530, // wbd_ref - 1, // wbd_sel - 5, // wbd_alpha - - 0, // agc1_max - 0, // agc1_min - - 65535, // agc2_max - 0, // agc2_min - - 0, // agc1_pt1 - 32, // agc1_pt2 - 114, // agc1_pt3 // 40.4dB - 143, // agc1_slope1 - 144, // agc1_slope2 - 114, // agc2_pt1 - 227, // agc2_pt2 - 116, // agc2_slope1 - 117, // agc2_slope2 - - 28, // alpha_mant // 5Hz with 90.2dB - 26, // alpha_exp - 31, // beta_mant - 51, // beta_exp - - 0, // perform_agc_softsplit + /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, + * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, + * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ + (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) + | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), + + 787, + 10, + + 0, + 118, + + 0, + 3530, + 1, + 5, + + 0, + 0, + + 65535, + 0, + + 0, + 32, + 114, + 143, + 144, + 114, + 227, + 116, + 117, + + 28, + 26, + 31, + 51, + + 0, } }; static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = { - 54000, 13500, // internal, sampling - 1, 18, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass - 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo - (3 << 14) | (1 << 12) | (599 << 0), // sad_cfg: refsel, sel, freq_15k - (0 << 25) | 0, // ifreq = 0 MHz - 20199727, // timf - 12000000, // xtal_hz + 54000, 13500, + 1, 18, 3, 1, 0, + 0, 0, 1, 1, 2, + (3 << 14) | (1 << 12) | (599 << 0), + (0 << 25) | 0, + 20199727, + 12000000, }; static int dib8090_get_adc_power(struct dvb_frontend *fe) @@ -1802,13 +1813,13 @@ static int dib8096_set_param_override(struct dvb_frontend *fe, return ret; switch (band) { - case BAND_VHF: + case BAND_VHF: offset = 100; break; - case BAND_UHF: + case BAND_UHF: offset = 550; break; - default: + default: offset = 0; break; } @@ -1816,31 +1827,26 @@ static int dib8096_set_param_override(struct dvb_frontend *fe, dib8000_set_wbd_ref(fe, offset); - if (band == BAND_CBAND) - { + if (band == BAND_CBAND) { deb_info("tuning in CBAND - soft-AGC startup\n"); /* TODO specific wbd target for dib0090 - needed for startup ? */ dib0090_set_tune_state(fe, CT_AGC_START); - do - { - ret = dib0090_gain_control(fe); - msleep(ret); - tune_state = dib0090_get_tune_state(fe); - if (tune_state == CT_AGC_STEP_0) - dib8000_set_gpio(fe, 6, 0, 1); - else if (tune_state == CT_AGC_STEP_1) - { - dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, <gain); - if (rf_gain_limit == 0) - dib8000_set_gpio(fe, 6, 0, 0); - } - } - while(tune_statecaptrim, adc, (u32) adc*(u32)1800/(u32)1024); + dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc*(u32)1800/(u32)1024); if (adc >= 400) { adc -= 400; @@ -174,7 +174,7 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state } if (adc < state->adc_diff) { - dprintk( "CAPTRIM=%hd is closer to target (%hd/%hd)", state->captrim, adc, state->adc_diff); + dprintk("CAPTRIM=%hd is closer to target (%hd/%hd)", state->captrim, adc, state->adc_diff); state->adc_diff = adc; state->fcaptrim = state->captrim; @@ -201,7 +201,7 @@ static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf { struct dib0070_state *state = fe->tuner_priv; u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0); - dprintk( "CTRL_LO5: 0x%x", lo5); + dprintk("CTRL_LO5: 0x%x", lo5); return dib0070_write_reg(state, 0x15, lo5); } @@ -215,10 +215,10 @@ void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open) } else { dib0070_write_reg(state, 0x1b, 0x4112); if (state->cfg->vga_filter != 0) { - dib0070_write_reg(state, 0x1a, state->cfg->vga_filter); - dprintk( "vga filter register is set to %x", state->cfg->vga_filter); + dib0070_write_reg(state, 0x1a, state->cfg->vga_filter); + dprintk("vga filter register is set to %x", state->cfg->vga_filter); } else - dib0070_write_reg(state, 0x1a, 0x0009); + dib0070_write_reg(state, 0x1a, 0x0009); } } @@ -255,7 +255,7 @@ static const struct dib0070_tuning dib0070_tuning_table[] = { { 189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000 }, { 250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000 }, { 569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800 }, /* UHF */ - { 699999, 2, 0 ,1, 4, 2, 2, 0x4000 | 0x0800 }, + { 699999, 2, 0, 1, 4, 2, 2, 0x4000 | 0x0800 }, { 863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800 }, { 0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND or everything higher than UHF */ }; @@ -291,7 +291,7 @@ static const struct dib0070_lna_match dib0070_lna[] = { { 0xffffffff, 7 }, }; -#define LPF 100 // define for the loop filter 100kHz by default 16-07-06 +#define LPF 100 static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) { struct dib0070_state *state = fe->tuner_priv; @@ -313,7 +313,7 @@ static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_par && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == (state->fe->dtv_property_cache.isdbt_sb_segment_count / 2))) || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))) - freq += 850; + freq += 850; #endif if (state->current_rf != freq) { @@ -340,95 +340,95 @@ static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_par } if (*tune_state == CT_TUNER_START) { - dprintk( "Tuning for Band: %hd (%d kHz)", band, freq); + dprintk("Tuning for Band: %hd (%d kHz)", band, freq); if (state->current_rf != freq) { - u8 REFDIV; - u32 FBDiv, Rest, FREF, VCOF_kHz; - u8 Den; - - state->current_rf = freq; - state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7); - - - dib0070_write_reg(state, 0x17, 0x30); - - - VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2; - - switch (band) { - case BAND_VHF: - REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000); - break; - case BAND_FM: - REFDIV = (u8) ((state->cfg->clock_khz) / 1000); - break; - default: - REFDIV = (u8) ( state->cfg->clock_khz / 10000); - break; - } - FREF = state->cfg->clock_khz / REFDIV; - - - - switch (state->revision) { - case DIB0070S_P1A: - FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF); - Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF; - break; - - case DIB0070_P1G: - case DIB0070_P1F: - default: - FBDiv = (freq / (FREF / 2)); - Rest = 2 * freq - FBDiv * FREF; - break; - } - - if (Rest < LPF) - Rest = 0; - else if (Rest < 2 * LPF) - Rest = 2 * LPF; - else if (Rest > (FREF - LPF)) { - Rest = 0; - FBDiv += 1; - } else if (Rest > (FREF - 2 * LPF)) - Rest = FREF - 2 * LPF; - Rest = (Rest * 6528) / (FREF / 10); - - Den = 1; - if (Rest > 0) { - state->lo4 |= (1 << 14) | (1 << 12); - Den = 255; - } - - - dib0070_write_reg(state, 0x11, (u16)FBDiv); - dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV); - dib0070_write_reg(state, 0x13, (u16) Rest); - - if (state->revision == DIB0070S_P1A) { - - if (band == BAND_SBAND) { - dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0); - dib0070_write_reg(state, 0x1d,0xFFFF); - } else - dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1); - } - - dib0070_write_reg(state, 0x20, - 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable); - - dprintk( "REFDIV: %hd, FREF: %d", REFDIV, FREF); - dprintk( "FBDIV: %d, Rest: %d", FBDiv, Rest); - dprintk( "Num: %hd, Den: %hd, SD: %hd",(u16) Rest, Den, (state->lo4 >> 12) & 0x1); - dprintk( "HFDIV code: %hd", state->current_tune_table_index->hfdiv); - dprintk( "VCO = %hd", state->current_tune_table_index->vco_band); - dprintk( "VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq); - - *tune_state = CT_TUNER_STEP_0; + u8 REFDIV; + u32 FBDiv, Rest, FREF, VCOF_kHz; + u8 Den; + + state->current_rf = freq; + state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7); + + + dib0070_write_reg(state, 0x17, 0x30); + + + VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2; + + switch (band) { + case BAND_VHF: + REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000); + break; + case BAND_FM: + REFDIV = (u8) ((state->cfg->clock_khz) / 1000); + break; + default: + REFDIV = (u8) (state->cfg->clock_khz / 10000); + break; + } + FREF = state->cfg->clock_khz / REFDIV; + + + + switch (state->revision) { + case DIB0070S_P1A: + FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF); + Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF; + break; + + case DIB0070_P1G: + case DIB0070_P1F: + default: + FBDiv = (freq / (FREF / 2)); + Rest = 2 * freq - FBDiv * FREF; + break; + } + + if (Rest < LPF) + Rest = 0; + else if (Rest < 2 * LPF) + Rest = 2 * LPF; + else if (Rest > (FREF - LPF)) { + Rest = 0; + FBDiv += 1; + } else if (Rest > (FREF - 2 * LPF)) + Rest = FREF - 2 * LPF; + Rest = (Rest * 6528) / (FREF / 10); + + Den = 1; + if (Rest > 0) { + state->lo4 |= (1 << 14) | (1 << 12); + Den = 255; + } + + + dib0070_write_reg(state, 0x11, (u16)FBDiv); + dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV); + dib0070_write_reg(state, 0x13, (u16) Rest); + + if (state->revision == DIB0070S_P1A) { + + if (band == BAND_SBAND) { + dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0); + dib0070_write_reg(state, 0x1d, 0xFFFF); + } else + dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1); + } + + dib0070_write_reg(state, 0x20, + 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable); + + dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF); + dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest); + dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1); + dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv); + dprintk("VCO = %hd", state->current_tune_table_index->vco_band); + dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq); + + *tune_state = CT_TUNER_STEP_0; } else { /* we are already tuned to this frequency - the configuration is correct */ - ret = 50; /* wakeup time */ - *tune_state = CT_TUNER_STEP_5; + ret = 50; /* wakeup time */ + *tune_state = CT_TUNER_STEP_5; } } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) { @@ -437,13 +437,13 @@ static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_par } else if (*tune_state == CT_TUNER_STEP_4) { const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain; if (tmp != NULL) { - while (freq/1000 > tmp->freq) /* find the right one */ - tmp++; - dib0070_write_reg(state, 0x0f, - (0 << 15) | (1 << 14) | (3 << 12) | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7) | (state-> - current_tune_table_index-> - wbdmux << 0)); - state->wbd_gain_current = tmp->wbd_gain_val; + while (freq/1000 > tmp->freq) /* find the right one */ + tmp++; + dib0070_write_reg(state, 0x0f, + (0 << 15) | (1 << 14) | (3 << 12) + | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7) + | (state->current_tune_table_index->wbdmux << 0)); + state->wbd_gain_current = tmp->wbd_gain_val; } else { dib0070_write_reg(state, 0x0f, (0 << 15) | (1 << 14) | (3 << 12) | (6 << 9) | (0 << 8) | (1 << 7) | (state->current_tune_table_index-> @@ -483,7 +483,7 @@ static int dib0070_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters do { ret = dib0070_tune_digital(fe, p); if (ret != FE_CALLBACK_TIME_NEVER) - msleep(ret/10); + msleep(ret/10); else break; } while (state->tune_state != CT_TUNER_STOP); @@ -512,18 +512,20 @@ u8 dib0070_get_rf_output(struct dvb_frontend *fe) struct dib0070_state *state = fe->tuner_priv; return (dib0070_read_reg(state, 0x07) >> 11) & 0x3; } - EXPORT_SYMBOL(dib0070_get_rf_output); + int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no) { struct dib0070_state *state = fe->tuner_priv; u16 rxrf2 = dib0070_read_reg(state, 0x07) & 0xfe7ff; - if (no > 3) no = 3; - if (no < 1) no = 1; + if (no > 3) + no = 3; + if (no < 1) + no = 1; return dib0070_write_reg(state, 0x07, rxrf2 | (no << 11)); } - EXPORT_SYMBOL(dib0070_set_rf_output); + static const u16 dib0070_p1f_defaults[] = { @@ -582,7 +584,7 @@ static void dib0070_wbd_offset_calibration(struct dib0070_state *state) u8 gain; for (gain = 6; gain < 8; gain++) { state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2); - dprintk( "Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain-6]); + dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain-6]); } } @@ -622,10 +624,10 @@ static int dib0070_reset(struct dvb_frontend *fe) state->revision = DIB0070S_P1A; /* P1F or not */ - dprintk( "Revision: %x", state->revision); + dprintk("Revision: %x", state->revision); if (state->revision == DIB0070_P1D) { - dprintk( "Error: this driver is not to be used meant for P1D or earlier"); + dprintk("Error: this driver is not to be used meant for P1D or earlier"); return -EINVAL; } @@ -702,7 +704,7 @@ static const struct dvb_tuner_ops dib0070_ops = { // .get_bandwidth = dib0070_get_bandwidth }; -struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg) +struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg) { struct dib0070_state *state = kzalloc(sizeof(struct dib0070_state), GFP_KERNEL); if (state == NULL) diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c index e37d32dbd5c..614552709a6 100644 --- a/drivers/media/dvb/frontends/dib0090.c +++ b/drivers/media/dvb/frontends/dib0090.c @@ -149,8 +149,8 @@ static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) { u8 b[2]; struct i2c_msg msg[2] = { - {.addr = state->config->i2c_address,.flags = 0,.buf = ®,.len = 1}, - {.addr = state->config->i2c_address,.flags = I2C_M_RD,.buf = b,.len = 2}, + {.addr = state->config->i2c_address, .flags = 0, .buf = ®, .len = 1}, + {.addr = state->config->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2}, }; if (i2c_transfer(state->i2c, msg, 2) != 2) { printk(KERN_WARNING "DiB0090 I2C read failed\n"); @@ -162,7 +162,7 @@ static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) { u8 b[3] = { reg & 0xff, val >> 8, val & 0xff }; - struct i2c_msg msg = {.addr = state->config->i2c_address,.flags = 0,.buf = b,.len = 3 }; + struct i2c_msg msg = {.addr = state->config->i2c_address, .flags = 0, .buf = b, .len = 3 }; if (i2c_transfer(state->i2c, &msg, 1) != 1) { printk(KERN_WARNING "DiB0090 I2C write failed\n"); return -EREMOTEIO; @@ -287,12 +287,12 @@ extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast) { struct dib0090_state *state = fe->tuner_priv; if (fast) - dib0090_write_reg(state, 0x04, 0); //1kHz + dib0090_write_reg(state, 0x04, 0); else - dib0090_write_reg(state, 0x04, 1); //almost frozen + dib0090_write_reg(state, 0x04, 1); } - EXPORT_SYMBOL(dib0090_dcc_freq); + static const u16 rf_ramp_pwm_cband[] = { 0, /* max RF gain in 10th of dB */ 0, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */ @@ -616,11 +616,11 @@ void dib0090_pwm_gain_reset(struct dvb_frontend *fe) else dib0090_write_reg(state, 0x32, (0 << 11)); - dib0090_write_reg(state, 0x39, (1 << 10)); // 0 gain by default + dib0090_write_reg(state, 0x39, (1 << 10)); } } - EXPORT_SYMBOL(dib0090_pwm_gain_reset); + int dib0090_gain_control(struct dvb_frontend *fe) { struct dib0090_state *state = fe->tuner_priv; @@ -760,7 +760,7 @@ int dib0090_gain_control(struct dvb_frontend *fe) #ifdef DEBUG_AGC dprintk ("FE: %d, tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm", - (u32) fe->id, (u32) * tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val, + (u32) fe->id, (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val, (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA)); #endif } @@ -770,8 +770,8 @@ int dib0090_gain_control(struct dvb_frontend *fe) dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly); return ret; } - EXPORT_SYMBOL(dib0090_gain_control); + void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt) { struct dib0090_state *state = fe->tuner_priv; @@ -784,15 +784,15 @@ void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * if (rflt) *rflt = (state->rf_lt_def >> 10) & 0x7; } - EXPORT_SYMBOL(dib0090_get_current_gain); + u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner) { struct dib0090_state *st = tuner->tuner_priv; return st->wbd_offset; } - EXPORT_SYMBOL(dib0090_get_wbd_offset); + static const u16 dib0090_defaults[] = { 25, 0x01, @@ -891,7 +891,7 @@ static int dib0090_reset(struct dvb_frontend *fe) return 0; } -#define steps(u) (((u)>15)?((u)-16):(u)) +#define steps(u) (((u) > 15) ? ((u)-16) : (u)) #define INTERN_WAIT 10 static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_state *tune_state) { @@ -1439,7 +1439,6 @@ enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe) return state->tune_state; } - EXPORT_SYMBOL(dib0090_get_tune_state); int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state) @@ -1449,7 +1448,6 @@ int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tun state->tune_state = tune_state; return 0; } - EXPORT_SYMBOL(dib0090_set_tune_state); static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency) @@ -1516,7 +1514,6 @@ struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapte fe->tuner_priv = NULL; return NULL; } - EXPORT_SYMBOL(dib0090_register); MODULE_AUTHOR("Patrick Boettcher "); diff --git a/drivers/media/dvb/frontends/dib0090.h b/drivers/media/dvb/frontends/dib0090.h index d72b7d758aa..83cc8ae9ba3 100644 --- a/drivers/media/dvb/frontends/dib0090.h +++ b/drivers/media/dvb/frontends/dib0090.h @@ -24,7 +24,7 @@ struct dib0090_io_config { u8 pll_loopdiv:6; u8 adc_clock_ratio; /* valid is 8, 7 ,6 */ - u16 pll_int_loop_filt; // internal loop filt value. If not fill in , default is 8165 + u16 pll_int_loop_filt; }; struct dib0090_config { diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c index b924e7eec5a..5218a5c19d1 100644 --- a/drivers/media/dvb/frontends/dib8000.c +++ b/drivers/media/dvb/frontends/dib8000.c @@ -937,21 +937,21 @@ static int dib8000_agc_startup(struct dvb_frontend *fe) static const int32_t lut_1000ln_mant[] = { - 908,7003,7090,7170,7244,7313,7377,7438,7495,7549,7600 + 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600 }; int32_t dib8000_get_adc_power(struct dvb_frontend *fe, uint8_t mode) { struct dib8000_state *state = fe->demodulator_priv; - uint32_t ix =0, tmp_val =0, exp = 0, mant = 0; + uint32_t ix = 0, tmp_val = 0, exp = 0, mant = 0; int32_t val; val = dib8000_read32(state, 384); /* mode = 1 : ln_agcpower calc using mant-exp conversion and mantis look up table */ - if(mode) { + if (mode) { tmp_val = val; - while(tmp_val>>=1) - exp++; + while (tmp_val >>= 1) + exp++; mant = (val * 1000 / (1<demodulator_priv; return state->tune_state; } EXPORT_SYMBOL(dib8000_get_tune_state); -int dib8000_set_tune_state(struct dvb_frontend* fe, enum frontend_tune_state tune_state) +int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state) { struct dib8000_state *state = fe->demodulator_priv; state->tune_state = tune_state; diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h index de05a0ae9d9..d99619ae983 100644 --- a/drivers/media/dvb/frontends/dib8000.h +++ b/drivers/media/dvb/frontends/dib8000.h @@ -46,8 +46,8 @@ extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value); extern int dib8000_pid_filter_ctrl(struct dvb_frontend *, u8 onoff); extern int dib8000_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff); -extern int dib8000_set_tune_state(struct dvb_frontend* fe, enum frontend_tune_state tune_state); -extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend* fe); +extern int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state); +extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe); extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe); extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode); #else @@ -92,12 +92,12 @@ static inline int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; } -static inline int dib8000_set_tune_state(struct dvb_frontend* fe, enum frontend_tune_state tune_state) +static inline int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; } -static inline enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend* fe) +static inline enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return CT_SHUTDOWN, diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h index 06328d8742f..4f5d141a308 100644 --- a/drivers/media/dvb/frontends/dibx000_common.h +++ b/drivers/media/dvb/frontends/dibx000_common.h @@ -45,7 +45,7 @@ extern u32 systime(void); #define BAND_FM 0x10 #define BAND_CBAND 0x20 -#define BAND_OF_FREQUENCY(freq_kHz) ( (freq_kHz) <= 170000 ? BAND_CBAND : \ +#define BAND_OF_FREQUENCY(freq_kHz) ((freq_kHz) <= 170000 ? BAND_CBAND : \ (freq_kHz) <= 115000 ? BAND_FM : \ (freq_kHz) <= 250000 ? BAND_VHF : \ (freq_kHz) <= 863000 ? BAND_UHF : \ @@ -214,6 +214,6 @@ struct dvb_frontend_parametersContext { #define FE_CALLBACK_TIME_NEVER 0xffffffff -#define ABS(x) ((x<0)?(-x):(x)) +#define ABS(x) ((x < 0) ? (-x) : (x)) #endif -- cgit v1.2.3-70-g09d2 From 9542f502cf5a51b34d1c04c25206a8d69d4b8d0f Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Mon, 7 Dec 2009 08:09:04 -0300 Subject: V4L/DVB (13585): STK807xPVR: correct the enumeration STK807xPVR: correct the enumeration Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index d4673c71dff..44972d01bbd 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1632,7 +1632,7 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap) dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); /* initialize IC 0 */ - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x80); + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80); adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib807x_dib8000_config[0]); @@ -1643,7 +1643,7 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap) static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) { /* initialize IC 1 */ - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x82); + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82); adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, &dib807x_dib8000_config[1]); -- cgit v1.2.3-70-g09d2 From acc5c9ee393952c00eb7fab8bdd529d45226f6ed Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Mon, 7 Dec 2009 08:22:53 -0300 Subject: V4L/DVB (13586): DiB0700: Add parameter to change the buffer size Add parameter to change the buffer size. This buffer size is specified in number of Ts packet. This parameter is stored inside the state. For firmware higher than 1.21, the xfer buffer size can be changed inside the dib0700 usb bridge the firware version is stored inside the state Signed-off-by: Patrick Boettcher Signed-off-by: Olivier Grenie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700.h | 26 ++++---- drivers/media/dvb/dvb-usb/dib0700_core.c | 101 ++++++++++++++++++++++++++++--- 2 files changed, 109 insertions(+), 18 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h index 8b544fe79b0..495a90577c5 100644 --- a/drivers/media/dvb/dvb-usb/dib0700.h +++ b/drivers/media/dvb/dvb-usb/dib0700.h @@ -20,20 +20,22 @@ extern int dvb_usb_dib0700_debug; #define deb_fwdata(args...) dprintk(dvb_usb_dib0700_debug,0x04,args) #define deb_data(args...) dprintk(dvb_usb_dib0700_debug,0x08,args) -#define REQUEST_I2C_READ 0x2 -#define REQUEST_I2C_WRITE 0x3 -#define REQUEST_POLL_RC 0x4 /* deprecated in firmware v1.20 */ -#define REQUEST_JUMPRAM 0x8 -#define REQUEST_SET_CLOCK 0xB -#define REQUEST_SET_GPIO 0xC -#define REQUEST_ENABLE_VIDEO 0xF +#define REQUEST_SET_USB_XFER_LEN 0x0 /* valid only for firmware version */ + /* higher than 1.21 */ +#define REQUEST_I2C_READ 0x2 +#define REQUEST_I2C_WRITE 0x3 +#define REQUEST_POLL_RC 0x4 /* deprecated in firmware v1.20 */ +#define REQUEST_JUMPRAM 0x8 +#define REQUEST_SET_CLOCK 0xB +#define REQUEST_SET_GPIO 0xC +#define REQUEST_ENABLE_VIDEO 0xF // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog) // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1) // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " ) -#define REQUEST_SET_RC 0x11 -#define REQUEST_NEW_I2C_READ 0x12 -#define REQUEST_NEW_I2C_WRITE 0x13 -#define REQUEST_GET_VERSION 0x15 +#define REQUEST_SET_RC 0x11 +#define REQUEST_NEW_I2C_READ 0x12 +#define REQUEST_NEW_I2C_WRITE 0x13 +#define REQUEST_GET_VERSION 0x15 struct dib0700_state { u8 channel_state; @@ -44,6 +46,8 @@ struct dib0700_state { u8 is_dib7000pc; u8 fw_use_new_i2c_api; u8 disable_streaming_master_mode; + u32 fw_version; + u32 nb_packet_buffer_size; }; extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index db7f7f79a66..0d3c9a9a33b 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -17,6 +17,14 @@ int dvb_usb_dib0700_ir_proto = 1; module_param(dvb_usb_dib0700_ir_proto, int, 0644); MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (default), 2=RC6)."); +static int nb_packet_buffer_size = 21; +module_param(nb_packet_buffer_size, int, 0644); +MODULE_PARM_DESC(nb_packet_buffer_size, + "Set the dib0700 driver data buffer size. This parameter " + "corresponds to the number of TS packets. The actual size of " + "the data buffer corresponds to this parameter " + "multiplied by 188 (default: 21)"); + DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); @@ -28,10 +36,14 @@ int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, REQUEST_GET_VERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, b, sizeof(b), USB_CTRL_GET_TIMEOUT); - *hwversion = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; - *romversion = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7]; - *ramversion = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11]; - *fwtype = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15]; + if (hwversion != NULL) + *hwversion = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; + if (romversion != NULL) + *romversion = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7]; + if (ramversion != NULL) + *ramversion = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11]; + if (fwtype != NULL) + *fwtype = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15]; return ret; } @@ -97,6 +109,27 @@ int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_ return dib0700_ctrl_wr(d,buf,3); } +static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets) +{ + struct dib0700_state *st = d->priv; + u8 b[3]; + int ret; + + if (st->fw_version >= 0x10201) { + b[0] = REQUEST_SET_USB_XFER_LEN; + b[1] = (nb_ts_packets >> 8)&0xff; + b[2] = nb_ts_packets & 0xff; + + deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets); + + ret = dib0700_ctrl_wr(d, b, 3); + } else { + deb_info("this firmware does not allow to change the USB xfer len\n"); + ret = -EIO; + } + return ret; +} + /* * I2C master xfer function (supported in 1.20 firmware) */ @@ -328,7 +361,9 @@ static int dib0700_jumpram(struct usb_device *udev, u32 address) int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw) { struct hexline hx; - int pos = 0, ret, act_len; + int pos = 0, ret, act_len, i, adap_num; + u8 b[16]; + u32 fw_version; u8 buf[260]; @@ -364,6 +399,34 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw } else ret = -EIO; + /* the number of ts packet has to be at least 1 */ + if (nb_packet_buffer_size < 1) + nb_packet_buffer_size = 1; + + /* get the fimware version */ + usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + REQUEST_GET_VERSION, + USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, + b, sizeof(b), USB_CTRL_GET_TIMEOUT); + fw_version = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11]; + + /* set the buffer size - DVB-USB is allocating URB buffers + * only after the firwmare download was successful */ + for (i = 0; i < dib0700_device_count; i++) { + for (adap_num = 0; adap_num < dib0700_devices[i].num_adapters; + adap_num++) { + if (fw_version >= 0x10201) + dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 188*nb_packet_buffer_size; + else { + /* for fw version older than 1.20.1, + * the buffersize has to be n times 512 */ + dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = ((188*nb_packet_buffer_size+188/2)/512)*512; + if (dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize < 512) + dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 512; + } + } + } + return ret; } @@ -371,6 +434,18 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) { struct dib0700_state *st = adap->dev->priv; u8 b[4]; + int ret; + + if ((onoff != 0) && (st->fw_version >= 0x10201)) { + /* for firmware later than 1.20.1, + * the USB xfer length can be set */ + ret = dib0700_set_usb_xfer_len(adap->dev, + st->nb_packet_buffer_size); + if (ret < 0) { + deb_info("can not set the USB xfer len\n"); + return ret; + } + } b[0] = REQUEST_ENABLE_VIDEO; b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */ @@ -415,9 +490,21 @@ static int dib0700_probe(struct usb_interface *intf, for (i = 0; i < dib0700_device_count; i++) if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE, - &dev, adapter_nr) == 0) - { + &dev, adapter_nr) == 0) { + struct dib0700_state *st = dev->priv; + u32 hwversion, romversion, fw_version, fwtype; + + dib0700_get_version(dev, &hwversion, &romversion, + &fw_version, &fwtype); + + deb_info("Firmware version: %x, %d, 0x%x, %d\n", + hwversion, romversion, fw_version, fwtype); + + st->fw_version = fw_version; + st->nb_packet_buffer_size = (u32)nb_packet_buffer_size; + dib0700_rc_setup(dev); + return 0; } -- cgit v1.2.3-70-g09d2 From 89dfc557d1b85bbaf04ca4c9927c6ea22df72e04 Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Mon, 30 Nov 2009 06:38:49 -0300 Subject: V4L/DVB (13587): DiB8000: enhance status lock Enhance status lock behaviour. Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/dib8000.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c index 5218a5c19d1..bb2ec1567cd 100644 --- a/drivers/media/dvb/frontends/dib8000.c +++ b/drivers/media/dvb/frontends/dib8000.c @@ -2083,29 +2083,31 @@ static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) *stat = 0; - if ((lock >> 14) & 1) // AGC + if ((lock >> 13) & 1) *stat |= FE_HAS_SIGNAL; - if ((lock >> 8) & 1) // Equal + if ((lock >> 8) & 1) /* Equal */ *stat |= FE_HAS_CARRIER; - if ((lock >> 3) & 1) // TMCC_SYNC + if (((lock >> 1) & 0xf) == 0xf) /* TMCC_SYNC */ *stat |= FE_HAS_SYNC; - if ((lock >> 5) & 7) // FEC MPEG + if (((lock >> 12) & 1) && ((lock >> 5) & 7)) /* FEC MPEG */ *stat |= FE_HAS_LOCK; - lock = dib8000_read_word(state, 554); // Viterbi Layer A - if (lock & 0x01) - *stat |= FE_HAS_VITERBI; + if ((lock >> 12) & 1) { + lock = dib8000_read_word(state, 554); /* Viterbi Layer A */ + if (lock & 0x01) + *stat |= FE_HAS_VITERBI; - lock = dib8000_read_word(state, 555); // Viterbi Layer B - if (lock & 0x01) - *stat |= FE_HAS_VITERBI; + lock = dib8000_read_word(state, 555); /* Viterbi Layer B */ + if (lock & 0x01) + *stat |= FE_HAS_VITERBI; - lock = dib8000_read_word(state, 556); // Viterbi Layer C - if (lock & 0x01) - *stat |= FE_HAS_VITERBI; + lock = dib8000_read_word(state, 556); /* Viterbi Layer C */ + if (lock & 0x01) + *stat |= FE_HAS_VITERBI; + } return 0; } -- cgit v1.2.3-70-g09d2 From 6e8fdbd023ef6a05da444baacfea75fdf97bdc50 Mon Sep 17 00:00:00 2001 From: Márton Németh Date: Sun, 22 Nov 2009 18:52:37 -0300 Subject: V4L/DVB (13589): dib8000: merge two conditionals MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge two ifs: the condition is the same. The second if uses the ncoeff which is initialized in the first if. Cc: Patrick Boettcher Signed-off-by: Márton Németh Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/dib8000.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c index bb2ec1567cd..335c6c03003 100644 --- a/drivers/media/dvb/frontends/dib8000.c +++ b/drivers/media/dvb/frontends/dib8000.c @@ -1423,10 +1423,9 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear } break; } - } - if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) for (i = 0; i < 8; i++) dib8000_write_word(state, 343 + i, ncoeff[i]); + } // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5 dib8000_write_word(state, 351, -- cgit v1.2.3-70-g09d2 From 7eca61eb6a57a3aae10e77d9306cda0b8c23cdab Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sun, 22 Nov 2009 23:02:02 -0300 Subject: V4L/DVB (13590): cpia: convert it to use proc_fops X-Patchwork-Id: 62090 Signed-off-by: Alexey Dobriyan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cpia.c | 212 ++++++++++++++++++++++----------------------- 1 file changed, 105 insertions(+), 107 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c index d6f2653afb6..551ddf216a4 100644 --- a/drivers/media/video/cpia.c +++ b/drivers/media/video/cpia.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -244,72 +245,67 @@ static void rvfree(void *mem, unsigned long size) #ifdef CONFIG_PROC_FS static struct proc_dir_entry *cpia_proc_root=NULL; -static int cpia_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int cpia_proc_show(struct seq_file *m, void *v) { - char *out = page; - int len, tmp; - struct cam_data *cam = data; + struct cam_data *cam = m->private; + int tmp; char tmpstr[29]; - /* IMPORTANT: This output MUST be kept under PAGE_SIZE - * or we need to get more sophisticated. */ - - out += sprintf(out, "read-only\n-----------------------\n"); - out += sprintf(out, "V4L Driver version: %d.%d.%d\n", + seq_printf(m, "read-only\n-----------------------\n"); + seq_printf(m, "V4L Driver version: %d.%d.%d\n", CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER); - out += sprintf(out, "CPIA Version: %d.%02d (%d.%d)\n", + seq_printf(m, "CPIA Version: %d.%02d (%d.%d)\n", cam->params.version.firmwareVersion, cam->params.version.firmwareRevision, cam->params.version.vcVersion, cam->params.version.vcRevision); - out += sprintf(out, "CPIA PnP-ID: %04x:%04x:%04x\n", + seq_printf(m, "CPIA PnP-ID: %04x:%04x:%04x\n", cam->params.pnpID.vendor, cam->params.pnpID.product, cam->params.pnpID.deviceRevision); - out += sprintf(out, "VP-Version: %d.%d %04x\n", + seq_printf(m, "VP-Version: %d.%d %04x\n", cam->params.vpVersion.vpVersion, cam->params.vpVersion.vpRevision, cam->params.vpVersion.cameraHeadID); - out += sprintf(out, "system_state: %#04x\n", + seq_printf(m, "system_state: %#04x\n", cam->params.status.systemState); - out += sprintf(out, "grab_state: %#04x\n", + seq_printf(m, "grab_state: %#04x\n", cam->params.status.grabState); - out += sprintf(out, "stream_state: %#04x\n", + seq_printf(m, "stream_state: %#04x\n", cam->params.status.streamState); - out += sprintf(out, "fatal_error: %#04x\n", + seq_printf(m, "fatal_error: %#04x\n", cam->params.status.fatalError); - out += sprintf(out, "cmd_error: %#04x\n", + seq_printf(m, "cmd_error: %#04x\n", cam->params.status.cmdError); - out += sprintf(out, "debug_flags: %#04x\n", + seq_printf(m, "debug_flags: %#04x\n", cam->params.status.debugFlags); - out += sprintf(out, "vp_status: %#04x\n", + seq_printf(m, "vp_status: %#04x\n", cam->params.status.vpStatus); - out += sprintf(out, "error_code: %#04x\n", + seq_printf(m, "error_code: %#04x\n", cam->params.status.errorCode); /* QX3 specific entries */ if (cam->params.qx3.qx3_detected) { - out += sprintf(out, "button: %4d\n", + seq_printf(m, "button: %4d\n", cam->params.qx3.button); - out += sprintf(out, "cradled: %4d\n", + seq_printf(m, "cradled: %4d\n", cam->params.qx3.cradled); } - out += sprintf(out, "video_size: %s\n", + seq_printf(m, "video_size: %s\n", cam->params.format.videoSize == VIDEOSIZE_CIF ? "CIF " : "QCIF"); - out += sprintf(out, "roi: (%3d, %3d) to (%3d, %3d)\n", + seq_printf(m, "roi: (%3d, %3d) to (%3d, %3d)\n", cam->params.roi.colStart*8, cam->params.roi.rowStart*4, cam->params.roi.colEnd*8, cam->params.roi.rowEnd*4); - out += sprintf(out, "actual_fps: %3d\n", cam->fps); - out += sprintf(out, "transfer_rate: %4dkB/s\n", + seq_printf(m, "actual_fps: %3d\n", cam->fps); + seq_printf(m, "transfer_rate: %4dkB/s\n", cam->transfer_rate); - out += sprintf(out, "\nread-write\n"); - out += sprintf(out, "----------------------- current min" + seq_printf(m, "\nread-write\n"); + seq_printf(m, "----------------------- current min" " max default comment\n"); - out += sprintf(out, "brightness: %8d %8d %8d %8d\n", + seq_printf(m, "brightness: %8d %8d %8d %8d\n", cam->params.colourParams.brightness, 0, 100, 50); if (cam->params.version.firmwareVersion == 1 && cam->params.version.firmwareRevision == 2) @@ -318,26 +314,26 @@ static int cpia_read_proc(char *page, char **start, off_t off, else tmp = 96; - out += sprintf(out, "contrast: %8d %8d %8d %8d" + seq_printf(m, "contrast: %8d %8d %8d %8d" " steps of 8\n", cam->params.colourParams.contrast, 0, tmp, 48); - out += sprintf(out, "saturation: %8d %8d %8d %8d\n", + seq_printf(m, "saturation: %8d %8d %8d %8d\n", cam->params.colourParams.saturation, 0, 100, 50); tmp = (25000+5000*cam->params.sensorFps.baserate)/ (1<params.sensorFps.divisor); - out += sprintf(out, "sensor_fps: %4d.%03d %8d %8d %8d\n", + seq_printf(m, "sensor_fps: %4d.%03d %8d %8d %8d\n", tmp/1000, tmp%1000, 3, 30, 15); - out += sprintf(out, "stream_start_line: %8d %8d %8d %8d\n", + seq_printf(m, "stream_start_line: %8d %8d %8d %8d\n", 2*cam->params.streamStartLine, 0, cam->params.format.videoSize == VIDEOSIZE_CIF ? 288:144, cam->params.format.videoSize == VIDEOSIZE_CIF ? 240:120); - out += sprintf(out, "sub_sample: %8s %8s %8s %8s\n", + seq_printf(m, "sub_sample: %8s %8s %8s %8s\n", cam->params.format.subSample == SUBSAMPLE_420 ? "420" : "422", "420", "422", "422"); - out += sprintf(out, "yuv_order: %8s %8s %8s %8s\n", + seq_printf(m, "yuv_order: %8s %8s %8s %8s\n", cam->params.format.yuvOrder == YUVORDER_YUYV ? "YUYV" : "UYVY", "YUYV" , "UYVY", "YUYV"); - out += sprintf(out, "ecp_timing: %8s %8s %8s %8s\n", + seq_printf(m, "ecp_timing: %8s %8s %8s %8s\n", cam->params.ecpTiming ? "slow" : "normal", "slow", "normal", "normal"); @@ -346,13 +342,13 @@ static int cpia_read_proc(char *page, char **start, off_t off, } else { sprintf(tmpstr, "manual"); } - out += sprintf(out, "color_balance_mode: %8s %8s %8s" + seq_printf(m, "color_balance_mode: %8s %8s %8s" " %8s\n", tmpstr, "manual", "auto", "auto"); - out += sprintf(out, "red_gain: %8d %8d %8d %8d\n", + seq_printf(m, "red_gain: %8d %8d %8d %8d\n", cam->params.colourBalance.redGain, 0, 212, 32); - out += sprintf(out, "green_gain: %8d %8d %8d %8d\n", + seq_printf(m, "green_gain: %8d %8d %8d %8d\n", cam->params.colourBalance.greenGain, 0, 212, 6); - out += sprintf(out, "blue_gain: %8d %8d %8d %8d\n", + seq_printf(m, "blue_gain: %8d %8d %8d %8d\n", cam->params.colourBalance.blueGain, 0, 212, 92); if (cam->params.version.firmwareVersion == 1 && @@ -363,10 +359,10 @@ static int cpia_read_proc(char *page, char **start, off_t off, sprintf(tmpstr, "%8d %8d %8d", 1, 8, 2); if (cam->params.exposure.gainMode == 0) - out += sprintf(out, "max_gain: unknown %28s" + seq_printf(m, "max_gain: unknown %28s" " powers of 2\n", tmpstr); else - out += sprintf(out, "max_gain: %8d %28s" + seq_printf(m, "max_gain: %8d %28s" " 1,2,4 or 8 \n", 1<<(cam->params.exposure.gainMode-1), tmpstr); @@ -382,12 +378,12 @@ static int cpia_read_proc(char *page, char **start, off_t off, sprintf(tmpstr, "unknown"); break; } - out += sprintf(out, "exposure_mode: %8s %8s %8s" + seq_printf(m, "exposure_mode: %8s %8s %8s" " %8s\n", tmpstr, "manual", "auto", "auto"); - out += sprintf(out, "centre_weight: %8s %8s %8s %8s\n", + seq_printf(m, "centre_weight: %8s %8s %8s %8s\n", (2-cam->params.exposure.centreWeight) ? "on" : "off", "off", "on", "on"); - out += sprintf(out, "gain: %8d %8d max_gain %8d 1,2,4,8 possible\n", + seq_printf(m, "gain: %8d %8d max_gain %8d 1,2,4,8 possible\n", 1<params.exposure.gain, 1, 1); if (cam->params.version.firmwareVersion == 1 && cam->params.version.firmwareRevision == 2) @@ -396,7 +392,7 @@ static int cpia_read_proc(char *page, char **start, off_t off, else tmp = 510; - out += sprintf(out, "fine_exp: %8d %8d %8d %8d\n", + seq_printf(m, "fine_exp: %8d %8d %8d %8d\n", cam->params.exposure.fineExp*2, 0, tmp, 0); if (cam->params.version.firmwareVersion == 1 && cam->params.version.firmwareRevision == 2) @@ -405,127 +401,122 @@ static int cpia_read_proc(char *page, char **start, off_t off, else tmp = MAX_EXP; - out += sprintf(out, "coarse_exp: %8d %8d %8d" + seq_printf(m, "coarse_exp: %8d %8d %8d" " %8d\n", cam->params.exposure.coarseExpLo+ 256*cam->params.exposure.coarseExpHi, 0, tmp, 185); - out += sprintf(out, "red_comp: %8d %8d %8d %8d\n", + seq_printf(m, "red_comp: %8d %8d %8d %8d\n", cam->params.exposure.redComp, COMP_RED, 255, COMP_RED); - out += sprintf(out, "green1_comp: %8d %8d %8d %8d\n", + seq_printf(m, "green1_comp: %8d %8d %8d %8d\n", cam->params.exposure.green1Comp, COMP_GREEN1, 255, COMP_GREEN1); - out += sprintf(out, "green2_comp: %8d %8d %8d %8d\n", + seq_printf(m, "green2_comp: %8d %8d %8d %8d\n", cam->params.exposure.green2Comp, COMP_GREEN2, 255, COMP_GREEN2); - out += sprintf(out, "blue_comp: %8d %8d %8d %8d\n", + seq_printf(m, "blue_comp: %8d %8d %8d %8d\n", cam->params.exposure.blueComp, COMP_BLUE, 255, COMP_BLUE); - out += sprintf(out, "apcor_gain1: %#8x %#8x %#8x %#8x\n", + seq_printf(m, "apcor_gain1: %#8x %#8x %#8x %#8x\n", cam->params.apcor.gain1, 0, 0xff, 0x1c); - out += sprintf(out, "apcor_gain2: %#8x %#8x %#8x %#8x\n", + seq_printf(m, "apcor_gain2: %#8x %#8x %#8x %#8x\n", cam->params.apcor.gain2, 0, 0xff, 0x1a); - out += sprintf(out, "apcor_gain4: %#8x %#8x %#8x %#8x\n", + seq_printf(m, "apcor_gain4: %#8x %#8x %#8x %#8x\n", cam->params.apcor.gain4, 0, 0xff, 0x2d); - out += sprintf(out, "apcor_gain8: %#8x %#8x %#8x %#8x\n", + seq_printf(m, "apcor_gain8: %#8x %#8x %#8x %#8x\n", cam->params.apcor.gain8, 0, 0xff, 0x2a); - out += sprintf(out, "vl_offset_gain1: %8d %8d %8d %8d\n", + seq_printf(m, "vl_offset_gain1: %8d %8d %8d %8d\n", cam->params.vlOffset.gain1, 0, 255, 24); - out += sprintf(out, "vl_offset_gain2: %8d %8d %8d %8d\n", + seq_printf(m, "vl_offset_gain2: %8d %8d %8d %8d\n", cam->params.vlOffset.gain2, 0, 255, 28); - out += sprintf(out, "vl_offset_gain4: %8d %8d %8d %8d\n", + seq_printf(m, "vl_offset_gain4: %8d %8d %8d %8d\n", cam->params.vlOffset.gain4, 0, 255, 30); - out += sprintf(out, "vl_offset_gain8: %8d %8d %8d %8d\n", + seq_printf(m, "vl_offset_gain8: %8d %8d %8d %8d\n", cam->params.vlOffset.gain8, 0, 255, 30); - out += sprintf(out, "flicker_control: %8s %8s %8s %8s\n", + seq_printf(m, "flicker_control: %8s %8s %8s %8s\n", cam->params.flickerControl.flickerMode ? "on" : "off", "off", "on", "off"); - out += sprintf(out, "mains_frequency: %8d %8d %8d %8d" + seq_printf(m, "mains_frequency: %8d %8d %8d %8d" " only 50/60\n", cam->mainsFreq ? 60 : 50, 50, 60, 50); if(cam->params.flickerControl.allowableOverExposure < 0) - out += sprintf(out, "allowable_overexposure: %4dauto auto %8d auto\n", + seq_printf(m, "allowable_overexposure: %4dauto auto %8d auto\n", -cam->params.flickerControl.allowableOverExposure, 255); else - out += sprintf(out, "allowable_overexposure: %8d auto %8d auto\n", + seq_printf(m, "allowable_overexposure: %8d auto %8d auto\n", cam->params.flickerControl.allowableOverExposure, 255); - out += sprintf(out, "compression_mode: "); + seq_printf(m, "compression_mode: "); switch(cam->params.compression.mode) { case CPIA_COMPRESSION_NONE: - out += sprintf(out, "%8s", "none"); + seq_printf(m, "%8s", "none"); break; case CPIA_COMPRESSION_AUTO: - out += sprintf(out, "%8s", "auto"); + seq_printf(m, "%8s", "auto"); break; case CPIA_COMPRESSION_MANUAL: - out += sprintf(out, "%8s", "manual"); + seq_printf(m, "%8s", "manual"); break; default: - out += sprintf(out, "%8s", "unknown"); + seq_printf(m, "%8s", "unknown"); break; } - out += sprintf(out, " none,auto,manual auto\n"); - out += sprintf(out, "decimation_enable: %8s %8s %8s %8s\n", + seq_printf(m, " none,auto,manual auto\n"); + seq_printf(m, "decimation_enable: %8s %8s %8s %8s\n", cam->params.compression.decimation == DECIMATION_ENAB ? "on":"off", "off", "on", "off"); - out += sprintf(out, "compression_target: %9s %9s %9s %9s\n", + seq_printf(m, "compression_target: %9s %9s %9s %9s\n", cam->params.compressionTarget.frTargeting == CPIA_COMPRESSION_TARGET_FRAMERATE ? "framerate":"quality", "framerate", "quality", "quality"); - out += sprintf(out, "target_framerate: %8d %8d %8d %8d\n", + seq_printf(m, "target_framerate: %8d %8d %8d %8d\n", cam->params.compressionTarget.targetFR, 1, 30, 15); - out += sprintf(out, "target_quality: %8d %8d %8d %8d\n", + seq_printf(m, "target_quality: %8d %8d %8d %8d\n", cam->params.compressionTarget.targetQ, 1, 64, 5); - out += sprintf(out, "y_threshold: %8d %8d %8d %8d\n", + seq_printf(m, "y_threshold: %8d %8d %8d %8d\n", cam->params.yuvThreshold.yThreshold, 0, 31, 6); - out += sprintf(out, "uv_threshold: %8d %8d %8d %8d\n", + seq_printf(m, "uv_threshold: %8d %8d %8d %8d\n", cam->params.yuvThreshold.uvThreshold, 0, 31, 6); - out += sprintf(out, "hysteresis: %8d %8d %8d %8d\n", + seq_printf(m, "hysteresis: %8d %8d %8d %8d\n", cam->params.compressionParams.hysteresis, 0, 255, 3); - out += sprintf(out, "threshold_max: %8d %8d %8d %8d\n", + seq_printf(m, "threshold_max: %8d %8d %8d %8d\n", cam->params.compressionParams.threshMax, 0, 255, 11); - out += sprintf(out, "small_step: %8d %8d %8d %8d\n", + seq_printf(m, "small_step: %8d %8d %8d %8d\n", cam->params.compressionParams.smallStep, 0, 255, 1); - out += sprintf(out, "large_step: %8d %8d %8d %8d\n", + seq_printf(m, "large_step: %8d %8d %8d %8d\n", cam->params.compressionParams.largeStep, 0, 255, 3); - out += sprintf(out, "decimation_hysteresis: %8d %8d %8d %8d\n", + seq_printf(m, "decimation_hysteresis: %8d %8d %8d %8d\n", cam->params.compressionParams.decimationHysteresis, 0, 255, 2); - out += sprintf(out, "fr_diff_step_thresh: %8d %8d %8d %8d\n", + seq_printf(m, "fr_diff_step_thresh: %8d %8d %8d %8d\n", cam->params.compressionParams.frDiffStepThresh, 0, 255, 5); - out += sprintf(out, "q_diff_step_thresh: %8d %8d %8d %8d\n", + seq_printf(m, "q_diff_step_thresh: %8d %8d %8d %8d\n", cam->params.compressionParams.qDiffStepThresh, 0, 255, 3); - out += sprintf(out, "decimation_thresh_mod: %8d %8d %8d %8d\n", + seq_printf(m, "decimation_thresh_mod: %8d %8d %8d %8d\n", cam->params.compressionParams.decimationThreshMod, 0, 255, 2); /* QX3 specific entries */ if (cam->params.qx3.qx3_detected) { - out += sprintf(out, "toplight: %8s %8s %8s %8s\n", + seq_printf(m, "toplight: %8s %8s %8s %8s\n", cam->params.qx3.toplight ? "on" : "off", "off", "on", "off"); - out += sprintf(out, "bottomlight: %8s %8s %8s %8s\n", + seq_printf(m, "bottomlight: %8s %8s %8s %8s\n", cam->params.qx3.bottomlight ? "on" : "off", "off", "on", "off"); } - len = out - page; - len -= off; - if (len < count) { - *eof = 1; - if (len <= 0) return 0; - } else - len = count; - - *start = page + off; - return len; + return 0; } +static int cpia_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, cpia_proc_show, PDE(inode)->data); +} -static int match(char *checkstr, char **buffer, unsigned long *count, +static int match(char *checkstr, char **buffer, size_t *count, int *find_colon, int *err) { int ret, colon_found = 1; @@ -551,7 +542,7 @@ static int match(char *checkstr, char **buffer, unsigned long *count, return ret; } -static unsigned long int value(char **buffer, unsigned long *count, int *err) +static unsigned long int value(char **buffer, size_t *count, int *err) { char *p; unsigned long int ret; @@ -565,10 +556,10 @@ static unsigned long int value(char **buffer, unsigned long *count, int *err) return ret; } -static int cpia_write_proc(struct file *file, const char __user *buf, - unsigned long count, void *data) +static ssize_t cpia_proc_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) { - struct cam_data *cam = data; + struct cam_data *cam = PDE(file->f_path.dentry->d_inode)->data; struct cam_params new_params; char *page, *buffer; int retval, find_colon; @@ -582,7 +573,7 @@ static int cpia_write_proc(struct file *file, const char __user *buf, * from the comx driver */ if (count > PAGE_SIZE) { - printk(KERN_ERR "count is %lu > %d!!!\n", count, (int)PAGE_SIZE); + printk(KERN_ERR "count is %zu > %d!!!\n", count, (int)PAGE_SIZE); return -ENOSPC; } @@ -1340,6 +1331,15 @@ out: return retval; } +static const struct file_operations cpia_proc_fops = { + .owner = THIS_MODULE, + .open = cpia_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = cpia_proc_write, +}; + static void create_proc_cpia_cam(struct cam_data *cam) { struct proc_dir_entry *ent; @@ -1347,14 +1347,12 @@ static void create_proc_cpia_cam(struct cam_data *cam) if (!cpia_proc_root || !cam) return; - ent = create_proc_entry(video_device_node_name(&cam->vdev), - S_IFREG|S_IRUGO|S_IWUSR, cpia_proc_root); + ent = proc_create_data(video_device_node_name(&cam->vdev), + S_IRUGO|S_IWUSR, cpia_proc_root, + &cpia_proc_fops, cam); if (!ent) return; - ent->data = cam; - ent->read_proc = cpia_read_proc; - ent->write_proc = cpia_write_proc; /* size of the proc entry is 3736 bytes for the standard webcam; the extra features of the QX3 microscope add 189 bytes. -- cgit v1.2.3-70-g09d2 From d995a18733a683c1c086a4d48315976f8c25d89b Mon Sep 17 00:00:00 2001 From: Lukas Karas Date: Tue, 24 Nov 2009 12:06:52 -0300 Subject: V4L/DVB (13591): add support for IR on FlyDVB Trio (saa7134) saa7134: Add support for IR reciever on card LifeView FlyDVB Trio -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html [mchehab@redhat.com: CodingStyle fixes and ported upstream] Tested-by: Petr Fiala Signed-off-by: Lukas Karas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ir-kbd-i2c.c | 3 +- drivers/media/video/saa7134/saa7134-cards.c | 22 ++++++++++ drivers/media/video/saa7134/saa7134-input.c | 62 +++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 64360d26b32..2856e780772 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -353,6 +353,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) ir_type = IR_TYPE_RC5; ir_codes = &ir_codes_fusionhdtv_mce_table; break; + case 0x0b: case 0x47: case 0x71: if (adap->id == I2C_HW_B_CX2388x || @@ -422,7 +423,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Make sure we are all setup before going on */ if (!name || !ir->get_key || !ir_type || !ir_codes) { - dprintk(1, DEVNAME ": Unsupported device at address 0x%02x\n", + dprintk(1, ": Unsupported device at address 0x%02x\n", addr); err = -ENODEV; goto err_out_free; diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 7e40d6d99dd..03f572708b8 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -7211,9 +7211,31 @@ int saa7134_board_init2(struct saa7134_dev *dev) } case SAA7134_BOARD_FLYDVB_TRIO: { + u8 temp = 0; + int rc; u8 data[] = { 0x3c, 0x33, 0x62}; struct i2c_msg msg = {.addr=0x09, .flags=0, .buf=data, .len = sizeof(data)}; i2c_transfer(&dev->i2c_adap, &msg, 1); + + /* + * send weak up message to pic16C505 chip + * @ LifeView FlyDVB Trio + */ + msg.buf = &temp; + msg.addr = 0x0b; + msg.len = 1; + if (1 != i2c_transfer(&dev->i2c_adap, &msg, 1)) { + printk(KERN_WARNING "%s: send wake up byte to pic16C505" + "(IR chip) failed\n", dev->name); + } else { + msg.flags = I2C_M_RD; + rc = i2c_transfer(&dev->i2c_adap, &msg, 1); + printk(KERN_INFO "%s: probe IR chip @ i2c 0x%02x: %s\n", + dev->name, msg.addr, + (1 == rc) ? "yes" : "no"); + if (rc == 1) + dev->has_remote = SAA7134_REMOTE_I2C; + } break; } case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 744918b1cd4..411a8410620 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -127,6 +127,61 @@ static int build_key(struct saa7134_dev *dev) /* --------------------- Chip specific I2C key builders ----------------- */ +static int get_key_flydvb_trio(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) +{ + int gpio; + int attempt = 0; + unsigned char b; + + /* We need this to access GPI Used by the saa_readl macro. */ + struct saa7134_dev *dev = ir->c->adapter->algo_data; + + if (dev == NULL) { + dprintk("get_key_flydvb_trio: " + "gir->c->adapter->algo_data is NULL!\n"); + return -EIO; + } + + /* rising SAA7134_GPIGPRESCAN reads the status */ + saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); + saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); + + gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2); + + if (0x40000 & ~gpio) + return 0; /* No button press */ + + /* No button press - only before first key pressed */ + if (b == 0xFF) + return 0; + + /* poll IR chip */ + /* weak up the IR chip */ + b = 0; + + while (1 != i2c_master_send(ir->c, &b, 1)) { + if ((attempt++) < 10) { + /* + * wait a bit for next attempt - + * I don't know how make it better + */ + msleep(10); + continue; + } + i2cdprintk("send wake up byte to pic16C505 (IR chip)" + "failed %dx\n", attempt); + return -EIO; + } + if (1 != i2c_master_recv(ir->c, &b, 1)) { + i2cdprintk("read error\n"); + return -EIO; + } + + *ir_key = b; + *ir_raw = b; + return 1; +} + static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) { @@ -622,6 +677,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) mask_keyup = 0x020000; polling = 50; /* ms */ break; + break; } if (NULL == ir_codes) { printk("%s: Oops: IR config error [card=%d]\n", @@ -788,6 +844,12 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: info.addr = 0x40; break; + case SAA7134_BOARD_FLYDVB_TRIO: + dev->init_data.name = "FlyDVB Trio"; + dev->init_data.get_key = get_key_flydvb_trio; + dev->init_data.ir_codes = &ir_codes_flydvb_table; + info.addr = 0x0b; + break; default: dprintk("No I2C IR support for board %x\n", dev->board); return; -- cgit v1.2.3-70-g09d2 From 38ffcd10d6831efd15ec5a223b1050eac12d4c28 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Mon, 30 Nov 2009 14:14:36 -0300 Subject: V4L/DVB (13581): DiBUSB: fix I2c access when there is a read-access w/o write sequence This patch fixes the behaviour of the dibusb-i2c-access which was previously changed to avoid accidental EEprom writes: Now it allow i2c-reads without prepended i2c-writes, but it is still not doing anything in case the EEprom is addressed. Thanks to Mario Bachmann for testing. Tested-by: Mario Bachmann Cc: Mario Bachmann Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dibusb-common.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c index b395e852e47..9143b5631e8 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/drivers/media/dvb/dvb-usb/dibusb-common.c @@ -142,8 +142,13 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num } else if ((msg[i].flags & I2C_M_RD) == 0) { if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0) break; - } else - break; + } else if (msg[i].addr != 0x50) { + /* 0x50 is the address of the eeprom - we need to protect it + * from dibusb's bad i2c implementation: reads without + * writing the offset before are forbidden */ + if (dibusb_i2c_msg(d, msg[i].addr, NULL, 0, msg[i].buf, msg[i].len) < 0) + break; + } } mutex_unlock(&d->i2c_mutex); -- cgit v1.2.3-70-g09d2 From 4315c414474cf43994f0c562ce8faea3628f550b Mon Sep 17 00:00:00 2001 From: Andrea Odetti Date: Thu, 10 Dec 2009 16:26:10 -0300 Subject: V4L/DVB (13593): PWC: parameter trace is only available in debug This patch fixes a small issue where modinfo says the parameter "trace" is always available, while it only works if CONFIG_USB_PWC_DEBUG is enabled. Signed-off-by: Andrea Odetti Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pwc/pwc-if.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index d0e2b57f174..aea7e224cef 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -1947,7 +1947,9 @@ MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30"); MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve"); MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers"); +#ifdef CONFIG_USB_PWC_DEBUG MODULE_PARM_DESC(trace, "For debugging purposes"); +#endif MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off"); MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)"); MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); -- cgit v1.2.3-70-g09d2 From cb63c2aad232930da8c8b5c5020dd560cb885cf5 Mon Sep 17 00:00:00 2001 From: Thiago Farina Date: Thu, 10 Dec 2009 16:40:50 -0300 Subject: V4L/DVB (13594): cpia2: use __stringify macro. Replace MAKE_STRING to __stringify macro Signed-off-by: Thiago Farina Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cpia2/cpia2_v4l.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c index 30d39b15fd4..6f91415eb7b 100644 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ b/drivers/media/video/cpia2/cpia2_v4l.c @@ -38,17 +38,12 @@ #include #include #include +#include #include #include "cpia2.h" #include "cpia2dev.h" - -//#define _CPIA2_DEBUG_ - -#define MAKE_STRING_1(x) #x -#define MAKE_STRING(x) MAKE_STRING_1(x) - static int video_nr = -1; module_param(video_nr, int, 0); MODULE_PARM_DESC(video_nr,"video device to register (0=/dev/video0, etc)"); @@ -60,26 +55,26 @@ MODULE_PARM_DESC(buffer_size, "Size for each frame buffer in bytes (default 68k) static int num_buffers = 3; module_param(num_buffers, int, 0); MODULE_PARM_DESC(num_buffers, "Number of frame buffers (1-" - MAKE_STRING(VIDEO_MAX_FRAME) ", default 3)"); + __stringify(VIDEO_MAX_FRAME) ", default 3)"); static int alternate = DEFAULT_ALT; module_param(alternate, int, 0); -MODULE_PARM_DESC(alternate, "USB Alternate (" MAKE_STRING(USBIF_ISO_1) "-" - MAKE_STRING(USBIF_ISO_6) ", default " - MAKE_STRING(DEFAULT_ALT) ")"); +MODULE_PARM_DESC(alternate, "USB Alternate (" __stringify(USBIF_ISO_1) "-" + __stringify(USBIF_ISO_6) ", default " + __stringify(DEFAULT_ALT) ")"); static int flicker_freq = 60; module_param(flicker_freq, int, 0); -MODULE_PARM_DESC(flicker_freq, "Flicker frequency (" MAKE_STRING(50) "or" - MAKE_STRING(60) ", default " - MAKE_STRING(60) ")"); +MODULE_PARM_DESC(flicker_freq, "Flicker frequency (" __stringify(50) "or" + __stringify(60) ", default " + __stringify(60) ")"); static int flicker_mode = NEVER_FLICKER; module_param(flicker_mode, int, 0); MODULE_PARM_DESC(flicker_mode, - "Flicker supression (" MAKE_STRING(NEVER_FLICKER) "or" - MAKE_STRING(ANTI_FLICKER_ON) ", default " - MAKE_STRING(NEVER_FLICKER) ")"); + "Flicker supression (" __stringify(NEVER_FLICKER) "or" + __stringify(ANTI_FLICKER_ON) ", default " + __stringify(NEVER_FLICKER) ")"); MODULE_AUTHOR("Steve Miller (STMicroelectronics) "); MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras"); -- cgit v1.2.3-70-g09d2 From 50e9d31183ed61c787b870cb3ee8f6c3db8c8a1e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 10 Dec 2009 16:44:51 -0300 Subject: V4L/DVB (13596): ov511.c typo: lock => unlock This was found with a static checker and has not been tested, but it seems pretty clear that the mutex_lock() was supposed to be mutex_unlock() Signed-off-by: Dan Carpenter Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ov511.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index c71865dcf48..e0bce8dc74b 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c @@ -5877,7 +5877,7 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) goto error; } - mutex_lock(&ov->lock); + mutex_unlock(&ov->lock); return 0; -- cgit v1.2.3-70-g09d2 From 0d94e29459d372b6c5dda964a8b35a8d40050ca7 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Thu, 10 Dec 2009 16:46:06 -0300 Subject: V4L/DVB (13597): bttv: add i2c addr for old WinTV card to IR probe list There are old bttv-driven Hauppauge WinTV series cards that have their IR part at i2c addr 0x71, which doesn't get considered in the new 2.6.31 i2c code. From a 2.6.29 kernel: lirc_i2c: chip 0x10005 found @ 0x71 (Hauppauge PVR150) Minor cosmetic glitch, the card in question isn't actually a PVR-150, its: 03:06.0 Multimedia video controller: Brooktree Corporation Bt878 Video Capture (rev 11) Subsystem: Hauppauge computer works Inc. WinTV Series Flags: bus master, medium devsel, latency 32, IRQ 19 Memory at f4ffe000 (32-bit, prefetchable) [size=4K] Capabilities: [44] Vital Product Data Capabilities: [4c] Power Management version 2 Kernel driver in use: bttv Kernel modules: bttv Device ID: 0x109e:0x036e, Sub-Device ID: 0x0070:0x13eb This simply adds 0x71 to the list of addresses i2c_new_probed_device should consider, which gets IR working on this card again. Reported-by: Adam Williamson Tested-by: Adam Williamson Signed-off-by: Jarod Wilson Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bt8xx/bttv-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c index beda363418b..a9d9ee73b25 100644 --- a/drivers/media/video/bt8xx/bttv-i2c.c +++ b/drivers/media/video/bt8xx/bttv-i2c.c @@ -400,7 +400,7 @@ int __devinit init_bttv_i2c(struct bttv *btv) That's why we probe 0x1a (~0x34) first. CB */ const unsigned short addr_list[] = { - 0x1a, 0x18, 0x4b, 0x64, 0x30, + 0x1a, 0x18, 0x4b, 0x64, 0x30, 0x71, I2C_CLIENT_END }; -- cgit v1.2.3-70-g09d2 From 31bedfa5068936b15a388842be1d03cdd1bdfb07 Mon Sep 17 00:00:00 2001 From: Muralidharan Karicheri Date: Thu, 10 Dec 2009 16:47:48 -0300 Subject: V4L/DVB (13598): videobuf_dma_contig_user_get() for non-aligned offsets If a USERPTR address that is not aligned to page boundary is passed to the videobuf_dma_contig_user_get() function, it saves a page aligned address to the dma_handle. This is not correct. This issue is observed when using USERPTR IO machism for buffer exchange. Updates from last version:- Adding offset for size calculation as per comment from Magnus Damm. This ensures the last page is also included for checking if memory is contiguous. Signed-off-by: Muralidharan Karicheri Acked-by: Magnus Damm Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videobuf-dma-contig.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c index d25f28461da..22c01097e8a 100644 --- a/drivers/media/video/videobuf-dma-contig.c +++ b/drivers/media/video/videobuf-dma-contig.c @@ -141,9 +141,11 @@ static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem, struct vm_area_struct *vma; unsigned long prev_pfn, this_pfn; unsigned long pages_done, user_address; + unsigned int offset; int ret; - mem->size = PAGE_ALIGN(vb->size); + offset = vb->baddr & ~PAGE_MASK; + mem->size = PAGE_ALIGN(vb->size + offset); mem->is_userptr = 0; ret = -EINVAL; @@ -166,7 +168,7 @@ static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem, break; if (pages_done == 0) - mem->dma_handle = this_pfn << PAGE_SHIFT; + mem->dma_handle = (this_pfn << PAGE_SHIFT) + offset; else if (this_pfn != (prev_pfn + 1)) ret = -EFAULT; -- cgit v1.2.3-70-g09d2 From 1aa925c957d37e077edb1de4553481734b8462cf Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Thu, 10 Dec 2009 16:49:34 -0300 Subject: V4L/DVB (13599): radio-si470x: move some file operations to common file The read and poll file operations of the si470x usb driver can be used also equally on the si470x i2c driver, so they go to the common file. Signed-off-by: Joonyoung Shim Acked-by: Tobias Lorenz Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/si470x/radio-si470x-common.c | 98 ++++++++++++++++++++++++ drivers/media/radio/si470x/radio-si470x-i2c.c | 15 +--- drivers/media/radio/si470x/radio-si470x-usb.c | 97 +---------------------- drivers/media/radio/si470x/radio-si470x.h | 3 +- 4 files changed, 104 insertions(+), 109 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c index f33315f2c54..4da0f150c6e 100644 --- a/drivers/media/radio/si470x/radio-si470x-common.c +++ b/drivers/media/radio/si470x/radio-si470x-common.c @@ -425,6 +425,104 @@ int si470x_rds_on(struct si470x_device *radio) +/************************************************************************** + * File Operations Interface + **************************************************************************/ + +/* + * si470x_fops_read - read RDS data + */ +static ssize_t si470x_fops_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct si470x_device *radio = video_drvdata(file); + int retval = 0; + unsigned int block_count = 0; + + /* switch on rds reception */ + if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) + si470x_rds_on(radio); + + /* block if no new data available */ + while (radio->wr_index == radio->rd_index) { + if (file->f_flags & O_NONBLOCK) { + retval = -EWOULDBLOCK; + goto done; + } + if (wait_event_interruptible(radio->read_queue, + radio->wr_index != radio->rd_index) < 0) { + retval = -EINTR; + goto done; + } + } + + /* calculate block count from byte count */ + count /= 3; + + /* copy RDS block out of internal buffer and to user buffer */ + mutex_lock(&radio->lock); + while (block_count < count) { + if (radio->rd_index == radio->wr_index) + break; + + /* always transfer rds complete blocks */ + if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3)) + /* retval = -EFAULT; */ + break; + + /* increment and wrap read pointer */ + radio->rd_index += 3; + if (radio->rd_index >= radio->buf_size) + radio->rd_index = 0; + + /* increment counters */ + block_count++; + buf += 3; + retval += 3; + } + mutex_unlock(&radio->lock); + +done: + return retval; +} + + +/* + * si470x_fops_poll - poll RDS data + */ +static unsigned int si470x_fops_poll(struct file *file, + struct poll_table_struct *pts) +{ + struct si470x_device *radio = video_drvdata(file); + int retval = 0; + + /* switch on rds reception */ + if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) + si470x_rds_on(radio); + + poll_wait(file, &radio->read_queue, pts); + + if (radio->rd_index != radio->wr_index) + retval = POLLIN | POLLRDNORM; + + return retval; +} + + +/* + * si470x_fops - file operations interface + */ +static const struct v4l2_file_operations si470x_fops = { + .owner = THIS_MODULE, + .read = si470x_fops_read, + .poll = si470x_fops_poll, + .ioctl = video_ioctl2, + .open = si470x_fops_open, + .release = si470x_fops_release, +}; + + + /************************************************************************** * Video4Linux Interface **************************************************************************/ diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c index 2d53b6a9409..4816a6d501c 100644 --- a/drivers/media/radio/si470x/radio-si470x-i2c.c +++ b/drivers/media/radio/si470x/radio-si470x-i2c.c @@ -173,7 +173,7 @@ int si470x_disconnect_check(struct si470x_device *radio) /* * si470x_fops_open - file open */ -static int si470x_fops_open(struct file *file) +int si470x_fops_open(struct file *file) { struct si470x_device *radio = video_drvdata(file); int retval = 0; @@ -194,7 +194,7 @@ static int si470x_fops_open(struct file *file) /* * si470x_fops_release - file release */ -static int si470x_fops_release(struct file *file) +int si470x_fops_release(struct file *file) { struct si470x_device *radio = video_drvdata(file); int retval = 0; @@ -215,17 +215,6 @@ static int si470x_fops_release(struct file *file) } -/* - * si470x_fops - file operations interface - */ -const struct v4l2_file_operations si470x_fops = { - .owner = THIS_MODULE, - .ioctl = video_ioctl2, - .open = si470x_fops_open, - .release = si470x_fops_release, -}; - - /************************************************************************** * Video4Linux Interface diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c index f2d0e1ddb30..a96e1b9dd64 100644 --- a/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/drivers/media/radio/si470x/radio-si470x-usb.c @@ -508,90 +508,10 @@ resubmit: * File Operations Interface **************************************************************************/ -/* - * si470x_fops_read - read RDS data - */ -static ssize_t si470x_fops_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - struct si470x_device *radio = video_drvdata(file); - int retval = 0; - unsigned int block_count = 0; - - /* switch on rds reception */ - if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) - si470x_rds_on(radio); - - /* block if no new data available */ - while (radio->wr_index == radio->rd_index) { - if (file->f_flags & O_NONBLOCK) { - retval = -EWOULDBLOCK; - goto done; - } - if (wait_event_interruptible(radio->read_queue, - radio->wr_index != radio->rd_index) < 0) { - retval = -EINTR; - goto done; - } - } - - /* calculate block count from byte count */ - count /= 3; - - /* copy RDS block out of internal buffer and to user buffer */ - mutex_lock(&radio->lock); - while (block_count < count) { - if (radio->rd_index == radio->wr_index) - break; - - /* always transfer rds complete blocks */ - if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3)) - /* retval = -EFAULT; */ - break; - - /* increment and wrap read pointer */ - radio->rd_index += 3; - if (radio->rd_index >= radio->buf_size) - radio->rd_index = 0; - - /* increment counters */ - block_count++; - buf += 3; - retval += 3; - } - mutex_unlock(&radio->lock); - -done: - return retval; -} - - -/* - * si470x_fops_poll - poll RDS data - */ -static unsigned int si470x_fops_poll(struct file *file, - struct poll_table_struct *pts) -{ - struct si470x_device *radio = video_drvdata(file); - int retval = 0; - - /* switch on rds reception */ - if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) - si470x_rds_on(radio); - - poll_wait(file, &radio->read_queue, pts); - - if (radio->rd_index != radio->wr_index) - retval = POLLIN | POLLRDNORM; - - return retval; -} - - /* * si470x_fops_open - file open */ -static int si470x_fops_open(struct file *file) +int si470x_fops_open(struct file *file) { struct si470x_device *radio = video_drvdata(file); int retval; @@ -645,7 +565,7 @@ done: /* * si470x_fops_release - file release */ -static int si470x_fops_release(struct file *file) +int si470x_fops_release(struct file *file) { struct si470x_device *radio = video_drvdata(file); int retval = 0; @@ -688,19 +608,6 @@ done: } -/* - * si470x_fops - file operations interface - */ -const struct v4l2_file_operations si470x_fops = { - .owner = THIS_MODULE, - .read = si470x_fops_read, - .poll = si470x_fops_poll, - .ioctl = video_ioctl2, - .open = si470x_fops_open, - .release = si470x_fops_release, -}; - - /************************************************************************** * Video4Linux Interface diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h index d0af194d194..f646f79d2f7 100644 --- a/drivers/media/radio/si470x/radio-si470x.h +++ b/drivers/media/radio/si470x/radio-si470x.h @@ -212,7 +212,6 @@ struct si470x_device { /************************************************************************** * Common Functions **************************************************************************/ -extern const struct v4l2_file_operations si470x_fops; extern struct video_device si470x_viddev_template; int si470x_get_register(struct si470x_device *radio, int regnr); int si470x_set_register(struct si470x_device *radio, int regnr); @@ -221,5 +220,7 @@ int si470x_set_freq(struct si470x_device *radio, unsigned int freq); int si470x_start(struct si470x_device *radio); int si470x_stop(struct si470x_device *radio); int si470x_rds_on(struct si470x_device *radio); +int si470x_fops_open(struct file *file); +int si470x_fops_release(struct file *file); int si470x_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *capability); -- cgit v1.2.3-70-g09d2 From fe2137dd4e6e4b2f5e758765d5305e8dbb0d931c Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Thu, 10 Dec 2009 16:50:34 -0300 Subject: V4L/DVB (13600): radio-si470x: support RDS on si470x i2c driver This patch is to support RDS on si470x i2c driver. The routine of RDS operation is almost same with thing of usb driver, but this uses RDS interrupt. Signed-off-by: Joonyoung Shim Acked-by: Tobias Lorenz Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/si470x/radio-si470x-i2c.c | 164 ++++++++++++++++++++++++-- drivers/media/radio/si470x/radio-si470x.h | 1 + 2 files changed, 155 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c index 4816a6d501c..b8c0d5cda2f 100644 --- a/drivers/media/radio/si470x/radio-si470x-i2c.c +++ b/drivers/media/radio/si470x/radio-si470x-i2c.c @@ -22,22 +22,17 @@ */ -/* - * ToDo: - * - RDS support - */ - - /* driver definitions */ #define DRIVER_AUTHOR "Joonyoung Shim "; -#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 0) +#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 1) #define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver" #define DRIVER_DESC "I2C radio driver for Si470x FM Radio Receivers" -#define DRIVER_VERSION "1.0.0" +#define DRIVER_VERSION "1.0.1" /* kernel includes */ #include #include +#include #include "radio-si470x.h" @@ -62,6 +57,20 @@ static int radio_nr = -1; module_param(radio_nr, int, 0444); MODULE_PARM_DESC(radio_nr, "Radio Nr"); +/* RDS buffer blocks */ +static unsigned int rds_buf = 100; +module_param(rds_buf, uint, 0444); +MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*"); + +/* RDS maximum block errors */ +static unsigned short max_rds_errors = 1; +/* 0 means 0 errors requiring correction */ +/* 1 means 1-2 errors requiring correction (used by original USBRadio.exe) */ +/* 2 means 3-5 errors requiring correction */ +/* 3 means 6+ errors or errors in checkword, correction not possible */ +module_param(max_rds_errors, ushort, 0644); +MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*"); + /************************************************************************** @@ -181,12 +190,21 @@ int si470x_fops_open(struct file *file) mutex_lock(&radio->lock); radio->users++; - if (radio->users == 1) + if (radio->users == 1) { /* start radio */ retval = si470x_start(radio); + if (retval < 0) + goto done; + + /* enable RDS interrupt */ + radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDSIEN; + radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_GPIO2; + radio->registers[SYSCONFIG1] |= 0x1 << 2; + retval = si470x_set_register(radio, SYSCONFIG1); + } +done: mutex_unlock(&radio->lock); - return retval; } @@ -241,6 +259,105 @@ int si470x_vidioc_querycap(struct file *file, void *priv, * I2C Interface **************************************************************************/ +/* + * si470x_i2c_interrupt_work - rds processing function + */ +static void si470x_i2c_interrupt_work(struct work_struct *work) +{ + struct si470x_device *radio = container_of(work, + struct si470x_device, radio_work); + unsigned char regnr; + unsigned char blocknum; + unsigned short bler; /* rds block errors */ + unsigned short rds; + unsigned char tmpbuf[3]; + int retval = 0; + + /* safety checks */ + if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) + return; + + /* Update RDS registers */ + for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) { + retval = si470x_get_register(radio, STATUSRSSI + regnr); + if (retval < 0) + return; + } + + /* get rds blocks */ + if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0) + /* No RDS group ready, better luck next time */ + return; + + for (blocknum = 0; blocknum < 4; blocknum++) { + switch (blocknum) { + default: + bler = (radio->registers[STATUSRSSI] & + STATUSRSSI_BLERA) >> 9; + rds = radio->registers[RDSA]; + break; + case 1: + bler = (radio->registers[READCHAN] & + READCHAN_BLERB) >> 14; + rds = radio->registers[RDSB]; + break; + case 2: + bler = (radio->registers[READCHAN] & + READCHAN_BLERC) >> 12; + rds = radio->registers[RDSC]; + break; + case 3: + bler = (radio->registers[READCHAN] & + READCHAN_BLERD) >> 10; + rds = radio->registers[RDSD]; + break; + }; + + /* Fill the V4L2 RDS buffer */ + put_unaligned_le16(rds, &tmpbuf); + tmpbuf[2] = blocknum; /* offset name */ + tmpbuf[2] |= blocknum << 3; /* received offset */ + if (bler > max_rds_errors) + tmpbuf[2] |= 0x80; /* uncorrectable errors */ + else if (bler > 0) + tmpbuf[2] |= 0x40; /* corrected error(s) */ + + /* copy RDS block to internal buffer */ + memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3); + radio->wr_index += 3; + + /* wrap write pointer */ + if (radio->wr_index >= radio->buf_size) + radio->wr_index = 0; + + /* check for overflow */ + if (radio->wr_index == radio->rd_index) { + /* increment and wrap read pointer */ + radio->rd_index += 3; + if (radio->rd_index >= radio->buf_size) + radio->rd_index = 0; + } + } + + if (radio->wr_index != radio->rd_index) + wake_up_interruptible(&radio->read_queue); +} + + +/* + * si470x_i2c_interrupt - interrupt handler + */ +static irqreturn_t si470x_i2c_interrupt(int irq, void *dev_id) +{ + struct si470x_device *radio = dev_id; + + if (!work_pending(&radio->radio_work)) + schedule_work(&radio->radio_work); + + return IRQ_HANDLED; +} + + /* * si470x_i2c_probe - probe for the device */ @@ -257,6 +374,8 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client, retval = -ENOMEM; goto err_initial; } + + INIT_WORK(&radio->radio_work, si470x_i2c_interrupt_work); radio->users = 0; radio->client = client; mutex_init(&radio->lock); @@ -308,6 +427,26 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client, /* set initial frequency */ si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */ + /* rds buffer allocation */ + radio->buf_size = rds_buf * 3; + radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); + if (!radio->buffer) { + retval = -EIO; + goto err_video; + } + + /* rds buffer configuration */ + radio->wr_index = 0; + radio->rd_index = 0; + init_waitqueue_head(&radio->read_queue); + + retval = request_irq(client->irq, si470x_i2c_interrupt, + IRQF_TRIGGER_FALLING, DRIVER_NAME, radio); + if (retval) { + dev_err(&client->dev, "Failed to register interrupt\n"); + goto err_rds; + } + /* register video device */ retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); @@ -319,6 +458,9 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client, return 0; err_all: + free_irq(client->irq, radio); +err_rds: + kfree(radio->buffer); err_video: video_device_release(radio->videodev); err_radio: @@ -335,6 +477,8 @@ static __devexit int si470x_i2c_remove(struct i2c_client *client) { struct si470x_device *radio = i2c_get_clientdata(client); + free_irq(client->irq, radio); + cancel_work_sync(&radio->radio_work); video_unregister_device(radio->videodev); kfree(radio); i2c_set_clientdata(client, NULL); diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h index f646f79d2f7..29e05cf5347 100644 --- a/drivers/media/radio/si470x/radio-si470x.h +++ b/drivers/media/radio/si470x/radio-si470x.h @@ -181,6 +181,7 @@ struct si470x_device { #if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE) struct i2c_client *client; + struct work_struct radio_work; #endif }; -- cgit v1.2.3-70-g09d2 From d1471f02dfb5b3424ee3afb6459d8cb97730af76 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Thu, 10 Dec 2009 16:52:50 -0300 Subject: V4L/DVB (13601): radio-si470x: support PM functions This patch is to support PM of the si470x i2c driver. Signed-off-by: Joonyoung Shim Acked-by: Tobias Lorenz Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/si470x/radio-si470x-i2c.c | 40 +++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c index b8c0d5cda2f..5466015346a 100644 --- a/drivers/media/radio/si470x/radio-si470x-i2c.c +++ b/drivers/media/radio/si470x/radio-si470x-i2c.c @@ -487,6 +487,44 @@ static __devexit int si470x_i2c_remove(struct i2c_client *client) } +#ifdef CONFIG_PM +/* + * si470x_i2c_suspend - suspend the device + */ +static int si470x_i2c_suspend(struct i2c_client *client, pm_message_t mesg) +{ + struct si470x_device *radio = i2c_get_clientdata(client); + + /* power down */ + radio->registers[POWERCFG] |= POWERCFG_DISABLE; + if (si470x_set_register(radio, POWERCFG) < 0) + return -EIO; + + return 0; +} + + +/* + * si470x_i2c_resume - resume the device + */ +static int si470x_i2c_resume(struct i2c_client *client) +{ + struct si470x_device *radio = i2c_get_clientdata(client); + + /* power up : need 110ms */ + radio->registers[POWERCFG] |= POWERCFG_ENABLE; + if (si470x_set_register(radio, POWERCFG) < 0) + return -EIO; + msleep(110); + + return 0; +} +#else +#define si470x_i2c_suspend NULL +#define si470x_i2c_resume NULL +#endif + + /* * si470x_i2c_driver - i2c driver interface */ @@ -497,6 +535,8 @@ static struct i2c_driver si470x_i2c_driver = { }, .probe = si470x_i2c_probe, .remove = __devexit_p(si470x_i2c_remove), + .suspend = si470x_i2c_suspend, + .resume = si470x_i2c_resume, .id_table = si470x_i2c_id, }; -- cgit v1.2.3-70-g09d2 From 0a25f3b292c5c70de80d2b1f1cf3f5b9aae91b86 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Thu, 10 Dec 2009 16:54:48 -0300 Subject: V4L/DVB (13602): bttv: fix MODULE_PARM_DESC for i2c_debug and i2c_hw Currently, i2c_debug shows up w/o a desc in modinfo, and i2c_hw shows up with i2c_debug's desc. Fix that. [dougsland@redhat.com: fixed checkpatch.pl warning (space between MODULE_PARM_DESC arguments)] Signed-off-by: Jarod Wilson Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bt8xx/bttv-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c index a9d9ee73b25..63aa31a041e 100644 --- a/drivers/media/video/bt8xx/bttv-i2c.c +++ b/drivers/media/video/bt8xx/bttv-i2c.c @@ -40,7 +40,7 @@ static int i2c_debug; static int i2c_hw; static int i2c_scan; module_param(i2c_debug, int, 0644); -MODULE_PARM_DESC(i2c_hw,"configure i2c debug level"); +MODULE_PARM_DESC(i2c_debug, "configure i2c debug level"); module_param(i2c_hw, int, 0444); MODULE_PARM_DESC(i2c_hw,"force use of hardware i2c support, " "instead of software bitbang"); -- cgit v1.2.3-70-g09d2 From f68fdb9a8c3d4bc245752f4d312f7035063ab64e Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 10 Dec 2009 16:59:02 -0300 Subject: V4L/DVB (13604): vpss: move vpss_remove to .devexit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function vpss_remove is used only wrapped by __devexit_p so define it using __devexit. Signed-off-by: Uwe Kleine-König Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/davinci/vpss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/davinci/vpss.c b/drivers/media/video/davinci/vpss.c index 453236bd755..7ee72ecd3d8 100644 --- a/drivers/media/video/davinci/vpss.c +++ b/drivers/media/video/davinci/vpss.c @@ -268,7 +268,7 @@ fail1: return status; } -static int vpss_remove(struct platform_device *pdev) +static int __devexit vpss_remove(struct platform_device *pdev) { iounmap(oper_cfg.vpss_bl_regs_base); release_mem_region(oper_cfg.r1->start, oper_cfg.len1); -- cgit v1.2.3-70-g09d2 From 50e55fd13fcf2d098e2b969c9d1bc270ae5f8b12 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 10 Dec 2009 17:00:13 -0300 Subject: V4L/DVB (13605): sh_mobile_ceu_camera: don't use __exit_p to wrap sh_mobile_ceu_remove MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function sh_mobile_ceu_remove is defined using __devexit, so don't use __exit_p but __devexit_p to wrap it. Signed-off-by: Uwe Kleine-König Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/sh_mobile_ceu_camera.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 961e4484d72..7509990c65d 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -1836,7 +1836,7 @@ static struct platform_driver sh_mobile_ceu_driver = { .pm = &sh_mobile_ceu_dev_pm_ops, }, .probe = sh_mobile_ceu_probe, - .remove = __exit_p(sh_mobile_ceu_remove), + .remove = __devexit_p(sh_mobile_ceu_remove), }; static int __init sh_mobile_ceu_init(void) -- cgit v1.2.3-70-g09d2 From 9d8938248c3b67904a8108a6fc3dcceb9d7f2aad Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 10 Dec 2009 17:01:13 -0300 Subject: V4L/DVB (13606): vpfe_capture: move vpfe_remove to .devexit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function vpfe_remove is used only wrapped by __devexit_p so define it using __devexit. Signed-off-by: Uwe Kleine-König Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/davinci/vpfe_capture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c index f2d3c9b6df1..87e97962ff5 100644 --- a/drivers/media/video/davinci/vpfe_capture.c +++ b/drivers/media/video/davinci/vpfe_capture.c @@ -2090,7 +2090,7 @@ probe_free_dev_mem: /* * vpfe_remove : It un-register device from V4L2 driver */ -static int vpfe_remove(struct platform_device *pdev) +static int __devexit vpfe_remove(struct platform_device *pdev) { struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev); struct resource *res; -- cgit v1.2.3-70-g09d2 From 0b0a860fec1a6d4cdcd0dc5241390d083a82c00d Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 10 Dec 2009 17:02:16 -0300 Subject: V4L/DVB (13607): vpif: move vpif_remove to .devexit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function vpif_remove is used only wrapped by __devexit_p so define it using __devexit. Signed-off-by: Uwe Kleine-König Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/davinci/vpif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/davinci/vpif.c b/drivers/media/video/davinci/vpif.c index 3b8eac31eca..1f532e31cd4 100644 --- a/drivers/media/video/davinci/vpif.c +++ b/drivers/media/video/davinci/vpif.c @@ -266,7 +266,7 @@ fail: return status; } -static int vpif_remove(struct platform_device *pdev) +static int __devexit vpif_remove(struct platform_device *pdev) { iounmap(vpif_base); release_mem_region(res->start, res_len); -- cgit v1.2.3-70-g09d2 From 4b8303747474033d6d73828607eafab77c620d96 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Thu, 10 Dec 2009 17:06:44 -0300 Subject: V4L/DVB (13608): radio-sf16fmi: fix mute, add SF16-FMP to texts Fix completely broken mute handling radio-sf16fmi. The sound was muted immediately after tuning in KRadio. Also fix typos and add SF16-FMP to the texts. Signed-off-by: Ondrej Zary Acked-by: Petr Vandrovec Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/Kconfig | 2 +- drivers/media/radio/radio-sf16fmi.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 4c2b8a24677..0fe93f2b48b 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -215,7 +215,7 @@ config RADIO_MIROPCM20 module will be called radio-miropcm20. config RADIO_SF16FMI - tristate "SF16FMI Radio" + tristate "SF16-FMI/SF16-FMP Radio" depends on ISA && VIDEO_V4L2 ---help--- Choose Y here if you have one of these FM radio cards. If you diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 93990b7899e..e9ecfe11cda 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c @@ -1,4 +1,4 @@ -/* SF16FMI radio driver for Linux radio support +/* SF16-FMI and SF16-FMP radio driver for Linux radio support * heavily based on rtrack driver... * (c) 1997 M. Kirkwood * (c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz @@ -11,7 +11,7 @@ * * Frequency control is done digitally -- ie out(port,encodefreq(95.8)); * No volume control - only mute/unmute - you have to use line volume - * control on SB-part of SF16FMI + * control on SB-part of SF16-FMI/SF16-FMP * * Converted to V4L2 API by Mauro Carvalho Chehab */ @@ -30,14 +30,14 @@ #include MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood"); -MODULE_DESCRIPTION("A driver for the SF16MI radio."); +MODULE_DESCRIPTION("A driver for the SF16-FMI and SF16-FMP radio."); MODULE_LICENSE("GPL"); static int io = -1; static int radio_nr = -1; module_param(io, int, 0); -MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)"); +MODULE_PARM_DESC(io, "I/O address of the SF16-FMI or SF16-FMP card (0x284 or 0x384)"); module_param(radio_nr, int, 0); #define RADIO_VERSION KERNEL_VERSION(0, 0, 2) @@ -47,7 +47,7 @@ struct fmi struct v4l2_device v4l2_dev; struct video_device vdev; int io; - int curvol; /* 1 or 0 */ + bool mute; unsigned long curfreq; /* freq in kHz */ struct mutex lock; }; @@ -105,7 +105,7 @@ static inline int fmi_setfreq(struct fmi *fmi, unsigned long freq) outbits(8, 0xC0, fmi->io); msleep(143); /* was schedule_timeout(HZ/7) */ mutex_unlock(&fmi->lock); - if (fmi->curvol) + if (!fmi->mute) fmi_unmute(fmi); return 0; } @@ -116,7 +116,7 @@ static inline int fmi_getsigstr(struct fmi *fmi) int res; mutex_lock(&fmi->lock); - val = fmi->curvol ? 0x08 : 0x00; /* unmute/mute */ + val = fmi->mute ? 0x00 : 0x08; /* mute/unmute */ outb(val, fmi->io); outb(val | 0x10, fmi->io); msleep(143); /* was schedule_timeout(HZ/7) */ @@ -208,7 +208,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv, switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: - ctrl->value = fmi->curvol; + ctrl->value = fmi->mute; return 0; } return -EINVAL; @@ -225,7 +225,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, fmi_mute(fmi); else fmi_unmute(fmi); - fmi->curvol = ctrl->value; + fmi->mute = ctrl->value; return 0; } return -EINVAL; -- cgit v1.2.3-70-g09d2 From 67cabf503cd0ad7473cf1856f9c9bb6320098be6 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Thu, 10 Dec 2009 17:12:32 -0300 Subject: V4L/DVB (13609): radio-sf16fmi: add autoprobing Add automatic probing of ports 0x284 and 0x384 to radio-sf16fmi if no card is found using PnP. Signed-off-by: Ondrej Zary Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/Kconfig | 5 +--- drivers/media/radio/radio-sf16fmi.c | 60 +++++++++++++++++++++++++++---------- 2 files changed, 46 insertions(+), 19 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 0fe93f2b48b..3f40f375981 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -218,10 +218,7 @@ config RADIO_SF16FMI tristate "SF16-FMI/SF16-FMP Radio" depends on ISA && VIDEO_V4L2 ---help--- - Choose Y here if you have one of these FM radio cards. If you - compile the driver into the kernel and your card is not PnP one, you - have to add "sf16fm=" to the kernel command line (I/O address is - 0x284 or 0x384). + Choose Y here if you have one of these FM radio cards. In order to control your radio card, you will need to use programs that are compatible with the Video For Linux API. Information on diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index e9ecfe11cda..985359d18aa 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c @@ -54,6 +54,7 @@ struct fmi static struct fmi fmi_card; static struct pnp_dev *dev; +bool pnp_attached; /* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ /* It is only useful to give freq in interval of 800 (=0.05Mhz), @@ -320,26 +321,54 @@ static int __init fmi_init(void) { struct fmi *fmi = &fmi_card; struct v4l2_device *v4l2_dev = &fmi->v4l2_dev; - int res; + int res, i; + int probe_ports[] = { 0, 0x284, 0x384 }; + + if (io < 0) { + for (i = 0; i < ARRAY_SIZE(probe_ports); i++) { + io = probe_ports[i]; + if (io == 0) { + io = isapnp_fmi_probe(); + if (io < 0) + continue; + pnp_attached = 1; + } + if (!request_region(io, 2, "radio-sf16fmi")) { + if (pnp_attached) + pnp_device_detach(dev); + io = -1; + continue; + } + if (pnp_attached || + ((inb(io) & 0xf9) == 0xf9 && (inb(io) & 0x4) == 0)) + break; + release_region(io, 2); + io = -1; + } + } else { + if (!request_region(io, 2, "radio-sf16fmi")) { + printk(KERN_ERR "radio-sf16fmi: port %#x already in use\n", io); + return -EBUSY; + } + if (inb(io) == 0xff) { + printk(KERN_ERR "radio-sf16fmi: card not present at %#x\n", io); + release_region(io, 2); + return -ENODEV; + } + } + if (io < 0) { + printk(KERN_ERR "radio-sf16fmi: no cards found\n"); + return -ENODEV; + } - if (io < 0) - io = isapnp_fmi_probe(); strlcpy(v4l2_dev->name, "sf16fmi", sizeof(v4l2_dev->name)); fmi->io = io; - if (fmi->io < 0) { - v4l2_err(v4l2_dev, "No PnP card found.\n"); - return fmi->io; - } - if (!request_region(io, 2, "radio-sf16fmi")) { - v4l2_err(v4l2_dev, "port 0x%x already in use\n", fmi->io); - pnp_device_detach(dev); - return -EBUSY; - } res = v4l2_device_register(NULL, v4l2_dev); if (res < 0) { release_region(fmi->io, 2); - pnp_device_detach(dev); + if (pnp_attached) + pnp_device_detach(dev); v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); return res; } @@ -356,7 +385,8 @@ static int __init fmi_init(void) if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { v4l2_device_unregister(v4l2_dev); release_region(fmi->io, 2); - pnp_device_detach(dev); + if (pnp_attached) + pnp_device_detach(dev); return -EINVAL; } @@ -373,7 +403,7 @@ static void __exit fmi_exit(void) video_unregister_device(&fmi->vdev); v4l2_device_unregister(&fmi->v4l2_dev); release_region(fmi->io, 2); - if (dev) + if (dev && pnp_attached) pnp_device_detach(dev); } -- cgit v1.2.3-70-g09d2 From ddb0b34f1345e1fec60f168bd99c487699f65212 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 10 Dec 2009 17:14:27 -0300 Subject: V4L/DVB (13610): uvc: Correct size given to memset Memset should be given the size of the structure, not the size of the pointer. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ type T; T *x; expression E; @@ memset(x, E, sizeof( + * x)) // Signed-off-by: Julia Lawall Acked-by: Laurent Pinchart Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 05139a4f14f..9a9802830d4 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -145,7 +145,7 @@ static int uvc_get_video_ctrl(struct uvc_streaming *stream, uvc_warn_once(stream->dev, UVC_WARN_MINMAX, "UVC non " "compliance - GET_MIN/MAX(PROBE) incorrectly " "supported. Enabling workaround.\n"); - memset(ctrl, 0, sizeof ctrl); + memset(ctrl, 0, sizeof *ctrl); ctrl->wCompQuality = le16_to_cpup((__le16 *)data); ret = 0; goto out; -- cgit v1.2.3-70-g09d2 From 909d15a70d6a269ba599c539c55a574482355ff1 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 10 Dec 2009 17:17:49 -0300 Subject: V4L/DVB (13611): radio-tea5764: Correct size given to memset Memset should be given the size of the structure, not the size of the pointer. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ type T; T *x; expression E; @@ memset(x, E, sizeof( + * x)) // Signed-off-by: Julia Lawall Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-tea5764.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c index 1d357b79b2f..8e718bfcdad 100644 --- a/drivers/media/radio/radio-tea5764.c +++ b/drivers/media/radio/radio-tea5764.c @@ -314,7 +314,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, if (v->index > 0) return -EINVAL; - memset(v, 0, sizeof(v)); + memset(v, 0, sizeof(*v)); strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; tea5764_i2c_read(radio); @@ -373,7 +373,7 @@ static int vidioc_g_frequency(struct file *file, void *priv, if (f->tuner != 0) return -EINVAL; tea5764_i2c_read(radio); - memset(f, 0, sizeof(f)); + memset(f, 0, sizeof(*f)); f->type = V4L2_TUNER_RADIO; if (r->tnctrl & TEA5764_TNCTRL_PUPD0) f->frequency = (tea5764_get_freq(radio) * 2) / 125; -- cgit v1.2.3-70-g09d2 From e27d38112eb727df189a9ebf560aa104cb102253 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2009 08:00:00 -0300 Subject: V4L/DVB (13612): IR: Move common IR code to drivers/media/IR This is the first step of creating a common code for IR that can be used by other input devices. For now, keep IR dir at drivers/media, to easy the movement of the IR files, but later patches may move it to drivers/IR or drivers/input/IR. No functional changes is done on this patch. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/IR/Kconfig | 4 + drivers/media/IR/Makefile | 3 + drivers/media/IR/ir-functions.c | 373 ++++ drivers/media/IR/ir-keymaps.c | 3395 +++++++++++++++++++++++++++++++++++ drivers/media/IR/ir-keytable.c | 433 +++++ drivers/media/Kconfig | 1 + drivers/media/Makefile | 2 +- drivers/media/common/Makefile | 2 - drivers/media/common/ir-functions.c | 373 ---- drivers/media/common/ir-keymaps.c | 3395 ----------------------------------- drivers/media/common/ir-keytable.c | 432 ----- drivers/media/video/Kconfig | 4 - 12 files changed, 4210 insertions(+), 4207 deletions(-) create mode 100644 drivers/media/IR/Kconfig create mode 100644 drivers/media/IR/Makefile create mode 100644 drivers/media/IR/ir-functions.c create mode 100644 drivers/media/IR/ir-keymaps.c create mode 100644 drivers/media/IR/ir-keytable.c delete mode 100644 drivers/media/common/ir-functions.c delete mode 100644 drivers/media/common/ir-keymaps.c delete mode 100644 drivers/media/common/ir-keytable.c (limited to 'drivers/media') diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig new file mode 100644 index 00000000000..5b4ac969a58 --- /dev/null +++ b/drivers/media/IR/Kconfig @@ -0,0 +1,4 @@ +config VIDEO_IR + tristate + depends on INPUT + default INPUT diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile new file mode 100644 index 00000000000..2781f430c6e --- /dev/null +++ b/drivers/media/IR/Makefile @@ -0,0 +1,3 @@ +ir-common-objs := ir-functions.o ir-keymaps.o ir-keytable.o + +obj-$(CONFIG_VIDEO_IR) += ir-common.o diff --git a/drivers/media/IR/ir-functions.c b/drivers/media/IR/ir-functions.c new file mode 100644 index 00000000000..e616f624cea --- /dev/null +++ b/drivers/media/IR/ir-functions.c @@ -0,0 +1,373 @@ +/* + * + * some common structs and functions to handle infrared remotes via + * input layer ... + * + * (c) 2003 Gerd Knorr [SuSE Labs] + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include + +/* -------------------------------------------------------------------------- */ + +MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); +MODULE_LICENSE("GPL"); + +static int repeat = 1; +module_param(repeat, int, 0444); +MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)"); + +int media_ir_debug; /* media_ir_debug level (0,1,2) */ +module_param_named(debug, media_ir_debug, int, 0644); + +/* -------------------------------------------------------------------------- */ + +static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) +{ + if (KEY_RESERVED == ir->keycode) { + printk(KERN_INFO "%s: unknown key: key=0x%02x down=%d\n", + dev->name, ir->ir_key, ir->keypressed); + return; + } + IR_dprintk(1,"%s: key event code=%d down=%d\n", + dev->name,ir->keycode,ir->keypressed); + input_report_key(dev,ir->keycode,ir->keypressed); + input_sync(dev); +} + +/* -------------------------------------------------------------------------- */ + +int ir_input_init(struct input_dev *dev, struct ir_input_state *ir, + int ir_type, struct ir_scancode_table *ir_codes) +{ + ir->ir_type = ir_type; + + ir->keytable.size = ir_roundup_tablesize(ir_codes->size); + ir->keytable.scan = kzalloc(ir->keytable.size * + sizeof(struct ir_scancode), GFP_KERNEL); + if (!ir->keytable.scan) + return -ENOMEM; + + IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n", + ir->keytable.size, + ir->keytable.size * sizeof(ir->keytable.scan)); + + ir_copy_table(&ir->keytable, ir_codes); + ir_set_keycode_table(dev, &ir->keytable); + + clear_bit(0, dev->keybit); + set_bit(EV_KEY, dev->evbit); + if (repeat) + set_bit(EV_REP, dev->evbit); + + return 0; +} +EXPORT_SYMBOL_GPL(ir_input_init); + + +void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir) +{ + if (ir->keypressed) { + ir->keypressed = 0; + ir_input_key_event(dev,ir); + } +} +EXPORT_SYMBOL_GPL(ir_input_nokey); + +void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, + u32 ir_key) +{ + u32 keycode = ir_g_keycode_from_table(dev, ir_key); + + if (ir->keypressed && ir->keycode != keycode) { + ir->keypressed = 0; + ir_input_key_event(dev,ir); + } + if (!ir->keypressed) { + ir->ir_key = ir_key; + ir->keycode = keycode; + ir->keypressed = 1; + ir_input_key_event(dev,ir); + } +} +EXPORT_SYMBOL_GPL(ir_input_keydown); + +/* -------------------------------------------------------------------------- */ +/* extract mask bits out of data and pack them into the result */ +u32 ir_extract_bits(u32 data, u32 mask) +{ + u32 vbit = 1, value = 0; + + do { + if (mask&1) { + if (data&1) + value |= vbit; + vbit<<=1; + } + data>>=1; + } while (mask>>=1); + + return value; +} +EXPORT_SYMBOL_GPL(ir_extract_bits); + +static int inline getbit(u32 *samples, int bit) +{ + return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0; +} + +/* sump raw samples for visual debugging ;) */ +int ir_dump_samples(u32 *samples, int count) +{ + int i, bit, start; + + printk(KERN_DEBUG "ir samples: "); + start = 0; + for (i = 0; i < count * 32; i++) { + bit = getbit(samples,i); + if (bit) + start = 1; + if (0 == start) + continue; + printk("%s", bit ? "#" : "_"); + } + printk("\n"); + return 0; +} +EXPORT_SYMBOL_GPL(ir_dump_samples); + +/* decode raw samples, pulse distance coding used by NEC remotes */ +int ir_decode_pulsedistance(u32 *samples, int count, int low, int high) +{ + int i,last,bit,len; + u32 curBit; + u32 value; + + /* find start burst */ + for (i = len = 0; i < count * 32; i++) { + bit = getbit(samples,i); + if (bit) { + len++; + } else { + if (len >= 29) + break; + len = 0; + } + } + + /* start burst to short */ + if (len < 29) + return 0xffffffff; + + /* find start silence */ + for (len = 0; i < count * 32; i++) { + bit = getbit(samples,i); + if (bit) { + break; + } else { + len++; + } + } + + /* silence to short */ + if (len < 7) + return 0xffffffff; + + /* go decoding */ + len = 0; + last = 1; + value = 0; curBit = 1; + for (; i < count * 32; i++) { + bit = getbit(samples,i); + if (last) { + if(bit) { + continue; + } else { + len = 1; + } + } else { + if (bit) { + if (len > (low + high) /2) + value |= curBit; + curBit <<= 1; + if (curBit == 1) + break; + } else { + len++; + } + } + last = bit; + } + + return value; +} +EXPORT_SYMBOL_GPL(ir_decode_pulsedistance); + +/* decode raw samples, biphase coding, used by rc5 for example */ +int ir_decode_biphase(u32 *samples, int count, int low, int high) +{ + int i,last,bit,len,flips; + u32 value; + + /* find start bit (1) */ + for (i = 0; i < 32; i++) { + bit = getbit(samples,i); + if (bit) + break; + } + + /* go decoding */ + len = 0; + flips = 0; + value = 1; + for (; i < count * 32; i++) { + if (len > high) + break; + if (flips > 1) + break; + last = bit; + bit = getbit(samples,i); + if (last == bit) { + len++; + continue; + } + if (len < low) { + len++; + flips++; + continue; + } + value <<= 1; + value |= bit; + flips = 0; + len = 1; + } + return value; +} +EXPORT_SYMBOL_GPL(ir_decode_biphase); + +/* RC5 decoding stuff, moved from bttv-input.c to share it with + * saa7134 */ + +/* decode raw bit pattern to RC5 code */ +u32 ir_rc5_decode(unsigned int code) +{ + unsigned int org_code = code; + unsigned int pair; + unsigned int rc5 = 0; + int i; + + for (i = 0; i < 14; ++i) { + pair = code & 0x3; + code >>= 2; + + rc5 <<= 1; + switch (pair) { + case 0: + case 2: + break; + case 1: + rc5 |= 1; + break; + case 3: + IR_dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code); + return 0; + } + } + IR_dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " + "instr=%x\n", rc5, org_code, RC5_START(rc5), + RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); + return rc5; +} +EXPORT_SYMBOL_GPL(ir_rc5_decode); + +void ir_rc5_timer_end(unsigned long data) +{ + struct card_ir *ir = (struct card_ir *)data; + struct timeval tv; + unsigned long current_jiffies, timeout; + u32 gap; + u32 rc5 = 0; + + /* get time */ + current_jiffies = jiffies; + do_gettimeofday(&tv); + + /* avoid overflow with gap >1s */ + if (tv.tv_sec - ir->base_time.tv_sec > 1) { + gap = 200000; + } else { + gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + + tv.tv_usec - ir->base_time.tv_usec; + } + + /* signal we're ready to start a new code */ + ir->active = 0; + + /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */ + if (gap < 28000) { + IR_dprintk(1, "ir-common: spurious timer_end\n"); + return; + } + + if (ir->last_bit < 20) { + /* ignore spurious codes (caused by light/other remotes) */ + IR_dprintk(1, "ir-common: short code: %x\n", ir->code); + } else { + ir->code = (ir->code << ir->shift_by) | 1; + rc5 = ir_rc5_decode(ir->code); + + /* two start bits? */ + if (RC5_START(rc5) != ir->start) { + IR_dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5)); + + /* right address? */ + } else if (RC5_ADDR(rc5) == ir->addr) { + u32 toggle = RC5_TOGGLE(rc5); + u32 instr = RC5_INSTR(rc5); + + /* Good code, decide if repeat/repress */ + if (toggle != RC5_TOGGLE(ir->last_rc5) || + instr != RC5_INSTR(ir->last_rc5)) { + IR_dprintk(1, "ir-common: instruction %x, toggle %x\n", instr, + toggle); + ir_input_nokey(ir->dev, &ir->ir); + ir_input_keydown(ir->dev, &ir->ir, instr); + } + + /* Set/reset key-up timer */ + timeout = current_jiffies + + msecs_to_jiffies(ir->rc5_key_timeout); + mod_timer(&ir->timer_keyup, timeout); + + /* Save code for repeat test */ + ir->last_rc5 = rc5; + } + } +} +EXPORT_SYMBOL_GPL(ir_rc5_timer_end); + +void ir_rc5_timer_keyup(unsigned long data) +{ + struct card_ir *ir = (struct card_ir *)data; + + IR_dprintk(1, "ir-common: key released\n"); + ir_input_nokey(ir->dev, &ir->ir); +} +EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup); diff --git a/drivers/media/IR/ir-keymaps.c b/drivers/media/IR/ir-keymaps.c new file mode 100644 index 00000000000..9bbe6b1e987 --- /dev/null +++ b/drivers/media/IR/ir-keymaps.c @@ -0,0 +1,3395 @@ +/* + Keytables for supported remote controls, used on drivers/media + devices. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * NOTICE FOR DEVELOPERS: + * The IR mappings should be as close as possible to what's + * specified at: + * http://linuxtv.org/wiki/index.php/Remote_Controllers + */ +#include + +#include +#include + +/* empty keytable, can be used as placeholder for not-yet created keytables */ +static struct ir_scancode ir_codes_empty[] = { + { 0x2a, KEY_COFFEE }, +}; + +struct ir_scancode_table ir_codes_empty_table = { + .scan = ir_codes_empty, + .size = ARRAY_SIZE(ir_codes_empty), +}; +EXPORT_SYMBOL_GPL(ir_codes_empty_table); + +/* Michal Majchrowicz */ +static struct ir_scancode ir_codes_proteus_2309[] = { + /* numeric */ + { 0x00, KEY_0 }, + { 0x01, KEY_1 }, + { 0x02, KEY_2 }, + { 0x03, KEY_3 }, + { 0x04, KEY_4 }, + { 0x05, KEY_5 }, + { 0x06, KEY_6 }, + { 0x07, KEY_7 }, + { 0x08, KEY_8 }, + { 0x09, KEY_9 }, + + { 0x5c, KEY_POWER }, /* power */ + { 0x20, KEY_ZOOM }, /* full screen */ + { 0x0f, KEY_BACKSPACE }, /* recall */ + { 0x1b, KEY_ENTER }, /* mute */ + { 0x41, KEY_RECORD }, /* record */ + { 0x43, KEY_STOP }, /* stop */ + { 0x16, KEY_S }, + { 0x1a, KEY_POWER2 }, /* off */ + { 0x2e, KEY_RED }, + { 0x1f, KEY_CHANNELDOWN }, /* channel - */ + { 0x1c, KEY_CHANNELUP }, /* channel + */ + { 0x10, KEY_VOLUMEDOWN }, /* volume - */ + { 0x1e, KEY_VOLUMEUP }, /* volume + */ + { 0x14, KEY_F1 }, +}; + +struct ir_scancode_table ir_codes_proteus_2309_table = { + .scan = ir_codes_proteus_2309, + .size = ARRAY_SIZE(ir_codes_proteus_2309), +}; +EXPORT_SYMBOL_GPL(ir_codes_proteus_2309_table); + +/* Matt Jesson >' */ + { 0x3a, KEY_RECORD }, /* 'capture' */ + { 0x0a, KEY_MUTE }, /* 'mute' */ + { 0x2c, KEY_RECORD }, /* 'record' */ + { 0x1c, KEY_PAUSE }, /* 'pause' */ + { 0x3c, KEY_STOP }, /* 'stop' */ + { 0x0c, KEY_PLAY }, /* 'play' */ + { 0x2e, KEY_RED }, /* 'red' */ + { 0x01, KEY_BLUE }, /* 'blue' / 'cancel' */ + { 0x0e, KEY_YELLOW }, /* 'yellow' / 'ok' */ + { 0x21, KEY_GREEN }, /* 'green' */ + { 0x11, KEY_CHANNELDOWN }, /* 'channel -' */ + { 0x31, KEY_CHANNELUP }, /* 'channel +' */ + { 0x1e, KEY_VOLUMEDOWN }, /* 'volume -' */ + { 0x3e, KEY_VOLUMEUP }, /* 'volume +' */ +}; + +struct ir_scancode_table ir_codes_avermedia_dvbt_table = { + .scan = ir_codes_avermedia_dvbt, + .size = ARRAY_SIZE(ir_codes_avermedia_dvbt), +}; +EXPORT_SYMBOL_GPL(ir_codes_avermedia_dvbt_table); + +/* Mauro Carvalho Chehab */ +static struct ir_scancode ir_codes_avermedia_m135a[] = { + { 0x00, KEY_POWER2 }, + { 0x2e, KEY_DOT }, /* '.' */ + { 0x01, KEY_MODE }, /* TV/FM */ + + { 0x05, KEY_1 }, + { 0x06, KEY_2 }, + { 0x07, KEY_3 }, + { 0x09, KEY_4 }, + { 0x0a, KEY_5 }, + { 0x0b, KEY_6 }, + { 0x0d, KEY_7 }, + { 0x0e, KEY_8 }, + { 0x0f, KEY_9 }, + { 0x11, KEY_0 }, + + { 0x13, KEY_RIGHT }, /* -> */ + { 0x12, KEY_LEFT }, /* <- */ + + { 0x17, KEY_SLEEP }, /* Capturar Imagem */ + { 0x10, KEY_SHUFFLE }, /* Amostra */ + + /* FIXME: The keys bellow aren't ok */ + + { 0x43, KEY_CHANNELUP }, + { 0x42, KEY_CHANNELDOWN }, + { 0x1f, KEY_VOLUMEUP }, + { 0x1e, KEY_VOLUMEDOWN }, + { 0x0c, KEY_ENTER }, + + { 0x14, KEY_MUTE }, + { 0x08, KEY_AUDIO }, + + { 0x03, KEY_TEXT }, + { 0x04, KEY_EPG }, + { 0x2b, KEY_TV2 }, /* TV2 */ + + { 0x1d, KEY_RED }, + { 0x1c, KEY_YELLOW }, + { 0x41, KEY_GREEN }, + { 0x40, KEY_BLUE }, + + { 0x1a, KEY_PLAYPAUSE }, + { 0x19, KEY_RECORD }, + { 0x18, KEY_PLAY }, + { 0x1b, KEY_STOP }, +}; + +struct ir_scancode_table ir_codes_avermedia_m135a_table = { + .scan = ir_codes_avermedia_m135a, + .size = ARRAY_SIZE(ir_codes_avermedia_m135a), +}; +EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a_table); + +/* Oldrich Jedlicka */ +static struct ir_scancode ir_codes_avermedia_cardbus[] = { + { 0x00, KEY_POWER }, + { 0x01, KEY_TUNER }, /* TV/FM */ + { 0x03, KEY_TEXT }, /* Teletext */ + { 0x04, KEY_EPG }, + { 0x05, KEY_1 }, + { 0x06, KEY_2 }, + { 0x07, KEY_3 }, + { 0x08, KEY_AUDIO }, + { 0x09, KEY_4 }, + { 0x0a, KEY_5 }, + { 0x0b, KEY_6 }, + { 0x0c, KEY_ZOOM }, /* Full screen */ + { 0x0d, KEY_7 }, + { 0x0e, KEY_8 }, + { 0x0f, KEY_9 }, + { 0x10, KEY_PAGEUP }, /* 16-CH PREV */ + { 0x11, KEY_0 }, + { 0x12, KEY_INFO }, + { 0x13, KEY_AGAIN }, /* CH RTN - channel return */ + { 0x14, KEY_MUTE }, + { 0x15, KEY_EDIT }, /* Autoscan */ + { 0x17, KEY_SAVE }, /* Screenshot */ + { 0x18, KEY_PLAYPAUSE }, + { 0x19, KEY_RECORD }, + { 0x1a, KEY_PLAY }, + { 0x1b, KEY_STOP }, + { 0x1c, KEY_FASTFORWARD }, + { 0x1d, KEY_REWIND }, + { 0x1e, KEY_VOLUMEDOWN }, + { 0x1f, KEY_VOLUMEUP }, + { 0x22, KEY_SLEEP }, /* Sleep */ + { 0x23, KEY_ZOOM }, /* Aspect */ + { 0x26, KEY_SCREEN }, /* Pos */ + { 0x27, KEY_ANGLE }, /* Size */ + { 0x28, KEY_SELECT }, /* Select */ + { 0x29, KEY_BLUE }, /* Blue/Picture */ + { 0x2a, KEY_BACKSPACE }, /* Back */ + { 0x2b, KEY_MEDIA }, /* PIP (Picture-in-picture) */ + { 0x2c, KEY_DOWN }, + { 0x2e, KEY_DOT }, + { 0x2f, KEY_TV }, /* Live TV */ + { 0x32, KEY_LEFT }, + { 0x33, KEY_CLEAR }, /* Clear */ + { 0x35, KEY_RED }, /* Red/TV */ + { 0x36, KEY_UP }, + { 0x37, KEY_HOME }, /* Home */ + { 0x39, KEY_GREEN }, /* Green/Video */ + { 0x3d, KEY_YELLOW }, /* Yellow/Music */ + { 0x3e, KEY_OK }, /* Ok */ + { 0x3f, KEY_RIGHT }, + { 0x40, KEY_NEXT }, /* Next */ + { 0x41, KEY_PREVIOUS }, /* Previous */ + { 0x42, KEY_CHANNELDOWN }, /* Channel down */ + { 0x43, KEY_CHANNELUP }, /* Channel up */ +}; + +struct ir_scancode_table ir_codes_avermedia_cardbus_table = { + .scan = ir_codes_avermedia_cardbus, + .size = ARRAY_SIZE(ir_codes_avermedia_cardbus), +}; +EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus_table); + +/* Attila Kondoros */ +static struct ir_scancode ir_codes_apac_viewcomp[] = { + + { 0x01, KEY_1 }, + { 0x02, KEY_2 }, + { 0x03, KEY_3 }, + { 0x04, KEY_4 }, + { 0x05, KEY_5 }, + { 0x06, KEY_6 }, + { 0x07, KEY_7 }, + { 0x08, KEY_8 }, + { 0x09, KEY_9 }, + { 0x00, KEY_0 }, + { 0x17, KEY_LAST }, /* +100 */ + { 0x0a, KEY_LIST }, /* recall */ + + + { 0x1c, KEY_TUNER }, /* TV/FM */ + { 0x15, KEY_SEARCH }, /* scan */ + { 0x12, KEY_POWER }, /* power */ + { 0x1f, KEY_VOLUMEDOWN }, /* vol up */ + { 0x1b, KEY_VOLUMEUP }, /* vol down */ + { 0x1e, KEY_CHANNELDOWN }, /* chn up */ + { 0x1a, KEY_CHANNELUP }, /* chn down */ + + { 0x11, KEY_VIDEO }, /* video */ + { 0x0f, KEY_ZOOM }, /* full screen */ + { 0x13, KEY_MUTE }, /* mute/unmute */ + { 0x10, KEY_TEXT }, /* min */ + + { 0x0d, KEY_STOP }, /* freeze */ + { 0x0e, KEY_RECORD }, /* record */ + { 0x1d, KEY_PLAYPAUSE }, /* stop */ + { 0x19, KEY_PLAY }, /* play */ + + { 0x16, KEY_GOTO }, /* osd */ + { 0x14, KEY_REFRESH }, /* default */ + { 0x0c, KEY_KPPLUS }, /* fine tune >>>> */ + { 0x18, KEY_KPMINUS }, /* fine tune <<<< */ +}; + +struct ir_scancode_table ir_codes_apac_viewcomp_table = { + .scan = ir_codes_apac_viewcomp, + .size = ARRAY_SIZE(ir_codes_apac_viewcomp), +}; +EXPORT_SYMBOL_GPL(ir_codes_apac_viewcomp_table); + +/* ---------------------------------------------------------------------- */ + +static struct ir_scancode ir_codes_pixelview[] = { + + { 0x1e, KEY_POWER }, /* power */ + { 0x07, KEY_MEDIA }, /* source */ + { 0x1c, KEY_SEARCH }, /* scan */ + + + { 0x03, KEY_TUNER }, /* TV/FM */ + + { 0x00, KEY_RECORD }, + { 0x08, KEY_STOP }, + { 0x11, KEY_PLAY }, + + { 0x1a, KEY_PLAYPAUSE }, /* freeze */ + { 0x19, KEY_ZOOM }, /* zoom */ + { 0x0f, KEY_TEXT }, /* min */ + + { 0x01, KEY_1 }, + { 0x0b, KEY_2 }, + { 0x1b, KEY_3 }, + { 0x05, KEY_4 }, + { 0x09, KEY_5 }, + { 0x15, KEY_6 }, + { 0x06, KEY_7 }, + { 0x0a, KEY_8 }, + { 0x12, KEY_9 }, + { 0x02, KEY_0 }, + { 0x10, KEY_LAST }, /* +100 */ + { 0x13, KEY_LIST }, /* recall */ + + { 0x1f, KEY_CHANNELUP }, /* chn down */ + { 0x17, KEY_CHANNELDOWN }, /* chn up */ + { 0x16, KEY_VOLUMEUP }, /* vol down */ + { 0x14, KEY_VOLUMEDOWN }, /* vol up */ + + { 0x04, KEY_KPMINUS }, /* <<< */ + { 0x0e, KEY_SETUP }, /* function */ + { 0x0c, KEY_KPPLUS }, /* >>> */ + + { 0x0d, KEY_GOTO }, /* mts */ + { 0x1d, KEY_REFRESH }, /* reset */ + { 0x18, KEY_MUTE }, /* mute/unmute */ +}; + +struct ir_scancode_table ir_codes_pixelview_table = { + .scan = ir_codes_pixelview, + .size = ARRAY_SIZE(ir_codes_pixelview), +}; +EXPORT_SYMBOL_GPL(ir_codes_pixelview_table); + +/* + Mauro Carvalho Chehab + present on PV MPEG 8000GT + */ +static struct ir_scancode ir_codes_pixelview_new[] = { + { 0x3c, KEY_TIME }, /* Timeshift */ + { 0x12, KEY_POWER }, + + { 0x3d, KEY_1 }, + { 0x38, KEY_2 }, + { 0x18, KEY_3 }, + { 0x35, KEY_4 }, + { 0x39, KEY_5 }, + { 0x15, KEY_6 }, + { 0x36, KEY_7 }, + { 0x3a, KEY_8 }, + { 0x1e, KEY_9 }, + { 0x3e, KEY_0 }, + + { 0x1c, KEY_AGAIN }, /* LOOP */ + { 0x3f, KEY_MEDIA }, /* Source */ + { 0x1f, KEY_LAST }, /* +100 */ + { 0x1b, KEY_MUTE }, + + { 0x17, KEY_CHANNELDOWN }, + { 0x16, KEY_CHANNELUP }, + { 0x10, KEY_VOLUMEUP }, + { 0x14, KEY_VOLUMEDOWN }, + { 0x13, KEY_ZOOM }, + + { 0x19, KEY_CAMERA }, /* SNAPSHOT */ + { 0x1a, KEY_SEARCH }, /* scan */ + + { 0x37, KEY_REWIND }, /* << */ + { 0x32, KEY_RECORD }, /* o (red) */ + { 0x33, KEY_FORWARD }, /* >> */ + { 0x11, KEY_STOP }, /* square */ + { 0x3b, KEY_PLAY }, /* > */ + { 0x30, KEY_PLAYPAUSE }, /* || */ + + { 0x31, KEY_TV }, + { 0x34, KEY_RADIO }, +}; + +struct ir_scancode_table ir_codes_pixelview_new_table = { + .scan = ir_codes_pixelview_new, + .size = ARRAY_SIZE(ir_codes_pixelview_new), +}; +EXPORT_SYMBOL_GPL(ir_codes_pixelview_new_table); + +static struct ir_scancode ir_codes_nebula[] = { + { 0x00, KEY_0 }, + { 0x01, KEY_1 }, + { 0x02, KEY_2 }, + { 0x03, KEY_3 }, + { 0x04, KEY_4 }, + { 0x05, KEY_5 }, + { 0x06, KEY_6 }, + { 0x07, KEY_7 }, + { 0x08, KEY_8 }, + { 0x09, KEY_9 }, + { 0x0a, KEY_TV }, + { 0x0b, KEY_AUX }, + { 0x0c, KEY_DVD }, + { 0x0d, KEY_POWER }, + { 0x0e, KEY_MHP }, /* labelled 'Picture' */ + { 0x0f, KEY_AUDIO }, + { 0x10, KEY_INFO }, + { 0x11, KEY_F13 }, /* 16:9 */ + { 0x12, KEY_F14 }, /* 14:9 */ + { 0x13, KEY_EPG }, + { 0x14, KEY_EXIT }, + { 0x15, KEY_MENU }, + { 0x16, KEY_UP }, + { 0x17, KEY_DOWN }, + { 0x18, KEY_LEFT }, + { 0x19, KEY_RIGHT }, + { 0x1a, KEY_ENTER }, + { 0x1b, KEY_CHANNELUP }, + { 0x1c, KEY_CHANNELDOWN }, + { 0x1d, KEY_VOLUMEUP }, + { 0x1e, KEY_VOLUMEDOWN }, + { 0x1f, KEY_RED }, + { 0x20, KEY_GREEN }, + { 0x21, KEY_YELLOW }, + { 0x22, KEY_BLUE }, + { 0x23, KEY_SUBTITLE }, + { 0x24, KEY_F15 }, /* AD */ + { 0x25, KEY_TEXT }, + { 0x26, KEY_MUTE }, + { 0x27, KEY_REWIND }, + { 0x28, KEY_STOP }, + { 0x29, KEY_PLAY }, + { 0x2a, KEY_FASTFORWARD }, + { 0x2b, KEY_F16 }, /* chapter */ + { 0x2c, KEY_PAUSE }, + { 0x2d, KEY_PLAY }, + { 0x2e, KEY_RECORD }, + { 0x2f, KEY_F17 }, /* picture in picture */ + { 0x30, KEY_KPPLUS }, /* zoom in */ + { 0x31, KEY_KPMINUS }, /* zoom out */ + { 0x32, KEY_F18 }, /* capture */ + { 0x33, KEY_F19 }, /* web */ + { 0x34, KEY_EMAIL }, + { 0x35, KEY_PHONE }, + { 0x36, KEY_PC }, +}; + +struct ir_scancode_table ir_codes_nebula_table = { + .scan = ir_codes_nebula, + .size = ARRAY_SIZE(ir_codes_nebula), +}; +EXPORT_SYMBOL_GPL(ir_codes_nebula_table); + +/* DigitalNow DNTV Live DVB-T Remote */ +static struct ir_scancode ir_codes_dntv_live_dvb_t[] = { + { 0x00, KEY_ESC }, /* 'go up a level?' */ + /* Keys 0 to 9 */ + { 0x0a, KEY_0 }, + { 0x01, KEY_1 }, + { 0x02, KEY_2 }, + { 0x03, KEY_3 }, + { 0x04, KEY_4 }, + { 0x05, KEY_5 }, + { 0x06, KEY_6 }, + { 0x07, KEY_7 }, + { 0x08, KEY_8 }, + { 0x09, KEY_9 }, + + { 0x0b, KEY_TUNER }, /* tv/fm */ + { 0x0c, KEY_SEARCH }, /* scan */ + { 0x0d, KEY_STOP }, + { 0x0e, KEY_PAUSE }, + { 0x0f, KEY_LIST }, /* source */ + + { 0x10, KEY_MUTE }, + { 0x11, KEY_REWIND }, /* backward << */ + { 0x12, KEY_POWER }, + { 0x13, KEY_CAMERA }, /* snap */ + { 0x14, KEY_AUDIO }, /* stereo */ + { 0x15, KEY_CLEAR }, /* reset */ + { 0x16, KEY_PLAY }, + { 0x17, KEY_ENTER }, + { 0x18, KEY_ZOOM }, /* full screen */ + { 0x19, KEY_FASTFORWARD }, /* forward >> */ + { 0x1a, KEY_CHANNELUP }, + { 0x1b, KEY_VOLUMEUP }, + { 0x1c, KEY_INFO }, /* preview */ + { 0x1d, KEY_RECORD }, /* record */ + { 0x1e, KEY_CHANNELDOWN }, + { 0x1f, KEY_VOLUMEDOWN }, +}; + +struct ir_scancode_table ir_codes_dntv_live_dvb_t_table = { + .scan = ir_codes_dntv_live_dvb_t, + .size = ARRAY_SIZE(ir_codes_dntv_live_dvb_t), +}; +EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvb_t_table); + +/* ---------------------------------------------------------------------- */ + +/* IO-DATA BCTV7E Remote */ +static struct ir_scancode ir_codes_iodata_bctv7e[] = { + { 0x40, KEY_TV }, + { 0x20, KEY_RADIO }, /* FM */ + { 0x60, KEY_EPG }, + { 0x00, KEY_POWER }, + + /* Keys 0 to 9 */ + { 0x44, KEY_0 }, /* 10 */ + { 0x50, KEY_1 }, + { 0x30, KEY_2 }, + { 0x70, KEY_3 }, + { 0x48, KEY_4 }, + { 0x28, KEY_5 }, + { 0x68, KEY_6 }, + { 0x58, KEY_7 }, + { 0x38, KEY_8 }, + { 0x78, KEY_9 }, + + { 0x10, KEY_L }, /* Live */ + { 0x08, KEY_TIME }, /* Time Shift */ + + { 0x18, KEY_PLAYPAUSE }, /* Play */ + + { 0x24, KEY_ENTER }, /* 11 */ + { 0x64, KEY_ESC }, /* 12 */ + { 0x04, KEY_M }, /* Multi */ + + { 0x54, KEY_VIDEO }, + { 0x34, KEY_CHANNELUP }, + { 0x74, KEY_VOLUMEUP }, + { 0x14, KEY_MUTE }, + + { 0x4c, KEY_VCR }, /* SVIDEO */ + { 0x2c, KEY_CHANNELDOWN }, + { 0x6c, KEY_VOLUMEDOWN }, + { 0x0c, KEY_ZOOM }, + + { 0x5c, KEY_PAUSE }, + { 0x3c, KEY_RED }, /* || (red) */ + { 0x7c, KEY_RECORD }, /* recording */ + { 0x1c, KEY_STOP }, + + { 0x41, KEY_REWIND }, /* backward << */ + { 0x21, KEY_PLAY }, + { 0x61, KEY_FASTFORWARD }, /* forward >> */ + { 0x01, KEY_NEXT }, /* skip >| */ +}; + +struct ir_scancode_table ir_codes_iodata_bctv7e_table = { + .scan = ir_codes_iodata_bctv7e, + .size = ARRAY_SIZE(ir_codes_iodata_bctv7e), +}; +EXPORT_SYMBOL_GPL(ir_codes_iodata_bctv7e_table); + +/* ---------------------------------------------------------------------- */ + +/* ADS Tech Instant TV DVB-T PCI Remote */ +static struct ir_scancode ir_codes_adstech_dvb_t_pci[] = { + /* Keys 0 to 9 */ + { 0x4d, KEY_0 }, + { 0x57, KEY_1 }, + { 0x4f, KEY_2 }, + { 0x53, KEY_3 }, + { 0x56, KEY_4 }, + { 0x4e, KEY_5 }, + { 0x5e, KEY_6 }, + { 0x54, KEY_7 }, + { 0x4c, KEY_8 }, + { 0x5c, KEY_9 }, + + { 0x5b, KEY_POWER }, + { 0x5f, KEY_MUTE }, + { 0x55, KEY_GOTO }, + { 0x5d, KEY_SEARCH }, + { 0x17, KEY_EPG }, /* Guide */ + { 0x1f, KEY_MENU }, + { 0x0f, KEY_UP }, + { 0x46, KEY_DOWN }, + { 0x16, KEY_LEFT }, + { 0x1e, KEY_RIGHT }, + { 0x0e, KEY_SELECT }, /* Enter */ + { 0x5a, KEY_INFO }, + { 0x52, KEY_EXIT }, + { 0x59, KEY_PREVIOUS }, + { 0x51, KEY_NEXT }, + { 0x58, KEY_REWIND }, + { 0x50, KEY_FORWARD }, + { 0x44, KEY_PLAYPAUSE }, + { 0x07, KEY_STOP }, + { 0x1b, KEY_RECORD }, + { 0x13, KEY_TUNER }, /* Live */ + { 0x0a, KEY_A }, + { 0x12, KEY_B }, + { 0x03, KEY_PROG1 }, /* 1 */ + { 0x01, KEY_PROG2 }, /* 2 */ + { 0x00, KEY_PROG3 }, /* 3 */ + { 0x06, KEY_DVD }, + { 0x48, KEY_AUX }, /* Photo */ + { 0x40, KEY_VIDEO }, + { 0x19, KEY_AUDIO }, /* Music */ + { 0x0b, KEY_CHANNELUP }, + { 0x08, KEY_CHANNELDOWN }, + { 0x15, KEY_VOLUMEUP }, + { 0x1c, KEY_VOLUMEDOWN }, +}; + +struct ir_scancode_table ir_codes_adstech_dvb_t_pci_table = { + .scan = ir_codes_adstech_dvb_t_pci, + .size = ARRAY_SIZE(ir_codes_adstech_dvb_t_pci), +}; +EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t_pci_table); + +/* ---------------------------------------------------------------------- */ + +/* MSI TV@nywhere MASTER remote */ + +static struct ir_scancode ir_codes_msi_tvanywhere[] = { + /* Keys 0 to 9 */ + { 0x00, KEY_0 }, + { 0x01, KEY_1 }, + { 0x02, KEY_2 }, + { 0x03, KEY_3 }, + { 0x04, KEY_4 }, + { 0x05, KEY_5 }, + { 0x06, KEY_6 }, + { 0x07, KEY_7 }, + { 0x08, KEY_8 }, + { 0x09, KEY_9 }, + + { 0x0c, KEY_MUTE }, + { 0x0f, KEY_SCREEN }, /* Full Screen */ + { 0x10, KEY_FN }, /* Funtion */ + { 0x11, KEY_TIME }, /* Time shift */ + { 0x12, KEY_POWER }, + { 0x13, KEY_MEDIA }, /* MTS */ + { 0x14, KEY_SLOW }, + { 0x16, KEY_REWIND }, /* backward << */ + { 0x17, KEY_ENTER }, /* Return */ + { 0x18, KEY_FASTFORWARD }, /* forward >> */ + { 0x1a, KEY_CHANNELUP }, + { 0x1b, KEY_VOLUMEUP }, + { 0x1e, KEY_CHANNELDOWN }, + { 0x1f, KEY_VOLUMEDOWN }, +}; + +struct ir_scancode_table ir_codes_msi_tvanywhere_table = { + .scan = ir_codes_msi_tvanywhere, + .size = ARRAY_SIZE(ir_codes_msi_tvanywhere), +}; +EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_table); + +/* ---------------------------------------------------------------------- */ + +/* + Keycodes for remote on the MSI TV@nywhere Plus. The controller IC on the card + is marked "KS003". The controller is I2C at address 0x30, but does not seem + to respond to probes until a read is performed from a valid device. + I don't know why... + + Note: This remote may be of similar or identical design to the + Pixelview remote (?). The raw codes and duplicate button codes + appear to be the same. + + Henry Wong + Some changes to formatting and keycodes by Mark Schultz + +*/ + +static struct ir_scancode ir_codes_msi_tvanywhere_plus[] = { + +/* ---- Remote Button Layout ---- + + POWER SOURCE SCAN MUTE + TV/FM 1 2 3 + |> 4 5 6 + <| 7 8 9 + ^^UP 0 + RECALL + vvDN RECORD STOP PLAY + + MINIMIZE ZOOM + + CH+ + VOL- VOL+ + CH- + + SNAPSHOT MTS + + << FUNC >> RESET +*/ + + { 0x01, KEY_1 }, /* 1 */ + { 0x0b, KEY_2 }, /* 2 */ + { 0x1b, KEY_3 }, /* 3 */ + { 0x05, KEY_4 }, /* 4 */ + { 0x09, KEY_5 }, /* 5 */ + { 0x15, KEY_6 }, /* 6 */ + { 0x06, KEY_7 }, /* 7 */ + { 0x0a, KEY_8 }, /* 8 */ + { 0x12, KEY_9 }, /* 9 */ + { 0x02, KEY_0 }, /* 0 */ + { 0x10, KEY_KPPLUS }, /* + */ + { 0x13, KEY_AGAIN }, /* Recall */ + + { 0x1e, KEY_POWER }, /* Power */ + { 0x07, KEY_TUNER }, /* Source */ + { 0x1c, KEY_SEARCH }, /* Scan */ + { 0x18, KEY_MUTE }, /* Mute */ + + { 0x03, KEY_RADIO }, /* TV/FM */ + /* The next four keys are duplicates that appear to send the + same IR code as Ch+, Ch-, >>, and << . The raw code assigned + to them is the actual code + 0x20 - they will never be + detected as such unless some way is discovered to distinguish + these buttons from those that have the same code. */ + { 0x3f, KEY_RIGHT }, /* |> and Ch+ */ + { 0x37, KEY_LEFT }, /* <| and Ch- */ + { 0x2c, KEY_UP }, /* ^^Up and >> */ + { 0x24, KEY_DOWN }, /* vvDn and << */ + + { 0x00, KEY_RECORD }, /* Record */ + { 0x08, KEY_STOP }, /* Stop */ + { 0x11, KEY_PLAY }, /* Play */ + + { 0x0f, KEY_CLOSE }, /* Minimize */ + { 0x19, KEY_ZOOM }, /* Zoom */ + { 0x1a, KEY_CAMERA }, /* Snapshot */ + { 0x0d, KEY_LANGUAGE }, /* MTS */ + + { 0x14, KEY_VOLUMEDOWN }, /* Vol- */ + { 0x16, KEY_VOLUMEUP }, /* Vol+ */ + { 0x17, KEY_CHANNELDOWN }, /* Ch- */ + { 0x1f, KEY_CHANNELUP }, /* Ch+ */ + + { 0x04, KEY_REWIND }, /* << */ + { 0x0e, KEY_MENU }, /* Function */ + { 0x0c, KEY_FASTFORWARD }, /* >> */ + { 0x1d, KEY_RESTART }, /* Reset */ +}; + +struct ir_scancode_table ir_codes_msi_tvanywhere_plus_table = { + .scan = ir_codes_msi_tvanywhere_plus, + .size = ARRAY_SIZE(ir_codes_msi_tvanywhere_plus), +}; +EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_plus_table); + +/* ---------------------------------------------------------------------- */ + +/* Cinergy 1400 DVB-T */ +static struct ir_scancode ir_codes_cinergy_1400[] = { + { 0x01, KEY_POWER }, + { 0x02, KEY_1 }, + { 0x03, KEY_2 }, + { 0x04, KEY_3 }, + { 0x05, KEY_4 }, + { 0x06, KEY_5 }, + { 0x07, KEY_6 }, + { 0x08, KEY_7 }, + { 0x09, KEY_8 }, + { 0x0a, KEY_9 }, + { 0x0c, KEY_0 }, + + { 0x0b, KEY_VIDEO }, + { 0x0d, KEY_REFRESH }, + { 0x0e, KEY_SELECT }, + { 0x0f, KEY_EPG }, + { 0x10, KEY_UP }, + { 0x11, KEY_LEFT }, + { 0x12, KEY_OK }, + { 0x13, KEY_RIGHT }, + { 0x14, KEY_DOWN }, + { 0x15, KEY_TEXT }, + { 0x16, KEY_INFO }, + + { 0x17, KEY_RED }, + { 0x18, KEY_GREEN }, + { 0x19, KEY_YELLOW }, + { 0x1a, KEY_BLUE }, + + { 0x1b, KEY_CHANNELUP }, + { 0x1c, KEY_VOLUMEUP }, + { 0x1d, KEY_MUTE }, + { 0x1e, KEY_VOLUMEDOWN }, + { 0x1f, KEY_CHANNELDOWN }, + + { 0x40, KEY_PAUSE }, + { 0x4c, KEY_PLAY }, + { 0x58, KEY_RECORD }, + { 0x54, KEY_PREVIOUS }, + { 0x48, KEY_STOP }, + { 0x5c, KEY_NEXT }, +}; + +struct ir_scancode_table ir_codes_cinergy_1400_table = { + .scan = ir_codes_cinergy_1400, + .size = ARRAY_SIZE(ir_codes_cinergy_1400), +}; +EXPORT_SYMBOL_GPL(ir_codes_cinergy_1400_table); + +/* ---------------------------------------------------------------------- */ + +/* AVERTV STUDIO 303 Remote */ +static struct ir_scancode ir_codes_avertv_303[] = { + { 0x2a, KEY_1 }, + { 0x32, KEY_2 }, + { 0x3a, KEY_3 }, + { 0x4a, KEY_4 }, + { 0x52, KEY_5 }, + { 0x5a, KEY_6 }, + { 0x6a, KEY_7 }, + { 0x72, KEY_8 }, + { 0x7a, KEY_9 }, + { 0x0e, KEY_0 }, + + { 0x02, KEY_POWER }, + { 0x22, KEY_VIDEO }, + { 0x42, KEY_AUDIO }, + { 0x62, KEY_ZOOM }, + { 0x0a, KEY_TV }, + { 0x12, KEY_CD }, + { 0x1a, KEY_TEXT }, + + { 0x16, KEY_SUBTITLE }, + { 0x1e, KEY_REWIND }, + { 0x06, KEY_PRINT }, + + { 0x2e, KEY_SEARCH }, + { 0x36, KEY_SLEEP }, + { 0x3e, KEY_SHUFFLE }, + { 0x26, KEY_MUTE }, + + { 0x4e, KEY_RECORD }, + { 0x56, KEY_PAUSE }, + { 0x5e, KEY_STOP }, + { 0x46, KEY_PLAY }, + + { 0x6e, KEY_RED }, + { 0x0b, KEY_GREEN }, + { 0x66, KEY_YELLOW }, + { 0x03, KEY_BLUE }, + + { 0x76, KEY_LEFT }, + { 0x7e, KEY_RIGHT }, + { 0x13, KEY_DOWN }, + { 0x1b, KEY_UP }, +}; + +struct ir_scancode_table ir_codes_avertv_303_table = { + .scan = ir_codes_avertv_303, + .size = ARRAY_SIZE(ir_codes_avertv_303), +}; +EXPORT_SYMBOL_GPL(ir_codes_avertv_303_table); + +/* ---------------------------------------------------------------------- */ + +/* DigitalNow DNTV Live! DVB-T Pro Remote */ +static struct ir_scancode ir_codes_dntv_live_dvbt_pro[] = { + { 0x16, KEY_POWER }, + { 0x5b, KEY_HOME }, + + { 0x55, KEY_TV }, /* live tv */ + { 0x58, KEY_TUNER }, /* digital Radio */ + { 0x5a, KEY_RADIO }, /* FM radio */ + { 0x59, KEY_DVD }, /* dvd menu */ + { 0x03, KEY_1 }, + { 0x01, KEY_2 }, + { 0x06, KEY_3 }, + { 0x09, KEY_4 }, + { 0x1d, KEY_5 }, + { 0x1f, KEY_6 }, + { 0x0d, KEY_7 }, + { 0x19, KEY_8 }, + { 0x1b, KEY_9 }, + { 0x0c, KEY_CANCEL }, + { 0x15, KEY_0 }, + { 0x4a, KEY_CLEAR }, + { 0x13, KEY_BACK }, + { 0x00, KEY_TAB }, + { 0x4b, KEY_UP }, + { 0x4e, KEY_LEFT }, + { 0x4f, KEY_OK }, + { 0x52, KEY_RIGHT }, + { 0x51, KEY_DOWN }, + { 0x1e, KEY_VOLUMEUP }, + { 0x0a, KEY_VOLUMEDOWN }, + { 0x02, KEY_CHANNELDOWN }, + { 0x05, KEY_CHANNELUP }, + { 0x11, KEY_RECORD }, + { 0x14, KEY_PLAY }, + { 0x4c, KEY_PAUSE }, + { 0x1a, KEY_STOP }, + { 0x40, KEY_REWIND }, + { 0x12, KEY_FASTFORWARD }, + { 0x41, KEY_PREVIOUSSONG }, /* replay |< */ + { 0x42, KEY_NEXTSONG }, /* skip >| */ + { 0x54, KEY_CAMERA }, /* capture */ + { 0x50, KEY_LANGUAGE }, /* sap */ + { 0x47, KEY_TV2 }, /* pip */ + { 0x4d, KEY_SCREEN }, + { 0x43, KEY_SUBTITLE }, + { 0x10, KEY_MUTE }, + { 0x49, KEY_AUDIO }, /* l/r */ + { 0x07, KEY_SLEEP }, + { 0x08, KEY_VIDEO }, /* a/v */ + { 0x0e, KEY_PREVIOUS }, /* recall */ + { 0x45, KEY_ZOOM }, /* zoom + */ + { 0x46, KEY_ANGLE }, /* zoom - */ + { 0x56, KEY_RED }, + { 0x57, KEY_GREEN }, + { 0x5c, KEY_YELLOW }, + { 0x5d, KEY_BLUE }, +}; + +struct ir_scancode_table ir_codes_dntv_live_dvbt_pro_table = { + .scan = ir_codes_dntv_live_dvbt_pro, + .size = ARRAY_SIZE(ir_codes_dntv_live_dvbt_pro), +}; +EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvbt_pro_table); + +static struct ir_scancode ir_codes_em_terratec[] = { + { 0x01, KEY_CHANNEL }, + { 0x02, KEY_SELECT }, + { 0x03, KEY_MUTE }, + { 0x04, KEY_POWER }, + { 0x05, KEY_1 }, + { 0x06, KEY_2 }, + { 0x07, KEY_3 }, + { 0x08, KEY_CHANNELUP }, + { 0x09, KEY_4 }, + { 0x0a, KEY_5 }, + { 0x0b, KEY_6 }, + { 0x0c, KEY_CHANNELDOWN }, + { 0x0d, KEY_7 }, + { 0x0e, KEY_8 }, + { 0x0f, KEY_9 }, + { 0x10, KEY_VOLUMEUP }, + { 0x11, KEY_0 }, + { 0x12, KEY_MENU }, + { 0x13, KEY_PRINT }, + { 0x14, KEY_VOLUMEDOWN }, + { 0x16, KEY_PAUSE }, + { 0x18, KEY_RECORD }, + { 0x19, KEY_REWIND }, + { 0x1a, KEY_PLAY }, + { 0x1b, KEY_FORWARD }, + { 0x1c, KEY_BACKSPACE }, + { 0x1e, KEY_STOP }, + { 0x40, KEY_ZOOM }, +}; + +struct ir_scancode_table ir_codes_em_terratec_table = { + .scan = ir_codes_em_terratec, + .size = ARRAY_SIZE(ir_codes_em_terratec), +}; +EXPORT_SYMBOL_GPL(ir_codes_em_terratec_table); + +static struct ir_scancode ir_codes_pinnacle_grey[] = { + { 0x3a, KEY_0 }, + { 0x31, KEY_1 }, + { 0x32, KEY_2 }, + { 0x33, KEY_3 }, + { 0x34, KEY_4 }, + { 0x35, KEY_5 }, + { 0x36, KEY_6 }, + { 0x37, KEY_7 }, + { 0x38, KEY_8 }, + { 0x39, KEY_9 }, + + { 0x2f, KEY_POWER }, + + { 0x2e, KEY_P }, + { 0x1f, KEY_L }, + { 0x2b, KEY_I }, + + { 0x2d, KEY_SCREEN }, + { 0x1e, KEY_ZOOM }, + { 0x1b, KEY_VOLUMEUP }, + { 0x0f, KEY_VOLUMEDOWN }, + { 0x17, KEY_CHANNELUP }, + { 0x1c, KEY_CHANNELDOWN }, + { 0x25, KEY_INFO }, + + { 0x3c, KEY_MUTE }, + + { 0x3d, KEY_LEFT }, + { 0x3b, KEY_RIGHT }, + + { 0x3f, KEY_UP }, + { 0x3e, KEY_DOWN }, + { 0x1a, KEY_ENTER }, + + { 0x1d, KEY_MENU }, + { 0x19, KEY_AGAIN }, + { 0x16, KEY_PREVIOUSSONG }, + { 0x13, KEY_NEXTSONG }, + { 0x15, KEY_PAUSE }, + { 0x0e, KEY_REWIND }, + { 0x0d, KEY_PLAY }, + { 0x0b, KEY_STOP }, + { 0x07, KEY_FORWARD }, + { 0x27, KEY_RECORD }, + { 0x26, KEY_TUNER }, + { 0x29, KEY_TEXT }, + { 0x2a, KEY_MEDIA }, + { 0x18, KEY_EPG }, +}; + +struct ir_scancode_table ir_codes_pinnacle_grey_table = { + .scan = ir_codes_pinnacle_grey, + .size = ARRAY_SIZE(ir_codes_pinnacle_grey), +}; +EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey_table); + +static struct ir_scancode ir_codes_flyvideo[] = { + { 0x0f, KEY_0 }, + { 0x03, KEY_1 }, + { 0x04, KEY_2 }, + { 0x05, KEY_3 }, + { 0x07, KEY_4 }, + { 0x08, KEY_5 }, + { 0x09, KEY_6 }, + { 0x0b, KEY_7 }, + { 0x0c, KEY_8 }, + { 0x0d, KEY_9 }, + + { 0x0e, KEY_MODE }, /* Air/Cable */ + { 0x11, KEY_VIDEO }, /* Video */ + { 0x15, KEY_AUDIO }, /* Audio */ + { 0x00, KEY_POWER }, /* Power */ + { 0x18, KEY_TUNER }, /* AV Source */ + { 0x02, KEY_ZOOM }, /* Fullscreen */ + { 0x1a, KEY_LANGUAGE }, /* Stereo */ + { 0x1b, KEY_MUTE }, /* Mute */ + { 0x14, KEY_VOLUMEUP }, /* Volume + */ + { 0x17, KEY_VOLUMEDOWN },/* Volume - */ + { 0x12, KEY_CHANNELUP },/* Channel + */ + { 0x13, KEY_CHANNELDOWN },/* Channel - */ + { 0x06, KEY_AGAIN }, /* Recall */ + { 0x10, KEY_ENTER }, /* Enter */ + + { 0x19, KEY_BACK }, /* Rewind ( <<< ) */ + { 0x1f, KEY_FORWARD }, /* Forward ( >>> ) */ + { 0x0a, KEY_ANGLE }, /* no label, may be used as the PAUSE button */ +}; + +struct ir_scancode_table ir_codes_flyvideo_table = { + .scan = ir_codes_flyvideo, + .size = ARRAY_SIZE(ir_codes_flyvideo), +}; +EXPORT_SYMBOL_GPL(ir_codes_flyvideo_table); + +static struct ir_scancode ir_codes_flydvb[] = { + { 0x01, KEY_ZOOM }, /* Full Screen */ + { 0x00, KEY_POWER }, /* Power */ + + { 0x03, KEY_1 }, + { 0x04, KEY_2 }, + { 0x05, KEY_3 }, + { 0x07, KEY_4 }, + { 0x08, KEY_5 }, + { 0x09, KEY_6 }, + { 0x0b, KEY_7 }, + { 0x0c, KEY_8 }, + { 0x0d, KEY_9 }, + { 0x06, KEY_AGAIN }, /* Recall */ + { 0x0f, KEY_0 }, + { 0x10, KEY_MUTE }, /* Mute */ + { 0x02, KEY_RADIO }, /* TV/Radio */ + { 0x1b, KEY_LANGUAGE }, /* SAP (Second Audio Program) */ + + { 0x14, KEY_VOLUMEUP }, /* VOL+ */ + { 0x17, KEY_VOLUMEDOWN }, /* VOL- */ + { 0x12, KEY_CHANNELUP }, /* CH+ */ + { 0x13, KEY_CHANNELDOWN }, /* CH- */ + { 0x1d, KEY_ENTER }, /* Enter */ + + { 0x1a, KEY_MODE }, /* PIP */ + { 0x18, KEY_TUNER }, /* Source */ + + { 0x1e, KEY_RECORD }, /* Record/Pause */ + { 0x15, KEY_ANGLE }, /* Swap (no label on key) */ + { 0x1c, KEY_PAUSE }, /* Timeshift/Pause */ + { 0x19, KEY_BACK }, /* Rewind << */ + { 0x0a, KEY_PLAYPAUSE }, /* Play/Pause */ + { 0x1f, KEY_FORWARD }, /* Forward >> */ + { 0x16, KEY_PREVIOUS }, /* Back |<< */ + { 0x11, KEY_STOP }, /* Stop */ + { 0x0e, KEY_NEXT }, /* End >>| */ +}; + +struct ir_scancode_table ir_codes_flydvb_table = { + .scan = ir_codes_flydvb, + .size = ARRAY_SIZE(ir_codes_flydvb), +}; +EXPORT_SYMBOL_GPL(ir_codes_flydvb_table); + +static struct ir_scancode ir_codes_cinergy[] = { + { 0x00, KEY_0 }, + { 0x01, KEY_1 }, + { 0x02, KEY_2 }, + { 0x03, KEY_3 }, + { 0x04, KEY_4 }, + { 0x05, KEY_5 }, + { 0x06, KEY_6 }, + { 0x07, KEY_7 }, + { 0x08, KEY_8 }, + { 0x09, KEY_9 }, + + { 0x0a, KEY_POWER }, + { 0x0b, KEY_PROG1 }, /* app */ + { 0x0c, KEY_ZOOM }, /* zoom/fullscreen */ + { 0x0d, KEY_CHANNELUP }, /* channel */ + { 0x0e, KEY_CHANNELDOWN }, /* channel- */ + { 0x0f, KEY_VOLUMEUP }, + { 0x10, KEY_VOLUMEDOWN }, + { 0x11, KEY_TUNER }, /* AV */ + { 0x12, KEY_NUMLOCK }, /* -/-- */ + { 0x13, KEY_AUDIO }, /* audio */ + { 0x14, KEY_MUTE }, + { 0x15, KEY_UP }, + { 0x16, KEY_DOWN }, + { 0x17, KEY_LEFT }, + { 0x18, KEY_RIGHT }, + { 0x19, BTN_LEFT, }, + { 0x1a, BTN_RIGHT, }, + { 0x1b, KEY_WWW }, /* text */ + { 0x1c, KEY_REWIND }, + { 0x1d, KEY_FORWARD }, + { 0x1e, KEY_RECORD }, + { 0x1f, KEY_PLAY }, + { 0x20, KEY_PREVIOUSSONG }, + { 0x21, KEY_NEXTSONG }, + { 0x22, KEY_PAUSE }, + { 0x23, KEY_STOP }, +}; + +struct ir_scancode_table ir_codes_cinergy_table = { + .scan = ir_codes_cinergy, + .size = ARRAY_SIZE(ir_codes_cinergy), +}; +EXPORT_SYMBOL_GPL(ir_codes_cinergy_table); + +/* Alfons Geser + * updates from Job D. R. Borges */ +static struct ir_scancode ir_codes_eztv[] = { + { 0x12, KEY_POWER }, + { 0x01, KEY_TV }, /* DVR */ + { 0x15, KEY_DVD }, /* DVD */ + { 0x17, KEY_AUDIO }, /* music */ + /* DVR mode / DVD mode / music mode */ + + { 0x1b, KEY_MUTE }, /* mute */ + { 0x02, KEY_LANGUAGE }, /* MTS/SAP / audio / autoseek */ + { 0x1e, KEY_SUBTITLE }, /* closed captioning / subtitle / seek */ + { 0x16, KEY_ZOOM }, /* full screen */ + { 0x1c, KEY_VIDEO }, /* video source / eject / delall */ + { 0x1d, KEY_RESTART }, /* playback / angle / del */ + { 0x2f, KEY_SEARCH }, /* scan / menu / playlist */ + { 0x30, KEY_CHANNEL }, /* CH surfing / bookmark / memo */ + + { 0x31, KEY_HELP }, /* help */ + { 0x32, KEY_MODE }, /* num/memo */ + { 0x33, KEY_ESC }, /* cancel */ + + { 0x0c, KEY_UP }, /* up */ + { 0x10, KEY_DOWN }, /* down */ + { 0x08, KEY_LEFT }, /* left */ + { 0x04, KEY_RIGHT }, /* right */ + { 0x03, KEY_SELECT }, /* select */ + + { 0x1f, KEY_REWIND }, /* rewind */ + { 0x20, KEY_PLAYPAUSE },/* play/pause */ + { 0x29, KEY_FORWARD }, /* forward */ + { 0x14, KEY_AGAIN }, /* repeat */ + { 0x2b, KEY_RECORD }, /* recording */ + { 0x2c, KEY_STOP }, /* stop */ + { 0x2d, KEY_PLAY }, /* play */ + { 0x2e, KEY_CAMERA }, /* snapshot / shuffle */ + + { 0x00, KEY_0 }, + { 0x05, KEY_1 }, + { 0x06, KEY_2 }, + { 0x07, KEY_3 }, + { 0x09, KEY_4 }, + { 0x0a, KEY_5 }, + { 0x0b, KEY_6 }, + { 0x0d, KEY_7 }, + { 0x0e, KEY_8 }, + { 0x0f, KEY_9 }, + + { 0x2a, KEY_VOLUMEUP }, + { 0x11, KEY_VOLUMEDOWN }, + { 0x18, KEY_CHANNELUP },/* CH.tracking up */ + { 0x19, KEY_CHANNELDOWN },/* CH.tracking down */ + + { 0x13, KEY_ENTER }, /* enter */ + { 0x21, KEY_DOT }, /* . (decimal dot) */ +}; + +struct ir_scancode_table ir_codes_eztv_table = { + .scan = ir_codes_eztv, + .size = ARRAY_SIZE(ir_codes_eztv), +}; +EXPORT_SYMBOL_GPL(ir_codes_eztv_table); + +/* Alex Hermann */ +static struct ir_scancode ir_codes_avermedia[] = { + { 0x28, KEY_1 }, + { 0x18, KEY_2 }, + { 0x38, KEY_3 }, + { 0x24, KEY_4 }, + { 0x14, KEY_5 }, + { 0x34, KEY_6 }, + { 0x2c, KEY_7 }, + { 0x1c, KEY_8 }, + { 0x3c, KEY_9 }, + { 0x22, KEY_0 }, + + { 0x20, KEY_TV }, /* TV/FM */ + { 0x10, KEY_CD }, /* CD */ + { 0x30, KEY_TEXT }, /* TELETEXT */ + { 0x00, KEY_POWER }, /* POWER */ + + { 0x08, KEY_VIDEO }, /* VIDEO */ + { 0x04, KEY_AUDIO }, /* AUDIO */ + { 0x0c, KEY_ZOOM }, /* FULL SCREEN */ + + { 0x12, KEY_SUBTITLE }, /* DISPLAY */ + { 0x32, KEY_REWIND }, /* LOOP */ + { 0x02, KEY_PRINT }, /* PREVIEW */ + + { 0x2a, KEY_SEARCH }, /* AUTOSCAN */ + { 0x1a, KEY_SLEEP }, /* FREEZE */ + { 0x3a, KEY_CAMERA }, /* SNAPSHOT */ + { 0x0a, KEY_MUTE }, /* MUTE */ + + { 0x26, KEY_RECORD }, /* RECORD */ + { 0x16, KEY_PAUSE }, /* PAUSE */ + { 0x36, KEY_STOP }, /* STOP */ + { 0x06, KEY_PLAY }, /* PLAY */ + + { 0x2e, KEY_RED }, /* RED */ + { 0x21, KEY_GREEN }, /* GREEN */ + { 0x0e, KEY_YELLOW }, /* YELLOW */ + { 0x01, KEY_BLUE }, /* BLUE */ + + { 0x1e, KEY_VOLUMEDOWN }, /* VOLUME- */ + { 0x3e, KEY_VOLUMEUP }, /* VOLUME+ */ + { 0x11, KEY_CHANNELDOWN }, /* CHANNEL/PAGE- */ + { 0x31, KEY_CHANNELUP } /* CHANNEL/PAGE+ */ +}; + +struct ir_scancode_table ir_codes_avermedia_table = { + .scan = ir_codes_avermedia, + .size = ARRAY_SIZE(ir_codes_avermedia), +}; +EXPORT_SYMBOL_GPL(ir_codes_avermedia_table); + +static struct ir_scancode ir_codes_videomate_tv_pvr[] = { + { 0x14, KEY_MUTE }, + { 0x24, KEY_ZOOM }, + + { 0x01, KEY_DVD }, + { 0x23, KEY_RADIO }, + { 0x00, KEY_TV }, + + { 0x0a, KEY_REWIND }, + { 0x08, KEY_PLAYPAUSE }, + { 0x0f, KEY_FORWARD }, + + { 0x02, KEY_PREVIOUS }, + { 0x07, KEY_STOP }, + { 0x06, KEY_NEXT }, + + { 0x0c, KEY_UP }, + { 0x0e, KEY_DOWN }, + { 0x0b, KEY_LEFT }, + { 0x0d, KEY_RIGHT }, + { 0x11, KEY_OK }, + + { 0x03, KEY_MENU }, + { 0x09, KEY_SETUP }, + { 0x05, KEY_VIDEO }, + { 0x22, KEY_CHANNEL }, + + { 0x12, KEY_VOLUMEUP }, + { 0x15, KEY_VOLUMEDOWN }, + { 0x10, KEY_CHANNELUP }, + { 0x13, KEY_CHANNELDOWN }, + + { 0x04, KEY_RECORD }, + + { 0x16, KEY_1 }, + { 0x17, KEY_2 }, + { 0x18, KEY_3 }, + { 0x19, KEY_4 }, + { 0x1a, KEY_5 }, + { 0x1b, KEY_6 }, + { 0x1c, KEY_7 }, + { 0x1d, KEY_8 }, + { 0x1e, KEY_9 }, + { 0x1f, KEY_0 }, + + { 0x20, KEY_LANGUAGE }, + { 0x21, KEY_SLEEP }, +}; + +struct ir_scancode_table ir_codes_videomate_tv_pvr_table = { + .scan = ir_codes_videomate_tv_pvr, + .size = ARRAY_SIZE(ir_codes_videomate_tv_pvr), +}; +EXPORT_SYMBOL_GPL(ir_codes_videomate_tv_pvr_table); + +/* Michael Tokarev + http://www.corpit.ru/mjt/beholdTV/remote_control.jpg + keytable is used by MANLI MTV00[0x0c] and BeholdTV 40[13] at + least, and probably other cards too. + The "ascii-art picture" below (in comments, first row + is the keycode in hex, and subsequent row(s) shows + the button labels (several variants when appropriate) + helps to descide which keycodes to assign to the buttons. + */ +static struct ir_scancode ir_codes_manli[] = { + + /* 0x1c 0x12 * + * FUNCTION POWER * + * FM (|) * + * */ + { 0x1c, KEY_RADIO }, /*XXX*/ + { 0x12, KEY_POWER }, + + /* 0x01 0x02 0x03 * + * 1 2 3 * + * * + * 0x04 0x05 0x06 * + * 4 5 6 * + * * + * 0x07 0x08 0x09 * + * 7 8 9 * + * */ + { 0x01, KEY_1 }, + { 0x02, KEY_2 }, + { 0x03, KEY_3 }, + { 0x04, KEY_4 }, + { 0x05, KEY_5 }, + { 0x06, KEY_6 }, + { 0x07, KEY_7 }, + { 0x08, KEY_8 }, + { 0x09, KEY_9 }, + + /* 0x0a 0x00 0x17 * + * RECALL 0 +100 * + * PLUS * + * */ + { 0x0a, KEY_AGAIN }, /*XXX KEY_REWIND? */ + { 0x00, KEY_0 }, + { 0x17, KEY_DIGITS }, /*XXX*/ + + /* 0x14 0x10 * + * MENU INFO * + * OSD */ + { 0x14, KEY_MENU }, + { 0x10, KEY_INFO }, + + /* 0x0b * + * Up * + * * + * 0x18 0x16 0x0c * + * Left Ok Right * + * * + * 0x015 * + * Down * + * */ + { 0x0b, KEY_UP }, + { 0x18, KEY_LEFT }, + { 0x16, KEY_OK }, /*XXX KEY_SELECT? KEY_ENTER? */ + { 0x0c, KEY_RIGHT }, + { 0x15, KEY_DOWN }, + + /* 0x11 0x0d * + * TV/AV MODE * + * SOURCE STEREO * + * */ + { 0x11, KEY_TV }, /*XXX*/ + { 0x0d, KEY_MODE }, /*XXX there's no KEY_STEREO */ + + /* 0x0f 0x1b 0x1a * + * AUDIO Vol+ Chan+ * + * TIMESHIFT??? * + * * + * 0x0e 0x1f 0x1e * + * SLEEP Vol- Chan- * + * */ + { 0x0f, KEY_AUDIO }, + { 0x1b, KEY_VOLUMEUP }, + { 0x1a, KEY_CHANNELUP }, + { 0x0e, KEY_TIME }, + { 0x1f, KEY_VOLUMEDOWN }, + { 0x1e, KEY_CHANNELDOWN }, + + /* 0x13 0x19 * + * MUTE SNAPSHOT* + * */ + { 0x13, KEY_MUTE }, + { 0x19, KEY_CAMERA }, + + /* 0x1d unused ? */ +}; + +struct ir_scancode_table ir_codes_manli_table = { + .scan = ir_codes_manli, + .size = ARRAY_SIZE(ir_codes_manli), +}; +EXPORT_SYMBOL_GPL(ir_codes_manli_table); + +/* Mike Baikov */ +static struct ir_scancode ir_codes_gotview7135[] = { + + { 0x11, KEY_POWER }, + { 0x35, KEY_TV }, + { 0x1b, KEY_0 }, + { 0x29, KEY_1 }, + { 0x19, KEY_2 }, + { 0x39, KEY_3 }, + { 0x1f, KEY_4 }, + { 0x2c, KEY_5 }, + { 0x21, KEY_6 }, + { 0x24, KEY_7 }, + { 0x18, KEY_8 }, + { 0x2b, KEY_9 }, + { 0x3b, KEY_AGAIN }, /* LOOP */ + { 0x06, KEY_AUDIO }, + { 0x31, KEY_PRINT }, /* PREVIEW */ + { 0x3e, KEY_VIDEO }, + { 0x10, KEY_CHANNELUP }, + { 0x20, KEY_CHANNELDOWN }, + { 0x0c, KEY_VOLUMEDOWN }, + { 0x28, KEY_VOLUMEUP }, + { 0x08, KEY_MUTE }, + { 0x26, KEY_SEARCH }, /* SCAN */ + { 0x3f, KEY_CAMERA }, /* SNAPSHOT */ + { 0x12, KEY_RECORD }, + { 0x32, KEY_STOP }, + { 0x3c, KEY_PLAY }, + { 0x1d, KEY_REWIND }, + { 0x2d, KEY_PAUSE }, + { 0x0d, KEY_FORWARD }, + { 0x05, KEY_ZOOM }, /*FULL*/ + + { 0x2a, KEY_F21 }, /* LIVE TIMESHIFT */ + { 0x0e, KEY_F22 }, /* MIN TIMESHIFT */ + { 0x1e, KEY_TIME }, /* TIMESHIFT */ + { 0x38, KEY_F24 }, /* NORMAL TIMESHIFT */ +}; + +struct ir_scancode_table ir_codes_gotview7135_table = { + .scan = ir_codes_gotview7135, + .size = ARRAY_SIZE(ir_codes_gotview7135), +}; +EXPORT_SYMBOL_GPL(ir_codes_gotview7135_table); + +static struct ir_scancode ir_codes_purpletv[] = { + { 0x03, KEY_POWER }, + { 0x6f, KEY_MUTE }, + { 0x10, KEY_BACKSPACE }, /* Recall */ + + { 0x11, KEY_0 }, + { 0x04, KEY_1 }, + { 0x05, KEY_2 }, + { 0x06, KEY_3 }, + { 0x08, KEY_4 }, + { 0x09, KEY_5 }, + { 0x0a, KEY_6 }, + { 0x0c, KEY_7 }, + { 0x0d, KEY_8 }, + { 0x0e, KEY_9 }, + { 0x12, KEY_DOT }, /* 100+ */ + + { 0x07, KEY_VOLUMEUP }, + { 0x0b, KEY_VOLUMEDOWN }, + { 0x1a, KEY_KPPLUS }, + { 0x18, KEY_KPMINUS }, + { 0x15, KEY_UP }, + { 0x1d, KEY_DOWN }, + { 0x0f, KEY_CHANNELUP }, + { 0x13, KEY_CHANNELDOWN }, + { 0x48, KEY_ZOOM }, + + { 0x1b, KEY_VIDEO }, /* Video source */ + { 0x1f, KEY_CAMERA }, /* Snapshot */ + { 0x49, KEY_LANGUAGE }, /* MTS Select */ + { 0x19, KEY_SEARCH }, /* Auto Scan */ + + { 0x4b, KEY_RECORD }, + { 0x46, KEY_PLAY }, + { 0x45, KEY_PAUSE }, /* Pause */ + { 0x44, KEY_STOP }, + { 0x43, KEY_TIME }, /* Time Shift */ + { 0x17, KEY_CHANNEL }, /* SURF CH */ + { 0x40, KEY_FORWARD }, /* Forward ? */ + { 0x42, KEY_REWIND }, /* Backward ? */ + +}; + +struct ir_scancode_table ir_codes_purpletv_table = { + .scan = ir_codes_purpletv, + .size = ARRAY_SIZE(ir_codes_purpletv), +}; +EXPORT_SYMBOL_GPL(ir_codes_purpletv_table); + +/* Mapping for the 28 key remote control as seen at + http://www.sednacomputer.com/photo/cardbus-tv.jpg + Pavel Mihaylov + Also for the remote bundled with Kozumi KTV-01C card */ +static struct ir_scancode ir_codes_pctv_sedna[] = { + { 0x00, KEY_0 }, + { 0x01, KEY_1 }, + { 0x02, KEY_2 }, + { 0x03, KEY_3 }, + { 0x04, KEY_4 }, + { 0x05, KEY_5 }, + { 0x06, KEY_6 }, + { 0x07, KEY_7 }, + { 0x08, KEY_8 }, + { 0x09, KEY_9 }, + + { 0x0a, KEY_AGAIN }, /* Recall */ + { 0x0b, KEY_CHANNELUP }, + { 0x0c, KEY_VOLUMEUP }, + { 0x0d, KEY_MODE }, /* Stereo */ + { 0x0e, KEY_STOP }, + { 0x0f, KEY_PREVIOUSSONG }, + { 0x10, KEY_ZOOM }, + { 0x11, KEY_TUNER }, /* Source */ + { 0x12, KEY_POWER }, + { 0x13, KEY_MUTE }, + { 0x15, KEY_CHANNELDOWN }, + { 0x18, KEY_VOLUMEDOWN }, + { 0x19, KEY_CAMERA }, /* Snapshot */ + { 0x1a, KEY_NEXTSONG }, + { 0x1b, KEY_TIME }, /* Time Shift */ + { 0x1c, KEY_RADIO }, /* FM Radio */ + { 0x1d, KEY_RECORD }, + { 0x1e, KEY_PAUSE }, + /* additional codes for Kozumi's remote */ + { 0x14, KEY_INFO }, /* OSD */ + { 0x16, KEY_OK }, /* OK */ + { 0x17, KEY_DIGITS }, /* Plus */ + { 0x1f, KEY_PLAY }, /* Play */ +}; + +struct ir_scancode_table ir_codes_pctv_sedna_table = { + .scan = ir_codes_pctv_sedna, + .size = ARRAY_SIZE(ir_codes_pctv_sedna), +}; +EXPORT_SYMBOL_GPL(ir_codes_pctv_sedna_table); + +/* Mark Phalan */ +static struct ir_scancode ir_codes_pv951[] = { + { 0x00, KEY_0 }, + { 0x01, KEY_1 }, + { 0x02, KEY_2 }, + { 0x03, KEY_3 }, + { 0x04, KEY_4 }, + { 0x05, KEY_5 }, + { 0x06, KEY_6 }, + { 0x07, KEY_7 }, + { 0x08, KEY_8 }, + { 0x09, KEY_9 }, + + { 0x12, KEY_POWER }, + { 0x10, KEY_MUTE }, + { 0x1f, KEY_VOLUMEDOWN }, + { 0x1b, KEY_VOLUMEUP }, + { 0x1a, KEY_CHANNELUP }, + { 0x1e, KEY_CHANNELDOWN }, + { 0x0e, KEY_PAGEUP }, + { 0x1d, KEY_PAGEDOWN }, + { 0x13, KEY_SOUND }, + + { 0x18, KEY_KPPLUSMINUS }, /* CH +/- */ + { 0x16, KEY_SUBTITLE }, /* CC */ + { 0x0d, KEY_TEXT }, /* TTX */ + { 0x0b, KEY_TV }, /* AIR/CBL */ + { 0x11, KEY_PC }, /* PC/TV */ + { 0x17, KEY_OK }, /* CH RTN */ + { 0x19, KEY_MODE }, /* FUNC */ + { 0x0c, KEY_SEARCH }, /* AUTOSCAN */ + + /* Not sure what to do with these ones! */ + { 0x0f, KEY_SELECT }, /* SOURCE */ + { 0x0a, KEY_KPPLUS }, /* +100 */ + { 0x14, KEY_EQUAL }, /* SYNC */ + { 0x1c, KEY_MEDIA }, /* PC/TV */ +}; + +struct ir_scancode_table ir_codes_pv951_table = { + .scan = ir_codes_pv951, + .size = ARRAY_SIZE(ir_codes_pv951), +}; +EXPORT_SYMBOL_GPL(ir_codes_pv951_table); + +/* generic RC5 keytable */ +/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */ +/* used by old (black) Hauppauge remotes */ +static struct ir_scancode ir_codes_rc5_tv[] = { + /* Keys 0 to 9 */ + { 0x00, KEY_0 }, + { 0x01, KEY_1 }, + { 0x02, KEY_2 }, + { 0x03, KEY_3 }, + { 0x04, KEY_4 }, + { 0x05, KEY_5 }, + { 0x06, KEY_6 }, + { 0x07, KEY_7 }, + { 0x08, KEY_8 }, + { 0x09, KEY_9 }, + + { 0x0b, KEY_CHANNEL }, /* channel / program (japan: 11) */ + { 0x0c, KEY_POWER }, /* standby */ + { 0x0d, KEY_MUTE }, /* mute / demute */ + { 0x0f, KEY_TV }, /* display */ + { 0x10, KEY_VOLUMEUP }, + { 0x11, KEY_VOLUMEDOWN }, + { 0x12, KEY_BRIGHTNESSUP }, + { 0x13, KEY_BRIGHTNESSDOWN }, + { 0x1e, KEY_SEARCH }, /* search + */ + { 0x20, KEY_CHANNELUP }, /* channel / program + */ + { 0x21, KEY_CHANNELDOWN }, /* channel / program - */ + { 0x22, KEY_CHANNEL }, /* alt / channel */ + { 0x23, KEY_LANGUAGE }, /* 1st / 2nd language */ + { 0x26, KEY_SLEEP }, /* sleeptimer */ + { 0x2e, KEY_MENU }, /* 2nd controls (USA: menu) */ + { 0x30, KEY_PAUSE }, + { 0x32, KEY_REWIND }, + { 0x33, KEY_GOTO }, + { 0x35, KEY_PLAY }, + { 0x36, KEY_STOP }, + { 0x37, KEY_RECORD }, /* recording */ + { 0x3c, KEY_TEXT }, /* teletext submode (Japan: 12) */ + { 0x3d, KEY_SUSPEND }, /* system standby */ + +}; + +struct ir_scancode_table ir_codes_rc5_tv_table = { + .scan = ir_codes_rc5_tv, + .size = ARRAY_SIZE(ir_codes_rc5_tv), +}; +EXPORT_SYMBOL_GPL(ir_codes_rc5_tv_table); + +/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */ +static struct ir_scancode ir_codes_winfast[] = { + /* Keys 0 to 9 */ + { 0x12, KEY_0 }, + { 0x05, KEY_1 }, + { 0x06, KEY_2 }, + { 0x07, KEY_3 }, + { 0x09, KEY_4 }, + { 0x0a, KEY_5 }, + { 0x0b, KEY_6 }, + { 0x0d, KEY_7 }, + { 0x0e, KEY_8 }, + { 0x0f, KEY_9 }, + + { 0x00, KEY_POWER }, + { 0x1b, KEY_AUDIO }, /* Audio Source */ + { 0x02, KEY_TUNER }, /* TV/FM, not on Y0400052 */ + { 0x1e, KEY_VIDEO }, /* Video Source */ + { 0x16, KEY_INFO }, /* Display information */ + { 0x04, KEY_VOLUMEUP }, + { 0x08, KEY_VOLUMEDOWN }, + { 0x0c, KEY_CHANNELUP }, + { 0x10, KEY_CHANNELDOWN }, + { 0x03, KEY_ZOOM }, /* fullscreen */ + { 0x1f, KEY_TEXT }, /* closed caption/teletext */ + { 0x20, KEY_SLEEP }, + { 0x29, KEY_CLEAR }, /* boss key */ + { 0x14, KEY_MUTE }, + { 0x2b, KEY_RED }, + { 0x2c, KEY_GREEN }, + { 0x2d, KEY_YELLOW }, + { 0x2e, KEY_BLUE }, + { 0x18, KEY_KPPLUS }, /* fine tune + , not on Y040052 */ + { 0x19, KEY_KPMINUS }, /* fine tune - , not on Y040052 */ + { 0x2a, KEY_MEDIA }, /* PIP (Picture in picture */ + { 0x21, KEY_DOT }, + { 0x13, KEY_ENTER }, + { 0x11, KEY_LAST }, /* Recall (last channel */ + { 0x22, KEY_PREVIOUS }, + { 0x23, KEY_PLAYPAUSE }, + { 0x24, KEY_NEXT }, + { 0x25, KEY_TIME }, /* Time Shifting */ + { 0x26, KEY_STOP }, + { 0x27, KEY_RECORD }, + { 0x28, KEY_SAVE }, /* Screenshot */ + { 0x2f, KEY_MENU }, + { 0x30, KEY_CANCEL }, + { 0x31, KEY_CHANNEL }, /* Channel Surf */ + { 0x32, KEY_SUBTITLE }, + { 0x33, KEY_LANGUAGE }, + { 0x34, KEY_REWIND }, + { 0x35, KEY_FASTFORWARD }, + { 0x36, KEY_TV }, + { 0x37, KEY_RADIO }, /* FM */ + { 0x38, KEY_DVD }, + + { 0x1a, KEY_MODE}, /* change to MCE mode on Y04G0051 */ + { 0x3e, KEY_F21 }, /* MCE +VOL, on Y04G0033 */ + { 0x3a, KEY_F22 }, /* MCE -VOL, on Y04G0033 */ + { 0x3b, KEY_F23 }, /* MCE +CH, on Y04G0033 */ + { 0x3f, KEY_F24 } /* MCE -CH, on Y04G0033 */ +}; + +struct ir_scancode_table ir_codes_winfast_table = { + .scan = ir_codes_winfast, + .size = ARRAY_SIZE(ir_codes_winfast), +}; +EXPORT_SYMBOL_GPL(ir_codes_winfast_table); + +static struct ir_scancode ir_codes_pinnacle_color[] = { + { 0x59, KEY_MUTE }, + { 0x4a, KEY_POWER }, + + { 0x18, KEY_TEXT }, + { 0x26, KEY_TV }, + { 0x3d, KEY_PRINT }, + + { 0x48, KEY_RED }, + { 0x04, KEY_GREEN }, + { 0x11, KEY_YELLOW }, + { 0x00, KEY_BLUE }, + + { 0x2d, KEY_VOLUMEUP }, + { 0x1e, KEY_VOLUMEDOWN }, + + { 0x49, KEY_MENU }, + + { 0x16, KEY_CHANNELUP }, + { 0x17, KEY_CHANNELDOWN }, + + { 0x20, KEY_UP }, + { 0x21, KEY_DOWN }, + { 0x22, KEY_LEFT }, + { 0x23, KEY_RIGHT }, + { 0x0d, KEY_SELECT }, + + { 0x08, KEY_BACK }, + { 0x07, KEY_REFRESH }, + + { 0x2f, KEY_ZOOM }, + { 0x29, KEY_RECORD }, + + { 0x4b, KEY_PAUSE }, + { 0x4d, KEY_REWIND }, + { 0x2e, KEY_PLAY }, + { 0x4e, KEY_FORWARD }, + { 0x53, KEY_PREVIOUS }, + { 0x4c, KEY_STOP }, + { 0x54, KEY_NEXT }, + + { 0x69, KEY_0 }, + { 0x6a, KEY_1 }, + { 0x6b, KEY_2 }, + { 0x6c, KEY_3 }, + { 0x6d, KEY_4 }, + { 0x6e, KEY_5 }, + { 0x6f, KEY_6 }, + { 0x70, KEY_7 }, + { 0x71, KEY_8 }, + { 0x72, KEY_9 }, + + { 0x74, KEY_CHANNEL }, + { 0x0a, KEY_BACKSPACE }, +}; + +struct ir_scancode_table ir_codes_pinnacle_color_table = { + .scan = ir_codes_pinnacle_color, + .size = ARRAY_SIZE(ir_codes_pinnacle_color), +}; +EXPORT_SYMBOL_GPL(ir_codes_pinnacle_color_table); + +/* Hauppauge: the newer, gray remotes (seems there are multiple + * slightly different versions), shipped with cx88+ivtv cards. + * almost rc5 coding, but some non-standard keys */ +static struct ir_scancode ir_codes_hauppauge_new[] = { + /* Keys 0 to 9 */ + { 0x00, KEY_0 }, + { 0x01, KEY_1 }, + { 0x02, KEY_2 }, + { 0x03, KEY_3 }, + { 0x04, KEY_4 }, + { 0x05, KEY_5 }, + { 0x06, KEY_6 }, + { 0x07, KEY_7 }, + { 0x08, KEY_8 }, + { 0x09, KEY_9 }, + + { 0x0a, KEY_TEXT }, /* keypad asterisk as well */ + { 0x0b, KEY_RED }, /* red button */ + { 0x0c, KEY_RADIO }, + { 0x0d, KEY_MENU }, + { 0x0e, KEY_SUBTITLE }, /* also the # key */ + { 0x0f, KEY_MUTE }, + { 0x10, KEY_VOLUMEUP }, + { 0x11, KEY_VOLUMEDOWN }, + { 0x12, KEY_PREVIOUS }, /* previous channel */ + { 0x14, KEY_UP }, + { 0x15, KEY_DOWN }, + { 0x16, KEY_LEFT }, + { 0x17, KEY_RIGHT }, + { 0x18, KEY_VIDEO }, /* Videos */ + { 0x19, KEY_AUDIO }, /* Music */ + /* 0x1a: Pictures - presume this means + "Multimedia Home Platform" - + no "PICTURES" key in input.h + */ + { 0x1a, KEY_MHP }, + + { 0x1b, KEY_EPG }, /* Guide */ + { 0x1c, KEY_TV }, + { 0x1e, KEY_NEXTSONG }, /* skip >| */ + { 0x1f, KEY_EXIT }, /* back/exit */ + { 0x20, KEY_CHANNELUP }, /* channel / program + */ + { 0x21, KEY_CHANNELDOWN }, /* channel / program - */ + { 0x22, KEY_CHANNEL }, /* source (old black remote) */ + { 0x24, KEY_PREVIOUSSONG }, /* replay |< */ + { 0x25, KEY_ENTER }, /* OK */ + { 0x26, KEY_SLEEP }, /* minimize (old black remote) */ + { 0x29, KEY_BLUE }, /* blue key */ + { 0x2e, KEY_GREEN }, /* green button */ + { 0x30, KEY_PAUSE }, /* pause */ + { 0x32, KEY_REWIND }, /* backward << */ + { 0x34, KEY_FASTFORWARD }, /* forward >> */ + { 0x35, KEY_PLAY }, + { 0x36, KEY_STOP }, + { 0x37, KEY_RECORD }, /* recording */ + { 0x38, KEY_YELLOW }, /* yellow key */ + { 0x3b, KEY_SELECT }, /* top right button */ + { 0x3c, KEY_ZOOM }, /* full */ + { 0x3d, KEY_POWER }, /* system power (green button) */ +}; + +struct ir_scancode_table ir_codes_hauppauge_new_table = { + .scan = ir_codes_hauppauge_new, + .size = ARRAY_SIZE(ir_codes_hauppauge_new), +}; +EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table); + +static struct ir_scancode ir_codes_npgtech[] = { + { 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */ + { 0x2a, KEY_FRONT }, + + { 0x3e, KEY_1 }, + { 0x02, KEY_2 }, + { 0x06, KEY_3 }, + { 0x0a, KEY_4 }, + { 0x0e, KEY_5 }, + { 0x12, KEY_6 }, + { 0x16, KEY_7 }, + { 0x1a, KEY_8 }, + { 0x1e, KEY_9 }, + { 0x3a, KEY_0 }, + { 0x22, KEY_NUMLOCK }, /* -/-- */ + { 0x20, KEY_REFRESH }, + + { 0x03, KEY_BRIGHTNESSDOWN }, + { 0x28, KEY_AUDIO }, + { 0x3c, KEY_CHANNELUP }, + { 0x3f, KEY_VOLUMEDOWN }, + { 0x2e, KEY_MUTE }, + { 0x3b, KEY_VOLUMEUP }, + { 0x00, KEY_CHANNELDOWN }, + { 0x07, KEY_BRIGHTNESSUP }, + { 0x2c, KEY_TEXT }, + + { 0x37, KEY_RECORD }, + { 0x17, KEY_PLAY }, + { 0x13, KEY_PAUSE }, + { 0x26, KEY_STOP }, + { 0x18, KEY_FASTFORWARD }, + { 0x14, KEY_REWIND }, + { 0x33, KEY_ZOOM }, + { 0x32, KEY_KEYBOARD }, + { 0x30, KEY_GOTO }, /* Pointing arrow */ + { 0x36, KEY_MACRO }, /* Maximize/Minimize (yellow) */ + { 0x0b, KEY_RADIO }, + { 0x10, KEY_POWER }, + +}; + +struct ir_scancode_table ir_codes_npgtech_table = { + .scan = ir_codes_npgtech, + .size = ARRAY_SIZE(ir_codes_npgtech), +}; +EXPORT_SYMBOL_GPL(ir_codes_npgtech_table); + +/* Norwood Micro (non-Pro) TV Tuner + By Peter Naulls + Key comments are the functions given in the manual */ +static struct ir_scancode ir_codes_norwood[] = { + /* Keys 0 to 9 */ + { 0x20, KEY_0 }, + { 0x21, KEY_1 }, + { 0x22, KEY_2 }, + { 0x23, KEY_3 }, + { 0x24, KEY_4 }, + { 0x25, KEY_5 }, + { 0x26, KEY_6 }, + { 0x27, KEY_7 }, + { 0x28, KEY_8 }, + { 0x29, KEY_9 }, + + { 0x78, KEY_TUNER }, /* Video Source */ + { 0x2c, KEY_EXIT }, /* Open/Close software */ + { 0x2a, KEY_SELECT }, /* 2 Digit Select */ + { 0x69, KEY_AGAIN }, /* Recall */ + + { 0x32, KEY_BRIGHTNESSUP }, /* Brightness increase */ + { 0x33, KEY_BRIGHTNESSDOWN }, /* Brightness decrease */ + { 0x6b, KEY_KPPLUS }, /* (not named >>>>>) */ + { 0x6c, KEY_KPMINUS }, /* (not named <<<<<) */ + + { 0x2d, KEY_MUTE }, /* Mute */ + { 0x30, KEY_VOLUMEUP }, /* Volume up */ + { 0x31, KEY_VOLUMEDOWN }, /* Volume down */ + { 0x60, KEY_CHANNELUP }, /* Channel up */ + { 0x61, KEY_CHANNELDOWN }, /* Channel down */ + + { 0x3f, KEY_RECORD }, /* Record */ + { 0x37, KEY_PLAY }, /* Play */ + { 0x36, KEY_PAUSE }, /* Pause */ + { 0x2b, KEY_STOP }, /* Stop */ + { 0x67, KEY_FASTFORWARD }, /* Foward */ + { 0x66, KEY_REWIND }, /* Rewind */ + { 0x3e, KEY_SEARCH }, /* Auto Scan */ + { 0x2e, KEY_CAMERA }, /* Capture Video */ + { 0x6d, KEY_MENU }, /* Show/Hide Control */ + { 0x2f, KEY_ZOOM }, /* Full Screen */ + { 0x34, KEY_RADIO }, /* FM */ + { 0x65, KEY_POWER }, /* Computer power */ +}; + +struct ir_scancode_table ir_codes_norwood_table = { + .scan = ir_codes_norwood, + .size = ARRAY_SIZE(ir_codes_norwood), +}; +EXPORT_SYMBOL_GPL(ir_codes_norwood_table); + +/* From reading the following remotes: + * Zenith Universal 7 / TV Mode 807 / VCR Mode 837 + * Hauppauge (from NOVA-CI-s box product) + * This is a "middle of the road" approach, differences are noted + */ +static struct ir_scancode ir_codes_budget_ci_old[] = { + { 0x00, KEY_0 }, + { 0x01, KEY_1 }, + { 0x02, KEY_2 }, + { 0x03, KEY_3 }, + { 0x04, KEY_4 }, + { 0x05, KEY_5 }, + { 0x06, KEY_6 }, + { 0x07, KEY_7 }, + { 0x08, KEY_8 }, + { 0x09, KEY_9 }, + { 0x0a, KEY_ENTER }, + { 0x0b, KEY_RED }, + { 0x0c, KEY_POWER }, /* RADIO on Hauppauge */ + { 0x0d, KEY_MUTE }, + { 0x0f, KEY_A }, /* TV on Hauppauge */ + { 0x10, KEY_VOLUMEUP }, + { 0x11, KEY_VOLUMEDOWN }, + { 0x14, KEY_B }, + { 0x1c, KEY_UP }, + { 0x1d, KEY_DOWN }, + { 0x1e, KEY_OPTION }, /* RESERVED on Hauppauge */ + { 0x1f, KEY_BREAK }, + { 0x20, KEY_CHANNELUP }, + { 0x21, KEY_CHANNELDOWN }, + { 0x22, KEY_PREVIOUS }, /* Prev Ch on Zenith, SOURCE on Hauppauge */ + { 0x24, KEY_RESTART }, + { 0x25, KEY_OK }, + { 0x26, KEY_CYCLEWINDOWS }, /* MINIMIZE on Hauppauge */ + { 0x28, KEY_ENTER }, /* VCR mode on Zenith */ + { 0x29, KEY_PAUSE }, + { 0x2b, KEY_RIGHT }, + { 0x2c, KEY_LEFT }, + { 0x2e, KEY_MENU }, /* FULL SCREEN on Hauppauge */ + { 0x30, KEY_SLOW }, + { 0x31, KEY_PREVIOUS }, /* VCR mode on Zenith */ + { 0x32, KEY_REWIND }, + { 0x34, KEY_FASTFORWARD }, + { 0x35, KEY_PLAY }, + { 0x36, KEY_STOP }, + { 0x37, KEY_RECORD }, + { 0x38, KEY_TUNER }, /* TV/VCR on Zenith */ + { 0x3a, KEY_C }, + { 0x3c, KEY_EXIT }, + { 0x3d, KEY_POWER2 }, + { 0x3e, KEY_TUNER }, +}; + +struct ir_scancode_table ir_codes_budget_ci_old_table = { + .scan = ir_codes_budget_ci_old, + .size = ARRAY_SIZE(ir_codes_budget_ci_old), +}; +EXPORT_SYMBOL_GPL(ir_codes_budget_ci_old_table); + +/* + * Marc Fargas + * this is the remote control that comes with the asus p7131 + * which has a label saying is "Model PC-39" + */ +static struct ir_scancode ir_codes_asus_pc39[] = { + /* Keys 0 to 9 */ + { 0x15, KEY_0 }, + { 0x29, KEY_1 }, + { 0x2d, KEY_2 }, + { 0x2b, KEY_3 }, + { 0x09, KEY_4 }, + { 0x0d, KEY_5 }, + { 0x0b, KEY_6 }, + { 0x31, KEY_7 }, + { 0x35, KEY_8 }, + { 0x33, KEY_9 }, + + { 0x3e, KEY_RADIO }, /* radio */ + { 0x03, KEY_MENU }, /* dvd/menu */ + { 0x2a, KEY_VOLUMEUP }, + { 0x19, KEY_VOLUMEDOWN }, + { 0x37, KEY_UP }, + { 0x3b, KEY_DOWN }, + { 0x27, KEY_LEFT }, + { 0x2f, KEY_RIGHT }, + { 0x25, KEY_VIDEO }, /* video */ + { 0x39, KEY_AUDIO }, /* music */ + + { 0x21, KEY_TV }, /* tv */ + { 0x1d, KEY_EXIT }, /* back */ + { 0x0a, KEY_CHANNELUP }, /* channel / program + */ + { 0x1b, KEY_CHANNELDOWN }, /* channel / program - */ + { 0x1a, KEY_ENTER }, /* enter */ + + { 0x06, KEY_PAUSE }, /* play/pause */ + { 0x1e, KEY_PREVIOUS }, /* rew */ + { 0x26, KEY_NEXT }, /* forward */ + { 0x0e, KEY_REWIND }, /* backward << */ + { 0x3a, KEY_FASTFORWARD }, /* forward >> */ + { 0x36, KEY_STOP }, + { 0x2e, KEY_RECORD }, /* recording */ + { 0x16, KEY_POWER }, /* the button that reads "close" */ + + { 0x11, KEY_ZOOM }, /* full screen */ + { 0x13, KEY_MACRO }, /* recall */ + { 0x23, KEY_HOME }, /* home */ + { 0x05, KEY_PVR }, /* picture */ + { 0x3d, KEY_MUTE }, /* mute */ + { 0x01, KEY_DVD }, /* dvd */ +}; + +struct ir_scancode_table ir_codes_asus_pc39_table = { + .scan = ir_codes_asus_pc39, + .size = ARRAY_SIZE(ir_codes_asus_pc39), +}; +EXPORT_SYMBOL_GPL(ir_codes_asus_pc39_table); + + +/* Encore ENLTV-FM - black plastic, white front cover with white glowing buttons + Juan Pablo Sormani */ +static struct ir_scancode ir_codes_encore_enltv[] = { + + /* Power button does nothing, neither in Windows app, + although it sends data (used for BIOS wakeup?) */ + { 0x0d, KEY_MUTE }, + + { 0x1e, KEY_TV }, + { 0x00, KEY_VIDEO }, + { 0x01, KEY_AUDIO }, /* music */ + { 0x02, KEY_MHP }, /* picture */ + + { 0x1f, KEY_1 }, + { 0x03, KEY_2 }, + { 0x04, KEY_3 }, + { 0x05, KEY_4 }, + { 0x1c, KEY_5 }, + { 0x06, KEY_6 }, + { 0x07, KEY_7 }, + { 0x08, KEY_8 }, + { 0x1d, KEY_9 }, + { 0x0a, KEY_0 }, + + { 0x09, KEY_LIST }, /* -/-- */ + { 0x0b, KEY_LAST }, /* recall */ + + { 0x14, KEY_HOME }, /* win start menu */ + { 0x15, KEY_EXIT }, /* exit */ + { 0x16, KEY_CHANNELUP }, /* UP */ + { 0x12, KEY_CHANNELDOWN }, /* DOWN */ + { 0x0c, KEY_VOLUMEUP }, /* RIGHT */ + { 0x17, KEY_VOLUMEDOWN }, /* LEFT */ + + { 0x18, KEY_ENTER }, /* OK */ + + { 0x0e, KEY_ESC }, + { 0x13, KEY_CYCLEWINDOWS }, /* desktop */ + { 0x11, KEY_TAB }, + { 0x19, KEY_SWITCHVIDEOMODE }, /* switch */ + + { 0x1a, KEY_MENU }, + { 0x1b, KEY_ZOOM }, /* fullscreen */ + { 0x44, KEY_TIME }, /* time shift */ + { 0x40, KEY_MODE }, /* source */ + + { 0x5a, KEY_RECORD }, + { 0x42, KEY_PLAY }, /* play/pause */ + { 0x45, KEY_STOP }, + { 0x43, KEY_CAMERA }, /* camera icon */ + + { 0x48, KEY_REWIND }, + { 0x4a, KEY_FASTFORWARD }, + { 0x49, KEY_PREVIOUS }, + { 0x4b, KEY_NEXT }, + + { 0x4c, KEY_FAVORITES }, /* tv wall */ + { 0x4d, KEY_SOUND }, /* DVD sound */ + { 0x4e, KEY_LANGUAGE }, /* DVD lang */ + { 0x4f, KEY_TEXT }, /* DVD text */ + + { 0x50, KEY_SLEEP }, /* shutdown */ + { 0x51, KEY_MODE }, /* stereo > main */ + { 0x52, KEY_SELECT }, /* stereo > sap */ + { 0x53, KEY_PROG1 }, /* teletext */ + + + { 0x59, KEY_RED }, /* AP1 */ + { 0x41, KEY_GREEN }, /* AP2 */ + { 0x47, KEY_YELLOW }, /* AP3 */ + { 0x57, KEY_BLUE }, /* AP4 */ +}; + +struct ir_scancode_table ir_codes_encore_enltv_table = { + .scan = ir_codes_encore_enltv, + .size = ARRAY_SIZE(ir_codes_encore_enltv), +}; +EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_table); + +/* Encore ENLTV2-FM - silver plastic - "Wand Media" written at the botton + Mauro Carvalho Chehab */ +static struct ir_scancode ir_codes_encore_enltv2[] = { + { 0x4c, KEY_POWER2 }, + { 0x4a, KEY_TUNER }, + { 0x40, KEY_1 }, + { 0x60, KEY_2 }, + { 0x50, KEY_3 }, + { 0x70, KEY_4 }, + { 0x48, KEY_5 }, + { 0x68, KEY_6 }, + { 0x58, KEY_7 }, + { 0x78, KEY_8 }, + { 0x44, KEY_9 }, + { 0x54, KEY_0 }, + + { 0x64, KEY_LAST }, /* +100 */ + { 0x4e, KEY_AGAIN }, /* Recall */ + + { 0x6c, KEY_SWITCHVIDEOMODE }, /* Video Source */ + { 0x5e, KEY_MENU }, + { 0x56, KEY_SCREEN }, + { 0x7a, KEY_SETUP }, + + { 0x46, KEY_MUTE }, + { 0x5c, KEY_MODE }, /* Stereo */ + { 0x74, KEY_INFO }, + { 0x7c, KEY_CLEAR }, + + { 0x55, KEY_UP }, + { 0x49, KEY_DOWN }, + { 0x7e, KEY_LEFT }, + { 0x59, KEY_RIGHT }, + { 0x6a, KEY_ENTER }, + + { 0x42, KEY_VOLUMEUP }, + { 0x62, KEY_VOLUMEDOWN }, + { 0x52, KEY_CHANNELUP }, + { 0x72, KEY_CHANNELDOWN }, + + { 0x41, KEY_RECORD }, + { 0x51, KEY_CAMERA }, /* Snapshot */ + { 0x75, KEY_TIME }, /* Timeshift */ + { 0x71, KEY_TV2 }, /* PIP */ + + { 0x45, KEY_REWIND }, + { 0x6f, KEY_PAUSE }, + { 0x7d, KEY_FORWARD }, + { 0x79, KEY_STOP }, +}; + +struct ir_scancode_table ir_codes_encore_enltv2_table = { + .scan = ir_codes_encore_enltv2, + .size = ARRAY_SIZE(ir_codes_encore_enltv2), +}; +EXPORT_SYMBOL_GPL(ir_codes_encore_enltv2_table); + +/* for the Technotrend 1500 bundled remotes (grey and black): */ +static struct ir_scancode ir_codes_tt_1500[] = { + { 0x01, KEY_POWER }, + { 0x02, KEY_SHUFFLE }, /* ? double-arrow key */ + { 0x03, KEY_1 }, + { 0x04, KEY_2 }, + { 0x05, KEY_3 }, + { 0x06, KEY_4 }, + { 0x07, KEY_5 }, + { 0x08, KEY_6 }, + { 0x09, KEY_7 }, + { 0x0a, KEY_8 }, + { 0x0b, KEY_9 }, + { 0x0c, KEY_0 }, + { 0x0d, KEY_UP }, + { 0x0e, KEY_LEFT }, + { 0x0f, KEY_OK }, + { 0x10, KEY_RIGHT }, + { 0x11, KEY_DOWN }, + { 0x12, KEY_INFO }, + { 0x13, KEY_EXIT }, + { 0x14, KEY_RED }, + { 0x15, KEY_GREEN }, + { 0x16, KEY_YELLOW }, + { 0x17, KEY_BLUE }, + { 0x18, KEY_MUTE }, + { 0x19, KEY_TEXT }, + { 0x1a, KEY_MODE }, /* ? TV/Radio */ + { 0x21, KEY_OPTION }, + { 0x22, KEY_EPG }, + { 0x23, KEY_CHANNELUP }, + { 0x24, KEY_CHANNELDOWN }, + { 0x25, KEY_VOLUMEUP }, + { 0x26, KEY_VOLUMEDOWN }, + { 0x27, KEY_SETUP }, + { 0x3a, KEY_RECORD }, /* these keys are only in the black remote */ + { 0x3b, KEY_PLAY }, + { 0x3c, KEY_STOP }, + { 0x3d, KEY_REWIND }, + { 0x3e, KEY_PAUSE }, + { 0x3f, KEY_FORWARD }, +}; + +struct ir_scancode_table ir_codes_tt_1500_table = { + .scan = ir_codes_tt_1500, + .size = ARRAY_SIZE(ir_codes_tt_1500), +}; +EXPORT_SYMBOL_GPL(ir_codes_tt_1500_table); + +/* DViCO FUSION HDTV MCE remote */ +static struct ir_scancode ir_codes_fusionhdtv_mce[] = { + + { 0x0b, KEY_1 }, + { 0x17, KEY_2 }, + { 0x1b, KEY_3 }, + { 0x07, KEY_4 }, + { 0x50, KEY_5 }, + { 0x54, KEY_6 }, + { 0x48, KEY_7 }, + { 0x4c, KEY_8 }, + { 0x58, KEY_9 }, + { 0x03, KEY_0 }, + + { 0x5e, KEY_OK }, + { 0x51, KEY_UP }, + { 0x53, KEY_DOWN }, + { 0x5b, KEY_LEFT }, + { 0x5f, KEY_RIGHT }, + + { 0x02, KEY_TV }, /* Labeled DTV on remote */ + { 0x0e, KEY_MP3 }, + { 0x1a, KEY_DVD }, + { 0x1e, KEY_FAVORITES }, /* Labeled CPF on remote */ + { 0x16, KEY_SETUP }, + { 0x46, KEY_POWER2 }, /* TV On/Off button on remote */ + { 0x0a, KEY_EPG }, /* Labeled Guide on remote */ + + { 0x49, KEY_BACK }, + { 0x59, KEY_INFO }, /* Labeled MORE on remote */ + { 0x4d, KEY_MENU }, /* Labeled DVDMENU on remote */ + { 0x55, KEY_CYCLEWINDOWS }, /* Labeled ALT-TAB on remote */ + + { 0x0f, KEY_PREVIOUSSONG }, /* Labeled |<< REPLAY on remote */ + { 0x12, KEY_NEXTSONG }, /* Labeled >>| SKIP on remote */ + { 0x42, KEY_ENTER }, /* Labeled START with a green + MS windows logo on remote */ + + { 0x15, KEY_VOLUMEUP }, + { 0x05, KEY_VOLUMEDOWN }, + { 0x11, KEY_CHANNELUP }, + { 0x09, KEY_CHANNELDOWN }, + + { 0x52, KEY_CAMERA }, + { 0x5a, KEY_TUNER }, + { 0x19, KEY_OPEN }, + + { 0x13, KEY_MODE }, /* 4:3 16:9 select */ + { 0x1f, KEY_ZOOM }, + + { 0x43, KEY_REWIND }, + { 0x47, KEY_PLAYPAUSE }, + { 0x4f, KEY_FASTFORWARD }, + { 0x57, KEY_MUTE }, + { 0x0d, KEY_STOP }, + { 0x01, KEY_RECORD }, + { 0x4e, KEY_POWER }, +}; + +struct ir_scancode_table ir_codes_fusionhdtv_mce_table = { + .scan = ir_codes_fusionhdtv_mce, + .size = ARRAY_SIZE(ir_codes_fusionhdtv_mce), +}; +EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce_table); + +/* Pinnacle PCTV HD 800i mini remote */ +static struct ir_scancode ir_codes_pinnacle_pctv_hd[] = { + + { 0x0f, KEY_1 }, + { 0x15, KEY_2 }, + { 0x10, KEY_3 }, + { 0x18, KEY_4 }, + { 0x1b, KEY_5 }, + { 0x1e, KEY_6 }, + { 0x11, KEY_7 }, + { 0x21, KEY_8 }, + { 0x12, KEY_9 }, + { 0x27, KEY_0 }, + + { 0x24, KEY_ZOOM }, + { 0x2a, KEY_SUBTITLE }, + + { 0x00, KEY_MUTE }, + { 0x01, KEY_ENTER }, /* Pinnacle Logo */ + { 0x39, KEY_POWER }, + + { 0x03, KEY_VOLUMEUP }, + { 0x09, KEY_VOLUMEDOWN }, + { 0x06, KEY_CHANNELUP }, + { 0x0c, KEY_CHANNELDOWN }, + + { 0x2d, KEY_REWIND }, + { 0x30, KEY_PLAYPAUSE }, + { 0x33, KEY_FASTFORWARD }, + { 0x3c, KEY_STOP }, + { 0x36, KEY_RECORD }, + { 0x3f, KEY_EPG }, /* Labeled "?" */ +}; + +struct ir_scancode_table ir_codes_pinnacle_pctv_hd_table = { + .scan = ir_codes_pinnacle_pctv_hd, + .size = ARRAY_SIZE(ir_codes_pinnacle_pctv_hd), +}; +EXPORT_SYMBOL_GPL(ir_codes_pinnacle_pctv_hd_table); + +/* + * Igor Kuznetsov + * Andrey J. Melnikov + * + * Keytable is used by BeholdTV 60x series, M6 series at + * least, and probably other cards too. + * The "ascii-art picture" below (in comments, first row + * is the keycode in hex, and subsequent row(s) shows + * the button labels (several variants when appropriate) + * helps to descide which keycodes to assign to the buttons. + */ +static struct ir_scancode ir_codes_behold[] = { + + /* 0x1c 0x12 * + * TV/FM POWER * + * */ + { 0x1c, KEY_TUNER }, /* XXX KEY_TV / KEY_RADIO */ + { 0x12, KEY_POWER }, + + /* 0x01 0x02 0x03 * + * 1 2 3 * + * * + * 0x04 0x05 0x06 * + * 4 5 6 * + * * + * 0x07 0x08 0x09 * + * 7 8 9 * + * */ + { 0x01, KEY_1 }, + { 0x02, KEY_2 }, + { 0x03, KEY_3 }, + { 0x04, KEY_4 }, + { 0x05, KEY_5 }, + { 0x06, KEY_6 }, + { 0x07, KEY_7 }, + { 0x08, KEY_8 }, + { 0x09, KEY_9 }, + + /* 0x0a 0x00 0x17 * + * RECALL 0 MODE * + * */ + { 0x0a, KEY_AGAIN }, + { 0x00, KEY_0 }, + { 0x17, KEY_MODE }, + + /* 0x14 0x10 * + * ASPECT FULLSCREEN * + * */ + { 0x14, KEY_SCREEN }, + { 0x10, KEY_ZOOM }, + + /* 0x0b * + * Up * + * * + * 0x18 0x16 0x0c * + * Left Ok Right * + * * + * 0x015 * + * Down * + * */ + { 0x0b, KEY_CHANNELUP }, + { 0x18, KEY_VOLUMEDOWN }, + { 0x16, KEY_OK }, /* XXX KEY_ENTER */ + { 0x0c, KEY_VOLUMEUP }, + { 0x15, KEY_CHANNELDOWN }, + + /* 0x11 0x0d * + * MUTE INFO * + * */ + { 0x11, KEY_MUTE }, + { 0x0d, KEY_INFO }, + + /* 0x0f 0x1b 0x1a * + * RECORD PLAY/PAUSE STOP * + * * + * 0x0e 0x1f 0x1e * + *TELETEXT AUDIO SOURCE * + * RED YELLOW * + * */ + { 0x0f, KEY_RECORD }, + { 0x1b, KEY_PLAYPAUSE }, + { 0x1a, KEY_STOP }, + { 0x0e, KEY_TEXT }, + { 0x1f, KEY_RED }, /*XXX KEY_AUDIO */ + { 0x1e, KEY_YELLOW }, /*XXX KEY_SOURCE */ + + /* 0x1d 0x13 0x19 * + * SLEEP PREVIEW DVB * + * GREEN BLUE * + * */ + { 0x1d, KEY_SLEEP }, + { 0x13, KEY_GREEN }, + { 0x19, KEY_BLUE }, /* XXX KEY_SAT */ + + /* 0x58 0x5c * + * FREEZE SNAPSHOT * + * */ + { 0x58, KEY_SLOW }, + { 0x5c, KEY_CAMERA }, + +}; + +struct ir_scancode_table ir_codes_behold_table = { + .scan = ir_codes_behold, + .size = ARRAY_SIZE(ir_codes_behold), +}; +EXPORT_SYMBOL_GPL(ir_codes_behold_table); + +/* Beholder Intl. Ltd. 2008 + * Dmitry Belimov d.belimov@google.com + * Keytable is used by BeholdTV Columbus + * The "ascii-art picture" below (in comments, first row + * is the keycode in hex, and subsequent row(s) shows + * the button labels (several variants when appropriate) + * helps to descide which keycodes to assign to the buttons. + */ +static struct ir_scancode ir_codes_behold_columbus[] = { + + /* 0x13 0x11 0x1C 0x12 * + * Mute Source TV/FM Power * + * */ + + { 0x13, KEY_MUTE }, + { 0x11, KEY_PROPS }, + { 0x1C, KEY_TUNER }, /* KEY_TV/KEY_RADIO */ + { 0x12, KEY_POWER }, + + /* 0x01 0x02 0x03 0x0D * + * 1 2 3 Stereo * + * * + * 0x04 0x05 0x06 0x19 * + * 4 5 6 Snapshot * + * * + * 0x07 0x08 0x09 0x10 * + * 7 8 9 Zoom * + * */ + { 0x01, KEY_1 }, + { 0x02, KEY_2 }, + { 0x03, KEY_3 }, + { 0x0D, KEY_SETUP }, /* Setup key */ + { 0x04, KEY_4 }, + { 0x05, KEY_5 }, + { 0x06, KEY_6 }, + { 0x19, KEY_CAMERA }, /* Snapshot key */ + { 0x07, KEY_7 }, + { 0x08, KEY_8 }, + { 0x09, KEY_9 }, + { 0x10, KEY_ZOOM }, + + /* 0x0A 0x00 0x0B 0x0C * + * RECALL 0 ChannelUp VolumeUp * + * */ + { 0x0A, KEY_AGAIN }, + { 0x00, KEY_0 }, + { 0x0B, KEY_CHANNELUP }, + { 0x0C, KEY_VOLUMEUP }, + + /* 0x1B 0x1D 0x15 0x18 * + * Timeshift Record ChannelDown VolumeDown * + * */ + + { 0x1B, KEY_TIME }, + { 0x1D, KEY_RECORD }, + { 0x15, KEY_CHANNELDOWN }, + { 0x18, KEY_VOLUMEDOWN }, + + /* 0x0E 0x1E 0x0F 0x1A * + * Stop Pause Previouse Next * + * */ + + { 0x0E, KEY_STOP }, + { 0x1E, KEY_PAUSE }, + { 0x0F, KEY_PREVIOUS }, + { 0x1A, KEY_NEXT }, + +}; + +struct ir_scancode_table ir_codes_behold_columbus_table = { + .scan = ir_codes_behold_columbus, + .size = ARRAY_SIZE(ir_codes_behold_columbus), +}; +EXPORT_SYMBOL_GPL(ir_codes_behold_columbus_table); + +/* + * Remote control for the Genius TVGO A11MCE + * Adrian Pardini + */ +static struct ir_scancode ir_codes_genius_tvgo_a11mce[] = { + /* Keys 0 to 9 */ + { 0x48, KEY_0 }, + { 0x09, KEY_1 }, + { 0x1d, KEY_2 }, + { 0x1f, KEY_3 }, + { 0x19, KEY_4 }, + { 0x1b, KEY_5 }, + { 0x11, KEY_6 }, + { 0x17, KEY_7 }, + { 0x12, KEY_8 }, + { 0x16, KEY_9 }, + + { 0x54, KEY_RECORD }, /* recording */ + { 0x06, KEY_MUTE }, /* mute */ + { 0x10, KEY_POWER }, + { 0x40, KEY_LAST }, /* recall */ + { 0x4c, KEY_CHANNELUP }, /* channel / program + */ + { 0x00, KEY_CHANNELDOWN }, /* channel / program - */ + { 0x0d, KEY_VOLUMEUP }, + { 0x15, KEY_VOLUMEDOWN }, + { 0x4d, KEY_OK }, /* also labeled as Pause */ + { 0x1c, KEY_ZOOM }, /* full screen and Stop*/ + { 0x02, KEY_MODE }, /* AV Source or Rewind*/ + { 0x04, KEY_LIST }, /* -/-- */ + /* small arrows above numbers */ + { 0x1a, KEY_NEXT }, /* also Fast Forward */ + { 0x0e, KEY_PREVIOUS }, /* also Rewind */ + /* these are in a rather non standard layout and have + an alternate name written */ + { 0x1e, KEY_UP }, /* Video Setting */ + { 0x0a, KEY_DOWN }, /* Video Default */ + { 0x05, KEY_CAMERA }, /* Snapshot */ + { 0x0c, KEY_RIGHT }, /* Hide Panel */ + /* Four buttons without label */ + { 0x49, KEY_RED }, + { 0x0b, KEY_GREEN }, + { 0x13, KEY_YELLOW }, + { 0x50, KEY_BLUE }, +}; + +struct ir_scancode_table ir_codes_genius_tvgo_a11mce_table = { + .scan = ir_codes_genius_tvgo_a11mce, + .size = ARRAY_SIZE(ir_codes_genius_tvgo_a11mce), +}; +EXPORT_SYMBOL_GPL(ir_codes_genius_tvgo_a11mce_table); + +/* + * Remote control for Powercolor Real Angel 330 + * Daniel Fraga + */ +static struct ir_scancode ir_codes_powercolor_real_angel[] = { + { 0x38, KEY_SWITCHVIDEOMODE }, /* switch inputs */ + { 0x0c, KEY_MEDIA }, /* Turn ON/OFF App */ + { 0x00, KEY_0 }, + { 0x01, KEY_1 }, + { 0x02, KEY_2 }, + { 0x03, KEY_3 }, + { 0x04, KEY_4 }, + { 0x05, KEY_5 }, + { 0x06, KEY_6 }, + { 0x07, KEY_7 }, + { 0x08, KEY_8 }, + { 0x09, KEY_9 }, + { 0x0a, KEY_DIGITS }, /* single, double, tripple digit */ + { 0x29, KEY_PREVIOUS }, /* previous channel */ + { 0x12, KEY_BRIGHTNESSUP }, + { 0x13, KEY_BRIGHTNESSDOWN }, + { 0x2b, KEY_MODE }, /* stereo/mono */ + { 0x2c, KEY_TEXT }, /* teletext */ + { 0x20, KEY_CHANNELUP }, /* channel up */ + { 0x21, KEY_CHANNELDOWN }, /* channel down */ + { 0x10, KEY_VOLUMEUP }, /* volume up */ + { 0x11, KEY_VOLUMEDOWN }, /* volume down */ + { 0x0d, KEY_MUTE }, + { 0x1f, KEY_RECORD }, + { 0x17, KEY_PLAY }, + { 0x16, KEY_PAUSE }, + { 0x0b, KEY_STOP }, + { 0x27, KEY_FASTFORWARD }, + { 0x26, KEY_REWIND }, + { 0x1e, KEY_SEARCH }, /* autoscan */ + { 0x0e, KEY_CAMERA }, /* snapshot */ + { 0x2d, KEY_SETUP }, + { 0x0f, KEY_SCREEN }, /* full screen */ + { 0x14, KEY_RADIO }, /* FM radio */ + { 0x25, KEY_POWER }, /* power */ +}; + +struct ir_scancode_table ir_codes_powercolor_real_angel_table = { + .scan = ir_codes_powercolor_real_angel, + .size = ARRAY_SIZE(ir_codes_powercolor_real_angel), +}; +EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel_table); + +/* Kworld Plus TV Analog Lite PCI IR + Mauro Carvalho Chehab + */ +static struct ir_scancode ir_codes_kworld_plus_tv_analog[] = { + { 0x0c, KEY_PROG1 }, /* Kworld key */ + { 0x16, KEY_CLOSECD }, /* -> ) */ + { 0x1d, KEY_POWER2 }, + + { 0x00, KEY_1 }, + { 0x01, KEY_2 }, + { 0x02, KEY_3 }, /* Two keys have the same code: 3 and left */ + { 0x03, KEY_4 }, /* Two keys have the same code: 3 and right */ + { 0x04, KEY_5 }, + { 0x05, KEY_6 }, + { 0x06, KEY_7 }, + { 0x07, KEY_8 }, + { 0x08, KEY_9 }, + { 0x0a, KEY_0 }, + + { 0x09, KEY_AGAIN }, + { 0x14, KEY_MUTE }, + + { 0x20, KEY_UP }, + { 0x21, KEY_DOWN }, + { 0x0b, KEY_ENTER }, + + { 0x10, KEY_CHANNELUP }, + { 0x11, KEY_CHANNELDOWN }, + + /* Couldn't map key left/key right since those + conflict with '3' and '4' scancodes + I dunno what the original driver does + */ + + { 0x13, KEY_VOLUMEUP }, + { 0x12, KEY_VOLUMEDOWN }, + + /* The lower part of the IR + There are several duplicated keycodes there. + Most of them conflict with digits. + Add mappings just to the unused scancodes. + Somehow, the original driver has a way to know, + but this doesn't seem to be on some GPIO. + Also, it is not related to the time between keyup + and keydown. + */ + { 0x19, KEY_TIME}, /* Timeshift */ + { 0x1a, KEY_STOP}, + { 0x1b, KEY_RECORD}, + + { 0x22, KEY_TEXT}, + + { 0x15, KEY_AUDIO}, /* ((*)) */ + { 0x0f, KEY_ZOOM}, + { 0x1c, KEY_CAMERA}, /* snapshot */ + + { 0x18, KEY_RED}, /* B */ + { 0x23, KEY_GREEN}, /* C */ +}; +struct ir_scancode_table ir_codes_kworld_plus_tv_analog_table = { + .scan = ir_codes_kworld_plus_tv_analog, + .size = ARRAY_SIZE(ir_codes_kworld_plus_tv_analog), +}; +EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog_table); + +/* Kaiomy TVnPC U2 + Mauro Carvalho Chehab + */ +static struct ir_scancode ir_codes_kaiomy[] = { + { 0x43, KEY_POWER2}, + { 0x01, KEY_LIST}, + { 0x0b, KEY_ZOOM}, + { 0x03, KEY_POWER}, + + { 0x04, KEY_1}, + { 0x08, KEY_2}, + { 0x02, KEY_3}, + + { 0x0f, KEY_4}, + { 0x05, KEY_5}, + { 0x06, KEY_6}, + + { 0x0c, KEY_7}, + { 0x0d, KEY_8}, + { 0x0a, KEY_9}, + + { 0x11, KEY_0}, + + { 0x09, KEY_CHANNELUP}, + { 0x07, KEY_CHANNELDOWN}, + + { 0x0e, KEY_VOLUMEUP}, + { 0x13, KEY_VOLUMEDOWN}, + + { 0x10, KEY_HOME}, + { 0x12, KEY_ENTER}, + + { 0x14, KEY_RECORD}, + { 0x15, KEY_STOP}, + { 0x16, KEY_PLAY}, + { 0x17, KEY_MUTE}, + + { 0x18, KEY_UP}, + { 0x19, KEY_DOWN}, + { 0x1a, KEY_LEFT}, + { 0x1b, KEY_RIGHT}, + + { 0x1c, KEY_RED}, + { 0x1d, KEY_GREEN}, + { 0x1e, KEY_YELLOW}, + { 0x1f, KEY_BLUE}, +}; +struct ir_scancode_table ir_codes_kaiomy_table = { + .scan = ir_codes_kaiomy, + .size = ARRAY_SIZE(ir_codes_kaiomy), +}; +EXPORT_SYMBOL_GPL(ir_codes_kaiomy_table); + +static struct ir_scancode ir_codes_avermedia_a16d[] = { + { 0x20, KEY_LIST}, + { 0x00, KEY_POWER}, + { 0x28, KEY_1}, + { 0x18, KEY_2}, + { 0x38, KEY_3}, + { 0x24, KEY_4}, + { 0x14, KEY_5}, + { 0x34, KEY_6}, + { 0x2c, KEY_7}, + { 0x1c, KEY_8}, + { 0x3c, KEY_9}, + { 0x12, KEY_SUBTITLE}, + { 0x22, KEY_0}, + { 0x32, KEY_REWIND}, + { 0x3a, KEY_SHUFFLE}, + { 0x02, KEY_PRINT}, + { 0x11, KEY_CHANNELDOWN}, + { 0x31, KEY_CHANNELUP}, + { 0x0c, KEY_ZOOM}, + { 0x1e, KEY_VOLUMEDOWN}, + { 0x3e, KEY_VOLUMEUP}, + { 0x0a, KEY_MUTE}, + { 0x04, KEY_AUDIO}, + { 0x26, KEY_RECORD}, + { 0x06, KEY_PLAY}, + { 0x36, KEY_STOP}, + { 0x16, KEY_PAUSE}, + { 0x2e, KEY_REWIND}, + { 0x0e, KEY_FASTFORWARD}, + { 0x30, KEY_TEXT}, + { 0x21, KEY_GREEN}, + { 0x01, KEY_BLUE}, + { 0x08, KEY_EPG}, + { 0x2a, KEY_MENU}, +}; +struct ir_scancode_table ir_codes_avermedia_a16d_table = { + .scan = ir_codes_avermedia_a16d, + .size = ARRAY_SIZE(ir_codes_avermedia_a16d), +}; +EXPORT_SYMBOL_GPL(ir_codes_avermedia_a16d_table); + +/* Encore ENLTV-FM v5.3 + Mauro Carvalho Chehab + */ +static struct ir_scancode ir_codes_encore_enltv_fm53[] = { + { 0x10, KEY_POWER2}, + { 0x06, KEY_MUTE}, + + { 0x09, KEY_1}, + { 0x1d, KEY_2}, + { 0x1f, KEY_3}, + { 0x19, KEY_4}, + { 0x1b, KEY_5}, + { 0x11, KEY_6}, + { 0x17, KEY_7}, + { 0x12, KEY_8}, + { 0x16, KEY_9}, + { 0x48, KEY_0}, + + { 0x04, KEY_LIST}, /* -/-- */ + { 0x40, KEY_LAST}, /* recall */ + + { 0x02, KEY_MODE}, /* TV/AV */ + { 0x05, KEY_CAMERA}, /* SNAPSHOT */ + + { 0x4c, KEY_CHANNELUP}, /* UP */ + { 0x00, KEY_CHANNELDOWN}, /* DOWN */ + { 0x0d, KEY_VOLUMEUP}, /* RIGHT */ + { 0x15, KEY_VOLUMEDOWN}, /* LEFT */ + { 0x49, KEY_ENTER}, /* OK */ + + { 0x54, KEY_RECORD}, + { 0x4d, KEY_PLAY}, /* pause */ + + { 0x1e, KEY_MENU}, /* video setting */ + { 0x0e, KEY_RIGHT}, /* <- */ + { 0x1a, KEY_LEFT}, /* -> */ + + { 0x0a, KEY_CLEAR}, /* video default */ + { 0x0c, KEY_ZOOM}, /* hide pannel */ + { 0x47, KEY_SLEEP}, /* shutdown */ +}; +struct ir_scancode_table ir_codes_encore_enltv_fm53_table = { + .scan = ir_codes_encore_enltv_fm53, + .size = ARRAY_SIZE(ir_codes_encore_enltv_fm53), +}; +EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_fm53_table); + +/* Zogis Real Audio 220 - 32 keys IR */ +static struct ir_scancode ir_codes_real_audio_220_32_keys[] = { + { 0x1c, KEY_RADIO}, + { 0x12, KEY_POWER2}, + + { 0x01, KEY_1}, + { 0x02, KEY_2}, + { 0x03, KEY_3}, + { 0x04, KEY_4}, + { 0x05, KEY_5}, + { 0x06, KEY_6}, + { 0x07, KEY_7}, + { 0x08, KEY_8}, + { 0x09, KEY_9}, + { 0x00, KEY_0}, + + { 0x0c, KEY_VOLUMEUP}, + { 0x18, KEY_VOLUMEDOWN}, + { 0x0b, KEY_CHANNELUP}, + { 0x15, KEY_CHANNELDOWN}, + { 0x16, KEY_ENTER}, + + { 0x11, KEY_LIST}, /* Source */ + { 0x0d, KEY_AUDIO}, /* stereo */ + + { 0x0f, KEY_PREVIOUS}, /* Prev */ + { 0x1b, KEY_TIME}, /* Timeshift */ + { 0x1a, KEY_NEXT}, /* Next */ + + { 0x0e, KEY_STOP}, + { 0x1f, KEY_PLAY}, + { 0x1e, KEY_PLAYPAUSE}, /* Pause */ + + { 0x1d, KEY_RECORD}, + { 0x13, KEY_MUTE}, + { 0x19, KEY_CAMERA}, /* Snapshot */ + +}; +struct ir_scancode_table ir_codes_real_audio_220_32_keys_table = { + .scan = ir_codes_real_audio_220_32_keys, + .size = ARRAY_SIZE(ir_codes_real_audio_220_32_keys), +}; +EXPORT_SYMBOL_GPL(ir_codes_real_audio_220_32_keys_table); + +/* ATI TV Wonder HD 600 USB + Devin Heitmueller + */ +static struct ir_scancode ir_codes_ati_tv_wonder_hd_600[] = { + { 0x00, KEY_RECORD}, /* Row 1 */ + { 0x01, KEY_PLAYPAUSE}, + { 0x02, KEY_STOP}, + { 0x03, KEY_POWER}, + { 0x04, KEY_PREVIOUS}, /* Row 2 */ + { 0x05, KEY_REWIND}, + { 0x06, KEY_FORWARD}, + { 0x07, KEY_NEXT}, + { 0x08, KEY_EPG}, /* Row 3 */ + { 0x09, KEY_HOME}, + { 0x0a, KEY_MENU}, + { 0x0b, KEY_CHANNELUP}, + { 0x0c, KEY_BACK}, /* Row 4 */ + { 0x0d, KEY_UP}, + { 0x0e, KEY_INFO}, + { 0x0f, KEY_CHANNELDOWN}, + { 0x10, KEY_LEFT}, /* Row 5 */ + { 0x11, KEY_SELECT}, + { 0x12, KEY_RIGHT}, + { 0x13, KEY_VOLUMEUP}, + { 0x14, KEY_LAST}, /* Row 6 */ + { 0x15, KEY_DOWN}, + { 0x16, KEY_MUTE}, + { 0x17, KEY_VOLUMEDOWN}, +}; +struct ir_scancode_table ir_codes_ati_tv_wonder_hd_600_table = { + .scan = ir_codes_ati_tv_wonder_hd_600, + .size = ARRAY_SIZE(ir_codes_ati_tv_wonder_hd_600), +}; +EXPORT_SYMBOL_GPL(ir_codes_ati_tv_wonder_hd_600_table); + +/* DVBWorld remotes + Igor M. Liplianin + */ +static struct ir_scancode ir_codes_dm1105_nec[] = { + { 0x0a, KEY_POWER2}, /* power */ + { 0x0c, KEY_MUTE}, /* mute */ + { 0x11, KEY_1}, + { 0x12, KEY_2}, + { 0x13, KEY_3}, + { 0x14, KEY_4}, + { 0x15, KEY_5}, + { 0x16, KEY_6}, + { 0x17, KEY_7}, + { 0x18, KEY_8}, + { 0x19, KEY_9}, + { 0x10, KEY_0}, + { 0x1c, KEY_CHANNELUP}, /* ch+ */ + { 0x0f, KEY_CHANNELDOWN}, /* ch- */ + { 0x1a, KEY_VOLUMEUP}, /* vol+ */ + { 0x0e, KEY_VOLUMEDOWN}, /* vol- */ + { 0x04, KEY_RECORD}, /* rec */ + { 0x09, KEY_CHANNEL}, /* fav */ + { 0x08, KEY_BACKSPACE}, /* rewind */ + { 0x07, KEY_FASTFORWARD}, /* fast */ + { 0x0b, KEY_PAUSE}, /* pause */ + { 0x02, KEY_ESC}, /* cancel */ + { 0x03, KEY_TAB}, /* tab */ + { 0x00, KEY_UP}, /* up */ + { 0x1f, KEY_ENTER}, /* ok */ + { 0x01, KEY_DOWN}, /* down */ + { 0x05, KEY_RECORD}, /* cap */ + { 0x06, KEY_STOP}, /* stop */ + { 0x40, KEY_ZOOM}, /* full */ + { 0x1e, KEY_TV}, /* tvmode */ + { 0x1b, KEY_B}, /* recall */ +}; +struct ir_scancode_table ir_codes_dm1105_nec_table = { + .scan = ir_codes_dm1105_nec, + .size = ARRAY_SIZE(ir_codes_dm1105_nec), +}; +EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec_table); + +static struct ir_scancode ir_codes_tevii_nec[] = { + { 0x0a, KEY_POWER2}, + { 0x0c, KEY_MUTE}, + { 0x11, KEY_1}, + { 0x12, KEY_2}, + { 0x13, KEY_3}, + { 0x14, KEY_4}, + { 0x15, KEY_5}, + { 0x16, KEY_6}, + { 0x17, KEY_7}, + { 0x18, KEY_8}, + { 0x19, KEY_9}, + { 0x10, KEY_0}, + { 0x1c, KEY_MENU}, + { 0x0f, KEY_VOLUMEDOWN}, + { 0x1a, KEY_LAST}, + { 0x0e, KEY_OPEN}, + { 0x04, KEY_RECORD}, + { 0x09, KEY_VOLUMEUP}, + { 0x08, KEY_CHANNELUP}, + { 0x07, KEY_PVR}, + { 0x0b, KEY_TIME}, + { 0x02, KEY_RIGHT}, + { 0x03, KEY_LEFT}, + { 0x00, KEY_UP}, + { 0x1f, KEY_OK}, + { 0x01, KEY_DOWN}, + { 0x05, KEY_TUNER}, + { 0x06, KEY_CHANNELDOWN}, + { 0x40, KEY_PLAYPAUSE}, + { 0x1e, KEY_REWIND}, + { 0x1b, KEY_FAVORITES}, + { 0x1d, KEY_BACK}, + { 0x4d, KEY_FASTFORWARD}, + { 0x44, KEY_EPG}, + { 0x4c, KEY_INFO}, + { 0x41, KEY_AB}, + { 0x43, KEY_AUDIO}, + { 0x45, KEY_SUBTITLE}, + { 0x4a, KEY_LIST}, + { 0x46, KEY_F1}, + { 0x47, KEY_F2}, + { 0x5e, KEY_F3}, + { 0x5c, KEY_F4}, + { 0x52, KEY_F5}, + { 0x5a, KEY_F6}, + { 0x56, KEY_MODE}, + { 0x58, KEY_SWITCHVIDEOMODE}, +}; +struct ir_scancode_table ir_codes_tevii_nec_table = { + .scan = ir_codes_tevii_nec, + .size = ARRAY_SIZE(ir_codes_tevii_nec), +}; +EXPORT_SYMBOL_GPL(ir_codes_tevii_nec_table); + +static struct ir_scancode ir_codes_tbs_nec[] = { + { 0x04, KEY_POWER2}, /*power*/ + { 0x14, KEY_MUTE}, /*mute*/ + { 0x07, KEY_1}, + { 0x06, KEY_2}, + { 0x05, KEY_3}, + { 0x0b, KEY_4}, + { 0x0a, KEY_5}, + { 0x09, KEY_6}, + { 0x0f, KEY_7}, + { 0x0e, KEY_8}, + { 0x0d, KEY_9}, + { 0x12, KEY_0}, + { 0x16, KEY_CHANNELUP}, /*ch+*/ + { 0x11, KEY_CHANNELDOWN},/*ch-*/ + { 0x13, KEY_VOLUMEUP}, /*vol+*/ + { 0x0c, KEY_VOLUMEDOWN},/*vol-*/ + { 0x03, KEY_RECORD}, /*rec*/ + { 0x18, KEY_PAUSE}, /*pause*/ + { 0x19, KEY_OK}, /*ok*/ + { 0x1a, KEY_CAMERA}, /* snapshot */ + { 0x01, KEY_UP}, + { 0x10, KEY_LEFT}, + { 0x02, KEY_RIGHT}, + { 0x08, KEY_DOWN}, + { 0x15, KEY_FAVORITES}, + { 0x17, KEY_SUBTITLE}, + { 0x1d, KEY_ZOOM}, + { 0x1f, KEY_EXIT}, + { 0x1e, KEY_MENU}, + { 0x1c, KEY_EPG}, + { 0x00, KEY_PREVIOUS}, + { 0x1b, KEY_MODE}, +}; +struct ir_scancode_table ir_codes_tbs_nec_table = { + .scan = ir_codes_tbs_nec, + .size = ARRAY_SIZE(ir_codes_tbs_nec), +}; +EXPORT_SYMBOL_GPL(ir_codes_tbs_nec_table); + +/* Terratec Cinergy Hybrid T USB XS + Devin Heitmueller + */ +static struct ir_scancode ir_codes_terratec_cinergy_xs[] = { + { 0x41, KEY_HOME}, + { 0x01, KEY_POWER}, + { 0x42, KEY_MENU}, + { 0x02, KEY_1}, + { 0x03, KEY_2}, + { 0x04, KEY_3}, + { 0x43, KEY_SUBTITLE}, + { 0x05, KEY_4}, + { 0x06, KEY_5}, + { 0x07, KEY_6}, + { 0x44, KEY_TEXT}, + { 0x08, KEY_7}, + { 0x09, KEY_8}, + { 0x0a, KEY_9}, + { 0x45, KEY_DELETE}, + { 0x0b, KEY_TUNER}, + { 0x0c, KEY_0}, + { 0x0d, KEY_MODE}, + { 0x46, KEY_TV}, + { 0x47, KEY_DVD}, + { 0x49, KEY_VIDEO}, + { 0x4b, KEY_AUX}, + { 0x10, KEY_UP}, + { 0x11, KEY_LEFT}, + { 0x12, KEY_OK}, + { 0x13, KEY_RIGHT}, + { 0x14, KEY_DOWN}, + { 0x0f, KEY_EPG}, + { 0x16, KEY_INFO}, + { 0x4d, KEY_BACKSPACE}, + { 0x1c, KEY_VOLUMEUP}, + { 0x4c, KEY_PLAY}, + { 0x1b, KEY_CHANNELUP}, + { 0x1e, KEY_VOLUMEDOWN}, + { 0x1d, KEY_MUTE}, + { 0x1f, KEY_CHANNELDOWN}, + { 0x17, KEY_RED}, + { 0x18, KEY_GREEN}, + { 0x19, KEY_YELLOW}, + { 0x1a, KEY_BLUE}, + { 0x58, KEY_RECORD}, + { 0x48, KEY_STOP}, + { 0x40, KEY_PAUSE}, + { 0x54, KEY_LAST}, + { 0x4e, KEY_REWIND}, + { 0x4f, KEY_FASTFORWARD}, + { 0x5c, KEY_NEXT}, +}; +struct ir_scancode_table ir_codes_terratec_cinergy_xs_table = { + .scan = ir_codes_terratec_cinergy_xs, + .size = ARRAY_SIZE(ir_codes_terratec_cinergy_xs), +}; +EXPORT_SYMBOL_GPL(ir_codes_terratec_cinergy_xs_table); + +/* EVGA inDtube + Devin Heitmueller + */ +static struct ir_scancode ir_codes_evga_indtube[] = { + { 0x12, KEY_POWER}, + { 0x02, KEY_MODE}, /* TV */ + { 0x14, KEY_MUTE}, + { 0x1a, KEY_CHANNELUP}, + { 0x16, KEY_TV2}, /* PIP */ + { 0x1d, KEY_VOLUMEUP}, + { 0x05, KEY_CHANNELDOWN}, + { 0x0f, KEY_PLAYPAUSE}, + { 0x19, KEY_VOLUMEDOWN}, + { 0x1c, KEY_REWIND}, + { 0x0d, KEY_RECORD}, + { 0x18, KEY_FORWARD}, + { 0x1e, KEY_PREVIOUS}, + { 0x1b, KEY_STOP}, + { 0x1f, KEY_NEXT}, + { 0x13, KEY_CAMERA}, +}; +struct ir_scancode_table ir_codes_evga_indtube_table = { + .scan = ir_codes_evga_indtube, + .size = ARRAY_SIZE(ir_codes_evga_indtube), +}; +EXPORT_SYMBOL_GPL(ir_codes_evga_indtube_table); + +static struct ir_scancode ir_codes_videomate_s350[] = { + { 0x00, KEY_TV}, + { 0x01, KEY_DVD}, + { 0x04, KEY_RECORD}, + { 0x05, KEY_VIDEO}, /* TV/Video */ + { 0x07, KEY_STOP}, + { 0x08, KEY_PLAYPAUSE}, + { 0x0a, KEY_REWIND}, + { 0x0f, KEY_FASTFORWARD}, + { 0x10, KEY_CHANNELUP}, + { 0x12, KEY_VOLUMEUP}, + { 0x13, KEY_CHANNELDOWN}, + { 0x14, KEY_MUTE}, + { 0x15, KEY_VOLUMEDOWN}, + { 0x16, KEY_1}, + { 0x17, KEY_2}, + { 0x18, KEY_3}, + { 0x19, KEY_4}, + { 0x1a, KEY_5}, + { 0x1b, KEY_6}, + { 0x1c, KEY_7}, + { 0x1d, KEY_8}, + { 0x1e, KEY_9}, + { 0x1f, KEY_0}, + { 0x21, KEY_SLEEP}, + { 0x24, KEY_ZOOM}, + { 0x25, KEY_LAST}, /* Recall */ + { 0x26, KEY_SUBTITLE}, /* CC */ + { 0x27, KEY_LANGUAGE}, /* MTS */ + { 0x29, KEY_CHANNEL}, /* SURF */ + { 0x2b, KEY_A}, + { 0x2c, KEY_B}, + { 0x2f, KEY_CAMERA}, /* Snapshot */ + { 0x23, KEY_RADIO}, + { 0x02, KEY_PREVIOUSSONG}, + { 0x06, KEY_NEXTSONG}, + { 0x03, KEY_EPG}, + { 0x09, KEY_SETUP}, + { 0x22, KEY_BACKSPACE}, + { 0x0c, KEY_UP}, + { 0x0e, KEY_DOWN}, + { 0x0b, KEY_LEFT}, + { 0x0d, KEY_RIGHT}, + { 0x11, KEY_ENTER}, + { 0x20, KEY_TEXT}, +}; +struct ir_scancode_table ir_codes_videomate_s350_table = { + .scan = ir_codes_videomate_s350, + .size = ARRAY_SIZE(ir_codes_videomate_s350), +}; +EXPORT_SYMBOL_GPL(ir_codes_videomate_s350_table); + +/* GADMEI UTV330+ RM008Z remote + Shine Liu + */ +static struct ir_scancode ir_codes_gadmei_rm008z[] = { + { 0x14, KEY_POWER2}, /* POWER OFF */ + { 0x0c, KEY_MUTE}, /* MUTE */ + + { 0x18, KEY_TV}, /* TV */ + { 0x0e, KEY_VIDEO}, /* AV */ + { 0x0b, KEY_AUDIO}, /* SV */ + { 0x0f, KEY_RADIO}, /* FM */ + + { 0x00, KEY_1}, + { 0x01, KEY_2}, + { 0x02, KEY_3}, + { 0x03, KEY_4}, + { 0x04, KEY_5}, + { 0x05, KEY_6}, + { 0x06, KEY_7}, + { 0x07, KEY_8}, + { 0x08, KEY_9}, + { 0x09, KEY_0}, + { 0x0a, KEY_INFO}, /* OSD */ + { 0x1c, KEY_BACKSPACE}, /* LAST */ + + { 0x0d, KEY_PLAY}, /* PLAY */ + { 0x1e, KEY_CAMERA}, /* SNAPSHOT */ + { 0x1a, KEY_RECORD}, /* RECORD */ + { 0x17, KEY_STOP}, /* STOP */ + + { 0x1f, KEY_UP}, /* UP */ + { 0x44, KEY_DOWN}, /* DOWN */ + { 0x46, KEY_TAB}, /* BACK */ + { 0x4a, KEY_ZOOM}, /* FULLSECREEN */ + + { 0x10, KEY_VOLUMEUP}, /* VOLUMEUP */ + { 0x11, KEY_VOLUMEDOWN}, /* VOLUMEDOWN */ + { 0x12, KEY_CHANNELUP}, /* CHANNELUP */ + { 0x13, KEY_CHANNELDOWN}, /* CHANNELDOWN */ + { 0x15, KEY_ENTER}, /* OK */ +}; +struct ir_scancode_table ir_codes_gadmei_rm008z_table = { + .scan = ir_codes_gadmei_rm008z, + .size = ARRAY_SIZE(ir_codes_gadmei_rm008z), +}; +EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table); + +/************************************************************* + * COMPLETE SCANCODE TABLES + * Instead of just a partial scancode, the tables bellow + * contains the complete scancode and the receiver protocol + *************************************************************/ + +/* + * Hauppauge:the newer, gray remotes (seems there are multiple + * slightly different versions), shipped with cx88+ivtv cards. + * + * This table contains the complete RC5 code, instead of just the data part + */ +static struct ir_scancode ir_codes_rc5_hauppauge_new[] = { + /* Keys 0 to 9 */ + { 0x1e00, KEY_0 }, + { 0x1e01, KEY_1 }, + { 0x1e02, KEY_2 }, + { 0x1e03, KEY_3 }, + { 0x1e04, KEY_4 }, + { 0x1e05, KEY_5 }, + { 0x1e06, KEY_6 }, + { 0x1e07, KEY_7 }, + { 0x1e08, KEY_8 }, + { 0x1e09, KEY_9 }, + + { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */ + { 0x1e0b, KEY_RED }, /* red button */ + { 0x1e0c, KEY_RADIO }, + { 0x1e0d, KEY_MENU }, + { 0x1e0e, KEY_SUBTITLE }, /* also the # key */ + { 0x1e0f, KEY_MUTE }, + { 0x1e10, KEY_VOLUMEUP }, + { 0x1e11, KEY_VOLUMEDOWN }, + { 0x1e12, KEY_PREVIOUS }, /* previous channel */ + { 0x1e14, KEY_UP }, + { 0x1e15, KEY_DOWN }, + { 0x1e16, KEY_LEFT }, + { 0x1e17, KEY_RIGHT }, + { 0x1e18, KEY_VIDEO }, /* Videos */ + { 0x1e19, KEY_AUDIO }, /* Music */ + /* 0x1e1a: Pictures - presume this means + "Multimedia Home Platform" - + no "PICTURES" key in input.h + */ + { 0x1e1a, KEY_MHP }, + + { 0x1e1b, KEY_EPG }, /* Guide */ + { 0x1e1c, KEY_TV }, + { 0x1e1e, KEY_NEXTSONG }, /* skip >| */ + { 0x1e1f, KEY_EXIT }, /* back/exit */ + { 0x1e20, KEY_CHANNELUP }, /* channel / program + */ + { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */ + { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */ + { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */ + { 0x1e25, KEY_ENTER }, /* OK */ + { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */ + { 0x1e29, KEY_BLUE }, /* blue key */ + { 0x1e2e, KEY_GREEN }, /* green button */ + { 0x1e30, KEY_PAUSE }, /* pause */ + { 0x1e32, KEY_REWIND }, /* backward << */ + { 0x1e34, KEY_FASTFORWARD }, /* forward >> */ + { 0x1e35, KEY_PLAY }, + { 0x1e36, KEY_STOP }, + { 0x1e37, KEY_RECORD }, /* recording */ + { 0x1e38, KEY_YELLOW }, /* yellow key */ + { 0x1e3b, KEY_SELECT }, /* top right button */ + { 0x1e3c, KEY_ZOOM }, /* full */ + { 0x1e3d, KEY_POWER }, /* system power (green button) */ +}; + +struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = { + .scan = ir_codes_rc5_hauppauge_new, + .size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new), + .ir_type = IR_TYPE_RC5, +}; +EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table); + +/* Terratec Cinergy Hybrid T USB XS FM + Mauro Carvalho Chehab + */ +static struct ir_scancode ir_codes_nec_terratec_cinergy_xs[] = { + { 0x1441, KEY_HOME}, + { 0x1401, KEY_POWER2}, + + { 0x1442, KEY_MENU}, /* DVD menu */ + { 0x1443, KEY_SUBTITLE}, + { 0x1444, KEY_TEXT}, /* Teletext */ + { 0x1445, KEY_DELETE}, + + { 0x1402, KEY_1}, + { 0x1403, KEY_2}, + { 0x1404, KEY_3}, + { 0x1405, KEY_4}, + { 0x1406, KEY_5}, + { 0x1407, KEY_6}, + { 0x1408, KEY_7}, + { 0x1409, KEY_8}, + { 0x140a, KEY_9}, + { 0x140c, KEY_0}, + + { 0x140b, KEY_TUNER}, /* AV */ + { 0x140d, KEY_MODE}, /* A.B */ + + { 0x1446, KEY_TV}, + { 0x1447, KEY_DVD}, + { 0x1449, KEY_VIDEO}, + { 0x144a, KEY_RADIO}, /* Music */ + { 0x144b, KEY_CAMERA}, /* PIC */ + + { 0x1410, KEY_UP}, + { 0x1411, KEY_LEFT}, + { 0x1412, KEY_OK}, + { 0x1413, KEY_RIGHT}, + { 0x1414, KEY_DOWN}, + + { 0x140f, KEY_EPG}, + { 0x1416, KEY_INFO}, + { 0x144d, KEY_BACKSPACE}, + + { 0x141c, KEY_VOLUMEUP}, + { 0x141e, KEY_VOLUMEDOWN}, + + { 0x144c, KEY_PLAY}, + { 0x141d, KEY_MUTE}, + + { 0x141b, KEY_CHANNELUP}, + { 0x141f, KEY_CHANNELDOWN}, + + { 0x1417, KEY_RED}, + { 0x1418, KEY_GREEN}, + { 0x1419, KEY_YELLOW}, + { 0x141a, KEY_BLUE}, + + { 0x1458, KEY_RECORD}, + { 0x1448, KEY_STOP}, + { 0x1440, KEY_PAUSE}, + + { 0x1454, KEY_LAST}, + { 0x144e, KEY_REWIND}, + { 0x144f, KEY_FASTFORWARD}, + { 0x145c, KEY_NEXT}, +}; +struct ir_scancode_table ir_codes_nec_terratec_cinergy_xs_table = { + .scan = ir_codes_nec_terratec_cinergy_xs, + .size = ARRAY_SIZE(ir_codes_nec_terratec_cinergy_xs), + .ir_type = IR_TYPE_NEC, +}; +EXPORT_SYMBOL_GPL(ir_codes_nec_terratec_cinergy_xs_table); + diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c new file mode 100644 index 00000000000..99ed2deceef --- /dev/null +++ b/drivers/media/IR/ir-keytable.c @@ -0,0 +1,433 @@ +/* ir-register.c - handle IR scancode->keycode tables + * + * Copyright (C) 2009 by Mauro Carvalho Chehab + */ + +#include + +#include + +#define IR_TAB_MIN_SIZE 32 +#define IR_TAB_MAX_SIZE 1024 + + +/** + * ir_seek_table() - returns the element order on the table + * @rc_tab: the ir_scancode_table with the keymap to be used + * @scancode: the scancode that we're seeking + * + * This routine is used by the input routines when a key is pressed at the + * IR. The scancode is received and needs to be converted into a keycode. + * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the + * corresponding keycode from the table. + */ +static int ir_seek_table(struct ir_scancode_table *rc_tab, u32 scancode) +{ + int rc; + unsigned long flags; + struct ir_scancode *keymap = rc_tab->scan; + + spin_lock_irqsave(&rc_tab->lock, flags); + + /* FIXME: replace it by a binary search */ + + for (rc = 0; rc < rc_tab->size; rc++) + if (keymap[rc].scancode == scancode) + goto exit; + + /* Not found */ + rc = -EINVAL; + +exit: + spin_unlock_irqrestore(&rc_tab->lock, flags); + return rc; +} + +/** + * ir_roundup_tablesize() - gets an optimum value for the table size + * @n_elems: minimum number of entries to store keycodes + * + * This routine is used to choose the keycode table size. + * + * In order to have some empty space for new keycodes, + * and knowing in advance that kmalloc allocates only power of two + * segments, it optimizes the allocated space to have some spare space + * for those new keycodes by using the maximum number of entries that + * will be effectively be allocated by kmalloc. + * In order to reduce the quantity of table resizes, it has a minimum + * table size of IR_TAB_MIN_SIZE. + */ +int ir_roundup_tablesize(int n_elems) +{ + size_t size; + + if (n_elems < IR_TAB_MIN_SIZE) + n_elems = IR_TAB_MIN_SIZE; + + /* + * As kmalloc only allocates sizes of power of two, get as + * much entries as possible for the allocated memory segment + */ + size = roundup_pow_of_two(n_elems * sizeof(struct ir_scancode)); + n_elems = size / sizeof(struct ir_scancode); + + return n_elems; +} + +/** + * ir_copy_table() - copies a keytable, discarding the unused entries + * @destin: destin table + * @origin: origin table + * + * Copies all entries where the keycode is not KEY_UNKNOWN/KEY_RESERVED + */ + +int ir_copy_table(struct ir_scancode_table *destin, + const struct ir_scancode_table *origin) +{ + int i, j = 0; + + for (i = 0; i < origin->size; i++) { + if (origin->scan[i].keycode == KEY_UNKNOWN || + origin->scan[i].keycode == KEY_RESERVED) + continue; + + memcpy(&destin->scan[j], &origin->scan[i], sizeof(struct ir_scancode)); + j++; + } + destin->size = j; + + IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", destin->size); + + return 0; +} + +/** + * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table + * @dev: the struct input_dev device descriptor + * @scancode: the desired scancode + * @keycode: the keycode to be retorned. + * + * This routine is used to handle evdev EVIOCGKEY ioctl. + * If the key is not found, returns -EINVAL, otherwise, returns 0. + */ +static int ir_getkeycode(struct input_dev *dev, + int scancode, int *keycode) +{ + int elem; + struct ir_scancode_table *rc_tab = input_get_drvdata(dev); + + elem = ir_seek_table(rc_tab, scancode); + if (elem >= 0) { + *keycode = rc_tab->scan[elem].keycode; + return 0; + } + + /* + * Scancode not found and table can't be expanded + */ + if (elem < 0 && rc_tab->size == IR_TAB_MAX_SIZE) + return -EINVAL; + + /* + * If is there extra space, returns KEY_RESERVED, + * otherwise, input core won't let ir_setkeycode to work + */ + *keycode = KEY_RESERVED; + return 0; +} + + +/** + * ir_is_resize_needed() - Check if the table needs rezise + * @table: keycode table that may need to resize + * @n_elems: minimum number of entries to store keycodes + * + * Considering that kmalloc uses power of two storage areas, this + * routine detects if the real alloced size will change. If not, it + * just returns without doing nothing. Otherwise, it will extend or + * reduce the table size to meet the new needs. + * + * It returns 0 if no resize is needed, 1 otherwise. + */ +static int ir_is_resize_needed(struct ir_scancode_table *table, int n_elems) +{ + int cur_size = ir_roundup_tablesize(table->size); + int new_size = ir_roundup_tablesize(n_elems); + + if (cur_size == new_size) + return 0; + + /* Resize is needed */ + return 1; +} + +/** + * ir_delete_key() - remove a keycode from the table + * @rc_tab: keycode table + * @elem: element to be removed + * + */ +static void ir_delete_key(struct ir_scancode_table *rc_tab, int elem) +{ + unsigned long flags = 0; + int newsize = rc_tab->size - 1; + int resize = ir_is_resize_needed(rc_tab, newsize); + struct ir_scancode *oldkeymap = rc_tab->scan; + struct ir_scancode *newkeymap; + + if (resize) { + newkeymap = kzalloc(ir_roundup_tablesize(newsize) * + sizeof(*newkeymap), GFP_ATOMIC); + + /* There's no memory for resize. Keep the old table */ + if (!newkeymap) + resize = 0; + } + + if (!resize) { + newkeymap = oldkeymap; + + /* We'll modify the live table. Lock it */ + spin_lock_irqsave(&rc_tab->lock, flags); + } + + /* + * Copy the elements before the one that will be deleted + * if (!resize), both oldkeymap and newkeymap points + * to the same place, so, there's no need to copy + */ + if (resize && elem > 0) + memcpy(newkeymap, oldkeymap, + elem * sizeof(*newkeymap)); + + /* + * Copy the other elements overwriting the element to be removed + * This operation applies to both resize and non-resize case + */ + if (elem < newsize) + memcpy(&newkeymap[elem], &oldkeymap[elem + 1], + (newsize - elem) * sizeof(*newkeymap)); + + if (resize) { + /* + * As the copy happened to a temporary table, only here + * it needs to lock while replacing the table pointers + * to use the new table + */ + spin_lock_irqsave(&rc_tab->lock, flags); + rc_tab->size = newsize; + rc_tab->scan = newkeymap; + spin_unlock_irqrestore(&rc_tab->lock, flags); + + /* Frees the old keytable */ + kfree(oldkeymap); + } else { + rc_tab->size = newsize; + spin_unlock_irqrestore(&rc_tab->lock, flags); + } +} + +/** + * ir_insert_key() - insert a keycode at the table + * @rc_tab: keycode table + * @scancode: the desired scancode + * @keycode: the keycode to be retorned. + * + */ +static int ir_insert_key(struct ir_scancode_table *rc_tab, + int scancode, int keycode) +{ + unsigned long flags; + int elem = rc_tab->size; + int newsize = rc_tab->size + 1; + int resize = ir_is_resize_needed(rc_tab, newsize); + struct ir_scancode *oldkeymap = rc_tab->scan; + struct ir_scancode *newkeymap; + + if (resize) { + newkeymap = kzalloc(ir_roundup_tablesize(newsize) * + sizeof(*newkeymap), GFP_ATOMIC); + if (!newkeymap) + return -ENOMEM; + + memcpy(newkeymap, oldkeymap, + rc_tab->size * sizeof(*newkeymap)); + } else + newkeymap = oldkeymap; + + /* Stores the new code at the table */ + IR_dprintk(1, "#%d: New scan 0x%04x with key 0x%04x\n", + rc_tab->size, scancode, keycode); + + spin_lock_irqsave(&rc_tab->lock, flags); + rc_tab->size = newsize; + if (resize) { + rc_tab->scan = newkeymap; + kfree(oldkeymap); + } + newkeymap[elem].scancode = scancode; + newkeymap[elem].keycode = keycode; + spin_unlock_irqrestore(&rc_tab->lock, flags); + + return 0; +} + +/** + * ir_setkeycode() - set a keycode at the evdev scancode ->keycode table + * @dev: the struct input_dev device descriptor + * @scancode: the desired scancode + * @keycode: the keycode to be retorned. + * + * This routine is used to handle evdev EVIOCSKEY ioctl. + * There's one caveat here: how can we increase the size of the table? + * If the key is not found, returns -EINVAL, otherwise, returns 0. + */ +static int ir_setkeycode(struct input_dev *dev, + int scancode, int keycode) +{ + int rc = 0; + struct ir_scancode_table *rc_tab = input_get_drvdata(dev); + struct ir_scancode *keymap = rc_tab->scan; + unsigned long flags; + + /* + * Handle keycode table deletions + * + * If userspace is adding a KEY_UNKNOWN or KEY_RESERVED, + * deal as a trial to remove an existing scancode attribution + * if table become too big, reduce it to save space + */ + if (keycode == KEY_UNKNOWN || keycode == KEY_RESERVED) { + rc = ir_seek_table(rc_tab, scancode); + if (rc < 0) + return 0; + + IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", rc, scancode); + clear_bit(keymap[rc].keycode, dev->keybit); + ir_delete_key(rc_tab, rc); + + return 0; + } + + /* + * Handle keycode replacements + * + * If the scancode exists, just replace by the new value + */ + rc = ir_seek_table(rc_tab, scancode); + if (rc >= 0) { + IR_dprintk(1, "#%d: Replacing scan 0x%04x with key 0x%04x\n", + rc, scancode, keycode); + + clear_bit(keymap[rc].keycode, dev->keybit); + + spin_lock_irqsave(&rc_tab->lock, flags); + keymap[rc].keycode = keycode; + spin_unlock_irqrestore(&rc_tab->lock, flags); + + set_bit(keycode, dev->keybit); + + return 0; + } + + /* + * Handle new scancode inserts + * + * reallocate table if needed and insert a new keycode + */ + + /* Avoid growing the table indefinitely */ + if (rc_tab->size + 1 > IR_TAB_MAX_SIZE) + return -EINVAL; + + rc = ir_insert_key(rc_tab, scancode, keycode); + if (rc < 0) + return rc; + set_bit(keycode, dev->keybit); + + return 0; +} + +/** + * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode + * @input_dev: the struct input_dev descriptor of the device + * @scancode: the scancode that we're seeking + * + * This routine is used by the input routines when a key is pressed at the + * IR. The scancode is received and needs to be converted into a keycode. + * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the + * corresponding keycode from the table. + */ +u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) +{ + struct ir_scancode_table *rc_tab = input_get_drvdata(dev); + struct ir_scancode *keymap = rc_tab->scan; + int elem; + + elem = ir_seek_table(rc_tab, scancode); + if (elem >= 0) { + IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", + dev->name, scancode, keymap[elem].keycode); + + return rc_tab->scan[elem].keycode; + } + + printk(KERN_INFO "%s: unknown key for scancode 0x%04x\n", + dev->name, scancode); + + /* Reports userspace that an unknown keycode were got */ + return KEY_RESERVED; +} + +/** + * ir_set_keycode_table() - sets the IR keycode table and add the handlers + * for keymap table get/set + * @input_dev: the struct input_dev descriptor of the device + * @rc_tab: the struct ir_scancode_table table of scancode/keymap + * + * This routine is used to initialize the input infrastructure to work with + * an IR. + * It should be called before registering the IR device. + */ +int ir_set_keycode_table(struct input_dev *input_dev, + struct ir_scancode_table *rc_tab) +{ + struct ir_scancode *keymap = rc_tab->scan; + int i; + + spin_lock_init(&rc_tab->lock); + + if (rc_tab->scan == NULL || !rc_tab->size) + return -EINVAL; + + /* set the bits for the keys */ + IR_dprintk(1, "key map size: %d\n", rc_tab->size); + for (i = 0; i < rc_tab->size; i++) { + IR_dprintk(1, "#%d: setting bit for keycode 0x%04x\n", + i, keymap[i].keycode); + set_bit(keymap[i].keycode, input_dev->keybit); + } + + input_dev->getkeycode = ir_getkeycode; + input_dev->setkeycode = ir_setkeycode; + input_set_drvdata(input_dev, rc_tab); + + return 0; +} + +void ir_input_free(struct input_dev *dev) +{ + struct ir_scancode_table *rc_tab = input_get_drvdata(dev); + + if (!rc_tab) + return; + + IR_dprintk(1, "Freed keycode table\n"); + + rc_tab->size = 0; + kfree(rc_tab->scan); + rc_tab->scan = NULL; +} +EXPORT_SYMBOL_GPL(ir_input_free); + diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index ba69beeb0e2..a28541b2b1a 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -99,6 +99,7 @@ config VIDEO_MEDIA comment "Multimedia drivers" source "drivers/media/common/Kconfig" +source "drivers/media/IR/Kconfig" # # Tuner drivers for DVB and V4L diff --git a/drivers/media/Makefile b/drivers/media/Makefile index 09a829d8a7e..499b0810d01 100644 --- a/drivers/media/Makefile +++ b/drivers/media/Makefile @@ -2,7 +2,7 @@ # Makefile for the kernel multimedia device drivers. # -obj-y += common/ video/ +obj-y += common/ IR/ video/ obj-$(CONFIG_VIDEO_DEV) += radio/ obj-$(CONFIG_DVB_CORE) += dvb/ diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile index 169b337b7c9..e3ec9639321 100644 --- a/drivers/media/common/Makefile +++ b/drivers/media/common/Makefile @@ -1,8 +1,6 @@ saa7146-objs := saa7146_i2c.o saa7146_core.o saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o -ir-common-objs := ir-functions.o ir-keymaps.o ir-keytable.o obj-y += tuners/ obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o -obj-$(CONFIG_VIDEO_IR) += ir-common.o diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c deleted file mode 100644 index e616f624cea..00000000000 --- a/drivers/media/common/ir-functions.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * - * some common structs and functions to handle infrared remotes via - * input layer ... - * - * (c) 2003 Gerd Knorr [SuSE Labs] - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include - -/* -------------------------------------------------------------------------- */ - -MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); -MODULE_LICENSE("GPL"); - -static int repeat = 1; -module_param(repeat, int, 0444); -MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)"); - -int media_ir_debug; /* media_ir_debug level (0,1,2) */ -module_param_named(debug, media_ir_debug, int, 0644); - -/* -------------------------------------------------------------------------- */ - -static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) -{ - if (KEY_RESERVED == ir->keycode) { - printk(KERN_INFO "%s: unknown key: key=0x%02x down=%d\n", - dev->name, ir->ir_key, ir->keypressed); - return; - } - IR_dprintk(1,"%s: key event code=%d down=%d\n", - dev->name,ir->keycode,ir->keypressed); - input_report_key(dev,ir->keycode,ir->keypressed); - input_sync(dev); -} - -/* -------------------------------------------------------------------------- */ - -int ir_input_init(struct input_dev *dev, struct ir_input_state *ir, - int ir_type, struct ir_scancode_table *ir_codes) -{ - ir->ir_type = ir_type; - - ir->keytable.size = ir_roundup_tablesize(ir_codes->size); - ir->keytable.scan = kzalloc(ir->keytable.size * - sizeof(struct ir_scancode), GFP_KERNEL); - if (!ir->keytable.scan) - return -ENOMEM; - - IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n", - ir->keytable.size, - ir->keytable.size * sizeof(ir->keytable.scan)); - - ir_copy_table(&ir->keytable, ir_codes); - ir_set_keycode_table(dev, &ir->keytable); - - clear_bit(0, dev->keybit); - set_bit(EV_KEY, dev->evbit); - if (repeat) - set_bit(EV_REP, dev->evbit); - - return 0; -} -EXPORT_SYMBOL_GPL(ir_input_init); - - -void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir) -{ - if (ir->keypressed) { - ir->keypressed = 0; - ir_input_key_event(dev,ir); - } -} -EXPORT_SYMBOL_GPL(ir_input_nokey); - -void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, - u32 ir_key) -{ - u32 keycode = ir_g_keycode_from_table(dev, ir_key); - - if (ir->keypressed && ir->keycode != keycode) { - ir->keypressed = 0; - ir_input_key_event(dev,ir); - } - if (!ir->keypressed) { - ir->ir_key = ir_key; - ir->keycode = keycode; - ir->keypressed = 1; - ir_input_key_event(dev,ir); - } -} -EXPORT_SYMBOL_GPL(ir_input_keydown); - -/* -------------------------------------------------------------------------- */ -/* extract mask bits out of data and pack them into the result */ -u32 ir_extract_bits(u32 data, u32 mask) -{ - u32 vbit = 1, value = 0; - - do { - if (mask&1) { - if (data&1) - value |= vbit; - vbit<<=1; - } - data>>=1; - } while (mask>>=1); - - return value; -} -EXPORT_SYMBOL_GPL(ir_extract_bits); - -static int inline getbit(u32 *samples, int bit) -{ - return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0; -} - -/* sump raw samples for visual debugging ;) */ -int ir_dump_samples(u32 *samples, int count) -{ - int i, bit, start; - - printk(KERN_DEBUG "ir samples: "); - start = 0; - for (i = 0; i < count * 32; i++) { - bit = getbit(samples,i); - if (bit) - start = 1; - if (0 == start) - continue; - printk("%s", bit ? "#" : "_"); - } - printk("\n"); - return 0; -} -EXPORT_SYMBOL_GPL(ir_dump_samples); - -/* decode raw samples, pulse distance coding used by NEC remotes */ -int ir_decode_pulsedistance(u32 *samples, int count, int low, int high) -{ - int i,last,bit,len; - u32 curBit; - u32 value; - - /* find start burst */ - for (i = len = 0; i < count * 32; i++) { - bit = getbit(samples,i); - if (bit) { - len++; - } else { - if (len >= 29) - break; - len = 0; - } - } - - /* start burst to short */ - if (len < 29) - return 0xffffffff; - - /* find start silence */ - for (len = 0; i < count * 32; i++) { - bit = getbit(samples,i); - if (bit) { - break; - } else { - len++; - } - } - - /* silence to short */ - if (len < 7) - return 0xffffffff; - - /* go decoding */ - len = 0; - last = 1; - value = 0; curBit = 1; - for (; i < count * 32; i++) { - bit = getbit(samples,i); - if (last) { - if(bit) { - continue; - } else { - len = 1; - } - } else { - if (bit) { - if (len > (low + high) /2) - value |= curBit; - curBit <<= 1; - if (curBit == 1) - break; - } else { - len++; - } - } - last = bit; - } - - return value; -} -EXPORT_SYMBOL_GPL(ir_decode_pulsedistance); - -/* decode raw samples, biphase coding, used by rc5 for example */ -int ir_decode_biphase(u32 *samples, int count, int low, int high) -{ - int i,last,bit,len,flips; - u32 value; - - /* find start bit (1) */ - for (i = 0; i < 32; i++) { - bit = getbit(samples,i); - if (bit) - break; - } - - /* go decoding */ - len = 0; - flips = 0; - value = 1; - for (; i < count * 32; i++) { - if (len > high) - break; - if (flips > 1) - break; - last = bit; - bit = getbit(samples,i); - if (last == bit) { - len++; - continue; - } - if (len < low) { - len++; - flips++; - continue; - } - value <<= 1; - value |= bit; - flips = 0; - len = 1; - } - return value; -} -EXPORT_SYMBOL_GPL(ir_decode_biphase); - -/* RC5 decoding stuff, moved from bttv-input.c to share it with - * saa7134 */ - -/* decode raw bit pattern to RC5 code */ -u32 ir_rc5_decode(unsigned int code) -{ - unsigned int org_code = code; - unsigned int pair; - unsigned int rc5 = 0; - int i; - - for (i = 0; i < 14; ++i) { - pair = code & 0x3; - code >>= 2; - - rc5 <<= 1; - switch (pair) { - case 0: - case 2: - break; - case 1: - rc5 |= 1; - break; - case 3: - IR_dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code); - return 0; - } - } - IR_dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " - "instr=%x\n", rc5, org_code, RC5_START(rc5), - RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); - return rc5; -} -EXPORT_SYMBOL_GPL(ir_rc5_decode); - -void ir_rc5_timer_end(unsigned long data) -{ - struct card_ir *ir = (struct card_ir *)data; - struct timeval tv; - unsigned long current_jiffies, timeout; - u32 gap; - u32 rc5 = 0; - - /* get time */ - current_jiffies = jiffies; - do_gettimeofday(&tv); - - /* avoid overflow with gap >1s */ - if (tv.tv_sec - ir->base_time.tv_sec > 1) { - gap = 200000; - } else { - gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + - tv.tv_usec - ir->base_time.tv_usec; - } - - /* signal we're ready to start a new code */ - ir->active = 0; - - /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */ - if (gap < 28000) { - IR_dprintk(1, "ir-common: spurious timer_end\n"); - return; - } - - if (ir->last_bit < 20) { - /* ignore spurious codes (caused by light/other remotes) */ - IR_dprintk(1, "ir-common: short code: %x\n", ir->code); - } else { - ir->code = (ir->code << ir->shift_by) | 1; - rc5 = ir_rc5_decode(ir->code); - - /* two start bits? */ - if (RC5_START(rc5) != ir->start) { - IR_dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5)); - - /* right address? */ - } else if (RC5_ADDR(rc5) == ir->addr) { - u32 toggle = RC5_TOGGLE(rc5); - u32 instr = RC5_INSTR(rc5); - - /* Good code, decide if repeat/repress */ - if (toggle != RC5_TOGGLE(ir->last_rc5) || - instr != RC5_INSTR(ir->last_rc5)) { - IR_dprintk(1, "ir-common: instruction %x, toggle %x\n", instr, - toggle); - ir_input_nokey(ir->dev, &ir->ir); - ir_input_keydown(ir->dev, &ir->ir, instr); - } - - /* Set/reset key-up timer */ - timeout = current_jiffies + - msecs_to_jiffies(ir->rc5_key_timeout); - mod_timer(&ir->timer_keyup, timeout); - - /* Save code for repeat test */ - ir->last_rc5 = rc5; - } - } -} -EXPORT_SYMBOL_GPL(ir_rc5_timer_end); - -void ir_rc5_timer_keyup(unsigned long data) -{ - struct card_ir *ir = (struct card_ir *)data; - - IR_dprintk(1, "ir-common: key released\n"); - ir_input_nokey(ir->dev, &ir->ir); -} -EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup); diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c deleted file mode 100644 index 9bbe6b1e987..00000000000 --- a/drivers/media/common/ir-keymaps.c +++ /dev/null @@ -1,3395 +0,0 @@ -/* - Keytables for supported remote controls, used on drivers/media - devices. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/* - * NOTICE FOR DEVELOPERS: - * The IR mappings should be as close as possible to what's - * specified at: - * http://linuxtv.org/wiki/index.php/Remote_Controllers - */ -#include - -#include -#include - -/* empty keytable, can be used as placeholder for not-yet created keytables */ -static struct ir_scancode ir_codes_empty[] = { - { 0x2a, KEY_COFFEE }, -}; - -struct ir_scancode_table ir_codes_empty_table = { - .scan = ir_codes_empty, - .size = ARRAY_SIZE(ir_codes_empty), -}; -EXPORT_SYMBOL_GPL(ir_codes_empty_table); - -/* Michal Majchrowicz */ -static struct ir_scancode ir_codes_proteus_2309[] = { - /* numeric */ - { 0x00, KEY_0 }, - { 0x01, KEY_1 }, - { 0x02, KEY_2 }, - { 0x03, KEY_3 }, - { 0x04, KEY_4 }, - { 0x05, KEY_5 }, - { 0x06, KEY_6 }, - { 0x07, KEY_7 }, - { 0x08, KEY_8 }, - { 0x09, KEY_9 }, - - { 0x5c, KEY_POWER }, /* power */ - { 0x20, KEY_ZOOM }, /* full screen */ - { 0x0f, KEY_BACKSPACE }, /* recall */ - { 0x1b, KEY_ENTER }, /* mute */ - { 0x41, KEY_RECORD }, /* record */ - { 0x43, KEY_STOP }, /* stop */ - { 0x16, KEY_S }, - { 0x1a, KEY_POWER2 }, /* off */ - { 0x2e, KEY_RED }, - { 0x1f, KEY_CHANNELDOWN }, /* channel - */ - { 0x1c, KEY_CHANNELUP }, /* channel + */ - { 0x10, KEY_VOLUMEDOWN }, /* volume - */ - { 0x1e, KEY_VOLUMEUP }, /* volume + */ - { 0x14, KEY_F1 }, -}; - -struct ir_scancode_table ir_codes_proteus_2309_table = { - .scan = ir_codes_proteus_2309, - .size = ARRAY_SIZE(ir_codes_proteus_2309), -}; -EXPORT_SYMBOL_GPL(ir_codes_proteus_2309_table); - -/* Matt Jesson >' */ - { 0x3a, KEY_RECORD }, /* 'capture' */ - { 0x0a, KEY_MUTE }, /* 'mute' */ - { 0x2c, KEY_RECORD }, /* 'record' */ - { 0x1c, KEY_PAUSE }, /* 'pause' */ - { 0x3c, KEY_STOP }, /* 'stop' */ - { 0x0c, KEY_PLAY }, /* 'play' */ - { 0x2e, KEY_RED }, /* 'red' */ - { 0x01, KEY_BLUE }, /* 'blue' / 'cancel' */ - { 0x0e, KEY_YELLOW }, /* 'yellow' / 'ok' */ - { 0x21, KEY_GREEN }, /* 'green' */ - { 0x11, KEY_CHANNELDOWN }, /* 'channel -' */ - { 0x31, KEY_CHANNELUP }, /* 'channel +' */ - { 0x1e, KEY_VOLUMEDOWN }, /* 'volume -' */ - { 0x3e, KEY_VOLUMEUP }, /* 'volume +' */ -}; - -struct ir_scancode_table ir_codes_avermedia_dvbt_table = { - .scan = ir_codes_avermedia_dvbt, - .size = ARRAY_SIZE(ir_codes_avermedia_dvbt), -}; -EXPORT_SYMBOL_GPL(ir_codes_avermedia_dvbt_table); - -/* Mauro Carvalho Chehab */ -static struct ir_scancode ir_codes_avermedia_m135a[] = { - { 0x00, KEY_POWER2 }, - { 0x2e, KEY_DOT }, /* '.' */ - { 0x01, KEY_MODE }, /* TV/FM */ - - { 0x05, KEY_1 }, - { 0x06, KEY_2 }, - { 0x07, KEY_3 }, - { 0x09, KEY_4 }, - { 0x0a, KEY_5 }, - { 0x0b, KEY_6 }, - { 0x0d, KEY_7 }, - { 0x0e, KEY_8 }, - { 0x0f, KEY_9 }, - { 0x11, KEY_0 }, - - { 0x13, KEY_RIGHT }, /* -> */ - { 0x12, KEY_LEFT }, /* <- */ - - { 0x17, KEY_SLEEP }, /* Capturar Imagem */ - { 0x10, KEY_SHUFFLE }, /* Amostra */ - - /* FIXME: The keys bellow aren't ok */ - - { 0x43, KEY_CHANNELUP }, - { 0x42, KEY_CHANNELDOWN }, - { 0x1f, KEY_VOLUMEUP }, - { 0x1e, KEY_VOLUMEDOWN }, - { 0x0c, KEY_ENTER }, - - { 0x14, KEY_MUTE }, - { 0x08, KEY_AUDIO }, - - { 0x03, KEY_TEXT }, - { 0x04, KEY_EPG }, - { 0x2b, KEY_TV2 }, /* TV2 */ - - { 0x1d, KEY_RED }, - { 0x1c, KEY_YELLOW }, - { 0x41, KEY_GREEN }, - { 0x40, KEY_BLUE }, - - { 0x1a, KEY_PLAYPAUSE }, - { 0x19, KEY_RECORD }, - { 0x18, KEY_PLAY }, - { 0x1b, KEY_STOP }, -}; - -struct ir_scancode_table ir_codes_avermedia_m135a_table = { - .scan = ir_codes_avermedia_m135a, - .size = ARRAY_SIZE(ir_codes_avermedia_m135a), -}; -EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a_table); - -/* Oldrich Jedlicka */ -static struct ir_scancode ir_codes_avermedia_cardbus[] = { - { 0x00, KEY_POWER }, - { 0x01, KEY_TUNER }, /* TV/FM */ - { 0x03, KEY_TEXT }, /* Teletext */ - { 0x04, KEY_EPG }, - { 0x05, KEY_1 }, - { 0x06, KEY_2 }, - { 0x07, KEY_3 }, - { 0x08, KEY_AUDIO }, - { 0x09, KEY_4 }, - { 0x0a, KEY_5 }, - { 0x0b, KEY_6 }, - { 0x0c, KEY_ZOOM }, /* Full screen */ - { 0x0d, KEY_7 }, - { 0x0e, KEY_8 }, - { 0x0f, KEY_9 }, - { 0x10, KEY_PAGEUP }, /* 16-CH PREV */ - { 0x11, KEY_0 }, - { 0x12, KEY_INFO }, - { 0x13, KEY_AGAIN }, /* CH RTN - channel return */ - { 0x14, KEY_MUTE }, - { 0x15, KEY_EDIT }, /* Autoscan */ - { 0x17, KEY_SAVE }, /* Screenshot */ - { 0x18, KEY_PLAYPAUSE }, - { 0x19, KEY_RECORD }, - { 0x1a, KEY_PLAY }, - { 0x1b, KEY_STOP }, - { 0x1c, KEY_FASTFORWARD }, - { 0x1d, KEY_REWIND }, - { 0x1e, KEY_VOLUMEDOWN }, - { 0x1f, KEY_VOLUMEUP }, - { 0x22, KEY_SLEEP }, /* Sleep */ - { 0x23, KEY_ZOOM }, /* Aspect */ - { 0x26, KEY_SCREEN }, /* Pos */ - { 0x27, KEY_ANGLE }, /* Size */ - { 0x28, KEY_SELECT }, /* Select */ - { 0x29, KEY_BLUE }, /* Blue/Picture */ - { 0x2a, KEY_BACKSPACE }, /* Back */ - { 0x2b, KEY_MEDIA }, /* PIP (Picture-in-picture) */ - { 0x2c, KEY_DOWN }, - { 0x2e, KEY_DOT }, - { 0x2f, KEY_TV }, /* Live TV */ - { 0x32, KEY_LEFT }, - { 0x33, KEY_CLEAR }, /* Clear */ - { 0x35, KEY_RED }, /* Red/TV */ - { 0x36, KEY_UP }, - { 0x37, KEY_HOME }, /* Home */ - { 0x39, KEY_GREEN }, /* Green/Video */ - { 0x3d, KEY_YELLOW }, /* Yellow/Music */ - { 0x3e, KEY_OK }, /* Ok */ - { 0x3f, KEY_RIGHT }, - { 0x40, KEY_NEXT }, /* Next */ - { 0x41, KEY_PREVIOUS }, /* Previous */ - { 0x42, KEY_CHANNELDOWN }, /* Channel down */ - { 0x43, KEY_CHANNELUP }, /* Channel up */ -}; - -struct ir_scancode_table ir_codes_avermedia_cardbus_table = { - .scan = ir_codes_avermedia_cardbus, - .size = ARRAY_SIZE(ir_codes_avermedia_cardbus), -}; -EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus_table); - -/* Attila Kondoros */ -static struct ir_scancode ir_codes_apac_viewcomp[] = { - - { 0x01, KEY_1 }, - { 0x02, KEY_2 }, - { 0x03, KEY_3 }, - { 0x04, KEY_4 }, - { 0x05, KEY_5 }, - { 0x06, KEY_6 }, - { 0x07, KEY_7 }, - { 0x08, KEY_8 }, - { 0x09, KEY_9 }, - { 0x00, KEY_0 }, - { 0x17, KEY_LAST }, /* +100 */ - { 0x0a, KEY_LIST }, /* recall */ - - - { 0x1c, KEY_TUNER }, /* TV/FM */ - { 0x15, KEY_SEARCH }, /* scan */ - { 0x12, KEY_POWER }, /* power */ - { 0x1f, KEY_VOLUMEDOWN }, /* vol up */ - { 0x1b, KEY_VOLUMEUP }, /* vol down */ - { 0x1e, KEY_CHANNELDOWN }, /* chn up */ - { 0x1a, KEY_CHANNELUP }, /* chn down */ - - { 0x11, KEY_VIDEO }, /* video */ - { 0x0f, KEY_ZOOM }, /* full screen */ - { 0x13, KEY_MUTE }, /* mute/unmute */ - { 0x10, KEY_TEXT }, /* min */ - - { 0x0d, KEY_STOP }, /* freeze */ - { 0x0e, KEY_RECORD }, /* record */ - { 0x1d, KEY_PLAYPAUSE }, /* stop */ - { 0x19, KEY_PLAY }, /* play */ - - { 0x16, KEY_GOTO }, /* osd */ - { 0x14, KEY_REFRESH }, /* default */ - { 0x0c, KEY_KPPLUS }, /* fine tune >>>> */ - { 0x18, KEY_KPMINUS }, /* fine tune <<<< */ -}; - -struct ir_scancode_table ir_codes_apac_viewcomp_table = { - .scan = ir_codes_apac_viewcomp, - .size = ARRAY_SIZE(ir_codes_apac_viewcomp), -}; -EXPORT_SYMBOL_GPL(ir_codes_apac_viewcomp_table); - -/* ---------------------------------------------------------------------- */ - -static struct ir_scancode ir_codes_pixelview[] = { - - { 0x1e, KEY_POWER }, /* power */ - { 0x07, KEY_MEDIA }, /* source */ - { 0x1c, KEY_SEARCH }, /* scan */ - - - { 0x03, KEY_TUNER }, /* TV/FM */ - - { 0x00, KEY_RECORD }, - { 0x08, KEY_STOP }, - { 0x11, KEY_PLAY }, - - { 0x1a, KEY_PLAYPAUSE }, /* freeze */ - { 0x19, KEY_ZOOM }, /* zoom */ - { 0x0f, KEY_TEXT }, /* min */ - - { 0x01, KEY_1 }, - { 0x0b, KEY_2 }, - { 0x1b, KEY_3 }, - { 0x05, KEY_4 }, - { 0x09, KEY_5 }, - { 0x15, KEY_6 }, - { 0x06, KEY_7 }, - { 0x0a, KEY_8 }, - { 0x12, KEY_9 }, - { 0x02, KEY_0 }, - { 0x10, KEY_LAST }, /* +100 */ - { 0x13, KEY_LIST }, /* recall */ - - { 0x1f, KEY_CHANNELUP }, /* chn down */ - { 0x17, KEY_CHANNELDOWN }, /* chn up */ - { 0x16, KEY_VOLUMEUP }, /* vol down */ - { 0x14, KEY_VOLUMEDOWN }, /* vol up */ - - { 0x04, KEY_KPMINUS }, /* <<< */ - { 0x0e, KEY_SETUP }, /* function */ - { 0x0c, KEY_KPPLUS }, /* >>> */ - - { 0x0d, KEY_GOTO }, /* mts */ - { 0x1d, KEY_REFRESH }, /* reset */ - { 0x18, KEY_MUTE }, /* mute/unmute */ -}; - -struct ir_scancode_table ir_codes_pixelview_table = { - .scan = ir_codes_pixelview, - .size = ARRAY_SIZE(ir_codes_pixelview), -}; -EXPORT_SYMBOL_GPL(ir_codes_pixelview_table); - -/* - Mauro Carvalho Chehab - present on PV MPEG 8000GT - */ -static struct ir_scancode ir_codes_pixelview_new[] = { - { 0x3c, KEY_TIME }, /* Timeshift */ - { 0x12, KEY_POWER }, - - { 0x3d, KEY_1 }, - { 0x38, KEY_2 }, - { 0x18, KEY_3 }, - { 0x35, KEY_4 }, - { 0x39, KEY_5 }, - { 0x15, KEY_6 }, - { 0x36, KEY_7 }, - { 0x3a, KEY_8 }, - { 0x1e, KEY_9 }, - { 0x3e, KEY_0 }, - - { 0x1c, KEY_AGAIN }, /* LOOP */ - { 0x3f, KEY_MEDIA }, /* Source */ - { 0x1f, KEY_LAST }, /* +100 */ - { 0x1b, KEY_MUTE }, - - { 0x17, KEY_CHANNELDOWN }, - { 0x16, KEY_CHANNELUP }, - { 0x10, KEY_VOLUMEUP }, - { 0x14, KEY_VOLUMEDOWN }, - { 0x13, KEY_ZOOM }, - - { 0x19, KEY_CAMERA }, /* SNAPSHOT */ - { 0x1a, KEY_SEARCH }, /* scan */ - - { 0x37, KEY_REWIND }, /* << */ - { 0x32, KEY_RECORD }, /* o (red) */ - { 0x33, KEY_FORWARD }, /* >> */ - { 0x11, KEY_STOP }, /* square */ - { 0x3b, KEY_PLAY }, /* > */ - { 0x30, KEY_PLAYPAUSE }, /* || */ - - { 0x31, KEY_TV }, - { 0x34, KEY_RADIO }, -}; - -struct ir_scancode_table ir_codes_pixelview_new_table = { - .scan = ir_codes_pixelview_new, - .size = ARRAY_SIZE(ir_codes_pixelview_new), -}; -EXPORT_SYMBOL_GPL(ir_codes_pixelview_new_table); - -static struct ir_scancode ir_codes_nebula[] = { - { 0x00, KEY_0 }, - { 0x01, KEY_1 }, - { 0x02, KEY_2 }, - { 0x03, KEY_3 }, - { 0x04, KEY_4 }, - { 0x05, KEY_5 }, - { 0x06, KEY_6 }, - { 0x07, KEY_7 }, - { 0x08, KEY_8 }, - { 0x09, KEY_9 }, - { 0x0a, KEY_TV }, - { 0x0b, KEY_AUX }, - { 0x0c, KEY_DVD }, - { 0x0d, KEY_POWER }, - { 0x0e, KEY_MHP }, /* labelled 'Picture' */ - { 0x0f, KEY_AUDIO }, - { 0x10, KEY_INFO }, - { 0x11, KEY_F13 }, /* 16:9 */ - { 0x12, KEY_F14 }, /* 14:9 */ - { 0x13, KEY_EPG }, - { 0x14, KEY_EXIT }, - { 0x15, KEY_MENU }, - { 0x16, KEY_UP }, - { 0x17, KEY_DOWN }, - { 0x18, KEY_LEFT }, - { 0x19, KEY_RIGHT }, - { 0x1a, KEY_ENTER }, - { 0x1b, KEY_CHANNELUP }, - { 0x1c, KEY_CHANNELDOWN }, - { 0x1d, KEY_VOLUMEUP }, - { 0x1e, KEY_VOLUMEDOWN }, - { 0x1f, KEY_RED }, - { 0x20, KEY_GREEN }, - { 0x21, KEY_YELLOW }, - { 0x22, KEY_BLUE }, - { 0x23, KEY_SUBTITLE }, - { 0x24, KEY_F15 }, /* AD */ - { 0x25, KEY_TEXT }, - { 0x26, KEY_MUTE }, - { 0x27, KEY_REWIND }, - { 0x28, KEY_STOP }, - { 0x29, KEY_PLAY }, - { 0x2a, KEY_FASTFORWARD }, - { 0x2b, KEY_F16 }, /* chapter */ - { 0x2c, KEY_PAUSE }, - { 0x2d, KEY_PLAY }, - { 0x2e, KEY_RECORD }, - { 0x2f, KEY_F17 }, /* picture in picture */ - { 0x30, KEY_KPPLUS }, /* zoom in */ - { 0x31, KEY_KPMINUS }, /* zoom out */ - { 0x32, KEY_F18 }, /* capture */ - { 0x33, KEY_F19 }, /* web */ - { 0x34, KEY_EMAIL }, - { 0x35, KEY_PHONE }, - { 0x36, KEY_PC }, -}; - -struct ir_scancode_table ir_codes_nebula_table = { - .scan = ir_codes_nebula, - .size = ARRAY_SIZE(ir_codes_nebula), -}; -EXPORT_SYMBOL_GPL(ir_codes_nebula_table); - -/* DigitalNow DNTV Live DVB-T Remote */ -static struct ir_scancode ir_codes_dntv_live_dvb_t[] = { - { 0x00, KEY_ESC }, /* 'go up a level?' */ - /* Keys 0 to 9 */ - { 0x0a, KEY_0 }, - { 0x01, KEY_1 }, - { 0x02, KEY_2 }, - { 0x03, KEY_3 }, - { 0x04, KEY_4 }, - { 0x05, KEY_5 }, - { 0x06, KEY_6 }, - { 0x07, KEY_7 }, - { 0x08, KEY_8 }, - { 0x09, KEY_9 }, - - { 0x0b, KEY_TUNER }, /* tv/fm */ - { 0x0c, KEY_SEARCH }, /* scan */ - { 0x0d, KEY_STOP }, - { 0x0e, KEY_PAUSE }, - { 0x0f, KEY_LIST }, /* source */ - - { 0x10, KEY_MUTE }, - { 0x11, KEY_REWIND }, /* backward << */ - { 0x12, KEY_POWER }, - { 0x13, KEY_CAMERA }, /* snap */ - { 0x14, KEY_AUDIO }, /* stereo */ - { 0x15, KEY_CLEAR }, /* reset */ - { 0x16, KEY_PLAY }, - { 0x17, KEY_ENTER }, - { 0x18, KEY_ZOOM }, /* full screen */ - { 0x19, KEY_FASTFORWARD }, /* forward >> */ - { 0x1a, KEY_CHANNELUP }, - { 0x1b, KEY_VOLUMEUP }, - { 0x1c, KEY_INFO }, /* preview */ - { 0x1d, KEY_RECORD }, /* record */ - { 0x1e, KEY_CHANNELDOWN }, - { 0x1f, KEY_VOLUMEDOWN }, -}; - -struct ir_scancode_table ir_codes_dntv_live_dvb_t_table = { - .scan = ir_codes_dntv_live_dvb_t, - .size = ARRAY_SIZE(ir_codes_dntv_live_dvb_t), -}; -EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvb_t_table); - -/* ---------------------------------------------------------------------- */ - -/* IO-DATA BCTV7E Remote */ -static struct ir_scancode ir_codes_iodata_bctv7e[] = { - { 0x40, KEY_TV }, - { 0x20, KEY_RADIO }, /* FM */ - { 0x60, KEY_EPG }, - { 0x00, KEY_POWER }, - - /* Keys 0 to 9 */ - { 0x44, KEY_0 }, /* 10 */ - { 0x50, KEY_1 }, - { 0x30, KEY_2 }, - { 0x70, KEY_3 }, - { 0x48, KEY_4 }, - { 0x28, KEY_5 }, - { 0x68, KEY_6 }, - { 0x58, KEY_7 }, - { 0x38, KEY_8 }, - { 0x78, KEY_9 }, - - { 0x10, KEY_L }, /* Live */ - { 0x08, KEY_TIME }, /* Time Shift */ - - { 0x18, KEY_PLAYPAUSE }, /* Play */ - - { 0x24, KEY_ENTER }, /* 11 */ - { 0x64, KEY_ESC }, /* 12 */ - { 0x04, KEY_M }, /* Multi */ - - { 0x54, KEY_VIDEO }, - { 0x34, KEY_CHANNELUP }, - { 0x74, KEY_VOLUMEUP }, - { 0x14, KEY_MUTE }, - - { 0x4c, KEY_VCR }, /* SVIDEO */ - { 0x2c, KEY_CHANNELDOWN }, - { 0x6c, KEY_VOLUMEDOWN }, - { 0x0c, KEY_ZOOM }, - - { 0x5c, KEY_PAUSE }, - { 0x3c, KEY_RED }, /* || (red) */ - { 0x7c, KEY_RECORD }, /* recording */ - { 0x1c, KEY_STOP }, - - { 0x41, KEY_REWIND }, /* backward << */ - { 0x21, KEY_PLAY }, - { 0x61, KEY_FASTFORWARD }, /* forward >> */ - { 0x01, KEY_NEXT }, /* skip >| */ -}; - -struct ir_scancode_table ir_codes_iodata_bctv7e_table = { - .scan = ir_codes_iodata_bctv7e, - .size = ARRAY_SIZE(ir_codes_iodata_bctv7e), -}; -EXPORT_SYMBOL_GPL(ir_codes_iodata_bctv7e_table); - -/* ---------------------------------------------------------------------- */ - -/* ADS Tech Instant TV DVB-T PCI Remote */ -static struct ir_scancode ir_codes_adstech_dvb_t_pci[] = { - /* Keys 0 to 9 */ - { 0x4d, KEY_0 }, - { 0x57, KEY_1 }, - { 0x4f, KEY_2 }, - { 0x53, KEY_3 }, - { 0x56, KEY_4 }, - { 0x4e, KEY_5 }, - { 0x5e, KEY_6 }, - { 0x54, KEY_7 }, - { 0x4c, KEY_8 }, - { 0x5c, KEY_9 }, - - { 0x5b, KEY_POWER }, - { 0x5f, KEY_MUTE }, - { 0x55, KEY_GOTO }, - { 0x5d, KEY_SEARCH }, - { 0x17, KEY_EPG }, /* Guide */ - { 0x1f, KEY_MENU }, - { 0x0f, KEY_UP }, - { 0x46, KEY_DOWN }, - { 0x16, KEY_LEFT }, - { 0x1e, KEY_RIGHT }, - { 0x0e, KEY_SELECT }, /* Enter */ - { 0x5a, KEY_INFO }, - { 0x52, KEY_EXIT }, - { 0x59, KEY_PREVIOUS }, - { 0x51, KEY_NEXT }, - { 0x58, KEY_REWIND }, - { 0x50, KEY_FORWARD }, - { 0x44, KEY_PLAYPAUSE }, - { 0x07, KEY_STOP }, - { 0x1b, KEY_RECORD }, - { 0x13, KEY_TUNER }, /* Live */ - { 0x0a, KEY_A }, - { 0x12, KEY_B }, - { 0x03, KEY_PROG1 }, /* 1 */ - { 0x01, KEY_PROG2 }, /* 2 */ - { 0x00, KEY_PROG3 }, /* 3 */ - { 0x06, KEY_DVD }, - { 0x48, KEY_AUX }, /* Photo */ - { 0x40, KEY_VIDEO }, - { 0x19, KEY_AUDIO }, /* Music */ - { 0x0b, KEY_CHANNELUP }, - { 0x08, KEY_CHANNELDOWN }, - { 0x15, KEY_VOLUMEUP }, - { 0x1c, KEY_VOLUMEDOWN }, -}; - -struct ir_scancode_table ir_codes_adstech_dvb_t_pci_table = { - .scan = ir_codes_adstech_dvb_t_pci, - .size = ARRAY_SIZE(ir_codes_adstech_dvb_t_pci), -}; -EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t_pci_table); - -/* ---------------------------------------------------------------------- */ - -/* MSI TV@nywhere MASTER remote */ - -static struct ir_scancode ir_codes_msi_tvanywhere[] = { - /* Keys 0 to 9 */ - { 0x00, KEY_0 }, - { 0x01, KEY_1 }, - { 0x02, KEY_2 }, - { 0x03, KEY_3 }, - { 0x04, KEY_4 }, - { 0x05, KEY_5 }, - { 0x06, KEY_6 }, - { 0x07, KEY_7 }, - { 0x08, KEY_8 }, - { 0x09, KEY_9 }, - - { 0x0c, KEY_MUTE }, - { 0x0f, KEY_SCREEN }, /* Full Screen */ - { 0x10, KEY_FN }, /* Funtion */ - { 0x11, KEY_TIME }, /* Time shift */ - { 0x12, KEY_POWER }, - { 0x13, KEY_MEDIA }, /* MTS */ - { 0x14, KEY_SLOW }, - { 0x16, KEY_REWIND }, /* backward << */ - { 0x17, KEY_ENTER }, /* Return */ - { 0x18, KEY_FASTFORWARD }, /* forward >> */ - { 0x1a, KEY_CHANNELUP }, - { 0x1b, KEY_VOLUMEUP }, - { 0x1e, KEY_CHANNELDOWN }, - { 0x1f, KEY_VOLUMEDOWN }, -}; - -struct ir_scancode_table ir_codes_msi_tvanywhere_table = { - .scan = ir_codes_msi_tvanywhere, - .size = ARRAY_SIZE(ir_codes_msi_tvanywhere), -}; -EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_table); - -/* ---------------------------------------------------------------------- */ - -/* - Keycodes for remote on the MSI TV@nywhere Plus. The controller IC on the card - is marked "KS003". The controller is I2C at address 0x30, but does not seem - to respond to probes until a read is performed from a valid device. - I don't know why... - - Note: This remote may be of similar or identical design to the - Pixelview remote (?). The raw codes and duplicate button codes - appear to be the same. - - Henry Wong - Some changes to formatting and keycodes by Mark Schultz - -*/ - -static struct ir_scancode ir_codes_msi_tvanywhere_plus[] = { - -/* ---- Remote Button Layout ---- - - POWER SOURCE SCAN MUTE - TV/FM 1 2 3 - |> 4 5 6 - <| 7 8 9 - ^^UP 0 + RECALL - vvDN RECORD STOP PLAY - - MINIMIZE ZOOM - - CH+ - VOL- VOL+ - CH- - - SNAPSHOT MTS - - << FUNC >> RESET -*/ - - { 0x01, KEY_1 }, /* 1 */ - { 0x0b, KEY_2 }, /* 2 */ - { 0x1b, KEY_3 }, /* 3 */ - { 0x05, KEY_4 }, /* 4 */ - { 0x09, KEY_5 }, /* 5 */ - { 0x15, KEY_6 }, /* 6 */ - { 0x06, KEY_7 }, /* 7 */ - { 0x0a, KEY_8 }, /* 8 */ - { 0x12, KEY_9 }, /* 9 */ - { 0x02, KEY_0 }, /* 0 */ - { 0x10, KEY_KPPLUS }, /* + */ - { 0x13, KEY_AGAIN }, /* Recall */ - - { 0x1e, KEY_POWER }, /* Power */ - { 0x07, KEY_TUNER }, /* Source */ - { 0x1c, KEY_SEARCH }, /* Scan */ - { 0x18, KEY_MUTE }, /* Mute */ - - { 0x03, KEY_RADIO }, /* TV/FM */ - /* The next four keys are duplicates that appear to send the - same IR code as Ch+, Ch-, >>, and << . The raw code assigned - to them is the actual code + 0x20 - they will never be - detected as such unless some way is discovered to distinguish - these buttons from those that have the same code. */ - { 0x3f, KEY_RIGHT }, /* |> and Ch+ */ - { 0x37, KEY_LEFT }, /* <| and Ch- */ - { 0x2c, KEY_UP }, /* ^^Up and >> */ - { 0x24, KEY_DOWN }, /* vvDn and << */ - - { 0x00, KEY_RECORD }, /* Record */ - { 0x08, KEY_STOP }, /* Stop */ - { 0x11, KEY_PLAY }, /* Play */ - - { 0x0f, KEY_CLOSE }, /* Minimize */ - { 0x19, KEY_ZOOM }, /* Zoom */ - { 0x1a, KEY_CAMERA }, /* Snapshot */ - { 0x0d, KEY_LANGUAGE }, /* MTS */ - - { 0x14, KEY_VOLUMEDOWN }, /* Vol- */ - { 0x16, KEY_VOLUMEUP }, /* Vol+ */ - { 0x17, KEY_CHANNELDOWN }, /* Ch- */ - { 0x1f, KEY_CHANNELUP }, /* Ch+ */ - - { 0x04, KEY_REWIND }, /* << */ - { 0x0e, KEY_MENU }, /* Function */ - { 0x0c, KEY_FASTFORWARD }, /* >> */ - { 0x1d, KEY_RESTART }, /* Reset */ -}; - -struct ir_scancode_table ir_codes_msi_tvanywhere_plus_table = { - .scan = ir_codes_msi_tvanywhere_plus, - .size = ARRAY_SIZE(ir_codes_msi_tvanywhere_plus), -}; -EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_plus_table); - -/* ---------------------------------------------------------------------- */ - -/* Cinergy 1400 DVB-T */ -static struct ir_scancode ir_codes_cinergy_1400[] = { - { 0x01, KEY_POWER }, - { 0x02, KEY_1 }, - { 0x03, KEY_2 }, - { 0x04, KEY_3 }, - { 0x05, KEY_4 }, - { 0x06, KEY_5 }, - { 0x07, KEY_6 }, - { 0x08, KEY_7 }, - { 0x09, KEY_8 }, - { 0x0a, KEY_9 }, - { 0x0c, KEY_0 }, - - { 0x0b, KEY_VIDEO }, - { 0x0d, KEY_REFRESH }, - { 0x0e, KEY_SELECT }, - { 0x0f, KEY_EPG }, - { 0x10, KEY_UP }, - { 0x11, KEY_LEFT }, - { 0x12, KEY_OK }, - { 0x13, KEY_RIGHT }, - { 0x14, KEY_DOWN }, - { 0x15, KEY_TEXT }, - { 0x16, KEY_INFO }, - - { 0x17, KEY_RED }, - { 0x18, KEY_GREEN }, - { 0x19, KEY_YELLOW }, - { 0x1a, KEY_BLUE }, - - { 0x1b, KEY_CHANNELUP }, - { 0x1c, KEY_VOLUMEUP }, - { 0x1d, KEY_MUTE }, - { 0x1e, KEY_VOLUMEDOWN }, - { 0x1f, KEY_CHANNELDOWN }, - - { 0x40, KEY_PAUSE }, - { 0x4c, KEY_PLAY }, - { 0x58, KEY_RECORD }, - { 0x54, KEY_PREVIOUS }, - { 0x48, KEY_STOP }, - { 0x5c, KEY_NEXT }, -}; - -struct ir_scancode_table ir_codes_cinergy_1400_table = { - .scan = ir_codes_cinergy_1400, - .size = ARRAY_SIZE(ir_codes_cinergy_1400), -}; -EXPORT_SYMBOL_GPL(ir_codes_cinergy_1400_table); - -/* ---------------------------------------------------------------------- */ - -/* AVERTV STUDIO 303 Remote */ -static struct ir_scancode ir_codes_avertv_303[] = { - { 0x2a, KEY_1 }, - { 0x32, KEY_2 }, - { 0x3a, KEY_3 }, - { 0x4a, KEY_4 }, - { 0x52, KEY_5 }, - { 0x5a, KEY_6 }, - { 0x6a, KEY_7 }, - { 0x72, KEY_8 }, - { 0x7a, KEY_9 }, - { 0x0e, KEY_0 }, - - { 0x02, KEY_POWER }, - { 0x22, KEY_VIDEO }, - { 0x42, KEY_AUDIO }, - { 0x62, KEY_ZOOM }, - { 0x0a, KEY_TV }, - { 0x12, KEY_CD }, - { 0x1a, KEY_TEXT }, - - { 0x16, KEY_SUBTITLE }, - { 0x1e, KEY_REWIND }, - { 0x06, KEY_PRINT }, - - { 0x2e, KEY_SEARCH }, - { 0x36, KEY_SLEEP }, - { 0x3e, KEY_SHUFFLE }, - { 0x26, KEY_MUTE }, - - { 0x4e, KEY_RECORD }, - { 0x56, KEY_PAUSE }, - { 0x5e, KEY_STOP }, - { 0x46, KEY_PLAY }, - - { 0x6e, KEY_RED }, - { 0x0b, KEY_GREEN }, - { 0x66, KEY_YELLOW }, - { 0x03, KEY_BLUE }, - - { 0x76, KEY_LEFT }, - { 0x7e, KEY_RIGHT }, - { 0x13, KEY_DOWN }, - { 0x1b, KEY_UP }, -}; - -struct ir_scancode_table ir_codes_avertv_303_table = { - .scan = ir_codes_avertv_303, - .size = ARRAY_SIZE(ir_codes_avertv_303), -}; -EXPORT_SYMBOL_GPL(ir_codes_avertv_303_table); - -/* ---------------------------------------------------------------------- */ - -/* DigitalNow DNTV Live! DVB-T Pro Remote */ -static struct ir_scancode ir_codes_dntv_live_dvbt_pro[] = { - { 0x16, KEY_POWER }, - { 0x5b, KEY_HOME }, - - { 0x55, KEY_TV }, /* live tv */ - { 0x58, KEY_TUNER }, /* digital Radio */ - { 0x5a, KEY_RADIO }, /* FM radio */ - { 0x59, KEY_DVD }, /* dvd menu */ - { 0x03, KEY_1 }, - { 0x01, KEY_2 }, - { 0x06, KEY_3 }, - { 0x09, KEY_4 }, - { 0x1d, KEY_5 }, - { 0x1f, KEY_6 }, - { 0x0d, KEY_7 }, - { 0x19, KEY_8 }, - { 0x1b, KEY_9 }, - { 0x0c, KEY_CANCEL }, - { 0x15, KEY_0 }, - { 0x4a, KEY_CLEAR }, - { 0x13, KEY_BACK }, - { 0x00, KEY_TAB }, - { 0x4b, KEY_UP }, - { 0x4e, KEY_LEFT }, - { 0x4f, KEY_OK }, - { 0x52, KEY_RIGHT }, - { 0x51, KEY_DOWN }, - { 0x1e, KEY_VOLUMEUP }, - { 0x0a, KEY_VOLUMEDOWN }, - { 0x02, KEY_CHANNELDOWN }, - { 0x05, KEY_CHANNELUP }, - { 0x11, KEY_RECORD }, - { 0x14, KEY_PLAY }, - { 0x4c, KEY_PAUSE }, - { 0x1a, KEY_STOP }, - { 0x40, KEY_REWIND }, - { 0x12, KEY_FASTFORWARD }, - { 0x41, KEY_PREVIOUSSONG }, /* replay |< */ - { 0x42, KEY_NEXTSONG }, /* skip >| */ - { 0x54, KEY_CAMERA }, /* capture */ - { 0x50, KEY_LANGUAGE }, /* sap */ - { 0x47, KEY_TV2 }, /* pip */ - { 0x4d, KEY_SCREEN }, - { 0x43, KEY_SUBTITLE }, - { 0x10, KEY_MUTE }, - { 0x49, KEY_AUDIO }, /* l/r */ - { 0x07, KEY_SLEEP }, - { 0x08, KEY_VIDEO }, /* a/v */ - { 0x0e, KEY_PREVIOUS }, /* recall */ - { 0x45, KEY_ZOOM }, /* zoom + */ - { 0x46, KEY_ANGLE }, /* zoom - */ - { 0x56, KEY_RED }, - { 0x57, KEY_GREEN }, - { 0x5c, KEY_YELLOW }, - { 0x5d, KEY_BLUE }, -}; - -struct ir_scancode_table ir_codes_dntv_live_dvbt_pro_table = { - .scan = ir_codes_dntv_live_dvbt_pro, - .size = ARRAY_SIZE(ir_codes_dntv_live_dvbt_pro), -}; -EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvbt_pro_table); - -static struct ir_scancode ir_codes_em_terratec[] = { - { 0x01, KEY_CHANNEL }, - { 0x02, KEY_SELECT }, - { 0x03, KEY_MUTE }, - { 0x04, KEY_POWER }, - { 0x05, KEY_1 }, - { 0x06, KEY_2 }, - { 0x07, KEY_3 }, - { 0x08, KEY_CHANNELUP }, - { 0x09, KEY_4 }, - { 0x0a, KEY_5 }, - { 0x0b, KEY_6 }, - { 0x0c, KEY_CHANNELDOWN }, - { 0x0d, KEY_7 }, - { 0x0e, KEY_8 }, - { 0x0f, KEY_9 }, - { 0x10, KEY_VOLUMEUP }, - { 0x11, KEY_0 }, - { 0x12, KEY_MENU }, - { 0x13, KEY_PRINT }, - { 0x14, KEY_VOLUMEDOWN }, - { 0x16, KEY_PAUSE }, - { 0x18, KEY_RECORD }, - { 0x19, KEY_REWIND }, - { 0x1a, KEY_PLAY }, - { 0x1b, KEY_FORWARD }, - { 0x1c, KEY_BACKSPACE }, - { 0x1e, KEY_STOP }, - { 0x40, KEY_ZOOM }, -}; - -struct ir_scancode_table ir_codes_em_terratec_table = { - .scan = ir_codes_em_terratec, - .size = ARRAY_SIZE(ir_codes_em_terratec), -}; -EXPORT_SYMBOL_GPL(ir_codes_em_terratec_table); - -static struct ir_scancode ir_codes_pinnacle_grey[] = { - { 0x3a, KEY_0 }, - { 0x31, KEY_1 }, - { 0x32, KEY_2 }, - { 0x33, KEY_3 }, - { 0x34, KEY_4 }, - { 0x35, KEY_5 }, - { 0x36, KEY_6 }, - { 0x37, KEY_7 }, - { 0x38, KEY_8 }, - { 0x39, KEY_9 }, - - { 0x2f, KEY_POWER }, - - { 0x2e, KEY_P }, - { 0x1f, KEY_L }, - { 0x2b, KEY_I }, - - { 0x2d, KEY_SCREEN }, - { 0x1e, KEY_ZOOM }, - { 0x1b, KEY_VOLUMEUP }, - { 0x0f, KEY_VOLUMEDOWN }, - { 0x17, KEY_CHANNELUP }, - { 0x1c, KEY_CHANNELDOWN }, - { 0x25, KEY_INFO }, - - { 0x3c, KEY_MUTE }, - - { 0x3d, KEY_LEFT }, - { 0x3b, KEY_RIGHT }, - - { 0x3f, KEY_UP }, - { 0x3e, KEY_DOWN }, - { 0x1a, KEY_ENTER }, - - { 0x1d, KEY_MENU }, - { 0x19, KEY_AGAIN }, - { 0x16, KEY_PREVIOUSSONG }, - { 0x13, KEY_NEXTSONG }, - { 0x15, KEY_PAUSE }, - { 0x0e, KEY_REWIND }, - { 0x0d, KEY_PLAY }, - { 0x0b, KEY_STOP }, - { 0x07, KEY_FORWARD }, - { 0x27, KEY_RECORD }, - { 0x26, KEY_TUNER }, - { 0x29, KEY_TEXT }, - { 0x2a, KEY_MEDIA }, - { 0x18, KEY_EPG }, -}; - -struct ir_scancode_table ir_codes_pinnacle_grey_table = { - .scan = ir_codes_pinnacle_grey, - .size = ARRAY_SIZE(ir_codes_pinnacle_grey), -}; -EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey_table); - -static struct ir_scancode ir_codes_flyvideo[] = { - { 0x0f, KEY_0 }, - { 0x03, KEY_1 }, - { 0x04, KEY_2 }, - { 0x05, KEY_3 }, - { 0x07, KEY_4 }, - { 0x08, KEY_5 }, - { 0x09, KEY_6 }, - { 0x0b, KEY_7 }, - { 0x0c, KEY_8 }, - { 0x0d, KEY_9 }, - - { 0x0e, KEY_MODE }, /* Air/Cable */ - { 0x11, KEY_VIDEO }, /* Video */ - { 0x15, KEY_AUDIO }, /* Audio */ - { 0x00, KEY_POWER }, /* Power */ - { 0x18, KEY_TUNER }, /* AV Source */ - { 0x02, KEY_ZOOM }, /* Fullscreen */ - { 0x1a, KEY_LANGUAGE }, /* Stereo */ - { 0x1b, KEY_MUTE }, /* Mute */ - { 0x14, KEY_VOLUMEUP }, /* Volume + */ - { 0x17, KEY_VOLUMEDOWN },/* Volume - */ - { 0x12, KEY_CHANNELUP },/* Channel + */ - { 0x13, KEY_CHANNELDOWN },/* Channel - */ - { 0x06, KEY_AGAIN }, /* Recall */ - { 0x10, KEY_ENTER }, /* Enter */ - - { 0x19, KEY_BACK }, /* Rewind ( <<< ) */ - { 0x1f, KEY_FORWARD }, /* Forward ( >>> ) */ - { 0x0a, KEY_ANGLE }, /* no label, may be used as the PAUSE button */ -}; - -struct ir_scancode_table ir_codes_flyvideo_table = { - .scan = ir_codes_flyvideo, - .size = ARRAY_SIZE(ir_codes_flyvideo), -}; -EXPORT_SYMBOL_GPL(ir_codes_flyvideo_table); - -static struct ir_scancode ir_codes_flydvb[] = { - { 0x01, KEY_ZOOM }, /* Full Screen */ - { 0x00, KEY_POWER }, /* Power */ - - { 0x03, KEY_1 }, - { 0x04, KEY_2 }, - { 0x05, KEY_3 }, - { 0x07, KEY_4 }, - { 0x08, KEY_5 }, - { 0x09, KEY_6 }, - { 0x0b, KEY_7 }, - { 0x0c, KEY_8 }, - { 0x0d, KEY_9 }, - { 0x06, KEY_AGAIN }, /* Recall */ - { 0x0f, KEY_0 }, - { 0x10, KEY_MUTE }, /* Mute */ - { 0x02, KEY_RADIO }, /* TV/Radio */ - { 0x1b, KEY_LANGUAGE }, /* SAP (Second Audio Program) */ - - { 0x14, KEY_VOLUMEUP }, /* VOL+ */ - { 0x17, KEY_VOLUMEDOWN }, /* VOL- */ - { 0x12, KEY_CHANNELUP }, /* CH+ */ - { 0x13, KEY_CHANNELDOWN }, /* CH- */ - { 0x1d, KEY_ENTER }, /* Enter */ - - { 0x1a, KEY_MODE }, /* PIP */ - { 0x18, KEY_TUNER }, /* Source */ - - { 0x1e, KEY_RECORD }, /* Record/Pause */ - { 0x15, KEY_ANGLE }, /* Swap (no label on key) */ - { 0x1c, KEY_PAUSE }, /* Timeshift/Pause */ - { 0x19, KEY_BACK }, /* Rewind << */ - { 0x0a, KEY_PLAYPAUSE }, /* Play/Pause */ - { 0x1f, KEY_FORWARD }, /* Forward >> */ - { 0x16, KEY_PREVIOUS }, /* Back |<< */ - { 0x11, KEY_STOP }, /* Stop */ - { 0x0e, KEY_NEXT }, /* End >>| */ -}; - -struct ir_scancode_table ir_codes_flydvb_table = { - .scan = ir_codes_flydvb, - .size = ARRAY_SIZE(ir_codes_flydvb), -}; -EXPORT_SYMBOL_GPL(ir_codes_flydvb_table); - -static struct ir_scancode ir_codes_cinergy[] = { - { 0x00, KEY_0 }, - { 0x01, KEY_1 }, - { 0x02, KEY_2 }, - { 0x03, KEY_3 }, - { 0x04, KEY_4 }, - { 0x05, KEY_5 }, - { 0x06, KEY_6 }, - { 0x07, KEY_7 }, - { 0x08, KEY_8 }, - { 0x09, KEY_9 }, - - { 0x0a, KEY_POWER }, - { 0x0b, KEY_PROG1 }, /* app */ - { 0x0c, KEY_ZOOM }, /* zoom/fullscreen */ - { 0x0d, KEY_CHANNELUP }, /* channel */ - { 0x0e, KEY_CHANNELDOWN }, /* channel- */ - { 0x0f, KEY_VOLUMEUP }, - { 0x10, KEY_VOLUMEDOWN }, - { 0x11, KEY_TUNER }, /* AV */ - { 0x12, KEY_NUMLOCK }, /* -/-- */ - { 0x13, KEY_AUDIO }, /* audio */ - { 0x14, KEY_MUTE }, - { 0x15, KEY_UP }, - { 0x16, KEY_DOWN }, - { 0x17, KEY_LEFT }, - { 0x18, KEY_RIGHT }, - { 0x19, BTN_LEFT, }, - { 0x1a, BTN_RIGHT, }, - { 0x1b, KEY_WWW }, /* text */ - { 0x1c, KEY_REWIND }, - { 0x1d, KEY_FORWARD }, - { 0x1e, KEY_RECORD }, - { 0x1f, KEY_PLAY }, - { 0x20, KEY_PREVIOUSSONG }, - { 0x21, KEY_NEXTSONG }, - { 0x22, KEY_PAUSE }, - { 0x23, KEY_STOP }, -}; - -struct ir_scancode_table ir_codes_cinergy_table = { - .scan = ir_codes_cinergy, - .size = ARRAY_SIZE(ir_codes_cinergy), -}; -EXPORT_SYMBOL_GPL(ir_codes_cinergy_table); - -/* Alfons Geser - * updates from Job D. R. Borges */ -static struct ir_scancode ir_codes_eztv[] = { - { 0x12, KEY_POWER }, - { 0x01, KEY_TV }, /* DVR */ - { 0x15, KEY_DVD }, /* DVD */ - { 0x17, KEY_AUDIO }, /* music */ - /* DVR mode / DVD mode / music mode */ - - { 0x1b, KEY_MUTE }, /* mute */ - { 0x02, KEY_LANGUAGE }, /* MTS/SAP / audio / autoseek */ - { 0x1e, KEY_SUBTITLE }, /* closed captioning / subtitle / seek */ - { 0x16, KEY_ZOOM }, /* full screen */ - { 0x1c, KEY_VIDEO }, /* video source / eject / delall */ - { 0x1d, KEY_RESTART }, /* playback / angle / del */ - { 0x2f, KEY_SEARCH }, /* scan / menu / playlist */ - { 0x30, KEY_CHANNEL }, /* CH surfing / bookmark / memo */ - - { 0x31, KEY_HELP }, /* help */ - { 0x32, KEY_MODE }, /* num/memo */ - { 0x33, KEY_ESC }, /* cancel */ - - { 0x0c, KEY_UP }, /* up */ - { 0x10, KEY_DOWN }, /* down */ - { 0x08, KEY_LEFT }, /* left */ - { 0x04, KEY_RIGHT }, /* right */ - { 0x03, KEY_SELECT }, /* select */ - - { 0x1f, KEY_REWIND }, /* rewind */ - { 0x20, KEY_PLAYPAUSE },/* play/pause */ - { 0x29, KEY_FORWARD }, /* forward */ - { 0x14, KEY_AGAIN }, /* repeat */ - { 0x2b, KEY_RECORD }, /* recording */ - { 0x2c, KEY_STOP }, /* stop */ - { 0x2d, KEY_PLAY }, /* play */ - { 0x2e, KEY_CAMERA }, /* snapshot / shuffle */ - - { 0x00, KEY_0 }, - { 0x05, KEY_1 }, - { 0x06, KEY_2 }, - { 0x07, KEY_3 }, - { 0x09, KEY_4 }, - { 0x0a, KEY_5 }, - { 0x0b, KEY_6 }, - { 0x0d, KEY_7 }, - { 0x0e, KEY_8 }, - { 0x0f, KEY_9 }, - - { 0x2a, KEY_VOLUMEUP }, - { 0x11, KEY_VOLUMEDOWN }, - { 0x18, KEY_CHANNELUP },/* CH.tracking up */ - { 0x19, KEY_CHANNELDOWN },/* CH.tracking down */ - - { 0x13, KEY_ENTER }, /* enter */ - { 0x21, KEY_DOT }, /* . (decimal dot) */ -}; - -struct ir_scancode_table ir_codes_eztv_table = { - .scan = ir_codes_eztv, - .size = ARRAY_SIZE(ir_codes_eztv), -}; -EXPORT_SYMBOL_GPL(ir_codes_eztv_table); - -/* Alex Hermann */ -static struct ir_scancode ir_codes_avermedia[] = { - { 0x28, KEY_1 }, - { 0x18, KEY_2 }, - { 0x38, KEY_3 }, - { 0x24, KEY_4 }, - { 0x14, KEY_5 }, - { 0x34, KEY_6 }, - { 0x2c, KEY_7 }, - { 0x1c, KEY_8 }, - { 0x3c, KEY_9 }, - { 0x22, KEY_0 }, - - { 0x20, KEY_TV }, /* TV/FM */ - { 0x10, KEY_CD }, /* CD */ - { 0x30, KEY_TEXT }, /* TELETEXT */ - { 0x00, KEY_POWER }, /* POWER */ - - { 0x08, KEY_VIDEO }, /* VIDEO */ - { 0x04, KEY_AUDIO }, /* AUDIO */ - { 0x0c, KEY_ZOOM }, /* FULL SCREEN */ - - { 0x12, KEY_SUBTITLE }, /* DISPLAY */ - { 0x32, KEY_REWIND }, /* LOOP */ - { 0x02, KEY_PRINT }, /* PREVIEW */ - - { 0x2a, KEY_SEARCH }, /* AUTOSCAN */ - { 0x1a, KEY_SLEEP }, /* FREEZE */ - { 0x3a, KEY_CAMERA }, /* SNAPSHOT */ - { 0x0a, KEY_MUTE }, /* MUTE */ - - { 0x26, KEY_RECORD }, /* RECORD */ - { 0x16, KEY_PAUSE }, /* PAUSE */ - { 0x36, KEY_STOP }, /* STOP */ - { 0x06, KEY_PLAY }, /* PLAY */ - - { 0x2e, KEY_RED }, /* RED */ - { 0x21, KEY_GREEN }, /* GREEN */ - { 0x0e, KEY_YELLOW }, /* YELLOW */ - { 0x01, KEY_BLUE }, /* BLUE */ - - { 0x1e, KEY_VOLUMEDOWN }, /* VOLUME- */ - { 0x3e, KEY_VOLUMEUP }, /* VOLUME+ */ - { 0x11, KEY_CHANNELDOWN }, /* CHANNEL/PAGE- */ - { 0x31, KEY_CHANNELUP } /* CHANNEL/PAGE+ */ -}; - -struct ir_scancode_table ir_codes_avermedia_table = { - .scan = ir_codes_avermedia, - .size = ARRAY_SIZE(ir_codes_avermedia), -}; -EXPORT_SYMBOL_GPL(ir_codes_avermedia_table); - -static struct ir_scancode ir_codes_videomate_tv_pvr[] = { - { 0x14, KEY_MUTE }, - { 0x24, KEY_ZOOM }, - - { 0x01, KEY_DVD }, - { 0x23, KEY_RADIO }, - { 0x00, KEY_TV }, - - { 0x0a, KEY_REWIND }, - { 0x08, KEY_PLAYPAUSE }, - { 0x0f, KEY_FORWARD }, - - { 0x02, KEY_PREVIOUS }, - { 0x07, KEY_STOP }, - { 0x06, KEY_NEXT }, - - { 0x0c, KEY_UP }, - { 0x0e, KEY_DOWN }, - { 0x0b, KEY_LEFT }, - { 0x0d, KEY_RIGHT }, - { 0x11, KEY_OK }, - - { 0x03, KEY_MENU }, - { 0x09, KEY_SETUP }, - { 0x05, KEY_VIDEO }, - { 0x22, KEY_CHANNEL }, - - { 0x12, KEY_VOLUMEUP }, - { 0x15, KEY_VOLUMEDOWN }, - { 0x10, KEY_CHANNELUP }, - { 0x13, KEY_CHANNELDOWN }, - - { 0x04, KEY_RECORD }, - - { 0x16, KEY_1 }, - { 0x17, KEY_2 }, - { 0x18, KEY_3 }, - { 0x19, KEY_4 }, - { 0x1a, KEY_5 }, - { 0x1b, KEY_6 }, - { 0x1c, KEY_7 }, - { 0x1d, KEY_8 }, - { 0x1e, KEY_9 }, - { 0x1f, KEY_0 }, - - { 0x20, KEY_LANGUAGE }, - { 0x21, KEY_SLEEP }, -}; - -struct ir_scancode_table ir_codes_videomate_tv_pvr_table = { - .scan = ir_codes_videomate_tv_pvr, - .size = ARRAY_SIZE(ir_codes_videomate_tv_pvr), -}; -EXPORT_SYMBOL_GPL(ir_codes_videomate_tv_pvr_table); - -/* Michael Tokarev - http://www.corpit.ru/mjt/beholdTV/remote_control.jpg - keytable is used by MANLI MTV00[0x0c] and BeholdTV 40[13] at - least, and probably other cards too. - The "ascii-art picture" below (in comments, first row - is the keycode in hex, and subsequent row(s) shows - the button labels (several variants when appropriate) - helps to descide which keycodes to assign to the buttons. - */ -static struct ir_scancode ir_codes_manli[] = { - - /* 0x1c 0x12 * - * FUNCTION POWER * - * FM (|) * - * */ - { 0x1c, KEY_RADIO }, /*XXX*/ - { 0x12, KEY_POWER }, - - /* 0x01 0x02 0x03 * - * 1 2 3 * - * * - * 0x04 0x05 0x06 * - * 4 5 6 * - * * - * 0x07 0x08 0x09 * - * 7 8 9 * - * */ - { 0x01, KEY_1 }, - { 0x02, KEY_2 }, - { 0x03, KEY_3 }, - { 0x04, KEY_4 }, - { 0x05, KEY_5 }, - { 0x06, KEY_6 }, - { 0x07, KEY_7 }, - { 0x08, KEY_8 }, - { 0x09, KEY_9 }, - - /* 0x0a 0x00 0x17 * - * RECALL 0 +100 * - * PLUS * - * */ - { 0x0a, KEY_AGAIN }, /*XXX KEY_REWIND? */ - { 0x00, KEY_0 }, - { 0x17, KEY_DIGITS }, /*XXX*/ - - /* 0x14 0x10 * - * MENU INFO * - * OSD */ - { 0x14, KEY_MENU }, - { 0x10, KEY_INFO }, - - /* 0x0b * - * Up * - * * - * 0x18 0x16 0x0c * - * Left Ok Right * - * * - * 0x015 * - * Down * - * */ - { 0x0b, KEY_UP }, - { 0x18, KEY_LEFT }, - { 0x16, KEY_OK }, /*XXX KEY_SELECT? KEY_ENTER? */ - { 0x0c, KEY_RIGHT }, - { 0x15, KEY_DOWN }, - - /* 0x11 0x0d * - * TV/AV MODE * - * SOURCE STEREO * - * */ - { 0x11, KEY_TV }, /*XXX*/ - { 0x0d, KEY_MODE }, /*XXX there's no KEY_STEREO */ - - /* 0x0f 0x1b 0x1a * - * AUDIO Vol+ Chan+ * - * TIMESHIFT??? * - * * - * 0x0e 0x1f 0x1e * - * SLEEP Vol- Chan- * - * */ - { 0x0f, KEY_AUDIO }, - { 0x1b, KEY_VOLUMEUP }, - { 0x1a, KEY_CHANNELUP }, - { 0x0e, KEY_TIME }, - { 0x1f, KEY_VOLUMEDOWN }, - { 0x1e, KEY_CHANNELDOWN }, - - /* 0x13 0x19 * - * MUTE SNAPSHOT* - * */ - { 0x13, KEY_MUTE }, - { 0x19, KEY_CAMERA }, - - /* 0x1d unused ? */ -}; - -struct ir_scancode_table ir_codes_manli_table = { - .scan = ir_codes_manli, - .size = ARRAY_SIZE(ir_codes_manli), -}; -EXPORT_SYMBOL_GPL(ir_codes_manli_table); - -/* Mike Baikov */ -static struct ir_scancode ir_codes_gotview7135[] = { - - { 0x11, KEY_POWER }, - { 0x35, KEY_TV }, - { 0x1b, KEY_0 }, - { 0x29, KEY_1 }, - { 0x19, KEY_2 }, - { 0x39, KEY_3 }, - { 0x1f, KEY_4 }, - { 0x2c, KEY_5 }, - { 0x21, KEY_6 }, - { 0x24, KEY_7 }, - { 0x18, KEY_8 }, - { 0x2b, KEY_9 }, - { 0x3b, KEY_AGAIN }, /* LOOP */ - { 0x06, KEY_AUDIO }, - { 0x31, KEY_PRINT }, /* PREVIEW */ - { 0x3e, KEY_VIDEO }, - { 0x10, KEY_CHANNELUP }, - { 0x20, KEY_CHANNELDOWN }, - { 0x0c, KEY_VOLUMEDOWN }, - { 0x28, KEY_VOLUMEUP }, - { 0x08, KEY_MUTE }, - { 0x26, KEY_SEARCH }, /* SCAN */ - { 0x3f, KEY_CAMERA }, /* SNAPSHOT */ - { 0x12, KEY_RECORD }, - { 0x32, KEY_STOP }, - { 0x3c, KEY_PLAY }, - { 0x1d, KEY_REWIND }, - { 0x2d, KEY_PAUSE }, - { 0x0d, KEY_FORWARD }, - { 0x05, KEY_ZOOM }, /*FULL*/ - - { 0x2a, KEY_F21 }, /* LIVE TIMESHIFT */ - { 0x0e, KEY_F22 }, /* MIN TIMESHIFT */ - { 0x1e, KEY_TIME }, /* TIMESHIFT */ - { 0x38, KEY_F24 }, /* NORMAL TIMESHIFT */ -}; - -struct ir_scancode_table ir_codes_gotview7135_table = { - .scan = ir_codes_gotview7135, - .size = ARRAY_SIZE(ir_codes_gotview7135), -}; -EXPORT_SYMBOL_GPL(ir_codes_gotview7135_table); - -static struct ir_scancode ir_codes_purpletv[] = { - { 0x03, KEY_POWER }, - { 0x6f, KEY_MUTE }, - { 0x10, KEY_BACKSPACE }, /* Recall */ - - { 0x11, KEY_0 }, - { 0x04, KEY_1 }, - { 0x05, KEY_2 }, - { 0x06, KEY_3 }, - { 0x08, KEY_4 }, - { 0x09, KEY_5 }, - { 0x0a, KEY_6 }, - { 0x0c, KEY_7 }, - { 0x0d, KEY_8 }, - { 0x0e, KEY_9 }, - { 0x12, KEY_DOT }, /* 100+ */ - - { 0x07, KEY_VOLUMEUP }, - { 0x0b, KEY_VOLUMEDOWN }, - { 0x1a, KEY_KPPLUS }, - { 0x18, KEY_KPMINUS }, - { 0x15, KEY_UP }, - { 0x1d, KEY_DOWN }, - { 0x0f, KEY_CHANNELUP }, - { 0x13, KEY_CHANNELDOWN }, - { 0x48, KEY_ZOOM }, - - { 0x1b, KEY_VIDEO }, /* Video source */ - { 0x1f, KEY_CAMERA }, /* Snapshot */ - { 0x49, KEY_LANGUAGE }, /* MTS Select */ - { 0x19, KEY_SEARCH }, /* Auto Scan */ - - { 0x4b, KEY_RECORD }, - { 0x46, KEY_PLAY }, - { 0x45, KEY_PAUSE }, /* Pause */ - { 0x44, KEY_STOP }, - { 0x43, KEY_TIME }, /* Time Shift */ - { 0x17, KEY_CHANNEL }, /* SURF CH */ - { 0x40, KEY_FORWARD }, /* Forward ? */ - { 0x42, KEY_REWIND }, /* Backward ? */ - -}; - -struct ir_scancode_table ir_codes_purpletv_table = { - .scan = ir_codes_purpletv, - .size = ARRAY_SIZE(ir_codes_purpletv), -}; -EXPORT_SYMBOL_GPL(ir_codes_purpletv_table); - -/* Mapping for the 28 key remote control as seen at - http://www.sednacomputer.com/photo/cardbus-tv.jpg - Pavel Mihaylov - Also for the remote bundled with Kozumi KTV-01C card */ -static struct ir_scancode ir_codes_pctv_sedna[] = { - { 0x00, KEY_0 }, - { 0x01, KEY_1 }, - { 0x02, KEY_2 }, - { 0x03, KEY_3 }, - { 0x04, KEY_4 }, - { 0x05, KEY_5 }, - { 0x06, KEY_6 }, - { 0x07, KEY_7 }, - { 0x08, KEY_8 }, - { 0x09, KEY_9 }, - - { 0x0a, KEY_AGAIN }, /* Recall */ - { 0x0b, KEY_CHANNELUP }, - { 0x0c, KEY_VOLUMEUP }, - { 0x0d, KEY_MODE }, /* Stereo */ - { 0x0e, KEY_STOP }, - { 0x0f, KEY_PREVIOUSSONG }, - { 0x10, KEY_ZOOM }, - { 0x11, KEY_TUNER }, /* Source */ - { 0x12, KEY_POWER }, - { 0x13, KEY_MUTE }, - { 0x15, KEY_CHANNELDOWN }, - { 0x18, KEY_VOLUMEDOWN }, - { 0x19, KEY_CAMERA }, /* Snapshot */ - { 0x1a, KEY_NEXTSONG }, - { 0x1b, KEY_TIME }, /* Time Shift */ - { 0x1c, KEY_RADIO }, /* FM Radio */ - { 0x1d, KEY_RECORD }, - { 0x1e, KEY_PAUSE }, - /* additional codes for Kozumi's remote */ - { 0x14, KEY_INFO }, /* OSD */ - { 0x16, KEY_OK }, /* OK */ - { 0x17, KEY_DIGITS }, /* Plus */ - { 0x1f, KEY_PLAY }, /* Play */ -}; - -struct ir_scancode_table ir_codes_pctv_sedna_table = { - .scan = ir_codes_pctv_sedna, - .size = ARRAY_SIZE(ir_codes_pctv_sedna), -}; -EXPORT_SYMBOL_GPL(ir_codes_pctv_sedna_table); - -/* Mark Phalan */ -static struct ir_scancode ir_codes_pv951[] = { - { 0x00, KEY_0 }, - { 0x01, KEY_1 }, - { 0x02, KEY_2 }, - { 0x03, KEY_3 }, - { 0x04, KEY_4 }, - { 0x05, KEY_5 }, - { 0x06, KEY_6 }, - { 0x07, KEY_7 }, - { 0x08, KEY_8 }, - { 0x09, KEY_9 }, - - { 0x12, KEY_POWER }, - { 0x10, KEY_MUTE }, - { 0x1f, KEY_VOLUMEDOWN }, - { 0x1b, KEY_VOLUMEUP }, - { 0x1a, KEY_CHANNELUP }, - { 0x1e, KEY_CHANNELDOWN }, - { 0x0e, KEY_PAGEUP }, - { 0x1d, KEY_PAGEDOWN }, - { 0x13, KEY_SOUND }, - - { 0x18, KEY_KPPLUSMINUS }, /* CH +/- */ - { 0x16, KEY_SUBTITLE }, /* CC */ - { 0x0d, KEY_TEXT }, /* TTX */ - { 0x0b, KEY_TV }, /* AIR/CBL */ - { 0x11, KEY_PC }, /* PC/TV */ - { 0x17, KEY_OK }, /* CH RTN */ - { 0x19, KEY_MODE }, /* FUNC */ - { 0x0c, KEY_SEARCH }, /* AUTOSCAN */ - - /* Not sure what to do with these ones! */ - { 0x0f, KEY_SELECT }, /* SOURCE */ - { 0x0a, KEY_KPPLUS }, /* +100 */ - { 0x14, KEY_EQUAL }, /* SYNC */ - { 0x1c, KEY_MEDIA }, /* PC/TV */ -}; - -struct ir_scancode_table ir_codes_pv951_table = { - .scan = ir_codes_pv951, - .size = ARRAY_SIZE(ir_codes_pv951), -}; -EXPORT_SYMBOL_GPL(ir_codes_pv951_table); - -/* generic RC5 keytable */ -/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */ -/* used by old (black) Hauppauge remotes */ -static struct ir_scancode ir_codes_rc5_tv[] = { - /* Keys 0 to 9 */ - { 0x00, KEY_0 }, - { 0x01, KEY_1 }, - { 0x02, KEY_2 }, - { 0x03, KEY_3 }, - { 0x04, KEY_4 }, - { 0x05, KEY_5 }, - { 0x06, KEY_6 }, - { 0x07, KEY_7 }, - { 0x08, KEY_8 }, - { 0x09, KEY_9 }, - - { 0x0b, KEY_CHANNEL }, /* channel / program (japan: 11) */ - { 0x0c, KEY_POWER }, /* standby */ - { 0x0d, KEY_MUTE }, /* mute / demute */ - { 0x0f, KEY_TV }, /* display */ - { 0x10, KEY_VOLUMEUP }, - { 0x11, KEY_VOLUMEDOWN }, - { 0x12, KEY_BRIGHTNESSUP }, - { 0x13, KEY_BRIGHTNESSDOWN }, - { 0x1e, KEY_SEARCH }, /* search + */ - { 0x20, KEY_CHANNELUP }, /* channel / program + */ - { 0x21, KEY_CHANNELDOWN }, /* channel / program - */ - { 0x22, KEY_CHANNEL }, /* alt / channel */ - { 0x23, KEY_LANGUAGE }, /* 1st / 2nd language */ - { 0x26, KEY_SLEEP }, /* sleeptimer */ - { 0x2e, KEY_MENU }, /* 2nd controls (USA: menu) */ - { 0x30, KEY_PAUSE }, - { 0x32, KEY_REWIND }, - { 0x33, KEY_GOTO }, - { 0x35, KEY_PLAY }, - { 0x36, KEY_STOP }, - { 0x37, KEY_RECORD }, /* recording */ - { 0x3c, KEY_TEXT }, /* teletext submode (Japan: 12) */ - { 0x3d, KEY_SUSPEND }, /* system standby */ - -}; - -struct ir_scancode_table ir_codes_rc5_tv_table = { - .scan = ir_codes_rc5_tv, - .size = ARRAY_SIZE(ir_codes_rc5_tv), -}; -EXPORT_SYMBOL_GPL(ir_codes_rc5_tv_table); - -/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */ -static struct ir_scancode ir_codes_winfast[] = { - /* Keys 0 to 9 */ - { 0x12, KEY_0 }, - { 0x05, KEY_1 }, - { 0x06, KEY_2 }, - { 0x07, KEY_3 }, - { 0x09, KEY_4 }, - { 0x0a, KEY_5 }, - { 0x0b, KEY_6 }, - { 0x0d, KEY_7 }, - { 0x0e, KEY_8 }, - { 0x0f, KEY_9 }, - - { 0x00, KEY_POWER }, - { 0x1b, KEY_AUDIO }, /* Audio Source */ - { 0x02, KEY_TUNER }, /* TV/FM, not on Y0400052 */ - { 0x1e, KEY_VIDEO }, /* Video Source */ - { 0x16, KEY_INFO }, /* Display information */ - { 0x04, KEY_VOLUMEUP }, - { 0x08, KEY_VOLUMEDOWN }, - { 0x0c, KEY_CHANNELUP }, - { 0x10, KEY_CHANNELDOWN }, - { 0x03, KEY_ZOOM }, /* fullscreen */ - { 0x1f, KEY_TEXT }, /* closed caption/teletext */ - { 0x20, KEY_SLEEP }, - { 0x29, KEY_CLEAR }, /* boss key */ - { 0x14, KEY_MUTE }, - { 0x2b, KEY_RED }, - { 0x2c, KEY_GREEN }, - { 0x2d, KEY_YELLOW }, - { 0x2e, KEY_BLUE }, - { 0x18, KEY_KPPLUS }, /* fine tune + , not on Y040052 */ - { 0x19, KEY_KPMINUS }, /* fine tune - , not on Y040052 */ - { 0x2a, KEY_MEDIA }, /* PIP (Picture in picture */ - { 0x21, KEY_DOT }, - { 0x13, KEY_ENTER }, - { 0x11, KEY_LAST }, /* Recall (last channel */ - { 0x22, KEY_PREVIOUS }, - { 0x23, KEY_PLAYPAUSE }, - { 0x24, KEY_NEXT }, - { 0x25, KEY_TIME }, /* Time Shifting */ - { 0x26, KEY_STOP }, - { 0x27, KEY_RECORD }, - { 0x28, KEY_SAVE }, /* Screenshot */ - { 0x2f, KEY_MENU }, - { 0x30, KEY_CANCEL }, - { 0x31, KEY_CHANNEL }, /* Channel Surf */ - { 0x32, KEY_SUBTITLE }, - { 0x33, KEY_LANGUAGE }, - { 0x34, KEY_REWIND }, - { 0x35, KEY_FASTFORWARD }, - { 0x36, KEY_TV }, - { 0x37, KEY_RADIO }, /* FM */ - { 0x38, KEY_DVD }, - - { 0x1a, KEY_MODE}, /* change to MCE mode on Y04G0051 */ - { 0x3e, KEY_F21 }, /* MCE +VOL, on Y04G0033 */ - { 0x3a, KEY_F22 }, /* MCE -VOL, on Y04G0033 */ - { 0x3b, KEY_F23 }, /* MCE +CH, on Y04G0033 */ - { 0x3f, KEY_F24 } /* MCE -CH, on Y04G0033 */ -}; - -struct ir_scancode_table ir_codes_winfast_table = { - .scan = ir_codes_winfast, - .size = ARRAY_SIZE(ir_codes_winfast), -}; -EXPORT_SYMBOL_GPL(ir_codes_winfast_table); - -static struct ir_scancode ir_codes_pinnacle_color[] = { - { 0x59, KEY_MUTE }, - { 0x4a, KEY_POWER }, - - { 0x18, KEY_TEXT }, - { 0x26, KEY_TV }, - { 0x3d, KEY_PRINT }, - - { 0x48, KEY_RED }, - { 0x04, KEY_GREEN }, - { 0x11, KEY_YELLOW }, - { 0x00, KEY_BLUE }, - - { 0x2d, KEY_VOLUMEUP }, - { 0x1e, KEY_VOLUMEDOWN }, - - { 0x49, KEY_MENU }, - - { 0x16, KEY_CHANNELUP }, - { 0x17, KEY_CHANNELDOWN }, - - { 0x20, KEY_UP }, - { 0x21, KEY_DOWN }, - { 0x22, KEY_LEFT }, - { 0x23, KEY_RIGHT }, - { 0x0d, KEY_SELECT }, - - { 0x08, KEY_BACK }, - { 0x07, KEY_REFRESH }, - - { 0x2f, KEY_ZOOM }, - { 0x29, KEY_RECORD }, - - { 0x4b, KEY_PAUSE }, - { 0x4d, KEY_REWIND }, - { 0x2e, KEY_PLAY }, - { 0x4e, KEY_FORWARD }, - { 0x53, KEY_PREVIOUS }, - { 0x4c, KEY_STOP }, - { 0x54, KEY_NEXT }, - - { 0x69, KEY_0 }, - { 0x6a, KEY_1 }, - { 0x6b, KEY_2 }, - { 0x6c, KEY_3 }, - { 0x6d, KEY_4 }, - { 0x6e, KEY_5 }, - { 0x6f, KEY_6 }, - { 0x70, KEY_7 }, - { 0x71, KEY_8 }, - { 0x72, KEY_9 }, - - { 0x74, KEY_CHANNEL }, - { 0x0a, KEY_BACKSPACE }, -}; - -struct ir_scancode_table ir_codes_pinnacle_color_table = { - .scan = ir_codes_pinnacle_color, - .size = ARRAY_SIZE(ir_codes_pinnacle_color), -}; -EXPORT_SYMBOL_GPL(ir_codes_pinnacle_color_table); - -/* Hauppauge: the newer, gray remotes (seems there are multiple - * slightly different versions), shipped with cx88+ivtv cards. - * almost rc5 coding, but some non-standard keys */ -static struct ir_scancode ir_codes_hauppauge_new[] = { - /* Keys 0 to 9 */ - { 0x00, KEY_0 }, - { 0x01, KEY_1 }, - { 0x02, KEY_2 }, - { 0x03, KEY_3 }, - { 0x04, KEY_4 }, - { 0x05, KEY_5 }, - { 0x06, KEY_6 }, - { 0x07, KEY_7 }, - { 0x08, KEY_8 }, - { 0x09, KEY_9 }, - - { 0x0a, KEY_TEXT }, /* keypad asterisk as well */ - { 0x0b, KEY_RED }, /* red button */ - { 0x0c, KEY_RADIO }, - { 0x0d, KEY_MENU }, - { 0x0e, KEY_SUBTITLE }, /* also the # key */ - { 0x0f, KEY_MUTE }, - { 0x10, KEY_VOLUMEUP }, - { 0x11, KEY_VOLUMEDOWN }, - { 0x12, KEY_PREVIOUS }, /* previous channel */ - { 0x14, KEY_UP }, - { 0x15, KEY_DOWN }, - { 0x16, KEY_LEFT }, - { 0x17, KEY_RIGHT }, - { 0x18, KEY_VIDEO }, /* Videos */ - { 0x19, KEY_AUDIO }, /* Music */ - /* 0x1a: Pictures - presume this means - "Multimedia Home Platform" - - no "PICTURES" key in input.h - */ - { 0x1a, KEY_MHP }, - - { 0x1b, KEY_EPG }, /* Guide */ - { 0x1c, KEY_TV }, - { 0x1e, KEY_NEXTSONG }, /* skip >| */ - { 0x1f, KEY_EXIT }, /* back/exit */ - { 0x20, KEY_CHANNELUP }, /* channel / program + */ - { 0x21, KEY_CHANNELDOWN }, /* channel / program - */ - { 0x22, KEY_CHANNEL }, /* source (old black remote) */ - { 0x24, KEY_PREVIOUSSONG }, /* replay |< */ - { 0x25, KEY_ENTER }, /* OK */ - { 0x26, KEY_SLEEP }, /* minimize (old black remote) */ - { 0x29, KEY_BLUE }, /* blue key */ - { 0x2e, KEY_GREEN }, /* green button */ - { 0x30, KEY_PAUSE }, /* pause */ - { 0x32, KEY_REWIND }, /* backward << */ - { 0x34, KEY_FASTFORWARD }, /* forward >> */ - { 0x35, KEY_PLAY }, - { 0x36, KEY_STOP }, - { 0x37, KEY_RECORD }, /* recording */ - { 0x38, KEY_YELLOW }, /* yellow key */ - { 0x3b, KEY_SELECT }, /* top right button */ - { 0x3c, KEY_ZOOM }, /* full */ - { 0x3d, KEY_POWER }, /* system power (green button) */ -}; - -struct ir_scancode_table ir_codes_hauppauge_new_table = { - .scan = ir_codes_hauppauge_new, - .size = ARRAY_SIZE(ir_codes_hauppauge_new), -}; -EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table); - -static struct ir_scancode ir_codes_npgtech[] = { - { 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */ - { 0x2a, KEY_FRONT }, - - { 0x3e, KEY_1 }, - { 0x02, KEY_2 }, - { 0x06, KEY_3 }, - { 0x0a, KEY_4 }, - { 0x0e, KEY_5 }, - { 0x12, KEY_6 }, - { 0x16, KEY_7 }, - { 0x1a, KEY_8 }, - { 0x1e, KEY_9 }, - { 0x3a, KEY_0 }, - { 0x22, KEY_NUMLOCK }, /* -/-- */ - { 0x20, KEY_REFRESH }, - - { 0x03, KEY_BRIGHTNESSDOWN }, - { 0x28, KEY_AUDIO }, - { 0x3c, KEY_CHANNELUP }, - { 0x3f, KEY_VOLUMEDOWN }, - { 0x2e, KEY_MUTE }, - { 0x3b, KEY_VOLUMEUP }, - { 0x00, KEY_CHANNELDOWN }, - { 0x07, KEY_BRIGHTNESSUP }, - { 0x2c, KEY_TEXT }, - - { 0x37, KEY_RECORD }, - { 0x17, KEY_PLAY }, - { 0x13, KEY_PAUSE }, - { 0x26, KEY_STOP }, - { 0x18, KEY_FASTFORWARD }, - { 0x14, KEY_REWIND }, - { 0x33, KEY_ZOOM }, - { 0x32, KEY_KEYBOARD }, - { 0x30, KEY_GOTO }, /* Pointing arrow */ - { 0x36, KEY_MACRO }, /* Maximize/Minimize (yellow) */ - { 0x0b, KEY_RADIO }, - { 0x10, KEY_POWER }, - -}; - -struct ir_scancode_table ir_codes_npgtech_table = { - .scan = ir_codes_npgtech, - .size = ARRAY_SIZE(ir_codes_npgtech), -}; -EXPORT_SYMBOL_GPL(ir_codes_npgtech_table); - -/* Norwood Micro (non-Pro) TV Tuner - By Peter Naulls - Key comments are the functions given in the manual */ -static struct ir_scancode ir_codes_norwood[] = { - /* Keys 0 to 9 */ - { 0x20, KEY_0 }, - { 0x21, KEY_1 }, - { 0x22, KEY_2 }, - { 0x23, KEY_3 }, - { 0x24, KEY_4 }, - { 0x25, KEY_5 }, - { 0x26, KEY_6 }, - { 0x27, KEY_7 }, - { 0x28, KEY_8 }, - { 0x29, KEY_9 }, - - { 0x78, KEY_TUNER }, /* Video Source */ - { 0x2c, KEY_EXIT }, /* Open/Close software */ - { 0x2a, KEY_SELECT }, /* 2 Digit Select */ - { 0x69, KEY_AGAIN }, /* Recall */ - - { 0x32, KEY_BRIGHTNESSUP }, /* Brightness increase */ - { 0x33, KEY_BRIGHTNESSDOWN }, /* Brightness decrease */ - { 0x6b, KEY_KPPLUS }, /* (not named >>>>>) */ - { 0x6c, KEY_KPMINUS }, /* (not named <<<<<) */ - - { 0x2d, KEY_MUTE }, /* Mute */ - { 0x30, KEY_VOLUMEUP }, /* Volume up */ - { 0x31, KEY_VOLUMEDOWN }, /* Volume down */ - { 0x60, KEY_CHANNELUP }, /* Channel up */ - { 0x61, KEY_CHANNELDOWN }, /* Channel down */ - - { 0x3f, KEY_RECORD }, /* Record */ - { 0x37, KEY_PLAY }, /* Play */ - { 0x36, KEY_PAUSE }, /* Pause */ - { 0x2b, KEY_STOP }, /* Stop */ - { 0x67, KEY_FASTFORWARD }, /* Foward */ - { 0x66, KEY_REWIND }, /* Rewind */ - { 0x3e, KEY_SEARCH }, /* Auto Scan */ - { 0x2e, KEY_CAMERA }, /* Capture Video */ - { 0x6d, KEY_MENU }, /* Show/Hide Control */ - { 0x2f, KEY_ZOOM }, /* Full Screen */ - { 0x34, KEY_RADIO }, /* FM */ - { 0x65, KEY_POWER }, /* Computer power */ -}; - -struct ir_scancode_table ir_codes_norwood_table = { - .scan = ir_codes_norwood, - .size = ARRAY_SIZE(ir_codes_norwood), -}; -EXPORT_SYMBOL_GPL(ir_codes_norwood_table); - -/* From reading the following remotes: - * Zenith Universal 7 / TV Mode 807 / VCR Mode 837 - * Hauppauge (from NOVA-CI-s box product) - * This is a "middle of the road" approach, differences are noted - */ -static struct ir_scancode ir_codes_budget_ci_old[] = { - { 0x00, KEY_0 }, - { 0x01, KEY_1 }, - { 0x02, KEY_2 }, - { 0x03, KEY_3 }, - { 0x04, KEY_4 }, - { 0x05, KEY_5 }, - { 0x06, KEY_6 }, - { 0x07, KEY_7 }, - { 0x08, KEY_8 }, - { 0x09, KEY_9 }, - { 0x0a, KEY_ENTER }, - { 0x0b, KEY_RED }, - { 0x0c, KEY_POWER }, /* RADIO on Hauppauge */ - { 0x0d, KEY_MUTE }, - { 0x0f, KEY_A }, /* TV on Hauppauge */ - { 0x10, KEY_VOLUMEUP }, - { 0x11, KEY_VOLUMEDOWN }, - { 0x14, KEY_B }, - { 0x1c, KEY_UP }, - { 0x1d, KEY_DOWN }, - { 0x1e, KEY_OPTION }, /* RESERVED on Hauppauge */ - { 0x1f, KEY_BREAK }, - { 0x20, KEY_CHANNELUP }, - { 0x21, KEY_CHANNELDOWN }, - { 0x22, KEY_PREVIOUS }, /* Prev Ch on Zenith, SOURCE on Hauppauge */ - { 0x24, KEY_RESTART }, - { 0x25, KEY_OK }, - { 0x26, KEY_CYCLEWINDOWS }, /* MINIMIZE on Hauppauge */ - { 0x28, KEY_ENTER }, /* VCR mode on Zenith */ - { 0x29, KEY_PAUSE }, - { 0x2b, KEY_RIGHT }, - { 0x2c, KEY_LEFT }, - { 0x2e, KEY_MENU }, /* FULL SCREEN on Hauppauge */ - { 0x30, KEY_SLOW }, - { 0x31, KEY_PREVIOUS }, /* VCR mode on Zenith */ - { 0x32, KEY_REWIND }, - { 0x34, KEY_FASTFORWARD }, - { 0x35, KEY_PLAY }, - { 0x36, KEY_STOP }, - { 0x37, KEY_RECORD }, - { 0x38, KEY_TUNER }, /* TV/VCR on Zenith */ - { 0x3a, KEY_C }, - { 0x3c, KEY_EXIT }, - { 0x3d, KEY_POWER2 }, - { 0x3e, KEY_TUNER }, -}; - -struct ir_scancode_table ir_codes_budget_ci_old_table = { - .scan = ir_codes_budget_ci_old, - .size = ARRAY_SIZE(ir_codes_budget_ci_old), -}; -EXPORT_SYMBOL_GPL(ir_codes_budget_ci_old_table); - -/* - * Marc Fargas - * this is the remote control that comes with the asus p7131 - * which has a label saying is "Model PC-39" - */ -static struct ir_scancode ir_codes_asus_pc39[] = { - /* Keys 0 to 9 */ - { 0x15, KEY_0 }, - { 0x29, KEY_1 }, - { 0x2d, KEY_2 }, - { 0x2b, KEY_3 }, - { 0x09, KEY_4 }, - { 0x0d, KEY_5 }, - { 0x0b, KEY_6 }, - { 0x31, KEY_7 }, - { 0x35, KEY_8 }, - { 0x33, KEY_9 }, - - { 0x3e, KEY_RADIO }, /* radio */ - { 0x03, KEY_MENU }, /* dvd/menu */ - { 0x2a, KEY_VOLUMEUP }, - { 0x19, KEY_VOLUMEDOWN }, - { 0x37, KEY_UP }, - { 0x3b, KEY_DOWN }, - { 0x27, KEY_LEFT }, - { 0x2f, KEY_RIGHT }, - { 0x25, KEY_VIDEO }, /* video */ - { 0x39, KEY_AUDIO }, /* music */ - - { 0x21, KEY_TV }, /* tv */ - { 0x1d, KEY_EXIT }, /* back */ - { 0x0a, KEY_CHANNELUP }, /* channel / program + */ - { 0x1b, KEY_CHANNELDOWN }, /* channel / program - */ - { 0x1a, KEY_ENTER }, /* enter */ - - { 0x06, KEY_PAUSE }, /* play/pause */ - { 0x1e, KEY_PREVIOUS }, /* rew */ - { 0x26, KEY_NEXT }, /* forward */ - { 0x0e, KEY_REWIND }, /* backward << */ - { 0x3a, KEY_FASTFORWARD }, /* forward >> */ - { 0x36, KEY_STOP }, - { 0x2e, KEY_RECORD }, /* recording */ - { 0x16, KEY_POWER }, /* the button that reads "close" */ - - { 0x11, KEY_ZOOM }, /* full screen */ - { 0x13, KEY_MACRO }, /* recall */ - { 0x23, KEY_HOME }, /* home */ - { 0x05, KEY_PVR }, /* picture */ - { 0x3d, KEY_MUTE }, /* mute */ - { 0x01, KEY_DVD }, /* dvd */ -}; - -struct ir_scancode_table ir_codes_asus_pc39_table = { - .scan = ir_codes_asus_pc39, - .size = ARRAY_SIZE(ir_codes_asus_pc39), -}; -EXPORT_SYMBOL_GPL(ir_codes_asus_pc39_table); - - -/* Encore ENLTV-FM - black plastic, white front cover with white glowing buttons - Juan Pablo Sormani */ -static struct ir_scancode ir_codes_encore_enltv[] = { - - /* Power button does nothing, neither in Windows app, - although it sends data (used for BIOS wakeup?) */ - { 0x0d, KEY_MUTE }, - - { 0x1e, KEY_TV }, - { 0x00, KEY_VIDEO }, - { 0x01, KEY_AUDIO }, /* music */ - { 0x02, KEY_MHP }, /* picture */ - - { 0x1f, KEY_1 }, - { 0x03, KEY_2 }, - { 0x04, KEY_3 }, - { 0x05, KEY_4 }, - { 0x1c, KEY_5 }, - { 0x06, KEY_6 }, - { 0x07, KEY_7 }, - { 0x08, KEY_8 }, - { 0x1d, KEY_9 }, - { 0x0a, KEY_0 }, - - { 0x09, KEY_LIST }, /* -/-- */ - { 0x0b, KEY_LAST }, /* recall */ - - { 0x14, KEY_HOME }, /* win start menu */ - { 0x15, KEY_EXIT }, /* exit */ - { 0x16, KEY_CHANNELUP }, /* UP */ - { 0x12, KEY_CHANNELDOWN }, /* DOWN */ - { 0x0c, KEY_VOLUMEUP }, /* RIGHT */ - { 0x17, KEY_VOLUMEDOWN }, /* LEFT */ - - { 0x18, KEY_ENTER }, /* OK */ - - { 0x0e, KEY_ESC }, - { 0x13, KEY_CYCLEWINDOWS }, /* desktop */ - { 0x11, KEY_TAB }, - { 0x19, KEY_SWITCHVIDEOMODE }, /* switch */ - - { 0x1a, KEY_MENU }, - { 0x1b, KEY_ZOOM }, /* fullscreen */ - { 0x44, KEY_TIME }, /* time shift */ - { 0x40, KEY_MODE }, /* source */ - - { 0x5a, KEY_RECORD }, - { 0x42, KEY_PLAY }, /* play/pause */ - { 0x45, KEY_STOP }, - { 0x43, KEY_CAMERA }, /* camera icon */ - - { 0x48, KEY_REWIND }, - { 0x4a, KEY_FASTFORWARD }, - { 0x49, KEY_PREVIOUS }, - { 0x4b, KEY_NEXT }, - - { 0x4c, KEY_FAVORITES }, /* tv wall */ - { 0x4d, KEY_SOUND }, /* DVD sound */ - { 0x4e, KEY_LANGUAGE }, /* DVD lang */ - { 0x4f, KEY_TEXT }, /* DVD text */ - - { 0x50, KEY_SLEEP }, /* shutdown */ - { 0x51, KEY_MODE }, /* stereo > main */ - { 0x52, KEY_SELECT }, /* stereo > sap */ - { 0x53, KEY_PROG1 }, /* teletext */ - - - { 0x59, KEY_RED }, /* AP1 */ - { 0x41, KEY_GREEN }, /* AP2 */ - { 0x47, KEY_YELLOW }, /* AP3 */ - { 0x57, KEY_BLUE }, /* AP4 */ -}; - -struct ir_scancode_table ir_codes_encore_enltv_table = { - .scan = ir_codes_encore_enltv, - .size = ARRAY_SIZE(ir_codes_encore_enltv), -}; -EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_table); - -/* Encore ENLTV2-FM - silver plastic - "Wand Media" written at the botton - Mauro Carvalho Chehab */ -static struct ir_scancode ir_codes_encore_enltv2[] = { - { 0x4c, KEY_POWER2 }, - { 0x4a, KEY_TUNER }, - { 0x40, KEY_1 }, - { 0x60, KEY_2 }, - { 0x50, KEY_3 }, - { 0x70, KEY_4 }, - { 0x48, KEY_5 }, - { 0x68, KEY_6 }, - { 0x58, KEY_7 }, - { 0x78, KEY_8 }, - { 0x44, KEY_9 }, - { 0x54, KEY_0 }, - - { 0x64, KEY_LAST }, /* +100 */ - { 0x4e, KEY_AGAIN }, /* Recall */ - - { 0x6c, KEY_SWITCHVIDEOMODE }, /* Video Source */ - { 0x5e, KEY_MENU }, - { 0x56, KEY_SCREEN }, - { 0x7a, KEY_SETUP }, - - { 0x46, KEY_MUTE }, - { 0x5c, KEY_MODE }, /* Stereo */ - { 0x74, KEY_INFO }, - { 0x7c, KEY_CLEAR }, - - { 0x55, KEY_UP }, - { 0x49, KEY_DOWN }, - { 0x7e, KEY_LEFT }, - { 0x59, KEY_RIGHT }, - { 0x6a, KEY_ENTER }, - - { 0x42, KEY_VOLUMEUP }, - { 0x62, KEY_VOLUMEDOWN }, - { 0x52, KEY_CHANNELUP }, - { 0x72, KEY_CHANNELDOWN }, - - { 0x41, KEY_RECORD }, - { 0x51, KEY_CAMERA }, /* Snapshot */ - { 0x75, KEY_TIME }, /* Timeshift */ - { 0x71, KEY_TV2 }, /* PIP */ - - { 0x45, KEY_REWIND }, - { 0x6f, KEY_PAUSE }, - { 0x7d, KEY_FORWARD }, - { 0x79, KEY_STOP }, -}; - -struct ir_scancode_table ir_codes_encore_enltv2_table = { - .scan = ir_codes_encore_enltv2, - .size = ARRAY_SIZE(ir_codes_encore_enltv2), -}; -EXPORT_SYMBOL_GPL(ir_codes_encore_enltv2_table); - -/* for the Technotrend 1500 bundled remotes (grey and black): */ -static struct ir_scancode ir_codes_tt_1500[] = { - { 0x01, KEY_POWER }, - { 0x02, KEY_SHUFFLE }, /* ? double-arrow key */ - { 0x03, KEY_1 }, - { 0x04, KEY_2 }, - { 0x05, KEY_3 }, - { 0x06, KEY_4 }, - { 0x07, KEY_5 }, - { 0x08, KEY_6 }, - { 0x09, KEY_7 }, - { 0x0a, KEY_8 }, - { 0x0b, KEY_9 }, - { 0x0c, KEY_0 }, - { 0x0d, KEY_UP }, - { 0x0e, KEY_LEFT }, - { 0x0f, KEY_OK }, - { 0x10, KEY_RIGHT }, - { 0x11, KEY_DOWN }, - { 0x12, KEY_INFO }, - { 0x13, KEY_EXIT }, - { 0x14, KEY_RED }, - { 0x15, KEY_GREEN }, - { 0x16, KEY_YELLOW }, - { 0x17, KEY_BLUE }, - { 0x18, KEY_MUTE }, - { 0x19, KEY_TEXT }, - { 0x1a, KEY_MODE }, /* ? TV/Radio */ - { 0x21, KEY_OPTION }, - { 0x22, KEY_EPG }, - { 0x23, KEY_CHANNELUP }, - { 0x24, KEY_CHANNELDOWN }, - { 0x25, KEY_VOLUMEUP }, - { 0x26, KEY_VOLUMEDOWN }, - { 0x27, KEY_SETUP }, - { 0x3a, KEY_RECORD }, /* these keys are only in the black remote */ - { 0x3b, KEY_PLAY }, - { 0x3c, KEY_STOP }, - { 0x3d, KEY_REWIND }, - { 0x3e, KEY_PAUSE }, - { 0x3f, KEY_FORWARD }, -}; - -struct ir_scancode_table ir_codes_tt_1500_table = { - .scan = ir_codes_tt_1500, - .size = ARRAY_SIZE(ir_codes_tt_1500), -}; -EXPORT_SYMBOL_GPL(ir_codes_tt_1500_table); - -/* DViCO FUSION HDTV MCE remote */ -static struct ir_scancode ir_codes_fusionhdtv_mce[] = { - - { 0x0b, KEY_1 }, - { 0x17, KEY_2 }, - { 0x1b, KEY_3 }, - { 0x07, KEY_4 }, - { 0x50, KEY_5 }, - { 0x54, KEY_6 }, - { 0x48, KEY_7 }, - { 0x4c, KEY_8 }, - { 0x58, KEY_9 }, - { 0x03, KEY_0 }, - - { 0x5e, KEY_OK }, - { 0x51, KEY_UP }, - { 0x53, KEY_DOWN }, - { 0x5b, KEY_LEFT }, - { 0x5f, KEY_RIGHT }, - - { 0x02, KEY_TV }, /* Labeled DTV on remote */ - { 0x0e, KEY_MP3 }, - { 0x1a, KEY_DVD }, - { 0x1e, KEY_FAVORITES }, /* Labeled CPF on remote */ - { 0x16, KEY_SETUP }, - { 0x46, KEY_POWER2 }, /* TV On/Off button on remote */ - { 0x0a, KEY_EPG }, /* Labeled Guide on remote */ - - { 0x49, KEY_BACK }, - { 0x59, KEY_INFO }, /* Labeled MORE on remote */ - { 0x4d, KEY_MENU }, /* Labeled DVDMENU on remote */ - { 0x55, KEY_CYCLEWINDOWS }, /* Labeled ALT-TAB on remote */ - - { 0x0f, KEY_PREVIOUSSONG }, /* Labeled |<< REPLAY on remote */ - { 0x12, KEY_NEXTSONG }, /* Labeled >>| SKIP on remote */ - { 0x42, KEY_ENTER }, /* Labeled START with a green - MS windows logo on remote */ - - { 0x15, KEY_VOLUMEUP }, - { 0x05, KEY_VOLUMEDOWN }, - { 0x11, KEY_CHANNELUP }, - { 0x09, KEY_CHANNELDOWN }, - - { 0x52, KEY_CAMERA }, - { 0x5a, KEY_TUNER }, - { 0x19, KEY_OPEN }, - - { 0x13, KEY_MODE }, /* 4:3 16:9 select */ - { 0x1f, KEY_ZOOM }, - - { 0x43, KEY_REWIND }, - { 0x47, KEY_PLAYPAUSE }, - { 0x4f, KEY_FASTFORWARD }, - { 0x57, KEY_MUTE }, - { 0x0d, KEY_STOP }, - { 0x01, KEY_RECORD }, - { 0x4e, KEY_POWER }, -}; - -struct ir_scancode_table ir_codes_fusionhdtv_mce_table = { - .scan = ir_codes_fusionhdtv_mce, - .size = ARRAY_SIZE(ir_codes_fusionhdtv_mce), -}; -EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce_table); - -/* Pinnacle PCTV HD 800i mini remote */ -static struct ir_scancode ir_codes_pinnacle_pctv_hd[] = { - - { 0x0f, KEY_1 }, - { 0x15, KEY_2 }, - { 0x10, KEY_3 }, - { 0x18, KEY_4 }, - { 0x1b, KEY_5 }, - { 0x1e, KEY_6 }, - { 0x11, KEY_7 }, - { 0x21, KEY_8 }, - { 0x12, KEY_9 }, - { 0x27, KEY_0 }, - - { 0x24, KEY_ZOOM }, - { 0x2a, KEY_SUBTITLE }, - - { 0x00, KEY_MUTE }, - { 0x01, KEY_ENTER }, /* Pinnacle Logo */ - { 0x39, KEY_POWER }, - - { 0x03, KEY_VOLUMEUP }, - { 0x09, KEY_VOLUMEDOWN }, - { 0x06, KEY_CHANNELUP }, - { 0x0c, KEY_CHANNELDOWN }, - - { 0x2d, KEY_REWIND }, - { 0x30, KEY_PLAYPAUSE }, - { 0x33, KEY_FASTFORWARD }, - { 0x3c, KEY_STOP }, - { 0x36, KEY_RECORD }, - { 0x3f, KEY_EPG }, /* Labeled "?" */ -}; - -struct ir_scancode_table ir_codes_pinnacle_pctv_hd_table = { - .scan = ir_codes_pinnacle_pctv_hd, - .size = ARRAY_SIZE(ir_codes_pinnacle_pctv_hd), -}; -EXPORT_SYMBOL_GPL(ir_codes_pinnacle_pctv_hd_table); - -/* - * Igor Kuznetsov - * Andrey J. Melnikov - * - * Keytable is used by BeholdTV 60x series, M6 series at - * least, and probably other cards too. - * The "ascii-art picture" below (in comments, first row - * is the keycode in hex, and subsequent row(s) shows - * the button labels (several variants when appropriate) - * helps to descide which keycodes to assign to the buttons. - */ -static struct ir_scancode ir_codes_behold[] = { - - /* 0x1c 0x12 * - * TV/FM POWER * - * */ - { 0x1c, KEY_TUNER }, /* XXX KEY_TV / KEY_RADIO */ - { 0x12, KEY_POWER }, - - /* 0x01 0x02 0x03 * - * 1 2 3 * - * * - * 0x04 0x05 0x06 * - * 4 5 6 * - * * - * 0x07 0x08 0x09 * - * 7 8 9 * - * */ - { 0x01, KEY_1 }, - { 0x02, KEY_2 }, - { 0x03, KEY_3 }, - { 0x04, KEY_4 }, - { 0x05, KEY_5 }, - { 0x06, KEY_6 }, - { 0x07, KEY_7 }, - { 0x08, KEY_8 }, - { 0x09, KEY_9 }, - - /* 0x0a 0x00 0x17 * - * RECALL 0 MODE * - * */ - { 0x0a, KEY_AGAIN }, - { 0x00, KEY_0 }, - { 0x17, KEY_MODE }, - - /* 0x14 0x10 * - * ASPECT FULLSCREEN * - * */ - { 0x14, KEY_SCREEN }, - { 0x10, KEY_ZOOM }, - - /* 0x0b * - * Up * - * * - * 0x18 0x16 0x0c * - * Left Ok Right * - * * - * 0x015 * - * Down * - * */ - { 0x0b, KEY_CHANNELUP }, - { 0x18, KEY_VOLUMEDOWN }, - { 0x16, KEY_OK }, /* XXX KEY_ENTER */ - { 0x0c, KEY_VOLUMEUP }, - { 0x15, KEY_CHANNELDOWN }, - - /* 0x11 0x0d * - * MUTE INFO * - * */ - { 0x11, KEY_MUTE }, - { 0x0d, KEY_INFO }, - - /* 0x0f 0x1b 0x1a * - * RECORD PLAY/PAUSE STOP * - * * - * 0x0e 0x1f 0x1e * - *TELETEXT AUDIO SOURCE * - * RED YELLOW * - * */ - { 0x0f, KEY_RECORD }, - { 0x1b, KEY_PLAYPAUSE }, - { 0x1a, KEY_STOP }, - { 0x0e, KEY_TEXT }, - { 0x1f, KEY_RED }, /*XXX KEY_AUDIO */ - { 0x1e, KEY_YELLOW }, /*XXX KEY_SOURCE */ - - /* 0x1d 0x13 0x19 * - * SLEEP PREVIEW DVB * - * GREEN BLUE * - * */ - { 0x1d, KEY_SLEEP }, - { 0x13, KEY_GREEN }, - { 0x19, KEY_BLUE }, /* XXX KEY_SAT */ - - /* 0x58 0x5c * - * FREEZE SNAPSHOT * - * */ - { 0x58, KEY_SLOW }, - { 0x5c, KEY_CAMERA }, - -}; - -struct ir_scancode_table ir_codes_behold_table = { - .scan = ir_codes_behold, - .size = ARRAY_SIZE(ir_codes_behold), -}; -EXPORT_SYMBOL_GPL(ir_codes_behold_table); - -/* Beholder Intl. Ltd. 2008 - * Dmitry Belimov d.belimov@google.com - * Keytable is used by BeholdTV Columbus - * The "ascii-art picture" below (in comments, first row - * is the keycode in hex, and subsequent row(s) shows - * the button labels (several variants when appropriate) - * helps to descide which keycodes to assign to the buttons. - */ -static struct ir_scancode ir_codes_behold_columbus[] = { - - /* 0x13 0x11 0x1C 0x12 * - * Mute Source TV/FM Power * - * */ - - { 0x13, KEY_MUTE }, - { 0x11, KEY_PROPS }, - { 0x1C, KEY_TUNER }, /* KEY_TV/KEY_RADIO */ - { 0x12, KEY_POWER }, - - /* 0x01 0x02 0x03 0x0D * - * 1 2 3 Stereo * - * * - * 0x04 0x05 0x06 0x19 * - * 4 5 6 Snapshot * - * * - * 0x07 0x08 0x09 0x10 * - * 7 8 9 Zoom * - * */ - { 0x01, KEY_1 }, - { 0x02, KEY_2 }, - { 0x03, KEY_3 }, - { 0x0D, KEY_SETUP }, /* Setup key */ - { 0x04, KEY_4 }, - { 0x05, KEY_5 }, - { 0x06, KEY_6 }, - { 0x19, KEY_CAMERA }, /* Snapshot key */ - { 0x07, KEY_7 }, - { 0x08, KEY_8 }, - { 0x09, KEY_9 }, - { 0x10, KEY_ZOOM }, - - /* 0x0A 0x00 0x0B 0x0C * - * RECALL 0 ChannelUp VolumeUp * - * */ - { 0x0A, KEY_AGAIN }, - { 0x00, KEY_0 }, - { 0x0B, KEY_CHANNELUP }, - { 0x0C, KEY_VOLUMEUP }, - - /* 0x1B 0x1D 0x15 0x18 * - * Timeshift Record ChannelDown VolumeDown * - * */ - - { 0x1B, KEY_TIME }, - { 0x1D, KEY_RECORD }, - { 0x15, KEY_CHANNELDOWN }, - { 0x18, KEY_VOLUMEDOWN }, - - /* 0x0E 0x1E 0x0F 0x1A * - * Stop Pause Previouse Next * - * */ - - { 0x0E, KEY_STOP }, - { 0x1E, KEY_PAUSE }, - { 0x0F, KEY_PREVIOUS }, - { 0x1A, KEY_NEXT }, - -}; - -struct ir_scancode_table ir_codes_behold_columbus_table = { - .scan = ir_codes_behold_columbus, - .size = ARRAY_SIZE(ir_codes_behold_columbus), -}; -EXPORT_SYMBOL_GPL(ir_codes_behold_columbus_table); - -/* - * Remote control for the Genius TVGO A11MCE - * Adrian Pardini - */ -static struct ir_scancode ir_codes_genius_tvgo_a11mce[] = { - /* Keys 0 to 9 */ - { 0x48, KEY_0 }, - { 0x09, KEY_1 }, - { 0x1d, KEY_2 }, - { 0x1f, KEY_3 }, - { 0x19, KEY_4 }, - { 0x1b, KEY_5 }, - { 0x11, KEY_6 }, - { 0x17, KEY_7 }, - { 0x12, KEY_8 }, - { 0x16, KEY_9 }, - - { 0x54, KEY_RECORD }, /* recording */ - { 0x06, KEY_MUTE }, /* mute */ - { 0x10, KEY_POWER }, - { 0x40, KEY_LAST }, /* recall */ - { 0x4c, KEY_CHANNELUP }, /* channel / program + */ - { 0x00, KEY_CHANNELDOWN }, /* channel / program - */ - { 0x0d, KEY_VOLUMEUP }, - { 0x15, KEY_VOLUMEDOWN }, - { 0x4d, KEY_OK }, /* also labeled as Pause */ - { 0x1c, KEY_ZOOM }, /* full screen and Stop*/ - { 0x02, KEY_MODE }, /* AV Source or Rewind*/ - { 0x04, KEY_LIST }, /* -/-- */ - /* small arrows above numbers */ - { 0x1a, KEY_NEXT }, /* also Fast Forward */ - { 0x0e, KEY_PREVIOUS }, /* also Rewind */ - /* these are in a rather non standard layout and have - an alternate name written */ - { 0x1e, KEY_UP }, /* Video Setting */ - { 0x0a, KEY_DOWN }, /* Video Default */ - { 0x05, KEY_CAMERA }, /* Snapshot */ - { 0x0c, KEY_RIGHT }, /* Hide Panel */ - /* Four buttons without label */ - { 0x49, KEY_RED }, - { 0x0b, KEY_GREEN }, - { 0x13, KEY_YELLOW }, - { 0x50, KEY_BLUE }, -}; - -struct ir_scancode_table ir_codes_genius_tvgo_a11mce_table = { - .scan = ir_codes_genius_tvgo_a11mce, - .size = ARRAY_SIZE(ir_codes_genius_tvgo_a11mce), -}; -EXPORT_SYMBOL_GPL(ir_codes_genius_tvgo_a11mce_table); - -/* - * Remote control for Powercolor Real Angel 330 - * Daniel Fraga - */ -static struct ir_scancode ir_codes_powercolor_real_angel[] = { - { 0x38, KEY_SWITCHVIDEOMODE }, /* switch inputs */ - { 0x0c, KEY_MEDIA }, /* Turn ON/OFF App */ - { 0x00, KEY_0 }, - { 0x01, KEY_1 }, - { 0x02, KEY_2 }, - { 0x03, KEY_3 }, - { 0x04, KEY_4 }, - { 0x05, KEY_5 }, - { 0x06, KEY_6 }, - { 0x07, KEY_7 }, - { 0x08, KEY_8 }, - { 0x09, KEY_9 }, - { 0x0a, KEY_DIGITS }, /* single, double, tripple digit */ - { 0x29, KEY_PREVIOUS }, /* previous channel */ - { 0x12, KEY_BRIGHTNESSUP }, - { 0x13, KEY_BRIGHTNESSDOWN }, - { 0x2b, KEY_MODE }, /* stereo/mono */ - { 0x2c, KEY_TEXT }, /* teletext */ - { 0x20, KEY_CHANNELUP }, /* channel up */ - { 0x21, KEY_CHANNELDOWN }, /* channel down */ - { 0x10, KEY_VOLUMEUP }, /* volume up */ - { 0x11, KEY_VOLUMEDOWN }, /* volume down */ - { 0x0d, KEY_MUTE }, - { 0x1f, KEY_RECORD }, - { 0x17, KEY_PLAY }, - { 0x16, KEY_PAUSE }, - { 0x0b, KEY_STOP }, - { 0x27, KEY_FASTFORWARD }, - { 0x26, KEY_REWIND }, - { 0x1e, KEY_SEARCH }, /* autoscan */ - { 0x0e, KEY_CAMERA }, /* snapshot */ - { 0x2d, KEY_SETUP }, - { 0x0f, KEY_SCREEN }, /* full screen */ - { 0x14, KEY_RADIO }, /* FM radio */ - { 0x25, KEY_POWER }, /* power */ -}; - -struct ir_scancode_table ir_codes_powercolor_real_angel_table = { - .scan = ir_codes_powercolor_real_angel, - .size = ARRAY_SIZE(ir_codes_powercolor_real_angel), -}; -EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel_table); - -/* Kworld Plus TV Analog Lite PCI IR - Mauro Carvalho Chehab - */ -static struct ir_scancode ir_codes_kworld_plus_tv_analog[] = { - { 0x0c, KEY_PROG1 }, /* Kworld key */ - { 0x16, KEY_CLOSECD }, /* -> ) */ - { 0x1d, KEY_POWER2 }, - - { 0x00, KEY_1 }, - { 0x01, KEY_2 }, - { 0x02, KEY_3 }, /* Two keys have the same code: 3 and left */ - { 0x03, KEY_4 }, /* Two keys have the same code: 3 and right */ - { 0x04, KEY_5 }, - { 0x05, KEY_6 }, - { 0x06, KEY_7 }, - { 0x07, KEY_8 }, - { 0x08, KEY_9 }, - { 0x0a, KEY_0 }, - - { 0x09, KEY_AGAIN }, - { 0x14, KEY_MUTE }, - - { 0x20, KEY_UP }, - { 0x21, KEY_DOWN }, - { 0x0b, KEY_ENTER }, - - { 0x10, KEY_CHANNELUP }, - { 0x11, KEY_CHANNELDOWN }, - - /* Couldn't map key left/key right since those - conflict with '3' and '4' scancodes - I dunno what the original driver does - */ - - { 0x13, KEY_VOLUMEUP }, - { 0x12, KEY_VOLUMEDOWN }, - - /* The lower part of the IR - There are several duplicated keycodes there. - Most of them conflict with digits. - Add mappings just to the unused scancodes. - Somehow, the original driver has a way to know, - but this doesn't seem to be on some GPIO. - Also, it is not related to the time between keyup - and keydown. - */ - { 0x19, KEY_TIME}, /* Timeshift */ - { 0x1a, KEY_STOP}, - { 0x1b, KEY_RECORD}, - - { 0x22, KEY_TEXT}, - - { 0x15, KEY_AUDIO}, /* ((*)) */ - { 0x0f, KEY_ZOOM}, - { 0x1c, KEY_CAMERA}, /* snapshot */ - - { 0x18, KEY_RED}, /* B */ - { 0x23, KEY_GREEN}, /* C */ -}; -struct ir_scancode_table ir_codes_kworld_plus_tv_analog_table = { - .scan = ir_codes_kworld_plus_tv_analog, - .size = ARRAY_SIZE(ir_codes_kworld_plus_tv_analog), -}; -EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog_table); - -/* Kaiomy TVnPC U2 - Mauro Carvalho Chehab - */ -static struct ir_scancode ir_codes_kaiomy[] = { - { 0x43, KEY_POWER2}, - { 0x01, KEY_LIST}, - { 0x0b, KEY_ZOOM}, - { 0x03, KEY_POWER}, - - { 0x04, KEY_1}, - { 0x08, KEY_2}, - { 0x02, KEY_3}, - - { 0x0f, KEY_4}, - { 0x05, KEY_5}, - { 0x06, KEY_6}, - - { 0x0c, KEY_7}, - { 0x0d, KEY_8}, - { 0x0a, KEY_9}, - - { 0x11, KEY_0}, - - { 0x09, KEY_CHANNELUP}, - { 0x07, KEY_CHANNELDOWN}, - - { 0x0e, KEY_VOLUMEUP}, - { 0x13, KEY_VOLUMEDOWN}, - - { 0x10, KEY_HOME}, - { 0x12, KEY_ENTER}, - - { 0x14, KEY_RECORD}, - { 0x15, KEY_STOP}, - { 0x16, KEY_PLAY}, - { 0x17, KEY_MUTE}, - - { 0x18, KEY_UP}, - { 0x19, KEY_DOWN}, - { 0x1a, KEY_LEFT}, - { 0x1b, KEY_RIGHT}, - - { 0x1c, KEY_RED}, - { 0x1d, KEY_GREEN}, - { 0x1e, KEY_YELLOW}, - { 0x1f, KEY_BLUE}, -}; -struct ir_scancode_table ir_codes_kaiomy_table = { - .scan = ir_codes_kaiomy, - .size = ARRAY_SIZE(ir_codes_kaiomy), -}; -EXPORT_SYMBOL_GPL(ir_codes_kaiomy_table); - -static struct ir_scancode ir_codes_avermedia_a16d[] = { - { 0x20, KEY_LIST}, - { 0x00, KEY_POWER}, - { 0x28, KEY_1}, - { 0x18, KEY_2}, - { 0x38, KEY_3}, - { 0x24, KEY_4}, - { 0x14, KEY_5}, - { 0x34, KEY_6}, - { 0x2c, KEY_7}, - { 0x1c, KEY_8}, - { 0x3c, KEY_9}, - { 0x12, KEY_SUBTITLE}, - { 0x22, KEY_0}, - { 0x32, KEY_REWIND}, - { 0x3a, KEY_SHUFFLE}, - { 0x02, KEY_PRINT}, - { 0x11, KEY_CHANNELDOWN}, - { 0x31, KEY_CHANNELUP}, - { 0x0c, KEY_ZOOM}, - { 0x1e, KEY_VOLUMEDOWN}, - { 0x3e, KEY_VOLUMEUP}, - { 0x0a, KEY_MUTE}, - { 0x04, KEY_AUDIO}, - { 0x26, KEY_RECORD}, - { 0x06, KEY_PLAY}, - { 0x36, KEY_STOP}, - { 0x16, KEY_PAUSE}, - { 0x2e, KEY_REWIND}, - { 0x0e, KEY_FASTFORWARD}, - { 0x30, KEY_TEXT}, - { 0x21, KEY_GREEN}, - { 0x01, KEY_BLUE}, - { 0x08, KEY_EPG}, - { 0x2a, KEY_MENU}, -}; -struct ir_scancode_table ir_codes_avermedia_a16d_table = { - .scan = ir_codes_avermedia_a16d, - .size = ARRAY_SIZE(ir_codes_avermedia_a16d), -}; -EXPORT_SYMBOL_GPL(ir_codes_avermedia_a16d_table); - -/* Encore ENLTV-FM v5.3 - Mauro Carvalho Chehab - */ -static struct ir_scancode ir_codes_encore_enltv_fm53[] = { - { 0x10, KEY_POWER2}, - { 0x06, KEY_MUTE}, - - { 0x09, KEY_1}, - { 0x1d, KEY_2}, - { 0x1f, KEY_3}, - { 0x19, KEY_4}, - { 0x1b, KEY_5}, - { 0x11, KEY_6}, - { 0x17, KEY_7}, - { 0x12, KEY_8}, - { 0x16, KEY_9}, - { 0x48, KEY_0}, - - { 0x04, KEY_LIST}, /* -/-- */ - { 0x40, KEY_LAST}, /* recall */ - - { 0x02, KEY_MODE}, /* TV/AV */ - { 0x05, KEY_CAMERA}, /* SNAPSHOT */ - - { 0x4c, KEY_CHANNELUP}, /* UP */ - { 0x00, KEY_CHANNELDOWN}, /* DOWN */ - { 0x0d, KEY_VOLUMEUP}, /* RIGHT */ - { 0x15, KEY_VOLUMEDOWN}, /* LEFT */ - { 0x49, KEY_ENTER}, /* OK */ - - { 0x54, KEY_RECORD}, - { 0x4d, KEY_PLAY}, /* pause */ - - { 0x1e, KEY_MENU}, /* video setting */ - { 0x0e, KEY_RIGHT}, /* <- */ - { 0x1a, KEY_LEFT}, /* -> */ - - { 0x0a, KEY_CLEAR}, /* video default */ - { 0x0c, KEY_ZOOM}, /* hide pannel */ - { 0x47, KEY_SLEEP}, /* shutdown */ -}; -struct ir_scancode_table ir_codes_encore_enltv_fm53_table = { - .scan = ir_codes_encore_enltv_fm53, - .size = ARRAY_SIZE(ir_codes_encore_enltv_fm53), -}; -EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_fm53_table); - -/* Zogis Real Audio 220 - 32 keys IR */ -static struct ir_scancode ir_codes_real_audio_220_32_keys[] = { - { 0x1c, KEY_RADIO}, - { 0x12, KEY_POWER2}, - - { 0x01, KEY_1}, - { 0x02, KEY_2}, - { 0x03, KEY_3}, - { 0x04, KEY_4}, - { 0x05, KEY_5}, - { 0x06, KEY_6}, - { 0x07, KEY_7}, - { 0x08, KEY_8}, - { 0x09, KEY_9}, - { 0x00, KEY_0}, - - { 0x0c, KEY_VOLUMEUP}, - { 0x18, KEY_VOLUMEDOWN}, - { 0x0b, KEY_CHANNELUP}, - { 0x15, KEY_CHANNELDOWN}, - { 0x16, KEY_ENTER}, - - { 0x11, KEY_LIST}, /* Source */ - { 0x0d, KEY_AUDIO}, /* stereo */ - - { 0x0f, KEY_PREVIOUS}, /* Prev */ - { 0x1b, KEY_TIME}, /* Timeshift */ - { 0x1a, KEY_NEXT}, /* Next */ - - { 0x0e, KEY_STOP}, - { 0x1f, KEY_PLAY}, - { 0x1e, KEY_PLAYPAUSE}, /* Pause */ - - { 0x1d, KEY_RECORD}, - { 0x13, KEY_MUTE}, - { 0x19, KEY_CAMERA}, /* Snapshot */ - -}; -struct ir_scancode_table ir_codes_real_audio_220_32_keys_table = { - .scan = ir_codes_real_audio_220_32_keys, - .size = ARRAY_SIZE(ir_codes_real_audio_220_32_keys), -}; -EXPORT_SYMBOL_GPL(ir_codes_real_audio_220_32_keys_table); - -/* ATI TV Wonder HD 600 USB - Devin Heitmueller - */ -static struct ir_scancode ir_codes_ati_tv_wonder_hd_600[] = { - { 0x00, KEY_RECORD}, /* Row 1 */ - { 0x01, KEY_PLAYPAUSE}, - { 0x02, KEY_STOP}, - { 0x03, KEY_POWER}, - { 0x04, KEY_PREVIOUS}, /* Row 2 */ - { 0x05, KEY_REWIND}, - { 0x06, KEY_FORWARD}, - { 0x07, KEY_NEXT}, - { 0x08, KEY_EPG}, /* Row 3 */ - { 0x09, KEY_HOME}, - { 0x0a, KEY_MENU}, - { 0x0b, KEY_CHANNELUP}, - { 0x0c, KEY_BACK}, /* Row 4 */ - { 0x0d, KEY_UP}, - { 0x0e, KEY_INFO}, - { 0x0f, KEY_CHANNELDOWN}, - { 0x10, KEY_LEFT}, /* Row 5 */ - { 0x11, KEY_SELECT}, - { 0x12, KEY_RIGHT}, - { 0x13, KEY_VOLUMEUP}, - { 0x14, KEY_LAST}, /* Row 6 */ - { 0x15, KEY_DOWN}, - { 0x16, KEY_MUTE}, - { 0x17, KEY_VOLUMEDOWN}, -}; -struct ir_scancode_table ir_codes_ati_tv_wonder_hd_600_table = { - .scan = ir_codes_ati_tv_wonder_hd_600, - .size = ARRAY_SIZE(ir_codes_ati_tv_wonder_hd_600), -}; -EXPORT_SYMBOL_GPL(ir_codes_ati_tv_wonder_hd_600_table); - -/* DVBWorld remotes - Igor M. Liplianin - */ -static struct ir_scancode ir_codes_dm1105_nec[] = { - { 0x0a, KEY_POWER2}, /* power */ - { 0x0c, KEY_MUTE}, /* mute */ - { 0x11, KEY_1}, - { 0x12, KEY_2}, - { 0x13, KEY_3}, - { 0x14, KEY_4}, - { 0x15, KEY_5}, - { 0x16, KEY_6}, - { 0x17, KEY_7}, - { 0x18, KEY_8}, - { 0x19, KEY_9}, - { 0x10, KEY_0}, - { 0x1c, KEY_CHANNELUP}, /* ch+ */ - { 0x0f, KEY_CHANNELDOWN}, /* ch- */ - { 0x1a, KEY_VOLUMEUP}, /* vol+ */ - { 0x0e, KEY_VOLUMEDOWN}, /* vol- */ - { 0x04, KEY_RECORD}, /* rec */ - { 0x09, KEY_CHANNEL}, /* fav */ - { 0x08, KEY_BACKSPACE}, /* rewind */ - { 0x07, KEY_FASTFORWARD}, /* fast */ - { 0x0b, KEY_PAUSE}, /* pause */ - { 0x02, KEY_ESC}, /* cancel */ - { 0x03, KEY_TAB}, /* tab */ - { 0x00, KEY_UP}, /* up */ - { 0x1f, KEY_ENTER}, /* ok */ - { 0x01, KEY_DOWN}, /* down */ - { 0x05, KEY_RECORD}, /* cap */ - { 0x06, KEY_STOP}, /* stop */ - { 0x40, KEY_ZOOM}, /* full */ - { 0x1e, KEY_TV}, /* tvmode */ - { 0x1b, KEY_B}, /* recall */ -}; -struct ir_scancode_table ir_codes_dm1105_nec_table = { - .scan = ir_codes_dm1105_nec, - .size = ARRAY_SIZE(ir_codes_dm1105_nec), -}; -EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec_table); - -static struct ir_scancode ir_codes_tevii_nec[] = { - { 0x0a, KEY_POWER2}, - { 0x0c, KEY_MUTE}, - { 0x11, KEY_1}, - { 0x12, KEY_2}, - { 0x13, KEY_3}, - { 0x14, KEY_4}, - { 0x15, KEY_5}, - { 0x16, KEY_6}, - { 0x17, KEY_7}, - { 0x18, KEY_8}, - { 0x19, KEY_9}, - { 0x10, KEY_0}, - { 0x1c, KEY_MENU}, - { 0x0f, KEY_VOLUMEDOWN}, - { 0x1a, KEY_LAST}, - { 0x0e, KEY_OPEN}, - { 0x04, KEY_RECORD}, - { 0x09, KEY_VOLUMEUP}, - { 0x08, KEY_CHANNELUP}, - { 0x07, KEY_PVR}, - { 0x0b, KEY_TIME}, - { 0x02, KEY_RIGHT}, - { 0x03, KEY_LEFT}, - { 0x00, KEY_UP}, - { 0x1f, KEY_OK}, - { 0x01, KEY_DOWN}, - { 0x05, KEY_TUNER}, - { 0x06, KEY_CHANNELDOWN}, - { 0x40, KEY_PLAYPAUSE}, - { 0x1e, KEY_REWIND}, - { 0x1b, KEY_FAVORITES}, - { 0x1d, KEY_BACK}, - { 0x4d, KEY_FASTFORWARD}, - { 0x44, KEY_EPG}, - { 0x4c, KEY_INFO}, - { 0x41, KEY_AB}, - { 0x43, KEY_AUDIO}, - { 0x45, KEY_SUBTITLE}, - { 0x4a, KEY_LIST}, - { 0x46, KEY_F1}, - { 0x47, KEY_F2}, - { 0x5e, KEY_F3}, - { 0x5c, KEY_F4}, - { 0x52, KEY_F5}, - { 0x5a, KEY_F6}, - { 0x56, KEY_MODE}, - { 0x58, KEY_SWITCHVIDEOMODE}, -}; -struct ir_scancode_table ir_codes_tevii_nec_table = { - .scan = ir_codes_tevii_nec, - .size = ARRAY_SIZE(ir_codes_tevii_nec), -}; -EXPORT_SYMBOL_GPL(ir_codes_tevii_nec_table); - -static struct ir_scancode ir_codes_tbs_nec[] = { - { 0x04, KEY_POWER2}, /*power*/ - { 0x14, KEY_MUTE}, /*mute*/ - { 0x07, KEY_1}, - { 0x06, KEY_2}, - { 0x05, KEY_3}, - { 0x0b, KEY_4}, - { 0x0a, KEY_5}, - { 0x09, KEY_6}, - { 0x0f, KEY_7}, - { 0x0e, KEY_8}, - { 0x0d, KEY_9}, - { 0x12, KEY_0}, - { 0x16, KEY_CHANNELUP}, /*ch+*/ - { 0x11, KEY_CHANNELDOWN},/*ch-*/ - { 0x13, KEY_VOLUMEUP}, /*vol+*/ - { 0x0c, KEY_VOLUMEDOWN},/*vol-*/ - { 0x03, KEY_RECORD}, /*rec*/ - { 0x18, KEY_PAUSE}, /*pause*/ - { 0x19, KEY_OK}, /*ok*/ - { 0x1a, KEY_CAMERA}, /* snapshot */ - { 0x01, KEY_UP}, - { 0x10, KEY_LEFT}, - { 0x02, KEY_RIGHT}, - { 0x08, KEY_DOWN}, - { 0x15, KEY_FAVORITES}, - { 0x17, KEY_SUBTITLE}, - { 0x1d, KEY_ZOOM}, - { 0x1f, KEY_EXIT}, - { 0x1e, KEY_MENU}, - { 0x1c, KEY_EPG}, - { 0x00, KEY_PREVIOUS}, - { 0x1b, KEY_MODE}, -}; -struct ir_scancode_table ir_codes_tbs_nec_table = { - .scan = ir_codes_tbs_nec, - .size = ARRAY_SIZE(ir_codes_tbs_nec), -}; -EXPORT_SYMBOL_GPL(ir_codes_tbs_nec_table); - -/* Terratec Cinergy Hybrid T USB XS - Devin Heitmueller - */ -static struct ir_scancode ir_codes_terratec_cinergy_xs[] = { - { 0x41, KEY_HOME}, - { 0x01, KEY_POWER}, - { 0x42, KEY_MENU}, - { 0x02, KEY_1}, - { 0x03, KEY_2}, - { 0x04, KEY_3}, - { 0x43, KEY_SUBTITLE}, - { 0x05, KEY_4}, - { 0x06, KEY_5}, - { 0x07, KEY_6}, - { 0x44, KEY_TEXT}, - { 0x08, KEY_7}, - { 0x09, KEY_8}, - { 0x0a, KEY_9}, - { 0x45, KEY_DELETE}, - { 0x0b, KEY_TUNER}, - { 0x0c, KEY_0}, - { 0x0d, KEY_MODE}, - { 0x46, KEY_TV}, - { 0x47, KEY_DVD}, - { 0x49, KEY_VIDEO}, - { 0x4b, KEY_AUX}, - { 0x10, KEY_UP}, - { 0x11, KEY_LEFT}, - { 0x12, KEY_OK}, - { 0x13, KEY_RIGHT}, - { 0x14, KEY_DOWN}, - { 0x0f, KEY_EPG}, - { 0x16, KEY_INFO}, - { 0x4d, KEY_BACKSPACE}, - { 0x1c, KEY_VOLUMEUP}, - { 0x4c, KEY_PLAY}, - { 0x1b, KEY_CHANNELUP}, - { 0x1e, KEY_VOLUMEDOWN}, - { 0x1d, KEY_MUTE}, - { 0x1f, KEY_CHANNELDOWN}, - { 0x17, KEY_RED}, - { 0x18, KEY_GREEN}, - { 0x19, KEY_YELLOW}, - { 0x1a, KEY_BLUE}, - { 0x58, KEY_RECORD}, - { 0x48, KEY_STOP}, - { 0x40, KEY_PAUSE}, - { 0x54, KEY_LAST}, - { 0x4e, KEY_REWIND}, - { 0x4f, KEY_FASTFORWARD}, - { 0x5c, KEY_NEXT}, -}; -struct ir_scancode_table ir_codes_terratec_cinergy_xs_table = { - .scan = ir_codes_terratec_cinergy_xs, - .size = ARRAY_SIZE(ir_codes_terratec_cinergy_xs), -}; -EXPORT_SYMBOL_GPL(ir_codes_terratec_cinergy_xs_table); - -/* EVGA inDtube - Devin Heitmueller - */ -static struct ir_scancode ir_codes_evga_indtube[] = { - { 0x12, KEY_POWER}, - { 0x02, KEY_MODE}, /* TV */ - { 0x14, KEY_MUTE}, - { 0x1a, KEY_CHANNELUP}, - { 0x16, KEY_TV2}, /* PIP */ - { 0x1d, KEY_VOLUMEUP}, - { 0x05, KEY_CHANNELDOWN}, - { 0x0f, KEY_PLAYPAUSE}, - { 0x19, KEY_VOLUMEDOWN}, - { 0x1c, KEY_REWIND}, - { 0x0d, KEY_RECORD}, - { 0x18, KEY_FORWARD}, - { 0x1e, KEY_PREVIOUS}, - { 0x1b, KEY_STOP}, - { 0x1f, KEY_NEXT}, - { 0x13, KEY_CAMERA}, -}; -struct ir_scancode_table ir_codes_evga_indtube_table = { - .scan = ir_codes_evga_indtube, - .size = ARRAY_SIZE(ir_codes_evga_indtube), -}; -EXPORT_SYMBOL_GPL(ir_codes_evga_indtube_table); - -static struct ir_scancode ir_codes_videomate_s350[] = { - { 0x00, KEY_TV}, - { 0x01, KEY_DVD}, - { 0x04, KEY_RECORD}, - { 0x05, KEY_VIDEO}, /* TV/Video */ - { 0x07, KEY_STOP}, - { 0x08, KEY_PLAYPAUSE}, - { 0x0a, KEY_REWIND}, - { 0x0f, KEY_FASTFORWARD}, - { 0x10, KEY_CHANNELUP}, - { 0x12, KEY_VOLUMEUP}, - { 0x13, KEY_CHANNELDOWN}, - { 0x14, KEY_MUTE}, - { 0x15, KEY_VOLUMEDOWN}, - { 0x16, KEY_1}, - { 0x17, KEY_2}, - { 0x18, KEY_3}, - { 0x19, KEY_4}, - { 0x1a, KEY_5}, - { 0x1b, KEY_6}, - { 0x1c, KEY_7}, - { 0x1d, KEY_8}, - { 0x1e, KEY_9}, - { 0x1f, KEY_0}, - { 0x21, KEY_SLEEP}, - { 0x24, KEY_ZOOM}, - { 0x25, KEY_LAST}, /* Recall */ - { 0x26, KEY_SUBTITLE}, /* CC */ - { 0x27, KEY_LANGUAGE}, /* MTS */ - { 0x29, KEY_CHANNEL}, /* SURF */ - { 0x2b, KEY_A}, - { 0x2c, KEY_B}, - { 0x2f, KEY_CAMERA}, /* Snapshot */ - { 0x23, KEY_RADIO}, - { 0x02, KEY_PREVIOUSSONG}, - { 0x06, KEY_NEXTSONG}, - { 0x03, KEY_EPG}, - { 0x09, KEY_SETUP}, - { 0x22, KEY_BACKSPACE}, - { 0x0c, KEY_UP}, - { 0x0e, KEY_DOWN}, - { 0x0b, KEY_LEFT}, - { 0x0d, KEY_RIGHT}, - { 0x11, KEY_ENTER}, - { 0x20, KEY_TEXT}, -}; -struct ir_scancode_table ir_codes_videomate_s350_table = { - .scan = ir_codes_videomate_s350, - .size = ARRAY_SIZE(ir_codes_videomate_s350), -}; -EXPORT_SYMBOL_GPL(ir_codes_videomate_s350_table); - -/* GADMEI UTV330+ RM008Z remote - Shine Liu - */ -static struct ir_scancode ir_codes_gadmei_rm008z[] = { - { 0x14, KEY_POWER2}, /* POWER OFF */ - { 0x0c, KEY_MUTE}, /* MUTE */ - - { 0x18, KEY_TV}, /* TV */ - { 0x0e, KEY_VIDEO}, /* AV */ - { 0x0b, KEY_AUDIO}, /* SV */ - { 0x0f, KEY_RADIO}, /* FM */ - - { 0x00, KEY_1}, - { 0x01, KEY_2}, - { 0x02, KEY_3}, - { 0x03, KEY_4}, - { 0x04, KEY_5}, - { 0x05, KEY_6}, - { 0x06, KEY_7}, - { 0x07, KEY_8}, - { 0x08, KEY_9}, - { 0x09, KEY_0}, - { 0x0a, KEY_INFO}, /* OSD */ - { 0x1c, KEY_BACKSPACE}, /* LAST */ - - { 0x0d, KEY_PLAY}, /* PLAY */ - { 0x1e, KEY_CAMERA}, /* SNAPSHOT */ - { 0x1a, KEY_RECORD}, /* RECORD */ - { 0x17, KEY_STOP}, /* STOP */ - - { 0x1f, KEY_UP}, /* UP */ - { 0x44, KEY_DOWN}, /* DOWN */ - { 0x46, KEY_TAB}, /* BACK */ - { 0x4a, KEY_ZOOM}, /* FULLSECREEN */ - - { 0x10, KEY_VOLUMEUP}, /* VOLUMEUP */ - { 0x11, KEY_VOLUMEDOWN}, /* VOLUMEDOWN */ - { 0x12, KEY_CHANNELUP}, /* CHANNELUP */ - { 0x13, KEY_CHANNELDOWN}, /* CHANNELDOWN */ - { 0x15, KEY_ENTER}, /* OK */ -}; -struct ir_scancode_table ir_codes_gadmei_rm008z_table = { - .scan = ir_codes_gadmei_rm008z, - .size = ARRAY_SIZE(ir_codes_gadmei_rm008z), -}; -EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table); - -/************************************************************* - * COMPLETE SCANCODE TABLES - * Instead of just a partial scancode, the tables bellow - * contains the complete scancode and the receiver protocol - *************************************************************/ - -/* - * Hauppauge:the newer, gray remotes (seems there are multiple - * slightly different versions), shipped with cx88+ivtv cards. - * - * This table contains the complete RC5 code, instead of just the data part - */ -static struct ir_scancode ir_codes_rc5_hauppauge_new[] = { - /* Keys 0 to 9 */ - { 0x1e00, KEY_0 }, - { 0x1e01, KEY_1 }, - { 0x1e02, KEY_2 }, - { 0x1e03, KEY_3 }, - { 0x1e04, KEY_4 }, - { 0x1e05, KEY_5 }, - { 0x1e06, KEY_6 }, - { 0x1e07, KEY_7 }, - { 0x1e08, KEY_8 }, - { 0x1e09, KEY_9 }, - - { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */ - { 0x1e0b, KEY_RED }, /* red button */ - { 0x1e0c, KEY_RADIO }, - { 0x1e0d, KEY_MENU }, - { 0x1e0e, KEY_SUBTITLE }, /* also the # key */ - { 0x1e0f, KEY_MUTE }, - { 0x1e10, KEY_VOLUMEUP }, - { 0x1e11, KEY_VOLUMEDOWN }, - { 0x1e12, KEY_PREVIOUS }, /* previous channel */ - { 0x1e14, KEY_UP }, - { 0x1e15, KEY_DOWN }, - { 0x1e16, KEY_LEFT }, - { 0x1e17, KEY_RIGHT }, - { 0x1e18, KEY_VIDEO }, /* Videos */ - { 0x1e19, KEY_AUDIO }, /* Music */ - /* 0x1e1a: Pictures - presume this means - "Multimedia Home Platform" - - no "PICTURES" key in input.h - */ - { 0x1e1a, KEY_MHP }, - - { 0x1e1b, KEY_EPG }, /* Guide */ - { 0x1e1c, KEY_TV }, - { 0x1e1e, KEY_NEXTSONG }, /* skip >| */ - { 0x1e1f, KEY_EXIT }, /* back/exit */ - { 0x1e20, KEY_CHANNELUP }, /* channel / program + */ - { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */ - { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */ - { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */ - { 0x1e25, KEY_ENTER }, /* OK */ - { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */ - { 0x1e29, KEY_BLUE }, /* blue key */ - { 0x1e2e, KEY_GREEN }, /* green button */ - { 0x1e30, KEY_PAUSE }, /* pause */ - { 0x1e32, KEY_REWIND }, /* backward << */ - { 0x1e34, KEY_FASTFORWARD }, /* forward >> */ - { 0x1e35, KEY_PLAY }, - { 0x1e36, KEY_STOP }, - { 0x1e37, KEY_RECORD }, /* recording */ - { 0x1e38, KEY_YELLOW }, /* yellow key */ - { 0x1e3b, KEY_SELECT }, /* top right button */ - { 0x1e3c, KEY_ZOOM }, /* full */ - { 0x1e3d, KEY_POWER }, /* system power (green button) */ -}; - -struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = { - .scan = ir_codes_rc5_hauppauge_new, - .size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new), - .ir_type = IR_TYPE_RC5, -}; -EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table); - -/* Terratec Cinergy Hybrid T USB XS FM - Mauro Carvalho Chehab - */ -static struct ir_scancode ir_codes_nec_terratec_cinergy_xs[] = { - { 0x1441, KEY_HOME}, - { 0x1401, KEY_POWER2}, - - { 0x1442, KEY_MENU}, /* DVD menu */ - { 0x1443, KEY_SUBTITLE}, - { 0x1444, KEY_TEXT}, /* Teletext */ - { 0x1445, KEY_DELETE}, - - { 0x1402, KEY_1}, - { 0x1403, KEY_2}, - { 0x1404, KEY_3}, - { 0x1405, KEY_4}, - { 0x1406, KEY_5}, - { 0x1407, KEY_6}, - { 0x1408, KEY_7}, - { 0x1409, KEY_8}, - { 0x140a, KEY_9}, - { 0x140c, KEY_0}, - - { 0x140b, KEY_TUNER}, /* AV */ - { 0x140d, KEY_MODE}, /* A.B */ - - { 0x1446, KEY_TV}, - { 0x1447, KEY_DVD}, - { 0x1449, KEY_VIDEO}, - { 0x144a, KEY_RADIO}, /* Music */ - { 0x144b, KEY_CAMERA}, /* PIC */ - - { 0x1410, KEY_UP}, - { 0x1411, KEY_LEFT}, - { 0x1412, KEY_OK}, - { 0x1413, KEY_RIGHT}, - { 0x1414, KEY_DOWN}, - - { 0x140f, KEY_EPG}, - { 0x1416, KEY_INFO}, - { 0x144d, KEY_BACKSPACE}, - - { 0x141c, KEY_VOLUMEUP}, - { 0x141e, KEY_VOLUMEDOWN}, - - { 0x144c, KEY_PLAY}, - { 0x141d, KEY_MUTE}, - - { 0x141b, KEY_CHANNELUP}, - { 0x141f, KEY_CHANNELDOWN}, - - { 0x1417, KEY_RED}, - { 0x1418, KEY_GREEN}, - { 0x1419, KEY_YELLOW}, - { 0x141a, KEY_BLUE}, - - { 0x1458, KEY_RECORD}, - { 0x1448, KEY_STOP}, - { 0x1440, KEY_PAUSE}, - - { 0x1454, KEY_LAST}, - { 0x144e, KEY_REWIND}, - { 0x144f, KEY_FASTFORWARD}, - { 0x145c, KEY_NEXT}, -}; -struct ir_scancode_table ir_codes_nec_terratec_cinergy_xs_table = { - .scan = ir_codes_nec_terratec_cinergy_xs, - .size = ARRAY_SIZE(ir_codes_nec_terratec_cinergy_xs), - .ir_type = IR_TYPE_NEC, -}; -EXPORT_SYMBOL_GPL(ir_codes_nec_terratec_cinergy_xs_table); - diff --git a/drivers/media/common/ir-keytable.c b/drivers/media/common/ir-keytable.c deleted file mode 100644 index ceef0e82fb4..00000000000 --- a/drivers/media/common/ir-keytable.c +++ /dev/null @@ -1,432 +0,0 @@ -/* ir-register.c - handle IR scancode->keycode tables - * - * Copyright (C) 2009 by Mauro Carvalho Chehab - */ - -#include - -#include - -#define IR_TAB_MIN_SIZE 32 -#define IR_TAB_MAX_SIZE 1024 - -/** - * ir_seek_table() - returns the element order on the table - * @rc_tab: the ir_scancode_table with the keymap to be used - * @scancode: the scancode that we're seeking - * - * This routine is used by the input routines when a key is pressed at the - * IR. The scancode is received and needs to be converted into a keycode. - * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the - * corresponding keycode from the table. - */ -static int ir_seek_table(struct ir_scancode_table *rc_tab, u32 scancode) -{ - int rc; - unsigned long flags; - struct ir_scancode *keymap = rc_tab->scan; - - spin_lock_irqsave(&rc_tab->lock, flags); - - /* FIXME: replace it by a binary search */ - - for (rc = 0; rc < rc_tab->size; rc++) - if (keymap[rc].scancode == scancode) - goto exit; - - /* Not found */ - rc = -EINVAL; - -exit: - spin_unlock_irqrestore(&rc_tab->lock, flags); - return rc; -} - -/** - * ir_roundup_tablesize() - gets an optimum value for the table size - * @n_elems: minimum number of entries to store keycodes - * - * This routine is used to choose the keycode table size. - * - * In order to have some empty space for new keycodes, - * and knowing in advance that kmalloc allocates only power of two - * segments, it optimizes the allocated space to have some spare space - * for those new keycodes by using the maximum number of entries that - * will be effectively be allocated by kmalloc. - * In order to reduce the quantity of table resizes, it has a minimum - * table size of IR_TAB_MIN_SIZE. - */ -int ir_roundup_tablesize(int n_elems) -{ - size_t size; - - if (n_elems < IR_TAB_MIN_SIZE) - n_elems = IR_TAB_MIN_SIZE; - - /* - * As kmalloc only allocates sizes of power of two, get as - * much entries as possible for the allocated memory segment - */ - size = roundup_pow_of_two(n_elems * sizeof(struct ir_scancode)); - n_elems = size / sizeof(struct ir_scancode); - - return n_elems; -} - -/** - * ir_copy_table() - copies a keytable, discarding the unused entries - * @destin: destin table - * @origin: origin table - * - * Copies all entries where the keycode is not KEY_UNKNOWN/KEY_RESERVED - */ - -int ir_copy_table(struct ir_scancode_table *destin, - const struct ir_scancode_table *origin) -{ - int i, j = 0; - - for (i = 0; i < origin->size; i++) { - if (origin->scan[i].keycode == KEY_UNKNOWN || - origin->scan[i].keycode == KEY_RESERVED) - continue; - - memcpy(&destin->scan[j], &origin->scan[i], sizeof(struct ir_scancode)); - j++; - } - destin->size = j; - - IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", destin->size); - - return 0; -} - -/** - * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table - * @dev: the struct input_dev device descriptor - * @scancode: the desired scancode - * @keycode: the keycode to be retorned. - * - * This routine is used to handle evdev EVIOCGKEY ioctl. - * If the key is not found, returns -EINVAL, otherwise, returns 0. - */ -static int ir_getkeycode(struct input_dev *dev, - int scancode, int *keycode) -{ - int elem; - struct ir_scancode_table *rc_tab = input_get_drvdata(dev); - - elem = ir_seek_table(rc_tab, scancode); - if (elem >= 0) { - *keycode = rc_tab->scan[elem].keycode; - return 0; - } - - /* - * Scancode not found and table can't be expanded - */ - if (elem < 0 && rc_tab->size == IR_TAB_MAX_SIZE) - return -EINVAL; - - /* - * If is there extra space, returns KEY_RESERVED, - * otherwise, input core won't let ir_setkeycode to work - */ - *keycode = KEY_RESERVED; - return 0; -} - - -/** - * ir_is_resize_needed() - Check if the table needs rezise - * @table: keycode table that may need to resize - * @n_elems: minimum number of entries to store keycodes - * - * Considering that kmalloc uses power of two storage areas, this - * routine detects if the real alloced size will change. If not, it - * just returns without doing nothing. Otherwise, it will extend or - * reduce the table size to meet the new needs. - * - * It returns 0 if no resize is needed, 1 otherwise. - */ -static int ir_is_resize_needed(struct ir_scancode_table *table, int n_elems) -{ - int cur_size = ir_roundup_tablesize(table->size); - int new_size = ir_roundup_tablesize(n_elems); - - if (cur_size == new_size) - return 0; - - /* Resize is needed */ - return 1; -} - -/** - * ir_delete_key() - remove a keycode from the table - * @rc_tab: keycode table - * @elem: element to be removed - * - */ -static void ir_delete_key(struct ir_scancode_table *rc_tab, int elem) -{ - unsigned long flags = 0; - int newsize = rc_tab->size - 1; - int resize = ir_is_resize_needed(rc_tab, newsize); - struct ir_scancode *oldkeymap = rc_tab->scan; - struct ir_scancode *newkeymap; - - if (resize) { - newkeymap = kzalloc(ir_roundup_tablesize(newsize) * - sizeof(*newkeymap), GFP_ATOMIC); - - /* There's no memory for resize. Keep the old table */ - if (!newkeymap) - resize = 0; - } - - if (!resize) { - newkeymap = oldkeymap; - - /* We'll modify the live table. Lock it */ - spin_lock_irqsave(&rc_tab->lock, flags); - } - - /* - * Copy the elements before the one that will be deleted - * if (!resize), both oldkeymap and newkeymap points - * to the same place, so, there's no need to copy - */ - if (resize && elem > 0) - memcpy(newkeymap, oldkeymap, - elem * sizeof(*newkeymap)); - - /* - * Copy the other elements overwriting the element to be removed - * This operation applies to both resize and non-resize case - */ - if (elem < newsize) - memcpy(&newkeymap[elem], &oldkeymap[elem + 1], - (newsize - elem) * sizeof(*newkeymap)); - - if (resize) { - /* - * As the copy happened to a temporary table, only here - * it needs to lock while replacing the table pointers - * to use the new table - */ - spin_lock_irqsave(&rc_tab->lock, flags); - rc_tab->size = newsize; - rc_tab->scan = newkeymap; - spin_unlock_irqrestore(&rc_tab->lock, flags); - - /* Frees the old keytable */ - kfree(oldkeymap); - } else { - rc_tab->size = newsize; - spin_unlock_irqrestore(&rc_tab->lock, flags); - } -} - -/** - * ir_insert_key() - insert a keycode at the table - * @rc_tab: keycode table - * @scancode: the desired scancode - * @keycode: the keycode to be retorned. - * - */ -static int ir_insert_key(struct ir_scancode_table *rc_tab, - int scancode, int keycode) -{ - unsigned long flags; - int elem = rc_tab->size; - int newsize = rc_tab->size + 1; - int resize = ir_is_resize_needed(rc_tab, newsize); - struct ir_scancode *oldkeymap = rc_tab->scan; - struct ir_scancode *newkeymap; - - if (resize) { - newkeymap = kzalloc(ir_roundup_tablesize(newsize) * - sizeof(*newkeymap), GFP_ATOMIC); - if (!newkeymap) - return -ENOMEM; - - memcpy(newkeymap, oldkeymap, - rc_tab->size * sizeof(*newkeymap)); - } else - newkeymap = oldkeymap; - - /* Stores the new code at the table */ - IR_dprintk(1, "#%d: New scan 0x%04x with key 0x%04x\n", - rc_tab->size, scancode, keycode); - - spin_lock_irqsave(&rc_tab->lock, flags); - rc_tab->size = newsize; - if (resize) { - rc_tab->scan = newkeymap; - kfree(oldkeymap); - } - newkeymap[elem].scancode = scancode; - newkeymap[elem].keycode = keycode; - spin_unlock_irqrestore(&rc_tab->lock, flags); - - return 0; -} - -/** - * ir_setkeycode() - set a keycode at the evdev scancode ->keycode table - * @dev: the struct input_dev device descriptor - * @scancode: the desired scancode - * @keycode: the keycode to be retorned. - * - * This routine is used to handle evdev EVIOCSKEY ioctl. - * There's one caveat here: how can we increase the size of the table? - * If the key is not found, returns -EINVAL, otherwise, returns 0. - */ -static int ir_setkeycode(struct input_dev *dev, - int scancode, int keycode) -{ - int rc = 0; - struct ir_scancode_table *rc_tab = input_get_drvdata(dev); - struct ir_scancode *keymap = rc_tab->scan; - unsigned long flags; - - /* - * Handle keycode table deletions - * - * If userspace is adding a KEY_UNKNOWN or KEY_RESERVED, - * deal as a trial to remove an existing scancode attribution - * if table become too big, reduce it to save space - */ - if (keycode == KEY_UNKNOWN || keycode == KEY_RESERVED) { - rc = ir_seek_table(rc_tab, scancode); - if (rc < 0) - return 0; - - IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", rc, scancode); - clear_bit(keymap[rc].keycode, dev->keybit); - ir_delete_key(rc_tab, rc); - - return 0; - } - - /* - * Handle keycode replacements - * - * If the scancode exists, just replace by the new value - */ - rc = ir_seek_table(rc_tab, scancode); - if (rc >= 0) { - IR_dprintk(1, "#%d: Replacing scan 0x%04x with key 0x%04x\n", - rc, scancode, keycode); - - clear_bit(keymap[rc].keycode, dev->keybit); - - spin_lock_irqsave(&rc_tab->lock, flags); - keymap[rc].keycode = keycode; - spin_unlock_irqrestore(&rc_tab->lock, flags); - - set_bit(keycode, dev->keybit); - - return 0; - } - - /* - * Handle new scancode inserts - * - * reallocate table if needed and insert a new keycode - */ - - /* Avoid growing the table indefinitely */ - if (rc_tab->size + 1 > IR_TAB_MAX_SIZE) - return -EINVAL; - - rc = ir_insert_key(rc_tab, scancode, keycode); - if (rc < 0) - return rc; - set_bit(keycode, dev->keybit); - - return 0; -} - -/** - * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode - * @input_dev: the struct input_dev descriptor of the device - * @scancode: the scancode that we're seeking - * - * This routine is used by the input routines when a key is pressed at the - * IR. The scancode is received and needs to be converted into a keycode. - * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the - * corresponding keycode from the table. - */ -u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) -{ - struct ir_scancode_table *rc_tab = input_get_drvdata(dev); - struct ir_scancode *keymap = rc_tab->scan; - int elem; - - elem = ir_seek_table(rc_tab, scancode); - if (elem >= 0) { - IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", - dev->name, scancode, keymap[elem].keycode); - - return rc_tab->scan[elem].keycode; - } - - printk(KERN_INFO "%s: unknown key for scancode 0x%04x\n", - dev->name, scancode); - - /* Reports userspace that an unknown keycode were got */ - return KEY_RESERVED; -} - -/** - * ir_set_keycode_table() - sets the IR keycode table and add the handlers - * for keymap table get/set - * @input_dev: the struct input_dev descriptor of the device - * @rc_tab: the struct ir_scancode_table table of scancode/keymap - * - * This routine is used to initialize the input infrastructure to work with - * an IR. - * It should be called before registering the IR device. - */ -int ir_set_keycode_table(struct input_dev *input_dev, - struct ir_scancode_table *rc_tab) -{ - struct ir_scancode *keymap = rc_tab->scan; - int i; - - spin_lock_init(&rc_tab->lock); - - if (rc_tab->scan == NULL || !rc_tab->size) - return -EINVAL; - - /* set the bits for the keys */ - IR_dprintk(1, "key map size: %d\n", rc_tab->size); - for (i = 0; i < rc_tab->size; i++) { - IR_dprintk(1, "#%d: setting bit for keycode 0x%04x\n", - i, keymap[i].keycode); - set_bit(keymap[i].keycode, input_dev->keybit); - } - - input_dev->getkeycode = ir_getkeycode; - input_dev->setkeycode = ir_setkeycode; - input_set_drvdata(input_dev, rc_tab); - - return 0; -} - -void ir_input_free(struct input_dev *dev) -{ - struct ir_scancode_table *rc_tab = input_get_drvdata(dev); - - if (!rc_tab) - return; - - IR_dprintk(1, "Freed keycode table\n"); - - rc_tab->size = 0; - kfree(rc_tab->scan); - rc_tab->scan = NULL; -} -EXPORT_SYMBOL_GPL(ir_input_free); - diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 9dc74c93bf2..f63909d9c70 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -37,10 +37,6 @@ config VIDEO_BTCX depends on PCI tristate -config VIDEO_IR - tristate - depends on INPUT - config VIDEO_TVEEPROM tristate depends on I2C -- cgit v1.2.3-70-g09d2 From 446e4a64d2f6efddc63a47169ba3c8037b620307 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2009 08:34:07 -0300 Subject: V4L/DVB (13613): IR: create ir-core module Split the ir-common into two separate modules: - ir-core: it is the IR-independent functions; - ir-common: has the common part used by V4L drivers. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/IR/Kconfig | 7 ++++- drivers/media/IR/Makefile | 4 ++- drivers/media/IR/ir-functions.c | 3 --- drivers/media/IR/ir-keytable.c | 21 +++++++++++++-- include/media/ir-common.h | 39 +--------------------------- include/media/ir-core.h | 57 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 86 insertions(+), 45 deletions(-) create mode 100644 include/media/ir-core.h (limited to 'drivers/media') diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig index 5b4ac969a58..4dde7d180a3 100644 --- a/drivers/media/IR/Kconfig +++ b/drivers/media/IR/Kconfig @@ -1,4 +1,9 @@ -config VIDEO_IR +config IR_CORE tristate depends on INPUT default INPUT + +config VIDEO_IR + tristate + depends on IR_CORE + default IR_CORE diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile index 2781f430c6e..df5ddb4bbbf 100644 --- a/drivers/media/IR/Makefile +++ b/drivers/media/IR/Makefile @@ -1,3 +1,5 @@ -ir-common-objs := ir-functions.o ir-keymaps.o ir-keytable.o +ir-common-objs := ir-functions.o ir-keymaps.o +ir-core-objs := ir-keytable.o +obj-$(CONFIG_IR_CORE) += ir-core.o obj-$(CONFIG_VIDEO_IR) += ir-common.o diff --git a/drivers/media/IR/ir-functions.c b/drivers/media/IR/ir-functions.c index e616f624cea..2db22948a31 100644 --- a/drivers/media/IR/ir-functions.c +++ b/drivers/media/IR/ir-functions.c @@ -34,9 +34,6 @@ static int repeat = 1; module_param(repeat, int, 0444); MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)"); -int media_ir_debug; /* media_ir_debug level (0,1,2) */ -module_param_named(debug, media_ir_debug, int, 0644); - /* -------------------------------------------------------------------------- */ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index 99ed2deceef..20d642dbab4 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c @@ -1,6 +1,15 @@ /* ir-register.c - handle IR scancode->keycode tables * * Copyright (C) 2009 by Mauro Carvalho Chehab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #include @@ -10,7 +19,6 @@ #define IR_TAB_MIN_SIZE 32 #define IR_TAB_MAX_SIZE 1024 - /** * ir_seek_table() - returns the element order on the table * @rc_tab: the ir_scancode_table with the keymap to be used @@ -73,6 +81,7 @@ int ir_roundup_tablesize(int n_elems) return n_elems; } +EXPORT_SYMBOL_GPL(ir_roundup_tablesize); /** * ir_copy_table() - copies a keytable, discarding the unused entries @@ -101,6 +110,7 @@ int ir_copy_table(struct ir_scancode_table *destin, return 0; } +EXPORT_SYMBOL_GPL(ir_copy_table); /** * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table @@ -137,7 +147,6 @@ static int ir_getkeycode(struct input_dev *dev, return 0; } - /** * ir_is_resize_needed() - Check if the table needs rezise * @table: keycode table that may need to resize @@ -379,6 +388,7 @@ u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) /* Reports userspace that an unknown keycode were got */ return KEY_RESERVED; } +EXPORT_SYMBOL_GPL(ir_g_keycode_from_table); /** * ir_set_keycode_table() - sets the IR keycode table and add the handlers @@ -415,6 +425,7 @@ int ir_set_keycode_table(struct input_dev *input_dev, return 0; } +EXPORT_SYMBOL_GPL(ir_set_keycode_table); void ir_input_free(struct input_dev *dev) { @@ -431,3 +442,9 @@ void ir_input_free(struct input_dev *dev) } EXPORT_SYMBOL_GPL(ir_input_free); +int ir_core_debug; /* ir_debug level (0,1,2) */ +EXPORT_SYMBOL_GPL(ir_core_debug); +module_param_named(debug, ir_core_debug, int, 0644); + +MODULE_AUTHOR("Mauro Carvalho Chehab "); +MODULE_LICENSE("GPL"); diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 45bf5cf5945..18d300414fa 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -26,31 +26,7 @@ #include #include #include -#include - -extern int media_ir_debug; /* media_ir_debug level (0,1,2) */ -#define IR_dprintk(level, fmt, arg...) if (media_ir_debug >= level) \ - printk(KERN_DEBUG "%s: " fmt , __func__, ## arg) - -enum ir_type { - IR_TYPE_UNKNOWN = 0, - IR_TYPE_RC5 = 1, - IR_TYPE_PD = 2, /* Pulse distance encoded IR */ - IR_TYPE_NEC = 3, - IR_TYPE_OTHER = 99, -}; - -struct ir_scancode { - u16 scancode; - u32 keycode; -}; - -struct ir_scancode_table { - struct ir_scancode *scan; - int size; - enum ir_type ir_type; - spinlock_t lock; -}; +#include #define RC5_START(x) (((x)>>12)&3) #define RC5_TOGGLE(x) (((x)>>11)&1) @@ -123,19 +99,6 @@ u32 ir_rc5_decode(unsigned int code); void ir_rc5_timer_end(unsigned long data); void ir_rc5_timer_keyup(unsigned long data); -/* Routines from ir-keytable.c */ - -u32 ir_g_keycode_from_table(struct input_dev *input_dev, - u32 scancode); - -int ir_set_keycode_table(struct input_dev *input_dev, - struct ir_scancode_table *rc_tab); - -int ir_roundup_tablesize(int n_elems); -int ir_copy_table(struct ir_scancode_table *destin, - const struct ir_scancode_table *origin); -void ir_input_free(struct input_dev *input_dev); - /* scancode->keycode map tables from ir-keymaps.c */ extern struct ir_scancode_table ir_codes_empty_table; diff --git a/include/media/ir-core.h b/include/media/ir-core.h new file mode 100644 index 00000000000..825d04a4e77 --- /dev/null +++ b/include/media/ir-core.h @@ -0,0 +1,57 @@ +/* + * Remote Controller core header + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _IR_CORE +#define _IR_CORE + +#include +#include + +extern int ir_core_debug; +#define IR_dprintk(level, fmt, arg...) if (ir_core_debug >= level) \ + printk(KERN_DEBUG "%s: " fmt , __func__, ## arg) + +enum ir_type { + IR_TYPE_UNKNOWN = 0, + IR_TYPE_RC5 = 1, + IR_TYPE_PD = 2, /* Pulse distance encoded IR */ + IR_TYPE_NEC = 3, + IR_TYPE_OTHER = 99, +}; + +struct ir_scancode { + u16 scancode; + u32 keycode; +}; + +struct ir_scancode_table { + struct ir_scancode *scan; + int size; + enum ir_type ir_type; + spinlock_t lock; +}; + +/* Routines from ir-keytable.c */ + +u32 ir_g_keycode_from_table(struct input_dev *input_dev, + u32 scancode); + +int ir_set_keycode_table(struct input_dev *input_dev, + struct ir_scancode_table *rc_tab); + +int ir_roundup_tablesize(int n_elems); +int ir_copy_table(struct ir_scancode_table *destin, + const struct ir_scancode_table *origin); +void ir_input_free(struct input_dev *input_dev); + +#endif -- cgit v1.2.3-70-g09d2 From 865fbf20bed00d456556ecd4b4c9dadc45cba759 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2009 09:29:57 -0300 Subject: V4L/DVB (13614): dib0090: Fix compilation when module is not selected Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/dib0090.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/dib0090.h b/drivers/media/dvb/frontends/dib0090.h index 83cc8ae9ba3..24ab5bf69d5 100644 --- a/drivers/media/dvb/frontends/dib0090.h +++ b/drivers/media/dvb/frontends/dib0090.h @@ -100,11 +100,6 @@ static inline int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_ return -ENODEV; } -static inline num frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); -return CT_SHUTDOWN,} - static inline void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); -- cgit v1.2.3-70-g09d2 From 75543cce0c1f46be495b981d8d3eda0882721d07 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2009 09:44:23 -0300 Subject: V4L/DVB (13615): ir-core: create ir_input_register Move non-V4L specific stuff from ir-functions ir_input_init() into a new function to register ir devices: ir_input_register(). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/IR/ir-functions.c | 17 ++------------ drivers/media/IR/ir-keytable.c | 51 +++++++++++++++++++++++++++++++---------- include/media/ir-common.h | 2 -- include/media/ir-core.h | 9 ++++++-- 4 files changed, 48 insertions(+), 31 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/IR/ir-functions.c b/drivers/media/IR/ir-functions.c index 2db22948a31..7401a798971 100644 --- a/drivers/media/IR/ir-functions.c +++ b/drivers/media/IR/ir-functions.c @@ -56,24 +56,11 @@ int ir_input_init(struct input_dev *dev, struct ir_input_state *ir, { ir->ir_type = ir_type; - ir->keytable.size = ir_roundup_tablesize(ir_codes->size); - ir->keytable.scan = kzalloc(ir->keytable.size * - sizeof(struct ir_scancode), GFP_KERNEL); - if (!ir->keytable.scan) - return -ENOMEM; - - IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n", - ir->keytable.size, - ir->keytable.size * sizeof(ir->keytable.scan)); - - ir_copy_table(&ir->keytable, ir_codes); - ir_set_keycode_table(dev, &ir->keytable); - - clear_bit(0, dev->keybit); - set_bit(EV_KEY, dev->evbit); if (repeat) set_bit(EV_REP, dev->evbit); + ir_input_register(dev, ir_codes); + return 0; } EXPORT_SYMBOL_GPL(ir_input_init); diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index 20d642dbab4..ddb8a0f8af4 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c @@ -125,7 +125,8 @@ static int ir_getkeycode(struct input_dev *dev, int scancode, int *keycode) { int elem; - struct ir_scancode_table *rc_tab = input_get_drvdata(dev); + struct ir_input_dev *ir_dev = input_get_drvdata(dev); + struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; elem = ir_seek_table(rc_tab, scancode); if (elem >= 0) { @@ -296,7 +297,8 @@ static int ir_setkeycode(struct input_dev *dev, int scancode, int keycode) { int rc = 0; - struct ir_scancode_table *rc_tab = input_get_drvdata(dev); + struct ir_input_dev *ir_dev = input_get_drvdata(dev); + struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; struct ir_scancode *keymap = rc_tab->scan; unsigned long flags; @@ -370,7 +372,8 @@ static int ir_setkeycode(struct input_dev *dev, */ u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) { - struct ir_scancode_table *rc_tab = input_get_drvdata(dev); + struct ir_input_dev *ir_dev = input_get_drvdata(dev); + struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; struct ir_scancode *keymap = rc_tab->scan; int elem; @@ -391,7 +394,7 @@ u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) EXPORT_SYMBOL_GPL(ir_g_keycode_from_table); /** - * ir_set_keycode_table() - sets the IR keycode table and add the handlers + * ir_input_register() - sets the IR keycode table and add the handlers * for keymap table get/set * @input_dev: the struct input_dev descriptor of the device * @rc_tab: the struct ir_scancode_table table of scancode/keymap @@ -400,17 +403,34 @@ EXPORT_SYMBOL_GPL(ir_g_keycode_from_table); * an IR. * It should be called before registering the IR device. */ -int ir_set_keycode_table(struct input_dev *input_dev, - struct ir_scancode_table *rc_tab) +int ir_input_register(struct input_dev *input_dev, + struct ir_scancode_table *rc_tab) { - struct ir_scancode *keymap = rc_tab->scan; + struct ir_input_dev *ir_dev; + struct ir_scancode *keymap = rc_tab->scan; int i; - spin_lock_init(&rc_tab->lock); - if (rc_tab->scan == NULL || !rc_tab->size) return -EINVAL; + ir_dev = kzalloc(sizeof(*ir_dev), GFP_KERNEL); + if (!ir_dev) + return -ENOMEM; + + spin_lock_init(&rc_tab->lock); + + ir_dev->rc_tab.size = ir_roundup_tablesize(rc_tab->size); + ir_dev->rc_tab.scan = kzalloc(ir_dev->rc_tab.size * + sizeof(struct ir_scancode), GFP_KERNEL); + if (!ir_dev->rc_tab.scan) + return -ENOMEM; + + IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n", + ir_dev->rc_tab.size, + ir_dev->rc_tab.size * sizeof(ir_dev->rc_tab.scan)); + + ir_copy_table(&ir_dev->rc_tab, rc_tab); + /* set the bits for the keys */ IR_dprintk(1, "key map size: %d\n", rc_tab->size); for (i = 0; i < rc_tab->size; i++) { @@ -418,18 +438,22 @@ int ir_set_keycode_table(struct input_dev *input_dev, i, keymap[i].keycode); set_bit(keymap[i].keycode, input_dev->keybit); } + clear_bit(0, input_dev->keybit); + + set_bit(EV_KEY, input_dev->evbit); input_dev->getkeycode = ir_getkeycode; input_dev->setkeycode = ir_setkeycode; - input_set_drvdata(input_dev, rc_tab); + input_set_drvdata(input_dev, ir_dev); return 0; } -EXPORT_SYMBOL_GPL(ir_set_keycode_table); +EXPORT_SYMBOL_GPL(ir_input_register); void ir_input_free(struct input_dev *dev) { - struct ir_scancode_table *rc_tab = input_get_drvdata(dev); + struct ir_input_dev *ir_dev = input_get_drvdata(dev); + struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; if (!rc_tab) return; @@ -439,6 +463,9 @@ void ir_input_free(struct input_dev *dev) rc_tab->size = 0; kfree(rc_tab->scan); rc_tab->scan = NULL; + + kfree(ir_dev); + input_set_drvdata(dev, NULL); } EXPORT_SYMBOL_GPL(ir_input_free); diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 18d300414fa..ac8ced6bf3e 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -37,8 +37,6 @@ struct ir_input_state { /* configuration */ int ir_type; - struct ir_scancode_table keytable; - /* key info */ u32 ir_key; /* ir scancode */ u32 keycode; /* linux key code */ diff --git a/include/media/ir-core.h b/include/media/ir-core.h index 825d04a4e77..ea76c199b67 100644 --- a/include/media/ir-core.h +++ b/include/media/ir-core.h @@ -41,6 +41,11 @@ struct ir_scancode_table { spinlock_t lock; }; +struct ir_input_dev { + struct input_dev *dev; + struct ir_scancode_table rc_tab; +}; + /* Routines from ir-keytable.c */ u32 ir_g_keycode_from_table(struct input_dev *input_dev, @@ -50,8 +55,8 @@ int ir_set_keycode_table(struct input_dev *input_dev, struct ir_scancode_table *rc_tab); int ir_roundup_tablesize(int n_elems); -int ir_copy_table(struct ir_scancode_table *destin, - const struct ir_scancode_table *origin); +int ir_input_register(struct input_dev *dev, + struct ir_scancode_table *ir_codes); void ir_input_free(struct input_dev *input_dev); #endif -- cgit v1.2.3-70-g09d2 From 38ef6aa884e3fd389f7d444b8dd36c16832e36b4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2009 09:47:42 -0300 Subject: V4L/DVB (13616): IR: rename ir_input_free as ir_input_unregister Now, ir_input_free does more than just freeing the keytab. Better to rename it as ir_input_unregister. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/IR/ir-keytable.c | 4 ++-- drivers/media/dvb/dm1105/dm1105.c | 4 ++-- drivers/media/dvb/ttpci/budget-ci.c | 4 ++-- drivers/media/video/bt8xx/bttv-input.c | 4 ++-- drivers/media/video/cx231xx/cx231xx-input.c | 4 ++-- drivers/media/video/cx23885/cx23885-input.c | 4 ++-- drivers/media/video/cx88/cx88-input.c | 4 ++-- drivers/media/video/em28xx/em28xx-input.c | 4 ++-- drivers/media/video/ir-kbd-i2c.c | 4 ++-- drivers/media/video/saa7134/saa7134-input.c | 4 ++-- include/media/ir-core.h | 2 +- 11 files changed, 21 insertions(+), 21 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index ddb8a0f8af4..e9c9bd34af6 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c @@ -450,7 +450,7 @@ int ir_input_register(struct input_dev *input_dev, } EXPORT_SYMBOL_GPL(ir_input_register); -void ir_input_free(struct input_dev *dev) +void ir_input_unregister(struct input_dev *dev) { struct ir_input_dev *ir_dev = input_get_drvdata(dev); struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; @@ -467,7 +467,7 @@ void ir_input_free(struct input_dev *dev) kfree(ir_dev); input_set_drvdata(dev, NULL); } -EXPORT_SYMBOL_GPL(ir_input_free); +EXPORT_SYMBOL_GPL(ir_input_unregister); int ir_core_debug; /* ir_debug level (0,1,2) */ EXPORT_SYMBOL_GPL(ir_core_debug); diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index 53e3f2a7d31..34e4e569cc7 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/drivers/media/dvb/dm1105/dm1105.c @@ -613,7 +613,7 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) err = input_register_device(input_dev); if (err) { - ir_input_free(input_dev); + ir_input_unregister(input_dev); input_free_device(input_dev); return err; } @@ -623,7 +623,7 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105) { - ir_input_free(dm1105->ir.input_dev); + ir_input_unregister(dm1105->ir.input_dev); input_unregister_device(dm1105->ir.input_dev); } diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 7d193ebc0ae..9c9070a403d 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -286,7 +286,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci) return 0; out2: - ir_input_free(input_dev); + ir_input_unregister(input_dev); input_free_device(input_dev); out1: return error; @@ -304,7 +304,7 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci) del_timer_sync(&dev->timer); ir_input_nokey(dev, &budget_ci->ir.state); - ir_input_free(dev); + ir_input_unregister(dev); input_unregister_device(dev); } diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c index 84a957e52c4..0e1a7aabefb 100644 --- a/drivers/media/video/bt8xx/bttv-input.c +++ b/drivers/media/video/bt8xx/bttv-input.c @@ -403,7 +403,7 @@ int bttv_input_init(struct bttv *btv) bttv_ir_stop(btv); btv->remote = NULL; err_out_free: - ir_input_free(input_dev); + ir_input_unregister(input_dev); input_free_device(input_dev); kfree(ir); return err; @@ -415,7 +415,7 @@ void bttv_input_fini(struct bttv *btv) return; bttv_ir_stop(btv); - ir_input_free(btv->remote->dev); + ir_input_unregister(btv->remote->dev); input_unregister_device(btv->remote->dev); kfree(btv->remote); btv->remote = NULL; diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c index cd135f01b9c..5eba1ec1205 100644 --- a/drivers/media/video/cx231xx/cx231xx-input.c +++ b/drivers/media/video/cx231xx/cx231xx-input.c @@ -226,7 +226,7 @@ err_out_stop: cx231xx_ir_stop(ir); dev->ir = NULL; err_out_free: - ir_input_free(input_dev); + ir_input_unregister(input_dev); input_free_device(input_dev); kfree(ir); return err; @@ -241,7 +241,7 @@ int cx231xx_ir_fini(struct cx231xx *dev) return 0; cx231xx_ir_stop(ir); - ir_input_free(ir->input); + ir_input_unregister(ir->input); input_unregister_device(ir->input); kfree(ir); diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c index 469e083dd5f..2a5e4d959e8 100644 --- a/drivers/media/video/cx23885/cx23885-input.c +++ b/drivers/media/video/cx23885/cx23885-input.c @@ -407,7 +407,7 @@ err_out_stop: cx23885_input_ir_stop(dev); dev->ir_input = NULL; err_out_free: - ir_input_free(input_dev); + ir_input_unregister(input_dev); input_free_device(input_dev); kfree(ir); return ret; @@ -420,7 +420,7 @@ void cx23885_input_fini(struct cx23885_dev *dev) if (dev->ir_input == NULL) return; - ir_input_free(dev->ir_input->dev); + ir_input_unregister(dev->ir_input->dev); input_unregister_device(dev->ir_input->dev); kfree(dev->ir_input); dev->ir_input = NULL; diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index 92b8cdf9fb8..d4dc2c2a3cb 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c @@ -393,7 +393,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) cx88_ir_stop(core, ir); core->ir = NULL; err_out_free: - ir_input_free(input_dev); + ir_input_unregister(input_dev); input_free_device(input_dev); kfree(ir); return err; @@ -408,7 +408,7 @@ int cx88_ir_fini(struct cx88_core *core) return 0; cx88_ir_stop(core, ir); - ir_input_free(ir->input); + ir_input_unregister(ir->input); input_unregister_device(ir->input); kfree(ir); diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index 5ddeb421ed5..9dc4e142726 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c @@ -422,7 +422,7 @@ int em28xx_ir_init(struct em28xx *dev) em28xx_ir_stop(ir); dev->ir = NULL; err_out_free: - ir_input_free(input_dev); + ir_input_unregister(input_dev); input_free_device(input_dev); kfree(ir); return err; @@ -437,7 +437,7 @@ int em28xx_ir_fini(struct em28xx *dev) return 0; em28xx_ir_stop(ir); - ir_input_free(ir->input); + ir_input_unregister(ir->input); input_unregister_device(ir->input); kfree(ir); diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 2856e780772..9d8e78dc614 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -460,7 +460,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) return 0; err_out_free: - ir_input_free(input_dev); + ir_input_unregister(input_dev); input_free_device(input_dev); kfree(ir); return err; @@ -474,7 +474,7 @@ static int ir_remove(struct i2c_client *client) cancel_delayed_work_sync(&ir->work); /* unregister device */ - ir_input_free(ir->input); + ir_input_unregister(ir->input); input_unregister_device(ir->input); /* free memory */ diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 411a8410620..5093e7a0d58 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -742,7 +742,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) saa7134_ir_stop(dev); dev->remote = NULL; err_out_free: - ir_input_free(input_dev); + ir_input_unregister(input_dev); input_free_device(input_dev); kfree(ir); return err; @@ -754,7 +754,7 @@ void saa7134_input_fini(struct saa7134_dev *dev) return; saa7134_ir_stop(dev); - ir_input_free(dev->remote->dev); + ir_input_unregister(dev->remote->dev); input_unregister_device(dev->remote->dev); kfree(dev->remote); dev->remote = NULL; diff --git a/include/media/ir-core.h b/include/media/ir-core.h index ea76c199b67..299d201e133 100644 --- a/include/media/ir-core.h +++ b/include/media/ir-core.h @@ -57,6 +57,6 @@ int ir_set_keycode_table(struct input_dev *input_dev, int ir_roundup_tablesize(int n_elems); int ir_input_register(struct input_dev *dev, struct ir_scancode_table *ir_codes); -void ir_input_free(struct input_dev *input_dev); +void ir_input_unregister(struct input_dev *input_dev); #endif -- cgit v1.2.3-70-g09d2 From 579e7d60ba0035228aadad69eb2ffeb138c51311 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2009 11:20:59 -0300 Subject: V4L/DVB (13617): ir: move input_register_device() to happen inside ir_input_register() We'll need to register a sysfs class for the IR devices. As such, the better is to have the input_register_device()/input_unregister_device() inside the ir register/unregister functions. Also, solves a naming problem with V4L ir_input_init() function, that were, in fact, registering a device. While here, do a few cleanups at budget-ci IR logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/IR/ir-functions.c | 4 +-- drivers/media/IR/ir-keytable.c | 20 ++++++++---- drivers/media/dvb/dm1105/dm1105.c | 12 ++----- drivers/media/dvb/ttpci/budget-ci.c | 50 +++++++++-------------------- drivers/media/video/bt8xx/bttv-input.c | 7 ++-- drivers/media/video/cx231xx/cx231xx-input.c | 8 ++--- drivers/media/video/cx23885/cx23885-input.c | 7 ++-- drivers/media/video/cx88/cx88-input.c | 7 ++-- drivers/media/video/em28xx/em28xx-input.c | 8 ++--- drivers/media/video/ir-kbd-i2c.c | 7 ++-- drivers/media/video/saa7134/saa7134-input.c | 7 ++-- include/media/ir-common.h | 2 +- 12 files changed, 48 insertions(+), 91 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/IR/ir-functions.c b/drivers/media/IR/ir-functions.c index 7401a798971..776a136616d 100644 --- a/drivers/media/IR/ir-functions.c +++ b/drivers/media/IR/ir-functions.c @@ -52,15 +52,13 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) /* -------------------------------------------------------------------------- */ int ir_input_init(struct input_dev *dev, struct ir_input_state *ir, - int ir_type, struct ir_scancode_table *ir_codes) + int ir_type) { ir->ir_type = ir_type; if (repeat) set_bit(EV_REP, dev->evbit); - ir_input_register(dev, ir_codes); - return 0; } EXPORT_SYMBOL_GPL(ir_input_init); diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index e9c9bd34af6..bff7a535603 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c @@ -12,8 +12,8 @@ * GNU General Public License for more details. */ -#include +#include #include #define IR_TAB_MIN_SIZE 32 @@ -408,7 +408,7 @@ int ir_input_register(struct input_dev *input_dev, { struct ir_input_dev *ir_dev; struct ir_scancode *keymap = rc_tab->scan; - int i; + int i, rc; if (rc_tab->scan == NULL || !rc_tab->size) return -EINVAL; @@ -446,26 +446,34 @@ int ir_input_register(struct input_dev *input_dev, input_dev->setkeycode = ir_setkeycode; input_set_drvdata(input_dev, ir_dev); - return 0; + rc = input_register_device(input_dev); + if (rc < 0) { + kfree(rc_tab->scan); + kfree(ir_dev); + input_set_drvdata(input_dev, NULL); + } + + return rc; } EXPORT_SYMBOL_GPL(ir_input_register); void ir_input_unregister(struct input_dev *dev) { struct ir_input_dev *ir_dev = input_get_drvdata(dev); - struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; + struct ir_scancode_table *rc_tab; - if (!rc_tab) + if (!ir_dev) return; IR_dprintk(1, "Freed keycode table\n"); + rc_tab = &ir_dev->rc_tab; rc_tab->size = 0; kfree(rc_tab->scan); rc_tab->scan = NULL; kfree(ir_dev); - input_set_drvdata(dev, NULL); + input_unregister_device(dev); } EXPORT_SYMBOL_GPL(ir_input_unregister); diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index 34e4e569cc7..f0f483ac8b8 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/drivers/media/dvb/dm1105/dm1105.c @@ -589,7 +589,7 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys), "pci-%s/ir0", pci_name(dm1105->pdev)); - err = ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes); + err = ir_input_init(input_dev, &dm1105->ir.ir, ir_type); if (err < 0) { input_free_device(input_dev); return err; @@ -611,20 +611,14 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) INIT_WORK(&dm1105->ir.work, dm1105_emit_key); - err = input_register_device(input_dev); - if (err) { - ir_input_unregister(input_dev); - input_free_device(input_dev); - return err; - } + err = ir_input_register(input_dev, ir_codes); - return 0; + return err; } void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105) { ir_input_unregister(dm1105->ir.input_dev); - input_unregister_device(dm1105->ir.input_dev); } static int __devinit dm1105dvb_hw_init(struct dm1105dvb *dm1105dvb) diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 9c9070a403d..9782e059373 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -190,12 +190,13 @@ static int msp430_ir_init(struct budget_ci *budget_ci) struct saa7146_dev *saa = budget_ci->budget.dev; struct input_dev *input_dev = budget_ci->ir.dev; int error; + struct ir_scancode_table *ir_codes; + budget_ci->ir.dev = input_dev = input_allocate_device(); if (!input_dev) { printk(KERN_ERR "budget_ci: IR interface initialisation failed\n"); - error = -ENOMEM; - goto out1; + return -ENOMEM; } snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name), @@ -217,6 +218,11 @@ static int msp430_ir_init(struct budget_ci *budget_ci) } input_dev->dev.parent = &saa->pci->dev; + if (rc5_device < 0) + budget_ci->ir.rc5_device = IR_DEVICE_ANY; + else + budget_ci->ir.rc5_device = rc5_device; + /* Select keymap and address */ switch (budget_ci->budget.dev->pci->subsystem_device) { case 0x100c: @@ -224,53 +230,34 @@ static int msp430_ir_init(struct budget_ci *budget_ci) case 0x1011: case 0x1012: /* The hauppauge keymap is a superset of these remotes */ - error = ir_input_init(input_dev, &budget_ci->ir.state, - IR_TYPE_RC5, &ir_codes_hauppauge_new_table); - if (error < 0) - goto out2; + ir_codes = &ir_codes_hauppauge_new_table; if (rc5_device < 0) budget_ci->ir.rc5_device = 0x1f; - else - budget_ci->ir.rc5_device = rc5_device; break; case 0x1010: case 0x1017: case 0x101a: /* for the Technotrend 1500 bundled remote */ - error = ir_input_init(input_dev, &budget_ci->ir.state, - IR_TYPE_RC5, &ir_codes_tt_1500_table); - if (error < 0) - goto out2; - - if (rc5_device < 0) - budget_ci->ir.rc5_device = IR_DEVICE_ANY; - else - budget_ci->ir.rc5_device = rc5_device; + ir_codes = &ir_codes_tt_1500_table; break; default: /* unknown remote */ - error = ir_input_init(input_dev, &budget_ci->ir.state, - IR_TYPE_RC5, &ir_codes_budget_ci_old_table); - if (error < 0) - goto out2; - - if (rc5_device < 0) - budget_ci->ir.rc5_device = IR_DEVICE_ANY; - else - budget_ci->ir.rc5_device = rc5_device; + ir_codes = &ir_codes_budget_ci_old_table; break; } + ir_input_init(input_dev, &budget_ci->ir.state, IR_TYPE_RC5); + /* initialise the key-up timeout handler */ init_timer(&budget_ci->ir.timer_keyup); budget_ci->ir.timer_keyup.function = msp430_ir_keyup; budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir; budget_ci->ir.last_raw = 0xffff; /* An impossible value */ - error = input_register_device(input_dev); + error = ir_input_register(input_dev, ir_codes); if (error) { printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); - goto out2; + return error; } /* note: these must be after input_register_device */ @@ -284,12 +271,6 @@ static int msp430_ir_init(struct budget_ci *budget_ci) saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI); return 0; - -out2: - ir_input_unregister(input_dev); - input_free_device(input_dev); -out1: - return error; } static void msp430_ir_deinit(struct budget_ci *budget_ci) @@ -305,7 +286,6 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci) ir_input_nokey(dev, &budget_ci->ir.state); ir_input_unregister(dev); - input_unregister_device(dev); } static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address) diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c index 0e1a7aabefb..277a092e121 100644 --- a/drivers/media/video/bt8xx/bttv-input.c +++ b/drivers/media/video/bt8xx/bttv-input.c @@ -368,7 +368,7 @@ int bttv_input_init(struct bttv *btv) snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(btv->c.pci)); - err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); + err = ir_input_init(input_dev, &ir->ir, ir_type); if (err < 0) goto err_out_free; @@ -389,7 +389,7 @@ int bttv_input_init(struct bttv *btv) bttv_ir_start(btv, ir); /* all done */ - err = input_register_device(btv->remote->dev); + err = ir_input_register(btv->remote->dev, ir_codes); if (err) goto err_out_stop; @@ -403,8 +403,6 @@ int bttv_input_init(struct bttv *btv) bttv_ir_stop(btv); btv->remote = NULL; err_out_free: - ir_input_unregister(input_dev); - input_free_device(input_dev); kfree(ir); return err; } @@ -416,7 +414,6 @@ void bttv_input_fini(struct bttv *btv) bttv_ir_stop(btv); ir_input_unregister(btv->remote->dev); - input_unregister_device(btv->remote->dev); kfree(btv->remote); btv->remote = NULL; } diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c index 5eba1ec1205..15826f98b68 100644 --- a/drivers/media/video/cx231xx/cx231xx-input.c +++ b/drivers/media/video/cx231xx/cx231xx-input.c @@ -197,8 +197,7 @@ int cx231xx_ir_init(struct cx231xx *dev) usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); strlcat(ir->phys, "/input0", sizeof(ir->phys)); - err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER, - dev->board.ir_codes); + err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER); if (err < 0) goto err_out_free; @@ -217,7 +216,7 @@ int cx231xx_ir_init(struct cx231xx *dev) cx231xx_ir_start(ir); /* all done */ - err = input_register_device(ir->input); + err = ir_input_register(ir->input, dev->board.ir_codes); if (err) goto err_out_stop; @@ -226,8 +225,6 @@ err_out_stop: cx231xx_ir_stop(ir); dev->ir = NULL; err_out_free: - ir_input_unregister(input_dev); - input_free_device(input_dev); kfree(ir); return err; } @@ -242,7 +239,6 @@ int cx231xx_ir_fini(struct cx231xx *dev) cx231xx_ir_stop(ir); ir_input_unregister(ir->input); - input_unregister_device(ir->input); kfree(ir); /* done */ diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c index 2a5e4d959e8..768eec92ccf 100644 --- a/drivers/media/video/cx23885/cx23885-input.c +++ b/drivers/media/video/cx23885/cx23885-input.c @@ -377,7 +377,7 @@ int cx23885_input_init(struct cx23885_dev *dev) cx23885_boards[dev->board].name); snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(dev->pci)); - ret = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); + ret = ir_input_init(input_dev, &ir->ir, ir_type); if (ret < 0) goto err_out_free; @@ -397,7 +397,7 @@ int cx23885_input_init(struct cx23885_dev *dev) dev->ir_input = ir; cx23885_input_ir_start(dev); - ret = input_register_device(ir->dev); + ret = ir_input_register(ir->dev, ir_codes); if (ret) goto err_out_stop; @@ -407,8 +407,6 @@ err_out_stop: cx23885_input_ir_stop(dev); dev->ir_input = NULL; err_out_free: - ir_input_unregister(input_dev); - input_free_device(input_dev); kfree(ir); return ret; } @@ -421,7 +419,6 @@ void cx23885_input_fini(struct cx23885_dev *dev) if (dev->ir_input == NULL) return; ir_input_unregister(dev->ir_input->dev); - input_unregister_device(dev->ir_input->dev); kfree(dev->ir_input); dev->ir_input = NULL; } diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index d4dc2c2a3cb..f9fda18b410 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c @@ -360,7 +360,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name); snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci)); - err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); + err = ir_input_init(input_dev, &ir->ir, ir_type); if (err < 0) goto err_out_free; @@ -383,7 +383,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) cx88_ir_start(core, ir); /* all done */ - err = input_register_device(ir->input); + err = ir_input_register(ir->input, ir_codes); if (err) goto err_out_stop; @@ -393,8 +393,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) cx88_ir_stop(core, ir); core->ir = NULL; err_out_free: - ir_input_unregister(input_dev); - input_free_device(input_dev); kfree(ir); return err; } @@ -409,7 +407,6 @@ int cx88_ir_fini(struct cx88_core *core) cx88_ir_stop(core, ir); ir_input_unregister(ir->input); - input_unregister_device(ir->input); kfree(ir); /* done */ diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index 9dc4e142726..af0d935c29b 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c @@ -393,8 +393,7 @@ int em28xx_ir_init(struct em28xx *dev) usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); strlcat(ir->phys, "/input0", sizeof(ir->phys)); - err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER, - dev->board.ir_codes); + err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER); if (err < 0) goto err_out_free; @@ -413,7 +412,7 @@ int em28xx_ir_init(struct em28xx *dev) em28xx_ir_start(ir); /* all done */ - err = input_register_device(ir->input); + err = ir_input_register(ir->input, dev->board.ir_codes); if (err) goto err_out_stop; @@ -422,8 +421,6 @@ int em28xx_ir_init(struct em28xx *dev) em28xx_ir_stop(ir); dev->ir = NULL; err_out_free: - ir_input_unregister(input_dev); - input_free_device(input_dev); kfree(ir); return err; } @@ -438,7 +435,6 @@ int em28xx_ir_fini(struct em28xx *dev) em28xx_ir_stop(ir); ir_input_unregister(ir->input); - input_unregister_device(ir->input); kfree(ir); /* done */ diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 9d8e78dc614..b86e35386ce 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -438,7 +438,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) dev_name(&client->dev)); /* init + register input device */ - err = ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes); + err = ir_input_init(input_dev, &ir->ir, ir_type); if (err < 0) goto err_out_free; @@ -446,7 +446,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) input_dev->name = ir->name; input_dev->phys = ir->phys; - err = input_register_device(ir->input); + err = ir_input_register(ir->input, ir->ir_codes); if (err) goto err_out_free; @@ -460,8 +460,6 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) return 0; err_out_free: - ir_input_unregister(input_dev); - input_free_device(input_dev); kfree(ir); return err; } @@ -475,7 +473,6 @@ static int ir_remove(struct i2c_client *client) /* unregister device */ ir_input_unregister(ir->input); - input_unregister_device(ir->input); /* free memory */ kfree(ir); diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 5093e7a0d58..f8e985989ca 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -708,7 +708,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(dev->pci)); - err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); + err = ir_input_init(input_dev, &ir->ir, ir_type); if (err < 0) goto err_out_free; @@ -728,7 +728,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) dev->remote = ir; saa7134_ir_start(dev, ir); - err = input_register_device(ir->dev); + err = ir_input_register(ir->dev, ir_codes); if (err) goto err_out_stop; @@ -742,8 +742,6 @@ int saa7134_input_init1(struct saa7134_dev *dev) saa7134_ir_stop(dev); dev->remote = NULL; err_out_free: - ir_input_unregister(input_dev); - input_free_device(input_dev); kfree(ir); return err; } @@ -755,7 +753,6 @@ void saa7134_input_fini(struct saa7134_dev *dev) saa7134_ir_stop(dev); ir_input_unregister(dev->remote->dev); - input_unregister_device(dev->remote->dev); kfree(dev->remote); dev->remote = NULL; } diff --git a/include/media/ir-common.h b/include/media/ir-common.h index ac8ced6bf3e..2c6af24b905 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -84,7 +84,7 @@ struct card_ir { /* Routines from ir-functions.c */ int ir_input_init(struct input_dev *dev, struct ir_input_state *ir, - int ir_type, struct ir_scancode_table *ir_codes); + int ir_type); void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir); void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, u32 ir_key); -- cgit v1.2.3-70-g09d2 From 2e535ed5a16b8cc23301f3d26cfd49f3091aadcc Mon Sep 17 00:00:00 2001 From: Muralidharan Karicheri Date: Thu, 10 Dec 2009 04:39:47 -0300 Subject: V4L/DVB (13618): v4l2: Adding helper function to get dv preset description This patch adds a helper function to get description of a digital video preset added by the video timing API. This will be useful for drivers implementing the above API. Signed-off-by: Muralidharan Karicheri Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-common.c | 47 +++++++++++++++++++++++++++++++++++++++ include/media/v4l2-common.h | 2 +- 2 files changed, 48 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index e8e5affbabc..36b5cb86fb5 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c @@ -1024,3 +1024,50 @@ void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax, } } EXPORT_SYMBOL_GPL(v4l_bound_align_image); + +/** + * v4l_fill_dv_preset_info - fill description of a digital video preset + * @preset - preset value + * @info - pointer to struct v4l2_dv_enum_preset + * + * drivers can use this helper function to fill description of dv preset + * in info. + */ +int v4l_fill_dv_preset_info(u32 preset, struct v4l2_dv_enum_preset *info) +{ + static const struct v4l2_dv_preset_info { + u16 width; + u16 height; + const char *name; + } dv_presets[] = { + { 0, 0, "Invalid" }, /* V4L2_DV_INVALID */ + { 720, 480, "480p@59.94" }, /* V4L2_DV_480P59_94 */ + { 720, 576, "576p@50" }, /* V4L2_DV_576P50 */ + { 1280, 720, "720p@24" }, /* V4L2_DV_720P24 */ + { 1280, 720, "720p@25" }, /* V4L2_DV_720P25 */ + { 1280, 720, "720p@30" }, /* V4L2_DV_720P30 */ + { 1280, 720, "720p@50" }, /* V4L2_DV_720P50 */ + { 1280, 720, "720p@59.94" }, /* V4L2_DV_720P59_94 */ + { 1280, 720, "720p@60" }, /* V4L2_DV_720P60 */ + { 1920, 1080, "1080i@29.97" }, /* V4L2_DV_1080I29_97 */ + { 1920, 1080, "1080i@30" }, /* V4L2_DV_1080I30 */ + { 1920, 1080, "1080i@25" }, /* V4L2_DV_1080I25 */ + { 1920, 1080, "1080i@50" }, /* V4L2_DV_1080I50 */ + { 1920, 1080, "1080i@60" }, /* V4L2_DV_1080I60 */ + { 1920, 1080, "1080p@24" }, /* V4L2_DV_1080P24 */ + { 1920, 1080, "1080p@25" }, /* V4L2_DV_1080P25 */ + { 1920, 1080, "1080p@30" }, /* V4L2_DV_1080P30 */ + { 1920, 1080, "1080p@50" }, /* V4L2_DV_1080P50 */ + { 1920, 1080, "1080p@60" }, /* V4L2_DV_1080P60 */ + }; + + if (info == NULL || preset >= ARRAY_SIZE(dv_presets)) + return -EINVAL; + + info->preset = preset; + info->width = dv_presets[preset].width; + info->height = dv_presets[preset].height; + strlcpy(info->name, dv_presets[preset].name, sizeof(info->name)); + return 0; +} +EXPORT_SYMBOL_GPL(v4l_fill_dv_preset_info); diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 1c25b10da34..1c7b259f341 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -212,5 +212,5 @@ void v4l_bound_align_image(unsigned int *w, unsigned int wmin, unsigned int *h, unsigned int hmin, unsigned int hmax, unsigned int halign, unsigned int salign); - +int v4l_fill_dv_preset_info(u32 preset, struct v4l2_dv_enum_preset *info); #endif /* V4L2_COMMON_H_ */ -- cgit v1.2.3-70-g09d2 From 37b372e5ebe187037e01885151a0afb546a38520 Mon Sep 17 00:00:00 2001 From: Márton Németh Date: Thu, 10 Dec 2009 11:31:09 -0300 Subject: V4L/DVB (13621): gspca - some subdrivers: Make device_table[]s constant. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Márton Németh Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/conex.c | 4 ++-- drivers/media/video/gspca/etoms.c | 4 ++-- drivers/media/video/gspca/pac7302.c | 4 ++-- drivers/media/video/gspca/pac7311.c | 4 ++-- drivers/media/video/gspca/sonixb.c | 4 ++-- drivers/media/video/gspca/spca506.c | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c index 2f0b8d621e0..c98b5d69c43 100644 --- a/drivers/media/video/gspca/conex.c +++ b/drivers/media/video/gspca/conex.c @@ -1046,14 +1046,14 @@ static struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] __devinitconst = { {USB_DEVICE(0x0572, 0x0041)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); /* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, +static int __devinit sd_probe(struct usb_interface *intf, const struct usb_device_id *id) { return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c index 9de86419ae1..fdf4c0ec5e7 100644 --- a/drivers/media/video/gspca/etoms.c +++ b/drivers/media/video/gspca/etoms.c @@ -864,7 +864,7 @@ static struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] __devinitconst = { {USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106}, #if !defined CONFIG_USB_ET61X251 && !defined CONFIG_USB_ET61X251_MODULE {USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX}, @@ -875,7 +875,7 @@ static __devinitdata struct usb_device_id device_table[] = { MODULE_DEVICE_TABLE(usb, device_table); /* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, +static int __devinit sd_probe(struct usb_interface *intf, const struct usb_device_id *id) { return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index e128514733d..de0b66c4b56 100644 --- a/drivers/media/video/gspca/pac7302.c +++ b/drivers/media/video/gspca/pac7302.c @@ -1229,7 +1229,7 @@ static struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] __devinitconst = { {USB_DEVICE(0x06f8, 0x3009)}, {USB_DEVICE(0x093a, 0x2620)}, {USB_DEVICE(0x093a, 0x2621)}, @@ -1245,7 +1245,7 @@ static __devinitdata struct usb_device_id device_table[] = { MODULE_DEVICE_TABLE(usb, device_table); /* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, +static int __devinit sd_probe(struct usb_interface *intf, const struct usb_device_id *id) { return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index e5697a6345e..42cfcdfd8f4 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -863,7 +863,7 @@ static struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] __devinitconst = { {USB_DEVICE(0x093a, 0x2600)}, {USB_DEVICE(0x093a, 0x2601)}, {USB_DEVICE(0x093a, 0x2603)}, @@ -875,7 +875,7 @@ static __devinitdata struct usb_device_id device_table[] = { MODULE_DEVICE_TABLE(usb, device_table); /* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, +static int __devinit sd_probe(struct usb_interface *intf, const struct usb_device_id *id) { return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 5be95bc6513..ddff2b5ee5c 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -1226,7 +1226,7 @@ static const struct sd_desc sd_desc = { .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge -static __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] __devinitconst = { {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, /* TAS5110C1B */ {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, /* TAS5110C1B */ #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE @@ -1257,7 +1257,7 @@ static __devinitdata struct usb_device_id device_table[] = { MODULE_DEVICE_TABLE(usb, device_table); /* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, +static int __devinit sd_probe(struct usb_interface *intf, const struct usb_device_id *id) { return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c index ab28cc23e41..39257e4e074 100644 --- a/drivers/media/video/gspca/spca506.c +++ b/drivers/media/video/gspca/spca506.c @@ -685,7 +685,7 @@ static struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] __devinitconst = { {USB_DEVICE(0x06e1, 0xa190)}, /*fixme: may be IntelPCCameraPro BRIDGE_SPCA505 {USB_DEVICE(0x0733, 0x0430)}, */ @@ -696,7 +696,7 @@ static __devinitdata struct usb_device_id device_table[] = { MODULE_DEVICE_TABLE(usb, device_table); /* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, +static int __devinit sd_probe(struct usb_interface *intf, const struct usb_device_id *id) { return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), -- cgit v1.2.3-70-g09d2 From 83955556669f69fccfd332b52e9b1796d60c77bd Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 12 Dec 2009 06:58:01 -0300 Subject: V4L/DVB (13626): gspca - many subdrivers: Fix some warnings. - gl860.c:332:15: warning: cast to restricted __le16 - gl860.c:333:15: warning: cast to restricted __le16 - gl860-mi1320.c:348:5: warning: symbol 'mi1320_camera_settings' was not declared. Should it be static? - gl860-mi2020.c:772:5: warning: symbol 'mi2020_camera_settings' was not declared. Should it be static? - m5602_ov9650.c:444:7: warning: symbol 'data' shadows an earlier one - m5602_core.c:84:5: warning: symbol 'm5602_wait_for_i2c' was not declared. Should it be static? - m5602_core.c:391:6: warning: symbol 'm5602_disconnect' was not declared. Should it be static? - m5602_s5k4aa.c:530:23: warning: dubious: x | !y - m5602_s5k4aa.c:575:23: warning: dubious: x | !y - gspca.c:1196:13: warning: potentially expensive pointer subtraction - mr97310a.c:70:5: warning: symbol 'force_sensor_type' was not declared. Should it be static? - ov519.c:2025:4: warning: do-while statement is not a compound statement - ov519.c:2063:4: warning: do-while statement is not a compound statement - ov519.c:2089:4: warning: do-while statement is not a compound statement - ov519.c:1985:34: warning: incorrect type in assignment (different base types) - sn9c20x.c:1164:5: warning: symbol 'i2c_r1' was not declared. Should it be static? - sn9c20x.c:1189:5: warning: symbol 'i2c_r2' was not declared. Should it be static? - sn9c20x.c:2237:27: warning: right shift by bigger than source value - sn9c20x.c:2237:27: warning: right shift by bigger than source value Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gl860/gl860-mi1320.c | 2 +- drivers/media/video/gspca/gl860/gl860-mi2020.c | 2 +- drivers/media/video/gspca/gl860/gl860.c | 10 +++++----- drivers/media/video/gspca/gspca.c | 6 ++++-- drivers/media/video/gspca/m5602/m5602_core.c | 4 ++-- drivers/media/video/gspca/m5602/m5602_ov9650.c | 2 +- drivers/media/video/gspca/m5602/m5602_s5k4aa.c | 10 ++++++++-- drivers/media/video/gspca/mr97310a.c | 2 +- drivers/media/video/gspca/ov519.c | 14 +++++++------- drivers/media/video/gspca/sn9c20x.c | 7 +++---- 10 files changed, 33 insertions(+), 26 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gl860/gl860-mi1320.c b/drivers/media/video/gspca/gl860/gl860-mi1320.c index 1355e526ee8..c276a7debde 100644 --- a/drivers/media/video/gspca/gl860/gl860-mi1320.c +++ b/drivers/media/video/gspca/gl860/gl860-mi1320.c @@ -345,7 +345,7 @@ static int mi1320_configure_alt(struct gspca_dev *gspca_dev) return 0; } -int mi1320_camera_settings(struct gspca_dev *gspca_dev) +static int mi1320_camera_settings(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; diff --git a/drivers/media/video/gspca/gl860/gl860-mi2020.c b/drivers/media/video/gspca/gl860/gl860-mi2020.c index 80cb3f1b36f..7c31b4f2abe 100644 --- a/drivers/media/video/gspca/gl860/gl860-mi2020.c +++ b/drivers/media/video/gspca/gl860/gl860-mi2020.c @@ -769,7 +769,7 @@ static int mi2020_configure_alt(struct gspca_dev *gspca_dev) return 0; } -int mi2020_camera_settings(struct gspca_dev *gspca_dev) +static int mi2020_camera_settings(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c index bd3c21a37be..4878c8f6654 100644 --- a/drivers/media/video/gspca/gl860/gl860.c +++ b/drivers/media/video/gspca/gl860/gl860.c @@ -40,7 +40,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, static void sd_callback(struct gspca_dev *gspca_dev); static int gl860_guess_sensor(struct gspca_dev *gspca_dev, - s32 vendor_id, s32 product_id); + u16 vendor_id, u16 product_id); /*============================ driver options ==============================*/ @@ -326,11 +326,11 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - s32 vendor_id, product_id; + u16 vendor_id, product_id; /* Get USB VendorID and ProductID */ - vendor_id = le16_to_cpu(id->idVendor); - product_id = le16_to_cpu(id->idProduct); + vendor_id = id->idVendor; + product_id = id->idProduct; sd->nbRightUp = 1; sd->nbIm = -1; @@ -673,7 +673,7 @@ void fetch_idxdata(struct gspca_dev *gspca_dev, struct idxdata *tbl, int len) } static int gl860_guess_sensor(struct gspca_dev *gspca_dev, - s32 vendor_id, s32 product_id) + u16 vendor_id, u16 product_id) { struct sd *sd = (struct sd *) gspca_dev; u8 probe, nb26, nb96, nOV, ntry; diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 95a8b84d4cf..e930a67d526 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -1175,12 +1175,14 @@ static int vidioc_queryctrl(struct file *file, void *priv, continue; ctrls = &gspca_dev->sd_desc->ctrls[i]; } + if (ctrls == NULL) + return -EINVAL; } else { ctrls = get_ctrl(gspca_dev, id); + if (ctrls == NULL) + return -EINVAL; i = ctrls - gspca_dev->sd_desc->ctrls; } - if (ctrls == NULL) - return -EINVAL; memcpy(q_ctrl, ctrls, sizeof *q_ctrl); if (gspca_dev->ctrl_inac & (1 << i)) q_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c index 844fc1d886d..4294c75e3b1 100644 --- a/drivers/media/video/gspca/m5602/m5602_core.c +++ b/drivers/media/video/gspca/m5602/m5602_core.c @@ -81,7 +81,7 @@ int m5602_write_bridge(struct sd *sd, const u8 address, const u8 i2c_data) return (err < 0) ? err : 0; } -int m5602_wait_for_i2c(struct sd *sd) +static int m5602_wait_for_i2c(struct sd *sd) { int err; u8 data; @@ -388,7 +388,7 @@ static int m5602_probe(struct usb_interface *intf, THIS_MODULE); } -void m5602_disconnect(struct usb_interface *intf) +static void m5602_disconnect(struct usb_interface *intf) { struct gspca_dev *gspca_dev = usb_get_intfdata(intf); struct sd *sd = (struct sd *) gspca_dev; diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c index c2739d6605a..923cdd5f7a6 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.c +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c @@ -439,7 +439,7 @@ int ov9650_start(struct sd *sd) err = m5602_write_bridge(sd, res_init_ov9650[i][1], res_init_ov9650[i][2]); else if (res_init_ov9650[i][0] == SENSOR) { - u8 data = res_init_ov9650[i][2]; + data = res_init_ov9650[i][2]; err = m5602_write_sensor(sd, res_init_ov9650[i][1], &data, 1); } diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c index a27afeb6f39..aa2f3c7e2cb 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c +++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c @@ -525,7 +525,10 @@ static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); if (err < 0) return err; - data = (data & 0xfe) | !val; + if (val) + data &= 0xfe; + else + data |= 0x01; err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); return err; } @@ -570,7 +573,10 @@ static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); if (err < 0) return err; - data = (data & 0xfe) | !val; + if (val) + data &= 0xfe; + else + data |= 0x01; err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); return err; } diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index 126d968dd9e..9154870e07d 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c @@ -67,7 +67,7 @@ MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver"); MODULE_LICENSE("GPL"); /* global parameters */ -int force_sensor_type = -1; +static int force_sensor_type = -1; module_param(force_sensor_type, int, 0644); MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)"); diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index ad9ec339981..b4f96573124 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -1982,7 +1982,7 @@ static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n) { int ret; - *((u32 *)sd->gspca_dev.usb_buf) = __cpu_to_le32(value); + *((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value); ret = usb_control_msg(sd->gspca_dev.dev, usb_sndctrlpipe(sd->gspca_dev.dev, 0), @@ -2021,9 +2021,9 @@ static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value) if (rc < 0) return rc; - do + do { rc = reg_r(sd, R511_I2C_CTL); - while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ + } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ if (rc < 0) return rc; @@ -2055,9 +2055,9 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg) if (rc < 0) return rc; - do + do { rc = reg_r(sd, R511_I2C_CTL); - while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ + } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ if (rc < 0) return rc; @@ -2081,9 +2081,9 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg) if (rc < 0) return rc; - do + do { rc = reg_r(sd, R511_I2C_CTL); - while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ + } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ if (rc < 0) return rc; diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index a3d8f4675c0..4cff8035614 100644 --- a/drivers/media/video/gspca/sn9c20x.c +++ b/drivers/media/video/gspca/sn9c20x.c @@ -1158,7 +1158,7 @@ static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val) return i2c_w(gspca_dev, row); } -int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val) +static int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val) { struct sd *sd = (struct sd *) gspca_dev; u8 row[8]; @@ -1183,7 +1183,7 @@ int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val) return 0; } -int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val) +static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val) { struct sd *sd = (struct sd *) gspca_dev; u8 row[8]; @@ -2175,8 +2175,7 @@ static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode) } #define HW_WIN(mode, hstart, vstart) \ -((const u8 []){hstart & 0xff, hstart >> 8, \ -vstart & 0xff, vstart >> 8, \ +((const u8 []){hstart, 0, vstart, 0, \ (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \ (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)}) -- cgit v1.2.3-70-g09d2 From 174c44e4a7d2418e8990c075dd7f5de51699781e Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 12 Dec 2009 13:20:49 -0300 Subject: V4L/DVB (13627): gspca - zc3xx: Set the quality for sensor tas5130c. - setting the quality gives a better brightness Reported-by: Benoit GIRARD Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/zc3xx.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 1d525c4d63c..1a800fc1c00 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -6919,7 +6919,6 @@ static int sd_start(struct gspca_dev *gspca_dev) switch (sd->sensor) { case SENSOR_OV7620: case SENSOR_PAS202B: - case SENSOR_TAS5130CXX: reg_r(gspca_dev, 0x0180); /* from win */ reg_w(dev, 0x00, 0x0180); break; -- cgit v1.2.3-70-g09d2 From 247cb142a924fad215337170a5201a5cf9d960e1 Mon Sep 17 00:00:00 2001 From: Abylay Ospan Date: Sat, 12 Dec 2009 13:37:44 -0300 Subject: V4L/DVB (13630): Print bitrate measured by stv0900 demod in stv0900_read_status Signed-off-by: Abylay Ospan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0900_core.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c index df49ea0983b..8762c86044a 100644 --- a/drivers/media/dvb/frontends/stv0900_core.c +++ b/drivers/media/dvb/frontends/stv0900_core.c @@ -1451,6 +1451,8 @@ static int stv0900_status(struct stv0900_internal *intp, { enum fe_stv0900_search_state demod_state; int locked = FALSE; + u8 tsbitrate0_val, tsbitrate1_val; + s32 bitrate; demod_state = stv0900_get_bits(intp, HEADER_MODE); switch (demod_state) { @@ -1473,6 +1475,17 @@ static int stv0900_status(struct stv0900_internal *intp, dprintk("%s: locked = %d\n", __func__, locked); + if (stvdebug) { + /* Print TS bitrate */ + tsbitrate0_val = stv0900_read_reg(intp, TSBITRATE0); + tsbitrate1_val = stv0900_read_reg(intp, TSBITRATE1); + /* Formula Bit rate = Mclk * px_tsfifo_bitrate / 16384 */ + bitrate = (stv0900_get_mclk_freq(intp, intp->quartz)/1000000) + * (tsbitrate1_val << 8 | tsbitrate0_val); + bitrate /= 16384; + dprintk("TS bitrate = %d Mbit/sec \n", bitrate); + }; + return locked; } -- cgit v1.2.3-70-g09d2 From 4a4bc5e4f976bf00ae3c96b57a5bcead72ade5ea Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 11 Dec 2009 11:06:00 -0300 Subject: V4L/DVB (13642): tw9910: The driver can also handle revision 1 of the chip Signed-off-by: Kuninori Morimoto Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tw9910.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index 269ab044072..7bf90a29dae 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c @@ -883,11 +883,12 @@ static int tw9910_video_probe(struct soc_camera_device *icd, /* * check and show Product ID + * So far only revisions 0 and 1 have been seen */ val = i2c_smbus_read_byte_data(client, ID); if (0x0B != GET_ID(val) || - 0x00 != GET_ReV(val)) { + 0x01 < GET_ReV(val)) { dev_err(&client->dev, "Product ID error %x:%x\n", GET_ID(val), GET_ReV(val)); return -ENODEV; -- cgit v1.2.3-70-g09d2 From 325361088b73269f4cc96256276a142addbf3454 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 11 Dec 2009 11:14:46 -0300 Subject: V4L/DVB (13644): v4l: add new v4l2-subdev sensor operations, use g_skip_top_lines in soc-camera Introduce new v4l2-subdev sensor operations, move .enum_framesizes() and .enum_frameintervals() methods to it, add a new .g_skip_top_lines() method and switch soc-camera to use it instead of .y_skip_top soc_camera_device member, which can now be removed. Signed-off-by: Guennadi Liakhovetski Reviewed-by: Hans Verkuil Reviewed-by: Sergio Aguirre Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/mt9m001.c | 30 ++++++++++++++++++++++------- drivers/media/video/mt9m111.c | 1 - drivers/media/video/mt9t031.c | 24 +++++++++++++++++++---- drivers/media/video/mt9v022.c | 32 ++++++++++++++++++++++--------- drivers/media/video/pxa_camera.c | 9 +++++++-- drivers/media/video/soc_camera_platform.c | 1 - include/media/soc_camera.h | 1 - include/media/v4l2-subdev.h | 22 ++++++++++++++++----- 8 files changed, 90 insertions(+), 30 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index 45388d2ce2f..17be2d46fd4 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c @@ -82,6 +82,7 @@ struct mt9m001 { int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ unsigned int gain; unsigned int exposure; + unsigned short y_skip_top; /* Lines to skip at the top */ unsigned char autoexposure; }; @@ -222,7 +223,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) soc_camera_limit_side(&rect.top, &rect.height, MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT); - total_h = rect.height + icd->y_skip_top + vblank; + total_h = rect.height + mt9m001->y_skip_top + vblank; /* Blanking and start values - default... */ ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank); @@ -239,7 +240,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect.width - 1); if (!ret) ret = reg_write(client, MT9M001_WINDOW_HEIGHT, - rect.height + icd->y_skip_top - 1); + rect.height + mt9m001->y_skip_top - 1); if (!ret && mt9m001->autoexposure) { ret = reg_write(client, MT9M001_SHUTTER_WIDTH, total_h); if (!ret) { @@ -327,13 +328,13 @@ static int mt9m001_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) static int mt9m001_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) { struct i2c_client *client = sd->priv; - struct soc_camera_device *icd = client->dev.platform_data; + struct mt9m001 *mt9m001 = to_mt9m001(client); struct v4l2_pix_format *pix = &f->fmt.pix; v4l_bound_align_image(&pix->width, MT9M001_MIN_WIDTH, MT9M001_MAX_WIDTH, 1, - &pix->height, MT9M001_MIN_HEIGHT + icd->y_skip_top, - MT9M001_MAX_HEIGHT + icd->y_skip_top, 0, 0); + &pix->height, MT9M001_MIN_HEIGHT + mt9m001->y_skip_top, + MT9M001_MAX_HEIGHT + mt9m001->y_skip_top, 0, 0); if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8 || pix->pixelformat == V4L2_PIX_FMT_SBGGR16) @@ -552,7 +553,7 @@ static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) if (ctrl->value) { const u16 vblank = 25; unsigned int total_h = mt9m001->rect.height + - icd->y_skip_top + vblank; + mt9m001->y_skip_top + vblank; if (reg_write(client, MT9M001_SHUTTER_WIDTH, total_h) < 0) return -EIO; @@ -655,6 +656,16 @@ static void mt9m001_video_remove(struct soc_camera_device *icd) icl->free_bus(icl); } +static int mt9m001_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines) +{ + struct i2c_client *client = sd->priv; + struct mt9m001 *mt9m001 = to_mt9m001(client); + + *lines = mt9m001->y_skip_top; + + return 0; +} + static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = { .g_ctrl = mt9m001_g_ctrl, .s_ctrl = mt9m001_s_ctrl, @@ -675,9 +686,14 @@ static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = { .cropcap = mt9m001_cropcap, }; +static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = { + .g_skip_top_lines = mt9m001_g_skip_top_lines, +}; + static struct v4l2_subdev_ops mt9m001_subdev_ops = { .core = &mt9m001_subdev_core_ops, .video = &mt9m001_subdev_video_ops, + .sensor = &mt9m001_subdev_sensor_ops, }; static int mt9m001_probe(struct i2c_client *client, @@ -714,8 +730,8 @@ static int mt9m001_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &mt9m001_ops; - icd->y_skip_top = 0; + mt9m001->y_skip_top = 0; mt9m001->rect.left = MT9M001_COLUMN_SKIP; mt9m001->rect.top = MT9M001_ROW_SKIP; mt9m001->rect.width = MT9M001_MAX_WIDTH; diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 90da699601e..30db625455e 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -1019,7 +1019,6 @@ static int mt9m111_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &mt9m111_ops; - icd->y_skip_top = 0; mt9m111->rect.left = MT9M111_MIN_DARK_COLS; mt9m111->rect.top = MT9M111_MIN_DARK_ROWS; diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c index 6966f644977..1adbb7b2b58 100644 --- a/drivers/media/video/mt9t031.c +++ b/drivers/media/video/mt9t031.c @@ -74,6 +74,7 @@ struct mt9t031 { u16 xskip; u16 yskip; unsigned int gain; + unsigned short y_skip_top; /* Lines to skip at the top */ unsigned int exposure; unsigned char autoexposure; }; @@ -301,9 +302,9 @@ static int mt9t031_set_params(struct soc_camera_device *icd, ret = reg_write(client, MT9T031_WINDOW_WIDTH, rect->width - 1); if (ret >= 0) ret = reg_write(client, MT9T031_WINDOW_HEIGHT, - rect->height + icd->y_skip_top - 1); + rect->height + mt9t031->y_skip_top - 1); if (ret >= 0 && mt9t031->autoexposure) { - unsigned int total_h = rect->height + icd->y_skip_top + vblank; + unsigned int total_h = rect->height + mt9t031->y_skip_top + vblank; ret = set_shutter(client, total_h); if (ret >= 0) { const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; @@ -657,7 +658,7 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) const u16 vblank = MT9T031_VERTICAL_BLANK; const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; unsigned int total_h = mt9t031->rect.height + - icd->y_skip_top + vblank; + mt9t031->y_skip_top + vblank; if (set_shutter(client, total_h) < 0) return -EIO; @@ -714,6 +715,16 @@ static int mt9t031_video_probe(struct i2c_client *client) return ret; } +static int mt9t031_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines) +{ + struct i2c_client *client = sd->priv; + struct mt9t031 *mt9t031 = to_mt9t031(client); + + *lines = mt9t031->y_skip_top; + + return 0; +} + static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = { .g_ctrl = mt9t031_g_ctrl, .s_ctrl = mt9t031_s_ctrl, @@ -734,9 +745,14 @@ static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = { .cropcap = mt9t031_cropcap, }; +static struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = { + .g_skip_top_lines = mt9t031_g_skip_top_lines, +}; + static struct v4l2_subdev_ops mt9t031_subdev_ops = { .core = &mt9t031_subdev_core_ops, .video = &mt9t031_subdev_video_ops, + .sensor = &mt9t031_subdev_sensor_ops, }; static int mt9t031_probe(struct i2c_client *client, @@ -773,8 +789,8 @@ static int mt9t031_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &mt9t031_ops; - icd->y_skip_top = 0; + mt9t031->y_skip_top = 0; mt9t031->rect.left = MT9T031_COLUMN_SKIP; mt9t031->rect.top = MT9T031_ROW_SKIP; mt9t031->rect.width = MT9T031_MAX_WIDTH; diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index 995607f9d3b..b71898f1b08 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c @@ -97,6 +97,7 @@ struct mt9v022 { __u32 fourcc; int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */ u16 chip_control; + unsigned short y_skip_top; /* Lines to skip at the top */ }; static struct mt9v022 *to_mt9v022(const struct i2c_client *client) @@ -265,7 +266,6 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) struct i2c_client *client = sd->priv; struct mt9v022 *mt9v022 = to_mt9v022(client); struct v4l2_rect rect = a->c; - struct soc_camera_device *icd = client->dev.platform_data; int ret; /* Bayer format - even size lengths */ @@ -287,10 +287,10 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) if (ret >= 0) { if (ret & 1) /* Autoexposure */ ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, - rect.height + icd->y_skip_top + 43); + rect.height + mt9v022->y_skip_top + 43); else ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, - rect.height + icd->y_skip_top + 43); + rect.height + mt9v022->y_skip_top + 43); } /* Setup frame format: defaults apart from width and height */ if (!ret) @@ -309,7 +309,7 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width); if (!ret) ret = reg_write(client, MT9V022_WINDOW_HEIGHT, - rect.height + icd->y_skip_top); + rect.height + mt9v022->y_skip_top); if (ret < 0) return ret; @@ -410,15 +410,15 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) static int mt9v022_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) { struct i2c_client *client = sd->priv; - struct soc_camera_device *icd = client->dev.platform_data; + struct mt9v022 *mt9v022 = to_mt9v022(client); struct v4l2_pix_format *pix = &f->fmt.pix; int align = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 || pix->pixelformat == V4L2_PIX_FMT_SBGGR16; v4l_bound_align_image(&pix->width, MT9V022_MIN_WIDTH, MT9V022_MAX_WIDTH, align, - &pix->height, MT9V022_MIN_HEIGHT + icd->y_skip_top, - MT9V022_MAX_HEIGHT + icd->y_skip_top, align, 0); + &pix->height, MT9V022_MIN_HEIGHT + mt9v022->y_skip_top, + MT9V022_MAX_HEIGHT + mt9v022->y_skip_top, align, 0); return 0; } @@ -787,6 +787,16 @@ static void mt9v022_video_remove(struct soc_camera_device *icd) icl->free_bus(icl); } +static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines) +{ + struct i2c_client *client = sd->priv; + struct mt9v022 *mt9v022 = to_mt9v022(client); + + *lines = mt9v022->y_skip_top; + + return 0; +} + static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = { .g_ctrl = mt9v022_g_ctrl, .s_ctrl = mt9v022_s_ctrl, @@ -807,9 +817,14 @@ static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = { .cropcap = mt9v022_cropcap, }; +static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = { + .g_skip_top_lines = mt9v022_g_skip_top_lines, +}; + static struct v4l2_subdev_ops mt9v022_subdev_ops = { .core = &mt9v022_subdev_core_ops, .video = &mt9v022_subdev_video_ops, + .sensor = &mt9v022_subdev_sensor_ops, }; static int mt9v022_probe(struct i2c_client *client, @@ -851,8 +866,7 @@ static int mt9v022_probe(struct i2c_client *client, * MT9V022 _really_ corrupts the first read out line. * TODO: verify on i.MX31 */ - icd->y_skip_top = 1; - + mt9v022->y_skip_top = 1; mt9v022->rect.left = MT9V022_COLUMN_SKIP; mt9v022->rect.top = MT9V022_ROW_SKIP; mt9v022->rect.width = MT9V022_MAX_WIDTH; diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index 51b683c63b7..4df09a693ec 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c @@ -1051,8 +1051,13 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd, { struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct pxa_camera_dev *pcdev = ici->priv; + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); unsigned long dw, bpp; - u32 cicr0, cicr1, cicr2, cicr3, cicr4 = 0; + u32 cicr0, cicr1, cicr2, cicr3, cicr4 = 0, y_skip_top; + int ret = v4l2_subdev_call(sd, sensor, g_skip_top_lines, &y_skip_top); + + if (ret < 0) + y_skip_top = 0; /* Datawidth is now guaranteed to be equal to one of the three values. * We fix bit-per-pixel equal to data-width... */ @@ -1118,7 +1123,7 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd, cicr2 = 0; cicr3 = CICR3_LPF_VAL(icd->user_height - 1) | - CICR3_BFW_VAL(min((unsigned short)255, icd->y_skip_top)); + CICR3_BFW_VAL(min((u32)255, y_skip_top)); cicr4 |= pcdev->mclk_divisor; __raw_writel(cicr1, pcdev->base + CICR1); diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c index b6a575ce5da..c7c91518c39 100644 --- a/drivers/media/video/soc_camera_platform.c +++ b/drivers/media/video/soc_camera_platform.c @@ -128,7 +128,6 @@ static int soc_camera_platform_probe(struct platform_device *pdev) /* Set the control device reference */ dev_set_drvdata(&icd->dev, &pdev->dev); - icd->y_skip_top = 0; icd->ops = &soc_camera_platform_ops; ici = to_soc_camera_host(icd->dev.parent); diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index c5afc8cf8e1..218639f133d 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -24,7 +24,6 @@ struct soc_camera_device { struct device *pdev; /* Platform device */ s32 user_width; s32 user_height; - unsigned short y_skip_top; /* Lines to skip at the top */ unsigned char iface; /* Host number */ unsigned char devnum; /* Device number per host */ unsigned char buswidth; /* See comment in .c */ diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 7a3408f9d0f..a128458dc9e 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -263,6 +263,17 @@ struct v4l2_subdev_video_ops { struct v4l2_dv_timings *timings); }; +/** + * struct v4l2_subdev_sensor_ops - v4l2-subdev sensor operations + * @g_skip_top_lines: number of lines at the top of the image to be skipped. + * This is needed for some sensors, which always corrupt + * several top lines of the output image, or which send their + * metadata in them. + */ +struct v4l2_subdev_sensor_ops { + int (*g_skip_top_lines)(struct v4l2_subdev *sd, u32 *lines); +}; + /* interrupt_service_routine: Called by the bridge chip's interrupt service handler, when an IR interrupt status has be raised due to this subdev, @@ -347,11 +358,12 @@ struct v4l2_subdev_ir_ops { }; struct v4l2_subdev_ops { - const struct v4l2_subdev_core_ops *core; - const struct v4l2_subdev_tuner_ops *tuner; - const struct v4l2_subdev_audio_ops *audio; - const struct v4l2_subdev_video_ops *video; - const struct v4l2_subdev_ir_ops *ir; + const struct v4l2_subdev_core_ops *core; + const struct v4l2_subdev_tuner_ops *tuner; + const struct v4l2_subdev_audio_ops *audio; + const struct v4l2_subdev_video_ops *video; + const struct v4l2_subdev_ir_ops *ir; + const struct v4l2_subdev_sensor_ops *sensor; }; #define V4L2_SUBDEV_NAME_SIZE 32 -- cgit v1.2.3-70-g09d2 From 5d28d525452f170e30bc038955439731462a5228 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 11 Dec 2009 11:15:05 -0300 Subject: V4L/DVB (13645): soc-camera: fix multi-line comment coding style Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/mt9m001.c | 36 +++++++++++++------- drivers/media/video/mt9t031.c | 24 ++++++++----- drivers/media/video/mt9v022.c | 48 +++++++++++++++++--------- drivers/media/video/mx1_camera.c | 36 +++++++++++++------- drivers/media/video/mx3_camera.c | 18 ++++++---- drivers/media/video/pxa_camera.c | 54 ++++++++++++++++++++---------- drivers/media/video/sh_mobile_ceu_camera.c | 18 ++++++---- drivers/media/video/soc_camera.c | 24 ++++++++----- drivers/media/video/tw9910.c | 8 ++--- include/media/ov772x.h | 3 +- 10 files changed, 178 insertions(+), 91 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index 17be2d46fd4..cc9066000c2 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c @@ -17,9 +17,11 @@ #include #include -/* mt9m001 i2c address 0x5d +/* + * mt9m001 i2c address 0x5d * The platform has to define ctruct i2c_board_info objects and link to them - * from struct soc_camera_link */ + * from struct soc_camera_link + */ /* mt9m001 selected register addresses */ #define MT9M001_CHIP_VERSION 0x00 @@ -47,8 +49,10 @@ #define MT9M001_ROW_SKIP 12 static const struct soc_camera_data_format mt9m001_colour_formats[] = { - /* Order important: first natively supported, - * second supported with a GPIO extender */ + /* + * Order important: first natively supported, + * second supported with a GPIO extender + */ { .name = "Bayer (sRGB) 10 bit", .depth = 10, @@ -230,8 +234,10 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) if (!ret) ret = reg_write(client, MT9M001_VERTICAL_BLANKING, vblank); - /* The caller provides a supported format, as verified per - * call to icd->try_fmt() */ + /* + * The caller provides a supported format, as verified per + * call to icd->try_fmt() + */ if (!ret) ret = reg_write(client, MT9M001_COLUMN_START, rect.left); if (!ret) @@ -569,8 +575,10 @@ static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) return 0; } -/* Interface active, can use i2c. If it fails, it can indeed mean, that - * this wasn't our capture interface, so, we wait for the right one */ +/* + * Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one + */ static int mt9m001_video_probe(struct soc_camera_device *icd, struct i2c_client *client) { @@ -580,8 +588,10 @@ static int mt9m001_video_probe(struct soc_camera_device *icd, unsigned long flags; int ret; - /* We must have a parent by now. And it cannot be a wrong one. - * So this entire test is completely redundant. */ + /* + * We must have a parent by now. And it cannot be a wrong one. + * So this entire test is completely redundant. + */ if (!icd->dev.parent || to_soc_camera_host(icd->dev.parent)->nr != icd->iface) return -ENODEV; @@ -737,8 +747,10 @@ static int mt9m001_probe(struct i2c_client *client, mt9m001->rect.width = MT9M001_MAX_WIDTH; mt9m001->rect.height = MT9M001_MAX_HEIGHT; - /* Simulated autoexposure. If enabled, we calculate shutter width - * ourselves in the driver based on vertical blanking and frame width */ + /* + * Simulated autoexposure. If enabled, we calculate shutter width + * ourselves in the driver based on vertical blanking and frame width + */ mt9m001->autoexposure = 1; ret = mt9m001_video_probe(icd, client); diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c index 1adbb7b2b58..e3f664f21c4 100644 --- a/drivers/media/video/mt9t031.c +++ b/drivers/media/video/mt9t031.c @@ -17,9 +17,11 @@ #include #include -/* mt9t031 i2c address 0x5d +/* + * mt9t031 i2c address 0x5d * The platform has to define i2c_board_info and link to it from - * struct soc_camera_link */ + * struct soc_camera_link + */ /* mt9t031 selected register addresses */ #define MT9T031_CHIP_VERSION 0x00 @@ -292,8 +294,10 @@ static int mt9t031_set_params(struct soc_camera_device *icd, dev_dbg(&client->dev, "new physical left %u, top %u\n", rect->left, rect->top); - /* The caller provides a supported format, as guaranteed by - * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */ + /* + * The caller provides a supported format, as guaranteed by + * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() + */ if (ret >= 0) ret = reg_write(client, MT9T031_COLUMN_START, rect->left); if (ret >= 0) @@ -674,8 +678,10 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) return 0; } -/* Interface active, can use i2c. If it fails, it can indeed mean, that - * this wasn't our capture interface, so, we wait for the right one */ +/* + * Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one + */ static int mt9t031_video_probe(struct i2c_client *client) { struct soc_camera_device *icd = client->dev.platform_data; @@ -796,8 +802,10 @@ static int mt9t031_probe(struct i2c_client *client, mt9t031->rect.width = MT9T031_MAX_WIDTH; mt9t031->rect.height = MT9T031_MAX_HEIGHT; - /* Simulated autoexposure. If enabled, we calculate shutter width - * ourselves in the driver based on vertical blanking and frame width */ + /* + * Simulated autoexposure. If enabled, we calculate shutter width + * ourselves in the driver based on vertical blanking and frame width + */ mt9t031->autoexposure = 1; mt9t031->xskip = 1; diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index b71898f1b08..f60a9a107f2 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c @@ -18,9 +18,11 @@ #include #include -/* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c +/* + * mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c * The platform has to define ctruct i2c_board_info objects and link to them - * from struct soc_camera_link */ + * from struct soc_camera_link + */ static char *sensor_type; module_param(sensor_type, charp, S_IRUGO); @@ -63,8 +65,10 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\""); #define MT9V022_ROW_SKIP 4 static const struct soc_camera_data_format mt9v022_colour_formats[] = { - /* Order important: first natively supported, - * second supported with a GPIO extender */ + /* + * Order important: first natively supported, + * second supported with a GPIO extender + */ { .name = "Bayer (sRGB) 10 bit", .depth = 10, @@ -144,9 +148,11 @@ static int mt9v022_init(struct i2c_client *client) struct mt9v022 *mt9v022 = to_mt9v022(client); int ret; - /* Almost the default mode: master, parallel, simultaneous, and an + /* + * Almost the default mode: master, parallel, simultaneous, and an * undocumented bit 0x200, which is present in table 7, but not in 8, - * plus snapshot mode to disable scan for now */ + * plus snapshot mode to disable scan for now + */ mt9v022->chip_control |= 0x10; ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control); if (!ret) @@ -298,8 +304,10 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) if (!ret) ret = reg_write(client, MT9V022_ROW_START, rect.top); if (!ret) - /* Default 94, Phytec driver says: - * "width + horizontal blank >= 660" */ + /* + * Default 94, Phytec driver says: + * "width + horizontal blank >= 660" + */ ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING, rect.width > 660 - 43 ? 43 : 660 - rect.width); @@ -376,8 +384,10 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) }; int ret; - /* The caller provides a supported format, as verified per call to - * icd->try_fmt(), datawidth is from our supported format list */ + /* + * The caller provides a supported format, as verified per call to + * icd->try_fmt(), datawidth is from our supported format list + */ switch (pix->pixelformat) { case V4L2_PIX_FMT_GREY: case V4L2_PIX_FMT_Y16: @@ -635,8 +645,10 @@ static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 48 + range / 2) / range + 16; if (gain >= 32) gain &= ~1; - /* The user wants to set gain manually, hope, she - * knows, what she's doing... Switch AGC off. */ + /* + * The user wants to set gain manually, hope, she + * knows, what she's doing... Switch AGC off. + */ if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) return -EIO; @@ -655,8 +667,10 @@ static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) unsigned long range = qctrl->maximum - qctrl->minimum; unsigned long shutter = ((ctrl->value - qctrl->minimum) * 479 + range / 2) / range + 1; - /* The user wants to set shutter width manually, hope, - * she knows, what she's doing... Switch AEC off. */ + /* + * The user wants to set shutter width manually, hope, + * she knows, what she's doing... Switch AEC off. + */ if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0) return -EIO; @@ -689,8 +703,10 @@ static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) return 0; } -/* Interface active, can use i2c. If it fails, it can indeed mean, that - * this wasn't our capture interface, so, we wait for the right one */ +/* + * Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one + */ static int mt9v022_video_probe(struct soc_camera_device *icd, struct i2c_client *client) { diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index 72802291e81..4c1a439373c 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c @@ -99,9 +99,11 @@ struct mx1_buffer { int inwork; }; -/* i.MX1/i.MXL is only supposed to handle one camera on its Camera Sensor +/* + * i.MX1/i.MXL is only supposed to handle one camera on its Camera Sensor * Interface. If anyone ever builds hardware to enable more than - * one camera, they will have to modify this driver too */ + * one camera, they will have to modify this driver too + */ struct mx1_camera_dev { struct soc_camera_host soc_host; struct soc_camera_device *icd; @@ -151,8 +153,10 @@ static void free_buffer(struct videobuf_queue *vq, struct mx1_buffer *buf) dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, vb, vb->baddr, vb->bsize); - /* This waits until this buffer is out of danger, i.e., until it is no - * longer in STATE_QUEUED or STATE_ACTIVE */ + /* + * This waits until this buffer is out of danger, i.e., until it is no + * longer in STATE_QUEUED or STATE_ACTIVE + */ videobuf_waiton(vb, 0, 0); videobuf_dma_contig_free(vq, vb); @@ -174,8 +178,10 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq, BUG_ON(NULL == icd->current_fmt); - /* I think, in buf_prepare you only have to protect global data, - * the actual buffer is yours */ + /* + * I think, in buf_prepare you only have to protect global data, + * the actual buffer is yours + */ buf->inwork = 1; if (buf->fmt != icd->current_fmt || @@ -381,8 +387,10 @@ static int mclk_get_divisor(struct mx1_camera_dev *pcdev) lcdclk = clk_get_rate(pcdev->clk); - /* We verify platform_mclk_10khz != 0, so if anyone breaks it, here - * they get a nice Oops */ + /* + * We verify platform_mclk_10khz != 0, so if anyone breaks it, here + * they get a nice Oops + */ div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1; dev_dbg(pcdev->icd->dev.parent, @@ -420,8 +428,10 @@ static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) clk_disable(pcdev->clk); } -/* The following two functions absolutely depend on the fact, that - * there can be only one camera on i.MX1/i.MXL camera sensor interface */ +/* + * The following two functions absolutely depend on the fact, that + * there can be only one camera on i.MX1/i.MXL camera sensor interface + */ static int mx1_camera_add_device(struct soc_camera_device *icd) { struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); @@ -578,10 +588,12 @@ static int mx1_camera_reqbufs(struct soc_camera_file *icf, { int i; - /* This is for locking debugging only. I removed spinlocks and now I + /* + * This is for locking debugging only. I removed spinlocks and now I * check whether .prepare is ever called on a linked buffer, or whether * a dma IRQ can occur for an in-work or unlinked buffer. Until now - * it hadn't triggered */ + * it hadn't triggered + */ for (i = 0; i < p->count; i++) { struct mx1_buffer *buf = container_of(icf->vb_vidq.bufs[i], struct mx1_buffer, vb); diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index 7db82bdf6f3..ae7d4832449 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c @@ -564,8 +564,10 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam, SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_LOW; - /* If requested data width is supported by the platform, use it or any - * possible lower value - i.MX31 is smart enough to schift bits */ + /* + * If requested data width is supported by the platform, use it or any + * possible lower value - i.MX31 is smart enough to schift bits + */ switch (buswidth) { case 15: if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)) @@ -1027,8 +1029,10 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; } - /* Make the camera work in widest common mode, we'll take care of - * the rest */ + /* + * Make the camera work in widest common mode, we'll take care of + * the rest + */ if (common_flags & SOCAM_DATAWIDTH_15) common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) | SOCAM_DATAWIDTH_15; @@ -1152,8 +1156,10 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev) if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 | MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10 | MX3_CAMERA_DATAWIDTH_15))) { - /* Platform hasn't set available data widths. This is bad. - * Warn and use a default. */ + /* + * Platform hasn't set available data widths. This is bad. + * Warn and use a default. + */ dev_warn(&pdev->dev, "WARNING! Platform hasn't set available " "data widths, using default 8 bit\n"); mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8; diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index 4df09a693ec..f063f5981f4 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c @@ -197,9 +197,11 @@ struct pxa_buffer { struct pxa_camera_dev { struct soc_camera_host soc_host; - /* PXA27x is only supposed to handle one camera on its Quick Capture + /* + * PXA27x is only supposed to handle one camera on its Quick Capture * interface. If anyone ever builds hardware to enable more than - * one camera, they will have to modify this driver too */ + * one camera, they will have to modify this driver too + */ struct soc_camera_device *icd; struct clk *clk; @@ -267,8 +269,10 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf) dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, &buf->vb, buf->vb.baddr, buf->vb.bsize); - /* This waits until this buffer is out of danger, i.e., until it is no - * longer in STATE_QUEUED or STATE_ACTIVE */ + /* + * This waits until this buffer is out of danger, i.e., until it is no + * longer in STATE_QUEUED or STATE_ACTIVE + */ videobuf_waiton(&buf->vb, 0, 0); videobuf_dma_unmap(vq, dma); videobuf_dma_free(dma); @@ -437,15 +441,19 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq, WARN_ON(!list_empty(&vb->queue)); #ifdef DEBUG - /* This can be useful if you want to see if we actually fill - * the buffer with something */ + /* + * This can be useful if you want to see if we actually fill + * the buffer with something + */ memset((void *)vb->baddr, 0xaa, vb->bsize); #endif BUG_ON(NULL == icd->current_fmt); - /* I think, in buf_prepare you only have to protect global data, - * the actual buffer is yours */ + /* + * I think, in buf_prepare you only have to protect global data, + * the actual buffer is yours + */ buf->inwork = 1; if (buf->fmt != icd->current_fmt || @@ -834,8 +842,10 @@ static void pxa_camera_init_videobuf(struct videobuf_queue *q, struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct pxa_camera_dev *pcdev = ici->priv; - /* We must pass NULL as dev pointer, then all pci_* dma operations - * transform to normal dma_* ones. */ + /* + * We must pass NULL as dev pointer, then all pci_* dma operations + * transform to normal dma_* ones. + */ videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, sizeof(struct pxa_buffer), icd); @@ -1059,8 +1069,10 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd, if (ret < 0) y_skip_top = 0; - /* Datawidth is now guaranteed to be equal to one of the three values. - * We fix bit-per-pixel equal to data-width... */ + /* + * Datawidth is now guaranteed to be equal to one of the three values. + * We fix bit-per-pixel equal to data-width... + */ switch (flags & SOCAM_DATAWIDTH_MASK) { case SOCAM_DATAWIDTH_10: dw = 4; @@ -1071,8 +1083,10 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd, bpp = 0x20; break; default: - /* Actually it can only be 8 now, - * default is just to silence compiler warnings */ + /* + * Actually it can only be 8 now, + * default is just to silence compiler warnings + */ case SOCAM_DATAWIDTH_8: dw = 2; bpp = 0; @@ -1524,10 +1538,12 @@ static int pxa_camera_reqbufs(struct soc_camera_file *icf, { int i; - /* This is for locking debugging only. I removed spinlocks and now I + /* + * This is for locking debugging only. I removed spinlocks and now I * check whether .prepare is ever called on a linked buffer, or whether * a dma IRQ can occur for an in-work or unlinked buffer. Until now - * it hadn't triggered */ + * it hadn't triggered + */ for (i = 0; i < p->count; i++) { struct pxa_buffer *buf = container_of(icf->vb_vidq.bufs[i], struct pxa_buffer, vb); @@ -1662,8 +1678,10 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev) pcdev->platform_flags = pcdev->pdata->flags; if (!(pcdev->platform_flags & (PXA_CAMERA_DATAWIDTH_8 | PXA_CAMERA_DATAWIDTH_9 | PXA_CAMERA_DATAWIDTH_10))) { - /* Platform hasn't set available data widths. This is bad. - * Warn and use a default. */ + /* + * Platform hasn't set available data widths. This is bad. + * Warn and use a default. + */ dev_warn(&pdev->dev, "WARNING! Platform hasn't set available " "data widths, using default 10 bit\n"); pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10; diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 7509990c65d..3271944f261 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -252,7 +252,8 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) u32 status; int ret = 0; - /* The hardware is _very_ picky about this sequence. Especially + /* + * The hardware is _very_ picky about this sequence. Especially * the CEU_CETCR_MAGIC value. It seems like we need to acknowledge * several not-so-well documented interrupt sources in CETCR. */ @@ -321,8 +322,10 @@ static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq, WARN_ON(!list_empty(&vb->queue)); #ifdef DEBUG - /* This can be useful if you want to see if we actually fill - * the buffer with something */ + /* + * This can be useful if you want to see if we actually fill + * the buffer with something + */ memset((void *)vb->baddr, 0xaa, vb->bsize); #endif @@ -709,7 +712,8 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, ceu_write(pcdev, CFLCR, pcdev->cflcr); - /* A few words about byte order (observed in Big Endian mode) + /* + * A few words about byte order (observed in Big Endian mode) * * In data fetch mode bytes are received in chunks of 8 bytes. * D0, D1, D2, D3, D4, D5, D6, D7 (D0 received first) @@ -1573,10 +1577,12 @@ static int sh_mobile_ceu_reqbufs(struct soc_camera_file *icf, { int i; - /* This is for locking debugging only. I removed spinlocks and now I + /* + * This is for locking debugging only. I removed spinlocks and now I * check whether .prepare is ever called on a linked buffer, or whether * a dma IRQ can occur for an in-work or unlinked buffer. Until now - * it hadn't triggered */ + * it hadn't triggered + */ for (i = 0; i < p->count; i++) { struct sh_mobile_ceu_buffer *buf; diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 804c675f2cb..5fdedc76640 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -621,8 +621,10 @@ static int soc_camera_streamoff(struct file *file, void *priv, mutex_lock(&icd->video_lock); - /* This calls buf_release from host driver's videobuf_queue_ops for all - * remaining buffers. When the last buffer is freed, stop capture */ + /* + * This calls buf_release from host driver's videobuf_queue_ops for all + * remaining buffers. When the last buffer is freed, stop capture + */ videobuf_streamoff(&icf->vb_vidq); v4l2_subdev_call(sd, video, s_stream, 0); @@ -1004,8 +1006,10 @@ epower: return ret; } -/* This is called on device_unregister, which only means we have to disconnect - * from the host, but not remove ourselves from the device list */ +/* + * This is called on device_unregister, which only means we have to disconnect + * from the host, but not remove ourselves from the device list + */ static int soc_camera_remove(struct device *dev) { struct soc_camera_device *icd = to_soc_camera_dev(dev); @@ -1205,8 +1209,10 @@ static int soc_camera_device_register(struct soc_camera_device *icd) } if (num < 0) - /* ok, we have 256 cameras on this host... - * man, stay reasonable... */ + /* + * ok, we have 256 cameras on this host... + * man, stay reasonable... + */ return -ENOMEM; icd->devnum = num; @@ -1333,9 +1339,11 @@ escdevreg: return ret; } -/* Only called on rmmod for each platform device, since they are not +/* + * Only called on rmmod for each platform device, since they are not * hot-pluggable. Now we know, that all our users - hosts and devices have - * been unloaded already */ + * been unloaded already + */ static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev) { struct soc_camera_device *icd = platform_get_drvdata(pdev); diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index 7bf90a29dae..3cb9ba6caa4 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c @@ -180,9 +180,8 @@ */ /* VBICNTL */ -/* RTSEL : control the real time signal -* output from the MPOUT pin -*/ + +/* RTSEL : control the real time signal output from the MPOUT pin */ #define RTSEL_MASK 0x07 #define RTSEL_VLOSS 0x00 /* 0000 = Video loss */ #define RTSEL_HLOCK 0x01 /* 0001 = H-lock */ @@ -596,7 +595,8 @@ static int tw9910_g_register(struct v4l2_subdev *sd, if (ret < 0) return ret; - /* ret = int + /* + * ret = int * reg->val = __u64 */ reg->val = (__u64)ret; diff --git a/include/media/ov772x.h b/include/media/ov772x.h index 30d9629198e..37bcd096dde 100644 --- a/include/media/ov772x.h +++ b/include/media/ov772x.h @@ -1,4 +1,5 @@ -/* ov772x Camera +/* + * ov772x Camera * * Copyright (C) 2008 Renesas Solutions Corp. * Kuninori Morimoto -- cgit v1.2.3-70-g09d2 From 6ed7c03884ee7c05ff880cafb46ae20915e22e3c Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 11 Dec 2009 11:15:06 -0300 Subject: V4L/DVB (13646): sh_mobile_ceu_camera: do not mark host occupied, when adding a client fails Currently, if resetting the host interface, when adding a new client, fails, a negative error code is returned, but the host is still marked as occupied. Fix this bug. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/sh_mobile_ceu_camera.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 3271944f261..2a38e1d9061 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -459,6 +459,7 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) { struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct sh_mobile_ceu_dev *pcdev = ici->priv; + int ret; if (pcdev->icd) return -EBUSY; @@ -469,9 +470,11 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) pm_runtime_get_sync(ici->v4l2_dev.dev); - pcdev->icd = icd; + ret = sh_mobile_ceu_soft_reset(pcdev); + if (!ret) + pcdev->icd = icd; - return sh_mobile_ceu_soft_reset(pcdev); + return ret; } /* Called with .video_lock held */ -- cgit v1.2.3-70-g09d2 From 0f4482940a75b52db931e1fff181c9d267e462d2 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 11 Dec 2009 11:31:35 -0300 Subject: V4L/DVB (13650): soc-camera: switch drivers and platforms to use .priv in struct soc_camera_link After this change drivers can be further extended to not fail, if they don't get platform data, but to use defaults. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- arch/sh/boards/mach-ap325rxa/setup.c | 38 ++++++++++++++++++++---------------- arch/sh/boards/mach-migor/setup.c | 32 +++++++++++++++++------------- drivers/media/video/ov772x.c | 4 ++-- drivers/media/video/tw9910.c | 6 +++--- include/media/ov772x.h | 1 - include/media/soc_camera_platform.h | 1 - include/media/tw9910.h | 1 - 7 files changed, 44 insertions(+), 39 deletions(-) (limited to 'drivers/media') diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index cf9dc12dfeb..4c860288457 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c @@ -324,12 +324,14 @@ static struct soc_camera_platform_info camera_info = { .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8, .set_capture = camera_set_capture, - .link = { - .bus_id = 0, - .add_device = ap325rxa_camera_add, - .del_device = ap325rxa_camera_del, - .module_name = "soc_camera_platform", - }, +}; + +struct soc_camera_link camera_link = { + .bus_id = 0, + .add_device = ap325rxa_camera_add, + .del_device = ap325rxa_camera_del, + .module_name = "soc_camera_platform", + .priv = &camera_info, }; static void dummy_release(struct device *dev) @@ -347,7 +349,7 @@ static struct platform_device camera_device = { static int ap325rxa_camera_add(struct soc_camera_link *icl, struct device *dev) { - if (icl != &camera_info.link || camera_probe() <= 0) + if (icl != &camera_link || camera_probe() <= 0) return -ENODEV; camera_info.dev = dev; @@ -357,7 +359,7 @@ static int ap325rxa_camera_add(struct soc_camera_link *icl, static void ap325rxa_camera_del(struct soc_camera_link *icl) { - if (icl != &camera_info.link) + if (icl != &camera_link) return; platform_device_unregister(&camera_device); @@ -470,13 +472,15 @@ static struct ov772x_camera_info ov7725_info = { .buswidth = SOCAM_DATAWIDTH_8, .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP, .edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0), - .link = { - .bus_id = 0, - .power = ov7725_power, - .board_info = &ap325rxa_i2c_camera[0], - .i2c_adapter_id = 0, - .module_name = "ov772x", - }, +}; + +static struct soc_camera_link ov7725_link = { + .bus_id = 0, + .power = ov7725_power, + .board_info = &ap325rxa_i2c_camera[0], + .i2c_adapter_id = 0, + .module_name = "ov772x", + .priv = &ov7725_info, }; static struct platform_device ap325rxa_camera[] = { @@ -484,13 +488,13 @@ static struct platform_device ap325rxa_camera[] = { .name = "soc-camera-pdrv", .id = 0, .dev = { - .platform_data = &ov7725_info.link, + .platform_data = &ov7725_link, }, }, { .name = "soc-camera-pdrv", .id = 1, .dev = { - .platform_data = &camera_info.link, + .platform_data = &camera_link, }, }, }; diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index 9099b6da995..507c77be476 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c @@ -432,23 +432,27 @@ static struct i2c_board_info migor_i2c_camera[] = { static struct ov772x_camera_info ov7725_info = { .buswidth = SOCAM_DATAWIDTH_8, - .link = { - .power = ov7725_power, - .board_info = &migor_i2c_camera[0], - .i2c_adapter_id = 0, - .module_name = "ov772x", - }, +}; + +static struct soc_camera_link ov7725_link = { + .power = ov7725_power, + .board_info = &migor_i2c_camera[0], + .i2c_adapter_id = 0, + .module_name = "ov772x", + .priv = &ov7725_info, }; static struct tw9910_video_info tw9910_info = { .buswidth = SOCAM_DATAWIDTH_8, .mpout = TW9910_MPO_FIELD, - .link = { - .power = tw9910_power, - .board_info = &migor_i2c_camera[1], - .i2c_adapter_id = 0, - .module_name = "tw9910", - } +}; + +static struct soc_camera_link tw9910_link = { + .power = tw9910_power, + .board_info = &migor_i2c_camera[1], + .i2c_adapter_id = 0, + .module_name = "tw9910", + .priv = &tw9910_info, }; static struct platform_device migor_camera[] = { @@ -456,13 +460,13 @@ static struct platform_device migor_camera[] = { .name = "soc-camera-pdrv", .id = 0, .dev = { - .platform_data = &ov7725_info.link, + .platform_data = &ov7725_link, }, }, { .name = "soc-camera-pdrv", .id = 1, .dev = { - .platform_data = &tw9910_info.link, + .platform_data = &tw9910_link, }, }, }; diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c index 20522933346..dcb690cb5ae 100644 --- a/drivers/media/video/ov772x.c +++ b/drivers/media/video/ov772x.c @@ -1143,10 +1143,10 @@ static int ov772x_probe(struct i2c_client *client, } icl = to_soc_camera_link(icd); - if (!icl) + if (!icl || !icl->priv) return -EINVAL; - info = container_of(icl, struct ov772x_camera_info, link); + info = icl->priv; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { dev_err(&adapter->dev, diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index 3cb9ba6caa4..35373d8bf6a 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c @@ -955,10 +955,10 @@ static int tw9910_probe(struct i2c_client *client, } icl = to_soc_camera_link(icd); - if (!icl) + if (!icl || !icl->priv) return -EINVAL; - info = container_of(icl, struct tw9910_video_info, link); + info = icl->priv; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { dev_err(&client->dev, @@ -976,7 +976,7 @@ static int tw9910_probe(struct i2c_client *client, v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops); icd->ops = &tw9910_ops; - icd->iface = info->link.bus_id; + icd->iface = icl->bus_id; ret = tw9910_video_probe(icd, client); if (ret) { diff --git a/include/media/ov772x.h b/include/media/ov772x.h index 37bcd096dde..14c77efd6a8 100644 --- a/include/media/ov772x.h +++ b/include/media/ov772x.h @@ -55,7 +55,6 @@ struct ov772x_edge_ctrl { struct ov772x_camera_info { unsigned long buswidth; unsigned long flags; - struct soc_camera_link link; struct ov772x_edge_ctrl edgectrl; }; diff --git a/include/media/soc_camera_platform.h b/include/media/soc_camera_platform.h index bb70401b814..88b3b5747f6 100644 --- a/include/media/soc_camera_platform.h +++ b/include/media/soc_camera_platform.h @@ -23,7 +23,6 @@ struct soc_camera_platform_info { unsigned long bus_param; struct device *dev; int (*set_capture)(struct soc_camera_platform_info *info, int enable); - struct soc_camera_link link; }; #endif /* __SOC_CAMERA_H__ */ diff --git a/include/media/tw9910.h b/include/media/tw9910.h index 73231e7880d..5e2895a05e6 100644 --- a/include/media/tw9910.h +++ b/include/media/tw9910.h @@ -32,7 +32,6 @@ enum tw9910_mpout_pin { struct tw9910_video_info { unsigned long buswidth; enum tw9910_mpout_pin mpout; - struct soc_camera_link link; }; -- cgit v1.2.3-70-g09d2 From 6d74e5f361bdacfdcfe14220868d562368aaadc2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 11 Dec 2009 11:34:50 -0300 Subject: V4L/DVB (13652): tw9910: Add revision control Also fix a badly chosen macro name. Signed-off-by: Kuninori Morimoto Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tw9910.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index 35373d8bf6a..e3a4942e0f3 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c @@ -29,7 +29,7 @@ #include #define GET_ID(val) ((val & 0xF8) >> 3) -#define GET_ReV(val) (val & 0x07) +#define GET_REV(val) (val & 0x07) /* * register offset @@ -225,6 +225,7 @@ struct tw9910_priv { struct v4l2_subdev subdev; struct tw9910_video_info *info; const struct tw9910_scale_ctrl *scale; + u32 revision; }; /* @@ -575,8 +576,11 @@ static int tw9910_enum_input(struct soc_camera_device *icd, static int tw9910_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) { + struct i2c_client *client = sd->priv; + struct tw9910_priv *priv = to_tw9910(client); + id->ident = V4L2_IDENT_TW9910; - id->revision = 0; + id->revision = priv->revision; return 0; } @@ -886,16 +890,18 @@ static int tw9910_video_probe(struct soc_camera_device *icd, * So far only revisions 0 and 1 have been seen */ val = i2c_smbus_read_byte_data(client, ID); + priv->revision = GET_REV(val); if (0x0B != GET_ID(val) || - 0x01 < GET_ReV(val)) { + 0x01 < priv->revision) { dev_err(&client->dev, - "Product ID error %x:%x\n", GET_ID(val), GET_ReV(val)); + "Product ID error %x:%x\n", + GET_ID(val), priv->revision); return -ENODEV; } dev_info(&client->dev, - "tw9910 Product ID %0x:%0x\n", GET_ID(val), GET_ReV(val)); + "tw9910 Product ID %0x:%0x\n", GET_ID(val), priv->revision); icd->vdev->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL; icd->vdev->current_norm = V4L2_STD_NTSC; -- cgit v1.2.3-70-g09d2 From 88a67c51dfc649c18fc8828970cb4fd09d1871b5 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 11 Dec 2009 11:34:50 -0300 Subject: V4L/DVB (13653): tw9910: simplify chip ID calculation Signed-off-by: Kuninori Morimoto Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tw9910.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index e3a4942e0f3..3d8a45f0eb2 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c @@ -863,7 +863,7 @@ static int tw9910_video_probe(struct soc_camera_device *icd, struct i2c_client *client) { struct tw9910_priv *priv = to_tw9910(client); - s32 val; + s32 id; /* * We must have a parent by now. And it cannot be a wrong one. @@ -889,19 +889,20 @@ static int tw9910_video_probe(struct soc_camera_device *icd, * check and show Product ID * So far only revisions 0 and 1 have been seen */ - val = i2c_smbus_read_byte_data(client, ID); - priv->revision = GET_REV(val); + id = i2c_smbus_read_byte_data(client, ID); + priv->revision = GET_REV(id); + id = GET_ID(id); - if (0x0B != GET_ID(val) || + if (0x0B != id || 0x01 < priv->revision) { dev_err(&client->dev, "Product ID error %x:%x\n", - GET_ID(val), priv->revision); + id, priv->revision); return -ENODEV; } dev_info(&client->dev, - "tw9910 Product ID %0x:%0x\n", GET_ID(val), priv->revision); + "tw9910 Product ID %0x:%0x\n", id, priv->revision); icd->vdev->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL; icd->vdev->current_norm = V4L2_STD_NTSC; -- cgit v1.2.3-70-g09d2 From 06f292e4806fcec2e7b2356c41241f5b6c4e3afb Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 11 Dec 2009 11:34:50 -0300 Subject: V4L/DVB (13654): tw9910: Tri-state pins when idle Tri-state all pins when not streaming to save power. Signed-off-by: Kuninori Morimoto Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tw9910.c | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index 3d8a45f0eb2..80b214efb24 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c @@ -152,7 +152,10 @@ /* 1 : non-auto */ #define VSCTL 0x08 /* 1 : Vertical out ctrl by DVALID */ /* 0 : Vertical out ctrl by HACTIVE and DVALID */ -#define OEN 0x04 /* Output Enable together with TRI_SEL. */ +#define OEN_TRI_SEL_MASK 0x07 +#define OEN_TRI_SEL_ALL_ON 0x00 /* Enable output for Rev0/Rev1 */ +#define OEN_TRI_SEL_ALL_OFF_r0 0x06 /* All tri-stated for Rev0 */ +#define OEN_TRI_SEL_ALL_OFF_r1 0x07 /* All tri-stated for Rev1 */ /* OUTCTR1 */ #define VSP_LO 0x00 /* 0 : VS pin output polarity is active low */ @@ -236,7 +239,6 @@ struct tw9910_priv { static const struct regval_list tw9910_default_regs[] = { - { OPFORM, 0x00 }, { OUTCTR1, VSP_LO | VSSL_VVALID | HSP_HI | HSSL_HSYNC }, ENDMARKER, }; @@ -519,20 +521,35 @@ static int tw9910_s_stream(struct v4l2_subdev *sd, int enable) struct i2c_client *client = sd->priv; struct tw9910_priv *priv = to_tw9910(client); - if (!enable) - return 0; + u8 val; - if (!priv->scale) { - dev_err(&client->dev, "norm select error\n"); - return -EPERM; - } + if (!enable) { + switch (priv->revision) { + case 0: + val = OEN_TRI_SEL_ALL_OFF_r0; + break; + case 1: + val = OEN_TRI_SEL_ALL_OFF_r1; + break; + default: + dev_err(&client->dev, "un-supported revision\n"); + return -EINVAL; + } + } else { + val = OEN_TRI_SEL_ALL_ON; - dev_dbg(&client->dev, "%s %dx%d\n", - priv->scale->name, - priv->scale->width, - priv->scale->height); + if (!priv->scale) { + dev_err(&client->dev, "norm select error\n"); + return -EPERM; + } - return 0; + dev_dbg(&client->dev, "%s %dx%d\n", + priv->scale->name, + priv->scale->width, + priv->scale->height); + } + + return tw9910_mask_set(client, OPFORM, OEN_TRI_SEL_MASK, val); } static int tw9910_set_bus_param(struct soc_camera_device *icd, -- cgit v1.2.3-70-g09d2 From 607e5ad8d596495341fa0a13e0a23121ee6053b6 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 11 Dec 2009 11:34:50 -0300 Subject: V4L/DVB (13655): tw9910: Add power control Power down internal blocks when not streaming. Signed-off-by: Kuninori Morimoto Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tw9910.c | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index 80b214efb24..c21acedcf02 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c @@ -181,6 +181,14 @@ * but all register content remain unchanged. * This bit is self-resetting. */ +#define ACNTL1_PDN_MASK 0x0e +#define CLK_PDN 0x08 /* system clock power down */ +#define Y_PDN 0x04 /* Luma ADC power down */ +#define C_PDN 0x02 /* Chroma ADC power down */ + +/* ACNTL2 */ +#define ACNTL2_PDN_MASK 0x40 +#define PLL_PDN 0x40 /* PLL power down */ /* VBICNTL */ @@ -478,10 +486,31 @@ static int tw9910_mask_set(struct i2c_client *client, u8 command, static void tw9910_reset(struct i2c_client *client) { - i2c_smbus_write_byte_data(client, ACNTL1, SRESET); + tw9910_mask_set(client, ACNTL1, SRESET, SRESET); msleep(1); } +static int tw9910_power(struct i2c_client *client, int enable) +{ + int ret; + u8 acntl1; + u8 acntl2; + + if (enable) { + acntl1 = 0; + acntl2 = 0; + } else { + acntl1 = CLK_PDN | Y_PDN | C_PDN; + acntl2 = PLL_PDN; + } + + ret = tw9910_mask_set(client, ACNTL1, ACNTL1_PDN_MASK, acntl1); + if (ret < 0) + return ret; + + return tw9910_mask_set(client, ACNTL2, ACNTL2_PDN_MASK, acntl2); +} + static const struct tw9910_scale_ctrl* tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height) { @@ -520,8 +549,8 @@ static int tw9910_s_stream(struct v4l2_subdev *sd, int enable) { struct i2c_client *client = sd->priv; struct tw9910_priv *priv = to_tw9910(client); - u8 val; + int ret; if (!enable) { switch (priv->revision) { @@ -549,7 +578,11 @@ static int tw9910_s_stream(struct v4l2_subdev *sd, int enable) priv->scale->height); } - return tw9910_mask_set(client, OPFORM, OEN_TRI_SEL_MASK, val); + ret = tw9910_mask_set(client, OPFORM, OEN_TRI_SEL_MASK, val); + if (ret < 0) + return ret; + + return tw9910_power(client, enable); } static int tw9910_set_bus_param(struct soc_camera_device *icd, -- cgit v1.2.3-70-g09d2 From 207970838186b2606896b03f590b89b13570a727 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 11 Dec 2009 11:34:51 -0300 Subject: V4L/DVB (13656): tw9910: tw9910_set_hsync clean up tw9910_set_hsync should use tw9910_mask_set to set bits 2-0 Signed-off-by: Kuninori Morimoto Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tw9910.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index c21acedcf02..2256ba6e614 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c @@ -371,6 +371,19 @@ static struct tw9910_priv *to_tw9910(const struct i2c_client *client) subdev); } +static int tw9910_mask_set(struct i2c_client *client, u8 command, + u8 mask, u8 set) +{ + s32 val = i2c_smbus_read_byte_data(client, command); + if (val < 0) + return val; + + val &= ~mask; + val |= set & mask; + + return i2c_smbus_write_byte_data(client, command, val); +} + static int tw9910_set_scale(struct i2c_client *client, const struct tw9910_scale_ctrl *scale) { @@ -445,14 +458,9 @@ static int tw9910_set_hsync(struct i2c_client *client, return ret; /* bit 2 - 0 */ - ret = i2c_smbus_read_byte_data(client, HSLOWCTL); - if (ret < 0) - return ret; - - ret = i2c_smbus_write_byte_data(client, HSLOWCTL, - (ret & 0x88) | - (hsync->start & 0x0007) << 4 | - (hsync->end & 0x0007)); + ret = tw9910_mask_set(client, HSLOWCTL, 0x77, + (hsync->start & 0x0007) << 4 | + (hsync->end & 0x0007)); return ret; } @@ -471,19 +479,6 @@ static int tw9910_write_array(struct i2c_client *client, return 0; } -static int tw9910_mask_set(struct i2c_client *client, u8 command, - u8 mask, u8 set) -{ - s32 val = i2c_smbus_read_byte_data(client, command); - if (val < 0) - return val; - - val &= ~mask; - val |= set & mask; - - return i2c_smbus_write_byte_data(client, command, val); -} - static void tw9910_reset(struct i2c_client *client) { tw9910_mask_set(client, ACNTL1, SRESET, SRESET); -- cgit v1.2.3-70-g09d2 From faa582610d87edf3ae1d07710a8f7e11c105686c Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 11 Dec 2009 11:34:51 -0300 Subject: V4L/DVB (13657): tw9910: Add revision control to tw9910_set_hsync Bits 10-3 of hsync control are the same for Rev0 and Rev1, but only Rev1 also has bits 2-0 for hsync. Account for this difference and also fix a register name. Signed-off-by: Kuninori Morimoto Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tw9910.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index 2256ba6e614..8ec1031dacc 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c @@ -117,7 +117,7 @@ #define LCTL24 0x68 #define LCTL25 0x69 #define LCTL26 0x6A -#define HSGEGIN 0x6B +#define HSBEGIN 0x6B #define HSEND 0x6C #define OVSDLY 0x6D #define OVSEND 0x6E @@ -443,10 +443,11 @@ static int tw9910_set_cropping(struct i2c_client *client, static int tw9910_set_hsync(struct i2c_client *client, const struct tw9910_hsync_ctrl *hsync) { + struct tw9910_priv *priv = to_tw9910(client); int ret; /* bit 10 - 3 */ - ret = i2c_smbus_write_byte_data(client, HSGEGIN, + ret = i2c_smbus_write_byte_data(client, HSBEGIN, (hsync->start & 0x07F8) >> 3); if (ret < 0) return ret; @@ -457,10 +458,12 @@ static int tw9910_set_hsync(struct i2c_client *client, if (ret < 0) return ret; + /* So far only revisions 0 and 1 have been seen */ /* bit 2 - 0 */ - ret = tw9910_mask_set(client, HSLOWCTL, 0x77, - (hsync->start & 0x0007) << 4 | - (hsync->end & 0x0007)); + if (1 == priv->revision) + ret = tw9910_mask_set(client, HSLOWCTL, 0x77, + (hsync->start & 0x0007) << 4 | + (hsync->end & 0x0007)); return ret; } -- cgit v1.2.3-70-g09d2 From 9a74251d8bee7a25fee89a0be3ccea73e01c1a05 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 11 Dec 2009 11:41:28 -0300 Subject: V4L/DVB (13658): v4l: add a media-bus API for configuring v4l2 subdev pixel and frame formats Video subdevices, like cameras, decoders, connect to video bridges over specialised busses. Data is being transferred over these busses in various formats, which only loosely correspond to fourcc codes, describing how video data is stored in RAM. This is not a one-to-one correspondence, therefore we cannot use fourcc codes to configure subdevice output data formats. This patch adds codes for several such on-the-bus formats and an API, similar to the familiar .s_fmt(), .g_fmt(), .try_fmt(), .enum_fmt() API for configuring those codes. After all users of the old API in struct v4l2_subdev_video_ops are converted, it will be removed. Also add helper routines to support generic pass-through mode for the soc-camera framework. create mode 100644 drivers/media/video/soc_mediabus.c create mode 100644 include/media/soc_mediabus.h create mode 100644 include/media/v4l2-mediabus.h Signed-off-by: Guennadi Liakhovetski Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Makefile | 2 +- drivers/media/video/soc_mediabus.c | 157 +++++++++++++++++++++++++++++++++++++ include/media/soc_mediabus.h | 65 +++++++++++++++ include/media/v4l2-mediabus.h | 61 ++++++++++++++ include/media/v4l2-subdev.h | 18 ++++- 5 files changed, 301 insertions(+), 2 deletions(-) create mode 100644 drivers/media/video/soc_mediabus.c create mode 100644 include/media/soc_mediabus.h create mode 100644 include/media/v4l2-mediabus.h (limited to 'drivers/media') diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 7a2dcc34111..e7bc8daae06 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -149,7 +149,7 @@ obj-$(CONFIG_VIDEO_VIVI) += vivi.o obj-$(CONFIG_VIDEO_CX23885) += cx23885/ obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o -obj-$(CONFIG_SOC_CAMERA) += soc_camera.o +obj-$(CONFIG_SOC_CAMERA) += soc_camera.o soc_mediabus.o obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o # soc-camera host drivers have to be linked after camera drivers obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/video/soc_mediabus.c new file mode 100644 index 00000000000..f8d5c87dc2a --- /dev/null +++ b/drivers/media/video/soc_mediabus.c @@ -0,0 +1,157 @@ +/* + * soc-camera media bus helper routines + * + * Copyright (C) 2009, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include + +#include +#include +#include + +#define MBUS_IDX(f) (V4L2_MBUS_FMT_ ## f - V4L2_MBUS_FMT_FIXED - 1) + +static const struct soc_mbus_pixelfmt mbus_fmt[] = { + [MBUS_IDX(YUYV8_2X8_LE)] = { + .fourcc = V4L2_PIX_FMT_YUYV, + .name = "YUYV", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + }, [MBUS_IDX(YVYU8_2X8_LE)] = { + .fourcc = V4L2_PIX_FMT_YVYU, + .name = "YVYU", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + }, [MBUS_IDX(YUYV8_2X8_BE)] = { + .fourcc = V4L2_PIX_FMT_UYVY, + .name = "UYVY", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + }, [MBUS_IDX(YVYU8_2X8_BE)] = { + .fourcc = V4L2_PIX_FMT_VYUY, + .name = "VYUY", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + }, [MBUS_IDX(RGB555_2X8_PADHI_LE)] = { + .fourcc = V4L2_PIX_FMT_RGB555, + .name = "RGB555", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + }, [MBUS_IDX(RGB555_2X8_PADHI_BE)] = { + .fourcc = V4L2_PIX_FMT_RGB555X, + .name = "RGB555X", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + }, [MBUS_IDX(RGB565_2X8_LE)] = { + .fourcc = V4L2_PIX_FMT_RGB565, + .name = "RGB565", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + }, [MBUS_IDX(RGB565_2X8_BE)] = { + .fourcc = V4L2_PIX_FMT_RGB565X, + .name = "RGB565X", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + }, [MBUS_IDX(SBGGR8_1X8)] = { + .fourcc = V4L2_PIX_FMT_SBGGR8, + .name = "Bayer 8 BGGR", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_NONE, + .order = SOC_MBUS_ORDER_LE, + }, [MBUS_IDX(SBGGR10_1X10)] = { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .name = "Bayer 10 BGGR", + .bits_per_sample = 10, + .packing = SOC_MBUS_PACKING_EXTEND16, + .order = SOC_MBUS_ORDER_LE, + }, [MBUS_IDX(GREY8_1X8)] = { + .fourcc = V4L2_PIX_FMT_GREY, + .name = "Grey", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_NONE, + .order = SOC_MBUS_ORDER_LE, + }, [MBUS_IDX(Y10_1X10)] = { + .fourcc = V4L2_PIX_FMT_Y10, + .name = "Grey 10bit", + .bits_per_sample = 10, + .packing = SOC_MBUS_PACKING_EXTEND16, + .order = SOC_MBUS_ORDER_LE, + }, [MBUS_IDX(SBGGR10_2X8_PADHI_LE)] = { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .name = "Bayer 10 BGGR", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + }, [MBUS_IDX(SBGGR10_2X8_PADLO_LE)] = { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .name = "Bayer 10 BGGR", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADLO, + .order = SOC_MBUS_ORDER_LE, + }, [MBUS_IDX(SBGGR10_2X8_PADHI_BE)] = { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .name = "Bayer 10 BGGR", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_BE, + }, [MBUS_IDX(SBGGR10_2X8_PADLO_BE)] = { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .name = "Bayer 10 BGGR", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADLO, + .order = SOC_MBUS_ORDER_BE, + }, +}; + +s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf) +{ + switch (mf->packing) { + case SOC_MBUS_PACKING_NONE: + return width * mf->bits_per_sample / 8; + case SOC_MBUS_PACKING_2X8_PADHI: + case SOC_MBUS_PACKING_2X8_PADLO: + case SOC_MBUS_PACKING_EXTEND16: + return width * 2; + } + return -EINVAL; +} +EXPORT_SYMBOL(soc_mbus_bytes_per_line); + +const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc( + enum v4l2_mbus_pixelcode code) +{ + if ((unsigned int)(code - V4L2_MBUS_FMT_FIXED) > ARRAY_SIZE(mbus_fmt)) + return NULL; + return mbus_fmt + code - V4L2_MBUS_FMT_FIXED - 1; +} +EXPORT_SYMBOL(soc_mbus_get_fmtdesc); + +static int __init soc_mbus_init(void) +{ + return 0; +} + +static void __exit soc_mbus_exit(void) +{ +} + +module_init(soc_mbus_init); +module_exit(soc_mbus_exit); + +MODULE_DESCRIPTION("soc-camera media bus interface"); +MODULE_AUTHOR("Guennadi Liakhovetski "); +MODULE_LICENSE("GPL v2"); diff --git a/include/media/soc_mediabus.h b/include/media/soc_mediabus.h new file mode 100644 index 00000000000..037cd7be001 --- /dev/null +++ b/include/media/soc_mediabus.h @@ -0,0 +1,65 @@ +/* + * SoC-camera Media Bus API extensions + * + * Copyright (C) 2009, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef SOC_MEDIABUS_H +#define SOC_MEDIABUS_H + +#include + +#include + +/** + * enum soc_mbus_packing - data packing types on the media-bus + * @SOC_MBUS_PACKING_NONE: no packing, bit-for-bit transfer to RAM + * @SOC_MBUS_PACKING_2X8_PADHI: 16 bits transferred in 2 8-bit samples, in the + * possibly incomplete byte high bits are padding + * @SOC_MBUS_PACKING_2X8_PADLO: as above, but low bits are padding + * @SOC_MBUS_PACKING_EXTEND16: sample width (e.g., 10 bits) has to be extended + * to 16 bits + */ +enum soc_mbus_packing { + SOC_MBUS_PACKING_NONE, + SOC_MBUS_PACKING_2X8_PADHI, + SOC_MBUS_PACKING_2X8_PADLO, + SOC_MBUS_PACKING_EXTEND16, +}; + +/** + * enum soc_mbus_order - sample order on the media bus + * @SOC_MBUS_ORDER_LE: least significant sample first + * @SOC_MBUS_ORDER_BE: most significant sample first + */ +enum soc_mbus_order { + SOC_MBUS_ORDER_LE, + SOC_MBUS_ORDER_BE, +}; + +/** + * struct soc_mbus_pixelfmt - Data format on the media bus + * @name: Name of the format + * @fourcc: Fourcc code, that will be obtained if the data is + * stored in memory in the following way: + * @packing: Type of sample-packing, that has to be used + * @order: Sample order when storing in memory + * @bits_per_sample: How many bits the bridge has to sample + */ +struct soc_mbus_pixelfmt { + const char *name; + u32 fourcc; + enum soc_mbus_packing packing; + enum soc_mbus_order order; + u8 bits_per_sample; +}; + +const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc( + enum v4l2_mbus_pixelcode code); +s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf); + +#endif diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h new file mode 100644 index 00000000000..0dbe02ada25 --- /dev/null +++ b/include/media/v4l2-mediabus.h @@ -0,0 +1,61 @@ +/* + * Media Bus API header + * + * Copyright (C) 2009, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef V4L2_MEDIABUS_H +#define V4L2_MEDIABUS_H + +/* + * These pixel codes uniquely identify data formats on the media bus. Mostly + * they correspond to similarly named V4L2_PIX_FMT_* formats, format 0 is + * reserved, V4L2_MBUS_FMT_FIXED shall be used by host-client pairs, where the + * data format is fixed. Additionally, "2X8" means that one pixel is transferred + * in two 8-bit samples, "BE" or "LE" specify in which order those samples are + * transferred over the bus: "LE" means that the least significant bits are + * transferred first, "BE" means that the most significant bits are transferred + * first, and "PADHI" and "PADLO" define which bits - low or high, in the + * incomplete high byte, are filled with padding bits. + */ +enum v4l2_mbus_pixelcode { + V4L2_MBUS_FMT_FIXED = 1, + V4L2_MBUS_FMT_YUYV8_2X8_LE, + V4L2_MBUS_FMT_YVYU8_2X8_LE, + V4L2_MBUS_FMT_YUYV8_2X8_BE, + V4L2_MBUS_FMT_YVYU8_2X8_BE, + V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, + V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, + V4L2_MBUS_FMT_RGB565_2X8_LE, + V4L2_MBUS_FMT_RGB565_2X8_BE, + V4L2_MBUS_FMT_SBGGR8_1X8, + V4L2_MBUS_FMT_SBGGR10_1X10, + V4L2_MBUS_FMT_GREY8_1X8, + V4L2_MBUS_FMT_Y10_1X10, + V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, + V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE, + V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, + V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, +}; + +/** + * struct v4l2_mbus_framefmt - frame format on the media bus + * @width: frame width + * @height: frame height + * @code: data format code + * @field: used interlacing type + * @colorspace: colorspace of the data + */ +struct v4l2_mbus_framefmt { + __u32 width; + __u32 height; + enum v4l2_mbus_pixelcode code; + enum v4l2_field field; + enum v4l2_colorspace colorspace; +}; + +#endif diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index a128458dc9e..9ba99cd39ee 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -22,6 +22,7 @@ #define _V4L2_SUBDEV_H #include +#include /* generic v4l2_device notify callback notification values */ #define V4L2_SUBDEV_IR_RX_NOTIFY _IOW('v', 0, u32) @@ -207,7 +208,7 @@ struct v4l2_subdev_audio_ops { s_std_output: set v4l2_std_id for video OUTPUT devices. This is ignored by video input devices. - s_crystal_freq: sets the frequency of the crystal used to generate the + s_crystal_freq: sets the frequency of the crystal used to generate the clocks in Hz. An extra flags field allows device specific configuration regarding clock frequency dividers, etc. If not used, then set flags to 0. If the frequency is not supported, then -EINVAL is returned. @@ -230,6 +231,13 @@ struct v4l2_subdev_audio_ops { g_dv_timings(): Get custom dv timings in the sub device. + enum_mbus_fmt: enumerate pixel formats, provided by a video data source + + g_mbus_fmt: get the current pixel format, provided by a video data source + + try_mbus_fmt: try to set a pixel format on a video data source + + s_mbus_fmt: set a pixel format on a video data source */ struct v4l2_subdev_video_ops { int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config); @@ -261,6 +269,14 @@ struct v4l2_subdev_video_ops { struct v4l2_dv_timings *timings); int (*g_dv_timings)(struct v4l2_subdev *sd, struct v4l2_dv_timings *timings); + int (*enum_mbus_fmt)(struct v4l2_subdev *sd, int index, + enum v4l2_mbus_pixelcode *code); + int (*g_mbus_fmt)(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt); + int (*try_mbus_fmt)(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt); + int (*s_mbus_fmt)(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt); }; /** -- cgit v1.2.3-70-g09d2 From 760697beca338599a65484389c7abbe54aedb664 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 11 Dec 2009 11:46:49 -0300 Subject: V4L/DVB (13659): soc-camera: convert to the new mediabus API Convert soc-camera core and all soc-camera drivers to the new mediabus API. This also takes soc-camera client drivers one step closer to also be usable with generic v4l2-subdev host drivers. Signed-off-by: Guennadi Liakhovetski Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- arch/sh/boards/mach-ap325rxa/setup.c | 3 +- drivers/media/video/mt9m001.c | 141 ++++++---- drivers/media/video/mt9m111.c | 188 ++++++++------ drivers/media/video/mt9t031.c | 66 ++--- drivers/media/video/mt9v022.c | 150 ++++++----- drivers/media/video/mx1_camera.c | 90 +++++-- drivers/media/video/mx3_camera.c | 278 +++++++++++--------- drivers/media/video/ov772x.c | 229 ++++++++-------- drivers/media/video/ov9640.c | 107 +++++--- drivers/media/video/pxa_camera.c | 272 ++++++++++--------- drivers/media/video/rj54n1cb0c.c | 201 ++++++++++---- drivers/media/video/sh_mobile_ceu_camera.c | 403 +++++++++++++++++------------ drivers/media/video/soc_camera.c | 78 +++--- drivers/media/video/soc_camera_platform.c | 39 ++- drivers/media/video/tw9910.c | 91 +++---- include/media/soc_camera.h | 25 +- include/media/soc_camera_platform.h | 2 +- 17 files changed, 1383 insertions(+), 980 deletions(-) (limited to 'drivers/media') diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index 4c860288457..7a9f69663f1 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c @@ -316,8 +316,9 @@ static struct soc_camera_platform_info camera_info = { .format_name = "UYVY", .format_depth = 16, .format = { - .pixelformat = V4L2_PIX_FMT_UYVY, + .code = V4L2_MBUS_FMT_YUYV8_2X8_BE, .colorspace = V4L2_COLORSPACE_SMPTE170M, + .field = V4L2_FIELD_NONE, .width = 640, .height = 480, }, diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index cc9066000c2..b62c0bd3f8e 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c @@ -48,41 +48,46 @@ #define MT9M001_COLUMN_SKIP 20 #define MT9M001_ROW_SKIP 12 -static const struct soc_camera_data_format mt9m001_colour_formats[] = { +/* MT9M001 has only one fixed colorspace per pixelcode */ +struct mt9m001_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct mt9m001_datafmt *mt9m001_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct mt9m001_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} + +static const struct mt9m001_datafmt mt9m001_colour_fmts[] = { /* * Order important: first natively supported, * second supported with a GPIO extender */ - { - .name = "Bayer (sRGB) 10 bit", - .depth = 10, - .fourcc = V4L2_PIX_FMT_SBGGR16, - .colorspace = V4L2_COLORSPACE_SRGB, - }, { - .name = "Bayer (sRGB) 8 bit", - .depth = 8, - .fourcc = V4L2_PIX_FMT_SBGGR8, - .colorspace = V4L2_COLORSPACE_SRGB, - } + {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, + {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, }; -static const struct soc_camera_data_format mt9m001_monochrome_formats[] = { +static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = { /* Order important - see above */ - { - .name = "Monochrome 10 bit", - .depth = 10, - .fourcc = V4L2_PIX_FMT_Y16, - }, { - .name = "Monochrome 8 bit", - .depth = 8, - .fourcc = V4L2_PIX_FMT_GREY, - }, + {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_GREY8_1X8, V4L2_COLORSPACE_JPEG}, }; struct mt9m001 { struct v4l2_subdev subdev; struct v4l2_rect rect; /* Sensor window */ - __u32 fourcc; + const struct mt9m001_datafmt *fmt; + const struct mt9m001_datafmt *fmts; + int num_fmts; int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ unsigned int gain; unsigned int exposure; @@ -209,8 +214,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) const u16 hblank = 9, vblank = 25; unsigned int total_h; - if (mt9m001->fourcc == V4L2_PIX_FMT_SBGGR8 || - mt9m001->fourcc == V4L2_PIX_FMT_SBGGR16) + if (mt9m001->fmts == mt9m001_colour_fmts) /* * Bayer format - even number of rows for simplicity, * but let the user play with the top row. @@ -290,32 +294,32 @@ static int mt9m001_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) return 0; } -static int mt9m001_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int mt9m001_g_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct mt9m001 *mt9m001 = to_mt9m001(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = mt9m001->rect.width; - pix->height = mt9m001->rect.height; - pix->pixelformat = mt9m001->fourcc; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_SRGB; + mf->width = mt9m001->rect.width; + mf->height = mt9m001->rect.height; + mf->code = mt9m001->fmt->code; + mf->colorspace = mt9m001->fmt->colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } -static int mt9m001_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int mt9m001_s_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct mt9m001 *mt9m001 = to_mt9m001(client); - struct v4l2_pix_format *pix = &f->fmt.pix; struct v4l2_crop a = { .c = { .left = mt9m001->rect.left, .top = mt9m001->rect.top, - .width = pix->width, - .height = pix->height, + .width = mf->width, + .height = mf->height, }, }; int ret; @@ -323,28 +327,39 @@ static int mt9m001_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) /* No support for scaling so far, just crop. TODO: use skipping */ ret = mt9m001_s_crop(sd, &a); if (!ret) { - pix->width = mt9m001->rect.width; - pix->height = mt9m001->rect.height; - mt9m001->fourcc = pix->pixelformat; + mf->width = mt9m001->rect.width; + mf->height = mt9m001->rect.height; + mt9m001->fmt = mt9m001_find_datafmt(mf->code, + mt9m001->fmts, mt9m001->num_fmts); + mf->colorspace = mt9m001->fmt->colorspace; } return ret; } -static int mt9m001_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int mt9m001_try_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct mt9m001 *mt9m001 = to_mt9m001(client); - struct v4l2_pix_format *pix = &f->fmt.pix; + const struct mt9m001_datafmt *fmt; - v4l_bound_align_image(&pix->width, MT9M001_MIN_WIDTH, + v4l_bound_align_image(&mf->width, MT9M001_MIN_WIDTH, MT9M001_MAX_WIDTH, 1, - &pix->height, MT9M001_MIN_HEIGHT + mt9m001->y_skip_top, + &mf->height, MT9M001_MIN_HEIGHT + mt9m001->y_skip_top, MT9M001_MAX_HEIGHT + mt9m001->y_skip_top, 0, 0); - if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8 || - pix->pixelformat == V4L2_PIX_FMT_SBGGR16) - pix->height = ALIGN(pix->height - 1, 2); + if (mt9m001->fmts == mt9m001_colour_fmts) + mf->height = ALIGN(mf->height - 1, 2); + + fmt = mt9m001_find_datafmt(mf->code, mt9m001->fmts, + mt9m001->num_fmts); + if (!fmt) { + fmt = mt9m001->fmt; + mf->code = fmt->code; + } + + mf->colorspace = fmt->colorspace; return 0; } @@ -608,11 +623,11 @@ static int mt9m001_video_probe(struct soc_camera_device *icd, case 0x8411: case 0x8421: mt9m001->model = V4L2_IDENT_MT9M001C12ST; - icd->formats = mt9m001_colour_formats; + mt9m001->fmts = mt9m001_colour_fmts; break; case 0x8431: mt9m001->model = V4L2_IDENT_MT9M001C12STM; - icd->formats = mt9m001_monochrome_formats; + mt9m001->fmts = mt9m001_monochrome_fmts; break; default: dev_err(&client->dev, @@ -620,7 +635,7 @@ static int mt9m001_video_probe(struct soc_camera_device *icd, return -ENODEV; } - icd->num_formats = 0; + mt9m001->num_fmts = 0; /* * This is a 10bit sensor, so by default we only allow 10bit. @@ -633,14 +648,14 @@ static int mt9m001_video_probe(struct soc_camera_device *icd, flags = SOCAM_DATAWIDTH_10; if (flags & SOCAM_DATAWIDTH_10) - icd->num_formats++; + mt9m001->num_fmts++; else - icd->formats++; + mt9m001->fmts++; if (flags & SOCAM_DATAWIDTH_8) - icd->num_formats++; + mt9m001->num_fmts++; - mt9m001->fourcc = icd->formats->fourcc; + mt9m001->fmt = &mt9m001->fmts[0]; dev_info(&client->dev, "Detected a MT9M001 chip ID %x (%s)\n", data, data == 0x8431 ? "C12STM" : "C12ST"); @@ -686,14 +701,28 @@ static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = { #endif }; +static int mt9m001_enum_fmt(struct v4l2_subdev *sd, int index, + enum v4l2_mbus_pixelcode *code) +{ + struct i2c_client *client = sd->priv; + struct mt9m001 *mt9m001 = to_mt9m001(client); + + if ((unsigned int)index >= mt9m001->num_fmts) + return -EINVAL; + + *code = mt9m001->fmts[index].code; + return 0; +} + static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = { .s_stream = mt9m001_s_stream, - .s_fmt = mt9m001_s_fmt, - .g_fmt = mt9m001_g_fmt, - .try_fmt = mt9m001_try_fmt, + .s_mbus_fmt = mt9m001_s_fmt, + .g_mbus_fmt = mt9m001_g_fmt, + .try_mbus_fmt = mt9m001_try_fmt, .s_crop = mt9m001_s_crop, .g_crop = mt9m001_g_crop, .cropcap = mt9m001_cropcap, + .enum_mbus_fmt = mt9m001_enum_fmt, }; static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = { diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 30db625455e..d35f536f9fc 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -123,23 +123,34 @@ #define MT9M111_MAX_HEIGHT 1024 #define MT9M111_MAX_WIDTH 1280 -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } -#define RGB_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_SRGB) -#define JPG_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) - -static const struct soc_camera_data_format mt9m111_colour_formats[] = { - JPG_FMT("CbYCrY 16 bit", 16, V4L2_PIX_FMT_UYVY), - JPG_FMT("CrYCbY 16 bit", 16, V4L2_PIX_FMT_VYUY), - JPG_FMT("YCbYCr 16 bit", 16, V4L2_PIX_FMT_YUYV), - JPG_FMT("YCrYCb 16 bit", 16, V4L2_PIX_FMT_YVYU), - RGB_FMT("RGB 565", 16, V4L2_PIX_FMT_RGB565), - RGB_FMT("RGB 555", 16, V4L2_PIX_FMT_RGB555), - RGB_FMT("Bayer (sRGB) 10 bit", 10, V4L2_PIX_FMT_SBGGR16), - RGB_FMT("Bayer (sRGB) 8 bit", 8, V4L2_PIX_FMT_SBGGR8), +/* MT9M111 has only one fixed colorspace per pixelcode */ +struct mt9m111_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct mt9m111_datafmt *mt9m111_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct mt9m111_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} + +static const struct mt9m111_datafmt mt9m111_colour_fmts[] = { + {V4L2_MBUS_FMT_YUYV8_2X8_LE, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YVYU8_2X8_LE, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8_BE, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YVYU8_2X8_BE, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, + {V4L2_MBUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB}, + {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, + {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, }; enum mt9m111_context { @@ -152,7 +163,7 @@ struct mt9m111 { int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */ enum mt9m111_context context; struct v4l2_rect rect; - u32 pixfmt; + const struct mt9m111_datafmt *fmt; unsigned int gain; unsigned char autoexposure; unsigned char datawidth; @@ -258,8 +269,8 @@ static int mt9m111_setup_rect(struct i2c_client *client, int width = rect->width; int height = rect->height; - if (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8 || - mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16) + if (mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8 || + mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) is_raw_format = 1; else is_raw_format = 0; @@ -307,7 +318,8 @@ static int mt9m111_setup_pixfmt(struct i2c_client *client, u16 outfmt) static int mt9m111_setfmt_bayer8(struct i2c_client *client) { - return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_PROCESSED_BAYER); + return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_PROCESSED_BAYER | + MT9M111_OUTFMT_RGB); } static int mt9m111_setfmt_bayer10(struct i2c_client *client) @@ -401,8 +413,8 @@ static int mt9m111_make_rect(struct i2c_client *client, { struct mt9m111 *mt9m111 = to_mt9m111(client); - if (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8 || - mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16) { + if (mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8 || + mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) { /* Bayer format - even size lengths */ rect->width = ALIGN(rect->width, 2); rect->height = ALIGN(rect->height, 2); @@ -460,120 +472,139 @@ static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) return 0; } -static int mt9m111_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int mt9m111_g_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct mt9m111 *mt9m111 = to_mt9m111(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = mt9m111->rect.width; - pix->height = mt9m111->rect.height; - pix->pixelformat = mt9m111->pixfmt; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_SRGB; + mf->width = mt9m111->rect.width; + mf->height = mt9m111->rect.height; + mf->code = mt9m111->fmt->code; + mf->field = V4L2_FIELD_NONE; return 0; } -static int mt9m111_set_pixfmt(struct i2c_client *client, u32 pixfmt) +static int mt9m111_set_pixfmt(struct i2c_client *client, + enum v4l2_mbus_pixelcode code) { struct mt9m111 *mt9m111 = to_mt9m111(client); int ret; - switch (pixfmt) { - case V4L2_PIX_FMT_SBGGR8: + switch (code) { + case V4L2_MBUS_FMT_SBGGR8_1X8: ret = mt9m111_setfmt_bayer8(client); break; - case V4L2_PIX_FMT_SBGGR16: + case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE: ret = mt9m111_setfmt_bayer10(client); break; - case V4L2_PIX_FMT_RGB555: + case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: ret = mt9m111_setfmt_rgb555(client); break; - case V4L2_PIX_FMT_RGB565: + case V4L2_MBUS_FMT_RGB565_2X8_LE: ret = mt9m111_setfmt_rgb565(client); break; - case V4L2_PIX_FMT_UYVY: + case V4L2_MBUS_FMT_YUYV8_2X8_BE: mt9m111->swap_yuv_y_chromas = 0; mt9m111->swap_yuv_cb_cr = 0; ret = mt9m111_setfmt_yuv(client); break; - case V4L2_PIX_FMT_VYUY: + case V4L2_MBUS_FMT_YVYU8_2X8_BE: mt9m111->swap_yuv_y_chromas = 0; mt9m111->swap_yuv_cb_cr = 1; ret = mt9m111_setfmt_yuv(client); break; - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8_LE: mt9m111->swap_yuv_y_chromas = 1; mt9m111->swap_yuv_cb_cr = 0; ret = mt9m111_setfmt_yuv(client); break; - case V4L2_PIX_FMT_YVYU: + case V4L2_MBUS_FMT_YVYU8_2X8_LE: mt9m111->swap_yuv_y_chromas = 1; mt9m111->swap_yuv_cb_cr = 1; ret = mt9m111_setfmt_yuv(client); break; default: dev_err(&client->dev, "Pixel format not handled : %x\n", - pixfmt); + code); ret = -EINVAL; } - if (!ret) - mt9m111->pixfmt = pixfmt; - return ret; } -static int mt9m111_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int mt9m111_s_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; + const struct mt9m111_datafmt *fmt; struct mt9m111 *mt9m111 = to_mt9m111(client); - struct v4l2_pix_format *pix = &f->fmt.pix; struct v4l2_rect rect = { .left = mt9m111->rect.left, .top = mt9m111->rect.top, - .width = pix->width, - .height = pix->height, + .width = mf->width, + .height = mf->height, }; int ret; + fmt = mt9m111_find_datafmt(mf->code, mt9m111_colour_fmts, + ARRAY_SIZE(mt9m111_colour_fmts)); + if (!fmt) + return -EINVAL; + dev_dbg(&client->dev, - "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", __func__, - pix->pixelformat, rect.left, rect.top, rect.width, rect.height); + "%s code=%x left=%d, top=%d, width=%d, height=%d\n", __func__, + mf->code, rect.left, rect.top, rect.width, rect.height); ret = mt9m111_make_rect(client, &rect); if (!ret) - ret = mt9m111_set_pixfmt(client, pix->pixelformat); - if (!ret) - mt9m111->rect = rect; + ret = mt9m111_set_pixfmt(client, mf->code); + if (!ret) { + mt9m111->rect = rect; + mt9m111->fmt = fmt; + mf->colorspace = fmt->colorspace; + } + return ret; } -static int mt9m111_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int mt9m111_try_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { - struct v4l2_pix_format *pix = &f->fmt.pix; - bool bayer = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 || - pix->pixelformat == V4L2_PIX_FMT_SBGGR16; + struct i2c_client *client = sd->priv; + struct mt9m111 *mt9m111 = to_mt9m111(client); + const struct mt9m111_datafmt *fmt; + bool bayer = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 || + mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE; + + fmt = mt9m111_find_datafmt(mf->code, mt9m111_colour_fmts, + ARRAY_SIZE(mt9m111_colour_fmts)); + if (!fmt) { + fmt = mt9m111->fmt; + mf->code = fmt->code; + } /* * With Bayer format enforce even side lengths, but let the user play * with the starting pixel */ - if (pix->height > MT9M111_MAX_HEIGHT) - pix->height = MT9M111_MAX_HEIGHT; - else if (pix->height < 2) - pix->height = 2; + if (mf->height > MT9M111_MAX_HEIGHT) + mf->height = MT9M111_MAX_HEIGHT; + else if (mf->height < 2) + mf->height = 2; else if (bayer) - pix->height = ALIGN(pix->height, 2); + mf->height = ALIGN(mf->height, 2); - if (pix->width > MT9M111_MAX_WIDTH) - pix->width = MT9M111_MAX_WIDTH; - else if (pix->width < 2) - pix->width = 2; + if (mf->width > MT9M111_MAX_WIDTH) + mf->width = MT9M111_MAX_WIDTH; + else if (mf->width < 2) + mf->width = 2; else if (bayer) - pix->width = ALIGN(pix->width, 2); + mf->width = ALIGN(mf->width, 2); + + mf->colorspace = fmt->colorspace; return 0; } @@ -863,7 +894,7 @@ static int mt9m111_restore_state(struct i2c_client *client) struct mt9m111 *mt9m111 = to_mt9m111(client); mt9m111_set_context(client, mt9m111->context); - mt9m111_set_pixfmt(client, mt9m111->pixfmt); + mt9m111_set_pixfmt(client, mt9m111->fmt->code); mt9m111_setup_rect(client, &mt9m111->rect); mt9m111_set_flip(client, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); mt9m111_set_flip(client, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); @@ -952,9 +983,6 @@ static int mt9m111_video_probe(struct soc_camera_device *icd, goto ei2c; } - icd->formats = mt9m111_colour_formats; - icd->num_formats = ARRAY_SIZE(mt9m111_colour_formats); - dev_info(&client->dev, "Detected a MT9M11x chip ID %x\n", data); ei2c: @@ -971,13 +999,24 @@ static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = { #endif }; +static int mt9m111_enum_fmt(struct v4l2_subdev *sd, int index, + enum v4l2_mbus_pixelcode *code) +{ + if ((unsigned int)index >= ARRAY_SIZE(mt9m111_colour_fmts)) + return -EINVAL; + + *code = mt9m111_colour_fmts[index].code; + return 0; +} + static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = { - .s_fmt = mt9m111_s_fmt, - .g_fmt = mt9m111_g_fmt, - .try_fmt = mt9m111_try_fmt, + .s_mbus_fmt = mt9m111_s_fmt, + .g_mbus_fmt = mt9m111_g_fmt, + .try_mbus_fmt = mt9m111_try_fmt, .s_crop = mt9m111_s_crop, .g_crop = mt9m111_g_crop, .cropcap = mt9m111_cropcap, + .enum_mbus_fmt = mt9m111_enum_fmt, }; static struct v4l2_subdev_ops mt9m111_subdev_ops = { @@ -1024,6 +1063,7 @@ static int mt9m111_probe(struct i2c_client *client, mt9m111->rect.top = MT9M111_MIN_DARK_ROWS; mt9m111->rect.width = MT9M111_MAX_WIDTH; mt9m111->rect.height = MT9M111_MAX_HEIGHT; + mt9m111->fmt = &mt9m111_colour_fmts[0]; ret = mt9m111_video_probe(icd, client); if (ret) { diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c index e3f664f21c4..69c227f65bc 100644 --- a/drivers/media/video/mt9t031.c +++ b/drivers/media/video/mt9t031.c @@ -60,15 +60,6 @@ SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH | \ SOCAM_MASTER | SOCAM_DATAWIDTH_10) -static const struct soc_camera_data_format mt9t031_colour_formats[] = { - { - .name = "Bayer (sRGB) 10 bit", - .depth = 10, - .fourcc = V4L2_PIX_FMT_SGRBG10, - .colorspace = V4L2_COLORSPACE_SRGB, - } -}; - struct mt9t031 { struct v4l2_subdev subdev; struct v4l2_rect rect; /* Sensor window */ @@ -378,27 +369,27 @@ static int mt9t031_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) return 0; } -static int mt9t031_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int mt9t031_g_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct mt9t031 *mt9t031 = to_mt9t031(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = mt9t031->rect.width / mt9t031->xskip; - pix->height = mt9t031->rect.height / mt9t031->yskip; - pix->pixelformat = V4L2_PIX_FMT_SGRBG10; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_SRGB; + mf->width = mt9t031->rect.width / mt9t031->xskip; + mf->height = mt9t031->rect.height / mt9t031->yskip; + mf->code = V4L2_MBUS_FMT_SBGGR10_1X10; + mf->colorspace = V4L2_COLORSPACE_SRGB; + mf->field = V4L2_FIELD_NONE; return 0; } -static int mt9t031_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int mt9t031_s_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct mt9t031 *mt9t031 = to_mt9t031(client); struct soc_camera_device *icd = client->dev.platform_data; - struct v4l2_pix_format *pix = &f->fmt.pix; u16 xskip, yskip; struct v4l2_rect rect = mt9t031->rect; @@ -406,8 +397,11 @@ static int mt9t031_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) * try_fmt has put width and height within limits. * S_FMT: use binning and skipping for scaling */ - xskip = mt9t031_skip(&rect.width, pix->width, MT9T031_MAX_WIDTH); - yskip = mt9t031_skip(&rect.height, pix->height, MT9T031_MAX_HEIGHT); + xskip = mt9t031_skip(&rect.width, mf->width, MT9T031_MAX_WIDTH); + yskip = mt9t031_skip(&rect.height, mf->height, MT9T031_MAX_HEIGHT); + + mf->code = V4L2_MBUS_FMT_SBGGR10_1X10; + mf->colorspace = V4L2_COLORSPACE_SRGB; /* mt9t031_set_params() doesn't change width and height */ return mt9t031_set_params(icd, &rect, xskip, yskip); @@ -417,13 +411,15 @@ static int mt9t031_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) * If a user window larger than sensor window is requested, we'll increase the * sensor window. */ -static int mt9t031_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int mt9t031_try_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { - struct v4l2_pix_format *pix = &f->fmt.pix; - v4l_bound_align_image( - &pix->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1, - &pix->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0); + &mf->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1, + &mf->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0); + + mf->code = V4L2_MBUS_FMT_SBGGR10_1X10; + mf->colorspace = V4L2_COLORSPACE_SRGB; return 0; } @@ -684,7 +680,6 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) */ static int mt9t031_video_probe(struct i2c_client *client) { - struct soc_camera_device *icd = client->dev.platform_data; struct mt9t031 *mt9t031 = to_mt9t031(client); s32 data; int ret; @@ -699,8 +694,6 @@ static int mt9t031_video_probe(struct i2c_client *client) switch (data) { case 0x1621: mt9t031->model = V4L2_IDENT_MT9T031; - icd->formats = mt9t031_colour_formats; - icd->num_formats = ARRAY_SIZE(mt9t031_colour_formats); break; default: dev_err(&client->dev, @@ -741,14 +734,25 @@ static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = { #endif }; +static int mt9t031_enum_fmt(struct v4l2_subdev *sd, int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index) + return -EINVAL; + + *code = V4L2_MBUS_FMT_SBGGR10_1X10; + return 0; +} + static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = { .s_stream = mt9t031_s_stream, - .s_fmt = mt9t031_s_fmt, - .g_fmt = mt9t031_g_fmt, - .try_fmt = mt9t031_try_fmt, + .s_mbus_fmt = mt9t031_s_fmt, + .g_mbus_fmt = mt9t031_g_fmt, + .try_mbus_fmt = mt9t031_try_fmt, .s_crop = mt9t031_s_crop, .g_crop = mt9t031_g_crop, .cropcap = mt9t031_cropcap, + .enum_mbus_fmt = mt9t031_enum_fmt, }; static struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = { diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index f60a9a107f2..91df7ec91fb 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c @@ -64,41 +64,46 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\""); #define MT9V022_COLUMN_SKIP 1 #define MT9V022_ROW_SKIP 4 -static const struct soc_camera_data_format mt9v022_colour_formats[] = { +/* MT9V022 has only one fixed colorspace per pixelcode */ +struct mt9v022_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct mt9v022_datafmt *mt9v022_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct mt9v022_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} + +static const struct mt9v022_datafmt mt9v022_colour_fmts[] = { /* * Order important: first natively supported, * second supported with a GPIO extender */ - { - .name = "Bayer (sRGB) 10 bit", - .depth = 10, - .fourcc = V4L2_PIX_FMT_SBGGR16, - .colorspace = V4L2_COLORSPACE_SRGB, - }, { - .name = "Bayer (sRGB) 8 bit", - .depth = 8, - .fourcc = V4L2_PIX_FMT_SBGGR8, - .colorspace = V4L2_COLORSPACE_SRGB, - } + {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, + {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, }; -static const struct soc_camera_data_format mt9v022_monochrome_formats[] = { +static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = { /* Order important - see above */ - { - .name = "Monochrome 10 bit", - .depth = 10, - .fourcc = V4L2_PIX_FMT_Y16, - }, { - .name = "Monochrome 8 bit", - .depth = 8, - .fourcc = V4L2_PIX_FMT_GREY, - }, + {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_GREY8_1X8, V4L2_COLORSPACE_JPEG}, }; struct mt9v022 { struct v4l2_subdev subdev; struct v4l2_rect rect; /* Sensor window */ - __u32 fourcc; + const struct mt9v022_datafmt *fmt; + const struct mt9v022_datafmt *fmts; + int num_fmts; int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */ u16 chip_control; unsigned short y_skip_top; /* Lines to skip at the top */ @@ -275,8 +280,7 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) int ret; /* Bayer format - even size lengths */ - if (mt9v022->fourcc == V4L2_PIX_FMT_SBGGR8 || - mt9v022->fourcc == V4L2_PIX_FMT_SBGGR16) { + if (mt9v022->fmts == mt9v022_colour_fmts) { rect.width = ALIGN(rect.width, 2); rect.height = ALIGN(rect.height, 2); /* Let the user play with the starting pixel */ @@ -354,32 +358,32 @@ static int mt9v022_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) return 0; } -static int mt9v022_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int mt9v022_g_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct mt9v022 *mt9v022 = to_mt9v022(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = mt9v022->rect.width; - pix->height = mt9v022->rect.height; - pix->pixelformat = mt9v022->fourcc; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_SRGB; + mf->width = mt9v022->rect.width; + mf->height = mt9v022->rect.height; + mf->code = mt9v022->fmt->code; + mf->colorspace = mt9v022->fmt->colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } -static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int mt9v022_s_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct mt9v022 *mt9v022 = to_mt9v022(client); - struct v4l2_pix_format *pix = &f->fmt.pix; struct v4l2_crop a = { .c = { .left = mt9v022->rect.left, .top = mt9v022->rect.top, - .width = pix->width, - .height = pix->height, + .width = mf->width, + .height = mf->height, }, }; int ret; @@ -388,14 +392,14 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) * The caller provides a supported format, as verified per call to * icd->try_fmt(), datawidth is from our supported format list */ - switch (pix->pixelformat) { - case V4L2_PIX_FMT_GREY: - case V4L2_PIX_FMT_Y16: + switch (mf->code) { + case V4L2_MBUS_FMT_GREY8_1X8: + case V4L2_MBUS_FMT_Y10_1X10: if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM) return -EINVAL; break; - case V4L2_PIX_FMT_SBGGR8: - case V4L2_PIX_FMT_SBGGR16: + case V4L2_MBUS_FMT_SBGGR8_1X8: + case V4L2_MBUS_FMT_SBGGR10_1X10: if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC) return -EINVAL; break; @@ -409,27 +413,39 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) /* No support for scaling on this camera, just crop. */ ret = mt9v022_s_crop(sd, &a); if (!ret) { - pix->width = mt9v022->rect.width; - pix->height = mt9v022->rect.height; - mt9v022->fourcc = pix->pixelformat; + mf->width = mt9v022->rect.width; + mf->height = mt9v022->rect.height; + mt9v022->fmt = mt9v022_find_datafmt(mf->code, + mt9v022->fmts, mt9v022->num_fmts); + mf->colorspace = mt9v022->fmt->colorspace; } return ret; } -static int mt9v022_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int mt9v022_try_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct mt9v022 *mt9v022 = to_mt9v022(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - int align = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 || - pix->pixelformat == V4L2_PIX_FMT_SBGGR16; + const struct mt9v022_datafmt *fmt; + int align = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 || + mf->code == V4L2_MBUS_FMT_SBGGR10_1X10; - v4l_bound_align_image(&pix->width, MT9V022_MIN_WIDTH, + v4l_bound_align_image(&mf->width, MT9V022_MIN_WIDTH, MT9V022_MAX_WIDTH, align, - &pix->height, MT9V022_MIN_HEIGHT + mt9v022->y_skip_top, + &mf->height, MT9V022_MIN_HEIGHT + mt9v022->y_skip_top, MT9V022_MAX_HEIGHT + mt9v022->y_skip_top, align, 0); + fmt = mt9v022_find_datafmt(mf->code, mt9v022->fmts, + mt9v022->num_fmts); + if (!fmt) { + fmt = mt9v022->fmt; + mf->code = fmt->code; + } + + mf->colorspace = fmt->colorspace; + return 0; } @@ -749,17 +765,17 @@ static int mt9v022_video_probe(struct soc_camera_device *icd, !strcmp("color", sensor_type))) { ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11); mt9v022->model = V4L2_IDENT_MT9V022IX7ATC; - icd->formats = mt9v022_colour_formats; + mt9v022->fmts = mt9v022_colour_fmts; } else { ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11); mt9v022->model = V4L2_IDENT_MT9V022IX7ATM; - icd->formats = mt9v022_monochrome_formats; + mt9v022->fmts = mt9v022_monochrome_fmts; } if (ret < 0) goto ei2c; - icd->num_formats = 0; + mt9v022->num_fmts = 0; /* * This is a 10bit sensor, so by default we only allow 10bit. @@ -772,14 +788,14 @@ static int mt9v022_video_probe(struct soc_camera_device *icd, flags = SOCAM_DATAWIDTH_10; if (flags & SOCAM_DATAWIDTH_10) - icd->num_formats++; + mt9v022->num_fmts++; else - icd->formats++; + mt9v022->fmts++; if (flags & SOCAM_DATAWIDTH_8) - icd->num_formats++; + mt9v022->num_fmts++; - mt9v022->fourcc = icd->formats->fourcc; + mt9v022->fmt = &mt9v022->fmts[0]; dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n", data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ? @@ -823,14 +839,28 @@ static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = { #endif }; +static int mt9v022_enum_fmt(struct v4l2_subdev *sd, int index, + enum v4l2_mbus_pixelcode *code) +{ + struct i2c_client *client = sd->priv; + struct mt9v022 *mt9v022 = to_mt9v022(client); + + if ((unsigned int)index >= mt9v022->num_fmts) + return -EINVAL; + + *code = mt9v022->fmts[index].code; + return 0; +} + static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = { .s_stream = mt9v022_s_stream, - .s_fmt = mt9v022_s_fmt, - .g_fmt = mt9v022_g_fmt, - .try_fmt = mt9v022_try_fmt, + .s_mbus_fmt = mt9v022_s_fmt, + .g_mbus_fmt = mt9v022_g_fmt, + .try_mbus_fmt = mt9v022_try_fmt, .s_crop = mt9v022_s_crop, .g_crop = mt9v022_g_crop, .cropcap = mt9v022_cropcap, + .enum_mbus_fmt = mt9v022_enum_fmt, }; static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = { diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index 4c1a439373c..2ba14fb5b03 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -94,9 +95,9 @@ /* buffer for one video frame */ struct mx1_buffer { /* common v4l buffer stuff -- must be first */ - struct videobuf_buffer vb; - const struct soc_camera_data_format *fmt; - int inwork; + struct videobuf_buffer vb; + enum v4l2_mbus_pixelcode code; + int inwork; }; /* @@ -128,9 +129,13 @@ static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) { struct soc_camera_device *icd = vq->priv_data; + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, + icd->current_fmt->host_fmt); - *size = icd->user_width * icd->user_height * - ((icd->current_fmt->depth + 7) >> 3); + if (bytes_per_line < 0) + return bytes_per_line; + + *size = bytes_per_line * icd->user_height; if (!*count) *count = 32; @@ -169,6 +174,11 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq, struct soc_camera_device *icd = vq->priv_data; struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb); int ret; + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, + icd->current_fmt->host_fmt); + + if (bytes_per_line < 0) + return bytes_per_line; dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, vb, vb->baddr, vb->bsize); @@ -184,18 +194,18 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq, */ buf->inwork = 1; - if (buf->fmt != icd->current_fmt || + if (buf->code != icd->current_fmt->code || vb->width != icd->user_width || vb->height != icd->user_height || vb->field != field) { - buf->fmt = icd->current_fmt; + buf->code = icd->current_fmt->code; vb->width = icd->user_width; vb->height = icd->user_height; vb->field = field; vb->state = VIDEOBUF_NEEDS_INIT; } - vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3); + vb->size = bytes_per_line * vb->height; if (0 != vb->baddr && vb->bsize < vb->size) { ret = -EINVAL; goto out; @@ -497,12 +507,10 @@ static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) /* MX1 supports only 8bit buswidth */ common_flags = soc_camera_bus_param_compatible(camera_flags, - CSI_BUS_FLAGS); + CSI_BUS_FLAGS); if (!common_flags) return -EINVAL; - icd->buswidth = 8; - /* Make choises, based on platform choice */ if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { @@ -555,7 +563,8 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; - int ret; + struct v4l2_mbus_framefmt mf; + int ret, buswidth; xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); if (!xlate) { @@ -564,12 +573,33 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd, return -EINVAL; } - ret = v4l2_subdev_call(sd, video, s_fmt, f); - if (!ret) { - icd->buswidth = xlate->buswidth; - icd->current_fmt = xlate->host_fmt; + buswidth = xlate->host_fmt->bits_per_sample; + if (buswidth > 8) { + dev_warn(icd->dev.parent, + "bits-per-sample %d for format %x unsupported\n", + buswidth, pix->pixelformat); + return -EINVAL; } + mf.width = pix->width; + mf.height = pix->height; + mf.field = pix->field; + mf.colorspace = pix->colorspace; + mf.code = xlate->code; + + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); + if (ret < 0) + return ret; + + if (mf.code != xlate->code) + return -EINVAL; + + pix->width = mf.width; + pix->height = mf.height; + pix->field = mf.field; + pix->colorspace = mf.colorspace; + icd->current_fmt = xlate; + return ret; } @@ -577,10 +607,36 @@ static int mx1_camera_try_fmt(struct soc_camera_device *icd, struct v4l2_format *f) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + const struct soc_camera_format_xlate *xlate; + struct v4l2_pix_format *pix = &f->fmt.pix; + struct v4l2_mbus_framefmt mf; + int ret; /* TODO: limit to mx1 hardware capabilities */ + xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); + if (!xlate) { + dev_warn(icd->dev.parent, "Format %x not found\n", + pix->pixelformat); + return -EINVAL; + } + + mf.width = pix->width; + mf.height = pix->height; + mf.field = pix->field; + mf.colorspace = pix->colorspace; + mf.code = xlate->code; + /* limit to sensor capabilities */ - return v4l2_subdev_call(sd, video, try_fmt, f); + ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); + if (ret < 0) + return ret; + + pix->width = mf.width; + pix->height = mf.height; + pix->field = mf.field; + pix->colorspace = mf.colorspace; + + return 0; } static int mx1_camera_reqbufs(struct soc_camera_file *icf, diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index ae7d4832449..bd297f567dc 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -63,7 +64,7 @@ struct mx3_camera_buffer { /* common v4l buffer stuff -- must be first */ struct videobuf_buffer vb; - const struct soc_camera_data_format *fmt; + enum v4l2_mbus_pixelcode code; /* One descriptot per scatterlist (per frame) */ struct dma_async_tx_descriptor *txd; @@ -118,8 +119,6 @@ struct dma_chan_request { enum ipu_channel id; }; -static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt); - static u32 csi_reg_read(struct mx3_camera_dev *mx3, off_t reg) { return __raw_readl(mx3->base + reg); @@ -211,17 +210,16 @@ static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, struct soc_camera_device *icd = vq->priv_data; struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct mx3_camera_dev *mx3_cam = ici->priv; - /* - * bits-per-pixel (depth) as specified in camera's pixel format does - * not necessarily match what the camera interface writes to RAM, but - * it should be good enough for now. - */ - unsigned int bpp = DIV_ROUND_UP(icd->current_fmt->depth, 8); + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, + icd->current_fmt->host_fmt); + + if (bytes_per_line < 0) + return bytes_per_line; if (!mx3_cam->idmac_channel[0]) return -EINVAL; - *size = icd->user_width * icd->user_height * bpp; + *size = bytes_per_line * icd->user_height; if (!*count) *count = 32; @@ -241,21 +239,26 @@ static int mx3_videobuf_prepare(struct videobuf_queue *vq, struct mx3_camera_dev *mx3_cam = ici->priv; struct mx3_camera_buffer *buf = container_of(vb, struct mx3_camera_buffer, vb); - /* current_fmt _must_ always be set */ - size_t new_size = icd->user_width * icd->user_height * - ((icd->current_fmt->depth + 7) >> 3); + size_t new_size; int ret; + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, + icd->current_fmt->host_fmt); + + if (bytes_per_line < 0) + return bytes_per_line; + + new_size = bytes_per_line * icd->user_height; /* * I think, in buf_prepare you only have to protect global data, * the actual buffer is yours */ - if (buf->fmt != icd->current_fmt || + if (buf->code != icd->current_fmt->code || vb->width != icd->user_width || vb->height != icd->user_height || vb->field != field) { - buf->fmt = icd->current_fmt; + buf->code = icd->current_fmt->code; vb->width = icd->user_width; vb->height = icd->user_height; vb->field = field; @@ -348,13 +351,13 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq, struct dma_async_tx_descriptor *txd = buf->txd; struct idmac_channel *ichan = to_idmac_chan(txd->chan); struct idmac_video_param *video = &ichan->params.video; - const struct soc_camera_data_format *data_fmt = icd->current_fmt; dma_cookie_t cookie; + u32 fourcc = icd->current_fmt->host_fmt->fourcc; BUG_ON(!irqs_disabled()); /* This is the configuration of one sg-element */ - video->out_pixel_fmt = fourcc_to_ipu_pix(data_fmt->fourcc); + video->out_pixel_fmt = fourcc_to_ipu_pix(fourcc); video->out_width = icd->user_width; video->out_height = icd->user_height; video->out_stride = icd->user_width; @@ -568,28 +571,33 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam, * If requested data width is supported by the platform, use it or any * possible lower value - i.MX31 is smart enough to schift bits */ + if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15) + *flags |= SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_10 | + SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4; + else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10) + *flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 | + SOCAM_DATAWIDTH_4; + else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8) + *flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4; + else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4) + *flags |= SOCAM_DATAWIDTH_4; + switch (buswidth) { case 15: - if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)) + if (!(*flags & SOCAM_DATAWIDTH_15)) return -EINVAL; - *flags |= SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_10 | - SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4; break; case 10: - if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)) + if (!(*flags & SOCAM_DATAWIDTH_10)) return -EINVAL; - *flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 | - SOCAM_DATAWIDTH_4; break; case 8: - if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)) + if (!(*flags & SOCAM_DATAWIDTH_8)) return -EINVAL; - *flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4; break; case 4: - if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)) + if (!(*flags & SOCAM_DATAWIDTH_4)) return -EINVAL; - *flags |= SOCAM_DATAWIDTH_4; break; default: dev_warn(mx3_cam->soc_host.v4l2_dev.dev, @@ -638,91 +646,92 @@ static bool chan_filter(struct dma_chan *chan, void *arg) pdata->dma_dev == chan->device->dev; } -static const struct soc_camera_data_format mx3_camera_formats[] = { +static const struct soc_mbus_pixelfmt mx3_camera_formats[] = { { - .name = "Bayer (sRGB) 8 bit", - .depth = 8, - .fourcc = V4L2_PIX_FMT_SBGGR8, - .colorspace = V4L2_COLORSPACE_SRGB, + .fourcc = V4L2_PIX_FMT_SBGGR8, + .name = "Bayer BGGR (sRGB) 8 bit", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_NONE, + .order = SOC_MBUS_ORDER_LE, }, { - .name = "Monochrome 8 bit", - .depth = 8, - .fourcc = V4L2_PIX_FMT_GREY, - .colorspace = V4L2_COLORSPACE_JPEG, + .fourcc = V4L2_PIX_FMT_GREY, + .name = "Monochrome 8 bit", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_NONE, + .order = SOC_MBUS_ORDER_LE, }, }; -static bool buswidth_supported(struct soc_camera_host *ici, int depth) +/* This will be corrected as we get more formats */ +static bool mx3_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt) { - struct mx3_camera_dev *mx3_cam = ici->priv; - - switch (depth) { - case 4: - return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4); - case 8: - return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8); - case 10: - return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10); - case 15: - return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15); - } - return false; + return fmt->packing == SOC_MBUS_PACKING_NONE || + (fmt->bits_per_sample == 8 && + fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) || + (fmt->bits_per_sample > 8 && + fmt->packing == SOC_MBUS_PACKING_EXTEND16); } static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx, struct soc_camera_format_xlate *xlate) { - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - int formats = 0, buswidth, ret; + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + struct device *dev = icd->dev.parent; + int formats = 0, ret; + enum v4l2_mbus_pixelcode code; + const struct soc_mbus_pixelfmt *fmt; - buswidth = icd->formats[idx].depth; + ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); + if (ret < 0) + /* No more formats */ + return 0; - if (!buswidth_supported(ici, buswidth)) + fmt = soc_mbus_get_fmtdesc(code); + if (!fmt) { + dev_err(icd->dev.parent, + "Invalid format code #%d: %d\n", idx, code); return 0; + } - ret = mx3_camera_try_bus_param(icd, buswidth); + /* This also checks support for the requested bits-per-sample */ + ret = mx3_camera_try_bus_param(icd, fmt->bits_per_sample); if (ret < 0) return 0; - switch (icd->formats[idx].fourcc) { - case V4L2_PIX_FMT_SGRBG10: + switch (code) { + case V4L2_MBUS_FMT_SBGGR10_1X10: formats++; if (xlate) { - xlate->host_fmt = &mx3_camera_formats[0]; - xlate->cam_fmt = icd->formats + idx; - xlate->buswidth = buswidth; + xlate->host_fmt = &mx3_camera_formats[0]; + xlate->code = code; xlate++; - dev_dbg(icd->dev.parent, - "Providing format %s using %s\n", - mx3_camera_formats[0].name, - icd->formats[idx].name); + dev_dbg(dev, "Providing format %s using code %d\n", + mx3_camera_formats[0].name, code); } - goto passthrough; - case V4L2_PIX_FMT_Y16: + break; + case V4L2_MBUS_FMT_Y10_1X10: formats++; if (xlate) { - xlate->host_fmt = &mx3_camera_formats[1]; - xlate->cam_fmt = icd->formats + idx; - xlate->buswidth = buswidth; + xlate->host_fmt = &mx3_camera_formats[1]; + xlate->code = code; xlate++; - dev_dbg(icd->dev.parent, - "Providing format %s using %s\n", - mx3_camera_formats[0].name, - icd->formats[idx].name); + dev_dbg(dev, "Providing format %s using code %d\n", + mx3_camera_formats[1].name, code); } + break; default: -passthrough: - /* Generic pass-through */ - formats++; - if (xlate) { - xlate->host_fmt = icd->formats + idx; - xlate->cam_fmt = icd->formats + idx; - xlate->buswidth = buswidth; - xlate++; - dev_dbg(icd->dev.parent, - "Providing format %s in pass-through mode\n", - icd->formats[idx].name); - } + if (!mx3_camera_packing_supported(fmt)) + return 0; + } + + /* Generic pass-through */ + formats++; + if (xlate) { + xlate->host_fmt = fmt; + xlate->code = code; + xlate++; + dev_dbg(dev, "Providing format %x in pass-through mode\n", + xlate->host_fmt->fourcc); } return formats; @@ -806,8 +815,7 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd, struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct mx3_camera_dev *mx3_cam = ici->priv; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - struct v4l2_format f = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE}; - struct v4l2_pix_format *pix = &f.fmt.pix; + struct v4l2_mbus_framefmt mf; int ret; soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096); @@ -818,19 +826,19 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd, return ret; /* The capture device might have changed its output */ - ret = v4l2_subdev_call(sd, video, g_fmt, &f); + ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); if (ret < 0) return ret; - if (pix->width & 7) { + if (mf.width & 7) { /* Ouch! We can only handle 8-byte aligned width... */ - stride_align(&pix->width); - ret = v4l2_subdev_call(sd, video, s_fmt, &f); + stride_align(&mf.width); + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); if (ret < 0) return ret; } - if (pix->width != icd->user_width || pix->height != icd->user_height) { + if (mf.width != icd->user_width || mf.height != icd->user_height) { /* * We now know pixel formats and can decide upon DMA-channel(s) * So far only direct camera-to-memory is supported @@ -841,14 +849,14 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd, return ret; } - configure_geometry(mx3_cam, pix->width, pix->height); + configure_geometry(mx3_cam, mf.width, mf.height); } dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n", - pix->width, pix->height); + mf.width, mf.height); - icd->user_width = pix->width; - icd->user_height = pix->height; + icd->user_width = mf.width; + icd->user_height = mf.height; return ret; } @@ -861,6 +869,7 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; + struct v4l2_mbus_framefmt mf; int ret; xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); @@ -885,11 +894,24 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd, configure_geometry(mx3_cam, pix->width, pix->height); - ret = v4l2_subdev_call(sd, video, s_fmt, f); - if (!ret) { - icd->buswidth = xlate->buswidth; - icd->current_fmt = xlate->host_fmt; - } + mf.width = pix->width; + mf.height = pix->height; + mf.field = pix->field; + mf.colorspace = pix->colorspace; + mf.code = xlate->code; + + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); + if (ret < 0) + return ret; + + if (mf.code != xlate->code) + return -EINVAL; + + pix->width = mf.width; + pix->height = mf.height; + pix->field = mf.field; + pix->colorspace = mf.colorspace; + icd->current_fmt = xlate; dev_dbg(icd->dev.parent, "Sensor set %dx%d\n", pix->width, pix->height); @@ -902,8 +924,8 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd, struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; + struct v4l2_mbus_framefmt mf; __u32 pixfmt = pix->pixelformat; - enum v4l2_field field; int ret; xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); @@ -918,23 +940,37 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd, if (pix->width > 4096) pix->width = 4096; - pix->bytesperline = pix->width * - DIV_ROUND_UP(xlate->host_fmt->depth, 8); + pix->bytesperline = soc_mbus_bytes_per_line(pix->width, + xlate->host_fmt); + if (pix->bytesperline < 0) + return pix->bytesperline; pix->sizeimage = pix->height * pix->bytesperline; - /* camera has to see its format, but the user the original one */ - pix->pixelformat = xlate->cam_fmt->fourcc; /* limit to sensor capabilities */ - ret = v4l2_subdev_call(sd, video, try_fmt, f); - pix->pixelformat = xlate->host_fmt->fourcc; + mf.width = pix->width; + mf.height = pix->height; + mf.field = pix->field; + mf.colorspace = pix->colorspace; + mf.code = xlate->code; - field = pix->field; + ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); + if (ret < 0) + return ret; - if (field == V4L2_FIELD_ANY) { + pix->width = mf.width; + pix->height = mf.height; + pix->colorspace = mf.colorspace; + + switch (mf.field) { + case V4L2_FIELD_ANY: pix->field = V4L2_FIELD_NONE; - } else if (field != V4L2_FIELD_NONE) { - dev_err(icd->dev.parent, "Field type %d unsupported.\n", field); - return -EINVAL; + break; + case V4L2_FIELD_NONE: + break; + default: + dev_err(icd->dev.parent, "Field type %d unsupported.\n", + mf.field); + ret = -EINVAL; } return ret; @@ -970,18 +1006,26 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) struct mx3_camera_dev *mx3_cam = ici->priv; unsigned long bus_flags, camera_flags, common_flags; u32 dw, sens_conf; - int ret = test_platform_param(mx3_cam, icd->buswidth, &bus_flags); + const struct soc_mbus_pixelfmt *fmt; + int buswidth; + int ret; const struct soc_camera_format_xlate *xlate; struct device *dev = icd->dev.parent; + fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code); + if (!fmt) + return -EINVAL; + + buswidth = fmt->bits_per_sample; + ret = test_platform_param(mx3_cam, buswidth, &bus_flags); + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); if (!xlate) { dev_warn(dev, "Format %x not found\n", pixfmt); return -EINVAL; } - dev_dbg(dev, "requested bus width %d bit: %d\n", - icd->buswidth, ret); + dev_dbg(dev, "requested bus width %d bit: %d\n", buswidth, ret); if (ret < 0) return ret; @@ -1082,7 +1126,7 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT; /* Just do what we're asked to do */ - switch (xlate->host_fmt->depth) { + switch (xlate->host_fmt->bits_per_sample) { case 4: dw = 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; break; diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c index dcb690cb5ae..3a45e945a52 100644 --- a/drivers/media/video/ov772x.c +++ b/drivers/media/video/ov772x.c @@ -24,6 +24,7 @@ #include #include #include +#include #include /* @@ -382,7 +383,8 @@ struct regval_list { }; struct ov772x_color_format { - const struct soc_camera_data_format *format; + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; u8 dsp3; u8 com3; u8 com7; @@ -399,7 +401,7 @@ struct ov772x_win_size { struct ov772x_priv { struct v4l2_subdev subdev; struct ov772x_camera_info *info; - const struct ov772x_color_format *fmt; + const struct ov772x_color_format *cfmt; const struct ov772x_win_size *win; int model; unsigned short flag_vflip:1; @@ -434,93 +436,57 @@ static const struct regval_list ov772x_vga_regs[] = { }; /* - * supported format list - */ - -#define SETFOURCC(type) .name = (#type), .fourcc = (V4L2_PIX_FMT_ ## type) -static const struct soc_camera_data_format ov772x_fmt_lists[] = { - { - SETFOURCC(YUYV), - .depth = 16, - .colorspace = V4L2_COLORSPACE_JPEG, - }, - { - SETFOURCC(YVYU), - .depth = 16, - .colorspace = V4L2_COLORSPACE_JPEG, - }, - { - SETFOURCC(UYVY), - .depth = 16, - .colorspace = V4L2_COLORSPACE_JPEG, - }, - { - SETFOURCC(RGB555), - .depth = 16, - .colorspace = V4L2_COLORSPACE_SRGB, - }, - { - SETFOURCC(RGB555X), - .depth = 16, - .colorspace = V4L2_COLORSPACE_SRGB, - }, - { - SETFOURCC(RGB565), - .depth = 16, - .colorspace = V4L2_COLORSPACE_SRGB, - }, - { - SETFOURCC(RGB565X), - .depth = 16, - .colorspace = V4L2_COLORSPACE_SRGB, - }, -}; - -/* - * color format list + * supported color format list */ static const struct ov772x_color_format ov772x_cfmts[] = { { - .format = &ov772x_fmt_lists[0], - .dsp3 = 0x0, - .com3 = SWAP_YUV, - .com7 = OFMT_YUV, + .code = V4L2_MBUS_FMT_YUYV8_2X8_LE, + .colorspace = V4L2_COLORSPACE_JPEG, + .dsp3 = 0x0, + .com3 = SWAP_YUV, + .com7 = OFMT_YUV, }, { - .format = &ov772x_fmt_lists[1], - .dsp3 = UV_ON, - .com3 = SWAP_YUV, - .com7 = OFMT_YUV, + .code = V4L2_MBUS_FMT_YVYU8_2X8_LE, + .colorspace = V4L2_COLORSPACE_JPEG, + .dsp3 = UV_ON, + .com3 = SWAP_YUV, + .com7 = OFMT_YUV, }, { - .format = &ov772x_fmt_lists[2], - .dsp3 = 0x0, - .com3 = 0x0, - .com7 = OFMT_YUV, + .code = V4L2_MBUS_FMT_YUYV8_2X8_BE, + .colorspace = V4L2_COLORSPACE_JPEG, + .dsp3 = 0x0, + .com3 = 0x0, + .com7 = OFMT_YUV, }, { - .format = &ov772x_fmt_lists[3], - .dsp3 = 0x0, - .com3 = SWAP_RGB, - .com7 = FMT_RGB555 | OFMT_RGB, + .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, + .colorspace = V4L2_COLORSPACE_SRGB, + .dsp3 = 0x0, + .com3 = SWAP_RGB, + .com7 = FMT_RGB555 | OFMT_RGB, }, { - .format = &ov772x_fmt_lists[4], - .dsp3 = 0x0, - .com3 = 0x0, - .com7 = FMT_RGB555 | OFMT_RGB, + .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, + .colorspace = V4L2_COLORSPACE_SRGB, + .dsp3 = 0x0, + .com3 = 0x0, + .com7 = FMT_RGB555 | OFMT_RGB, }, { - .format = &ov772x_fmt_lists[5], - .dsp3 = 0x0, - .com3 = SWAP_RGB, - .com7 = FMT_RGB565 | OFMT_RGB, + .code = V4L2_MBUS_FMT_RGB565_2X8_LE, + .colorspace = V4L2_COLORSPACE_SRGB, + .dsp3 = 0x0, + .com3 = SWAP_RGB, + .com7 = FMT_RGB565 | OFMT_RGB, }, { - .format = &ov772x_fmt_lists[6], - .dsp3 = 0x0, - .com3 = 0x0, - .com7 = FMT_RGB565 | OFMT_RGB, + .code = V4L2_MBUS_FMT_RGB565_2X8_BE, + .colorspace = V4L2_COLORSPACE_SRGB, + .dsp3 = 0x0, + .com3 = 0x0, + .com7 = FMT_RGB565 | OFMT_RGB, }, }; @@ -642,15 +608,15 @@ static int ov772x_s_stream(struct v4l2_subdev *sd, int enable) return 0; } - if (!priv->win || !priv->fmt) { + if (!priv->win || !priv->cfmt) { dev_err(&client->dev, "norm or win select error\n"); return -EPERM; } ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0); - dev_dbg(&client->dev, "format %s, win %s\n", - priv->fmt->format->name, priv->win->name); + dev_dbg(&client->dev, "format %d, win %s\n", + priv->cfmt->code, priv->win->name); return 0; } @@ -806,8 +772,8 @@ static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height) return win; } -static int ov772x_set_params(struct i2c_client *client, - u32 *width, u32 *height, u32 pixfmt) +static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height, + enum v4l2_mbus_pixelcode code) { struct ov772x_priv *priv = to_ov772x(client); int ret = -EINVAL; @@ -817,14 +783,14 @@ static int ov772x_set_params(struct i2c_client *client, /* * select format */ - priv->fmt = NULL; + priv->cfmt = NULL; for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) { - if (pixfmt == ov772x_cfmts[i].format->fourcc) { - priv->fmt = ov772x_cfmts + i; + if (code == ov772x_cfmts[i].code) { + priv->cfmt = ov772x_cfmts + i; break; } } - if (!priv->fmt) + if (!priv->cfmt) goto ov772x_set_fmt_error; /* @@ -894,7 +860,7 @@ static int ov772x_set_params(struct i2c_client *client, /* * set DSP_CTRL3 */ - val = priv->fmt->dsp3; + val = priv->cfmt->dsp3; if (val) { ret = ov772x_mask_set(client, DSP_CTRL3, UV_MASK, val); @@ -905,7 +871,7 @@ static int ov772x_set_params(struct i2c_client *client, /* * set COM3 */ - val = priv->fmt->com3; + val = priv->cfmt->com3; if (priv->info->flags & OV772X_FLAG_VFLIP) val |= VFLIP_IMG; if (priv->info->flags & OV772X_FLAG_HFLIP) @@ -923,9 +889,9 @@ static int ov772x_set_params(struct i2c_client *client, /* * set COM7 */ - val = priv->win->com7_bit | priv->fmt->com7; + val = priv->win->com7_bit | priv->cfmt->com7; ret = ov772x_mask_set(client, - COM7, (SLCT_MASK | FMT_MASK | OFMT_MASK), + COM7, SLCT_MASK | FMT_MASK | OFMT_MASK, val); if (ret < 0) goto ov772x_set_fmt_error; @@ -951,7 +917,7 @@ ov772x_set_fmt_error: ov772x_reset(client); priv->win = NULL; - priv->fmt = NULL; + priv->cfmt = NULL; return ret; } @@ -981,54 +947,79 @@ static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) return 0; } -static int ov772x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int ov772x_g_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct ov772x_priv *priv = to_ov772x(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - if (!priv->win || !priv->fmt) { + if (!priv->win || !priv->cfmt) { u32 width = VGA_WIDTH, height = VGA_HEIGHT; int ret = ov772x_set_params(client, &width, &height, - V4L2_PIX_FMT_YUYV); + V4L2_MBUS_FMT_YUYV8_2X8_LE); if (ret < 0) return ret; } - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - pix->width = priv->win->width; - pix->height = priv->win->height; - pix->pixelformat = priv->fmt->format->fourcc; - pix->colorspace = priv->fmt->format->colorspace; - pix->field = V4L2_FIELD_NONE; + mf->width = priv->win->width; + mf->height = priv->win->height; + mf->code = priv->cfmt->code; + mf->colorspace = priv->cfmt->colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } -static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int ov772x_s_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; - struct v4l2_pix_format *pix = &f->fmt.pix; + struct ov772x_priv *priv = to_ov772x(client); + int ret = ov772x_set_params(client, &mf->width, &mf->height, + mf->code); + + if (!ret) + mf->colorspace = priv->cfmt->colorspace; - return ov772x_set_params(client, &pix->width, &pix->height, - pix->pixelformat); + return ret; } static int ov772x_try_fmt(struct v4l2_subdev *sd, - struct v4l2_format *f) + struct v4l2_mbus_framefmt *mf) { - struct v4l2_pix_format *pix = &f->fmt.pix; + struct i2c_client *client = sd->priv; + struct ov772x_priv *priv = to_ov772x(client); const struct ov772x_win_size *win; + int i; /* * select suitable win */ - win = ov772x_select_win(pix->width, pix->height); + win = ov772x_select_win(mf->width, mf->height); + + mf->width = win->width; + mf->height = win->height; + mf->field = V4L2_FIELD_NONE; - pix->width = win->width; - pix->height = win->height; - pix->field = V4L2_FIELD_NONE; + for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) + if (mf->code == ov772x_cfmts[i].code) + break; + + if (i == ARRAY_SIZE(ov772x_cfmts)) { + /* Unsupported format requested. Propose either */ + if (priv->cfmt) { + /* the current one or */ + mf->colorspace = priv->cfmt->colorspace; + mf->code = priv->cfmt->code; + } else { + /* the default one */ + mf->colorspace = ov772x_cfmts[0].colorspace; + mf->code = ov772x_cfmts[0].code; + } + } else { + /* Also return the colorspace */ + mf->colorspace = ov772x_cfmts[i].colorspace; + } return 0; } @@ -1057,9 +1048,6 @@ static int ov772x_video_probe(struct soc_camera_device *icd, return -ENODEV; } - icd->formats = ov772x_fmt_lists; - icd->num_formats = ARRAY_SIZE(ov772x_fmt_lists); - /* * check and show product ID and manufacturer ID */ @@ -1109,13 +1097,24 @@ static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = { #endif }; +static int ov772x_enum_fmt(struct v4l2_subdev *sd, int index, + enum v4l2_mbus_pixelcode *code) +{ + if ((unsigned int)index >= ARRAY_SIZE(ov772x_cfmts)) + return -EINVAL; + + *code = ov772x_cfmts[index].code; + return 0; +} + static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { .s_stream = ov772x_s_stream, - .g_fmt = ov772x_g_fmt, - .s_fmt = ov772x_s_fmt, - .try_fmt = ov772x_try_fmt, + .g_mbus_fmt = ov772x_g_fmt, + .s_mbus_fmt = ov772x_s_fmt, + .try_mbus_fmt = ov772x_try_fmt, .cropcap = ov772x_cropcap, .g_crop = ov772x_g_crop, + .enum_mbus_fmt = ov772x_enum_fmt, }; static struct v4l2_subdev_ops ov772x_subdev_ops = { diff --git a/drivers/media/video/ov9640.c b/drivers/media/video/ov9640.c index c81ae219288..47bf60ceb7a 100644 --- a/drivers/media/video/ov9640.c +++ b/drivers/media/video/ov9640.c @@ -154,19 +154,10 @@ static const struct ov9640_reg ov9640_regs_rgb[] = { { OV9640_MTXS, 0x65 }, }; -/* - * TODO: this sensor also supports RGB555 and RGB565 formats, but support for - * them has not yet been sufficiently tested and so it is not included with - * this version of the driver. To test and debug these formats add two entries - * to the below array, see ov722x.c for an example. - */ -static const struct soc_camera_data_format ov9640_fmt_lists[] = { - { - .name = "UYVY", - .fourcc = V4L2_PIX_FMT_UYVY, - .depth = 16, - .colorspace = V4L2_COLORSPACE_JPEG, - }, +static enum v4l2_mbus_pixelcode ov9640_codes[] = { + V4L2_MBUS_FMT_YUYV8_2X8_BE, + V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, + V4L2_MBUS_FMT_RGB565_2X8_LE, }; static const struct v4l2_queryctrl ov9640_controls[] = { @@ -434,20 +425,22 @@ static void ov9640_res_roundup(u32 *width, u32 *height) } /* Prepare necessary register changes depending on color encoding */ -static void ov9640_alter_regs(u32 pixfmt, struct ov9640_reg_alt *alt) +static void ov9640_alter_regs(enum v4l2_mbus_pixelcode code, + struct ov9640_reg_alt *alt) { - switch (pixfmt) { - case V4L2_PIX_FMT_UYVY: + switch (code) { + default: + case V4L2_MBUS_FMT_YUYV8_2X8_BE: alt->com12 = OV9640_COM12_YUV_AVG; alt->com13 = OV9640_COM13_Y_DELAY_EN | OV9640_COM13_YUV_DLY(0x01); break; - case V4L2_PIX_FMT_RGB555: + case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: alt->com7 = OV9640_COM7_RGB; alt->com13 = OV9640_COM13_RGB_AVG; alt->com15 = OV9640_COM15_RGB_555; break; - case V4L2_PIX_FMT_RGB565: + case V4L2_MBUS_FMT_RGB565_2X8_LE: alt->com7 = OV9640_COM7_RGB; alt->com13 = OV9640_COM13_RGB_AVG; alt->com15 = OV9640_COM15_RGB_565; @@ -456,8 +449,8 @@ static void ov9640_alter_regs(u32 pixfmt, struct ov9640_reg_alt *alt) } /* Setup registers according to resolution and color encoding */ -static int ov9640_write_regs(struct i2c_client *client, - u32 width, u32 pixfmt, struct ov9640_reg_alt *alts) +static int ov9640_write_regs(struct i2c_client *client, u32 width, + enum v4l2_mbus_pixelcode code, struct ov9640_reg_alt *alts) { const struct ov9640_reg *ov9640_regs, *matrix_regs; int ov9640_regs_len, matrix_regs_len; @@ -500,7 +493,7 @@ static int ov9640_write_regs(struct i2c_client *client, } /* select color matrix configuration for given color encoding */ - if (pixfmt == V4L2_PIX_FMT_UYVY) { + if (code == V4L2_MBUS_FMT_YUYV8_2X8_BE) { matrix_regs = ov9640_regs_yuv; matrix_regs_len = ARRAY_SIZE(ov9640_regs_yuv); } else { @@ -562,15 +555,17 @@ static int ov9640_prog_dflt(struct i2c_client *client) } /* set the format we will capture in */ -static int ov9640_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int ov9640_s_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; - struct v4l2_pix_format *pix = &f->fmt.pix; struct ov9640_reg_alt alts = {0}; + enum v4l2_colorspace cspace; + enum v4l2_mbus_pixelcode code = mf->code; int ret; - ov9640_res_roundup(&pix->width, &pix->height); - ov9640_alter_regs(pix->pixelformat, &alts); + ov9640_res_roundup(&mf->width, &mf->height); + ov9640_alter_regs(mf->code, &alts); ov9640_reset(client); @@ -578,19 +573,57 @@ static int ov9640_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) if (ret) return ret; - return ov9640_write_regs(client, pix->width, pix->pixelformat, &alts); + switch (code) { + case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: + case V4L2_MBUS_FMT_RGB565_2X8_LE: + cspace = V4L2_COLORSPACE_SRGB; + break; + default: + code = V4L2_MBUS_FMT_YUYV8_2X8_BE; + case V4L2_MBUS_FMT_YUYV8_2X8_BE: + cspace = V4L2_COLORSPACE_JPEG; + } + + ret = ov9640_write_regs(client, mf->width, code, &alts); + if (!ret) { + mf->code = code; + mf->colorspace = cspace; + } + + return ret; } -static int ov9640_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int ov9640_try_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { - struct v4l2_pix_format *pix = &f->fmt.pix; + ov9640_res_roundup(&mf->width, &mf->height); - ov9640_res_roundup(&pix->width, &pix->height); - pix->field = V4L2_FIELD_NONE; + mf->field = V4L2_FIELD_NONE; + + switch (mf->code) { + case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: + case V4L2_MBUS_FMT_RGB565_2X8_LE: + mf->colorspace = V4L2_COLORSPACE_SRGB; + break; + default: + mf->code = V4L2_MBUS_FMT_YUYV8_2X8_BE; + case V4L2_MBUS_FMT_YUYV8_2X8_BE: + mf->colorspace = V4L2_COLORSPACE_JPEG; + } return 0; } +static int ov9640_enum_fmt(struct v4l2_subdev *sd, int index, + enum v4l2_mbus_pixelcode *code) +{ + if ((unsigned int)index >= ARRAY_SIZE(ov9640_codes)) + return -EINVAL; + + *code = ov9640_codes[index]; + return 0; +} + static int ov9640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) { a->c.left = 0; @@ -637,9 +670,6 @@ static int ov9640_video_probe(struct soc_camera_device *icd, goto err; } - icd->formats = ov9640_fmt_lists; - icd->num_formats = ARRAY_SIZE(ov9640_fmt_lists); - /* * check and show product ID and manufacturer ID */ @@ -702,11 +732,12 @@ static struct v4l2_subdev_core_ops ov9640_core_ops = { }; static struct v4l2_subdev_video_ops ov9640_video_ops = { - .s_stream = ov9640_s_stream, - .s_fmt = ov9640_s_fmt, - .try_fmt = ov9640_try_fmt, - .cropcap = ov9640_cropcap, - .g_crop = ov9640_g_crop, + .s_stream = ov9640_s_stream, + .s_mbus_fmt = ov9640_s_fmt, + .try_mbus_fmt = ov9640_try_fmt, + .enum_mbus_fmt = ov9640_enum_fmt, + .cropcap = ov9640_cropcap, + .g_crop = ov9640_g_crop, }; diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index f063f5981f4..294f860ce2b 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -183,16 +184,12 @@ struct pxa_cam_dma { /* buffer for one video frame */ struct pxa_buffer { /* common v4l buffer stuff -- must be first */ - struct videobuf_buffer vb; - - const struct soc_camera_data_format *fmt; - + struct videobuf_buffer vb; + enum v4l2_mbus_pixelcode code; /* our descriptor lists for Y, U and V channels */ - struct pxa_cam_dma dmas[3]; - - int inwork; - - enum pxa_camera_active_dma active_dma; + struct pxa_cam_dma dmas[3]; + int inwork; + enum pxa_camera_active_dma active_dma; }; struct pxa_camera_dev { @@ -243,11 +240,15 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) { struct soc_camera_device *icd = vq->priv_data; + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, + icd->current_fmt->host_fmt); + + if (bytes_per_line < 0) + return bytes_per_line; dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size); - *size = roundup(icd->user_width * icd->user_height * - ((icd->current_fmt->depth + 7) >> 3), 8); + *size = bytes_per_line * icd->user_height; if (0 == *count) *count = 32; @@ -433,6 +434,11 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq, struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); int ret; int size_y, size_u = 0, size_v = 0; + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, + icd->current_fmt->host_fmt); + + if (bytes_per_line < 0) + return bytes_per_line; dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, vb, vb->baddr, vb->bsize); @@ -456,18 +462,18 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq, */ buf->inwork = 1; - if (buf->fmt != icd->current_fmt || + if (buf->code != icd->current_fmt->code || vb->width != icd->user_width || vb->height != icd->user_height || vb->field != field) { - buf->fmt = icd->current_fmt; + buf->code = icd->current_fmt->code; vb->width = icd->user_width; vb->height = icd->user_height; vb->field = field; vb->state = VIDEOBUF_NEEDS_INIT; } - vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3); + vb->size = bytes_per_line * vb->height; if (0 != vb->baddr && vb->bsize < vb->size) { ret = -EINVAL; goto out; @@ -1157,9 +1163,15 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct pxa_camera_dev *pcdev = ici->priv; unsigned long bus_flags, camera_flags, common_flags; - int ret = test_platform_param(pcdev, icd->buswidth, &bus_flags); + const struct soc_mbus_pixelfmt *fmt; + int ret; struct pxa_cam *cam = icd->host_priv; + fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code); + if (!fmt) + return -EINVAL; + + ret = test_platform_param(pcdev, fmt->bits_per_sample, &bus_flags); if (ret < 0) return ret; @@ -1223,59 +1235,49 @@ static int pxa_camera_try_bus_param(struct soc_camera_device *icd, return soc_camera_bus_param_compatible(camera_flags, bus_flags) ? 0 : -EINVAL; } -static const struct soc_camera_data_format pxa_camera_formats[] = { +static const struct soc_mbus_pixelfmt pxa_camera_formats[] = { { - .name = "Planar YUV422 16 bit", - .depth = 16, - .fourcc = V4L2_PIX_FMT_YUV422P, - .colorspace = V4L2_COLORSPACE_JPEG, + .fourcc = V4L2_PIX_FMT_YUV422P, + .name = "Planar YUV422 16 bit", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, }, }; -static bool buswidth_supported(struct soc_camera_device *icd, int depth) +/* This will be corrected as we get more formats */ +static bool pxa_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt) { - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - struct pxa_camera_dev *pcdev = ici->priv; - - switch (depth) { - case 8: - return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8); - case 9: - return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_9); - case 10: - return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10); - } - return false; -} - -static int required_buswidth(const struct soc_camera_data_format *fmt) -{ - switch (fmt->fourcc) { - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_VYUY: - case V4L2_PIX_FMT_YUYV: - case V4L2_PIX_FMT_YVYU: - case V4L2_PIX_FMT_RGB565: - case V4L2_PIX_FMT_RGB555: - return 8; - default: - return fmt->depth; - } + return fmt->packing == SOC_MBUS_PACKING_NONE || + (fmt->bits_per_sample == 8 && + fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) || + (fmt->bits_per_sample > 8 && + fmt->packing == SOC_MBUS_PACKING_EXTEND16); } static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, struct soc_camera_format_xlate *xlate) { + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->dev.parent; - int formats = 0, buswidth, ret; + int formats = 0, ret; struct pxa_cam *cam; + enum v4l2_mbus_pixelcode code; + const struct soc_mbus_pixelfmt *fmt; - buswidth = required_buswidth(icd->formats + idx); + ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); + if (ret < 0) + /* No more formats */ + return 0; - if (!buswidth_supported(icd, buswidth)) + fmt = soc_mbus_get_fmtdesc(code); + if (!fmt) { + dev_err(dev, "Invalid format code #%d: %d\n", idx, code); return 0; + } - ret = pxa_camera_try_bus_param(icd, buswidth); + /* This also checks support for the requested bits-per-sample */ + ret = pxa_camera_try_bus_param(icd, fmt->bits_per_sample); if (ret < 0) return 0; @@ -1289,45 +1291,40 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, cam = icd->host_priv; } - switch (icd->formats[idx].fourcc) { - case V4L2_PIX_FMT_UYVY: + switch (code) { + case V4L2_MBUS_FMT_YUYV8_2X8_BE: formats++; if (xlate) { - xlate->host_fmt = &pxa_camera_formats[0]; - xlate->cam_fmt = icd->formats + idx; - xlate->buswidth = buswidth; + xlate->host_fmt = &pxa_camera_formats[0]; + xlate->code = code; xlate++; - dev_dbg(dev, "Providing format %s using %s\n", - pxa_camera_formats[0].name, - icd->formats[idx].name); + dev_dbg(dev, "Providing format %s using code %d\n", + pxa_camera_formats[0].name, code); } - case V4L2_PIX_FMT_VYUY: - case V4L2_PIX_FMT_YUYV: - case V4L2_PIX_FMT_YVYU: - case V4L2_PIX_FMT_RGB565: - case V4L2_PIX_FMT_RGB555: - formats++; - if (xlate) { - xlate->host_fmt = icd->formats + idx; - xlate->cam_fmt = icd->formats + idx; - xlate->buswidth = buswidth; - xlate++; + case V4L2_MBUS_FMT_YVYU8_2X8_BE: + case V4L2_MBUS_FMT_YUYV8_2X8_LE: + case V4L2_MBUS_FMT_YVYU8_2X8_LE: + case V4L2_MBUS_FMT_RGB565_2X8_LE: + case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: + if (xlate) dev_dbg(dev, "Providing format %s packed\n", - icd->formats[idx].name); - } + fmt->name); break; default: - /* Generic pass-through */ - formats++; - if (xlate) { - xlate->host_fmt = icd->formats + idx; - xlate->cam_fmt = icd->formats + idx; - xlate->buswidth = icd->formats[idx].depth; - xlate++; + if (!pxa_camera_packing_supported(fmt)) + return 0; + if (xlate) dev_dbg(dev, "Providing format %s in pass-through mode\n", - icd->formats[idx].name); - } + fmt->name); + } + + /* Generic pass-through */ + formats++; + if (xlate) { + xlate->host_fmt = fmt; + xlate->code = code; + xlate++; } return formats; @@ -1339,11 +1336,11 @@ static void pxa_camera_put_formats(struct soc_camera_device *icd) icd->host_priv = NULL; } -static int pxa_camera_check_frame(struct v4l2_pix_format *pix) +static int pxa_camera_check_frame(u32 width, u32 height) { /* limit to pxa hardware capabilities */ - return pix->height < 32 || pix->height > 2048 || pix->width < 48 || - pix->width > 2048 || (pix->width & 0x01); + return height < 32 || height > 2048 || width < 48 || width > 2048 || + (width & 0x01); } static int pxa_camera_set_crop(struct soc_camera_device *icd, @@ -1358,9 +1355,9 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd, .master_clock = pcdev->mclk, .pixel_clock_max = pcdev->ciclk / 4, }; - struct v4l2_format f; - struct v4l2_pix_format *pix = &f.fmt.pix, pix_tmp; + struct v4l2_mbus_framefmt mf; struct pxa_cam *cam = icd->host_priv; + u32 fourcc = icd->current_fmt->host_fmt->fourcc; int ret; /* If PCLK is used to latch data from the sensor, check sense */ @@ -1377,27 +1374,23 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd, return ret; } - f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - ret = v4l2_subdev_call(sd, video, g_fmt, &f); + ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); if (ret < 0) return ret; - pix_tmp = *pix; - if (pxa_camera_check_frame(pix)) { + if (pxa_camera_check_frame(mf.width, mf.height)) { /* * Camera cropping produced a frame beyond our capabilities. * FIXME: just extract a subframe, that we can process. */ - v4l_bound_align_image(&pix->width, 48, 2048, 1, - &pix->height, 32, 2048, 0, - icd->current_fmt->fourcc == V4L2_PIX_FMT_YUV422P ? - 4 : 0); - ret = v4l2_subdev_call(sd, video, s_fmt, &f); + v4l_bound_align_image(&mf.width, 48, 2048, 1, + &mf.height, 32, 2048, 0, + fourcc == V4L2_PIX_FMT_YUV422P ? 4 : 0); + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); if (ret < 0) return ret; - if (pxa_camera_check_frame(pix)) { + if (pxa_camera_check_frame(mf.width, mf.height)) { dev_warn(icd->dev.parent, "Inconsistent state. Use S_FMT to repair\n"); return -EINVAL; @@ -1414,10 +1407,10 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd, recalculate_fifo_timeout(pcdev, sense.pixel_clock); } - icd->user_width = pix->width; - icd->user_height = pix->height; + icd->user_width = mf.width; + icd->user_height = mf.height; - pxa_camera_setup_cicr(icd, cam->flags, icd->current_fmt->fourcc); + pxa_camera_setup_cicr(icd, cam->flags, fourcc); return ret; } @@ -1429,14 +1422,13 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, struct pxa_camera_dev *pcdev = ici->priv; struct device *dev = icd->dev.parent; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - const struct soc_camera_data_format *cam_fmt = NULL; const struct soc_camera_format_xlate *xlate = NULL; struct soc_camera_sense sense = { .master_clock = pcdev->mclk, .pixel_clock_max = pcdev->ciclk / 4, }; struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_format cam_f = *f; + struct v4l2_mbus_framefmt mf; int ret; xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); @@ -1445,26 +1437,31 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, return -EINVAL; } - cam_fmt = xlate->cam_fmt; - /* If PCLK is used to latch data from the sensor, check sense */ if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) + /* The caller holds a mutex. */ icd->sense = &sense; - cam_f.fmt.pix.pixelformat = cam_fmt->fourcc; - ret = v4l2_subdev_call(sd, video, s_fmt, &cam_f); - cam_f.fmt.pix.pixelformat = pix->pixelformat; - *pix = cam_f.fmt.pix; + mf.width = pix->width; + mf.height = pix->height; + mf.field = pix->field; + mf.colorspace = pix->colorspace; + mf.code = xlate->code; + + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); + + if (mf.code != xlate->code) + return -EINVAL; icd->sense = NULL; if (ret < 0) { dev_warn(dev, "Failed to configure for format %x\n", pix->pixelformat); - } else if (pxa_camera_check_frame(pix)) { + } else if (pxa_camera_check_frame(mf.width, mf.height)) { dev_warn(dev, "Camera driver produced an unsupported frame %dx%d\n", - pix->width, pix->height); + mf.width, mf.height); ret = -EINVAL; } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { if (sense.pixel_clock > sense.pixel_clock_max) { @@ -1476,10 +1473,14 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, recalculate_fifo_timeout(pcdev, sense.pixel_clock); } - if (!ret) { - icd->buswidth = xlate->buswidth; - icd->current_fmt = xlate->host_fmt; - } + if (ret < 0) + return ret; + + pix->width = mf.width; + pix->height = mf.height; + pix->field = mf.field; + pix->colorspace = mf.colorspace; + icd->current_fmt = xlate; return ret; } @@ -1487,17 +1488,16 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, static int pxa_camera_try_fmt(struct soc_camera_device *icd, struct v4l2_format *f) { - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; + struct v4l2_mbus_framefmt mf; __u32 pixfmt = pix->pixelformat; - enum v4l2_field field; int ret; xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); if (!xlate) { - dev_warn(ici->v4l2_dev.dev, "Format %x not found\n", pixfmt); + dev_warn(icd->dev.parent, "Format %x not found\n", pixfmt); return -EINVAL; } @@ -1511,22 +1511,36 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd, &pix->height, 32, 2048, 0, pixfmt == V4L2_PIX_FMT_YUV422P ? 4 : 0); - pix->bytesperline = pix->width * - DIV_ROUND_UP(xlate->host_fmt->depth, 8); + pix->bytesperline = soc_mbus_bytes_per_line(pix->width, + xlate->host_fmt); + if (pix->bytesperline < 0) + return pix->bytesperline; pix->sizeimage = pix->height * pix->bytesperline; - /* camera has to see its format, but the user the original one */ - pix->pixelformat = xlate->cam_fmt->fourcc; /* limit to sensor capabilities */ - ret = v4l2_subdev_call(sd, video, try_fmt, f); - pix->pixelformat = pixfmt; + mf.width = pix->width; + mf.height = pix->height; + mf.field = pix->field; + mf.colorspace = pix->colorspace; + mf.code = xlate->code; - field = pix->field; + ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); + if (ret < 0) + return ret; - if (field == V4L2_FIELD_ANY) { - pix->field = V4L2_FIELD_NONE; - } else if (field != V4L2_FIELD_NONE) { - dev_err(icd->dev.parent, "Field type %d unsupported.\n", field); + pix->width = mf.width; + pix->height = mf.height; + pix->colorspace = mf.colorspace; + + switch (mf.field) { + case V4L2_FIELD_ANY: + case V4L2_FIELD_NONE: + pix->field = V4L2_FIELD_NONE; + break; + default: + /* TODO: support interlaced at least in pass-through mode */ + dev_err(icd->dev.parent, "Field type %d unsupported.\n", + mf.field); return -EINVAL; } diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c index 373f2a30a67..7b08bff443f 100644 --- a/drivers/media/video/rj54n1cb0c.c +++ b/drivers/media/video/rj54n1cb0c.c @@ -16,6 +16,7 @@ #include #include #include +#include #define RJ54N1_DEV_CODE 0x0400 #define RJ54N1_DEV_CODE2 0x0401 @@ -85,18 +86,35 @@ /* I2C addresses: 0x50, 0x51, 0x60, 0x61 */ -static const struct soc_camera_data_format rj54n1_colour_formats[] = { - { - .name = "YUYV", - .depth = 16, - .fourcc = V4L2_PIX_FMT_YUYV, - .colorspace = V4L2_COLORSPACE_JPEG, - }, { - .name = "RGB565", - .depth = 16, - .fourcc = V4L2_PIX_FMT_RGB565, - .colorspace = V4L2_COLORSPACE_SRGB, - } +/* RJ54N1CB0C has only one fixed colorspace per pixelcode */ +struct rj54n1_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct rj54n1_datafmt *rj54n1_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct rj54n1_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} + +static const struct rj54n1_datafmt rj54n1_colour_fmts[] = { + {V4L2_MBUS_FMT_YUYV8_2X8_LE, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YVYU8_2X8_LE, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB}, + {V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB}, + {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, + {V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE, V4L2_COLORSPACE_SRGB}, + {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, V4L2_COLORSPACE_SRGB}, + {V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, V4L2_COLORSPACE_SRGB}, + {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, }; struct rj54n1_clock_div { @@ -109,12 +127,12 @@ struct rj54n1_clock_div { struct rj54n1 { struct v4l2_subdev subdev; + const struct rj54n1_datafmt *fmt; struct v4l2_rect rect; /* Sensor window */ unsigned short width; /* Output window */ unsigned short height; unsigned short resize; /* Sensor * 1024 / resize = Output */ struct rj54n1_clock_div clk_div; - u32 fourcc; unsigned short scale; u8 bank; }; @@ -440,6 +458,16 @@ static int reg_write_multiple(struct i2c_client *client, return 0; } +static int rj54n1_enum_fmt(struct v4l2_subdev *sd, int index, + enum v4l2_mbus_pixelcode *code) +{ + if ((unsigned int)index >= ARRAY_SIZE(rj54n1_colour_fmts)) + return -EINVAL; + + *code = rj54n1_colour_fmts[index].code; + return 0; +} + static int rj54n1_s_stream(struct v4l2_subdev *sd, int enable) { /* TODO: start / stop streaming */ @@ -527,16 +555,17 @@ static int rj54n1_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) return 0; } -static int rj54n1_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int rj54n1_g_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct rj54n1 *rj54n1 = to_rj54n1(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->pixelformat = rj54n1->fourcc; - pix->field = V4L2_FIELD_NONE; - pix->width = rj54n1->width; - pix->height = rj54n1->height; + mf->code = rj54n1->fmt->code; + mf->colorspace = rj54n1->fmt->colorspace; + mf->field = V4L2_FIELD_NONE; + mf->width = rj54n1->width; + mf->height = rj54n1->height; return 0; } @@ -787,26 +816,44 @@ static int rj54n1_reg_init(struct i2c_client *client) } /* FIXME: streaming output only up to 800x600 is functional */ -static int rj54n1_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int rj54n1_try_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { - struct v4l2_pix_format *pix = &f->fmt.pix; + struct i2c_client *client = sd->priv; + struct rj54n1 *rj54n1 = to_rj54n1(client); + const struct rj54n1_datafmt *fmt; + int align = mf->code == V4L2_MBUS_FMT_SBGGR10_1X10 || + mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE || + mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE || + mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE || + mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE; + + dev_dbg(&client->dev, "%s: code = %d, width = %u, height = %u\n", + __func__, mf->code, mf->width, mf->height); + + fmt = rj54n1_find_datafmt(mf->code, rj54n1_colour_fmts, + ARRAY_SIZE(rj54n1_colour_fmts)); + if (!fmt) { + fmt = rj54n1->fmt; + mf->code = fmt->code; + } - pix->field = V4L2_FIELD_NONE; + mf->field = V4L2_FIELD_NONE; + mf->colorspace = fmt->colorspace; - if (pix->width > 800) - pix->width = 800; - if (pix->height > 600) - pix->height = 600; + v4l_bound_align_image(&mf->width, 112, RJ54N1_MAX_WIDTH, align, + &mf->height, 84, RJ54N1_MAX_HEIGHT, align, 0); return 0; } -static int rj54n1_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int rj54n1_s_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct rj54n1 *rj54n1 = to_rj54n1(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - unsigned int output_w, output_h, + const struct rj54n1_datafmt *fmt; + unsigned int output_w, output_h, max_w, max_h, input_w = rj54n1->rect.width, input_h = rj54n1->rect.height; int ret; @@ -814,7 +861,7 @@ static int rj54n1_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) * The host driver can call us without .try_fmt(), so, we have to take * care ourseleves */ - ret = rj54n1_try_fmt(sd, f); + ret = rj54n1_try_fmt(sd, mf); /* * Verify if the sensor has just been powered on. TODO: replace this @@ -832,49 +879,101 @@ static int rj54n1_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } /* RA_SEL_UL is only relevant for raw modes, ignored otherwise. */ - switch (pix->pixelformat) { - case V4L2_PIX_FMT_YUYV: + switch (mf->code) { + case V4L2_MBUS_FMT_YUYV8_2X8_LE: ret = reg_write(client, RJ54N1_OUT_SEL, 0); if (!ret) ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); break; - case V4L2_PIX_FMT_RGB565: + case V4L2_MBUS_FMT_YVYU8_2X8_LE: + ret = reg_write(client, RJ54N1_OUT_SEL, 0); + if (!ret) + ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); + break; + case V4L2_MBUS_FMT_RGB565_2X8_LE: ret = reg_write(client, RJ54N1_OUT_SEL, 0x11); if (!ret) ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); break; + case V4L2_MBUS_FMT_RGB565_2X8_BE: + ret = reg_write(client, RJ54N1_OUT_SEL, 0x11); + if (!ret) + ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); + break; + case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE: + ret = reg_write(client, RJ54N1_OUT_SEL, 4); + if (!ret) + ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); + if (!ret) + ret = reg_write(client, RJ54N1_RA_SEL_UL, 0); + break; + case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE: + ret = reg_write(client, RJ54N1_OUT_SEL, 4); + if (!ret) + ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); + if (!ret) + ret = reg_write(client, RJ54N1_RA_SEL_UL, 8); + break; + case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE: + ret = reg_write(client, RJ54N1_OUT_SEL, 4); + if (!ret) + ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); + if (!ret) + ret = reg_write(client, RJ54N1_RA_SEL_UL, 0); + break; + case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE: + ret = reg_write(client, RJ54N1_OUT_SEL, 4); + if (!ret) + ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); + if (!ret) + ret = reg_write(client, RJ54N1_RA_SEL_UL, 8); + break; + case V4L2_MBUS_FMT_SBGGR10_1X10: + ret = reg_write(client, RJ54N1_OUT_SEL, 5); + break; default: ret = -EINVAL; } + /* Special case: a raw mode with 10 bits of data per clock tick */ + if (!ret) + ret = reg_set(client, RJ54N1_OCLK_SEL_EN, + (mf->code == V4L2_MBUS_FMT_SBGGR10_1X10) << 1, 2); + if (ret < 0) return ret; - /* Supported scales 1:1 - 1:16 */ - if (pix->width < input_w / 16) - pix->width = input_w / 16; - if (pix->height < input_h / 16) - pix->height = input_h / 16; + /* Supported scales 1:1 >= scale > 1:16 */ + max_w = mf->width * (16 * 1024 - 1) / 1024; + if (input_w > max_w) + input_w = max_w; + max_h = mf->height * (16 * 1024 - 1) / 1024; + if (input_h > max_h) + input_h = max_h; - output_w = pix->width; - output_h = pix->height; + output_w = mf->width; + output_h = mf->height; ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h); if (ret < 0) return ret; - rj54n1->fourcc = pix->pixelformat; + fmt = rj54n1_find_datafmt(mf->code, rj54n1_colour_fmts, + ARRAY_SIZE(rj54n1_colour_fmts)); + + rj54n1->fmt = fmt; rj54n1->resize = ret; rj54n1->rect.width = input_w; rj54n1->rect.height = input_h; rj54n1->width = output_w; rj54n1->height = output_h; - pix->width = output_w; - pix->height = output_h; - pix->field = V4L2_FIELD_NONE; + mf->width = output_w; + mf->height = output_h; + mf->field = V4L2_FIELD_NONE; + mf->colorspace = fmt->colorspace; - return ret; + return 0; } static int rj54n1_g_chip_ident(struct v4l2_subdev *sd, @@ -1054,9 +1153,10 @@ static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = { static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = { .s_stream = rj54n1_s_stream, - .s_fmt = rj54n1_s_fmt, - .g_fmt = rj54n1_g_fmt, - .try_fmt = rj54n1_try_fmt, + .s_mbus_fmt = rj54n1_s_fmt, + .g_mbus_fmt = rj54n1_g_fmt, + .try_mbus_fmt = rj54n1_try_fmt, + .enum_mbus_fmt = rj54n1_enum_fmt, .g_crop = rj54n1_g_crop, .cropcap = rj54n1_cropcap, }; @@ -1153,7 +1253,7 @@ static int rj54n1_probe(struct i2c_client *client, rj54n1->rect.height = RJ54N1_MAX_HEIGHT; rj54n1->width = RJ54N1_MAX_WIDTH; rj54n1->height = RJ54N1_MAX_HEIGHT; - rj54n1->fourcc = V4L2_PIX_FMT_YUYV; + rj54n1->fmt = &rj54n1_colour_fmts[0]; rj54n1->resize = 1024; ret = rj54n1_video_probe(icd, client); @@ -1164,9 +1264,6 @@ static int rj54n1_probe(struct i2c_client *client, return ret; } - icd->formats = rj54n1_colour_formats; - icd->num_formats = ARRAY_SIZE(rj54n1_colour_formats); - return ret; } diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 2a38e1d9061..273ad34f9d8 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -38,6 +38,8 @@ #include #include #include +#include +#include /* register offsets for sh7722 / sh7723 */ @@ -85,7 +87,7 @@ /* per video frame buffer */ struct sh_mobile_ceu_buffer { struct videobuf_buffer vb; /* v4l buffer must be first */ - const struct soc_camera_data_format *fmt; + enum v4l2_mbus_pixelcode code; }; struct sh_mobile_ceu_dev { @@ -114,8 +116,8 @@ struct sh_mobile_ceu_cam { struct v4l2_rect ceu_rect; unsigned int cam_width; unsigned int cam_height; - const struct soc_camera_data_format *extra_fmt; - const struct soc_camera_data_format *camera_fmt; + const struct soc_mbus_pixelfmt *extra_fmt; + enum v4l2_mbus_pixelcode code; }; static unsigned long make_bus_param(struct sh_mobile_ceu_dev *pcdev) @@ -197,10 +199,13 @@ static int sh_mobile_ceu_videobuf_setup(struct videobuf_queue *vq, struct soc_camera_device *icd = vq->priv_data; struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct sh_mobile_ceu_dev *pcdev = ici->priv; - int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3; + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, + icd->current_fmt->host_fmt); - *size = PAGE_ALIGN(icd->user_width * icd->user_height * - bytes_per_pixel); + if (bytes_per_line < 0) + return bytes_per_line; + + *size = PAGE_ALIGN(bytes_per_line * icd->user_height); if (0 == *count) *count = 2; @@ -284,7 +289,7 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) ceu_write(pcdev, CDBYR, phys_addr_bottom); } - switch (icd->current_fmt->fourcc) { + switch (icd->current_fmt->host_fmt->fourcc) { case V4L2_PIX_FMT_NV12: case V4L2_PIX_FMT_NV21: case V4L2_PIX_FMT_NV16: @@ -311,8 +316,13 @@ static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq, { struct soc_camera_device *icd = vq->priv_data; struct sh_mobile_ceu_buffer *buf; + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, + icd->current_fmt->host_fmt); int ret; + if (bytes_per_line < 0) + return bytes_per_line; + buf = container_of(vb, struct sh_mobile_ceu_buffer, vb); dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, @@ -331,18 +341,18 @@ static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq, BUG_ON(NULL == icd->current_fmt); - if (buf->fmt != icd->current_fmt || + if (buf->code != icd->current_fmt->code || vb->width != icd->user_width || vb->height != icd->user_height || vb->field != field) { - buf->fmt = icd->current_fmt; + buf->code = icd->current_fmt->code; vb->width = icd->user_width; vb->height = icd->user_height; vb->field = field; vb->state = VIDEOBUF_NEEDS_INIT; } - vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3); + vb->size = vb->height * bytes_per_line; if (0 != vb->baddr && vb->bsize < vb->size) { ret = -EINVAL; goto out; @@ -564,19 +574,30 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd, in_width *= 2; left_offset *= 2; } - width = cdwdr_width = out_width; + width = out_width; + cdwdr_width = out_width; } else { - unsigned int w_factor = (icd->current_fmt->depth + 7) >> 3; + int bytes_per_line = soc_mbus_bytes_per_line(out_width, + icd->current_fmt->host_fmt); + unsigned int w_factor; - width = out_width * w_factor / 2; + width = out_width; - if (!pcdev->is_16bit) - w_factor *= 2; + switch (icd->current_fmt->host_fmt->packing) { + case SOC_MBUS_PACKING_2X8_PADHI: + w_factor = 2; + break; + default: + w_factor = 1; + } - in_width = rect->width * w_factor / 2; - left_offset = left_offset * w_factor / 2; + in_width = rect->width * w_factor; + left_offset = left_offset * w_factor; - cdwdr_width = width * 2; + if (bytes_per_line < 0) + cdwdr_width = out_width; + else + cdwdr_width = bytes_per_line; } height = out_height; @@ -673,24 +694,24 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, value = 0x00000010; /* data fetch by default */ yuv_lineskip = 0; - switch (icd->current_fmt->fourcc) { + switch (icd->current_fmt->host_fmt->fourcc) { case V4L2_PIX_FMT_NV12: case V4L2_PIX_FMT_NV21: yuv_lineskip = 1; /* skip for NV12/21, no skip for NV16/61 */ /* fall-through */ case V4L2_PIX_FMT_NV16: case V4L2_PIX_FMT_NV61: - switch (cam->camera_fmt->fourcc) { - case V4L2_PIX_FMT_UYVY: + switch (cam->code) { + case V4L2_MBUS_FMT_YUYV8_2X8_BE: value = 0x00000000; /* Cb0, Y0, Cr0, Y1 */ break; - case V4L2_PIX_FMT_VYUY: + case V4L2_MBUS_FMT_YVYU8_2X8_BE: value = 0x00000100; /* Cr0, Y0, Cb0, Y1 */ break; - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8_LE: value = 0x00000200; /* Y0, Cb0, Y1, Cr0 */ break; - case V4L2_PIX_FMT_YVYU: + case V4L2_MBUS_FMT_YVYU8_2X8_LE: value = 0x00000300; /* Y0, Cr0, Y1, Cb0 */ break; default: @@ -698,8 +719,8 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, } } - if (icd->current_fmt->fourcc == V4L2_PIX_FMT_NV21 || - icd->current_fmt->fourcc == V4L2_PIX_FMT_NV61) + if (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV21 || + icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV61) value ^= 0x00000100; /* swap U, V to change from NV1x->NVx1 */ value |= common_flags & SOCAM_VSYNC_ACTIVE_LOW ? 1 << 1 : 0; @@ -746,7 +767,8 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, return 0; } -static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd) +static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd, + unsigned char buswidth) { struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct sh_mobile_ceu_dev *pcdev = ici->priv; @@ -755,48 +777,75 @@ static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd) camera_flags = icd->ops->query_bus_param(icd); common_flags = soc_camera_bus_param_compatible(camera_flags, make_bus_param(pcdev)); - if (!common_flags) + if (!common_flags || buswidth > 16 || + (buswidth > 8 && !(common_flags & SOCAM_DATAWIDTH_16))) return -EINVAL; return 0; } -static const struct soc_camera_data_format sh_mobile_ceu_formats[] = { - { - .name = "NV12", - .depth = 12, - .fourcc = V4L2_PIX_FMT_NV12, - .colorspace = V4L2_COLORSPACE_JPEG, - }, - { - .name = "NV21", - .depth = 12, - .fourcc = V4L2_PIX_FMT_NV21, - .colorspace = V4L2_COLORSPACE_JPEG, - }, - { - .name = "NV16", - .depth = 16, - .fourcc = V4L2_PIX_FMT_NV16, - .colorspace = V4L2_COLORSPACE_JPEG, - }, +static const struct soc_mbus_pixelfmt sh_mobile_ceu_formats[] = { { - .name = "NV61", - .depth = 16, - .fourcc = V4L2_PIX_FMT_NV61, - .colorspace = V4L2_COLORSPACE_JPEG, + .fourcc = V4L2_PIX_FMT_NV12, + .name = "NV12", + .bits_per_sample = 12, + .packing = SOC_MBUS_PACKING_NONE, + .order = SOC_MBUS_ORDER_LE, + }, { + .fourcc = V4L2_PIX_FMT_NV21, + .name = "NV21", + .bits_per_sample = 12, + .packing = SOC_MBUS_PACKING_NONE, + .order = SOC_MBUS_ORDER_LE, + }, { + .fourcc = V4L2_PIX_FMT_NV16, + .name = "NV16", + .bits_per_sample = 16, + .packing = SOC_MBUS_PACKING_NONE, + .order = SOC_MBUS_ORDER_LE, + }, { + .fourcc = V4L2_PIX_FMT_NV61, + .name = "NV61", + .bits_per_sample = 16, + .packing = SOC_MBUS_PACKING_NONE, + .order = SOC_MBUS_ORDER_LE, }, }; +/* This will be corrected as we get more formats */ +static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt) +{ + return fmt->packing == SOC_MBUS_PACKING_NONE || + (fmt->bits_per_sample == 8 && + fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) || + (fmt->bits_per_sample > 8 && + fmt->packing == SOC_MBUS_PACKING_EXTEND16); +} + static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, struct soc_camera_format_xlate *xlate) { + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->dev.parent; int ret, k, n; int formats = 0; struct sh_mobile_ceu_cam *cam; + enum v4l2_mbus_pixelcode code; + const struct soc_mbus_pixelfmt *fmt; - ret = sh_mobile_ceu_try_bus_param(icd); + ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); + if (ret < 0) + /* No more formats */ + return 0; + + fmt = soc_mbus_get_fmtdesc(code); + if (!fmt) { + dev_err(icd->dev.parent, + "Invalid format code #%d: %d\n", idx, code); + return -EINVAL; + } + + ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample); if (ret < 0) return 0; @@ -814,13 +863,13 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, if (!idx) cam->extra_fmt = NULL; - switch (icd->formats[idx].fourcc) { - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_VYUY: - case V4L2_PIX_FMT_YUYV: - case V4L2_PIX_FMT_YVYU: + switch (code) { + case V4L2_MBUS_FMT_YUYV8_2X8_BE: + case V4L2_MBUS_FMT_YVYU8_2X8_BE: + case V4L2_MBUS_FMT_YUYV8_2X8_LE: + case V4L2_MBUS_FMT_YVYU8_2X8_LE: if (cam->extra_fmt) - goto add_single_format; + break; /* * Our case is simple so far: for any of the above four camera @@ -831,32 +880,31 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, * the host_priv pointer and check whether the format you're * going to add now is already there. */ - cam->extra_fmt = (void *)sh_mobile_ceu_formats; + cam->extra_fmt = sh_mobile_ceu_formats; n = ARRAY_SIZE(sh_mobile_ceu_formats); formats += n; for (k = 0; xlate && k < n; k++) { - xlate->host_fmt = &sh_mobile_ceu_formats[k]; - xlate->cam_fmt = icd->formats + idx; - xlate->buswidth = icd->formats[idx].depth; + xlate->host_fmt = &sh_mobile_ceu_formats[k]; + xlate->code = code; xlate++; - dev_dbg(dev, "Providing format %s using %s\n", - sh_mobile_ceu_formats[k].name, - icd->formats[idx].name); + dev_dbg(dev, "Providing format %s using code %d\n", + sh_mobile_ceu_formats[k].name, code); } + break; default: -add_single_format: - /* Generic pass-through */ - formats++; - if (xlate) { - xlate->host_fmt = icd->formats + idx; - xlate->cam_fmt = icd->formats + idx; - xlate->buswidth = icd->formats[idx].depth; - xlate++; - dev_dbg(dev, - "Providing format %s in pass-through mode\n", - icd->formats[idx].name); - } + if (!sh_mobile_ceu_packing_supported(fmt)) + return 0; + } + + /* Generic pass-through */ + formats++; + if (xlate) { + xlate->host_fmt = fmt; + xlate->code = code; + xlate++; + dev_dbg(dev, "Providing format %s in pass-through mode\n", + xlate->host_fmt->name); } return formats; @@ -1036,17 +1084,15 @@ static int client_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *crop, static int get_camera_scales(struct v4l2_subdev *sd, struct v4l2_rect *rect, unsigned int *scale_h, unsigned int *scale_v) { - struct v4l2_format f; + struct v4l2_mbus_framefmt mf; int ret; - f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - ret = v4l2_subdev_call(sd, video, g_fmt, &f); + ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); if (ret < 0) return ret; - *scale_h = calc_generic_scale(rect->width, f.fmt.pix.width); - *scale_v = calc_generic_scale(rect->height, f.fmt.pix.height); + *scale_h = calc_generic_scale(rect->width, mf.width); + *scale_v = calc_generic_scale(rect->height, mf.height); return 0; } @@ -1061,32 +1107,29 @@ static int get_camera_subwin(struct soc_camera_device *icd, if (!ceu_rect->width) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->dev.parent; - struct v4l2_format f; - struct v4l2_pix_format *pix = &f.fmt.pix; + struct v4l2_mbus_framefmt mf; int ret; /* First time */ - f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - ret = v4l2_subdev_call(sd, video, g_fmt, &f); + ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); if (ret < 0) return ret; - dev_geo(dev, "camera fmt %ux%u\n", pix->width, pix->height); + dev_geo(dev, "camera fmt %ux%u\n", mf.width, mf.height); - if (pix->width > 2560) { + if (mf.width > 2560) { ceu_rect->width = 2560; - ceu_rect->left = (pix->width - 2560) / 2; + ceu_rect->left = (mf.width - 2560) / 2; } else { - ceu_rect->width = pix->width; + ceu_rect->width = mf.width; ceu_rect->left = 0; } - if (pix->height > 1920) { + if (mf.height > 1920) { ceu_rect->height = 1920; - ceu_rect->top = (pix->height - 1920) / 2; + ceu_rect->top = (mf.height - 1920) / 2; } else { - ceu_rect->height = pix->height; + ceu_rect->height = mf.height; ceu_rect->top = 0; } @@ -1103,13 +1146,12 @@ static int get_camera_subwin(struct soc_camera_device *icd, return 0; } -static int client_s_fmt(struct soc_camera_device *icd, struct v4l2_format *f, - bool ceu_can_scale) +static int client_s_fmt(struct soc_camera_device *icd, + struct v4l2_mbus_framefmt *mf, bool ceu_can_scale) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->dev.parent; - struct v4l2_pix_format *pix = &f->fmt.pix; - unsigned int width = pix->width, height = pix->height, tmp_w, tmp_h; + unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h; unsigned int max_width, max_height; struct v4l2_cropcap cap; int ret; @@ -1123,29 +1165,29 @@ static int client_s_fmt(struct soc_camera_device *icd, struct v4l2_format *f, max_width = min(cap.bounds.width, 2560); max_height = min(cap.bounds.height, 1920); - ret = v4l2_subdev_call(sd, video, s_fmt, f); + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, mf); if (ret < 0) return ret; - dev_geo(dev, "camera scaled to %ux%u\n", pix->width, pix->height); + dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height); - if ((width == pix->width && height == pix->height) || !ceu_can_scale) + if ((width == mf->width && height == mf->height) || !ceu_can_scale) return 0; /* Camera set a format, but geometry is not precise, try to improve */ - tmp_w = pix->width; - tmp_h = pix->height; + tmp_w = mf->width; + tmp_h = mf->height; /* width <= max_width && height <= max_height - guaranteed by try_fmt */ while ((width > tmp_w || height > tmp_h) && tmp_w < max_width && tmp_h < max_height) { tmp_w = min(2 * tmp_w, max_width); tmp_h = min(2 * tmp_h, max_height); - pix->width = tmp_w; - pix->height = tmp_h; - ret = v4l2_subdev_call(sd, video, s_fmt, f); + mf->width = tmp_w; + mf->height = tmp_h; + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, mf); dev_geo(dev, "Camera scaled to %ux%u\n", - pix->width, pix->height); + mf->width, mf->height); if (ret < 0) { /* This shouldn't happen */ dev_err(dev, "Client failed to set format: %d\n", ret); @@ -1163,27 +1205,26 @@ static int client_s_fmt(struct soc_camera_device *icd, struct v4l2_format *f, */ static int client_scale(struct soc_camera_device *icd, struct v4l2_rect *rect, struct v4l2_rect *sub_rect, struct v4l2_rect *ceu_rect, - struct v4l2_format *f, bool ceu_can_scale) + struct v4l2_mbus_framefmt *mf, bool ceu_can_scale) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct sh_mobile_ceu_cam *cam = icd->host_priv; struct device *dev = icd->dev.parent; - struct v4l2_format f_tmp = *f; - struct v4l2_pix_format *pix_tmp = &f_tmp.fmt.pix; + struct v4l2_mbus_framefmt mf_tmp = *mf; unsigned int scale_h, scale_v; int ret; /* 5. Apply iterative camera S_FMT for camera user window. */ - ret = client_s_fmt(icd, &f_tmp, ceu_can_scale); + ret = client_s_fmt(icd, &mf_tmp, ceu_can_scale); if (ret < 0) return ret; dev_geo(dev, "5: camera scaled to %ux%u\n", - pix_tmp->width, pix_tmp->height); + mf_tmp.width, mf_tmp.height); /* 6. Retrieve camera output window (g_fmt) */ - /* unneeded - it is already in "f_tmp" */ + /* unneeded - it is already in "mf_tmp" */ /* 7. Calculate new camera scales. */ ret = get_camera_scales(sd, rect, &scale_h, &scale_v); @@ -1192,10 +1233,11 @@ static int client_scale(struct soc_camera_device *icd, struct v4l2_rect *rect, dev_geo(dev, "7: camera scales %u:%u\n", scale_h, scale_v); - cam->cam_width = pix_tmp->width; - cam->cam_height = pix_tmp->height; - f->fmt.pix.width = pix_tmp->width; - f->fmt.pix.height = pix_tmp->height; + cam->cam_width = mf_tmp.width; + cam->cam_height = mf_tmp.height; + mf->width = mf_tmp.width; + mf->height = mf_tmp.height; + mf->colorspace = mf_tmp.colorspace; /* * 8. Calculate new CEU crop - apply camera scales to previously @@ -1259,8 +1301,7 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, struct v4l2_rect *cam_rect = &cam_crop.c, *ceu_rect = &cam->ceu_rect; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->dev.parent; - struct v4l2_format f; - struct v4l2_pix_format *pix = &f.fmt.pix; + struct v4l2_mbus_framefmt mf; unsigned int scale_comb_h, scale_comb_v, scale_ceu_h, scale_ceu_v, out_width, out_height; u32 capsr, cflcr; @@ -1309,25 +1350,24 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, * 5. Using actual input window and calculated combined scales calculate * camera target output window. */ - pix->width = scale_down(cam_rect->width, scale_comb_h); - pix->height = scale_down(cam_rect->height, scale_comb_v); + mf.width = scale_down(cam_rect->width, scale_comb_h); + mf.height = scale_down(cam_rect->height, scale_comb_v); - dev_geo(dev, "5: camera target %ux%u\n", pix->width, pix->height); + dev_geo(dev, "5: camera target %ux%u\n", mf.width, mf.height); /* 6. - 9. */ - pix->pixelformat = cam->camera_fmt->fourcc; - pix->colorspace = cam->camera_fmt->colorspace; + mf.code = cam->code; + mf.field = pcdev->is_interlaced ? V4L2_FIELD_INTERLACED : + V4L2_FIELD_NONE; capsr = capture_save_reset(pcdev); dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr); /* Make relative to camera rectangle */ - rect->left -= cam_rect->left; - rect->top -= cam_rect->top; + rect->left -= cam_rect->left; + rect->top -= cam_rect->top; - f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - ret = client_scale(icd, cam_rect, rect, ceu_rect, &f, + ret = client_scale(icd, cam_rect, rect, ceu_rect, &mf, pcdev->image_mode && !pcdev->is_interlaced); dev_geo(dev, "6-9: %d\n", ret); @@ -1375,8 +1415,7 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, struct sh_mobile_ceu_dev *pcdev = ici->priv; struct sh_mobile_ceu_cam *cam = icd->host_priv; struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_format cam_f = *f; - struct v4l2_pix_format *cam_pix = &cam_f.fmt.pix; + struct v4l2_mbus_framefmt mf; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->dev.parent; __u32 pixfmt = pix->pixelformat; @@ -1445,9 +1484,11 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, * 4. Calculate camera output window by applying combined scales to real * input window. */ - cam_pix->width = scale_down(cam_rect->width, scale_h); - cam_pix->height = scale_down(cam_rect->height, scale_v); - cam_pix->pixelformat = xlate->cam_fmt->fourcc; + mf.width = scale_down(cam_rect->width, scale_h); + mf.height = scale_down(cam_rect->height, scale_v); + mf.field = pix->field; + mf.colorspace = pix->colorspace; + mf.code = xlate->code; switch (pixfmt) { case V4L2_PIX_FMT_NV12: @@ -1460,11 +1501,10 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, image_mode = false; } - dev_geo(dev, "4: camera output %ux%u\n", - cam_pix->width, cam_pix->height); + dev_geo(dev, "4: camera output %ux%u\n", mf.width, mf.height); /* 5. - 9. */ - ret = client_scale(icd, cam_rect, &cam_subrect, &ceu_rect, &cam_f, + ret = client_scale(icd, cam_rect, &cam_subrect, &ceu_rect, &mf, image_mode && !is_interlaced); dev_geo(dev, "5-9: client scale %d\n", ret); @@ -1472,37 +1512,48 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, /* Done with the camera. Now see if we can improve the result */ dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n", - ret, cam_pix->width, cam_pix->height, pix->width, pix->height); + ret, mf.width, mf.height, pix->width, pix->height); if (ret < 0) return ret; + if (mf.code != xlate->code) + return -EINVAL; + /* 10. Use CEU scaling to scale to the requested user window. */ /* We cannot scale up */ - if (pix->width > cam_pix->width) - pix->width = cam_pix->width; + if (pix->width > mf.width) + pix->width = mf.width; if (pix->width > ceu_rect.width) pix->width = ceu_rect.width; - if (pix->height > cam_pix->height) - pix->height = cam_pix->height; + if (pix->height > mf.height) + pix->height = mf.height; if (pix->height > ceu_rect.height) pix->height = ceu_rect.height; - /* Let's rock: scale pix->{width x height} down to width x height */ - scale_h = calc_scale(ceu_rect.width, &pix->width); - scale_v = calc_scale(ceu_rect.height, &pix->height); + pix->colorspace = mf.colorspace; + + if (image_mode) { + /* Scale pix->{width x height} down to width x height */ + scale_h = calc_scale(ceu_rect.width, &pix->width); + scale_v = calc_scale(ceu_rect.height, &pix->height); + + pcdev->cflcr = scale_h | (scale_v << 16); + } else { + pix->width = ceu_rect.width; + pix->height = ceu_rect.height; + scale_h = scale_v = 0; + pcdev->cflcr = 0; + } dev_geo(dev, "10: W: %u : 0x%x = %u, H: %u : 0x%x = %u\n", ceu_rect.width, scale_h, pix->width, ceu_rect.height, scale_v, pix->height); - pcdev->cflcr = scale_h | (scale_v << 16); - - icd->buswidth = xlate->buswidth; - icd->current_fmt = xlate->host_fmt; - cam->camera_fmt = xlate->cam_fmt; - cam->ceu_rect = ceu_rect; + cam->code = xlate->code; + cam->ceu_rect = ceu_rect; + icd->current_fmt = xlate; pcdev->is_interlaced = is_interlaced; pcdev->image_mode = image_mode; @@ -1516,6 +1567,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + struct v4l2_mbus_framefmt mf; __u32 pixfmt = pix->pixelformat; int width, height; int ret; @@ -1534,18 +1586,27 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, width = pix->width; height = pix->height; - pix->bytesperline = pix->width * - DIV_ROUND_UP(xlate->host_fmt->depth, 8); - pix->sizeimage = pix->height * pix->bytesperline; - - pix->pixelformat = xlate->cam_fmt->fourcc; + pix->bytesperline = soc_mbus_bytes_per_line(width, xlate->host_fmt); + if (pix->bytesperline < 0) + return pix->bytesperline; + pix->sizeimage = height * pix->bytesperline; /* limit to sensor capabilities */ - ret = v4l2_subdev_call(sd, video, try_fmt, f); - pix->pixelformat = pixfmt; + mf.width = pix->width; + mf.height = pix->height; + mf.field = pix->field; + mf.code = xlate->code; + mf.colorspace = pix->colorspace; + + ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); if (ret < 0) return ret; + pix->width = mf.width; + pix->height = mf.height; + pix->field = mf.field; + pix->colorspace = mf.colorspace; + switch (pixfmt) { case V4L2_PIX_FMT_NV12: case V4L2_PIX_FMT_NV21: @@ -1554,21 +1615,25 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, /* FIXME: check against rect_max after converting soc-camera */ /* We can scale precisely, need a bigger image from camera */ if (pix->width < width || pix->height < height) { - int tmp_w = pix->width, tmp_h = pix->height; - pix->width = 2560; - pix->height = 1920; - ret = v4l2_subdev_call(sd, video, try_fmt, f); + /* + * We presume, the sensor behaves sanely, i.e., if + * requested a bigger rectangle, it will not return a + * smaller one. + */ + mf.width = 2560; + mf.height = 1920; + ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); if (ret < 0) { /* Shouldn't actually happen... */ dev_err(icd->dev.parent, - "FIXME: try_fmt() returned %d\n", ret); - pix->width = tmp_w; - pix->height = tmp_h; + "FIXME: client try_fmt() = %d\n", ret); + return ret; } } - if (pix->width > width) + /* We will scale exactly */ + if (mf.width > width) pix->width = width; - if (pix->height > height) + if (mf.height > height) pix->height = height; } @@ -1663,7 +1728,7 @@ static int sh_mobile_ceu_set_ctrl(struct soc_camera_device *icd, switch (ctrl->id) { case V4L2_CID_SHARPNESS: - switch (icd->current_fmt->fourcc) { + switch (icd->current_fmt->host_fmt->fourcc) { case V4L2_PIX_FMT_NV12: case V4L2_PIX_FMT_NV21: case V4L2_PIX_FMT_NV16: diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 5fdedc76640..6b3fbcca774 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -31,6 +31,7 @@ #include #include #include +#include /* Default to VGA resolution */ #define DEFAULT_WIDTH 640 @@ -40,18 +41,6 @@ static LIST_HEAD(hosts); static LIST_HEAD(devices); static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */ -const struct soc_camera_data_format *soc_camera_format_by_fourcc( - struct soc_camera_device *icd, unsigned int fourcc) -{ - unsigned int i; - - for (i = 0; i < icd->num_formats; i++) - if (icd->formats[i].fourcc == fourcc) - return icd->formats + i; - return NULL; -} -EXPORT_SYMBOL(soc_camera_format_by_fourcc); - const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( struct soc_camera_device *icd, unsigned int fourcc) { @@ -207,21 +196,26 @@ static int soc_camera_dqbuf(struct file *file, void *priv, /* Always entered with .video_lock held */ static int soc_camera_init_user_formats(struct soc_camera_device *icd) { + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - int i, fmts = 0, ret; + int i, fmts = 0, raw_fmts = 0, ret; + enum v4l2_mbus_pixelcode code; + + while (!v4l2_subdev_call(sd, video, enum_mbus_fmt, raw_fmts, &code)) + raw_fmts++; if (!ici->ops->get_formats) /* * Fallback mode - the host will have to serve all * sensor-provided formats one-to-one to the user */ - fmts = icd->num_formats; + fmts = raw_fmts; else /* * First pass - only count formats this host-sensor * configuration can provide */ - for (i = 0; i < icd->num_formats; i++) { + for (i = 0; i < raw_fmts; i++) { ret = ici->ops->get_formats(icd, i, NULL); if (ret < 0) return ret; @@ -242,11 +236,12 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd) /* Second pass - actually fill data formats */ fmts = 0; - for (i = 0; i < icd->num_formats; i++) + for (i = 0; i < raw_fmts; i++) if (!ici->ops->get_formats) { - icd->user_formats[i].host_fmt = icd->formats + i; - icd->user_formats[i].cam_fmt = icd->formats + i; - icd->user_formats[i].buswidth = icd->formats[i].depth; + v4l2_subdev_call(sd, video, enum_mbus_fmt, i, &code); + icd->user_formats[i].host_fmt = + soc_mbus_get_fmtdesc(code); + icd->user_formats[i].code = code; } else { ret = ici->ops->get_formats(icd, i, &icd->user_formats[fmts]); @@ -255,7 +250,7 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd) fmts += ret; } - icd->current_fmt = icd->user_formats[0].host_fmt; + icd->current_fmt = &icd->user_formats[0]; return 0; @@ -281,7 +276,7 @@ static void soc_camera_free_user_formats(struct soc_camera_device *icd) #define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \ ((x) >> 24) & 0xff -/* Called with .vb_lock held */ +/* Called with .vb_lock held, or from the first open(2), see comment there */ static int soc_camera_set_fmt(struct soc_camera_file *icf, struct v4l2_format *f) { @@ -302,7 +297,7 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf, if (ret < 0) { return ret; } else if (!icd->current_fmt || - icd->current_fmt->fourcc != pix->pixelformat) { + icd->current_fmt->host_fmt->fourcc != pix->pixelformat) { dev_err(&icd->dev, "Host driver hasn't set up current format correctly!\n"); return -EINVAL; @@ -310,6 +305,7 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf, icd->user_width = pix->width; icd->user_height = pix->height; + icd->colorspace = pix->colorspace; icf->vb_vidq.field = icd->field = pix->field; @@ -369,8 +365,9 @@ static int soc_camera_open(struct file *file) .width = icd->user_width, .height = icd->user_height, .field = icd->field, - .pixelformat = icd->current_fmt->fourcc, - .colorspace = icd->current_fmt->colorspace, + .colorspace = icd->colorspace, + .pixelformat = + icd->current_fmt->host_fmt->fourcc, }, }; @@ -390,7 +387,12 @@ static int soc_camera_open(struct file *file) goto eiciadd; } - /* Try to configure with default parameters */ + /* + * Try to configure with default parameters. Notice: this is the + * very first open, so, we cannot race against other calls, + * apart from someone else calling open() simultaneously, but + * .video_lock is protecting us against it. + */ ret = soc_camera_set_fmt(icf, &f); if (ret < 0) goto esfmt; @@ -534,7 +536,7 @@ static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv, { struct soc_camera_file *icf = file->private_data; struct soc_camera_device *icd = icf->icd; - const struct soc_camera_data_format *format; + const struct soc_mbus_pixelfmt *format; WARN_ON(priv != file->private_data); @@ -543,7 +545,8 @@ static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv, format = icd->user_formats[f->index].host_fmt; - strlcpy(f->description, format->name, sizeof(f->description)); + if (format->name) + strlcpy(f->description, format->name, sizeof(f->description)); f->pixelformat = format->fourcc; return 0; } @@ -560,12 +563,15 @@ static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv, pix->width = icd->user_width; pix->height = icd->user_height; pix->field = icf->vb_vidq.field; - pix->pixelformat = icd->current_fmt->fourcc; - pix->bytesperline = pix->width * - DIV_ROUND_UP(icd->current_fmt->depth, 8); + pix->pixelformat = icd->current_fmt->host_fmt->fourcc; + pix->bytesperline = soc_mbus_bytes_per_line(pix->width, + icd->current_fmt->host_fmt); + pix->colorspace = icd->colorspace; + if (pix->bytesperline < 0) + return pix->bytesperline; pix->sizeimage = pix->height * pix->bytesperline; dev_dbg(&icd->dev, "current_fmt->fourcc: 0x%08x\n", - icd->current_fmt->fourcc); + icd->current_fmt->host_fmt->fourcc); return 0; } @@ -894,7 +900,7 @@ static int soc_camera_probe(struct device *dev) struct soc_camera_link *icl = to_soc_camera_link(icd); struct device *control = NULL; struct v4l2_subdev *sd; - struct v4l2_format f = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE}; + struct v4l2_mbus_framefmt mf; int ret; dev_info(dev, "Probing %s\n", dev_name(dev)); @@ -965,9 +971,11 @@ static int soc_camera_probe(struct device *dev) /* Try to improve our guess of a reasonable window format */ sd = soc_camera_to_subdev(icd); - if (!v4l2_subdev_call(sd, video, g_fmt, &f)) { - icd->user_width = f.fmt.pix.width; - icd->user_height = f.fmt.pix.height; + if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) { + icd->user_width = mf.width; + icd->user_height = mf.height; + icd->colorspace = mf.colorspace; + icd->field = mf.field; } /* Do we have to sysfs_remove_link() before device_unregister()? */ diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c index c7c91518c39..10b003a8be8 100644 --- a/drivers/media/video/soc_camera_platform.c +++ b/drivers/media/video/soc_camera_platform.c @@ -22,7 +22,6 @@ struct soc_camera_platform_priv { struct v4l2_subdev subdev; - struct soc_camera_data_format format; }; static struct soc_camera_platform_priv *get_priv(struct platform_device *pdev) @@ -58,36 +57,36 @@ soc_camera_platform_query_bus_param(struct soc_camera_device *icd) } static int soc_camera_platform_try_fmt(struct v4l2_subdev *sd, - struct v4l2_format *f) + struct v4l2_mbus_framefmt *mf) { struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = p->format.width; - pix->height = p->format.height; + mf->width = p->format.width; + mf->height = p->format.height; + mf->code = p->format.code; + mf->colorspace = p->format.colorspace; + return 0; } -static void soc_camera_platform_video_probe(struct soc_camera_device *icd, - struct platform_device *pdev) +static struct v4l2_subdev_core_ops platform_subdev_core_ops; + +static int soc_camera_platform_enum_fmt(struct v4l2_subdev *sd, int index, + enum v4l2_mbus_pixelcode *code) { - struct soc_camera_platform_priv *priv = get_priv(pdev); - struct soc_camera_platform_info *p = pdev->dev.platform_data; + struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); - priv->format.name = p->format_name; - priv->format.depth = p->format_depth; - priv->format.fourcc = p->format.pixelformat; - priv->format.colorspace = p->format.colorspace; + if (index) + return -EINVAL; - icd->formats = &priv->format; - icd->num_formats = 1; + *code = p->format.code; + return 0; } -static struct v4l2_subdev_core_ops platform_subdev_core_ops; - static struct v4l2_subdev_video_ops platform_subdev_video_ops = { .s_stream = soc_camera_platform_s_stream, - .try_fmt = soc_camera_platform_try_fmt, + .try_mbus_fmt = soc_camera_platform_try_fmt, + .enum_mbus_fmt = soc_camera_platform_enum_fmt, }; static struct v4l2_subdev_ops platform_subdev_ops = { @@ -128,12 +127,10 @@ static int soc_camera_platform_probe(struct platform_device *pdev) /* Set the control device reference */ dev_set_drvdata(&icd->dev, &pdev->dev); - icd->ops = &soc_camera_platform_ops; + icd->ops = &soc_camera_platform_ops; ici = to_soc_camera_host(icd->dev.parent); - soc_camera_platform_video_probe(icd, pdev); - v4l2_subdev_init(&priv->subdev, &platform_subdev_ops); v4l2_set_subdevdata(&priv->subdev, p); strncpy(priv->subdev.name, dev_name(&pdev->dev), V4L2_SUBDEV_NAME_SIZE); diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index 8ec1031dacc..341d0e035cb 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c @@ -251,15 +251,6 @@ static const struct regval_list tw9910_default_regs[] = ENDMARKER, }; -static const struct soc_camera_data_format tw9910_color_fmt[] = { - { - .name = "VYUY", - .fourcc = V4L2_PIX_FMT_VYUY, - .depth = 16, - .colorspace = V4L2_COLORSPACE_SMPTE170M, - } -}; - static const struct tw9910_scale_ctrl tw9910_ntsc_scales[] = { { .name = "NTSC SQ", @@ -814,11 +805,11 @@ static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) return 0; } -static int tw9910_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int tw9910_g_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct tw9910_priv *priv = to_tw9910(client); - struct v4l2_pix_format *pix = &f->fmt.pix; if (!priv->scale) { int ret; @@ -835,74 +826,76 @@ static int tw9910_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) return ret; } - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - pix->width = priv->scale->width; - pix->height = priv->scale->height; - pix->pixelformat = V4L2_PIX_FMT_VYUY; - pix->colorspace = V4L2_COLORSPACE_SMPTE170M; - pix->field = V4L2_FIELD_INTERLACED; + mf->width = priv->scale->width; + mf->height = priv->scale->height; + mf->code = V4L2_MBUS_FMT_YVYU8_2X8_BE; + mf->colorspace = V4L2_COLORSPACE_JPEG; + mf->field = V4L2_FIELD_INTERLACED; return 0; } -static int tw9910_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int tw9910_s_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct tw9910_priv *priv = to_tw9910(client); - struct v4l2_pix_format *pix = &f->fmt.pix; /* See tw9910_s_crop() - no proper cropping support */ struct v4l2_crop a = { .c = { .left = 0, .top = 0, - .width = pix->width, - .height = pix->height, + .width = mf->width, + .height = mf->height, }, }; - int i, ret; + int ret; + + WARN_ON(mf->field != V4L2_FIELD_ANY && + mf->field != V4L2_FIELD_INTERLACED); /* * check color format */ - for (i = 0; i < ARRAY_SIZE(tw9910_color_fmt); i++) - if (pix->pixelformat == tw9910_color_fmt[i].fourcc) - break; - - if (i == ARRAY_SIZE(tw9910_color_fmt)) + if (mf->code != V4L2_MBUS_FMT_YVYU8_2X8_BE) return -EINVAL; + mf->colorspace = V4L2_COLORSPACE_JPEG; + ret = tw9910_s_crop(sd, &a); if (!ret) { - pix->width = priv->scale->width; - pix->height = priv->scale->height; + mf->width = priv->scale->width; + mf->height = priv->scale->height; } return ret; } -static int tw9910_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int tw9910_try_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; - struct v4l2_pix_format *pix = &f->fmt.pix; const struct tw9910_scale_ctrl *scale; - if (V4L2_FIELD_ANY == pix->field) { - pix->field = V4L2_FIELD_INTERLACED; - } else if (V4L2_FIELD_INTERLACED != pix->field) { - dev_err(&client->dev, "Field type invalid.\n"); + if (V4L2_FIELD_ANY == mf->field) { + mf->field = V4L2_FIELD_INTERLACED; + } else if (V4L2_FIELD_INTERLACED != mf->field) { + dev_err(&client->dev, "Field type %d invalid.\n", mf->field); return -EINVAL; } + mf->code = V4L2_MBUS_FMT_YVYU8_2X8_BE; + mf->colorspace = V4L2_COLORSPACE_JPEG; + /* * select suitable norm */ - scale = tw9910_select_norm(icd, pix->width, pix->height); + scale = tw9910_select_norm(icd, mf->width, mf->height); if (!scale) return -EINVAL; - pix->width = scale->width; - pix->height = scale->height; + mf->width = scale->width; + mf->height = scale->height; return 0; } @@ -930,9 +923,6 @@ static int tw9910_video_probe(struct soc_camera_device *icd, return -ENODEV; } - icd->formats = tw9910_color_fmt; - icd->num_formats = ARRAY_SIZE(tw9910_color_fmt); - /* * check and show Product ID * So far only revisions 0 and 1 have been seen @@ -973,14 +963,25 @@ static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = { #endif }; +static int tw9910_enum_fmt(struct v4l2_subdev *sd, int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index) + return -EINVAL; + + *code = V4L2_MBUS_FMT_YVYU8_2X8_BE; + return 0; +} + static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { .s_stream = tw9910_s_stream, - .g_fmt = tw9910_g_fmt, - .s_fmt = tw9910_s_fmt, - .try_fmt = tw9910_try_fmt, + .g_mbus_fmt = tw9910_g_fmt, + .s_mbus_fmt = tw9910_s_fmt, + .try_mbus_fmt = tw9910_try_fmt, .cropcap = tw9910_cropcap, .g_crop = tw9910_g_crop, .s_crop = tw9910_s_crop, + .enum_mbus_fmt = tw9910_enum_fmt, }; static struct v4l2_subdev_ops tw9910_subdev_ops = { diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 831efffaf2a..dcc5b86bcb6 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -24,15 +24,13 @@ struct soc_camera_device { struct device *pdev; /* Platform device */ s32 user_width; s32 user_height; + enum v4l2_colorspace colorspace; unsigned char iface; /* Host number */ unsigned char devnum; /* Device number per host */ - unsigned char buswidth; /* See comment in .c */ struct soc_camera_sense *sense; /* See comment in struct definition */ struct soc_camera_ops *ops; struct video_device *vdev; - const struct soc_camera_data_format *current_fmt; - const struct soc_camera_data_format *formats; - int num_formats; + const struct soc_camera_format_xlate *current_fmt; struct soc_camera_format_xlate *user_formats; int num_user_formats; enum v4l2_field field; /* Preserve field over close() */ @@ -161,23 +159,13 @@ static inline struct v4l2_subdev *soc_camera_to_subdev( int soc_camera_host_register(struct soc_camera_host *ici); void soc_camera_host_unregister(struct soc_camera_host *ici); -const struct soc_camera_data_format *soc_camera_format_by_fourcc( - struct soc_camera_device *icd, unsigned int fourcc); const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( struct soc_camera_device *icd, unsigned int fourcc); -struct soc_camera_data_format { - const char *name; - unsigned int depth; - __u32 fourcc; - enum v4l2_colorspace colorspace; -}; - /** * struct soc_camera_format_xlate - match between host and sensor formats - * @cam_fmt: sensor format provided by the sensor - * @host_fmt: host format after host translation from cam_fmt - * @buswidth: bus width for this format + * @code: code of a sensor provided format + * @host_fmt: host format after host translation from code * * Host and sensor translation structure. Used in table of host and sensor * formats matchings in soc_camera_device. A host can override the generic list @@ -185,9 +173,8 @@ struct soc_camera_data_format { * format setup. */ struct soc_camera_format_xlate { - const struct soc_camera_data_format *cam_fmt; - const struct soc_camera_data_format *host_fmt; - unsigned char buswidth; + enum v4l2_mbus_pixelcode code; + const struct soc_mbus_pixelfmt *host_fmt; }; struct soc_camera_ops { diff --git a/include/media/soc_camera_platform.h b/include/media/soc_camera_platform.h index 88b3b5747f6..0ecefe227b7 100644 --- a/include/media/soc_camera_platform.h +++ b/include/media/soc_camera_platform.h @@ -19,7 +19,7 @@ struct device; struct soc_camera_platform_info { const char *format_name; unsigned long format_depth; - struct v4l2_pix_format format; + struct v4l2_mbus_framefmt format; unsigned long bus_param; struct device *dev; int (*set_capture)(struct soc_camera_platform_info *info, int enable); -- cgit v1.2.3-70-g09d2 From a6b5f2008a3d54b5f5350a01121b718dd6bfead7 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 11 Dec 2009 11:53:45 -0300 Subject: V4L/DVB (13661): rj54n1cb0c: Add cropping, auto white balance, restrict sizes, add platform data It has been experimentally found out, that the sensor only supports up to 512x384 video output and also has some restrictions on minimum scale. We disable non-working size ranges until, maybe, someone finds out how to properly set them up. Also add cropping support, an auto white balance control, platform data to specify master clock frequency and polarity of the IOCTL pin. create mode 100644 include/media/rj54n1cb0c.h Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- arch/sh/boards/mach-kfr2r09/setup.c | 13 +- drivers/media/video/rj54n1cb0c.c | 277 ++++++++++++++++++++++++++++++------ include/media/rj54n1cb0c.h | 19 +++ 3 files changed, 261 insertions(+), 48 deletions(-) create mode 100644 include/media/rj54n1cb0c.h (limited to 'drivers/media') diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index 87438d6603d..9038d768a52 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include