From cc7185f96b8e9132c28118367f6c84569939c37d Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 16 Dec 2008 00:56:08 -0500 Subject: sms1xxx: enable rf switch on Hauppauge Tiger devices From: Michael Krufky Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/siano/sms-cards.c | 23 +++++++++++++++++++++-- linux/drivers/media/dvb/siano/sms-cards.h | 3 ++- linux/drivers/media/dvb/siano/smsdvb.c | 19 +++++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/siano/sms-cards.c b/linux/drivers/media/dvb/siano/sms-cards.c index 79f5715c0..6c8faeb74 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.c +++ b/linux/drivers/media/dvb/siano/sms-cards.c @@ -117,6 +117,7 @@ static struct sms_board sms_boards[] = { .type = SMS_NOVA_B0, .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", .lna_ctrl = 29, + .rf_switch = 17, }, [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = { .name = "Hauppauge WinTV MiniCard", @@ -199,8 +200,8 @@ int sms_board_power(struct smscore_device_t *coredev, int onoff) case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: /* LNA */ - sms_set_gpio(coredev, - board->lna_ctrl, onoff ? 1 : 0); + if (!onoff) + sms_set_gpio(coredev, board->lna_ctrl, 0); break; } return 0; @@ -227,3 +228,21 @@ int sms_board_led_feedback(struct smscore_device_t *coredev, int led) } return 0; } + +int sms_board_lna_control(struct smscore_device_t *coredev, int onoff) +{ + int board_id = smscore_get_board_id(coredev); + struct sms_board *board = sms_get_board(board_id); + + sms_debug("%s: LNA %s", __func__, onoff ? "enabled" : "disabled"); + + switch (board_id) { + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: + sms_set_gpio(coredev, + board->rf_switch, onoff ? 1 : 0); + return sms_set_gpio(coredev, + board->lna_ctrl, onoff ? 1 : 0); + } + return -EINVAL; +} diff --git a/linux/drivers/media/dvb/siano/sms-cards.h b/linux/drivers/media/dvb/siano/sms-cards.h index 8e0fe9fd2..fe292aaea 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.h +++ b/linux/drivers/media/dvb/siano/sms-cards.h @@ -40,7 +40,7 @@ struct sms_board { char *name, *fw[DEVICE_MODE_MAX]; /* gpios */ - int led_power, led_hi, led_lo, lna_ctrl; + int led_power, led_hi, led_lo, lna_ctrl, rf_switch; }; struct sms_board *sms_get_board(int id); @@ -52,6 +52,7 @@ int sms_board_setup(struct smscore_device_t *coredev); #define SMS_LED_HI 2 int sms_board_led_feedback(struct smscore_device_t *coredev, int led); int sms_board_power(struct smscore_device_t *coredev, int onoff); +int sms_board_lna_control(struct smscore_device_t *coredev, int onoff); extern struct usb_device_id smsusb_id_table[]; diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c index bbc87fe2e..a2efb402e 100644 --- a/linux/drivers/media/dvb/siano/smsdvb.c +++ b/linux/drivers/media/dvb/siano/smsdvb.c @@ -262,6 +262,7 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, struct SmsMsgHdr_ST Msg; u32 Data[3]; } Msg; + int ret; Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; Msg.Msg.msgDstId = HIF_TASK; @@ -285,6 +286,24 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, default: return -EINVAL; } + /* Disable LNA, if any. An error is returned if no LNA is present */ + ret = sms_board_lna_control(client->coredev, 0); + if (ret == 0) { + fe_status_t status; + + /* tune with LNA off at first */ + ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), + &client->tune_done); + + smsdvb_read_status(fe, &status); + + if (status & FE_HAS_LOCK) + return ret; + + /* previous tune didnt lock - enable LNA and tune again */ + sms_board_lna_control(client->coredev, 1); + } + return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->tune_done); } -- cgit v1.2.3 From 5180a035b637308ddd873e58c46fdedbecb061f6 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 31 Aug 2008 16:15:47 -0400 Subject: sms1xxx: move definition of struct smsdvb_client_t into smsdvb.c From: Michael Krufky Nobody uses struct smsdvb_client_t other than smsdvb.c -- this does not need to be inside smscoreapi.h Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/siano/smscoreapi.h | 21 --------------------- linux/drivers/media/dvb/siano/smsdvb.c | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 21 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index 1ab277767..0469f1bd8 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -523,27 +523,6 @@ struct smscore_gpio_config { u8 outputdriving; }; -struct smsdvb_client_t { - struct list_head entry; - - struct smscore_device_t *coredev; - struct smscore_client_t *smsclient; - - struct dvb_adapter adapter; - struct dvb_demux demux; - struct dmxdev dmxdev; - struct dvb_frontend frontend; - - fe_status_t fe_status; - int fe_ber, fe_snr, fe_unc, fe_signal_strength; - - struct completion tune_done, stat_done; - - /* todo: save freq/band instead whole struct */ - struct dvb_frontend_parameters fe_params; - -}; - extern void smscore_registry_setmode(char *devpath, int mode); extern int smscore_registry_getmode(char *devpath); diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c index a2efb402e..68f3f31bb 100644 --- a/linux/drivers/media/dvb/siano/smsdvb.c +++ b/linux/drivers/media/dvb/siano/smsdvb.c @@ -27,6 +27,26 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); +struct smsdvb_client_t { + struct list_head entry; + + struct smscore_device_t *coredev; + struct smscore_client_t *smsclient; + + struct dvb_adapter adapter; + struct dvb_demux demux; + struct dmxdev dmxdev; + struct dvb_frontend frontend; + + fe_status_t fe_status; + int fe_ber, fe_snr, fe_unc, fe_signal_strength; + + struct completion tune_done, stat_done; + + /* todo: save freq/band instead whole struct */ + struct dvb_frontend_parameters fe_params; +}; + static struct list_head g_smsdvb_clients; static struct mutex g_smsdvb_clientslock; -- cgit v1.2.3 From c058193ee17449d1cb5e4685cab530b95bbb2b1b Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 30 Aug 2008 23:44:04 -0400 Subject: sms1xxx: restore smsusb_driver.name to smsusb From: Uri Shkolnik The sms1xxx driver will be broken down into smaller modules, so the original name, smsusb, is more appropriate. Signed-off-by: Uri Shkolnik Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/siano/smsusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index fd191b0ef..7a04b34b0 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/drivers/media/dvb/siano/smsusb.c @@ -479,7 +479,7 @@ static int smsusb_resume(struct usb_interface *intf) } static struct usb_driver smsusb_driver = { - .name = "sms1xxx", + .name = "smsusb", .probe = smsusb_probe, .disconnect = smsusb_disconnect, .id_table = smsusb_id_table, -- cgit v1.2.3 From ddc98ba47b865fb467edeb186cb64ae65d608e26 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 31 Aug 2008 16:03:15 -0400 Subject: sms1xxx: move smsusb_id_table into smsusb.c From: Michael Krufky Move the usb_device_id table to the smsusb module in preparation for the sms1xxx module to be split into sub-modules. This will allow the smsusb driver to start up automatically upon insertion of the USB device. Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/siano/sms-cards.c | 47 ------------------------------- linux/drivers/media/dvb/siano/sms-cards.h | 2 -- linux/drivers/media/dvb/siano/smsusb.c | 47 +++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 49 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/siano/sms-cards.c b/linux/drivers/media/dvb/siano/sms-cards.c index 6c8faeb74..39f83faa2 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.c +++ b/linux/drivers/media/dvb/siano/sms-cards.c @@ -19,53 +19,6 @@ #include "sms-cards.h" -struct usb_device_id smsusb_id_table[] = { -#ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS - { USB_DEVICE(0x187f, 0x0010), - .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, - { USB_DEVICE(0x187f, 0x0100), - .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, - { USB_DEVICE(0x187f, 0x0200), - .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A }, - { USB_DEVICE(0x187f, 0x0201), - .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B }, - { USB_DEVICE(0x187f, 0x0300), - .driver_info = SMS1XXX_BOARD_SIANO_VEGA }, -#endif - { USB_DEVICE(0x2040, 0x1700), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT }, - { USB_DEVICE(0x2040, 0x1800), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A }, - { USB_DEVICE(0x2040, 0x1801), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B }, - { USB_DEVICE(0x2040, 0x2000), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x2009), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 }, - { USB_DEVICE(0x2040, 0x200a), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x2010), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x2011), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x2019), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x5500), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5510), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5520), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5530), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5580), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5590), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, smsusb_id_table); - static struct sms_board sms_boards[] = { [SMS_BOARD_UNKNOWN] = { .name = "Unknown board", diff --git a/linux/drivers/media/dvb/siano/sms-cards.h b/linux/drivers/media/dvb/siano/sms-cards.h index fe292aaea..8f539a2e5 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.h +++ b/linux/drivers/media/dvb/siano/sms-cards.h @@ -54,6 +54,4 @@ int sms_board_led_feedback(struct smscore_device_t *coredev, int led); int sms_board_power(struct smscore_device_t *coredev, int onoff); int sms_board_lna_control(struct smscore_device_t *coredev, int onoff); -extern struct usb_device_id smsusb_id_table[]; - #endif /* __SMS_CARDS_H__ */ diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index 7a04b34b0..19005c26b 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/drivers/media/dvb/siano/smsusb.c @@ -478,6 +478,53 @@ static int smsusb_resume(struct usb_interface *intf) return 0; } +struct usb_device_id smsusb_id_table[] = { +#ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS + { USB_DEVICE(0x187f, 0x0010), + .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, + { USB_DEVICE(0x187f, 0x0100), + .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, + { USB_DEVICE(0x187f, 0x0200), + .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A }, + { USB_DEVICE(0x187f, 0x0201), + .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B }, + { USB_DEVICE(0x187f, 0x0300), + .driver_info = SMS1XXX_BOARD_SIANO_VEGA }, +#endif + { USB_DEVICE(0x2040, 0x1700), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT }, + { USB_DEVICE(0x2040, 0x1800), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A }, + { USB_DEVICE(0x2040, 0x1801), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B }, + { USB_DEVICE(0x2040, 0x2000), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, + { USB_DEVICE(0x2040, 0x2009), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 }, + { USB_DEVICE(0x2040, 0x200a), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, + { USB_DEVICE(0x2040, 0x2010), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, + { USB_DEVICE(0x2040, 0x2011), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, + { USB_DEVICE(0x2040, 0x2019), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, + { USB_DEVICE(0x2040, 0x5500), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0x5510), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0x5520), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0x5530), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0x5580), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0x5590), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, smsusb_id_table); + static struct usb_driver smsusb_driver = { .name = "smsusb", .probe = smsusb_probe, -- cgit v1.2.3 From e8a3398295b9a981e3c19553f7908bebe95de079 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 30 Aug 2008 23:44:04 -0400 Subject: import changes from Siano From: Uri Shkolnik Import the following changes from Uri Shkolnik * Two-ways merge with Siano internal repository * Continuing with DVB sub-system separation * kconfig and makefile updates * Code cleanup This is a work-in-progress sync with Siano's internal repository. Some changes had to be altered or dropped in order not to break the build. This breaks normal operation for the current driver, but it is being committed now for tracking purposes. These changes introduce the following checkpatch.pl violations: ERROR: do not use C99 // comments 156: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1373: +//#ifdef DVB_CORE ERROR: do not use C99 // comments 157: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1374: +// smsdvb_unregister(); ERROR: do not use C99 // comments 158: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1375: +//#endif WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 163: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1380: +EXPORT_SYMBOL(smscore_onresponse); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 164: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1381: +EXPORT_SYMBOL(sms_get_board); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 165: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1382: +EXPORT_SYMBOL(sms_debug); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 166: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1383: +EXPORT_SYMBOL(smscore_putbuffer); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 167: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1384: +EXPORT_SYMBOL(smscore_registry_getmode); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 168: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1385: +EXPORT_SYMBOL(smscore_register_device); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 169: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1386: +EXPORT_SYMBOL(smscore_set_board_id); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 170: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1387: +EXPORT_SYMBOL(smscore_start_device); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 171: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1388: +EXPORT_SYMBOL(smsusb_id_table); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 172: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1389: +EXPORT_SYMBOL(smscore_unregister_device); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 173: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1390: +EXPORT_SYMBOL(smscore_getbuffer); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 174: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1391: +EXPORT_SYMBOL(smscore_get_device_mode); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 175: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1392: +EXPORT_SYMBOL(smscore_register_client); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 176: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1393: +EXPORT_SYMBOL(smscore_unregister_hotplug); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 177: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1394: +EXPORT_SYMBOL(smsclient_sendrequest); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 178: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1395: +EXPORT_SYMBOL(smscore_unregister_client); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 179: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1396: +EXPORT_SYMBOL(smscore_get_board_id); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 180: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1397: +EXPORT_SYMBOL(smscore_register_hotplug); WARNING: line over 80 characters 391: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:398: +extern int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, char* filename); ERROR: "foo* bar" should be "foo *bar" 391: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:398: +extern int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, char* filename); WARNING: line over 80 characters 392: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:399: +extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8* ufwbuf,int size); ERROR: "foo* bar" should be "foo *bar" 392: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:399: +extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8* ufwbuf,int size); ERROR: space required after that ',' (ctx:VxV) 392: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:399: +extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8* ufwbuf,int size); ^ WARNING: __func__ should be used instead of gcc specific __FUNCTION__ 489: FILE: linux/drivers/media/dvb/siano/smsusb.c:443: + printk(KERN_INFO"%s Entering status %d.\n", __FUNCTION__, msg.event); WARNING: __func__ should be used instead of gcc specific __FUNCTION__ 501: FILE: linux/drivers/media/dvb/siano/smsusb.c:455: + printk(KERN_INFO "%s Entering.\n", __FUNCTION__); ERROR: space prohibited before that '++' (ctx:WxB) 505: FILE: linux/drivers/media/dvb/siano/smsusb.c:459: + for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i ++) ^ WARNING: __func__ should be used instead of gcc specific __FUNCTION__ 517: FILE: linux/drivers/media/dvb/siano/smsusb.c:471: + __FUNCTION__, rc); total: 7 errors, 23 warnings, 524 lines checked Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/siano/Makefile | 4 +- linux/drivers/media/dvb/siano/smscoreapi.c | 121 +++++++++++++++++++++++++---- linux/drivers/media/dvb/siano/smscoreapi.h | 15 ++-- linux/drivers/media/dvb/siano/smsdvb.c | 23 +++--- linux/drivers/media/dvb/siano/smsusb.c | 10 ++- 5 files changed, 134 insertions(+), 39 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/siano/Makefile b/linux/drivers/media/dvb/siano/Makefile index ee0737af9..bcf93f482 100644 --- a/linux/drivers/media/dvb/siano/Makefile +++ b/linux/drivers/media/dvb/siano/Makefile @@ -1,6 +1,8 @@ -sms1xxx-objs := smscoreapi.o smsusb.o smsdvb.o sms-cards.o +sms1xxx-objs := smscoreapi.o sms-cards.o obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o +obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsusb.o +obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsdvb.o EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core diff --git a/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c index b19dd9c7d..5d56f6295 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.c +++ b/linux/drivers/media/dvb/siano/smscoreapi.c @@ -3,7 +3,7 @@ * * This file contains implementation for the interface to sms core component * - * author: Anatoly Greenblat + * author: Uri Shkolnik * * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. * @@ -732,7 +732,7 @@ static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { /*DVBH*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, /*TDMB*/ - {"none", "tdmb_nova_12mhz.inp", "none", "none"}, + {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"}, /*DABIP*/ {"none", "none", "none", "none"}, /*BDA*/ @@ -960,10 +960,6 @@ void smscore_onresponse(struct smscore_device_t *coredev, #endif /* If no client registered for type & id, * check for control client where type is not registered */ -#if 0 - if (!client) - client = smscore_find_client(coredev, 0, phdr->msgDstId); -#endif if (client) rc = client->onresponse_handler(client->context, cb); @@ -1337,12 +1333,67 @@ static int __init smscore_module_init(void) INIT_LIST_HEAD(&g_smscore_registry); kmutex_init(&g_smscore_registrylock); - /* USB Register */ - rc = smsusb_register(); +#if 0 /* def SMS_CHAR_CLIENT */ + /* Char interface Register */ + rc = smschar_register(); + if (rc) { + sms_err("Error registering char device client.\n"); + goto smschar_error; + } +#endif +#if 0 /* def SMS_DVB_CLIENT */ /* DVB Register */ rc = smsdvb_register(); + if (rc) { + sms_err("Error registering DVB client.\n"); + goto smsdvb_error; + } +#endif + +#if 0 /* def SMS_NET_CLIENT */ + /* DVB Register */ + rc = smsnet_register(); + if (rc) { + sms_err("Error registering Network client.\n"); + goto smsnet_error; + } +#endif +#if 0 /* def SMS_USB_BUS_DRV */ + /* USB Register */ + rc = smsusb_register(); + if (rc) { + sms_err("Error registering USB bus driver.\n"); + goto sms_bus_drv_error; + } +#endif + +#if 0 /* def SMS_SPI_BUS_DRV */ + /* USB Register */ + rc = smsspi_register(); + if (rc) { + sms_err("Error registering spi bus driver.\n"); + goto sms_bus_drv_error; + } +#endif + + return rc; +#if 0 +sms_bus_drv_error: +#endif /* 0 */ +#if 0 /* def SMS_NET_CLIENT */ + smsnet_unregister(); +smsnet_error: +#endif +#if 0 /* def SMS_DVB_CLIENT */ + smsdvb_unregister(); +smsdvb_error: +#endif +#if 0 /* def SMS_CHAR_CLIENT */ + smschar_unregister(); +smschar_error: +#endif sms_debug("rc %d", rc); return rc; @@ -1350,6 +1401,30 @@ static int __init smscore_module_init(void) static void __exit smscore_module_exit(void) { +#if 0 /* def SMS_CHAR_CLIENT */ + /* Char interface UnRegister */ + smschar_unregister(); +#endif + +#if 0 /* def SMS_DVB_CLIENT */ + /* DVB UnRegister */ + smsdvb_unregister(); +#endif + +#if 0 /* def SMS_NET_CLIENT */ + /* NET UnRegister */ + smsnet_unregister(); +#endif + +#if 0 /* def SMS_USB_BUS_DRV */ + /* Unregister USB */ + smsusb_unregister(); +#endif + +#if 0 /* def SMS_SPI_BUS_DRV */ + /* Unregister SPI */ + smsspi_unregister(); +#endif kmutex_lock(&g_smscore_deviceslock); while (!list_empty(&g_smscore_notifyees)) { @@ -1373,18 +1448,34 @@ static void __exit smscore_module_exit(void) } kmutex_unlock(&g_smscore_registrylock); - /* DVB UnRegister */ - smsdvb_unregister(); - - /* Unregister USB */ - smsusb_unregister(); +//#ifdef DVB_CORE +// smsdvb_unregister(); +//#endif sms_debug(""); } +EXPORT_SYMBOL(smscore_onresponse); +EXPORT_SYMBOL(sms_get_board); +EXPORT_SYMBOL(sms_debug); +EXPORT_SYMBOL(smscore_putbuffer); +EXPORT_SYMBOL(smscore_registry_getmode); +EXPORT_SYMBOL(smscore_register_device); +EXPORT_SYMBOL(smscore_set_board_id); +EXPORT_SYMBOL(smscore_start_device); +EXPORT_SYMBOL(smscore_unregister_device); +EXPORT_SYMBOL(smscore_getbuffer); +EXPORT_SYMBOL(smscore_get_device_mode); +EXPORT_SYMBOL(smscore_register_client); +EXPORT_SYMBOL(smscore_unregister_hotplug); +EXPORT_SYMBOL(smsclient_sendrequest); +EXPORT_SYMBOL(smscore_unregister_client); +EXPORT_SYMBOL(smscore_get_board_id); +EXPORT_SYMBOL(smscore_register_hotplug); + module_init(smscore_module_init); module_exit(smscore_module_exit); -MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle"); -MODULE_AUTHOR("Siano Mobile Silicon,,, (doronc@siano-ms.com)"); +MODULE_DESCRIPTION("Siano MDTV Core module"); +MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)"); MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index 0469f1bd8..2134a2fb7 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -29,14 +29,14 @@ #include #include #include - +#include #include "compat.h" + #include "dmxdev.h" #include "dvbdev.h" #include "dvb_demux.h" #include "dvb_frontend.h" -#include #define kmutex_init(_p_) mutex_init(_p_) #define kmutex_lock(_p_) mutex_lock(_p_) @@ -551,10 +551,12 @@ extern int smsclient_sendrequest(struct smscore_client_t *client, extern void smscore_onresponse(struct smscore_device_t *coredev, struct smscore_buffer_t *cb); -#if 0 +#if 1 extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev); extern int smscore_map_common_buffer(struct smscore_device_t *coredev, struct vm_area_struct *vma); +extern int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, char* filename); +extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8* ufwbuf,int size); #endif extern @@ -571,13 +573,6 @@ int smscore_get_board_id(struct smscore_device_t *core); int smscore_led_state(struct smscore_device_t *core, int led); -/* smsdvb.c */ -int smsdvb_register(void); -void smsdvb_unregister(void); - -/* smsusb.c */ -int smsusb_register(void); -void smsusb_unregister(void); /* ------------------------------------------------------------------------ */ diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c index 68f3f31bb..c91f6f242 100644 --- a/linux/drivers/media/dvb/siano/smsdvb.c +++ b/linux/drivers/media/dvb/siano/smsdvb.c @@ -1,7 +1,7 @@ /* * Driver for the Siano SMS1xxx USB dongle * - * author: Anatoly Greenblat + * Author: Uri Shkolni * * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. * @@ -371,7 +371,7 @@ static void smsdvb_release(struct dvb_frontend *fe) static struct dvb_frontend_ops smsdvb_fe_ops = { .info = { - .name = "Siano Mobile Digital SMS1xxx", + .name = "Siano Mobile Digital MDTV Receiver", .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, @@ -413,16 +413,10 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, if (!arrival) return 0; - if (smscore_get_device_mode(coredev) != 4) { -#if 1 /* new siano drop (1.2.17) does this -- yuck */ + if (smscore_get_device_mode(coredev) != DEVICE_MODE_DVBT_BDA) { sms_err("SMS Device mode is not set for " "DVB operation."); return 0; -#else - rc = smscore_set_device_mode(coredev, 4); - if (rc < 0) - return rc; -#endif } client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); @@ -521,7 +515,7 @@ adapter_error: return rc; } -int smsdvb_register(void) +int smsdvb_module_init(void) { int rc; @@ -535,7 +529,7 @@ int smsdvb_register(void) return rc; } -void smsdvb_unregister(void) +void smsdvb_module_exit(void) { smscore_unregister_hotplug(smsdvb_hotplug); @@ -547,3 +541,10 @@ void smsdvb_unregister(void) kmutex_unlock(&g_smsdvb_clientslock); } + +module_init(smsdvb_module_init); +module_exit(smsdvb_module_exit); + +MODULE_DESCRIPTION("SMS DVB subsystem adaptation module"); +MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)"); +MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index 19005c26b..eb12b08df 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/drivers/media/dvb/siano/smsusb.c @@ -535,7 +535,7 @@ static struct usb_driver smsusb_driver = { .resume = smsusb_resume, }; -int smsusb_register(void) +int smsusb_module_init(void) { int rc = usb_register(&smsusb_driver); if (rc) @@ -546,10 +546,16 @@ int smsusb_register(void) return rc; } -void smsusb_unregister(void) +void smsusb_module_exit(void) { sms_debug(""); /* Regular USB Cleanup */ usb_deregister(&smsusb_driver); } +module_init(smsusb_module_init); +module_exit(smsusb_module_exit); + +MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle"); +MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 319b736506ba8f695f973876299c72930508f68c Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 31 Aug 2008 15:08:15 -0400 Subject: sms1xxx: fix checkpatch.pl violations introduced by previous changeset From: Michael Krufky Fix checkpatch.pl violations introduced by previous changeset: ERROR: do not use C99 // comments 156: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1373: +//#ifdef DVB_CORE ERROR: do not use C99 // comments 157: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1374: +// smsdvb_unregister(); ERROR: do not use C99 // comments 158: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1375: +//#endif WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 163: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1380: +EXPORT_SYMBOL(smscore_onresponse); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 164: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1381: +EXPORT_SYMBOL(sms_get_board); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 165: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1382: +EXPORT_SYMBOL(sms_debug); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 166: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1383: +EXPORT_SYMBOL(smscore_putbuffer); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 167: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1384: +EXPORT_SYMBOL(smscore_registry_getmode); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 168: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1385: +EXPORT_SYMBOL(smscore_register_device); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 169: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1386: +EXPORT_SYMBOL(smscore_set_board_id); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 170: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1387: +EXPORT_SYMBOL(smscore_start_device); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 171: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1388: +EXPORT_SYMBOL(smsusb_id_table); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 172: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1389: +EXPORT_SYMBOL(smscore_unregister_device); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 173: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1390: +EXPORT_SYMBOL(smscore_getbuffer); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 174: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1391: +EXPORT_SYMBOL(smscore_get_device_mode); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 175: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1392: +EXPORT_SYMBOL(smscore_register_client); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 176: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1393: +EXPORT_SYMBOL(smscore_unregister_hotplug); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 177: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1394: +EXPORT_SYMBOL(smsclient_sendrequest); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 178: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1395: +EXPORT_SYMBOL(smscore_unregister_client); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 179: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1396: +EXPORT_SYMBOL(smscore_get_board_id); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 180: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1397: +EXPORT_SYMBOL(smscore_register_hotplug); WARNING: line over 80 characters 391: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:398: +extern int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, char* filename); ERROR: "foo* bar" should be "foo *bar" 391: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:398: +extern int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, char* filename); WARNING: line over 80 characters 392: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:399: +extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8* ufwbuf,int size); ERROR: "foo* bar" should be "foo *bar" 392: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:399: +extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8* ufwbuf,int size); ERROR: space required after that ',' (ctx:VxV) 392: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:399: +extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8* ufwbuf,int size); ^ WARNING: __func__ should be used instead of gcc specific __FUNCTION__ 489: FILE: linux/drivers/media/dvb/siano/smsusb.c:443: + printk(KERN_INFO"%s Entering status %d.\n", __FUNCTION__, msg.event); WARNING: __func__ should be used instead of gcc specific __FUNCTION__ 501: FILE: linux/drivers/media/dvb/siano/smsusb.c:455: + printk(KERN_INFO "%s Entering.\n", __FUNCTION__); ERROR: space prohibited before that '++' (ctx:WxB) 505: FILE: linux/drivers/media/dvb/siano/smsusb.c:459: + for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i ++) ^ WARNING: __func__ should be used instead of gcc specific __FUNCTION__ 517: FILE: linux/drivers/media/dvb/siano/smsusb.c:471: + __FUNCTION__, rc); Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/siano/sms-cards.c | 5 ++++ linux/drivers/media/dvb/siano/smscoreapi.c | 41 +++++++++++++----------------- linux/drivers/media/dvb/siano/smscoreapi.h | 10 +++++--- linux/drivers/media/dvb/siano/smsdvb.c | 4 +++ linux/drivers/media/dvb/siano/smsusb.c | 13 ++++++---- 5 files changed, 40 insertions(+), 33 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/siano/sms-cards.c b/linux/drivers/media/dvb/siano/sms-cards.c index 39f83faa2..4fa86f5b7 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.c +++ b/linux/drivers/media/dvb/siano/sms-cards.c @@ -86,6 +86,7 @@ struct sms_board *sms_get_board(int id) return &sms_boards[id]; } +EXPORT_SYMBOL(sms_get_board); static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable) { @@ -138,6 +139,7 @@ int sms_board_setup(struct smscore_device_t *coredev) } return 0; } +EXPORT_SYMBOL(sms_board_setup); int sms_board_power(struct smscore_device_t *coredev, int onoff) { @@ -159,6 +161,7 @@ int sms_board_power(struct smscore_device_t *coredev, int onoff) } return 0; } +EXPORT_SYMBOL(sms_board_power); int sms_board_led_feedback(struct smscore_device_t *coredev, int led) { @@ -181,6 +184,7 @@ int sms_board_led_feedback(struct smscore_device_t *coredev, int led) } return 0; } +EXPORT_SYMBOL(sms_board_led_feedback); int sms_board_lna_control(struct smscore_device_t *coredev, int onoff) { @@ -199,3 +203,4 @@ int sms_board_lna_control(struct smscore_device_t *coredev, int onoff) } return -EINVAL; } +EXPORT_SYMBOL(sms_board_lna_control); diff --git a/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c index 5d56f6295..8cb36f540 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.c +++ b/linux/drivers/media/dvb/siano/smscoreapi.c @@ -34,8 +34,8 @@ #include "smscoreapi.h" #include "sms-cards.h" -int sms_debug; -module_param_named(debug, sms_debug, int, 0644); +int sms_dbg; +module_param_named(debug, sms_dbg, int, 0644); MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); struct smscore_device_notifyee_t { @@ -105,11 +105,13 @@ int smscore_led_state(struct smscore_device_t *core, int led) core->led_state = led; return core->led_state; } +EXPORT_SYMBOL(smscore_set_board_id); int smscore_get_board_id(struct smscore_device_t *core) { return core->board_id; } +EXPORT_SYMBOL(smscore_get_board_id); struct smscore_registry_entry_t { struct list_head entry; @@ -170,6 +172,7 @@ int smscore_registry_getmode(char *devpath) return default_mode; } +EXPORT_SYMBOL(smscore_registry_getmode); static enum sms_device_type_st smscore_registry_gettype(char *devpath) { @@ -261,6 +264,7 @@ int smscore_register_hotplug(hotplug_t hotplug) return rc; } +EXPORT_SYMBOL(smscore_register_hotplug); /** * unregister a client callback that called when device plugged in/unplugged @@ -289,6 +293,7 @@ void smscore_unregister_hotplug(hotplug_t hotplug) kmutex_unlock(&g_smscore_deviceslock); } +EXPORT_SYMBOL(smscore_unregister_hotplug); static void smscore_notify_clients(struct smscore_device_t *coredev) { @@ -432,6 +437,7 @@ int smscore_register_device(struct smsdevice_params_t *params, return 0; } +EXPORT_SYMBOL(smscore_register_device); /** * sets initial device mode and notifies client hotplugs that device is ready @@ -460,6 +466,7 @@ int smscore_start_device(struct smscore_device_t *coredev) return rc; } +EXPORT_SYMBOL(smscore_start_device); static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, void *buffer, size_t size, @@ -688,6 +695,7 @@ void smscore_unregister_device(struct smscore_device_t *coredev) sms_info("device %p destroyed", coredev); } +EXPORT_SYMBOL(smscore_unregister_device); static int smscore_detect_mode(struct smscore_device_t *coredev) { @@ -879,6 +887,7 @@ int smscore_get_device_mode(struct smscore_device_t *coredev) { return coredev->mode; } +EXPORT_SYMBOL(smscore_get_device_mode); /** * find client by response id & type within the clients list. @@ -1013,6 +1022,7 @@ void smscore_onresponse(struct smscore_device_t *coredev, smscore_putbuffer(coredev, cb); } } +EXPORT_SYMBOL(smscore_onresponse); /** * return pointer to next free buffer descriptor from core pool @@ -1038,6 +1048,7 @@ struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev) return cb; } +EXPORT_SYMBOL(smscore_getbuffer); /** * return buffer descriptor to a pool @@ -1052,6 +1063,7 @@ void smscore_putbuffer(struct smscore_device_t *coredev, { list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock); } +EXPORT_SYMBOL(smscore_putbuffer); static int smscore_validate_client(struct smscore_device_t *coredev, struct smscore_client_t *client, @@ -1131,6 +1143,7 @@ int smscore_register_client(struct smscore_device_t *coredev, return 0; } +EXPORT_SYMBOL(smscore_register_client); /** * frees smsclient object and all subclients associated with it @@ -1161,6 +1174,7 @@ void smscore_unregister_client(struct smscore_client_t *client) spin_unlock_irqrestore(&coredev->clientslock, flags); } +EXPORT_SYMBOL(smscore_unregister_client); /** * verifies that source id is not taken by another client, @@ -1200,6 +1214,7 @@ int smsclient_sendrequest(struct smscore_client_t *client, return coredev->sendrequest_handler(coredev->context, buffer, size); } +EXPORT_SYMBOL(smsclient_sendrequest); #if 0 /** @@ -1448,31 +1463,9 @@ static void __exit smscore_module_exit(void) } kmutex_unlock(&g_smscore_registrylock); -//#ifdef DVB_CORE -// smsdvb_unregister(); -//#endif - sms_debug(""); } -EXPORT_SYMBOL(smscore_onresponse); -EXPORT_SYMBOL(sms_get_board); -EXPORT_SYMBOL(sms_debug); -EXPORT_SYMBOL(smscore_putbuffer); -EXPORT_SYMBOL(smscore_registry_getmode); -EXPORT_SYMBOL(smscore_register_device); -EXPORT_SYMBOL(smscore_set_board_id); -EXPORT_SYMBOL(smscore_start_device); -EXPORT_SYMBOL(smscore_unregister_device); -EXPORT_SYMBOL(smscore_getbuffer); -EXPORT_SYMBOL(smscore_get_device_mode); -EXPORT_SYMBOL(smscore_register_client); -EXPORT_SYMBOL(smscore_unregister_hotplug); -EXPORT_SYMBOL(smsclient_sendrequest); -EXPORT_SYMBOL(smscore_unregister_client); -EXPORT_SYMBOL(smscore_get_board_id); -EXPORT_SYMBOL(smscore_register_hotplug); - module_init(smscore_module_init); module_exit(smscore_module_exit); diff --git a/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index 2134a2fb7..14dcbdd80 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -555,8 +555,10 @@ extern void smscore_onresponse(struct smscore_device_t *coredev, extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev); extern int smscore_map_common_buffer(struct smscore_device_t *coredev, struct vm_area_struct *vma); -extern int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, char* filename); -extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8* ufwbuf,int size); +extern int smscore_get_fw_filename(struct smscore_device_t *coredev, + int mode, char *filename); +extern int smscore_send_fw_file(struct smscore_device_t *coredev, + u8 *ufwbuf, int size); #endif extern @@ -576,7 +578,7 @@ int smscore_led_state(struct smscore_device_t *core, int led); /* ------------------------------------------------------------------------ */ -extern int sms_debug; +extern int sms_dbg; #define DBG_INFO 1 #define DBG_ADV 2 @@ -585,7 +587,7 @@ extern int sms_debug; printk(kern "%s: " fmt "\n", __func__, ##arg) #define dprintk(kern, lvl, fmt, arg...) do {\ - if (sms_debug & lvl) \ + if (sms_dbg & lvl) \ sms_printk(kern, fmt, ##arg); } while (0) #define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg) diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c index c91f6f242..f7f5569c1 100644 --- a/linux/drivers/media/dvb/siano/smsdvb.c +++ b/linux/drivers/media/dvb/siano/smsdvb.c @@ -50,6 +50,10 @@ struct smsdvb_client_t { static struct list_head g_smsdvb_clients; static struct mutex g_smsdvb_clientslock; +int sms_dbg; +module_param_named(debug, sms_dbg, int, 0644); +MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); + static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) { struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index eb12b08df..e5c378e46 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/drivers/media/dvb/siano/smsusb.c @@ -27,6 +27,10 @@ #include "smscoreapi.h" #include "sms-cards.h" +int sms_dbg; +module_param_named(debug, sms_dbg, int, 0644); +MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); + #define USB1_BUFFER_SIZE 0x1000 #define USB2_BUFFER_SIZE 0x4000 @@ -440,7 +444,7 @@ static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg) { struct smsusb_device_t *dev = (struct smsusb_device_t *)usb_get_intfdata(intf); - printk(KERN_INFO "%s Entering status %d.\n", __func__, msg.event); + printk(KERN_INFO "%s: Entering status %d.\n", __func__, msg.event); smsusb_stop_streaming(dev); return 0; } @@ -452,7 +456,7 @@ static int smsusb_resume(struct usb_interface *intf) (struct smsusb_device_t *)usb_get_intfdata(intf); struct usb_device *udev = interface_to_usbdev(intf); - printk(KERN_INFO "%s Entering.\n", __func__); + printk(KERN_INFO "%s: Entering.\n", __func__); usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81)); usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02)); @@ -467,9 +471,8 @@ static int smsusb_resume(struct usb_interface *intf) intf->cur_altsetting->desc. bInterfaceNumber, 0); if (rc < 0) { - printk(KERN_INFO - "%s usb_set_interface failed, rc %d\n", - __func__, rc); + printk(KERN_INFO "%s usb_set_interface failed, " + "rc %d\n", __func__, rc); return rc; } } -- cgit v1.2.3 From 7d89270edcc221ddc81a48fb810066488b224b25 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 31 Aug 2008 16:39:58 -0400 Subject: sms1xxx: load smsdvb module automatically based on device id From: Michael Krufky The smsdvb module was separated from the core and usb code. This change loads smsdvb automatically for driver configurations that depend on it. Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/siano/sms-cards.c | 17 +++++++++++++++++ linux/drivers/media/dvb/siano/sms-cards.h | 2 ++ linux/drivers/media/dvb/siano/smsusb.c | 1 + 3 files changed, 20 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/dvb/siano/sms-cards.c b/linux/drivers/media/dvb/siano/sms-cards.c index 4fa86f5b7..44df81a81 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.c +++ b/linux/drivers/media/dvb/siano/sms-cards.c @@ -204,3 +204,20 @@ int sms_board_lna_control(struct smscore_device_t *coredev, int onoff) return -EINVAL; } EXPORT_SYMBOL(sms_board_lna_control); + +int sms_board_load_modules(int id) +{ + switch (id) { + case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT: + case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A: + case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B: + case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: + request_module("smsdvb"); + break; + default: + /* do nothing */ + break; + } + return 0; +} +EXPORT_SYMBOL(sms_board_load_modules); diff --git a/linux/drivers/media/dvb/siano/sms-cards.h b/linux/drivers/media/dvb/siano/sms-cards.h index 8f539a2e5..64d74c59c 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.h +++ b/linux/drivers/media/dvb/siano/sms-cards.h @@ -54,4 +54,6 @@ int sms_board_led_feedback(struct smscore_device_t *coredev, int led); int sms_board_power(struct smscore_device_t *coredev, int onoff); int sms_board_lna_control(struct smscore_device_t *coredev, int onoff); +extern int sms_board_load_modules(int id); + #endif /* __SMS_CARDS_H__ */ diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index e5c378e46..a2da36122 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/drivers/media/dvb/siano/smsusb.c @@ -432,6 +432,7 @@ static int smsusb_probe(struct usb_interface *intf, rc = smsusb_init_device(intf, id->driver_info); sms_info("rc %d", rc); + sms_board_load_modules(id->driver_info); return rc; } -- cgit v1.2.3 From e501fc404f4586051d179c0471d73ad264930f26 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 31 Dec 2008 11:27:42 +0100 Subject: gspca - main: Version change. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/gspca.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index 479b4feea..6b66e02e3 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -48,7 +48,7 @@ MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("GSPCA USB Camera Driver"); MODULE_LICENSE("GPL"); -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 4, 0) +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 5, 0) static int video_nr = -1; -- cgit v1.2.3 From b607a50c0b4865aa58898a163630d4fe9f4413ea Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 31 Dec 2008 12:13:46 +0100 Subject: gspca - main and many subdrivers: Remove the epaddr variable. From: Jean-Francois Moine The transfer endpoint address is now automatically chosen. Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/conex.c | 1 - linux/drivers/media/video/gspca/etoms.c | 1 - linux/drivers/media/video/gspca/finepix.c | 6 ++---- linux/drivers/media/video/gspca/gspca.c | 17 ++++------------- linux/drivers/media/video/gspca/gspca.h | 1 - linux/drivers/media/video/gspca/m5602/m5602_core.c | 1 - linux/drivers/media/video/gspca/mars.c | 1 - linux/drivers/media/video/gspca/ov519.c | 1 - linux/drivers/media/video/gspca/ov534.c | 1 - linux/drivers/media/video/gspca/pac207.c | 1 - linux/drivers/media/video/gspca/pac7311.c | 1 - linux/drivers/media/video/gspca/sonixb.c | 1 - linux/drivers/media/video/gspca/sonixj.c | 1 - linux/drivers/media/video/gspca/spca500.c | 1 - linux/drivers/media/video/gspca/spca501.c | 1 - linux/drivers/media/video/gspca/spca505.c | 1 - linux/drivers/media/video/gspca/spca506.c | 1 - linux/drivers/media/video/gspca/spca508.c | 1 - linux/drivers/media/video/gspca/spca561.c | 1 - linux/drivers/media/video/gspca/stk014.c | 4 +--- linux/drivers/media/video/gspca/stv06xx/stv06xx.c | 1 - linux/drivers/media/video/gspca/sunplus.c | 1 - linux/drivers/media/video/gspca/t613.c | 1 - linux/drivers/media/video/gspca/tv8532.c | 1 - linux/drivers/media/video/gspca/vc032x.c | 1 - linux/drivers/media/video/gspca/zc3xx.c | 1 - 26 files changed, 7 insertions(+), 43 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/conex.c b/linux/drivers/media/video/gspca/conex.c index 1753f5bb3..a7088f60b 100644 --- a/linux/drivers/media/video/gspca/conex.c +++ b/linux/drivers/media/video/gspca/conex.c @@ -815,7 +815,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; - cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; diff --git a/linux/drivers/media/video/gspca/etoms.c b/linux/drivers/media/video/gspca/etoms.c index 84b56c303..38a7d3d70 100644 --- a/linux/drivers/media/video/gspca/etoms.c +++ b/linux/drivers/media/video/gspca/etoms.c @@ -658,7 +658,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; - cam->epaddr = 1; sd->sensor = id->driver_info; if (sd->sensor == SENSOR_PAS106) { cam->cam_mode = sif_mode; diff --git a/linux/drivers/media/video/gspca/finepix.c b/linux/drivers/media/video/gspca/finepix.c index afc8b2dd3..76c6e03cb 100644 --- a/linux/drivers/media/video/gspca/finepix.c +++ b/linux/drivers/media/video/gspca/finepix.c @@ -259,7 +259,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = fpix_mode; cam->nmodes = 1; - cam->epaddr = 0x01; /* todo: correct for all cams? */ cam->bulk_size = FPIX_MAX_TRANSFER; /* gspca_dev->nbalt = 1; * use bulk transfer */ @@ -335,8 +334,7 @@ static int sd_start(struct gspca_dev *gspca_dev) /* Read the result of the command. Ignore the result, for it * varies with the device. */ ret = usb_bulk_msg(gspca_dev->dev, - usb_rcvbulkpipe(gspca_dev->dev, - gspca_dev->cam.epaddr), + gspca_dev->urb[0]->pipe, gspca_dev->usb_buf, FPIX_MAX_TRANSFER, &size_ret, FPIX_TIMEOUT); if (ret != 0) { @@ -363,7 +361,7 @@ static int sd_start(struct gspca_dev *gspca_dev) } /* Again, reset bulk in endpoint */ - usb_clear_halt(gspca_dev->dev, gspca_dev->cam.epaddr); + usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe); /* Allocate a control URB */ dev->control_urb = usb_alloc_urb(0, GFP_KERNEL); diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index 6b66e02e3..1a6c61f71 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -447,22 +447,16 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) * look for an input transfer endpoint in an alternate setting */ static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, - __u8 epaddr, __u8 xfer) { struct usb_host_endpoint *ep; int i, attr; - epaddr |= USB_DIR_IN; for (i = 0; i < alt->desc.bNumEndpoints; i++) { ep = &alt->endpoint[i]; - if (ep->desc.bEndpointAddress == epaddr) { - attr = ep->desc.bmAttributes - & USB_ENDPOINT_XFERTYPE_MASK; - if (attr == xfer) - return ep; - break; - } + attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; + if (attr == xfer) + return ep; } return NULL; } @@ -488,7 +482,6 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev) /* try isoc */ while (--i > 0) { /* alt 0 is unusable */ ep = alt_xfer(&intf->altsetting[i], - gspca_dev->cam.epaddr, USB_ENDPOINT_XFER_ISOC); if (ep) break; @@ -497,7 +490,6 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev) /* if no isoc, try bulk */ if (ep == NULL) { ep = alt_xfer(&intf->altsetting[0], - gspca_dev->cam.epaddr, USB_ENDPOINT_XFER_BULK); if (ep == NULL) { err("no transfer endpoint found"); @@ -626,8 +618,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) /* clear the bulk endpoint */ if (gspca_dev->alt == 0) /* if bulk transfer */ usb_clear_halt(gspca_dev->dev, - usb_rcvintpipe(gspca_dev->dev, - gspca_dev->cam.epaddr)); + gspca_dev->urb[0]->pipe); /* start the cam */ ret = gspca_dev->sd_desc->start(gspca_dev); diff --git a/linux/drivers/media/video/gspca/gspca.h b/linux/drivers/media/video/gspca/gspca.h index c90af9cb1..e5c8eb709 100644 --- a/linux/drivers/media/video/gspca/gspca.h +++ b/linux/drivers/media/video/gspca/gspca.h @@ -62,7 +62,6 @@ struct cam { * - cannot be > MAX_NURBS * - when 0 and bulk_size != 0 means * 1 URB and submit done by subdriver */ - __u8 epaddr; }; struct gspca_dev; diff --git a/linux/drivers/media/video/gspca/m5602/m5602_core.c b/linux/drivers/media/video/gspca/m5602/m5602_core.c index ed906fe31..37a47db29 100644 --- a/linux/drivers/media/video/gspca/m5602/m5602_core.c +++ b/linux/drivers/media/video/gspca/m5602/m5602_core.c @@ -332,7 +332,6 @@ static int m5602_configure(struct gspca_dev *gspca_dev, int err; cam = &gspca_dev->cam; - cam->epaddr = M5602_ISOC_ENDPOINT_ADDR; sd->desc = &sd_desc; if (dump_bridge) diff --git a/linux/drivers/media/video/gspca/mars.c b/linux/drivers/media/video/gspca/mars.c index 3d2090e67..ba79afbf8 100644 --- a/linux/drivers/media/video/gspca/mars.c +++ b/linux/drivers/media/video/gspca/mars.c @@ -121,7 +121,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; - cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); sd->qindex = 1; /* set the quantization table */ diff --git a/linux/drivers/media/video/gspca/ov519.c b/linux/drivers/media/video/gspca/ov519.c index 5e31a9145..f9a9f5723 100644 --- a/linux/drivers/media/video/gspca/ov519.c +++ b/linux/drivers/media/video/gspca/ov519.c @@ -1360,7 +1360,6 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam = &gspca_dev->cam; - cam->epaddr = OV511_ENDPOINT_ADDRESS; if (!sd->sif) { cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); diff --git a/linux/drivers/media/video/gspca/ov534.c b/linux/drivers/media/video/gspca/ov534.c index 3bf15e401..01314e999 100644 --- a/linux/drivers/media/video/gspca/ov534.c +++ b/linux/drivers/media/video/gspca/ov534.c @@ -379,7 +379,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam = &gspca_dev->cam; - cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); diff --git a/linux/drivers/media/video/gspca/pac207.c b/linux/drivers/media/video/gspca/pac207.c index c90ac852b..546820f52 100644 --- a/linux/drivers/media/video/gspca/pac207.c +++ b/linux/drivers/media/video/gspca/pac207.c @@ -256,7 +256,6 @@ static int sd_config(struct gspca_dev *gspca_dev, " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); cam = &gspca_dev->cam; - cam->epaddr = 0x05; cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); sd->brightness = PAC207_BRIGHTNESS_DEFAULT; diff --git a/linux/drivers/media/video/gspca/pac7311.c b/linux/drivers/media/video/gspca/pac7311.c index 83ab0df0e..a86cdc6a4 100644 --- a/linux/drivers/media/video/gspca/pac7311.c +++ b/linux/drivers/media/video/gspca/pac7311.c @@ -512,7 +512,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; - cam->epaddr = 0x05; sd->sensor = id->driver_info; if (sd->sensor == SENSOR_PAC7302) { diff --git a/linux/drivers/media/video/gspca/sonixb.c b/linux/drivers/media/video/gspca/sonixb.c index 75b44b362..c5ace7d59 100644 --- a/linux/drivers/media/video/gspca/sonixb.c +++ b/linux/drivers/media/video/gspca/sonixb.c @@ -900,7 +900,6 @@ static int sd_config(struct gspca_dev *gspca_dev, gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis; cam = &gspca_dev->cam; - cam->epaddr = 0x01; if (!(sensor_data[sd->sensor].flags & F_SIF)) { cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 217db0d88..9e2f6b0aa 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -1026,7 +1026,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; - cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); diff --git a/linux/drivers/media/video/gspca/spca500.c b/linux/drivers/media/video/gspca/spca500.c index 6b4865280..9a3e8d9c6 100644 --- a/linux/drivers/media/video/gspca/spca500.c +++ b/linux/drivers/media/video/gspca/spca500.c @@ -646,7 +646,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; - cam->epaddr = 0x01; sd->subtype = id->driver_info; if (sd->subtype != LogitechClickSmart310) { cam->cam_mode = vga_mode; diff --git a/linux/drivers/media/video/gspca/spca501.c b/linux/drivers/media/video/gspca/spca501.c index 609459321..3826cd4dc 100644 --- a/linux/drivers/media/video/gspca/spca501.c +++ b/linux/drivers/media/video/gspca/spca501.c @@ -1982,7 +1982,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; - cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; sd->subtype = id->driver_info; diff --git a/linux/drivers/media/video/gspca/spca505.c b/linux/drivers/media/video/gspca/spca505.c index 854ed1ff5..f0a6109cf 100644 --- a/linux/drivers/media/video/gspca/spca505.c +++ b/linux/drivers/media/video/gspca/spca505.c @@ -705,7 +705,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; - cam->epaddr = 0x01; cam->cam_mode = vga_mode; sd->subtype = id->driver_info; if (sd->subtype != IntelPCCameraPro) diff --git a/linux/drivers/media/video/gspca/spca506.c b/linux/drivers/media/video/gspca/spca506.c index 96e2512e0..99fa3fc1c 100644 --- a/linux/drivers/media/video/gspca/spca506.c +++ b/linux/drivers/media/video/gspca/spca506.c @@ -303,7 +303,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; - cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; diff --git a/linux/drivers/media/video/gspca/spca508.c b/linux/drivers/media/video/gspca/spca508.c index 698d4ed95..b7bf042ab 100644 --- a/linux/drivers/media/video/gspca/spca508.c +++ b/linux/drivers/media/video/gspca/spca508.c @@ -1525,7 +1525,6 @@ static int sd_config(struct gspca_dev *gspca_dev, PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1); cam = &gspca_dev->cam; - cam->epaddr = 0x01; cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); diff --git a/linux/drivers/media/video/gspca/spca561.c b/linux/drivers/media/video/gspca/spca561.c index 499511fa0..c5974fbd5 100644 --- a/linux/drivers/media/video/gspca/spca561.c +++ b/linux/drivers/media/video/gspca/spca561.c @@ -548,7 +548,6 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam = &gspca_dev->cam; - cam->epaddr = 0x01; gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */ sd->chip_revision = id->driver_info; diff --git a/linux/drivers/media/video/gspca/stk014.c b/linux/drivers/media/video/gspca/stk014.c index 60de9af87..cd1fbff0c 100644 --- a/linux/drivers/media/video/gspca/stk014.c +++ b/linux/drivers/media/video/gspca/stk014.c @@ -180,7 +180,7 @@ static int rcv_val(struct gspca_dev *gspca_dev, reg_w(gspca_dev, 0x63b, 0); reg_w(gspca_dev, 0x630, 5); ret = usb_bulk_msg(dev, - usb_rcvbulkpipe(dev, 5), + usb_rcvbulkpipe(dev, 0x05), gspca_dev->usb_buf, 4, /* length */ &alen, @@ -294,9 +294,7 @@ 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 = &gspca_dev->cam; - cam->epaddr = 0x02; gspca_dev->cam.cam_mode = vga_mode; gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); sd->brightness = BRIGHTNESS_DEF; diff --git a/linux/drivers/media/video/gspca/stv06xx/stv06xx.c b/linux/drivers/media/video/gspca/stv06xx/stv06xx.c index 13a021e3c..c60b16333 100644 --- a/linux/drivers/media/video/gspca/stv06xx/stv06xx.c +++ b/linux/drivers/media/video/gspca/stv06xx/stv06xx.c @@ -429,7 +429,6 @@ static int stv06xx_config(struct gspca_dev *gspca_dev, PDEBUG(D_PROBE, "Configuring camera"); cam = &gspca_dev->cam; - cam->epaddr = STV_ISOC_ENDPOINT_ADDR; sd->desc = sd_desc; gspca_dev->sd_desc = &sd->desc; diff --git a/linux/drivers/media/video/gspca/sunplus.c b/linux/drivers/media/video/gspca/sunplus.c index 3692062d0..f86c81435 100644 --- a/linux/drivers/media/video/gspca/sunplus.c +++ b/linux/drivers/media/video/gspca/sunplus.c @@ -843,7 +843,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; - cam->epaddr = 0x01; sd->bridge = id->driver_info >> 8; sd->subtype = id->driver_info; diff --git a/linux/drivers/media/video/gspca/t613.c b/linux/drivers/media/video/gspca/t613.c index 2d032aa0e..6cb6e3ffe 100644 --- a/linux/drivers/media/video/gspca/t613.c +++ b/linux/drivers/media/video/gspca/t613.c @@ -538,7 +538,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; - cam->epaddr = 0x01; cam->cam_mode = vga_mode_t16; cam->nmodes = ARRAY_SIZE(vga_mode_t16); diff --git a/linux/drivers/media/video/gspca/tv8532.c b/linux/drivers/media/video/gspca/tv8532.c index 7d11a0d3e..41292fa68 100644 --- a/linux/drivers/media/video/gspca/tv8532.c +++ b/linux/drivers/media/video/gspca/tv8532.c @@ -241,7 +241,6 @@ static int sd_config(struct gspca_dev *gspca_dev, tv_8532WriteEEprom(gspca_dev); cam = &gspca_dev->cam; - cam->epaddr = 1; cam->cam_mode = sif_mode; cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; diff --git a/linux/drivers/media/video/gspca/vc032x.c b/linux/drivers/media/video/gspca/vc032x.c index 82dc818f4..c5abcd690 100644 --- a/linux/drivers/media/video/gspca/vc032x.c +++ b/linux/drivers/media/video/gspca/vc032x.c @@ -2005,7 +2005,6 @@ static int sd_config(struct gspca_dev *gspca_dev, int sensor; cam = &gspca_dev->cam; - cam->epaddr = 0x02; sd->bridge = id->driver_info; vc0321_reset(gspca_dev); diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index 79d2a776d..9e5859a29 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -7152,7 +7152,6 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam = &gspca_dev->cam; - cam->epaddr = 0x01; /*fixme:test*/ gspca_dev->nbalt--; if (vga) { -- cgit v1.2.3 From 50ddb76ea0fd5b75b96af9efdbb4e54740286732 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 31 Dec 2008 18:33:53 +0100 Subject: gspca - stv06xx: Rework control description. From: Erik Andren Priority: normal Signed-off-by: Erik Andren Signed-off-by: Jean-Francois Moine --- .../media/video/gspca/stv06xx/stv06xx_hdcs.c | 76 +++++++++- .../media/video/gspca/stv06xx/stv06xx_hdcs.h | 65 -------- .../media/video/gspca/stv06xx/stv06xx_pb0100.c | 163 ++++++++++++++++++++- .../media/video/gspca/stv06xx/stv06xx_pb0100.h | 150 ------------------- .../media/video/gspca/stv06xx/stv06xx_sensor.h | 8 - .../media/video/gspca/stv06xx/stv06xx_vv6410.c | 61 +++++++- .../media/video/gspca/stv06xx/stv06xx_vv6410.h | 56 ------- 7 files changed, 280 insertions(+), 299 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/linux/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c index 14335a9e4..b16903814 100644 --- a/linux/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c +++ b/linux/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c @@ -30,6 +30,66 @@ #include "stv06xx_hdcs.h" +static const struct ctrl hdcs1x00_ctrl[] = { + { + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "exposure", + .minimum = 0x00, + .maximum = 0xffff, + .step = 0x1, + .default_value = HDCS_DEFAULT_EXPOSURE, + .flags = V4L2_CTRL_FLAG_SLIDER + }, + .set = hdcs_set_exposure, + .get = hdcs_get_exposure + }, { + { + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "gain", + .minimum = 0x00, + .maximum = 0xff, + .step = 0x1, + .default_value = HDCS_DEFAULT_GAIN, + .flags = V4L2_CTRL_FLAG_SLIDER + }, + .set = hdcs_set_gain, + .get = hdcs_get_gain + } +}; + +static struct v4l2_pix_format hdcs1x00_mode[] = { + { + HDCS_1X00_DEF_WIDTH, + HDCS_1X00_DEF_HEIGHT, + V4L2_PIX_FMT_SBGGR8, + V4L2_FIELD_NONE, + .sizeimage = + HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT, + .bytesperline = HDCS_1X00_DEF_WIDTH, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1 + } +}; + +static const struct ctrl hdcs1020_ctrl[] = {}; + +static struct v4l2_pix_format hdcs1020_mode[] = { + { + HDCS_1020_DEF_WIDTH, + HDCS_1020_DEF_HEIGHT, + V4L2_PIX_FMT_SBGGR8, + V4L2_FIELD_NONE, + .sizeimage = + HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT, + .bytesperline = HDCS_1020_DEF_WIDTH, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1 + } +}; + enum hdcs_power_state { HDCS_STATE_SLEEP, HDCS_STATE_IDLE, @@ -353,10 +413,10 @@ static int hdcs_probe_1x00(struct sd *sd) info("HDCS-1000/1100 sensor detected"); - sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1x00.modes; - sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1x00.nmodes; - sd->desc.ctrls = stv06xx_sensor_hdcs1x00.ctrls; - sd->desc.nctrls = stv06xx_sensor_hdcs1x00.nctrls; + sd->gspca_dev.cam.cam_mode = hdcs1x00_mode; + sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1x00_mode); + sd->desc.ctrls = hdcs1x00_ctrl; + sd->desc.nctrls = ARRAY_SIZE(hdcs1x00_ctrl); hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL); if (!hdcs) @@ -412,10 +472,10 @@ static int hdcs_probe_1020(struct sd *sd) info("HDCS-1020 sensor detected"); - sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1020.modes; - sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1020.nmodes; - sd->desc.ctrls = stv06xx_sensor_hdcs1020.ctrls; - sd->desc.nctrls = stv06xx_sensor_hdcs1020.nctrls; + sd->gspca_dev.cam.cam_mode = hdcs1020_mode; + sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1020_mode); + sd->desc.ctrls = hdcs1020_ctrl; + sd->desc.nctrls = ARRAY_SIZE(hdcs1020_ctrl); hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL); if (!hdcs) diff --git a/linux/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/linux/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h index 9c7279a4c..412f06cf3 100644 --- a/linux/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h +++ b/linux/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h @@ -152,53 +152,6 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1x00 = { .stop = hdcs_stop, .disconnect = hdcs_disconnect, .dump = hdcs_dump, - - .nctrls = 2, - .ctrls = { - { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "exposure", - .minimum = 0x00, - .maximum = 0xffff, - .step = 0x1, - .default_value = HDCS_DEFAULT_EXPOSURE, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = hdcs_set_exposure, - .get = hdcs_get_exposure - }, - { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "gain", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x1, - .default_value = HDCS_DEFAULT_GAIN, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = hdcs_set_gain, - .get = hdcs_get_gain - } - }, - - .nmodes = 1, - .modes = { - { - HDCS_1X00_DEF_WIDTH, - HDCS_1X00_DEF_HEIGHT, - V4L2_PIX_FMT_SBGGR8, - V4L2_FIELD_NONE, - .sizeimage = - HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT, - .bytesperline = HDCS_1X00_DEF_WIDTH, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - } - } }; const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = { @@ -207,29 +160,11 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = { .i2c_addr = (0x55 << 1), .i2c_len = 1, - .nctrls = 0, - .ctrls = {}, - .init = hdcs_init, .probe = hdcs_probe_1020, .start = hdcs_start, .stop = hdcs_stop, .dump = hdcs_dump, - - .nmodes = 1, - .modes = { - { - HDCS_1020_DEF_WIDTH, - HDCS_1020_DEF_HEIGHT, - V4L2_PIX_FMT_SBGGR8, - V4L2_FIELD_NONE, - .sizeimage = - HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT, - .bytesperline = HDCS_1020_DEF_WIDTH, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - } - } }; static const u16 stv_bridge_init[][2] = { diff --git a/linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c index d0a0f8596..7d2c41650 100644 --- a/linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c +++ b/linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c @@ -46,6 +46,154 @@ #include "stv06xx_pb0100.h" +static const struct ctrl pb0100_ctrl[] = { +#define GAIN_IDX 0 + { + { + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gain", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 128 + }, + .set = pb0100_set_gain, + .get = pb0100_get_gain + }, +#define RED_BALANCE_IDX 1 + { + { + .id = V4L2_CID_RED_BALANCE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Red Balance", + .minimum = -255, + .maximum = 255, + .step = 1, + .default_value = 0 + }, + .set = pb0100_set_red_balance, + .get = pb0100_get_red_balance + }, +#define BLUE_BALANCE_IDX 2 + { + { + .id = V4L2_CID_BLUE_BALANCE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Blue Balance", + .minimum = -255, + .maximum = 255, + .step = 1, + .default_value = 0 + }, + .set = pb0100_set_blue_balance, + .get = pb0100_get_blue_balance + }, +#define EXPOSURE_IDX 3 + { + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure", + .minimum = 0, + .maximum = 511, + .step = 1, + .default_value = 12 + }, + .set = pb0100_set_exposure, + .get = pb0100_get_exposure + }, +#define AUTOGAIN_IDX 4 + { + { + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Automatic Gain and Exposure", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1 + }, + .set = pb0100_set_autogain, + .get = pb0100_get_autogain + }, +#define AUTOGAIN_TARGET_IDX 5 + { + { + .id = V4L2_CTRL_CLASS_USER + 0x1000, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Automatic Gain Target", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 128 + }, + .set = pb0100_set_autogain_target, + .get = pb0100_get_autogain_target + }, +#define NATURAL_IDX 6 + { + { + .id = V4L2_CTRL_CLASS_USER + 0x1001, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Natural Light Source", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1 + }, + .set = pb0100_set_natural, + .get = pb0100_get_natural + } +}; + +static struct v4l2_pix_format pb0100_mode[] = { +/* low res / subsample modes disabled as they are only half res horizontal, + halving the vertical resolution does not seem to work */ +#if 0 + { + 160, + 120, + V4L2_PIX_FMT_SGRBG8, + V4L2_FIELD_NONE, + .sizeimage = 160 * 120 * 2, + .bytesperline = 160, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = PB0100_CROP_TO_VGA | PB0100_SUBSAMPLE + }, + { + 176, + 144, + V4L2_PIX_FMT_SGRBG8, + V4L2_FIELD_NONE, + .sizeimage = 176 * 144 * 2, + .bytesperline = 176, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = PB0100_SUBSAMPLE + }, +#endif + { + 320, + 240, + V4L2_PIX_FMT_SGRBG8, + V4L2_FIELD_NONE, + .sizeimage = 320 * 240, + .bytesperline = 320, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = PB0100_CROP_TO_VGA + }, + { + 352, + 288, + V4L2_PIX_FMT_SGRBG8, + V4L2_FIELD_NONE, + .sizeimage = 352 * 288, + .bytesperline = 352, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0 + } +}; + static int pb0100_probe(struct sd *sd) { u16 sensor; @@ -59,20 +207,19 @@ static int pb0100_probe(struct sd *sd) if ((sensor >> 8) == 0x64) { sensor_settings = kmalloc( - stv06xx_sensor_pb0100.nctrls * sizeof(s32), + ARRAY_SIZE(pb0100_ctrl) * sizeof(s32), GFP_KERNEL); if (!sensor_settings) return -ENOMEM; info("Photobit pb0100 sensor detected"); - sd->gspca_dev.cam.cam_mode = stv06xx_sensor_pb0100.modes; - sd->gspca_dev.cam.nmodes = stv06xx_sensor_pb0100.nmodes; - sd->desc.ctrls = stv06xx_sensor_pb0100.ctrls; - sd->desc.nctrls = stv06xx_sensor_pb0100.nctrls; - for (i = 0; i < stv06xx_sensor_pb0100.nctrls; i++) - sensor_settings[i] = stv06xx_sensor_pb0100. - ctrls[i].qctrl.default_value; + sd->gspca_dev.cam.cam_mode = pb0100_mode; + sd->gspca_dev.cam.nmodes = ARRAY_SIZE(pb0100_mode); + sd->desc.ctrls = pb0100_ctrl; + sd->desc.nctrls = ARRAY_SIZE(pb0100_ctrl); + for (i = 0; i < sd->desc.nctrls; i++) + sensor_settings[i] = pb0100_ctrl[i].qctrl.default_value; sd->sensor_priv = sensor_settings; return 0; diff --git a/linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h b/linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h index 4b47270aa..da7c13ed8 100644 --- a/linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h +++ b/linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h @@ -137,161 +137,11 @@ const struct stv06xx_sensor stv06xx_sensor_pb0100 = { .i2c_addr = 0xba, .i2c_len = 2, - .nctrls = 7, - .ctrls = { -#define GAIN_IDX 0 - { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gain", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 128 - }, - .set = pb0100_set_gain, - .get = pb0100_get_gain - }, -#define RED_BALANCE_IDX 1 - { - { - .id = V4L2_CID_RED_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Red Balance", - .minimum = -255, - .maximum = 255, - .step = 1, - .default_value = 0 - }, - .set = pb0100_set_red_balance, - .get = pb0100_get_red_balance - }, -#define BLUE_BALANCE_IDX 2 - { - { - .id = V4L2_CID_BLUE_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Blue Balance", - .minimum = -255, - .maximum = 255, - .step = 1, - .default_value = 0 - }, - .set = pb0100_set_blue_balance, - .get = pb0100_get_blue_balance - }, -#define EXPOSURE_IDX 3 - { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure", - .minimum = 0, - .maximum = 511, - .step = 1, - .default_value = 12 - }, - .set = pb0100_set_exposure, - .get = pb0100_get_exposure - }, -#define AUTOGAIN_IDX 4 - { - { - .id = V4L2_CID_AUTOGAIN, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Automatic Gain and Exposure", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1 - }, - .set = pb0100_set_autogain, - .get = pb0100_get_autogain - }, -#define AUTOGAIN_TARGET_IDX 5 - { - { - .id = V4L2_CTRL_CLASS_USER + 0x1000, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Automatic Gain Target", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 128 - }, - .set = pb0100_set_autogain_target, - .get = pb0100_get_autogain_target - }, -#define NATURAL_IDX 6 - { - { - .id = V4L2_CTRL_CLASS_USER + 0x1001, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Natural Light Source", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1 - }, - .set = pb0100_set_natural, - .get = pb0100_get_natural - }, - }, - .init = pb0100_init, .probe = pb0100_probe, .start = pb0100_start, .stop = pb0100_stop, .dump = pb0100_dump, - - .nmodes = 2, - .modes = { -/* low res / subsample modes disabled as they are only half res horizontal, - halving the vertical resolution does not seem to work */ -#if 0 - { - 160, - 120, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = 160 * 120 * 2, - .bytesperline = 160, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = PB0100_CROP_TO_VGA | PB0100_SUBSAMPLE - }, - { - 176, - 144, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = 176 * 144 * 2, - .bytesperline = 176, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = PB0100_SUBSAMPLE - }, -#endif - { - 320, - 240, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = 320 * 240, - .bytesperline = 320, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = PB0100_CROP_TO_VGA - }, - { - 352, - 288, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = 352 * 288, - .bytesperline = 352, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - }, - } }; #endif diff --git a/linux/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h b/linux/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h index c726dacef..e88c42f7d 100644 --- a/linux/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h +++ b/linux/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h @@ -41,8 +41,6 @@ extern const struct stv06xx_sensor stv06xx_sensor_hdcs1x00; extern const struct stv06xx_sensor stv06xx_sensor_hdcs1020; extern const struct stv06xx_sensor stv06xx_sensor_pb0100; -#define STV06XX_MAX_CTRLS (V4L2_CID_LASTP1 - V4L2_CID_BASE + 10) - struct stv06xx_sensor { /* Defines the name of a sensor */ char name[32]; @@ -81,12 +79,6 @@ struct stv06xx_sensor { /* Instructs the sensor to dump all its contents */ int (*dump)(struct sd *sd); - - int nctrls; - struct ctrl ctrls[STV06XX_MAX_CTRLS]; - - char nmodes; - struct v4l2_pix_format modes[]; }; #endif diff --git a/linux/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/linux/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c index 1ca91f2a6..a204b5891 100644 --- a/linux/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c +++ b/linux/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c @@ -29,6 +29,59 @@ #include "stv06xx_vv6410.h" +static struct v4l2_pix_format vv6410_mode[] = { + { + 356, + 292, + V4L2_PIX_FMT_SGRBG8, + V4L2_FIELD_NONE, + .sizeimage = 356 * 292, + .bytesperline = 356, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0 + } +}; + +static const struct ctrl vv6410_ctrl[] = { + { + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "horizontal flip", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0 + }, + .set = vv6410_set_hflip, + .get = vv6410_get_hflip + }, { + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "vertical flip", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0 + }, + .set = vv6410_set_vflip, + .get = vv6410_get_vflip + }, { + { + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "analog gain", + .minimum = 0, + .maximum = 15, + .step = 1, + .default_value = 0 + }, + .set = vv6410_set_analog_gain, + .get = vv6410_get_analog_gain + } +}; + static int vv6410_probe(struct sd *sd) { u16 data; @@ -42,10 +95,10 @@ static int vv6410_probe(struct sd *sd) if (data == 0x19) { info("vv6410 sensor detected"); - sd->gspca_dev.cam.cam_mode = stv06xx_sensor_vv6410.modes; - sd->gspca_dev.cam.nmodes = stv06xx_sensor_vv6410.nmodes; - sd->desc.ctrls = stv06xx_sensor_vv6410.ctrls; - sd->desc.nctrls = stv06xx_sensor_vv6410.nctrls; + sd->gspca_dev.cam.cam_mode = vv6410_mode; + sd->gspca_dev.cam.nmodes = ARRAY_SIZE(vv6410_mode); + sd->desc.ctrls = vv6410_ctrl; + sd->desc.nctrls = ARRAY_SIZE(vv6410_ctrl); return 0; } diff --git a/linux/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/linux/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h index 3ff8c4ea3..1cb5f5765 100644 --- a/linux/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h +++ b/linux/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h @@ -197,62 +197,6 @@ const struct stv06xx_sensor stv06xx_sensor_vv6410 = { .start = vv6410_start, .stop = vv6410_stop, .dump = vv6410_dump, - - .nctrls = 3, - .ctrls = { - { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "horizontal flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = vv6410_set_hflip, - .get = vv6410_get_hflip - }, { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = vv6410_set_vflip, - .get = vv6410_get_vflip - }, { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "analog gain", - .minimum = 0, - .maximum = 15, - .step = 1, - .default_value = 0 - }, - .set = vv6410_set_analog_gain, - .get = vv6410_get_analog_gain - } - }, - - .nmodes = 1, - .modes = { - { - 356, - 292, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = - 356 * 292, - .bytesperline = 356, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - } - } }; /* If NULL, only single value to write, stored in len */ -- cgit v1.2.3 From 9afdb51d6cd6f5d7d5ad2841fbd24db72f8e0a41 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 1 Jan 2009 17:02:07 +0100 Subject: gspca - all subdrivers: Fix CodingStyle in sd_mod_init function. From: Alexey Klimov Introduce int ret and check it value after call to usb_register(). Priority: normal Signed-off-by: Alexey Klimov Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/conex.c | 4 +++- linux/drivers/media/video/gspca/etoms.c | 4 +++- linux/drivers/media/video/gspca/finepix.c | 4 +++- linux/drivers/media/video/gspca/m5602/m5602_core.c | 4 +++- linux/drivers/media/video/gspca/mars.c | 4 +++- linux/drivers/media/video/gspca/ov519.c | 4 +++- linux/drivers/media/video/gspca/ov534.c | 4 +++- linux/drivers/media/video/gspca/pac207.c | 4 +++- linux/drivers/media/video/gspca/pac7311.c | 4 +++- linux/drivers/media/video/gspca/sonixb.c | 4 +++- linux/drivers/media/video/gspca/sonixj.c | 4 +++- linux/drivers/media/video/gspca/spca500.c | 4 +++- linux/drivers/media/video/gspca/spca501.c | 4 +++- linux/drivers/media/video/gspca/spca505.c | 4 +++- linux/drivers/media/video/gspca/spca506.c | 4 +++- linux/drivers/media/video/gspca/spca508.c | 4 +++- linux/drivers/media/video/gspca/spca561.c | 4 +++- linux/drivers/media/video/gspca/stk014.c | 4 +++- linux/drivers/media/video/gspca/stv06xx/stv06xx.c | 4 +++- linux/drivers/media/video/gspca/sunplus.c | 4 +++- linux/drivers/media/video/gspca/t613.c | 4 +++- linux/drivers/media/video/gspca/tv8532.c | 4 +++- linux/drivers/media/video/gspca/vc032x.c | 4 +++- linux/drivers/media/video/gspca/zc3xx.c | 4 +++- 24 files changed, 72 insertions(+), 24 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/conex.c b/linux/drivers/media/video/gspca/conex.c index a7088f60b..825342be4 100644 --- a/linux/drivers/media/video/gspca/conex.c +++ b/linux/drivers/media/video/gspca/conex.c @@ -1028,7 +1028,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/etoms.c b/linux/drivers/media/video/gspca/etoms.c index 38a7d3d70..c9457f642 100644 --- a/linux/drivers/media/video/gspca/etoms.c +++ b/linux/drivers/media/video/gspca/etoms.c @@ -933,7 +933,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/finepix.c b/linux/drivers/media/video/gspca/finepix.c index 76c6e03cb..96a5ca775 100644 --- a/linux/drivers/media/video/gspca/finepix.c +++ b/linux/drivers/media/video/gspca/finepix.c @@ -454,7 +454,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/m5602/m5602_core.c b/linux/drivers/media/video/gspca/m5602/m5602_core.c index 37a47db29..e78914d7a 100644 --- a/linux/drivers/media/video/gspca/m5602/m5602_core.c +++ b/linux/drivers/media/video/gspca/m5602/m5602_core.c @@ -373,7 +373,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init mod_m5602_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/mars.c b/linux/drivers/media/video/gspca/mars.c index ba79afbf8..420224afa 100644 --- a/linux/drivers/media/video/gspca/mars.c +++ b/linux/drivers/media/video/gspca/mars.c @@ -420,7 +420,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/ov519.c b/linux/drivers/media/video/gspca/ov519.c index f9a9f5723..76438efb7 100644 --- a/linux/drivers/media/video/gspca/ov519.c +++ b/linux/drivers/media/video/gspca/ov519.c @@ -2201,7 +2201,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/ov534.c b/linux/drivers/media/video/gspca/ov534.c index 01314e999..e20ec7df3 100644 --- a/linux/drivers/media/video/gspca/ov534.c +++ b/linux/drivers/media/video/gspca/ov534.c @@ -584,7 +584,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/pac207.c b/linux/drivers/media/video/gspca/pac207.c index 546820f52..10331728f 100644 --- a/linux/drivers/media/video/gspca/pac207.c +++ b/linux/drivers/media/video/gspca/pac207.c @@ -564,7 +564,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/pac7311.c b/linux/drivers/media/video/gspca/pac7311.c index a86cdc6a4..aee8c27e5 100644 --- a/linux/drivers/media/video/gspca/pac7311.c +++ b/linux/drivers/media/video/gspca/pac7311.c @@ -1110,7 +1110,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/sonixb.c b/linux/drivers/media/video/gspca/sonixb.c index c5ace7d59..95a606f1c 100644 --- a/linux/drivers/media/video/gspca/sonixb.c +++ b/linux/drivers/media/video/gspca/sonixb.c @@ -1301,7 +1301,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 9e2f6b0aa..b4a410c35 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -1809,7 +1809,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; info("registered"); return 0; diff --git a/linux/drivers/media/video/gspca/spca500.c b/linux/drivers/media/video/gspca/spca500.c index 9a3e8d9c6..e107775d7 100644 --- a/linux/drivers/media/video/gspca/spca500.c +++ b/linux/drivers/media/video/gspca/spca500.c @@ -1109,7 +1109,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/spca501.c b/linux/drivers/media/video/gspca/spca501.c index 3826cd4dc..eb24e8425 100644 --- a/linux/drivers/media/video/gspca/spca501.c +++ b/linux/drivers/media/video/gspca/spca501.c @@ -2258,7 +2258,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/spca505.c b/linux/drivers/media/video/gspca/spca505.c index f0a6109cf..d87de1141 100644 --- a/linux/drivers/media/video/gspca/spca505.c +++ b/linux/drivers/media/video/gspca/spca505.c @@ -931,7 +931,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/spca506.c b/linux/drivers/media/video/gspca/spca506.c index 99fa3fc1c..aa3ecc8ac 100644 --- a/linux/drivers/media/video/gspca/spca506.c +++ b/linux/drivers/media/video/gspca/spca506.c @@ -771,7 +771,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/spca508.c b/linux/drivers/media/video/gspca/spca508.c index b7bf042ab..8670b8be4 100644 --- a/linux/drivers/media/video/gspca/spca508.c +++ b/linux/drivers/media/video/gspca/spca508.c @@ -1703,7 +1703,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/spca561.c b/linux/drivers/media/video/gspca/spca561.c index c5974fbd5..501b7d5b4 100644 --- a/linux/drivers/media/video/gspca/spca561.c +++ b/linux/drivers/media/video/gspca/spca561.c @@ -1203,7 +1203,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/stk014.c b/linux/drivers/media/video/gspca/stk014.c index cd1fbff0c..8743c03ed 100644 --- a/linux/drivers/media/video/gspca/stk014.c +++ b/linux/drivers/media/video/gspca/stk014.c @@ -560,7 +560,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; info("registered"); return 0; diff --git a/linux/drivers/media/video/gspca/stv06xx/stv06xx.c b/linux/drivers/media/video/gspca/stv06xx/stv06xx.c index c60b16333..c43534db7 100644 --- a/linux/drivers/media/video/gspca/stv06xx/stv06xx.c +++ b/linux/drivers/media/video/gspca/stv06xx/stv06xx.c @@ -500,7 +500,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/sunplus.c b/linux/drivers/media/video/gspca/sunplus.c index f86c81435..8b725532d 100644 --- a/linux/drivers/media/video/gspca/sunplus.c +++ b/linux/drivers/media/video/gspca/sunplus.c @@ -1495,7 +1495,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/t613.c b/linux/drivers/media/video/gspca/t613.c index 6cb6e3ffe..cf07ef91b 100644 --- a/linux/drivers/media/video/gspca/t613.c +++ b/linux/drivers/media/video/gspca/t613.c @@ -1175,7 +1175,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/tv8532.c b/linux/drivers/media/video/gspca/tv8532.c index 41292fa68..65e61e1b8 100644 --- a/linux/drivers/media/video/gspca/tv8532.c +++ b/linux/drivers/media/video/gspca/tv8532.c @@ -578,7 +578,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/vc032x.c b/linux/drivers/media/video/gspca/vc032x.c index c5abcd690..63953db7e 100644 --- a/linux/drivers/media/video/gspca/vc032x.c +++ b/linux/drivers/media/video/gspca/vc032x.c @@ -2485,7 +2485,9 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index 9e5859a29..483d866c6 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -7608,7 +7608,9 @@ static struct usb_driver sd_driver = { static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0; -- cgit v1.2.3 From 8295b6940120a069aa0078103ba943997fad6fd1 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 1 Jan 2009 17:04:58 +0100 Subject: gspca - all subdrivers: Return ret instead of -1 in sd_mod_init. From: Alexey Klimov Priority: normal Signed-off-by: Alexey Klimov Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/conex.c | 2 +- linux/drivers/media/video/gspca/etoms.c | 2 +- linux/drivers/media/video/gspca/finepix.c | 2 +- linux/drivers/media/video/gspca/m5602/m5602_core.c | 2 +- linux/drivers/media/video/gspca/mars.c | 2 +- linux/drivers/media/video/gspca/ov519.c | 2 +- linux/drivers/media/video/gspca/ov534.c | 2 +- linux/drivers/media/video/gspca/pac207.c | 2 +- linux/drivers/media/video/gspca/pac7311.c | 2 +- linux/drivers/media/video/gspca/sonixb.c | 2 +- linux/drivers/media/video/gspca/sonixj.c | 2 +- linux/drivers/media/video/gspca/spca500.c | 2 +- linux/drivers/media/video/gspca/spca501.c | 2 +- linux/drivers/media/video/gspca/spca505.c | 2 +- linux/drivers/media/video/gspca/spca506.c | 2 +- linux/drivers/media/video/gspca/spca508.c | 2 +- linux/drivers/media/video/gspca/spca561.c | 2 +- linux/drivers/media/video/gspca/stk014.c | 2 +- linux/drivers/media/video/gspca/stv06xx/stv06xx.c | 2 +- linux/drivers/media/video/gspca/sunplus.c | 2 +- linux/drivers/media/video/gspca/t613.c | 2 +- linux/drivers/media/video/gspca/tv8532.c | 2 +- linux/drivers/media/video/gspca/vc032x.c | 2 +- linux/drivers/media/video/gspca/zc3xx.c | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/conex.c b/linux/drivers/media/video/gspca/conex.c index 825342be4..2de8906e5 100644 --- a/linux/drivers/media/video/gspca/conex.c +++ b/linux/drivers/media/video/gspca/conex.c @@ -1031,7 +1031,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/etoms.c b/linux/drivers/media/video/gspca/etoms.c index c9457f642..7e69d7bed 100644 --- a/linux/drivers/media/video/gspca/etoms.c +++ b/linux/drivers/media/video/gspca/etoms.c @@ -936,7 +936,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/finepix.c b/linux/drivers/media/video/gspca/finepix.c index 96a5ca775..dc65c363a 100644 --- a/linux/drivers/media/video/gspca/finepix.c +++ b/linux/drivers/media/video/gspca/finepix.c @@ -457,7 +457,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/m5602/m5602_core.c b/linux/drivers/media/video/gspca/m5602/m5602_core.c index e78914d7a..b35e4838a 100644 --- a/linux/drivers/media/video/gspca/m5602/m5602_core.c +++ b/linux/drivers/media/video/gspca/m5602/m5602_core.c @@ -376,7 +376,7 @@ static int __init mod_m5602_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/mars.c b/linux/drivers/media/video/gspca/mars.c index 420224afa..477441e22 100644 --- a/linux/drivers/media/video/gspca/mars.c +++ b/linux/drivers/media/video/gspca/mars.c @@ -423,7 +423,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/ov519.c b/linux/drivers/media/video/gspca/ov519.c index 76438efb7..bd70e9adb 100644 --- a/linux/drivers/media/video/gspca/ov519.c +++ b/linux/drivers/media/video/gspca/ov519.c @@ -2204,7 +2204,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/ov534.c b/linux/drivers/media/video/gspca/ov534.c index e20ec7df3..55d920caa 100644 --- a/linux/drivers/media/video/gspca/ov534.c +++ b/linux/drivers/media/video/gspca/ov534.c @@ -587,7 +587,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/pac207.c b/linux/drivers/media/video/gspca/pac207.c index 10331728f..93616cebf 100644 --- a/linux/drivers/media/video/gspca/pac207.c +++ b/linux/drivers/media/video/gspca/pac207.c @@ -567,7 +567,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/pac7311.c b/linux/drivers/media/video/gspca/pac7311.c index aee8c27e5..6a857805a 100644 --- a/linux/drivers/media/video/gspca/pac7311.c +++ b/linux/drivers/media/video/gspca/pac7311.c @@ -1113,7 +1113,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/sonixb.c b/linux/drivers/media/video/gspca/sonixb.c index 95a606f1c..edb2bfa85 100644 --- a/linux/drivers/media/video/gspca/sonixb.c +++ b/linux/drivers/media/video/gspca/sonixb.c @@ -1304,7 +1304,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index b4a410c35..f977dd22e 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -1812,7 +1812,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; info("registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/spca500.c b/linux/drivers/media/video/gspca/spca500.c index e107775d7..8054c5f62 100644 --- a/linux/drivers/media/video/gspca/spca500.c +++ b/linux/drivers/media/video/gspca/spca500.c @@ -1112,7 +1112,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/spca501.c b/linux/drivers/media/video/gspca/spca501.c index eb24e8425..1caf45ae4 100644 --- a/linux/drivers/media/video/gspca/spca501.c +++ b/linux/drivers/media/video/gspca/spca501.c @@ -2261,7 +2261,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/spca505.c b/linux/drivers/media/video/gspca/spca505.c index d87de1141..c7a23f237 100644 --- a/linux/drivers/media/video/gspca/spca505.c +++ b/linux/drivers/media/video/gspca/spca505.c @@ -934,7 +934,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/spca506.c b/linux/drivers/media/video/gspca/spca506.c index aa3ecc8ac..8cedb0097 100644 --- a/linux/drivers/media/video/gspca/spca506.c +++ b/linux/drivers/media/video/gspca/spca506.c @@ -774,7 +774,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/spca508.c b/linux/drivers/media/video/gspca/spca508.c index 8670b8be4..0109ab132 100644 --- a/linux/drivers/media/video/gspca/spca508.c +++ b/linux/drivers/media/video/gspca/spca508.c @@ -1706,7 +1706,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/spca561.c b/linux/drivers/media/video/gspca/spca561.c index 501b7d5b4..b991ddde5 100644 --- a/linux/drivers/media/video/gspca/spca561.c +++ b/linux/drivers/media/video/gspca/spca561.c @@ -1206,7 +1206,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/stk014.c b/linux/drivers/media/video/gspca/stk014.c index 8743c03ed..ba31eb318 100644 --- a/linux/drivers/media/video/gspca/stk014.c +++ b/linux/drivers/media/video/gspca/stk014.c @@ -563,7 +563,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; info("registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/stv06xx/stv06xx.c b/linux/drivers/media/video/gspca/stv06xx/stv06xx.c index c43534db7..9dff2e65b 100644 --- a/linux/drivers/media/video/gspca/stv06xx/stv06xx.c +++ b/linux/drivers/media/video/gspca/stv06xx/stv06xx.c @@ -503,7 +503,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/sunplus.c b/linux/drivers/media/video/gspca/sunplus.c index 8b725532d..6c46743b7 100644 --- a/linux/drivers/media/video/gspca/sunplus.c +++ b/linux/drivers/media/video/gspca/sunplus.c @@ -1498,7 +1498,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/t613.c b/linux/drivers/media/video/gspca/t613.c index cf07ef91b..af704242a 100644 --- a/linux/drivers/media/video/gspca/t613.c +++ b/linux/drivers/media/video/gspca/t613.c @@ -1178,7 +1178,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/tv8532.c b/linux/drivers/media/video/gspca/tv8532.c index 65e61e1b8..4ee13d3d8 100644 --- a/linux/drivers/media/video/gspca/tv8532.c +++ b/linux/drivers/media/video/gspca/tv8532.c @@ -581,7 +581,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/vc032x.c b/linux/drivers/media/video/gspca/vc032x.c index 63953db7e..a615cc402 100644 --- a/linux/drivers/media/video/gspca/vc032x.c +++ b/linux/drivers/media/video/gspca/vc032x.c @@ -2488,7 +2488,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index 483d866c6..c044cd495 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -7611,7 +7611,7 @@ static int __init sd_mod_init(void) int ret; ret = usb_register(&sd_driver); if (ret < 0) - return -1; + return ret; PDEBUG(D_PROBE, "registered"); return 0; } -- cgit v1.2.3 From 3bdb904852c74d8c0d7c55a17fb9ed559ae1e855 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 1 Jan 2009 17:20:42 +0100 Subject: gspca - common: Simplify the debug macros. From: Jean-Francois Moine The err, warning and info redefinitions don't need the use of do {} while. Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/gspca.h | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/gspca.h b/linux/drivers/media/video/gspca/gspca.h index e5c8eb709..6f172e9e5 100644 --- a/linux/drivers/media/video/gspca/gspca.h +++ b/linux/drivers/media/video/gspca/gspca.h @@ -33,19 +33,13 @@ extern int gspca_debug; #endif #undef err #define err(fmt, args...) \ - do {\ - printk(KERN_ERR MODULE_NAME ": " fmt "\n", ## args); \ - } while (0) + printk(KERN_ERR MODULE_NAME ": " fmt "\n", ## args) #undef info #define info(fmt, args...) \ - do {\ - printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args); \ - } while (0) + printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args) #undef warn #define warn(fmt, args...) \ - do {\ - printk(KERN_WARNING MODULE_NAME ": " fmt "\n", ## args); \ - } while (0) + printk(KERN_WARNING MODULE_NAME ": " fmt "\n", ## args) #define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ /* image transfers */ -- cgit v1.2.3 From b590fcfdc57bf6463013c041449c69751049fda5 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 29 Jan 2009 22:24:01 -0500 Subject: dib0700: add data debug to dib0700_i2c_xfer_new From: Michael Krufky Data debug for i2c transactions was provided by the functions called by dib0700_i2c_xfer_legacy, but not dib0700_i2c_xfer_new. This patch adds the missing data debug dumps to dib0700_i2c_xfer_new. Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/dib0700_core.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_core.c b/linux/drivers/media/dvb/dvb-usb/dib0700_core.c index 46c425643..ef5c89c82 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -158,6 +158,10 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg, err("i2c read error (status = %d)\n", result); break; } + + deb_data("<<< "); + debug_dump(msg[i].buf, msg[i].len, deb_data); + } else { /* Write request */ buf[0] = REQUEST_NEW_I2C_WRITE; @@ -169,6 +173,9 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg, /* The Actual i2c payload */ memcpy(&buf[4], msg[i].buf, msg[i].len); + deb_data(">>> "); + debug_dump(buf, msg[i].len + 4, deb_data); + result = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0), REQUEST_NEW_I2C_WRITE, -- cgit v1.2.3 From 564916a52c7355ed4408de16431f67d66461363f Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 6 Jan 2009 12:10:59 -0500 Subject: tveeprom: update to include Hauppauge tuners 151-155 From: Michael Krufky Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/video/tveeprom.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/tveeprom.c b/linux/drivers/media/video/tveeprom.c index de93ac3b5..acd601a52 100644 --- a/linux/drivers/media/video/tveeprom.c +++ b/linux/drivers/media/video/tveeprom.c @@ -263,6 +263,11 @@ hauppauge_tuner[] = { TUNER_PHILIPS_TDA8290, "Philips 18271_8295"}, /* 150-159 */ { TUNER_ABSENT, "Xceive XC5000"}, + { TUNER_ABSENT, "Xceive XC3028L"}, + { TUNER_ABSENT, "NXP 18271C2_716x"}, + { TUNER_ABSENT, "Xceive XC4000"}, + { TUNER_ABSENT, "Dibcom 7070"}, + { TUNER_PHILIPS_TDA8290, "NXP 18271C2"}, }; /* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are -- cgit v1.2.3 From 96bc6ac47653539f76499de79dddf3695a1abe3f Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 7 Jan 2009 10:01:01 +0100 Subject: gspca - main: Remove #include version.h. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/gspca.c | 1 - 1 file changed, 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index 1a6c61f71..a68b1a969 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -21,7 +21,6 @@ #define MODULE_NAME "gspca" #include -#include #include #include #include -- cgit v1.2.3 From 4dc396f356b2837f3295f459f2a5fb40bd178bb9 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 7 Jan 2009 10:09:27 +0100 Subject: gspca - stv06xx: Plug a memory leak in the pb0100 sensor driver. From: Erik Andren Priority: normal Signed-off-by: Erik Andren Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c | 6 ++++++ linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h | 2 ++ 2 files changed, 8 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c index 7d2c41650..180f52c36 100644 --- a/linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c +++ b/linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c @@ -290,6 +290,12 @@ out: return (err < 0) ? err : 0; } +static void pb0100_disconnect(struct sd *sd) +{ + sd->sensor = NULL; + kfree(sd->sensor_priv); +} + /* FIXME: Sort the init commands out and put them into tables, this is only for getting the camera to work */ /* FIXME: No error handling for now, diff --git a/linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h b/linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h index da7c13ed8..4de4fa5eb 100644 --- a/linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h +++ b/linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h @@ -114,6 +114,7 @@ static int pb0100_start(struct sd *sd); static int pb0100_init(struct sd *sd); static int pb0100_stop(struct sd *sd); static int pb0100_dump(struct sd *sd); +static void pb0100_disconnect(struct sd *sd); /* V4L2 controls supported by the driver */ static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val); @@ -142,6 +143,7 @@ const struct stv06xx_sensor stv06xx_sensor_pb0100 = { .start = pb0100_start, .stop = pb0100_stop, .dump = pb0100_dump, + .disconnect = pb0100_disconnect, }; #endif -- cgit v1.2.3 From 721419f06f4c6afd216f35c556233b9e66fb98f8 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 7 Jan 2009 10:11:50 +0100 Subject: gspca - stv06xx: Add ctrl caching to the vv6410. From: Erik Andren Priority: normal Signed-off-by: Erik Andren Signed-off-by: Jean-Francois Moine --- .../media/video/gspca/stv06xx/stv06xx_vv6410.c | 66 ++++++++++++++-------- .../media/video/gspca/stv06xx/stv06xx_vv6410.h | 2 + 2 files changed, 43 insertions(+), 25 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/linux/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c index a204b5891..69c77c932 100644 --- a/linux/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c +++ b/linux/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c @@ -43,6 +43,7 @@ static struct v4l2_pix_format vv6410_mode[] = { }; static const struct ctrl vv6410_ctrl[] = { +#define HFLIP_IDX 0 { { .id = V4L2_CID_HFLIP, @@ -55,7 +56,9 @@ static const struct ctrl vv6410_ctrl[] = { }, .set = vv6410_set_hflip, .get = vv6410_get_hflip - }, { + }, +#define VFLIP_IDX 1 + { { .id = V4L2_CID_VFLIP, .type = V4L2_CTRL_TYPE_BOOLEAN, @@ -67,7 +70,9 @@ static const struct ctrl vv6410_ctrl[] = { }, .set = vv6410_set_vflip, .get = vv6410_get_vflip - }, { + }, +#define GAIN_IDX 2 + { { .id = V4L2_CID_GAIN, .type = V4L2_CTRL_TYPE_INTEGER, @@ -85,23 +90,31 @@ static const struct ctrl vv6410_ctrl[] = { static int vv6410_probe(struct sd *sd) { u16 data; - int err; + int err, i; + s32 *sensor_settings; err = stv06xx_read_sensor(sd, VV6410_DEVICEH, &data); - if (err < 0) return -ENODEV; if (data == 0x19) { info("vv6410 sensor detected"); + sensor_settings = kmalloc(ARRAY_SIZE(vv6410_ctrl) * sizeof(s32), + GFP_KERNEL); + if (!sensor_settings) + return -ENOMEM; + sd->gspca_dev.cam.cam_mode = vv6410_mode; sd->gspca_dev.cam.nmodes = ARRAY_SIZE(vv6410_mode); sd->desc.ctrls = vv6410_ctrl; sd->desc.nctrls = ARRAY_SIZE(vv6410_ctrl); + + for (i = 0; i < sd->desc.nctrls; i++) + sensor_settings[i] = vv6410_ctrl[i].qctrl.default_value; + sd->sensor_priv = sensor_settings; return 0; } - return -ENODEV; } @@ -133,6 +146,12 @@ static int vv6410_init(struct sd *sd) return (err < 0) ? err : 0; } +static void vv6410_disconnect(struct sd *sd) +{ + sd->sensor = NULL; + kfree(sd->sensor_priv); +} + static int vv6410_start(struct sd *sd) { int err; @@ -209,17 +228,13 @@ static int vv6410_dump(struct sd *sd) static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) { - int err; - u16 i2c_data; struct sd *sd = (struct sd *) gspca_dev; + s32 *sensor_settings = sd->sensor_priv; - err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); - - *val = (i2c_data & VV6410_HFLIP) ? 1 : 0; - + *val = sensor_settings[HFLIP_IDX]; PDEBUG(D_V4L2, "Read horizontal flip %d", *val); - return (err < 0) ? err : 0; + return 0; } static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val) @@ -227,6 +242,9 @@ static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val) int err; u16 i2c_data; struct sd *sd = (struct sd *) gspca_dev; + s32 *sensor_settings = sd->sensor_priv; + + sensor_settings[HFLIP_IDX] = val; err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); if (err < 0) return err; @@ -244,17 +262,13 @@ static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val) static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) { - int err; - u16 i2c_data; struct sd *sd = (struct sd *) gspca_dev; + s32 *sensor_settings = sd->sensor_priv; - err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); - - *val = (i2c_data & VV6410_VFLIP) ? 1 : 0; - + *val = sensor_settings[VFLIP_IDX]; PDEBUG(D_V4L2, "Read vertical flip %d", *val); - return (err < 0) ? err : 0; + return 0; } static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val) @@ -262,6 +276,9 @@ static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val) int err; u16 i2c_data; struct sd *sd = (struct sd *) gspca_dev; + s32 *sensor_settings = sd->sensor_priv; + + sensor_settings[VFLIP_IDX] = val; err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); if (err < 0) return err; @@ -279,24 +296,23 @@ static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val) static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val) { - int err; - u16 i2c_data; struct sd *sd = (struct sd *) gspca_dev; + s32 *sensor_settings = sd->sensor_priv; - err = stv06xx_read_sensor(sd, VV6410_ANALOGGAIN, &i2c_data); - - *val = i2c_data & 0xf; + *val = sensor_settings[GAIN_IDX]; PDEBUG(D_V4L2, "Read analog gain %d", *val); - return (err < 0) ? err : 0; + return 0; } static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val) { int err; struct sd *sd = (struct sd *) gspca_dev; + s32 *sensor_settings = sd->sensor_priv; + sensor_settings[GAIN_IDX] = val; PDEBUG(D_V4L2, "Set analog gain to %d", val); err = stv06xx_write_sensor(sd, VV6410_ANALOGGAIN, 0xf0 | (val & 0xf)); diff --git a/linux/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/linux/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h index 1cb5f5765..95ac55891 100644 --- a/linux/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h +++ b/linux/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h @@ -178,6 +178,7 @@ static int vv6410_start(struct sd *sd); static int vv6410_init(struct sd *sd); static int vv6410_stop(struct sd *sd); static int vv6410_dump(struct sd *sd); +static void vv6410_disconnect(struct sd *sd); /* V4L2 controls supported by the driver */ static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); @@ -197,6 +198,7 @@ const struct stv06xx_sensor stv06xx_sensor_vv6410 = { .start = vv6410_start, .stop = vv6410_stop, .dump = vv6410_dump, + .disconnect = vv6410_disconnect, }; /* If NULL, only single value to write, stored in len */ -- cgit v1.2.3 From 1efd156795c55b086c28f4eeab1d33ca12adfed5 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 7 Jan 2009 12:00:18 +0100 Subject: gspca - zc3xx / zc0301: Handle the 0ac8:303b instead of zc0301. From: Jean-Francois Moine This webcam is generic and some sensors are not treated by the driver zc0301. Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/zc3xx.c | 2 -- linux/drivers/media/video/zc0301/zc0301_sensor.h | 8 ++++++++ 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index c044cd495..8a799dbf5 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -7573,9 +7573,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0ac8, 0x0301), .driver_info = SENSOR_PAS106}, {USB_DEVICE(0x0ac8, 0x0302)}, {USB_DEVICE(0x0ac8, 0x301b)}, -#if !defined CONFIG_USB_ZC0301 && !defined CONFIG_USB_ZC0301_MODULE {USB_DEVICE(0x0ac8, 0x303b)}, -#endif {USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250}, {USB_DEVICE(0x0ac8, 0x307b)}, {USB_DEVICE(0x10fd, 0x0128)}, diff --git a/linux/drivers/media/video/zc0301/zc0301_sensor.h b/linux/drivers/media/video/zc0301/zc0301_sensor.h index 4dc95b5c2..a9cde5419 100644 --- a/linux/drivers/media/video/zc0301/zc0301_sensor.h +++ b/linux/drivers/media/video/zc0301/zc0301_sensor.h @@ -59,12 +59,20 @@ zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor); .idProduct = (prod), \ .bInterfaceClass = (intclass) +#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE #define ZC0301_ID_TABLE \ static const struct usb_device_id zc0301_id_table[] = { \ { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \ { ZC0301_USB_DEVICE(0x0ac8, 0x303b, 0xff), }, /* PB-0330 */ \ { } \ }; +#else +#define ZC0301_ID_TABLE \ +static const struct usb_device_id zc0301_id_table[] = { \ + { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \ + { } \ +}; +#endif /*****************************************************************************/ -- cgit v1.2.3 From 87a6b9a42841dabe6d78f0997a1b7432363d3cf2 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 7 Jan 2009 13:09:36 +0100 Subject: gspca - ov534: Disable the Hercules webcams. From: Antonio Ospite The Hercules webcam based on ov534 use different sensor than Playstation Eye, disable them until full support is provided. Priority: normal Signed-off-by: Antonio Ospite Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/ov534.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/ov534.c b/linux/drivers/media/video/gspca/ov534.c index 55d920caa..de0ab8e06 100644 --- a/linux/drivers/media/video/gspca/ov534.c +++ b/linux/drivers/media/video/gspca/ov534.c @@ -555,8 +555,11 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { +#if 0 + /* these two are not supported yet, different sensors */ {USB_DEVICE(0x06f8, 0x3002)}, /* Hercules Blog Webcam */ {USB_DEVICE(0x06f8, 0x3003)}, /* Hercules Dualpix HD Weblog */ +#endif {USB_DEVICE(0x1415, 0x2000)}, /* Sony HD Eye for PS3 (SLEH 00201) */ {} }; -- cgit v1.2.3 From 708897dcfe69ded8bd4e9cf6283bb1f44d7727b9 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 7 Jan 2009 20:49:57 +0100 Subject: gspca - jpeg subdrivers: One quantization table per subdriver. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/conex.c | 8 +- linux/drivers/media/video/gspca/jpeg.h | 283 +++++++++++++++++------------- linux/drivers/media/video/gspca/mars.c | 9 +- linux/drivers/media/video/gspca/sonixj.c | 5 +- linux/drivers/media/video/gspca/spca500.c | 5 +- linux/drivers/media/video/gspca/stk014.c | 10 +- linux/drivers/media/video/gspca/sunplus.c | 7 +- linux/drivers/media/video/gspca/zc3xx.c | 36 ++-- 8 files changed, 183 insertions(+), 180 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/conex.c b/linux/drivers/media/video/gspca/conex.c index 2de8906e5..de2e608bf 100644 --- a/linux/drivers/media/video/gspca/conex.c +++ b/linux/drivers/media/video/gspca/conex.c @@ -23,6 +23,7 @@ #include "gspca.h" #define CONEX_CAM 1 /* special JPEG header */ +#define QUANT_VAL 0 /* quantization table */ #include "jpeg.h" MODULE_AUTHOR("Michel Xhaard "); @@ -36,8 +37,6 @@ struct sd { unsigned char brightness; unsigned char contrast; unsigned char colors; - - unsigned char qindex; }; /* V4L2 controls supported by the driver */ @@ -818,7 +817,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; - sd->qindex = 0; /* set the quantization */ sd->brightness = BRIGHTNESS_DEF; sd->contrast = CONTRAST_DEF; sd->colors = COLOR_DEF; @@ -882,9 +880,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, data, 0); /* put the JPEG header in the new frame */ - jpeg_put_header(gspca_dev, frame, - ((struct sd *) gspca_dev)->qindex, - 0x22); + jpeg_put_header(gspca_dev, frame, 0x22); data += 2; len -= 2; } diff --git a/linux/drivers/media/video/gspca/jpeg.h b/linux/drivers/media/video/gspca/jpeg.h index d823b47bd..7d2df9720 100644 --- a/linux/drivers/media/video/gspca/jpeg.h +++ b/linux/drivers/media/video/gspca/jpeg.h @@ -24,171 +24,207 @@ * */ -/* start of jpeg frame + quantization table */ -static const unsigned char quant[][0x88] = { -/* index 0 - Q40*/ - { +/* + * generation options + * CONEX_CAM Conexant if present + * QUANT_VAL quantization table (0..8) + */ + +/* + * JPEG header: + * - start of jpeg frame + * - quantization table + * - huffman table + * - start of SOF0 + */ +static const u8 jpeg_head[] = { 0xff, 0xd8, /* jpeg */ 0xff, 0xdb, 0x00, 0x84, /* DQT */ +#if QUANT_VAL == 0 +/* index 0 - Q40*/ 0, /* quantization table part 1 */ - 20, 14, 15, 18, 15, 13, 20, 18, 16, 18, 23, 21, 20, 24, 30, 50, - 33, 30, 28, 28, 30, 61, 44, 46, 36, 50, 73, 64, 76, 75, 71, 64, - 70, 69, 80, 90, 115, 98, 80, 85, 109, 86, 69, 70, 100, 136, 101, - 109, - 119, 123, 129, 130, 129, 78, 96, 141, 151, 140, 125, 150, 115, - 126, 129, 124, + 0x14, 0x0e, 0x0f, 0x12, 0x0f, 0x0d, 0x14, 0x12, + 0x10, 0x12, 0x17, 0x15, 0x14, 0x18, 0x1e, 0x32, + 0x21, 0x1e, 0x1c, 0x1c, 0x1e, 0x3d, 0x2c, 0x2e, + 0x24, 0x32, 0x49, 0x40, 0x4c, 0x4b, 0x47, 0x40, + 0x46, 0x45, 0x50, 0x5a, 0x73, 0x62, 0x50, 0x55, + 0x6d, 0x56, 0x45, 0x46, 0x64, 0x88, 0x65, 0x6d, + 0x77, 0x7b, 0x81, 0x82, 0x81, 0x4e, 0x60, 0x8d, + 0x97, 0x8c, 0x7d, 0x96, 0x73, 0x7e, 0x81, 0x7c, 1, /* quantization table part 2 */ - 21, 23, 23, 30, 26, 30, 59, 33, 33, 59, 124, 83, 70, 83, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124}, + 0x15, 0x17, 0x17, 0x1e, 0x1a, 0x1e, 0x3b, 0x21, + 0x21, 0x3b, 0x7c, 0x53, 0x46, 0x53, 0x7c, 0x0c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, +#elif QUANT_VAL == 1 /* index 1 - Q50 */ - { - 0xff, 0xd8, - 0xff, 0xdb, 0x00, 0x84, /* DQT */ 0, - 16, 11, 12, 14, 12, 10, 16, 14, 13, 14, 18, 17, 16, 19, 24, 40, - 26, 24, 22, 22, 24, 49, 35, 37, 29, 40, 58, 51, 61, 60, 57, 51, - 56, 55, 64, 72, 92, 78, 64, 68, 87, 69, 55, 56, 80, 109, 81, 87, - 95, 98, 103, 104, 103, 62, 77, 113, 121, 112, 100, 120, 92, 101, - 103, 99, + 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, + 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, + 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, + 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, + 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44, + 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57, + 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, + 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63, 1, - 17, 18, 18, 24, 21, 24, 47, 26, 26, 47, 99, 66, 56, 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, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}, + 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, + 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, +#elif QUANT_VAL == 2 /* index 2 Q60 */ - { - 0xff, 0xd8, - 0xff, 0xdb, 0x00, 0x84, /* DQT */ 0, - 13, 9, 10, 11, 10, 8, 13, 11, 10, 11, 14, 14, 13, 15, 19, 32, - 21, 19, 18, 18, 19, 39, 28, 30, 23, 32, 46, 41, 49, 48, 46, 41, - 45, 44, 51, 58, 74, 62, 51, 54, 70, 55, 44, 45, 64, 87, 65, 70, - 76, 78, 82, 83, 82, 50, 62, 90, 97, 90, 80, 96, 74, 81, 82, 79, + 0x0d, 0x09, 0x0a, 0x0b, 0x0a, 0x08, 0x0d, 0x0b, + 0x0a, 0x0b, 0x0e, 0x0e, 0x0d, 0x0f, 0x13, 0x20, + 0x15, 0x13, 0x12, 0x12, 0x13, 0x27, 0x1c, 0x1e, + 0x17, 0x20, 0x2e, 0x29, 0x31, 0x30, 0x2e, 0x29, + 0x2d, 0x2c, 0x33, 0x3a, 0x4a, 0x3e, 0x33, 0x36, + 0x46, 0x37, 0x2c, 0x2d, 0x40, 0x57, 0x41, 0x46, + 0x4c, 0x4e, 0x52, 0x53, 0x52, 0x32, 0x3e, 0x5a, + 0x61, 0x5a, 0x50, 0x60, 0x4a, 0x51, 0x52, 0x4f, 1, - 14, 14, 14, 19, 17, 19, 38, 21, 21, 38, 79, 53, 45, 53, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79}, + 0x0e, 0x0e, 0x0e, 0x13, 0x11, 0x13, 0x26, 0x15, + 0x15, 0x26, 0x4f, 0x35, 0x2d, 0x35, 0x4f, 0x4f, + 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, + 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, + 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, + 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, + 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, + 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, +#elif QUANT_VAL == 3 /* index 3 - Q70 */ - { - 0xff, 0xd8, - 0xff, 0xdb, 0x00, 0x84, /* DQT */ 0, - 10, 7, 7, 8, 7, 6, 10, 8, 8, 8, 11, 10, 10, 11, 14, 24, - 16, 14, 13, 13, 14, 29, 21, 22, 17, 24, 35, 31, 37, 36, 34, 31, - 34, 33, 38, 43, 55, 47, 38, 41, 52, 41, 33, 34, 48, 65, 49, 52, - 57, 59, 62, 62, 62, 37, 46, 68, 73, 67, 60, 72, 55, 61, 62, 59, + 0x0a, 0x07, 0x07, 0x08, 0x07, 0x06, 0x0a, 0x08, + 0x08, 0x08, 0x0b, 0x0a, 0x0a, 0x0b, 0x0e, 0x18, + 0x10, 0x0e, 0x0d, 0x0d, 0x0e, 0x1d, 0x15, 0x16, + 0x11, 0x18, 0x23, 0x1f, 0x25, 0x24, 0x22, 0x1f, + 0x22, 0x21, 0x26, 0x2b, 0x37, 0x2f, 0x26, 0x29, + 0x34, 0x29, 0x21, 0x22, 0x30, 0x41, 0x31, 0x34, + 0x39, 0x3b, 0x3e, 0x3e, 0x3e, 0x25, 0x2e, 0x44, + 0x49, 0x43, 0x3c, 0x48, 0x37, 0x3d, 0x3e, 0x3b, 1, - 10, 11, 11, 14, 13, 14, 28, 16, 16, 28, 59, 40, 34, 40, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59}, + 0x0a, 0x0b, 0x0b, 0x0e, 0x0d, 0x0e, 0x1c, 0x10, + 0x10, 0x1c, 0x3b, 0x28, 0x22, 0x28, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, +#elif QUANT_VAL == 4 /* index 4 - Q80 */ - { - 0xff, 0xd8, - 0xff, 0xdb, 0x00, 0x84, /* DQT */ 0, - 6, 4, 5, 6, 5, 4, 6, 6, 5, 6, 7, 7, 6, 8, 10, 16, - 10, 10, 9, 9, 10, 20, 14, 15, 12, 16, 23, 20, 24, 24, 23, 20, - 22, 22, 26, 29, 37, 31, 26, 27, 35, 28, 22, 22, 32, 44, 32, 35, - 38, 39, 41, 42, 41, 25, 31, 45, 48, 45, 40, 48, 37, 40, 41, 40, + 0x06, 0x04, 0x05, 0x06, 0x05, 0x04, 0x06, 0x06, + 0x05, 0x06, 0x07, 0x07, 0x06, 0x08, 0x0a, 0x10, + 0x0a, 0x0a, 0x09, 0x09, 0x0a, 0x14, 0x0e, 0x0f, + 0x0c, 0x10, 0x17, 0x14, 0x18, 0x18, 0x17, 0x14, + 0x16, 0x16, 0x1a, 0x1d, 0x25, 0x1f, 0x1a, 0x1b, + 0x23, 0x1c, 0x16, 0x16, 0x20, 0x2c, 0x20, 0x23, + 0x26, 0x27, 0x29, 0x2a, 0x29, 0x19, 0x1f, 0x2d, + 0x30, 0x2d, 0x28, 0x30, 0x25, 0x28, 0x29, 0x28, 1, - 7, 7, 7, 10, 8, 10, 19, 10, 10, 19, 40, 26, 22, 26, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}, + 0x07, 0x07, 0x07, 0x0a, 0x08, 0x0a, 0x13, 0x0a, + 0x0a, 0x13, 0x28, 0x1a, 0x16, 0x1a, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, +#elif QUANT_VAL == 5 /* index 5 - Q85 */ - { - 0xff, 0xd8, - 0xff, 0xdb, 0x00, 0x84, /* DQT */ 0, - 5, 3, 4, 4, 4, 3, 5, 4, 4, 4, 5, 5, 5, 6, 7, 12, - 8, 7, 7, 7, 7, 15, 11, 11, 9, 12, 17, 15, 18, 18, 17, 15, - 17, 17, 19, 22, 28, 23, 19, 20, 26, 21, 17, 17, 24, 33, 24, 26, - 29, 29, 31, 31, 31, 19, 23, 34, 36, 34, 30, 36, 28, 30, 31, 30, + 0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, + 0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, + 0x08, 0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, + 0x09, 0x0c, 0x11, 0x0f, 0x12, 0x12, 0x11, 0x0f, + 0x11, 0x11, 0x13, 0x16, 0x1c, 0x17, 0x13, 0x14, + 0x1a, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1a, + 0x1d, 0x1d, 0x1f, 0x1f, 0x1f, 0x13, 0x17, 0x22, + 0x24, 0x22, 0x1e, 0x24, 0x1c, 0x1e, 0x1f, 0x1e, 1, - 5, 5, 5, 7, 6, 7, 14, 8, 8, 14, 30, 20, 17, 20, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, + 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x0e, 0x08, + 0x08, 0x0e, 0x1e, 0x14, 0x11, 0x14, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, +#elif QUANT_VAL == 6 /* index 6 - 86 */ -{ - 0xff, 0xd8, - 0xff, 0xdb, 0x00, 0x84, /* DQT */ 0, 0x04, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x04, 0x05, 0x07, 0x0B, - 0x07, 0x07, 0x06, 0x06, 0x07, 0x0E, 0x0A, 0x0A, - 0x08, 0x0B, 0x10, 0x0E, 0x11, 0x11, 0x10, 0x0E, - 0x10, 0x0F, 0x12, 0x14, 0x1A, 0x16, 0x12, 0x13, - 0x18, 0x13, 0x0F, 0x10, 0x16, 0x1F, 0x17, 0x18, - 0x1B, 0x1B, 0x1D, 0x1D, 0x1D, 0x11, 0x16, 0x20, - 0x22, 0x1F, 0x1C, 0x22, 0x1A, 0x1C, 0x1D, 0x1C, + 0x07, 0x07, 0x06, 0x06, 0x07, 0x0e, 0x0a, 0x0a, + 0x08, 0x0B, 0x10, 0x0e, 0x11, 0x11, 0x10, 0x0e, + 0x10, 0x0f, 0x12, 0x14, 0x1a, 0x16, 0x12, 0x13, + 0x18, 0x13, 0x0f, 0x10, 0x16, 0x1f, 0x17, 0x18, + 0x1b, 0x1b, 0x1d, 0x1d, 0x1d, 0x11, 0x16, 0x20, + 0x22, 0x1f, 0x1c, 0x22, 0x1a, 0x1c, 0x1d, 0x1c, 1, 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x0D, 0x07, - 0x07, 0x0D, 0x1C, 0x12, 0x10, 0x12, 0x1C, 0x1C, - 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, - 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, - 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, - 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, - 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, - 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, - }, + 0x07, 0x0D, 0x1c, 0x12, 0x10, 0x12, 0x1c, 0x1c, + 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, + 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, + 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, + 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, + 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, + 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, +#elif QUANT_VAL == 7 /* index 7 - 88 */ -{ - 0xff, 0xd8, - 0xff, 0xdb, 0x00, 0x84, /* DQT */ 0, 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x04, 0x03, - 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x06, 0x0A, + 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x06, 0x0a, 0x06, 0x06, 0x05, 0x05, 0x06, 0x0C, 0x08, 0x09, - 0x07, 0x0A, 0x0E, 0x0C, 0x0F, 0x0E, 0x0E, 0x0C, - 0x0D, 0x0D, 0x0F, 0x11, 0x16, 0x13, 0x0F, 0x10, - 0x15, 0x11, 0x0D, 0x0D, 0x13, 0x1A, 0x13, 0x15, - 0x17, 0x18, 0x19, 0x19, 0x19, 0x0F, 0x12, 0x1B, - 0x1D, 0x1B, 0x18, 0x1D, 0x16, 0x18, 0x19, 0x18, + 0x07, 0x0a, 0x0e, 0x0c, 0x0f, 0x0e, 0x0e, 0x0c, + 0x0d, 0x0d, 0x0f, 0x11, 0x16, 0x13, 0x0f, 0x10, + 0x15, 0x11, 0x0d, 0x0d, 0x13, 0x1a, 0x13, 0x15, + 0x17, 0x18, 0x19, 0x19, 0x19, 0x0f, 0x12, 0x1b, + 0x1d, 0x1b, 0x18, 0x1d, 0x16, 0x18, 0x19, 0x18, 1, 0x04, 0x04, 0x04, 0x06, 0x05, 0x06, 0x0B, 0x06, - 0x06, 0x0B, 0x18, 0x10, 0x0D, 0x10, 0x18, 0x18, + 0x06, 0x0B, 0x18, 0x10, 0x0d, 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, -}, +#elif QUANT_VAL == 8 /* index 8 - ?? */ -{ - 0xff, 0xd8, - 0xff, 0xdb, 0x00, 0x84, /* DQT */ 0, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x05, 0x03, 0x03, 0x03, 0x03, 0x03, 0x06, 0x04, 0x05, 0x04, 0x05, 0x07, 0x06, 0x08, 0x08, 0x07, 0x06, - 0x07, 0x07, 0x08, 0x09, 0x0C, 0x0A, 0x08, 0x09, - 0x0B, 0x09, 0x07, 0x07, 0x0A, 0x0E, 0x0A, 0x0B, - 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x08, 0x0A, 0x0E, - 0x0F, 0x0E, 0x0D, 0x0F, 0x0C, 0x0D, 0x0D, 0x0C, + 0x07, 0x07, 0x08, 0x09, 0x0c, 0x0a, 0x08, 0x09, + 0x0B, 0x09, 0x07, 0x07, 0x0a, 0x0e, 0x0a, 0x0b, + 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x08, 0x0a, 0x0e, + 0x0f, 0x0e, 0x0d, 0x0f, 0x0c, 0x0d, 0x0d, 0x0c, 1, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x06, 0x03, - 0x03, 0x06, 0x0C, 0x08, 0x07, 0x08, 0x0C, 0x0C, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C -} -}; + 0x03, 0x06, 0x0c, 0x08, 0x07, 0x08, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, +#else +#error "Invalid quantization table" +#endif -/* huffman table + start of SOF0 */ -static unsigned char huffman[] = { +/* huffman table */ 0xff, 0xc4, 0x01, 0xa2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -260,7 +296,7 @@ static unsigned char huffman[] = { */ /* end of header */ -static unsigned char eoh[] = { +static u8 eoh[] = { 0x00, /* quant Y */ 0x02, 0x11, 0x01, /* samples CbCr - quant CbCr */ 0x03, 0x11, 0x01, @@ -273,17 +309,14 @@ static unsigned char eoh[] = { /* -- output the JPEG header -- */ static void jpeg_put_header(struct gspca_dev *gspca_dev, struct gspca_frame *frame, - int qindex, int samplesY) { #ifndef CONEX_CAM - unsigned char tmpbuf[8]; + u8 tmpbuf[8]; #endif gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - (unsigned char *) quant[qindex], sizeof quant[0]); - gspca_frame_add(gspca_dev, INTER_PACKET, frame, - (unsigned char *) huffman, sizeof huffman); + jpeg_head, sizeof jpeg_head); #ifndef CONEX_CAM tmpbuf[0] = gspca_dev->height >> 8; tmpbuf[1] = gspca_dev->height & 0xff; diff --git a/linux/drivers/media/video/gspca/mars.c b/linux/drivers/media/video/gspca/mars.c index 477441e22..54c68ea7e 100644 --- a/linux/drivers/media/video/gspca/mars.c +++ b/linux/drivers/media/video/gspca/mars.c @@ -22,6 +22,7 @@ #define MODULE_NAME "mars" #include "gspca.h" +#define QUANT_VAL 1 /* quantization table */ #include "jpeg.h" MODULE_AUTHOR("Michel Xhaard "); @@ -31,8 +32,6 @@ MODULE_LICENSE("GPL"); /* specific webcam descriptor */ struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - - char qindex; }; /* V4L2 controls supported by the driver */ @@ -117,13 +116,11 @@ static void bulk_w(struct gspca_dev *gspca_dev, 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; cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); - sd->qindex = 1; /* set the quantization table */ return 0; } @@ -345,7 +342,6 @@ 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; int p; if (len < 6) { @@ -368,8 +364,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, frame, data, 0); /* put the JPEG header */ - jpeg_put_header(gspca_dev, frame, - sd->qindex, 0x21); + jpeg_put_header(gspca_dev, frame, 0x21); data += 16; len -= 16; break; diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index f977dd22e..f4fb45fb3 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -22,6 +22,7 @@ #define MODULE_NAME "sonixj" #include "gspca.h" +#define QUANT_VAL 4 /* quantization table */ #include "jpeg.h" #define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0) @@ -49,7 +50,6 @@ struct sd { __s8 ag_cnt; #define AG_CNT_START 13 - __u8 qindex; __u8 bridge; #define BRIDGE_SN9C102P 0 #define BRIDGE_SN9C105 1 @@ -1033,7 +1033,6 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->sensor = id->driver_info >> 8; sd->i2c_base = id->driver_info; - sd->qindex = 4; /* set the quantization table */ sd->brightness = BRIGHTNESS_DEF; sd->contrast = CONTRAST_DEF; sd->colors = COLOR_DEF; @@ -1565,7 +1564,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, if (gspca_dev->last_packet_type == LAST_PACKET) { /* put the JPEG 422 header */ - jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21); + jpeg_put_header(gspca_dev, frame, 0x21); } gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); } diff --git a/linux/drivers/media/video/gspca/spca500.c b/linux/drivers/media/video/gspca/spca500.c index 8054c5f62..0f91c5173 100644 --- a/linux/drivers/media/video/gspca/spca500.c +++ b/linux/drivers/media/video/gspca/spca500.c @@ -22,6 +22,7 @@ #define MODULE_NAME "spca500" #include "gspca.h" +#define QUANT_VAL 5 /* quantization table */ #include "jpeg.h" MODULE_AUTHOR("Michel Xhaard "); @@ -39,7 +40,6 @@ struct sd { unsigned char contrast; unsigned char colors; - char qindex; char subtype; #define AgfaCl20 0 #define AiptekPocketDV 1 @@ -654,7 +654,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); } - sd->qindex = 5; sd->brightness = BRIGHTNESS_DEF; sd->contrast = CONTRAST_DEF; sd->colors = COLOR_DEF; @@ -917,7 +916,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, ffd9, 2); /* put the JPEG header in the new frame */ - jpeg_put_header(gspca_dev, frame, sd->qindex, 0x22); + jpeg_put_header(gspca_dev, frame, 0x22); data += SPCA500_OFFSET_DATA; len -= SPCA500_OFFSET_DATA; diff --git a/linux/drivers/media/video/gspca/stk014.c b/linux/drivers/media/video/gspca/stk014.c index ba31eb318..d1d54edd8 100644 --- a/linux/drivers/media/video/gspca/stk014.c +++ b/linux/drivers/media/video/gspca/stk014.c @@ -21,6 +21,8 @@ #define MODULE_NAME "stk014" #include "gspca.h" +#define QUANT_VAL 7 /* quantization table */ + /* <= 4 KO - 7: good (enough!) */ #include "jpeg.h" MODULE_AUTHOR("Jean-Francois Moine "); @@ -37,9 +39,6 @@ struct sd { unsigned char lightfreq; }; -/* global parameters */ -static int sd_quant = 7; /* <= 4 KO - 7: good (enough!) */ - /* 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); @@ -418,7 +417,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, ffd9, 2); /* put the JPEG 411 header */ - jpeg_put_header(gspca_dev, frame, sd_quant, 0x22); + jpeg_put_header(gspca_dev, frame, 0x22); /* beginning of the frame */ #define STKHDRSZ 12 @@ -575,6 +574,3 @@ static void __exit sd_mod_exit(void) module_init(sd_mod_init); module_exit(sd_mod_exit); - -module_param_named(quant, sd_quant, int, 0644); -MODULE_PARM_DESC(quant, "Quantization index (0..8)"); diff --git a/linux/drivers/media/video/gspca/sunplus.c b/linux/drivers/media/video/gspca/sunplus.c index 6c46743b7..852711731 100644 --- a/linux/drivers/media/video/gspca/sunplus.c +++ b/linux/drivers/media/video/gspca/sunplus.c @@ -22,6 +22,7 @@ #define MODULE_NAME "sunplus" #include "gspca.h" +#define QUANT_VAL 5 /* quantization table */ #include "jpeg.h" MODULE_AUTHOR("Michel Xhaard "); @@ -40,7 +41,6 @@ struct sd { unsigned char colors; unsigned char autogain; - char qindex; char bridge; #define BRIDGE_SPCA504 0 #define BRIDGE_SPCA504B 1 @@ -880,7 +880,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0]; break; } - sd->qindex = 5; /* set the quantization table */ sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; @@ -1185,9 +1184,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, ffd9, 2); /* put the JPEG header in the new frame */ - jpeg_put_header(gspca_dev, frame, - ((struct sd *) gspca_dev)->qindex, - 0x22); + jpeg_put_header(gspca_dev, frame, 0x22); } /* add 0x00 after 0xff */ diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index 8a799dbf5..a3aad1aa1 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -31,6 +31,7 @@ MODULE_LICENSE("GPL"); static int force_sensor = -1; +#define QUANT_VAL 1 /* quantization table */ #include "jpeg.h" #include "zc3xx-reg.h" @@ -45,7 +46,6 @@ struct sd { __u8 lightfreq; __u8 sharpness; - char qindex; signed char sensor; /* Type of image sensor chip */ /* !! values used in different tables */ #define SENSOR_CS2102 0 @@ -6541,7 +6541,6 @@ static void setquality(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; - __u8 quality; __u8 frxt; switch (sd->sensor) { @@ -6552,26 +6551,18 @@ static void setquality(struct gspca_dev *gspca_dev) return; } /*fixme: is it really 0008 0007 0018 for all other sensors? */ - quality = sd->qindex; - reg_w(dev, quality, 0x0008); + reg_w(dev, QUANT_VAL, 0x0008); frxt = 0x30; reg_w(dev, frxt, 0x0007); - switch (quality) { - case 0: - case 1: - case 2: - frxt = 0xff; - break; - case 3: - frxt = 0xf0; - break; - case 4: - frxt = 0xe0; - break; - case 5: - frxt = 0x20; - break; - } +#if QUANT_VAL == 0 || QUANT_VAL == 1 || QUANT_VAL == 2 + frxt = 0xff; +#elif QUANT_VAL == 3 + frxt = 0xf0; +#elif QUANT_VAL == 4 + frxt = 0xe0; +#else + frxt = 0x20; +#endif reg_w(dev, frxt, 0x0018); } @@ -7161,7 +7152,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); } - sd->qindex = 1; sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; sd->gamma = gamma[(int) sd->sensor]; @@ -7367,9 +7357,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); /* put the JPEG header in the new frame */ - jpeg_put_header(gspca_dev, frame, - ((struct sd *) gspca_dev)->qindex, - 0x21); + jpeg_put_header(gspca_dev, frame, 0x21); /* remove the webcam's header: * ff d8 ff fe 00 0e 00 00 ss ss 00 01 ww ww hh hh pp pp * - 'ss ss' is the frame sequence number (BE) -- cgit v1.2.3 From 0da36c289360f80fd9628741887f48947f33ca71 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 8 Jan 2009 13:38:45 +0100 Subject: gspca - zc3xx: Fix bad variable type with i2c read. From: Jean-Francois Moine The returned value of i2c read is a 16 bits word. It was stored in a 8 bits variable, preventing a sensor to be detected. Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/zc3xx.c | 125 +++++++++++++++----------------- 1 file changed, 59 insertions(+), 66 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index a3aad1aa1..fcfced0c2 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -6242,7 +6242,7 @@ static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = { {} }; -static int reg_r_i(struct gspca_dev *gspca_dev, +static u8 reg_r_i(struct gspca_dev *gspca_dev, __u16 index) { usb_control_msg(gspca_dev->dev, @@ -6255,10 +6255,10 @@ static int reg_r_i(struct gspca_dev *gspca_dev, return gspca_dev->usb_buf[0]; } -static int reg_r(struct gspca_dev *gspca_dev, +static u8 reg_r(struct gspca_dev *gspca_dev, __u16 index) { - int ret; + u8 ret; ret = reg_r_i(gspca_dev, index); PDEBUG(D_USBI, "reg r [%04x] -> %02x", index, ret); @@ -6739,26 +6739,25 @@ static int sif_probe(struct gspca_dev *gspca_dev) static int vga_2wr_probe(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; - __u8 retbyte; - __u16 checkword; + u16 retword; start_2wr_probe(dev, 0x00); /* HV7131B */ i2c_write(gspca_dev, 0x01, 0xaa, 0x00); - retbyte = i2c_read(gspca_dev, 0x01); - if (retbyte != 0) + retword = i2c_read(gspca_dev, 0x01); + if (retword != 0) return 0x00; /* HV7131B */ start_2wr_probe(dev, 0x04); /* CS2102 */ i2c_write(gspca_dev, 0x01, 0xaa, 0x00); - retbyte = i2c_read(gspca_dev, 0x01); - if (retbyte != 0) + retword = i2c_read(gspca_dev, 0x01); + if (retword != 0) return 0x04; /* CS2102 */ start_2wr_probe(dev, 0x06); /* OmniVision */ reg_w(dev, 0x08, 0x008d); i2c_write(gspca_dev, 0x11, 0xaa, 0x00); - retbyte = i2c_read(gspca_dev, 0x11); - if (retbyte != 0) { + retword = i2c_read(gspca_dev, 0x11); + if (retword != 0) { /* (should have returned 0xaa) --> Omnivision? */ /* reg_r 0x10 -> 0x06 --> */ goto ov_check; @@ -6766,40 +6765,40 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev) start_2wr_probe(dev, 0x08); /* HDCS2020 */ i2c_write(gspca_dev, 0x15, 0xaa, 0x00); - retbyte = i2c_read(gspca_dev, 0x15); - if (retbyte != 0) + retword = i2c_read(gspca_dev, 0x15); + if (retword != 0) return 0x08; /* HDCS2020 */ start_2wr_probe(dev, 0x0a); /* PB0330 */ i2c_write(gspca_dev, 0x07, 0xaa, 0xaa); - retbyte = i2c_read(gspca_dev, 0x07); - if (retbyte != 0) + retword = i2c_read(gspca_dev, 0x07); + if (retword != 0) return 0x0a; /* PB0330 */ - retbyte = i2c_read(gspca_dev, 0x03); - if (retbyte != 0) + retword = i2c_read(gspca_dev, 0x03); + if (retword != 0) return 0x0a; /* PB0330 ?? */ - retbyte = i2c_read(gspca_dev, 0x04); - if (retbyte != 0) + retword = i2c_read(gspca_dev, 0x04); + if (retword != 0) return 0x0a; /* PB0330 ?? */ start_2wr_probe(dev, 0x0c); /* ICM105A */ i2c_write(gspca_dev, 0x01, 0x11, 0x00); - retbyte = i2c_read(gspca_dev, 0x01); - if (retbyte != 0) + retword = i2c_read(gspca_dev, 0x01); + if (retword != 0) return 0x0c; /* ICM105A */ start_2wr_probe(dev, 0x0e); /* PAS202BCB */ reg_w(dev, 0x08, 0x008d); i2c_write(gspca_dev, 0x03, 0xaa, 0x00); msleep(500); - retbyte = i2c_read(gspca_dev, 0x03); - if (retbyte != 0) + retword = i2c_read(gspca_dev, 0x03); + if (retword != 0) return 0x0e; /* PAS202BCB */ start_2wr_probe(dev, 0x02); /* ?? */ i2c_write(gspca_dev, 0x01, 0xaa, 0x00); - retbyte = i2c_read(gspca_dev, 0x01); - if (retbyte != 0) + retword = i2c_read(gspca_dev, 0x01); + if (retword != 0) return 0x02; /* ?? */ ov_check: reg_r(gspca_dev, 0x0010); /* ?? */ @@ -6813,12 +6812,10 @@ ov_check: msleep(500); reg_w(dev, 0x01, 0x0012); i2c_write(gspca_dev, 0x12, 0x80, 0x00); /* sensor reset */ - retbyte = i2c_read(gspca_dev, 0x0a); - checkword = retbyte << 8; - retbyte = i2c_read(gspca_dev, 0x0b); - checkword |= retbyte; - PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", checkword); - switch (checkword) { + retword = i2c_read(gspca_dev, 0x0a) << 8; + retword |= i2c_read(gspca_dev, 0x0b); + PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", retword); + switch (retword) { case 0x7631: /* OV7630C */ reg_w(dev, 0x06, 0x0010); break; @@ -6828,7 +6825,7 @@ ov_check: default: return -1; /* not OmniVision */ } - return checkword; + return retword; } struct sensor_by_chipset_revision { @@ -6849,7 +6846,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) struct usb_device *dev = gspca_dev->dev; int i; __u8 retbyte; - __u16 checkword; + u16 retword; /*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/ reg_w(dev, 0x02, 0x0010); @@ -6861,27 +6858,25 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) reg_w(dev, 0x03, 0x0012); reg_w(dev, 0x01, 0x0012); reg_w(dev, 0x05, 0x0012); - retbyte = i2c_read(gspca_dev, 0x14); - if (retbyte != 0) + retword = i2c_read(gspca_dev, 0x14); + if (retword != 0) return 0x11; /* HV7131R */ - retbyte = i2c_read(gspca_dev, 0x15); - if (retbyte != 0) + retword = i2c_read(gspca_dev, 0x15); + if (retword != 0) return 0x11; /* HV7131R */ - retbyte = i2c_read(gspca_dev, 0x16); - if (retbyte != 0) + retword = i2c_read(gspca_dev, 0x16); + if (retword != 0) return 0x11; /* HV7131R */ reg_w(dev, 0x02, 0x0010); - retbyte = reg_r(gspca_dev, 0x000b); - checkword = retbyte << 8; - retbyte = reg_r(gspca_dev, 0x000a); - checkword |= retbyte; - PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", checkword); + retword = reg_r(gspca_dev, 0x000b) << 8; + retword |= reg_r(gspca_dev, 0x000a); + PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword); reg_r(gspca_dev, 0x0010); /* this is tested only once anyway */ for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) { - if (chipset_revision_sensor[i].revision == checkword) { - sd->chip_revision = checkword; + if (chipset_revision_sensor[i].revision == retword) { + sd->chip_revision = retword; send_unknown(dev, SENSOR_PB0330); return chipset_revision_sensor[i].internal_sensor_id; } @@ -6893,8 +6888,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) reg_w(dev, 0x0a, 0x0010); reg_w(dev, 0x03, 0x0012); reg_w(dev, 0x01, 0x0012); - retbyte = i2c_read(gspca_dev, 0x00); - if (retbyte != 0) { + retword = i2c_read(gspca_dev, 0x00); + if (retword != 0) { PDEBUG(D_PROBE, "probe 3wr vga type 0a ?"); return 0x0a; /* ?? */ } @@ -6906,14 +6901,14 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) reg_w(dev, 0x03, 0x0012); msleep(2); reg_w(dev, 0x01, 0x0012); - retbyte = i2c_read(gspca_dev, 0x00); - if (retbyte != 0) { - PDEBUG(D_PROBE, "probe 3wr vga type %02x", retbyte); - if (retbyte == 0x11) /* VF0250 */ + retword = i2c_read(gspca_dev, 0x00); + if (retword != 0) { + PDEBUG(D_PROBE, "probe 3wr vga type %02x", retword); + if (retword == 0x0011) /* VF0250 */ return 0x0250; - if (retbyte == 0x29) /* gc0305 */ + if (retword == 0x0029) /* gc0305 */ send_unknown(dev, SENSOR_GC0305); - return retbyte; + return retword; } reg_w(dev, 0x01, 0x0000); /* check OmniVision */ @@ -6923,8 +6918,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) reg_w(dev, 0x06, 0x0010); reg_w(dev, 0x01, 0x0012); reg_w(dev, 0x05, 0x0012); - if (i2c_read(gspca_dev, 0x1c) == 0x7f /* OV7610 - manufacturer ID */ - && i2c_read(gspca_dev, 0x1d) == 0xa2) { + if (i2c_read(gspca_dev, 0x1c) == 0x007f /* OV7610 - manufacturer ID */ + && i2c_read(gspca_dev, 0x1d) == 0x00a2) { send_unknown(dev, SENSOR_OV7620); return 0x06; /* OmniVision confirm ? */ } @@ -6938,16 +6933,14 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) /* msleep(150); */ reg_w(dev, 0x01, 0x0012); reg_w(dev, 0x05, 0x0012); - retbyte = i2c_read(gspca_dev, 0x0000); /* ID 0 */ - checkword = retbyte << 8; - retbyte = i2c_read(gspca_dev, 0x0001); /* ID 1 */ - checkword |= retbyte; - PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", checkword); - if (checkword == 0x2030) { + retword = i2c_read(gspca_dev, 0x00) << 8; /* ID 0 */ + retword |= i2c_read(gspca_dev, 0x01); /* ID 1 */ + PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", retword); + if (retword == 0x2030) { retbyte = i2c_read(gspca_dev, 0x02); /* revision number */ PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte); send_unknown(dev, SENSOR_PO2030); - return checkword; + return retword; } reg_w(dev, 0x01, 0x0000); @@ -6958,9 +6951,9 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) reg_w(dev, 0x01, 0x0012); reg_w(dev, 0x05, 0x0001); reg_w(dev, 0xd3, 0x008b); - retbyte = i2c_read(gspca_dev, 0x01); - if (retbyte != 0) { - PDEBUG(D_PROBE, "probe 3wr vga type 0a ?"); + retword = i2c_read(gspca_dev, 0x01); + if (retword != 0) { + PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword); return 0x0a; /* ?? */ } return -1; -- cgit v1.2.3 From 46d0baca550ed5a58ad1dbf12de389f08e2e97b3 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 8 Jan 2009 20:29:38 +0100 Subject: gspca - mars: Optimize, rewrite initialization and add controls. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/mars.c | 465 ++++++++++++++++++++------------- 1 file changed, 277 insertions(+), 188 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/mars.c b/linux/drivers/media/video/gspca/mars.c index 54c68ea7e..c51327f26 100644 --- a/linux/drivers/media/video/gspca/mars.c +++ b/linux/drivers/media/video/gspca/mars.c @@ -32,16 +32,86 @@ MODULE_LICENSE("GPL"); /* specific webcam descriptor */ struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ + + u8 brightness; + u8 colors; + u8 gamma; + u8 sharpness; }; /* 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_setcolors(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getgamma(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 struct ctrl sd_ctrls[] = { + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 30, + .step = 1, +#define BRIGHTNESS_DEF 15 + .default_value = BRIGHTNESS_DEF, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, + { + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Color", + .minimum = 0, + .maximum = 220, + .step = 1, +#define COLOR_DEF 190 + .default_value = COLOR_DEF, + }, + .set = sd_setcolors, + .get = sd_getcolors, + }, + { + { + .id = V4L2_CID_GAMMA, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gamma", + .minimum = 0, + .maximum = 3, + .step = 1, +#define GAMMA_DEF 1 + .default_value = GAMMA_DEF, + }, + .set = sd_setgamma, + .get = sd_getgamma, + }, + { + { + .id = V4L2_CID_SHARPNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Sharpness", + .minimum = 0, + .maximum = 2, + .step = 1, +#define SHARPNESS_DEF 1 + .default_value = SHARPNESS_DEF, + }, + .set = sd_setsharpness, + .get = sd_getsharpness, + }, }; static const struct v4l2_pix_format vga_mode[] = { {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 589, + .sizeimage = 320 * 240 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 2}, {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, @@ -51,76 +121,62 @@ static const struct v4l2_pix_format vga_mode[] = { .priv = 1}, }; -/* MI Register table //elvis */ -enum { - REG_HW_MI_0, - REG_HW_MI_1, - REG_HW_MI_2, - REG_HW_MI_3, - REG_HW_MI_4, - REG_HW_MI_5, - REG_HW_MI_6, - REG_HW_MI_7, - REG_HW_MI_9 = 0x09, - REG_HW_MI_B = 0x0B, - REG_HW_MI_C, - REG_HW_MI_D, - REG_HW_MI_1E = 0x1E, - REG_HW_MI_20 = 0x20, - REG_HW_MI_2B = 0x2B, - REG_HW_MI_2C, - REG_HW_MI_2D, - REG_HW_MI_2E, - REG_HW_MI_35 = 0x35, - REG_HW_MI_5F = 0x5f, - REG_HW_MI_60, - REG_HW_MI_61, - REG_HW_MI_62, - REG_HW_MI_63, - REG_HW_MI_64, - REG_HW_MI_F1 = 0xf1, - ATTR_TOTAL_MI_REG = 0xf2 +static const __u8 mi_data[0x20] = { +/* 01 02 03 04 05 06 07 08 */ + 0x48, 0x22, 0x01, 0x47, 0x10, 0x00, 0x00, 0x00, +/* 09 0a 0b 0c 0d 0e 0f 10 */ + 0x00, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, +/* 11 12 13 14 15 16 17 18 */ + 0x30, 0x00, 0x04, 0x00, 0x06, 0x01, 0xe2, 0x02, +/* 19 1a 1b 1c 1d 1e 1f 20 */ + 0x82, 0x00, 0x20, 0x17, 0x80, 0x08, 0x0c, 0x00 }; -/* the bytes to write are in gspca_dev->usb_buf */ +/* write bytes from gspca_dev->usb_buf */ static int reg_w(struct gspca_dev *gspca_dev, - __u16 index, int len) + int len) { - int rc; - - rc = usb_control_msg(gspca_dev->dev, - usb_sndbulkpipe(gspca_dev->dev, 4), - 0x12, - 0xc8, /* ?? */ - 0, /* value */ - index, gspca_dev->usb_buf, len, 500); - if (rc < 0) - PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc); - return rc; + int alen, ret; + + ret = usb_bulk_msg(gspca_dev->dev, + usb_sndbulkpipe(gspca_dev->dev, 4), + gspca_dev->usb_buf, + len, + &alen, + 500); /* timeout in milliseconds */ + if (ret < 0) + PDEBUG(D_ERR, "reg write [%02x] error %d", + gspca_dev->usb_buf[0], ret); + return ret; } -static void bulk_w(struct gspca_dev *gspca_dev, - __u16 *pch, - __u16 Address) +static void mi_w(struct gspca_dev *gspca_dev, + u8 addr, + u8 value) { gspca_dev->usb_buf[0] = 0x1f; gspca_dev->usb_buf[1] = 0; /* control byte */ - gspca_dev->usb_buf[2] = Address; - gspca_dev->usb_buf[3] = *pch >> 8; /* high byte */ - gspca_dev->usb_buf[4] = *pch; /* low byte */ + gspca_dev->usb_buf[2] = addr; + gspca_dev->usb_buf[3] = value; - reg_w(gspca_dev, Address, 5); + reg_w(gspca_dev, 4); } /* 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; cam = &gspca_dev->cam; cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); + sd->brightness = BRIGHTNESS_DEF; + sd->colors = COLOR_DEF; + sd->gamma = GAMMA_DEF; + sd->sharpness = SHARPNESS_DEF; + gspca_dev->iface = 9; /* use the altsetting 08 */ return 0; } @@ -132,24 +188,16 @@ static int sd_init(struct gspca_dev *gspca_dev) static int sd_start(struct gspca_dev *gspca_dev) { + struct sd *sd = (struct sd *) gspca_dev; int err_code; - __u8 *data; - __u16 *MI_buf; - int h_size, v_size; - int intpipe; - - PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface); - err_code = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 8); - if (err_code < 0) { - PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error"); - return err_code; - } + u8 *data; + int i, val; data = gspca_dev->usb_buf; + data[0] = 0x01; /* address */ data[1] = 0x01; - - err_code = reg_w(gspca_dev, data[0], 2); + err_code = reg_w(gspca_dev, 2); if (err_code < 0) return err_code; @@ -159,30 +207,33 @@ static int sd_start(struct gspca_dev *gspca_dev) data[0] = 0x00; /* address */ data[1] = 0x0c | 0x01; /* reg 0 */ data[2] = 0x01; /* reg 1 */ - h_size = gspca_dev->width; - v_size = gspca_dev->height; - data[3] = h_size / 8; /* h_size , reg 2 */ - data[4] = v_size / 8; /* v_size , reg 3 */ + data[3] = gspca_dev->width / 8; /* h_size , reg 2 */ + data[4] = gspca_dev->height / 8; /* v_size , reg 3 */ data[5] = 0x30; /* reg 4, MI, PAS5101 : * 0x30 for 24mhz , 0x28 for 12mhz */ - data[6] = 4; /* reg 5, H start */ - data[7] = 0xc0; /* reg 6, gamma 1.5 */ - data[8] = 3; /* reg 7, V start */ + data[6] = 0x02; /* reg 5, H start - was 0x04 */ + data[7] = sd->gamma * 0x40; /* reg 0x06: gamma */ + data[8] = 0x01; /* reg 7, V start - was 0x03 */ /* if (h_size == 320 ) */ /* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */ /* else */ data[9] = 0x52; /* reg 8, 24MHz, no scale down */ +#if 1 +/*jfm: from win trace*/ + data[10] = 0x18; +#else data[10] = 0x5d; /* reg 9, I2C device address * [for PAS5101 (0x40)] [for MI (0x5d)] */ +#endif - err_code = reg_w(gspca_dev, data[0], 11); + err_code = reg_w(gspca_dev, 11); if (err_code < 0) return err_code; data[0] = 0x23; /* address */ data[1] = 0x09; /* reg 35, append frame header */ - err_code = reg_w(gspca_dev, data[0], 2); + err_code = reg_w(gspca_dev, 2); if (err_code < 0) return err_code; @@ -193,137 +244,88 @@ static int sd_start(struct gspca_dev *gspca_dev) /* else */ data[1] = 50; /* 50 reg 60, pc-cam frame size * (unit: 4KB) 200KB */ - err_code = reg_w(gspca_dev, data[0], 2); + err_code = reg_w(gspca_dev, 2); if (err_code < 0) return err_code; - if (0) { /* fixed dark-gain */ - data[1] = 0; /* reg 94, Y Gain (1.75) */ - data[2] = 0; /* reg 95, UV Gain (1.75) */ - data[3] = 0x3f; /* reg 96, Y Gain/UV Gain/disable - * auto dark-gain */ - data[4] = 0; /* reg 97, set fixed dark level */ - data[5] = 0; /* reg 98, don't care */ - } else { /* auto dark-gain */ - data[1] = 0; /* reg 94, Y Gain (auto) */ - data[2] = 0; /* reg 95, UV Gain (1.75) */ - data[3] = 0x78; /* reg 96, Y Gain/UV Gain/disable - * auto dark-gain */ - switch (gspca_dev->width) { -/* case 1280: */ -/* data[4] = 154; - * reg 97, %3 shadow point (unit: 256 pixel) */ -/* data[5] = 51; - * reg 98, %1 highlight point - * (uint: 256 pixel) */ -/* break; */ - default: -/* case 640: */ - data[4] = 36; /* reg 97, %3 shadow point - * (unit: 256 pixel) */ - data[5] = 12; /* reg 98, %1 highlight point - * (uint: 256 pixel) */ - break; - case 320: - data[4] = 9; /* reg 97, %3 shadow point - * (unit: 256 pixel) */ - data[5] = 3; /* reg 98, %1 highlight point - * (uint: 256 pixel) */ - break; - } - } /* auto dark-gain */ data[0] = 0x5e; /* address */ + data[1] = 0; /* reg 94, Y Gain (auto) */ +#if 1 +/*jfm: from win trace*/ + val = sd->colors * 0x40 + 0x400; + data[2] = val; /* reg 0x5f/0x60 (LE) = saturation */ + data[3] = val >> 8; + data[4] = sd->brightness; /* reg 0x61 = brightness */ + data[5] = 0x00; +#else + data[2] = 0; /* reg 95, UV Gain (1.75) */ + data[3] = 0x78; /* reg 96, Y Gain/UV Gain/disable + * auto dark-gain */ + switch (gspca_dev->width) { +/* case 1280: */ +/* data[4] = 154; + * reg 97, %3 shadow point (unit: 256 pixel) */ +/* data[5] = 51; + * reg 98, %1 highlight point + * (uint: 256 pixel) */ +/* break; */ + default: +/* case 640: */ + data[4] = 36; /* reg 97, %3 shadow point + * (unit: 256 pixel) */ + data[5] = 12; /* reg 98, %1 highlight point + * (uint: 256 pixel) */ + break; + case 320: + data[4] = 9; /* reg 97, %3 shadow point + * (unit: 256 pixel) */ + data[5] = 3; /* reg 98, %1 highlight point + * (uint: 256 pixel) */ + break; + } +#endif - err_code = reg_w(gspca_dev, data[0], 6); + err_code = reg_w(gspca_dev, 6); if (err_code < 0) return err_code; data[0] = 0x67; +#if 1 +/*jfm: from win trace*/ + data[1] = sd->sharpness * 4 + 3; + data[2] = 0x14; + err_code = reg_w(gspca_dev, 3); + if (err_code < 0) + return err_code; + + data[0] = 0x69; + data[1] = 0x2f; + data[2] = 0x28; + data[3] = 0x42; + err_code = reg_w(gspca_dev, 4); + if (err_code < 0) + return err_code; + + data[0] = 0x63; + data[1] = 0x07; + err_code = reg_w(gspca_dev, 2); +/*jfm: win trace - many writes here to reg 0x64*/ +#else data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */ - err_code = reg_w(gspca_dev, data[0], 2); + err_code = reg_w(gspca_dev, 2); +#endif if (err_code < 0) return err_code; - /* - * initialize the value of MI sensor... - */ - MI_buf = kzalloc(ATTR_TOTAL_MI_REG * sizeof *MI_buf, GFP_KERNEL); - MI_buf[REG_HW_MI_1] = 0x000a; - MI_buf[REG_HW_MI_2] = 0x000c; - MI_buf[REG_HW_MI_3] = 0x0405; - MI_buf[REG_HW_MI_4] = 0x0507; - /* mi_Attr_Reg_[REG_HW_MI_5] = 0x01ff;//13 */ - MI_buf[REG_HW_MI_5] = 0x0013; /* 13 */ - MI_buf[REG_HW_MI_6] = 0x001f; /* vertical blanking */ - /* mi_Attr_Reg_[REG_HW_MI_6] = 0x0400; // vertical blanking */ - MI_buf[REG_HW_MI_7] = 0x0002; - /* mi_Attr_Reg_[REG_HW_MI_9] = 0x015f; */ - /* mi_Attr_Reg_[REG_HW_MI_9] = 0x030f; */ - MI_buf[REG_HW_MI_9] = 0x0374; - MI_buf[REG_HW_MI_B] = 0x0000; - MI_buf[REG_HW_MI_C] = 0x0000; - MI_buf[REG_HW_MI_D] = 0x0000; - MI_buf[REG_HW_MI_1E] = 0x8000; -/* mi_Attr_Reg_[REG_HW_MI_20] = 0x1104; */ - MI_buf[REG_HW_MI_20] = 0x1104; /* 0x111c; */ - MI_buf[REG_HW_MI_2B] = 0x0008; -/* mi_Attr_Reg_[REG_HW_MI_2C] = 0x000f; */ - MI_buf[REG_HW_MI_2C] = 0x001f; /* lita suggest */ - MI_buf[REG_HW_MI_2D] = 0x0008; - MI_buf[REG_HW_MI_2E] = 0x0008; - MI_buf[REG_HW_MI_35] = 0x0051; - MI_buf[REG_HW_MI_5F] = 0x0904; /* fail to write */ - MI_buf[REG_HW_MI_60] = 0x0000; - MI_buf[REG_HW_MI_61] = 0x0000; - MI_buf[REG_HW_MI_62] = 0x0498; - MI_buf[REG_HW_MI_63] = 0x0000; - MI_buf[REG_HW_MI_64] = 0x0000; - MI_buf[REG_HW_MI_F1] = 0x0001; - /* changing while setting up the different value of dx/dy */ - - if (gspca_dev->width != 1280) { - MI_buf[0x01] = 0x010a; - MI_buf[0x02] = 0x014c; - MI_buf[0x03] = 0x01e5; - MI_buf[0x04] = 0x0287; - } - MI_buf[0x20] = 0x1104; - - bulk_w(gspca_dev, MI_buf + 1, 1); - bulk_w(gspca_dev, MI_buf + 2, 2); - bulk_w(gspca_dev, MI_buf + 3, 3); - bulk_w(gspca_dev, MI_buf + 4, 4); - bulk_w(gspca_dev, MI_buf + 5, 5); - bulk_w(gspca_dev, MI_buf + 6, 6); - bulk_w(gspca_dev, MI_buf + 7, 7); - bulk_w(gspca_dev, MI_buf + 9, 9); - bulk_w(gspca_dev, MI_buf + 0x0b, 0x0b); - bulk_w(gspca_dev, MI_buf + 0x0c, 0x0c); - bulk_w(gspca_dev, MI_buf + 0x0d, 0x0d); - bulk_w(gspca_dev, MI_buf + 0x1e, 0x1e); - bulk_w(gspca_dev, MI_buf + 0x20, 0x20); - bulk_w(gspca_dev, MI_buf + 0x2b, 0x2b); - bulk_w(gspca_dev, MI_buf + 0x2c, 0x2c); - bulk_w(gspca_dev, MI_buf + 0x2d, 0x2d); - bulk_w(gspca_dev, MI_buf + 0x2e, 0x2e); - bulk_w(gspca_dev, MI_buf + 0x35, 0x35); - bulk_w(gspca_dev, MI_buf + 0x5f, 0x5f); - bulk_w(gspca_dev, MI_buf + 0x60, 0x60); - bulk_w(gspca_dev, MI_buf + 0x61, 0x61); - bulk_w(gspca_dev, MI_buf + 0x62, 0x62); - bulk_w(gspca_dev, MI_buf + 0x63, 0x63); - bulk_w(gspca_dev, MI_buf + 0x64, 0x64); - bulk_w(gspca_dev, MI_buf + 0xf1, 0xf1); - kfree(MI_buf); - - intpipe = usb_sndintpipe(gspca_dev->dev, 0); - err_code = usb_clear_halt(gspca_dev->dev, intpipe); + /* initialize the MI sensor */ + for (i = 0; i < sizeof mi_data; i++) + mi_w(gspca_dev, i + 1, mi_data[i]); data[0] = 0x00; data[1] = 0x4d; /* ISOC transfering enable... */ - reg_w(gspca_dev, data[0], 2); - return err_code; + reg_w(gspca_dev, 2); + return 0; } static void sd_stopN(struct gspca_dev *gspca_dev) @@ -332,7 +334,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) gspca_dev->usb_buf[0] = 1; gspca_dev->usb_buf[1] = 0; - result = reg_w(gspca_dev, gspca_dev->usb_buf[0], 2); + result = reg_w(gspca_dev, 2); if (result < 0) PDEBUG(D_ERR, "Camera Stop failed"); } @@ -358,7 +360,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, || data[5 + p] == 0x65 || data[5 + p] == 0x66 || data[5 + p] == 0x67) { - PDEBUG(D_PACK, "sof offset: %d leng: %d", + PDEBUG(D_PACK, "sof offset: %d len: %d", p, len); frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); @@ -374,6 +376,92 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, 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) { + gspca_dev->usb_buf[0] = 0x61; + gspca_dev->usb_buf[1] = val; + reg_w(gspca_dev, 2); + } + 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_setcolors(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->colors = val; + if (gspca_dev->streaming) { + val = val * 0x40 + 0x400; + gspca_dev->usb_buf[0] = 0x5f; + gspca_dev->usb_buf[1] = val; + gspca_dev->usb_buf[2] = val >> 8; + reg_w(gspca_dev, 3); + } + 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_setgamma(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->gamma = val; + if (gspca_dev->streaming) { + gspca_dev->usb_buf[0] = 0x06; + gspca_dev->usb_buf[1] = val * 0x40; + reg_w(gspca_dev, 2); + } + return 0; +} + +static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->gamma; + 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) { + gspca_dev->usb_buf[0] = 0x67; + gspca_dev->usb_buf[1] = val * 4 + 3; + reg_w(gspca_dev, 2); + } + 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; +} + /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, @@ -416,6 +504,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 From 976d86691c5d5d9ecc516afc37357d024f9b314f Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 8 Jan 2009 20:30:58 +0100 Subject: gspca - mars: Bad isoc packet scanning. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/mars.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/mars.c b/linux/drivers/media/video/gspca/mars.c index c51327f26..a91e69c40 100644 --- a/linux/drivers/media/video/gspca/mars.c +++ b/linux/drivers/media/video/gspca/mars.c @@ -363,12 +363,12 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, PDEBUG(D_PACK, "sof offset: %d len: %d", p, len); frame = gspca_frame_add(gspca_dev, LAST_PACKET, - frame, data, 0); + frame, data, p); /* put the JPEG header */ jpeg_put_header(gspca_dev, frame, 0x21); - data += 16; - len -= 16; + data += p + 16; + len -= p + 16; break; } } -- cgit v1.2.3 From 6c69d1429f52dba16d0ed37ad632bdea237b5526 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 9 Jan 2009 13:13:26 +0100 Subject: gspca - tv8532: Cleanup code. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/tv8532.c | 479 +++++++++++++------------------ 1 file changed, 200 insertions(+), 279 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/tv8532.c b/linux/drivers/media/video/gspca/tv8532.c index 4ee13d3d8..024d798ad 100644 --- a/linux/drivers/media/video/gspca/tv8532.c +++ b/linux/drivers/media/video/gspca/tv8532.c @@ -31,7 +31,6 @@ struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ __u16 brightness; - __u16 contrast; __u8 packet; }; @@ -39,11 +38,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 struct ctrl sd_ctrls[] = { -#define SD_BRIGHTNESS 0 { { .id = V4L2_CID_BRIGHTNESS, @@ -52,25 +48,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 1, .maximum = 0x2ff, .step = 1, - .default_value = 0x18f, +#define BRIGHTNESS_DEF 0x18f + .default_value = BRIGHTNESS_DEF, }, .set = sd_setbrightness, .get = sd_getbrightness, }, -#define SD_CONTRAST 1 - { - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast", - .minimum = 0, - .maximum = 0xffff, - .step = 1, - .default_value = 0x7fff, - }, - .set = sd_setcontrast, - .get = sd_getcontrast, - }, }; static const struct v4l2_pix_format sif_mode[] = { @@ -86,78 +69,64 @@ static const struct v4l2_pix_format sif_mode[] = { .priv = 0}, }; -/* - * Initialization data: this is the first set-up data written to the - * device (before the open data). - */ -#define TESTCLK 0x10 /* reg 0x2c -> 0x12 //10 */ -#define TESTCOMP 0x90 /* reg 0x28 -> 0x80 */ -#define TESTLINE 0x81 /* reg 0x29 -> 0x81 */ -#define QCIFLINE 0x41 /* reg 0x29 -> 0x81 */ -#define TESTPTL 0x14 /* reg 0x2D -> 0x14 */ -#define TESTPTH 0x01 /* reg 0x2E -> 0x01 */ -#define TESTPTBL 0x12 /* reg 0x2F -> 0x0a */ -#define TESTPTBH 0x01 /* reg 0x30 -> 0x01 */ -#define ADWIDTHL 0xe8 /* reg 0x0c -> 0xe8 */ -#define ADWIDTHH 0x03 /* reg 0x0d -> 0x03 */ -#define ADHEIGHL 0x90 /* reg 0x0e -> 0x91 //93 */ -#define ADHEIGHH 0x01 /* reg 0x0f -> 0x01 */ -#define EXPOL 0x8f /* reg 0x1c -> 0x8f */ -#define EXPOH 0x01 /* reg 0x1d -> 0x01 */ -#define ADCBEGINL 0x44 /* reg 0x10 -> 0x46 //47 */ -#define ADCBEGINH 0x00 /* reg 0x11 -> 0x00 */ -#define ADRBEGINL 0x0a /* reg 0x14 -> 0x0b //0x0c */ -#define ADRBEGINH 0x00 /* reg 0x15 -> 0x00 */ -#define TV8532_CMD_UPDATE 0x84 - -#define TV8532_EEprom_Add 0x03 -#define TV8532_EEprom_DataL 0x04 -#define TV8532_EEprom_DataM 0x05 -#define TV8532_EEprom_DataH 0x06 -#define TV8532_EEprom_TableLength 0x07 -#define TV8532_EEprom_Write 0x08 -#define TV8532_PART_CTRL 0x00 -#define TV8532_CTRL 0x01 -#define TV8532_CMD_EEprom_Open 0x30 -#define TV8532_CMD_EEprom_Close 0x29 -#define TV8532_UDP_UPDATE 0x31 -#define TV8532_GPIO 0x39 -#define TV8532_GPIO_OE 0x3B -#define TV8532_REQ_RegWrite 0x02 -#define TV8532_REQ_RegRead 0x03 - -#define TV8532_ADWIDTH_L 0x0C -#define TV8532_ADWIDTH_H 0x0D -#define TV8532_ADHEIGHT_L 0x0E -#define TV8532_ADHEIGHT_H 0x0F -#define TV8532_EXPOSURE 0x1C -#define TV8532_QUANT_COMP 0x28 -#define TV8532_MODE_PACKET 0x29 -#define TV8532_SETCLK 0x2C -#define TV8532_POINT_L 0x2D -#define TV8532_POINT_H 0x2E -#define TV8532_POINTB_L 0x2F -#define TV8532_POINTB_H 0x30 -#define TV8532_BUDGET_L 0x2A -#define TV8532_BUDGET_H 0x2B -#define TV8532_VID_L 0x34 -#define TV8532_VID_H 0x35 -#define TV8532_PID_L 0x36 -#define TV8532_PID_H 0x37 -#define TV8532_DeviceID 0x83 -#define TV8532_AD_SLOPE 0x91 -#define TV8532_AD_BITCTRL 0x94 -#define TV8532_AD_COLBEGIN_L 0x10 -#define TV8532_AD_COLBEGIN_H 0x11 -#define TV8532_AD_ROWBEGIN_L 0x14 -#define TV8532_AD_ROWBEGIN_H 0x15 - -static const __u32 tv_8532_eeprom_data[] = { -/* add dataL dataM dataH */ - 0x00010001, 0x01018011, 0x02050014, 0x0305001c, - 0x040d001e, 0x0505001f, 0x06050519, 0x0705011b, - 0x0805091e, 0x090d892e, 0x0a05892f, 0x0b050dd9, - 0x0c0509f1, 0 +/* TV-8532A (ICM532A) registers (LE) */ +#define R00_PART_CONTROL 0x00 +#define LATENT_CHANGE 0x80 +#define EXPO_CHANGE 0x04 +#define R01_TIMING_CONTROL_LOW 0x01 +#define CMD_EEprom_Open 0x30 +#define CMD_EEprom_Close 0x29 +#define R03_TABLE_ADDR 0x03 +#define R04_WTRAM_DATA_L 0x04 +#define R05_WTRAM_DATA_M 0x05 +#define R06_WTRAM_DATA_H 0x06 +#define R07_TABLE_LEN 0x07 +#define R08_RAM_WRITE_ACTION 0x08 +#define R0C_AD_WIDTHL 0x0c +#define R0D_AD_WIDTHH 0x0d +#define R0E_AD_HEIGHTL 0x0e +#define R0F_AD_HEIGHTH 0x0f +#define R10_AD_COL_BEGINL 0x10 +#define R11_AD_COL_BEGINH 0x11 +#define MIRROR 0x04 /* [10] */ +#define R14_AD_ROW_BEGINL 0x14 +#define R15_AD_ROWBEGINH 0x15 +#define R1C_AD_EXPOSE_TIMEL 0x1c +#define R28_QUANT 0x28 +#define R29_LINE 0x29 +#define R2C_POLARITY 0x2c +#define R2D_POINT 0x2d +#define R2E_POINTH 0x2e +#define R2F_POINTB 0x2f +#define R30_POINTBH 0x30 +#define R31_UPD 0x31 +#define R2A_HIGH_BUDGET 0x2a +#define R2B_LOW_BUDGET 0x2b +#define R34_VID 0x34 +#define R35_VIDH 0x35 +#define R36_PID 0x36 +#define R37_PIDH 0x37 +#define R39_Test1 0x39 /* GPIO */ +#define R3B_Test3 0x3B /* GPIO */ +#define R83_AD_IDH 0x83 +#define R91_AD_SLOPEREG 0x91 +#define R94_AD_BITCONTROL 0x94 + +static const u8 eeprom_data[][3] = { +/* dataH dataM dataL */ + {0x01, 0x00, 0x01}, + {0x01, 0x80, 0x11}, + {0x05, 0x00, 0x14}, + {0x05, 0x00, 0x1c}, + {0x0d, 0x00, 0x1e}, + {0x05, 0x00, 0x1f}, + {0x05, 0x05, 0x19}, + {0x05, 0x01, 0x1b}, + {0x05, 0x09, 0x1e}, + {0x0d, 0x89, 0x2e}, + {0x05, 0x89, 0x2f}, + {0x05, 0x0d, 0xd9}, + {0x05, 0x09, 0xf1}, }; static int reg_r(struct gspca_dev *gspca_dev, @@ -165,7 +134,7 @@ static int reg_r(struct gspca_dev *gspca_dev, { usb_control_msg(gspca_dev->dev, usb_rcvctrlpipe(gspca_dev->dev, 0), - TV8532_REQ_RegRead, + 0x03, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ index, gspca_dev->usb_buf, 1, @@ -174,27 +143,27 @@ static int reg_r(struct gspca_dev *gspca_dev, } /* write 1 byte */ -static void reg_w_1(struct gspca_dev *gspca_dev, +static void reg_w1(struct gspca_dev *gspca_dev, __u16 index, __u8 value) { gspca_dev->usb_buf[0] = value; usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), - TV8532_REQ_RegWrite, + 0x02, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ index, gspca_dev->usb_buf, 1, 500); } /* write 2 bytes */ -static void reg_w_2(struct gspca_dev *gspca_dev, - __u16 index, __u8 val1, __u8 val2) +static void reg_w2(struct gspca_dev *gspca_dev, + u16 index, u16 value) { - gspca_dev->usb_buf[0] = val1; - gspca_dev->usb_buf[1] = val2; + gspca_dev->usb_buf[0] = value; + gspca_dev->usb_buf[1] = value >> 8; usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), - TV8532_REQ_RegWrite, + 0x02, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ index, gspca_dev->usb_buf, 2, 500); @@ -202,32 +171,18 @@ static void reg_w_2(struct gspca_dev *gspca_dev, static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev) { - int i = 0; - __u8 reg, data0, data1, data2; - - reg_w_1(gspca_dev, TV8532_GPIO, 0xb0); - reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Open); -/* msleep(1); */ - while (tv_8532_eeprom_data[i]) { - reg = (tv_8532_eeprom_data[i] & 0xff000000) >> 24; - reg_w_1(gspca_dev, TV8532_EEprom_Add, reg); - /* msleep(1); */ - data0 = (tv_8532_eeprom_data[i] & 0x000000ff); - reg_w_1(gspca_dev, TV8532_EEprom_DataL, data0); - /* msleep(1); */ - data1 = (tv_8532_eeprom_data[i] & 0x0000ff00) >> 8; - reg_w_1(gspca_dev, TV8532_EEprom_DataM, data1); - /* msleep(1); */ - data2 = (tv_8532_eeprom_data[i] & 0x00ff0000) >> 16; - reg_w_1(gspca_dev, TV8532_EEprom_DataH, data2); - /* msleep(1); */ - reg_w_1(gspca_dev, TV8532_EEprom_Write, 0); - /* msleep(10); */ - i++; + int i; + + reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Open); + for (i = 0; i < ARRAY_SIZE(eeprom_data); i++) { + reg_w1(gspca_dev, R03_TABLE_ADDR, i); + reg_w1(gspca_dev, R04_WTRAM_DATA_L, eeprom_data[i][2]); + reg_w1(gspca_dev, R05_WTRAM_DATA_M, eeprom_data[i][1]); + reg_w1(gspca_dev, R06_WTRAM_DATA_H, eeprom_data[i][0]); + reg_w1(gspca_dev, R08_RAM_WRITE_ACTION, 0); } - reg_w_1(gspca_dev, TV8532_EEprom_TableLength, i); -/* msleep(1); */ - reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Close); + reg_w1(gspca_dev, R07_TABLE_LEN, i); + reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Close); msleep(10); } @@ -238,78 +193,82 @@ static int sd_config(struct gspca_dev *gspca_dev, struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - tv_8532WriteEEprom(gspca_dev); - cam = &gspca_dev->cam; cam->cam_mode = sif_mode; - cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; + cam->nmodes = ARRAY_SIZE(sif_mode); - sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; - sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; + sd->brightness = BRIGHTNESS_DEF; return 0; } static void tv_8532ReadRegisters(struct gspca_dev *gspca_dev) { - __u8 data; + int i; + static u8 reg_tb[] = { + R0C_AD_WIDTHL, + R0D_AD_WIDTHH, + R28_QUANT, + R29_LINE, + R2C_POLARITY, + R2D_POINT, + R2E_POINTH, + R2F_POINTB, + R30_POINTBH, + R2A_HIGH_BUDGET, + R2B_LOW_BUDGET, + R34_VID, + R35_VIDH, + R36_PID, + R37_PIDH, + R83_AD_IDH, + R10_AD_COL_BEGINL, + R11_AD_COL_BEGINH, + R14_AD_ROW_BEGINL, + R15_AD_ROWBEGINH, + 0 + }; +#if 0 data = reg_r(gspca_dev, 0x0001); PDEBUG(D_USBI, "register 0x01-> %x", data); data = reg_r(gspca_dev, 0x0002); PDEBUG(D_USBI, "register 0x02-> %x", data); - reg_r(gspca_dev, TV8532_ADWIDTH_L); - reg_r(gspca_dev, TV8532_ADWIDTH_H); - reg_r(gspca_dev, TV8532_QUANT_COMP); - reg_r(gspca_dev, TV8532_MODE_PACKET); - reg_r(gspca_dev, TV8532_SETCLK); - reg_r(gspca_dev, TV8532_POINT_L); - reg_r(gspca_dev, TV8532_POINT_H); - reg_r(gspca_dev, TV8532_POINTB_L); - reg_r(gspca_dev, TV8532_POINTB_H); - reg_r(gspca_dev, TV8532_BUDGET_L); - reg_r(gspca_dev, TV8532_BUDGET_H); - reg_r(gspca_dev, TV8532_VID_L); - reg_r(gspca_dev, TV8532_VID_H); - reg_r(gspca_dev, TV8532_PID_L); - reg_r(gspca_dev, TV8532_PID_H); - reg_r(gspca_dev, TV8532_DeviceID); - reg_r(gspca_dev, TV8532_AD_COLBEGIN_L); - reg_r(gspca_dev, TV8532_AD_COLBEGIN_H); - reg_r(gspca_dev, TV8532_AD_ROWBEGIN_L); - reg_r(gspca_dev, TV8532_AD_ROWBEGIN_H); +#endif + i = 0; + do { + reg_r(gspca_dev, reg_tb[i]); + i++; + } while (reg_tb[i] != 0); } static void tv_8532_setReg(struct gspca_dev *gspca_dev) { - reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L, - ADCBEGINL); /* 0x10 */ - reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H, - ADCBEGINH); /* also digital gain */ - reg_w_1(gspca_dev, TV8532_PART_CTRL, - TV8532_CMD_UPDATE); /* 0x00<-0x84 */ - - reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0a); + reg_w1(gspca_dev, R10_AD_COL_BEGINL, 0x44); + /* begin active line */ + reg_w1(gspca_dev, R11_AD_COL_BEGINH, 0x00); + /* mirror and digital gain */ + reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE); + /* = 0x84 */ + + reg_w1(gspca_dev, R3B_Test3, 0x0a); /* Test0Sel = 10 */ /******************************************************/ - reg_w_1(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL); /* 0e */ - reg_w_1(gspca_dev, TV8532_ADHEIGHT_H, ADHEIGHH); /* 0f */ - reg_w_2(gspca_dev, TV8532_EXPOSURE, - EXPOL, EXPOH); /* 350d 0x014c; 1c */ - reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L, - ADCBEGINL); /* 0x10 */ - reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H, - ADCBEGINH); /* also digital gain */ - reg_w_1(gspca_dev, TV8532_AD_ROWBEGIN_L, - ADRBEGINL); /* 0x14 */ - - reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */ - reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x02); /* 0x94 */ - - reg_w_1(gspca_dev, TV8532_CTRL, - TV8532_CMD_EEprom_Close); /* 0x01 */ - - reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */ - reg_w_1(gspca_dev, TV8532_PART_CTRL, - TV8532_CMD_UPDATE); /* 0x00<-0x84 */ + reg_w1(gspca_dev, R0E_AD_HEIGHTL, 0x90); + reg_w1(gspca_dev, R0F_AD_HEIGHTH, 0x01); + reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, 0x018f); + reg_w1(gspca_dev, R10_AD_COL_BEGINL, 0x44); + /* begin active line */ + reg_w1(gspca_dev, R11_AD_COL_BEGINH, 0x00); + /* mirror and digital gain */ + reg_w1(gspca_dev, R14_AD_ROW_BEGINL, 0x0a); + + reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x00); + reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x02); + + reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Close); + + reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x00); + reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE); + /* = 0x84 */ } static void tv_8532_PollReg(struct gspca_dev *gspca_dev) @@ -318,54 +277,55 @@ static void tv_8532_PollReg(struct gspca_dev *gspca_dev) /* strange polling from tgc */ for (i = 0; i < 10; i++) { - reg_w_1(gspca_dev, TV8532_SETCLK, - TESTCLK); /* 0x48; //0x08; 0x2c */ - reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE); - reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */ + reg_w1(gspca_dev, R2C_POLARITY, 0x10); + reg_w1(gspca_dev, R00_PART_CONTROL, + LATENT_CHANGE | EXPO_CHANGE); + reg_w1(gspca_dev, R31_UPD, 0x01); } } /* this function is called at probe and resume time */ static int sd_init(struct gspca_dev *gspca_dev) { - reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32); - reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00); + tv_8532WriteEEprom(gspca_dev); + + reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x32); /* slope begin 1,7V, + * slope rate 2 */ + reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x00); tv_8532ReadRegisters(gspca_dev); - reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); - reg_w_2(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL, - ADHEIGHH); /* 401d 0x0169; 0e */ - reg_w_2(gspca_dev, TV8532_EXPOSURE, EXPOL, - EXPOH); /* 350d 0x014c; 1c */ - reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */ - reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */ + reg_w1(gspca_dev, R3B_Test3, 0x0b); + reg_w2(gspca_dev, R0E_AD_HEIGHTL, 0x0190); + reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, 0x018f); + reg_w1(gspca_dev, R0C_AD_WIDTHL, 0xe8); + reg_w1(gspca_dev, R0D_AD_WIDTHH, 0x03); /*******************************************************************/ - reg_w_1(gspca_dev, TV8532_QUANT_COMP, - TESTCOMP); /* 0x72 compressed mode 0x28 */ - reg_w_1(gspca_dev, TV8532_MODE_PACKET, - TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */ + reg_w1(gspca_dev, R28_QUANT, 0x90); + /* no compress - fixed Q - quant 0 */ + reg_w1(gspca_dev, R29_LINE, 0x81); + /* 0x84; // CIF | 4 packet 0x29 */ /************************************************/ - reg_w_1(gspca_dev, TV8532_SETCLK, - TESTCLK); /* 0x48; //0x08; 0x2c */ - reg_w_1(gspca_dev, TV8532_POINT_L, - TESTPTL); /* 0x38; 0x2d */ - reg_w_1(gspca_dev, TV8532_POINT_H, - TESTPTH); /* 0x04; 0x2e */ - reg_w_1(gspca_dev, TV8532_POINTB_L, - TESTPTBL); /* 0x04; 0x2f */ - reg_w_1(gspca_dev, TV8532_POINTB_H, - TESTPTBH); /* 0x04; 0x30 */ - reg_w_1(gspca_dev, TV8532_PART_CTRL, - TV8532_CMD_UPDATE); /* 0x00<-0x84 */ + reg_w1(gspca_dev, R2C_POLARITY, 0x10); + /* 0x48; //0x08; 0x2c */ + reg_w1(gspca_dev, R2D_POINT, 0x14); + /* 0x38; 0x2d */ + reg_w1(gspca_dev, R2E_POINTH, 0x01); + /* 0x04; 0x2e */ + reg_w1(gspca_dev, R2F_POINTB, 0x12); + /* 0x04; 0x2f */ + reg_w1(gspca_dev, R30_POINTBH, 0x01); + /* 0x04; 0x30 */ + reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE); + /* 0x00<-0x84 */ /*************************************************/ - reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */ + reg_w1(gspca_dev, R31_UPD, 0x01); /* update registers */ msleep(200); - reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ + reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */ /*************************************************/ tv_8532_setReg(gspca_dev); /*************************************************/ - reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); + reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */ /*************************************************/ tv_8532_setReg(gspca_dev); /*************************************************/ @@ -376,11 +336,10 @@ static int sd_init(struct gspca_dev *gspca_dev) static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - int brightness = sd->brightness; - reg_w_2(gspca_dev, TV8532_EXPOSURE, - brightness >> 8, brightness); /* 1c */ - reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE); + reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, sd->brightness); + reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE); + /* 0x84 */ } /* -- start the camera -- */ @@ -388,57 +347,50 @@ static int sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32); - reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00); + reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x32); /* slope begin 1,7V, + * slope rate 2 */ + reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x00); tv_8532ReadRegisters(gspca_dev); - reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); - reg_w_2(gspca_dev, TV8532_ADHEIGHT_L, - ADHEIGHL, ADHEIGHH); /* 401d 0x0169; 0e */ -/* reg_w_2(gspca_dev, TV8532_EXPOSURE, - EXPOL, EXPOH); * 350d 0x014c; 1c */ + reg_w1(gspca_dev, R3B_Test3, 0x0b); + + reg_w2(gspca_dev, R0E_AD_HEIGHTL, 0x0190); setbrightness(gspca_dev); - reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */ - reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */ + reg_w1(gspca_dev, R0C_AD_WIDTHL, 0xe8); /* 0x20; 0x0c */ + reg_w1(gspca_dev, R0D_AD_WIDTHH, 0x03); /************************************************/ - reg_w_1(gspca_dev, TV8532_QUANT_COMP, - TESTCOMP); /* 0x72 compressed mode 0x28 */ + reg_w1(gspca_dev, R28_QUANT, 0x90); + /* 0x72 compressed mode 0x28 */ if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { /* 176x144 */ - reg_w_1(gspca_dev, TV8532_MODE_PACKET, - QCIFLINE); /* 0x84; // CIF | 4 packet 0x29 */ + reg_w1(gspca_dev, R29_LINE, 0x41); + /* CIF - 2 lines/packet */ } else { /* 352x288 */ - reg_w_1(gspca_dev, TV8532_MODE_PACKET, - TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */ + reg_w1(gspca_dev, R29_LINE, 0x81); + /* CIF - 2 lines/packet */ } /************************************************/ - reg_w_1(gspca_dev, TV8532_SETCLK, - TESTCLK); /* 0x48; //0x08; 0x2c */ - reg_w_1(gspca_dev, TV8532_POINT_L, - TESTPTL); /* 0x38; 0x2d */ - reg_w_1(gspca_dev, TV8532_POINT_H, - TESTPTH); /* 0x04; 0x2e */ - reg_w_1(gspca_dev, TV8532_POINTB_L, - TESTPTBL); /* 0x04; 0x2f */ - reg_w_1(gspca_dev, TV8532_POINTB_H, - TESTPTBH); /* 0x04; 0x30 */ - reg_w_1(gspca_dev, TV8532_PART_CTRL, - TV8532_CMD_UPDATE); /* 0x00<-0x84 */ + reg_w1(gspca_dev, R2C_POLARITY, 0x10); /* slow clock */ + reg_w1(gspca_dev, R2D_POINT, 0x14); + reg_w1(gspca_dev, R2E_POINTH, 0x01); + reg_w1(gspca_dev, R2F_POINTB, 0x12); + reg_w1(gspca_dev, R30_POINTBH, 0x01); + reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE); /************************************************/ - reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */ + reg_w1(gspca_dev, R31_UPD, 0x01); /* update registers */ msleep(200); - reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ + reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */ /************************************************/ tv_8532_setReg(gspca_dev); /************************************************/ - reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); + reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */ /************************************************/ tv_8532_setReg(gspca_dev); /************************************************/ tv_8532_PollReg(gspca_dev); - reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ + reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */ gspca_dev->empty_packet = 0; /* check the empty packets */ sd->packet = 0; /* ignore the first packets */ @@ -448,7 +400,7 @@ static int sd_start(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev) { - reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); + reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */ } static void sd_pkt_scan(struct gspca_dev *gspca_dev, @@ -472,9 +424,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, /* each packet contains: * - header 2 bytes - * - RG line + * - RGRG line * - 4 bytes - * - GB line + * - GBGB line * - 4 bytes */ gspca_frame_add(gspca_dev, packet_type0, @@ -483,19 +435,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, frame, data + gspca_dev->width + 6, gspca_dev->width); } -static void setcontrast(struct gspca_dev *gspca_dev) -{ -#if 0 - value[0] = (gspca_dev->contrast) & 0xff; - value[1] = (gspca_dev->contrast >> 8) & 0xff; - reg_w_1(gspca_dev, 0x0020, value[1]); - reg_w_1(gspca_dev, 0x0022, value[1]); - reg_w_1(gspca_dev, 0x0024, value[1]); - reg_w_1(gspca_dev, 0x0026, value[1]); - reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE); -#endif -} - static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -514,24 +453,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) 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; -} - /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, -- cgit v1.2.3 From 1ce7e8070683daa9537beb9754d011392a4551c3 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 10 Jan 2009 19:54:44 +0100 Subject: gspca - spca508: Cleanup code. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/spca508.c | 124 ++++++++++++++---------------- 1 file changed, 56 insertions(+), 68 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/spca508.c b/linux/drivers/media/video/gspca/spca508.c index 0109ab132..9a403acfe 100644 --- a/linux/drivers/media/video/gspca/spca508.c +++ b/linux/drivers/media/video/gspca/spca508.c @@ -101,8 +101,7 @@ static const struct v4l2_pix_format sif_mode[] = { * Initialization data: this is the first set-up data written to the * device (before the open data). */ -static const __u16 spca508_init_data[][3] = -#define IGN(x) /* nothing */ +static const u16 spca508_init_data[][2] = { /* line URB value, index */ /* 44274 1804 */ {0x0000, 0x870b}, @@ -616,20 +615,10 @@ static const __u16 spca508_init_data[][3] = {} }; -#if 0 -/* - * Data to initialize the camera using the internal CCD - */ -static const __u16 spca508_open_data[][3] = { - /* line bmRequest,value,index */ - {} -}; -#endif - /* * Initialization data for Intel EasyPC Camera CS110 */ -static const __u16 spca508cs110_init_data[][3] = { +static const u16 spca508cs110_init_data[][2] = { {0x0000, 0x870b}, /* Reset CTL3 */ {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ {0x0000, 0x8111}, /* Normal operation on reset */ @@ -713,7 +702,7 @@ static const __u16 spca508cs110_init_data[][3] = { {} }; -static const __u16 spca508_sightcam_init_data[][3] = { +static const u16 spca508_sightcam_init_data[][2] = { /* This line seems to setup the frame/canvas */ /*368 */ {0x000f, 0x8402}, @@ -796,8 +785,7 @@ static const __u16 spca508_sightcam_init_data[][3] = { {} }; -static const __u16 spca508_sightcam2_init_data[][3] = { -#if 1 +static const u16 spca508_sightcam2_init_data[][2] = { /* 35 */ {0x0020, 0x8112}, /* 36 */ {0x000f, 0x8402}, @@ -1138,14 +1126,13 @@ static const __u16 spca508_sightcam2_init_data[][3] = { /* since it has been build into the driver */ /* jfm: don't start now */ /* 590 * {0x0030, 0x8112}, */ -#endif {} }; /* * Initialization data for Creative Webcam Vista */ -static const __u16 spca508_vista_init_data[][3] = { +static const u16 spca508_vista_init_data[][2] = { {0x0008, 0x8200}, /* Clear register */ {0x0000, 0x870b}, /* Reset CTL3 */ {0x0020, 0x8112}, /* Video Drop packet enable */ @@ -1347,18 +1334,18 @@ static const __u16 spca508_vista_init_data[][3] = { {0x0050, 0x8703}, {0x0002, 0x8704}, /* External input CKIx1 */ - {0x0001, 0x870C}, /* Select CKOx2 output */ - {0x009A, 0x8600}, /* Line memory Read Counter (L) */ + {0x0001, 0x870c}, /* Select CKOx2 output */ + {0x009a, 0x8600}, /* Line memory Read Counter (L) */ {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ {0x0023, 0x8601}, {0x0010, 0x8602}, - {0x000A, 0x8603}, + {0x000a, 0x8603}, {0x009A, 0x8600}, - {0x0001, 0x865B}, /* 1 Horizontal Offset for Valid Pixel(L) */ - {0x0003, 0x865C}, /* Vertical offset for valid lines (L) */ - {0x0058, 0x865D}, /* Horizontal valid pixels window (L) */ - {0x0048, 0x865E}, /* Vertical valid lines window (L) */ - {0x0000, 0x865F}, + {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ + {0x0003, 0x865c}, /* Vertical offset for valid lines (L) */ + {0x0058, 0x865d}, /* Horizontal valid pixels window (L) */ + {0x0048, 0x865e}, /* Vertical valid lines window (L) */ + {0x0000, 0x865f}, {0x0006, 0x8660}, /* Enable nibble data input, select nibble input order */ @@ -1366,63 +1353,63 @@ static const __u16 spca508_vista_init_data[][3] = { {0x0013, 0x8608}, /* A11 Coeficients for color correction */ {0x0028, 0x8609}, /* Note: these values are confirmed at the end of array */ - {0x0005, 0x860A}, /* ... */ - {0x0025, 0x860B}, - {0x00E1, 0x860C}, - {0x00FA, 0x860D}, - {0x00F4, 0x860E}, - {0x00E8, 0x860F}, + {0x0005, 0x860a}, /* ... */ + {0x0025, 0x860b}, + {0x00e1, 0x860c}, + {0x00fa, 0x860D}, + {0x00f4, 0x860e}, + {0x00e8, 0x860f}, {0x0025, 0x8610}, /* A33 Coef. */ - {0x00FC, 0x8611}, /* White balance offset: R */ + {0x00fc, 0x8611}, /* White balance offset: R */ {0x0001, 0x8612}, /* White balance offset: Gr */ - {0x00FE, 0x8613}, /* White balance offset: B */ + {0x00fe, 0x8613}, /* White balance offset: B */ {0x0000, 0x8614}, /* White balance offset: Gb */ {0x0064, 0x8651}, /* R gain for white balance (L) */ {0x0040, 0x8652}, /* Gr gain for white balance (L) */ {0x0066, 0x8653}, /* B gain for white balance (L) */ {0x0040, 0x8654}, /* Gb gain for white balance (L) */ - {0x0001, 0x863F}, /* Enable fixed gamma correction */ + {0x0001, 0x863f}, /* Enable fixed gamma correction */ - {0x00A1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */ + {0x00a1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */ /* UV division: UV no change, Enable New edge enhancement */ {0x0018, 0x8657}, /* Edge gain high threshold */ {0x0020, 0x8658}, /* Edge gain low threshold */ {0x000A, 0x8659}, /* Edge bandwidth high threshold */ - {0x0005, 0x865A}, /* Edge bandwidth low threshold */ + {0x0005, 0x865a}, /* Edge bandwidth low threshold */ {0x0064, 0x8607}, /* UV filter enable */ {0x0016, 0x8660}, - {0x0000, 0x86B0}, /* Bad pixels compensation address */ - {0x00DC, 0x86B1}, /* X coord for bad pixels compensation (L) */ - {0x0000, 0x86B2}, - {0x0009, 0x86B3}, /* Y coord for bad pixels compensation (L) */ - {0x0000, 0x86B4}, - - {0x0001, 0x86B0}, - {0x00F5, 0x86B1}, - {0x0000, 0x86B2}, - {0x00C6, 0x86B3}, - {0x0000, 0x86B4}, - - {0x0002, 0x86B0}, - {0x001C, 0x86B1}, - {0x0001, 0x86B2}, - {0x00D7, 0x86B3}, - {0x0000, 0x86B4}, - - {0x0003, 0x86B0}, - {0x001C, 0x86B1}, - {0x0001, 0x86B2}, - {0x00D8, 0x86B3}, - {0x0000, 0x86B4}, - - {0x0004, 0x86B0}, - {0x001D, 0x86B1}, - {0x0001, 0x86B2}, - {0x00D8, 0x86B3}, - {0x0000, 0x86B4}, - {0x001E, 0x8660}, + {0x0000, 0x86b0}, /* Bad pixels compensation address */ + {0x00dc, 0x86b1}, /* X coord for bad pixels compensation (L) */ + {0x0000, 0x86b2}, + {0x0009, 0x86b3}, /* Y coord for bad pixels compensation (L) */ + {0x0000, 0x86b4}, + + {0x0001, 0x86b0}, + {0x00f5, 0x86b1}, + {0x0000, 0x86b2}, + {0x00c6, 0x86b3}, + {0x0000, 0x86b4}, + + {0x0002, 0x86b0}, + {0x001c, 0x86b1}, + {0x0001, 0x86b2}, + {0x00d7, 0x86b3}, + {0x0000, 0x86b4}, + + {0x0003, 0x86b0}, + {0x001c, 0x86b1}, + {0x0001, 0x86b2}, + {0x00d8, 0x86b3}, + {0x0000, 0x86b4}, + + {0x0004, 0x86b0}, + {0x001d, 0x86b1}, + {0x0001, 0x86b2}, + {0x00d8, 0x86b3}, + {0x0000, 0x86b4}, + {0x001e, 0x8660}, /* READ { 0, 0x0000, 0x8608 } -> 0000: 13 */ @@ -1487,7 +1474,7 @@ static int reg_read(struct gspca_dev *gspca_dev, } static int write_vector(struct gspca_dev *gspca_dev, - const __u16 data[][3]) + const u16 data[][2]) { struct usb_device *dev = gspca_dev->dev; int ret, i = 0; @@ -1704,6 +1691,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 From 090f6baf5cf3eea5a88f5c48269bd8b2918c72a2 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 10 Jan 2009 20:11:25 +0100 Subject: gspca - some subdrivers: Don't get the control values from the webcam. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/etoms.c | 29 --------------- linux/drivers/media/video/gspca/spca500.c | 33 ----------------- linux/drivers/media/video/gspca/spca501.c | 38 -------------------- linux/drivers/media/video/gspca/spca505.c | 9 ----- linux/drivers/media/video/gspca/spca506.c | 50 -------------------------- linux/drivers/media/video/gspca/spca508.c | 8 ----- linux/drivers/media/video/gspca/sunplus.c | 59 ------------------------------- 7 files changed, 226 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/etoms.c b/linux/drivers/media/video/gspca/etoms.c index 7e69d7bed..84f3a5eb8 100644 --- a/linux/drivers/media/video/gspca/etoms.c +++ b/linux/drivers/media/video/gspca/etoms.c @@ -472,19 +472,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) reg_w_val(gspca_dev, ET_O_RED + i, brightness); } -static void getbrightness(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i; - int brightness = 0; - - for (i = 0; i < 4; i++) { - reg_r(gspca_dev, ET_O_RED + i, 1); - brightness += gspca_dev->usb_buf[0]; - } - sd->brightness = brightness >> 3; -} - static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -495,19 +482,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) reg_w(gspca_dev, ET_G_RED, RGBG, 6); } -static void getcontrast(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i; - int contrast = 0; - - for (i = 0; i < 4; i++) { - reg_r(gspca_dev, ET_G_RED + i, 1); - contrast += gspca_dev->usb_buf[0]; - } - sd->contrast = contrast >> 2; -} - static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -826,7 +800,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - getbrightness(gspca_dev); *val = sd->brightness; return 0; } @@ -845,7 +818,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - getcontrast(gspca_dev); *val = sd->contrast; return 0; } @@ -864,7 +836,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - getcolors(gspca_dev); *val = sd->colors; return 0; } diff --git a/linux/drivers/media/video/gspca/spca500.c b/linux/drivers/media/video/gspca/spca500.c index 0f91c5173..61b127022 100644 --- a/linux/drivers/media/video/gspca/spca500.c +++ b/linux/drivers/media/video/gspca/spca500.c @@ -952,16 +952,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) (__u8) (sd->brightness - 128)); } -static void getbrightness(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int ret; - - ret = reg_r_12(gspca_dev, 0x00, 0x8167, 1); - if (ret >= 0) - sd->brightness = ret + 128; -} - static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -969,16 +959,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x00, 0x8168, sd->contrast); } -static void getcontrast(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int ret; - - ret = reg_r_12(gspca_dev, 0x0, 0x8168, 1); - if (ret >= 0) - sd->contrast = ret; -} - static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -986,16 +966,6 @@ static void setcolors(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x00, 0x8169, sd->colors); } -static void getcolors(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int ret; - - ret = reg_r_12(gspca_dev, 0x0, 0x8169, 1); - if (ret >= 0) - sd->colors = ret; -} - static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -1010,7 +980,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - getbrightness(gspca_dev); *val = sd->brightness; return 0; } @@ -1029,7 +998,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - getcontrast(gspca_dev); *val = sd->contrast; return 0; } @@ -1048,7 +1016,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - getcolors(gspca_dev); *val = sd->colors; return 0; } diff --git a/linux/drivers/media/video/gspca/spca501.c b/linux/drivers/media/video/gspca/spca501.c index 1caf45ae4..61dfc714f 100644 --- a/linux/drivers/media/video/gspca/spca501.c +++ b/linux/drivers/media/video/gspca/spca501.c @@ -1908,17 +1908,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, sd->brightness); } -static void getbrightness(struct gspca_dev *gspca_dev) -{ -#if 0 - struct sd *sd = (struct sd *) gspca_dev; - __u16 brightness; - - brightness = reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x12, 2); - sd->brightness = brightness; -#endif -} - static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1929,21 +1918,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) sd->contrast & 0xff); } -static void getcontrast(struct gspca_dev *gspca_dev) -{ -#if 0 - __u8 byte = 0; - byte = (reg_read(gspca_dev, - 0x00, - 0x00, - 1) & 0xff) << 8; - ss->contrast = byte | (reg_read(gspca_dev, - 0x00, - 0x01, - 1) & 0xff); -#endif -} - static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1951,15 +1925,6 @@ static void setcolors(struct gspca_dev *gspca_dev) reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, sd->colors); } -static void getcolors(struct gspca_dev *gspca_dev) -{ -#if 0 - struct sd *sd = (struct sd *) gspca_dev; - - sd->colors = reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x0c, 2); -#endif -} - static void setblue_balance(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -2131,7 +2096,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - getbrightness(gspca_dev); *val = sd->brightness; return 0; } @@ -2150,7 +2114,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - getcontrast(gspca_dev); *val = sd->contrast; return 0; } @@ -2169,7 +2132,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - getcolors(gspca_dev); *val = sd->colors; return 0; } diff --git a/linux/drivers/media/video/gspca/spca505.c b/linux/drivers/media/video/gspca/spca505.c index c7a23f237..d997cdedc 100644 --- a/linux/drivers/media/video/gspca/spca505.c +++ b/linux/drivers/media/video/gspca/spca505.c @@ -859,14 +859,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) reg_write(gspca_dev->dev, 5, 0x01, (255 - brightness) << 2); } -static void getbrightness(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->brightness = 255 - - ((reg_read(gspca_dev, 5, 0x01, 1) >> 2) - + (reg_read(gspca_dev, 5, 0x0, 1) << 6)); -} static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) { @@ -882,7 +874,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - getbrightness(gspca_dev); *val = sd->brightness; return 0; } diff --git a/linux/drivers/media/video/gspca/spca506.c b/linux/drivers/media/video/gspca/spca506.c index 8cedb0097..3a0c893f9 100644 --- a/linux/drivers/media/video/gspca/spca506.c +++ b/linux/drivers/media/video/gspca/spca506.c @@ -193,24 +193,6 @@ static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur, } } -static int spca506_ReadI2c(struct gspca_dev *gspca_dev, __u16 reg) -{ - int retry = 60; - - reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004); - reg_w(gspca_dev->dev, 0x07, reg, 0x0001); - reg_w(gspca_dev->dev, 0x07, 0x01, 0x0002); - while (--retry) { - reg_r(gspca_dev, 0x07, 0x0003, 2); - if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00) - break; - } - if (retry == 0) - return -1; - reg_r(gspca_dev, 0x07, 0x0000, 1); - return gspca_dev->usb_buf[0]; -} - static void spca506_SetNormeInput(struct gspca_dev *gspca_dev, __u16 norme, __u16 channel) @@ -595,13 +577,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) spca506_WriteI2c(gspca_dev, 0x01, 0x09); } -static void getbrightness(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->brightness = spca506_ReadI2c(gspca_dev, SAA7113_bright); -} - static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -611,13 +586,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) spca506_WriteI2c(gspca_dev, 0x01, 0x09); } -static void getcontrast(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->contrast = spca506_ReadI2c(gspca_dev, SAA7113_contrast); -} - static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -627,13 +595,6 @@ static void setcolors(struct gspca_dev *gspca_dev) spca506_WriteI2c(gspca_dev, 0x01, 0x09); } -static void getcolors(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->colors = spca506_ReadI2c(gspca_dev, SAA7113_saturation); -} - static void sethue(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -643,13 +604,6 @@ static void sethue(struct gspca_dev *gspca_dev) spca506_WriteI2c(gspca_dev, 0x01, 0x09); } -static void gethue(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->hue = spca506_ReadI2c(gspca_dev, SAA7113_hue); -} - static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -664,7 +618,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - getbrightness(gspca_dev); *val = sd->brightness; return 0; } @@ -683,7 +636,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - getcontrast(gspca_dev); *val = sd->contrast; return 0; } @@ -702,7 +654,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - getcolors(gspca_dev); *val = sd->colors; return 0; } @@ -721,7 +672,6 @@ static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - gethue(gspca_dev); *val = sd->hue; return 0; } diff --git a/linux/drivers/media/video/gspca/spca508.c b/linux/drivers/media/video/gspca/spca508.c index 9a403acfe..e3afc9e7f 100644 --- a/linux/drivers/media/video/gspca/spca508.c +++ b/linux/drivers/media/video/gspca/spca508.c @@ -1617,13 +1617,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) reg_write(gspca_dev->dev, 0x8654, brightness); } -static void getbrightness(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->brightness = reg_read(gspca_dev, 0x8651); -} - static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -1638,7 +1631,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - getbrightness(gspca_dev); *val = sd->brightness; return 0; } diff --git a/linux/drivers/media/video/gspca/sunplus.c b/linux/drivers/media/video/gspca/sunplus.c index 852711731..fba6f98d1 100644 --- a/linux/drivers/media/video/gspca/sunplus.c +++ b/linux/drivers/media/video/gspca/sunplus.c @@ -1225,26 +1225,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) } } -static void getbrightness(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - __u16 brightness = 0; - - switch (sd->bridge) { - default: -/* case BRIDGE_SPCA533: */ -/* case BRIDGE_SPCA504B: */ -/* case BRIDGE_SPCA504: */ -/* case BRIDGE_SPCA504C: */ - brightness = reg_r_12(gspca_dev, 0x00, 0x21a7, 2); - break; - case BRIDGE_SPCA536: - brightness = reg_r_12(gspca_dev, 0x00, 0x20f0, 2); - break; - } - sd->brightness = ((brightness & 0xff) - 128) % 255; -} - static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1264,24 +1244,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) } } -static void getcontrast(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->bridge) { - default: -/* case BRIDGE_SPCA533: */ -/* case BRIDGE_SPCA504B: */ -/* case BRIDGE_SPCA504: */ -/* case BRIDGE_SPCA504C: */ - sd->contrast = reg_r_12(gspca_dev, 0x00, 0x21a8, 2); - break; - case BRIDGE_SPCA536: - sd->contrast = reg_r_12(gspca_dev, 0x00, 0x20f1, 2); - break; - } -} - static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1301,24 +1263,6 @@ static void setcolors(struct gspca_dev *gspca_dev) } } -static void getcolors(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->bridge) { - default: -/* case BRIDGE_SPCA533: */ -/* case BRIDGE_SPCA504B: */ -/* case BRIDGE_SPCA504: */ -/* case BRIDGE_SPCA504C: */ - sd->colors = reg_r_12(gspca_dev, 0x00, 0x21ae, 2) >> 1; - break; - case BRIDGE_SPCA536: - sd->colors = reg_r_12(gspca_dev, 0x00, 0x20f6, 2) >> 1; - break; - } -} - static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -1333,7 +1277,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - getbrightness(gspca_dev); *val = sd->brightness; return 0; } @@ -1352,7 +1295,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - getcontrast(gspca_dev); *val = sd->contrast; return 0; } @@ -1371,7 +1313,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - getcolors(gspca_dev); *val = sd->colors; return 0; } -- cgit v1.2.3 From 07204c883fe47f8936c1288e11252a14173dce1e Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 10 Jan 2009 20:14:12 +0100 Subject: gspca - tv8532: Change the max brightness. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/tv8532.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/tv8532.c b/linux/drivers/media/video/gspca/tv8532.c index 024d798ad..79b78f234 100644 --- a/linux/drivers/media/video/gspca/tv8532.c +++ b/linux/drivers/media/video/gspca/tv8532.c @@ -46,9 +46,9 @@ static struct ctrl sd_ctrls[] = { .type = V4L2_CTRL_TYPE_INTEGER, .name = "Brightness", .minimum = 1, - .maximum = 0x2ff, + .maximum = 0x15f, /* = 352 - 1 */ .step = 1, -#define BRIGHTNESS_DEF 0x18f +#define BRIGHTNESS_DEF 0x14c .default_value = BRIGHTNESS_DEF, }, .set = sd_setbrightness, -- cgit v1.2.3 From 2d4f2fbb05799ae2c5d8cd0c001364ab3f3dbf24 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 11 Jan 2009 09:12:43 +0000 Subject: dvb: constify VFTs From: Jan Engelhardt dvb: constify VFTs Signed-off-by: Jan Engelhardt Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/bt8xx/dst_ca.c | 2 +- linux/drivers/media/dvb/dvb-core/dmxdev.c | 2 +- linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c | 2 +- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 2 +- linux/drivers/media/dvb/dvb-core/dvb_net.c | 2 +- linux/drivers/media/dvb/dvb-core/dvbdev.c | 4 ++-- linux/drivers/media/dvb/dvb-core/dvbdev.h | 2 +- linux/drivers/media/dvb/ttpci/av7110.c | 2 +- linux/drivers/media/dvb/ttpci/av7110_av.c | 4 ++-- linux/drivers/media/dvb/ttpci/av7110_ca.c | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/bt8xx/dst_ca.c b/linux/drivers/media/dvb/bt8xx/dst_ca.c index 0b462e7bb..68aef6786 100644 --- a/linux/drivers/media/dvb/bt8xx/dst_ca.c +++ b/linux/drivers/media/dvb/bt8xx/dst_ca.c @@ -778,7 +778,7 @@ static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t return 0; } -static struct file_operations dst_ca_fops = { +static const struct file_operations dst_ca_fops = { .owner = THIS_MODULE, .ioctl = dst_ca_ioctl, .open = dst_ca_open, diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.c b/linux/drivers/media/dvb/dvb-core/dmxdev.c index 0c733c66a..cc143929a 100644 --- a/linux/drivers/media/dvb/dvb-core/dmxdev.c +++ b/linux/drivers/media/dvb/dvb-core/dmxdev.c @@ -1026,7 +1026,7 @@ static int dvb_demux_release(struct inode *inode, struct file *file) return ret; } -static struct file_operations dvb_demux_fops = { +static const struct file_operations dvb_demux_fops = { .owner = THIS_MODULE, .read = dvb_demux_read, .ioctl = dvb_demux_ioctl, diff --git a/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index 19965a055..02a4e94cb 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c @@ -1608,7 +1608,7 @@ static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table * wait) EXPORT_SYMBOL(dvb_ca_en50221_init); -static struct file_operations dvb_ca_fops = { +static const struct file_operations dvb_ca_fops = { .owner = THIS_MODULE, .read = dvb_ca_en50221_io_read, .write = dvb_ca_en50221_io_write, diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 01a9ceb37..05b327403 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1989,7 +1989,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) return ret; } -static struct file_operations dvb_frontend_fops = { +static const struct file_operations dvb_frontend_fops = { .owner = THIS_MODULE, .ioctl = dvb_generic_ioctl, .poll = dvb_frontend_poll, diff --git a/linux/drivers/media/dvb/dvb-core/dvb_net.c b/linux/drivers/media/dvb/dvb-core/dvb_net.c index f0cd3b8ed..5f4856c6d 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_net.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_net.c @@ -1526,7 +1526,7 @@ static int dvb_net_close(struct inode *inode, struct file *file) } -static struct file_operations dvb_net_fops = { +static const struct file_operations dvb_net_fops = { .owner = THIS_MODULE, .ioctl = dvb_net_ioctl, .open = dvb_generic_open, diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c index 940114768..4609e3ebd 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.c +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c @@ -237,8 +237,8 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, dvbdev->fops = dvbdevfops; init_waitqueue_head (&dvbdev->wait_queue); - memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations)); - dvbdev->fops->owner = adap->module; + memcpy(dvbdevfops, template->fops, sizeof(struct file_operations)); + dvbdevfops->owner = adap->module; list_add_tail (&dvbdev->list_head, &adap->device_list); diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.h b/linux/drivers/media/dvb/dvb-core/dvbdev.h index dca49cf96..79927305e 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.h +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.h @@ -71,7 +71,7 @@ struct dvb_adapter { struct dvb_device { struct list_head list_head; - struct file_operations *fops; + const struct file_operations *fops; struct dvb_adapter *adapter; int type; int minor; diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c index b99057a68..841590ed5 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.c +++ b/linux/drivers/media/dvb/ttpci/av7110.c @@ -728,7 +728,7 @@ static int dvb_osd_ioctl(struct inode *inode, struct file *file, } -static struct file_operations dvb_osd_fops = { +static const struct file_operations dvb_osd_fops = { .owner = THIS_MODULE, .ioctl = dvb_generic_ioctl, .open = dvb_generic_open, diff --git a/linux/drivers/media/dvb/ttpci/av7110_av.c b/linux/drivers/media/dvb/ttpci/av7110_av.c index bdc62acf2..e4d0900d5 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_av.c +++ b/linux/drivers/media/dvb/ttpci/av7110_av.c @@ -1456,7 +1456,7 @@ static int dvb_audio_release(struct inode *inode, struct file *file) * driver registration ******************************************************************************/ -static struct file_operations dvb_video_fops = { +static const struct file_operations dvb_video_fops = { .owner = THIS_MODULE, .write = dvb_video_write, .ioctl = dvb_generic_ioctl, @@ -1474,7 +1474,7 @@ static struct dvb_device dvbdev_video = { .kernel_ioctl = dvb_video_ioctl, }; -static struct file_operations dvb_audio_fops = { +static const struct file_operations dvb_audio_fops = { .owner = THIS_MODULE, .write = dvb_audio_write, .ioctl = dvb_generic_ioctl, diff --git a/linux/drivers/media/dvb/ttpci/av7110_ca.c b/linux/drivers/media/dvb/ttpci/av7110_ca.c index 261135ded..c7a65b154 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_ca.c +++ b/linux/drivers/media/dvb/ttpci/av7110_ca.c @@ -345,7 +345,7 @@ static ssize_t dvb_ca_read(struct file *file, char __user *buf, return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos); } -static struct file_operations dvb_ca_fops = { +static const struct file_operations dvb_ca_fops = { .owner = THIS_MODULE, .read = dvb_ca_read, .write = dvb_ca_write, -- cgit v1.2.3 From 5c190e9dc01651545a2cb6e709953984ebae4be2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 12 Jan 2009 10:17:43 +0100 Subject: tvp514x: make the module aware of rich people From: Sebastian Andrzej Siewior because they might design two of those chips on a single board. You never know. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/tvp514x.c | 106 ++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 46 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tvp514x.c b/linux/drivers/media/video/tvp514x.c index 5f4cbc2b2..f0b2b8ed2 100644 --- a/linux/drivers/media/video/tvp514x.c +++ b/linux/drivers/media/video/tvp514x.c @@ -86,9 +86,12 @@ struct tvp514x_std_info { struct v4l2_standard standard; }; +static struct tvp514x_reg tvp514x_reg_list_default[0x40]; /** - * struct tvp514x_decoded - TVP5146/47 decoder object + * struct tvp514x_decoder - TVP5146/47 decoder object * @v4l2_int_device: Slave handle + * @tvp514x_slave: Slave pointer which is used by @v4l2_int_device + * @tvp514x_regs: copy of hw's regs with preset values. * @pdata: Board specific * @client: I2C client data * @id: Entry from I2C table @@ -103,7 +106,9 @@ struct tvp514x_std_info { * @route: input and output routing at chip level */ struct tvp514x_decoder { - struct v4l2_int_device *v4l2_int_device; + struct v4l2_int_device v4l2_int_device; + struct v4l2_int_slave tvp514x_slave; + struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)]; const struct tvp514x_platform_data *pdata; struct i2c_client *client; @@ -124,7 +129,7 @@ struct tvp514x_decoder { }; /* TVP514x default register values */ -static struct tvp514x_reg tvp514x_reg_list[] = { +static struct tvp514x_reg tvp514x_reg_list_default[] = { {TOK_WRITE, REG_INPUT_SEL, 0x05}, /* Composite selected */ {TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F}, {TOK_WRITE, REG_VIDEO_STD, 0x00}, /* Auto mode */ @@ -422,7 +427,7 @@ static int tvp514x_configure(struct tvp514x_decoder *decoder) /* common register initialization */ err = - tvp514x_write_regs(decoder->client, tvp514x_reg_list); + tvp514x_write_regs(decoder->client, decoder->tvp514x_regs); if (err) return err; @@ -580,7 +585,8 @@ static int ioctl_s_std(struct v4l2_int_device *s, v4l2_std_id *std_id) return err; decoder->current_std = i; - tvp514x_reg_list[REG_VIDEO_STD].val = decoder->std_list[i].video_std; + decoder->tvp514x_regs[REG_VIDEO_STD].val = + decoder->std_list[i].video_std; v4l_dbg(1, debug, decoder->client, "Standard set to: %s", decoder->std_list[i].standard.name); @@ -625,8 +631,8 @@ static int ioctl_s_routing(struct v4l2_int_device *s, if (err) return err; - tvp514x_reg_list[REG_INPUT_SEL].val = input_sel; - tvp514x_reg_list[REG_OUTPUT_FORMATTER1].val = output_sel; + decoder->tvp514x_regs[REG_INPUT_SEL].val = input_sel; + decoder->tvp514x_regs[REG_OUTPUT_FORMATTER1].val = output_sel; /* Clear status */ msleep(LOCK_RETRY_DELAY); @@ -779,16 +785,16 @@ ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: - ctrl->value = tvp514x_reg_list[REG_BRIGHTNESS].val; + ctrl->value = decoder->tvp514x_regs[REG_BRIGHTNESS].val; break; case V4L2_CID_CONTRAST: - ctrl->value = tvp514x_reg_list[REG_CONTRAST].val; + ctrl->value = decoder->tvp514x_regs[REG_CONTRAST].val; break; case V4L2_CID_SATURATION: - ctrl->value = tvp514x_reg_list[REG_SATURATION].val; + ctrl->value = decoder->tvp514x_regs[REG_SATURATION].val; break; case V4L2_CID_HUE: - ctrl->value = tvp514x_reg_list[REG_HUE].val; + ctrl->value = decoder->tvp514x_regs[REG_HUE].val; if (ctrl->value == 0x7F) ctrl->value = 180; else if (ctrl->value == 0x80) @@ -798,7 +804,7 @@ ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) break; case V4L2_CID_AUTOGAIN: - ctrl->value = tvp514x_reg_list[REG_AFE_GAIN_CTRL].val; + ctrl->value = decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val; if ((ctrl->value & 0x3) == 3) ctrl->value = 1; else @@ -848,7 +854,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) value); if (err) return err; - tvp514x_reg_list[REG_BRIGHTNESS].val = value; + decoder->tvp514x_regs[REG_BRIGHTNESS].val = value; break; case V4L2_CID_CONTRAST: if (ctrl->value < 0 || ctrl->value > 255) { @@ -861,7 +867,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) value); if (err) return err; - tvp514x_reg_list[REG_CONTRAST].val = value; + decoder->tvp514x_regs[REG_CONTRAST].val = value; break; case V4L2_CID_SATURATION: if (ctrl->value < 0 || ctrl->value > 255) { @@ -874,7 +880,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) value); if (err) return err; - tvp514x_reg_list[REG_SATURATION].val = value; + decoder->tvp514x_regs[REG_SATURATION].val = value; break; case V4L2_CID_HUE: if (value == 180) @@ -893,7 +899,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) value); if (err) return err; - tvp514x_reg_list[REG_HUE].val = value; + decoder->tvp514x_regs[REG_HUE].val = value; break; case V4L2_CID_AUTOGAIN: if (value == 1) @@ -910,7 +916,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) value); if (err) return err; - tvp514x_reg_list[REG_AFE_GAIN_CTRL].val = value; + decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value; break; default: v4l_err(decoder->client, @@ -1275,7 +1281,7 @@ static int ioctl_init(struct v4l2_int_device *s) struct tvp514x_decoder *decoder = s->priv; /* Set default standard to auto */ - tvp514x_reg_list[REG_VIDEO_STD].val = + decoder->tvp514x_regs[REG_VIDEO_STD].val = VIDEO_STD_AUTO_SWITCH_BIT; return tvp514x_configure(decoder); @@ -1344,11 +1350,6 @@ static struct v4l2_int_ioctl_desc tvp514x_ioctl_desc[] = { (v4l2_int_ioctl_func *) ioctl_s_routing}, }; -static struct v4l2_int_slave tvp514x_slave = { - .ioctls = tvp514x_ioctl_desc, - .num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc), -}; - static struct tvp514x_decoder tvp514x_dev = { .state = STATE_NOT_DETECTED, @@ -1369,17 +1370,15 @@ static struct tvp514x_decoder tvp514x_dev = { .current_std = STD_NTSC_MJ, .std_list = tvp514x_std_list, .num_stds = ARRAY_SIZE(tvp514x_std_list), - -}; - -static struct v4l2_int_device tvp514x_int_device = { - .module = THIS_MODULE, - .name = TVP514X_MODULE_NAME, - .priv = &tvp514x_dev, - .type = v4l2_int_type_slave, - .u = { - .slave = &tvp514x_slave, - }, + .v4l2_int_device = { + .module = THIS_MODULE, + .name = TVP514X_MODULE_NAME, + .type = v4l2_int_type_slave, + }, + .tvp514x_slave = { + .ioctls = tvp514x_ioctl_desc, + .num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc), + }, }; /** @@ -1392,26 +1391,37 @@ static struct v4l2_int_device tvp514x_int_device = { static int tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct tvp514x_decoder *decoder = &tvp514x_dev; + struct tvp514x_decoder *decoder; int err; /* Check if the adapter supports the needed features */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; - decoder->pdata = client->dev.platform_data; - if (!decoder->pdata) { + decoder = kzalloc(sizeof(*decoder), GFP_KERNEL); + if (!decoder) + return -ENOMEM; + + if (!client->dev.platform_data) { v4l_err(client, "No platform data!!\n"); - return -ENODEV; + err = -ENODEV; + goto out_free; } + + *decoder = tvp514x_dev; + decoder->v4l2_int_device.priv = decoder; + decoder->pdata = client->dev.platform_data; + decoder->v4l2_int_device.u.slave = &decoder->tvp514x_slave; + memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default, + sizeof(tvp514x_reg_list_default)); /* * Fetch platform specific data, and configure the * tvp514x_reg_list[] accordingly. Since this is one * time configuration, no need to preserve. */ - tvp514x_reg_list[REG_OUTPUT_FORMATTER2].val |= + decoder->tvp514x_regs[REG_OUTPUT_FORMATTER2].val |= (decoder->pdata->clk_polarity << 1); - tvp514x_reg_list[REG_SYNC_CONTROL].val |= + decoder->tvp514x_regs[REG_SYNC_CONTROL].val |= ((decoder->pdata->hs_polarity << 2) | (decoder->pdata->vs_polarity << 3)); /* @@ -1419,23 +1429,27 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id) */ decoder->id = (struct i2c_device_id *)id; /* Attach to Master */ - strcpy(tvp514x_int_device.u.slave->attach_to, decoder->pdata->master); - decoder->v4l2_int_device = &tvp514x_int_device; + strcpy(decoder->v4l2_int_device.u.slave->attach_to, + decoder->pdata->master); decoder->client = client; i2c_set_clientdata(client, decoder); /* Register with V4L2 layer as slave device */ - err = v4l2_int_device_register(decoder->v4l2_int_device); + err = v4l2_int_device_register(&decoder->v4l2_int_device); if (err) { i2c_set_clientdata(client, NULL); v4l_err(client, "Unable to register to v4l2. Err[%d]\n", err); + goto out_free; } else v4l_info(client, "Registered to v4l2 master %s!!\n", decoder->pdata->master); - return 0; + +out_free: + kfree(decoder); + return err; } /** @@ -1452,9 +1466,9 @@ static int __exit tvp514x_remove(struct i2c_client *client) if (!client->adapter) return -ENODEV; /* our client isn't attached */ - v4l2_int_device_unregister(decoder->v4l2_int_device); + v4l2_int_device_unregister(&decoder->v4l2_int_device); i2c_set_clientdata(client, NULL); - + kfree(decoder); return 0; } /* -- cgit v1.2.3 From ea1a5784b0f9edacdb25b4ab26dde75d86b6bb1f Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 10 Mar 2009 16:02:07 -0400 Subject: saa7134: fix typo in product name From: Michael Krufky replace occurances of "HVR1150" with "HVR1120" - this was a typo. Priority: normal Signed-off-by: Michael Krufky --- linux/Documentation/video4linux/CARDLIST.saa7134 | 2 +- linux/drivers/media/video/saa7134/saa7134-cards.c | 20 ++++++++++---------- linux/drivers/media/video/saa7134/saa7134.h | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'linux') diff --git a/linux/Documentation/video4linux/CARDLIST.saa7134 b/linux/Documentation/video4linux/CARDLIST.saa7134 index 325c69fe9..626820e51 100644 --- a/linux/Documentation/video4linux/CARDLIST.saa7134 +++ b/linux/Documentation/video4linux/CARDLIST.saa7134 @@ -153,5 +153,5 @@ 152 -> Asus Tiger Rev:1.00 [1043:4857] 153 -> Kworld Plus TV Analog Lite PCI [17de:7128] 154 -> Avermedia AVerTV GO 007 FM Plus [1461:f31d] -155 -> Hauppauge WinTV-HVR1150 [0070:6706,0070:6708] +155 -> Hauppauge WinTV-HVR1120 [0070:6706,0070:6708] 156 -> Hauppauge WinTV-HVR1110r3 [0070:6707,0070:6709,0070:670a] diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c index 725c05f9e..09697c0f1 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -3331,8 +3331,8 @@ struct saa7134_board saa7134_boards[] = { .gpio = 0x0200100, }, }, - [SAA7134_BOARD_HAUPPAUGE_HVR1150] = { - .name = "Hauppauge WinTV-HVR1150", + [SAA7134_BOARD_HAUPPAUGE_HVR1120] = { + .name = "Hauppauge WinTV-HVR1120", .audio_clock = 0x00187de7, .tuner_type = TUNER_PHILIPS_TDA8290, .radio_type = UNSET, @@ -5505,7 +5505,7 @@ struct pci_device_id saa7134_pci_tbl[] = { .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x0070, .subdevice = 0x6706, - .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1150, + .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1120, },{ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, @@ -5517,7 +5517,7 @@ struct pci_device_id saa7134_pci_tbl[] = { .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x0070, .subdevice = 0x6708, - .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1150, + .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1120, },{ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, @@ -6057,7 +6057,7 @@ static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev, switch (command) { case TDA18271_CALLBACK_CMD_AGC_ENABLE: /* 0 */ switch (dev->board) { - case SAA7134_BOARD_HAUPPAUGE_HVR1150: + case SAA7134_BOARD_HAUPPAUGE_HVR1120: case SAA7134_BOARD_HAUPPAUGE_HVR1110R3: ret = saa7134_tda18271_hvr11x0_toggle_agc(dev, arg); break; @@ -6078,7 +6078,7 @@ static int saa7134_tda8290_callback(struct saa7134_dev *dev, int ret; switch (dev->board) { - case SAA7134_BOARD_HAUPPAUGE_HVR1150: + case SAA7134_BOARD_HAUPPAUGE_HVR1120: case SAA7134_BOARD_HAUPPAUGE_HVR1110R3: /* tda8290 + tda18271 */ ret = saa7134_tda8290_18271_callback(dev, command, arg); @@ -6125,7 +6125,7 @@ static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data) switch (tv.model) { case 67019: /* WinTV-HVR1110 (Retail, IR Blaster, hybrid, FM, SVid/Comp, 3.5mm audio in) */ case 67109: /* WinTV-HVR1000 (Retail, IR Receive, analog, no FM, SVid/Comp, 3.5mm audio in) */ - case 67201: /* WinTV-HVR1150 (Retail, IR Receive, hybrid, FM, SVid/Comp, 3.5mm audio in) */ + case 67201: /* WinTV-HVR1120 (Retail, IR Receive, hybrid, FM, SVid/Comp, 3.5mm audio in) */ case 67301: /* WinTV-HVR1000 (Retail, IR Receive, analog, no FM, SVid/Comp, 3.5mm audio in) */ case 67209: /* WinTV-HVR1110 (Retail, IR Receive, hybrid, FM, SVid/Comp, 3.5mm audio in) */ case 67559: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */ @@ -6133,7 +6133,7 @@ static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data) case 67579: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM) */ case 67589: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM, SVid/Comp, RCA aud) */ case 67599: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM, SVid/Comp, RCA aud) */ - case 67651: /* WinTV-HVR1150 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */ + case 67651: /* WinTV-HVR1120 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */ case 67659: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */ break; default: @@ -6315,7 +6315,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) saa_writeb (SAA7134_PRODUCTION_TEST_MODE, 0x00); break; - case SAA7134_BOARD_HAUPPAUGE_HVR1150: + case SAA7134_BOARD_HAUPPAUGE_HVR1120: case SAA7134_BOARD_HAUPPAUGE_HVR1110R3: /* GPIO 26 high for digital, low for analog */ saa7134_set_gpio(dev, 26, 0); @@ -6577,7 +6577,7 @@ int saa7134_board_init2(struct saa7134_dev *dev) dev->name, saa7134_boards[dev->board].name); } break; - case SAA7134_BOARD_HAUPPAUGE_HVR1150: + case SAA7134_BOARD_HAUPPAUGE_HVR1120: case SAA7134_BOARD_HAUPPAUGE_HVR1110R3: hauppauge_eeprom(dev, dev->eedata+0x80); break; diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h index 0e45c0931..b21679a71 100644 --- a/linux/drivers/media/video/saa7134/saa7134.h +++ b/linux/drivers/media/video/saa7134/saa7134.h @@ -279,7 +279,7 @@ struct saa7134_format { #define SAA7134_BOARD_ASUSTeK_TIGER 152 #define SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG 153 #define SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS 154 -#define SAA7134_BOARD_HAUPPAUGE_HVR1150 155 +#define SAA7134_BOARD_HAUPPAUGE_HVR1120 155 #define SAA7134_BOARD_HAUPPAUGE_HVR1110R3 156 #define SAA7134_MAXBOARDS 32 -- cgit v1.2.3 From da20a75e939aeba2dd14cef84e0de195daaff4ac Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 13 Jan 2009 02:03:26 -0500 Subject: saa7134: enable serial transport streaming interface From: Michael Krufky Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/video/saa7134/saa7134-ts.c | 15 +++++++++++++-- linux/drivers/media/video/saa7134/saa7134.h | 6 ++++++ 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7134/saa7134-ts.c b/linux/drivers/media/video/saa7134/saa7134-ts.c index ef55a59f0..cc8b923af 100644 --- a/linux/drivers/media/video/saa7134/saa7134-ts.c +++ b/linux/drivers/media/video/saa7134/saa7134-ts.c @@ -79,8 +79,19 @@ static int buffer_activate(struct saa7134_dev *dev, saa_writeb(SAA7134_TS_SERIAL1, 0x00); /* Start TS stream */ - saa_writeb(SAA7134_TS_SERIAL0, 0x40); - saa_writeb(SAA7134_TS_PARALLEL, 0xEC); + switch (saa7134_boards[dev->board].ts_type) { + case SAA7134_MPEG_TS_PARALLEL: + saa_writeb(SAA7134_TS_SERIAL0, 0x40); + saa_writeb(SAA7134_TS_PARALLEL, 0xec); + break; + case SAA7134_MPEG_TS_SERIAL: + saa_writeb(SAA7134_TS_SERIAL0, 0xd8); + saa_writeb(SAA7134_TS_PARALLEL, 0x6c); + saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc); + saa_writeb(SAA7134_TS_SERIAL1, 0x02); + break; + } + dev->ts_state = SAA7134_TS_STARTED; } diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h index b21679a71..d2b29ed9e 100644 --- a/linux/drivers/media/video/saa7134/saa7134.h +++ b/linux/drivers/media/video/saa7134/saa7134.h @@ -313,6 +313,11 @@ enum saa7134_mpeg_type { SAA7134_MPEG_DVB, }; +enum saa7134_mpeg_ts_type { + SAA7134_MPEG_TS_PARALLEL = 0, + SAA7134_MPEG_TS_SERIAL, +}; + struct saa7134_board { char *name; unsigned int audio_clock; @@ -335,6 +340,7 @@ struct saa7134_board { /* peripheral I/O */ enum saa7134_video_out video_out; enum saa7134_mpeg_type mpeg; + enum saa7134_mpeg_ts_type ts_type; unsigned int vid_port_opts; }; -- cgit v1.2.3 From 57f11b4d55f26d34f0e66cc7e84e4e63dc8c80bf Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 13 Jan 2009 02:40:36 -0500 Subject: add support for LG Electronics LGDT3305 ATSC/QAM-B Demodulator From: Michael Krufky Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/Kconfig | 8 + linux/drivers/media/dvb/frontends/Makefile | 1 + linux/drivers/media/dvb/frontends/lgdt3305.c | 1115 ++++++++++++++++++++++++++ linux/drivers/media/dvb/frontends/lgdt3305.h | 85 ++ 4 files changed, 1209 insertions(+) create mode 100644 linux/drivers/media/dvb/frontends/lgdt3305.c create mode 100644 linux/drivers/media/dvb/frontends/lgdt3305.h (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig index 2887d3398..5c78f6329 100644 --- a/linux/drivers/media/dvb/frontends/Kconfig +++ b/linux/drivers/media/dvb/frontends/Kconfig @@ -419,6 +419,14 @@ config DVB_LGDT3304 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want to support this frontend. +config DVB_LGDT3305 + tristate "LG Electronics LGDT3305 based" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want + to support this frontend. + config DVB_S5H1409 tristate "Samsung S5H1409 based" depends on DVB_CORE && I2C diff --git a/linux/drivers/media/dvb/frontends/Makefile b/linux/drivers/media/dvb/frontends/Makefile index 1e3866b2f..2a250399b 100644 --- a/linux/drivers/media/dvb/frontends/Makefile +++ b/linux/drivers/media/dvb/frontends/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o obj-$(CONFIG_DVB_S5H1420) += s5h1420.o obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o obj-$(CONFIG_DVB_LGDT3304) += lgdt3304.o +obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o obj-$(CONFIG_DVB_CX24123) += cx24123.o obj-$(CONFIG_DVB_LNBP21) += lnbp21.o obj-$(CONFIG_DVB_ISL6405) += isl6405.o diff --git a/linux/drivers/media/dvb/frontends/lgdt3305.c b/linux/drivers/media/dvb/frontends/lgdt3305.c new file mode 100644 index 000000000..aeb34e924 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/lgdt3305.c @@ -0,0 +1,1115 @@ +/* + * Support for LGDT3305 - VSB/QAM + * + * Copyright (C) 2008, 2009 Michael Krufky + * + * 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 "compat.h" +#include +#include "dvb_math.h" +#include "lgdt3305.h" + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))"); + +#define DBG_INFO 1 +#define DBG_REG 2 + +#define lg_printk(kern, fmt, arg...) \ + printk(kern "%s: " fmt, __func__, ##arg) + +#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3305: " fmt, ##arg) +#define lg_warn(fmt, arg...) lg_printk(KERN_WARNING, fmt, ##arg) +#define lg_err(fmt, arg...) lg_printk(KERN_ERR, fmt, ##arg) +#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \ + lg_printk(KERN_DEBUG, fmt, ##arg) +#define lg_reg(fmt, arg...) if (debug & DBG_REG) \ + lg_printk(KERN_DEBUG, fmt, ##arg) + +#define lg_fail(ret) \ +({ \ + int __ret; \ + __ret = (ret < 0); \ + if (__ret) \ + lg_err("error %d on line %d\n", ret, __LINE__); \ + __ret; \ +}) + +struct lgdt3305_state { + struct i2c_adapter *i2c_adap; + const struct lgdt3305_config *cfg; + + struct dvb_frontend frontend; + + fe_modulation_t current_modulation; + u32 current_frequency; + u32 snr; +}; + +/* ------------------------------------------------------------------------ */ + +#define LGDT3305_GEN_CTRL_1 0x0000 +#define LGDT3305_GEN_CTRL_2 0x0001 +#define LGDT3305_GEN_CTRL_3 0x0002 +#define LGDT3305_GEN_STATUS 0x0003 +#define LGDT3305_GEN_CONTROL 0x0007 +#define LGDT3305_GEN_CTRL_4 0x000a +#define LGDT3305_DGTL_AGC_REF_1 0x0012 +#define LGDT3305_DGTL_AGC_REF_2 0x0013 +#define LGDT3305_CR_CTR_FREQ_1 0x0106 +#define LGDT3305_CR_CTR_FREQ_2 0x0107 +#define LGDT3305_CR_CTR_FREQ_3 0x0108 +#define LGDT3305_CR_CTR_FREQ_4 0x0109 +#define LGDT3305_CR_MSE_1 0x011b +#define LGDT3305_CR_MSE_2 0x011c +#define LGDT3305_CR_LOCK_STATUS 0x011d +#define LGDT3305_CR_CTRL_7 0x0126 +#define LGDT3305_AGC_POWER_REF_1 0x0300 +#define LGDT3305_AGC_POWER_REF_2 0x0301 +#define LGDT3305_AGC_DELAY_PT_1 0x0302 +#define LGDT3305_AGC_DELAY_PT_2 0x0303 +#define LGDT3305_RFAGC_LOOP_FLTR_BW_1 0x0306 +#define LGDT3305_RFAGC_LOOP_FLTR_BW_2 0x0307 +#define LGDT3305_IFBW_1 0x0308 +#define LGDT3305_IFBW_2 0x0309 +#define LGDT3305_AGC_CTRL_1 0x030c +#define LGDT3305_AGC_CTRL_4 0x0314 +#define LGDT3305_EQ_MSE_1 0x0413 +#define LGDT3305_EQ_MSE_2 0x0414 +#define LGDT3305_EQ_MSE_3 0x0415 +#define LGDT3305_PT_MSE_1 0x0417 +#define LGDT3305_PT_MSE_2 0x0418 +#define LGDT3305_PT_MSE_3 0x0419 +#define LGDT3305_FEC_BLOCK_CTRL 0x0504 +#define LGDT3305_FEC_LOCK_STATUS 0x050a +#define LGDT3305_FEC_PKT_ERR_1 0x050c +#define LGDT3305_FEC_PKT_ERR_2 0x050d +#define LGDT3305_TP_CTRL_1 0x050e +#define LGDT3305_BERT_PERIOD 0x0801 +#define LGDT3305_BERT_ERROR_COUNT_1 0x080a +#define LGDT3305_BERT_ERROR_COUNT_2 0x080b +#define LGDT3305_BERT_ERROR_COUNT_3 0x080c +#define LGDT3305_BERT_ERROR_COUNT_4 0x080d + +static int lgdt3305_write_reg(struct lgdt3305_state *state, u16 reg, u8 val) +{ + int ret; + u8 buf[] = { reg >> 8, reg & 0xff, val }; + struct i2c_msg msg = { + .addr = state->cfg->i2c_addr, .flags = 0, + .buf = buf, .len = 3, + }; + + lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val); + + ret = i2c_transfer(state->i2c_adap, &msg, 1); + + if (ret != 1) { + lg_err("error (addr %02x %02x <- %02x, err = %i)\n", + msg.buf[0], msg.buf[1], msg.buf[2], ret); + if (ret < 0) + return ret; + else + return -EREMOTEIO; + } + return 0; +} + +static int lgdt3305_read_reg(struct lgdt3305_state *state, u16 reg, u8 *val) +{ + int ret; + u8 reg_buf[] = { reg >> 8, reg & 0xff }; + struct i2c_msg msg[] = { + { .addr = state->cfg->i2c_addr, + .flags = 0, .buf = reg_buf, .len = 2 }, + { .addr = state->cfg->i2c_addr, + .flags = I2C_M_RD, .buf = val, .len = 1 }, + }; + + lg_reg("reg: 0x%04x\n", reg); + + ret = i2c_transfer(state->i2c_adap, msg, 2); + + if (ret != 2) { + lg_err("error (addr %02x reg %04x error (ret == %i)\n", + state->cfg->i2c_addr, reg, ret); + if (ret < 0) + return ret; + else + return -EREMOTEIO; + } + return 0; +} + +#define read_reg(state, reg) \ +({ \ + u8 __val; \ + int ret = lgdt3305_read_reg(state, reg, &__val); \ + if (lg_fail(ret)) \ + __val = 0; \ + __val; \ +}) + +static int lgdt3305_set_reg_bit(struct lgdt3305_state *state, + u16 reg, int bit, int onoff) +{ + u8 val; + int ret; + + lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff); + + ret = lgdt3305_read_reg(state, reg, &val); + if (lg_fail(ret)) + goto fail; + + val &= ~(1 << bit); + val |= (onoff & 1) << bit; + + ret = lgdt3305_write_reg(state, reg, val); +fail: + return ret; +} + +struct lgdt3305_reg { + u16 reg; + u8 val; +}; + +static int lgdt3305_write_regs(struct lgdt3305_state *state, + struct lgdt3305_reg *regs, int len) +{ + int i, ret; + + lg_reg("writing %d registers...\n", len); + + for (i = 0; i < len - 1; i++) { + ret = lgdt3305_write_reg(state, regs[i].reg, regs[i].val); + if (lg_fail(ret)) + return ret; + } + return 0; +} + +/* ------------------------------------------------------------------------ */ + +static int lgdt3305_soft_reset(struct lgdt3305_state *state) +{ + int ret; + + lg_dbg("\n"); + + ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 0); + if (lg_fail(ret)) + goto fail; + + msleep(20); + ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 1); +fail: + return ret; +} + +static inline int lgdt3305_mpeg_mode(struct lgdt3305_state *state, + enum lgdt3305_mpeg_mode mode) +{ + lg_dbg("(%d)\n", mode); + return lgdt3305_set_reg_bit(state, LGDT3305_TP_CTRL_1, 5, mode); +} + +static int lgdt3305_mpeg_mode_polarity(struct lgdt3305_state *state, + enum lgdt3305_tp_clock_edge edge, + enum lgdt3305_tp_valid_polarity valid) +{ + u8 val; + int ret; + + lg_dbg("edge = %d, valid = %d\n", edge, valid); + + ret = lgdt3305_read_reg(state, LGDT3305_TP_CTRL_1, &val); + if (lg_fail(ret)) + goto fail; + + val &= ~0x09; + + if (edge) + val |= 0x08; + if (valid) + val |= 0x01; + + ret = lgdt3305_write_reg(state, LGDT3305_TP_CTRL_1, val); + if (lg_fail(ret)) + goto fail; + + ret = lgdt3305_soft_reset(state); +fail: + return ret; +} + +static int lgdt3305_set_modulation(struct lgdt3305_state *state, + struct dvb_frontend_parameters *param) +{ + u8 opermode; + int ret; + + lg_dbg("\n"); + + ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_1, &opermode); + if (lg_fail(ret)) + goto fail; + + opermode &= ~0x03; + + switch (param->u.vsb.modulation) { + case VSB_8: + opermode |= 0x03; + break; + case QAM_64: + opermode |= 0x00; + break; + case QAM_256: + opermode |= 0x01; + break; + default: + return -EINVAL; + } + ret = lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_1, opermode); +fail: + return ret; +} + +static int lgdt3305_set_filter_extension(struct lgdt3305_state *state, + struct dvb_frontend_parameters *param) +{ + int val; + + switch (param->u.vsb.modulation) { + case VSB_8: + val = 0; + break; + case QAM_64: + case QAM_256: + val = 1; + break; + default: + return -EINVAL; + } + lg_dbg("val = %d\n", val); + + return lgdt3305_set_reg_bit(state, 0x043f, 2, val); +} + +/* ------------------------------------------------------------------------ */ + +static int lgdt3305_passband_digital_agc(struct lgdt3305_state *state, + struct dvb_frontend_parameters *param) +{ + u16 agc_ref; + + switch (param->u.vsb.modulation) { + case VSB_8: + agc_ref = 0x32c4; + break; + case QAM_64: + agc_ref = 0x2a00; + break; + case QAM_256: + agc_ref = 0x2a80; + break; + default: + return -EINVAL; + } + + lg_dbg("agc ref: 0x%04x\n", agc_ref); + + lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_1, agc_ref >> 8); + lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_2, agc_ref & 0xff); + + return 0; +} + +static int lgdt3305_rfagc_loop(struct lgdt3305_state *state, + struct dvb_frontend_parameters *param) +{ + u16 ifbw, rfbw, agcdelay; + + switch (param->u.vsb.modulation) { + case VSB_8: + agcdelay = 0x04c0; + rfbw = 0x8000; + ifbw = 0x8000; + break; + case QAM_64: + case QAM_256: + agcdelay = 0x046b; + rfbw = 0x8889; + ifbw = 0x8888; + break; + default: + return -EINVAL; + } + + if (state->cfg->rf_agc_loop) { + lg_dbg("agcdelay: 0x%04x, rfbw: 0x%04x\n", agcdelay, rfbw); + + /* rf agc loop filter bandwidth */ + lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_1, + agcdelay >> 8); + lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_2, + agcdelay & 0xff); + + lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_1, + rfbw >> 8); + lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_2, + rfbw & 0xff); + } else { + lg_dbg("ifbw: 0x%04x\n", ifbw); + + /* if agc loop filter bandwidth */ + lgdt3305_write_reg(state, LGDT3305_IFBW_1, ifbw >> 8); + lgdt3305_write_reg(state, LGDT3305_IFBW_2, ifbw & 0xff); + } + + return 0; +} + +static int lgdt3305_agc_setup(struct lgdt3305_state *state, + struct dvb_frontend_parameters *param) +{ + int lockdten, acqen; + + switch (param->u.vsb.modulation) { + case VSB_8: + lockdten = 0; + acqen = 0; + break; + case QAM_64: + case QAM_256: + lockdten = 1; + acqen = 1; + break; + default: + return -EINVAL; + } + + lg_dbg("lockdten = %d, acqen = %d\n", lockdten, acqen); + + /* control agc function */ + lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1); + lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen); + + return lgdt3305_rfagc_loop(state, param); +} + +static int lgdt3305_set_agc_power_ref(struct lgdt3305_state *state, + struct dvb_frontend_parameters *param) +{ + u16 usref = 0; + + switch (param->u.vsb.modulation) { + case VSB_8: + if (state->cfg->usref_8vsb) + usref = state->cfg->usref_8vsb; + break; + case QAM_64: + if (state->cfg->usref_qam64) + usref = state->cfg->usref_qam64; + break; + case QAM_256: + if (state->cfg->usref_qam256) + usref = state->cfg->usref_qam256; + break; + default: + return -EINVAL; + } + + if (usref) { + lg_dbg("set manual mode: 0x%04x\n", usref); + + lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 3, 1); + + lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_1, + 0xff & (usref >> 8)); + lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_2, + 0xff & (usref >> 0)); + } + return 0; +} + +/* ------------------------------------------------------------------------ */ + +static int lgdt3305_spectral_inversion(struct lgdt3305_state *state, + struct dvb_frontend_parameters *param, + int inversion) +{ + int ret; + + lg_dbg("(%d)\n", inversion); + + switch (param->u.vsb.modulation) { + case VSB_8: + ret = lgdt3305_write_reg(state, LGDT3305_CR_CTRL_7, + inversion ? 0xf9 : 0x79); + break; + case QAM_64: + case QAM_256: + ret = lgdt3305_write_reg(state, LGDT3305_FEC_BLOCK_CTRL, + inversion ? 0xfd : 0xff); + break; + default: + ret = -EINVAL; + } + return ret; +} + +static int lgdt3305_set_if(struct lgdt3305_state *state, + struct dvb_frontend_parameters *param) +{ + u16 if_freq_khz; + u8 nco1, nco2, nco3, nco4; + u64 nco; + + switch (param->u.vsb.modulation) { + case VSB_8: + if_freq_khz = state->cfg->vsb_if_khz; + break; + case QAM_64: + case QAM_256: + if_freq_khz = state->cfg->qam_if_khz; + break; + default: + return -EINVAL; + } + + nco = if_freq_khz / 10; + +#define LGDT3305_64BIT_DIVISION_ENABLED 0 + /* FIXME: 64bit division disabled to avoid linking error: + * WARNING: "__udivdi3" [lgdt3305.ko] undefined! + */ + switch (param->u.vsb.modulation) { + case VSB_8: +#if LGDT3305_64BIT_DIVISION_ENABLED + nco <<= 24; + nco /= 625; +#else + nco *= ((1 << 24) / 625); +#endif + break; + case QAM_64: + case QAM_256: +#if LGDT3305_64BIT_DIVISION_ENABLED + nco <<= 28; + nco /= 625; +#else + nco *= ((1 << 28) / 625); +#endif + break; + default: + return -EINVAL; + } + + nco1 = (nco >> 24) & 0x3f; + nco1 |= 0x40; + nco2 = (nco >> 16) & 0xff; + nco3 = (nco >> 8) & 0xff; + nco4 = nco & 0xff; + + lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, nco1); + lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, nco2); + lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, nco3); + lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, nco4); + + lg_dbg("%d KHz -> [%02x%02x%02x%02x]\n", + if_freq_khz, nco1, nco2, nco3, nco4); + + return 0; +} + +/* ------------------------------------------------------------------------ */ + +static int lgdt3305_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct lgdt3305_state *state = fe->demodulator_priv; + + if (state->cfg->deny_i2c_rptr) + return 0; + + lg_dbg("(%d)\n", enable); + + return lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_2, 5, + enable ? 0 : 1); +} + +static int lgdt3305_sleep(struct dvb_frontend *fe) +{ + struct lgdt3305_state *state = fe->demodulator_priv; + u8 gen_ctrl_3, gen_ctrl_4; + + lg_dbg("\n"); + + gen_ctrl_3 = read_reg(state, LGDT3305_GEN_CTRL_3); + gen_ctrl_4 = read_reg(state, LGDT3305_GEN_CTRL_4); + + /* hold in software reset while sleeping */ + gen_ctrl_3 &= ~0x01; + /* tristate the IF-AGC pin */ + gen_ctrl_3 |= 0x02; + /* tristate the RF-AGC pin */ + gen_ctrl_3 |= 0x04; + + /* disable vsb/qam module */ + gen_ctrl_4 &= ~0x01; + /* disable adc module */ + gen_ctrl_4 &= ~0x02; + + lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_3, gen_ctrl_3); + lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_4, gen_ctrl_4); + + return 0; +} + +static int lgdt3305_init(struct dvb_frontend *fe) +{ + struct lgdt3305_state *state = fe->demodulator_priv; + int ret; + + static struct lgdt3305_reg lgdt3305_init_data[] = { + { .reg = LGDT3305_GEN_CTRL_1, + .val = 0x03, }, + { .reg = LGDT3305_GEN_CTRL_2, + .val = 0xb0, }, + { .reg = LGDT3305_GEN_CTRL_3, + .val = 0x01, }, + { .reg = LGDT3305_GEN_CONTROL, + .val = 0x6f, }, + { .reg = LGDT3305_GEN_CTRL_4, + .val = 0x03, }, + { .reg = LGDT3305_DGTL_AGC_REF_1, + .val = 0x32, }, + { .reg = LGDT3305_DGTL_AGC_REF_2, + .val = 0xc4, }, + { .reg = LGDT3305_CR_CTR_FREQ_1, + .val = 0x00, }, + { .reg = LGDT3305_CR_CTR_FREQ_2, + .val = 0x00, }, + { .reg = LGDT3305_CR_CTR_FREQ_3, + .val = 0x00, }, + { .reg = LGDT3305_CR_CTR_FREQ_4, + .val = 0x00, }, + { .reg = LGDT3305_CR_CTRL_7, + .val = 0x79, }, + { .reg = LGDT3305_AGC_POWER_REF_1, + .val = 0x32, }, + { .reg = LGDT3305_AGC_POWER_REF_2, + .val = 0xc4, }, + { .reg = LGDT3305_AGC_DELAY_PT_1, + .val = 0x0d, }, + { .reg = LGDT3305_AGC_DELAY_PT_2, + .val = 0x30, }, + { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_1, + .val = 0x80, }, + { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_2, + .val = 0x00, }, + { .reg = LGDT3305_IFBW_1, + .val = 0x80, }, + { .reg = LGDT3305_IFBW_2, + .val = 0x00, }, + { .reg = LGDT3305_AGC_CTRL_1, + .val = 0x30, }, + { .reg = LGDT3305_AGC_CTRL_4, + .val = 0x61, }, + { .reg = LGDT3305_FEC_BLOCK_CTRL, + .val = 0xff, }, + { .reg = LGDT3305_TP_CTRL_1, + .val = 0x1b, }, + }; + + lg_dbg("\n"); + + ret = lgdt3305_write_regs(state, lgdt3305_init_data, + ARRAY_SIZE(lgdt3305_init_data)); + if (lg_fail(ret)) + goto fail; + + ret = lgdt3305_soft_reset(state); +fail: + return ret; +} + +static int lgdt3305_set_parameters(struct dvb_frontend *fe, + struct dvb_frontend_parameters *param) +{ + struct lgdt3305_state *state = fe->demodulator_priv; + int ret; + + lg_dbg("(%d, %d)\n", param->frequency, param->u.vsb.modulation); + + if (fe->ops.tuner_ops.set_params) { + ret = fe->ops.tuner_ops.set_params(fe, param); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + if (lg_fail(ret)) + goto fail; + state->current_frequency = param->frequency; + } + + ret = lgdt3305_set_modulation(state, param); + if (lg_fail(ret)) + goto fail; + + ret = lgdt3305_passband_digital_agc(state, param); + if (lg_fail(ret)) + goto fail; + ret = lgdt3305_set_agc_power_ref(state, param); + if (lg_fail(ret)) + goto fail; + ret = lgdt3305_agc_setup(state, param); + if (lg_fail(ret)) + goto fail; + + /* low if */ + ret = lgdt3305_write_reg(state, LGDT3305_GEN_CONTROL, 0x2f); + if (lg_fail(ret)) + goto fail; + ret = lgdt3305_set_reg_bit(state, LGDT3305_CR_CTR_FREQ_1, 6, 1); + if (lg_fail(ret)) + goto fail; + + ret = lgdt3305_set_if(state, param); + if (lg_fail(ret)) + goto fail; + ret = lgdt3305_spectral_inversion(state, param, + state->cfg->spectral_inversion + ? 1 : 0); + if (lg_fail(ret)) + goto fail; + + ret = lgdt3305_set_filter_extension(state, param); + if (lg_fail(ret)) + goto fail; + + state->current_modulation = param->u.vsb.modulation; + + ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode); + if (lg_fail(ret)) + goto fail; + + /* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */ + ret = lgdt3305_mpeg_mode_polarity(state, + state->cfg->tpclk_edge, + state->cfg->tpvalid_polarity); +fail: + return ret; +} + +static int lgdt3305_get_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *param) +{ + struct lgdt3305_state *state = fe->demodulator_priv; + + lg_dbg("\n"); + + param->u.vsb.modulation = state->current_modulation; + param->frequency = state->current_frequency; + return 0; +} + +/* ------------------------------------------------------------------------ */ + +static int lgdt3305_read_cr_lock_status(struct lgdt3305_state *state, + int *locked) +{ + u8 val; + int ret; + char *cr_lock_state = ""; + + *locked = 0; + + ret = lgdt3305_read_reg(state, LGDT3305_CR_LOCK_STATUS, &val); + if (lg_fail(ret)) + goto fail; + + switch (state->current_modulation) { + case QAM_256: + case QAM_64: + if (val & (1 << 1)) + *locked = 1; + + switch (val & 0x07) { + case 0: + cr_lock_state = "QAM UNLOCK"; + break; + case 4: + cr_lock_state = "QAM 1stLock"; + break; + case 6: + cr_lock_state = "QAM 2ndLock"; + break; + case 7: + cr_lock_state = "QAM FinalLock"; + break; + default: + cr_lock_state = "CLOCKQAM-INVALID!"; + break; + } + break; + case VSB_8: + if (val & (1 << 7)) { + *locked = 1; + cr_lock_state = "CLOCKVSB"; + } + break; + default: + ret = -EINVAL; + } + lg_dbg("(%d) %s\n", *locked, cr_lock_state); +fail: + return ret; +} + +static int lgdt3305_read_fec_lock_status(struct lgdt3305_state *state, + int *locked) +{ + u8 val; + int ret, mpeg_lock, fec_lock, viterbi_lock; + + *locked = 0; + + switch (state->current_modulation) { + case QAM_256: + case QAM_64: + ret = lgdt3305_read_reg(state, + LGDT3305_FEC_LOCK_STATUS, &val); + if (lg_fail(ret)) + goto fail; + + mpeg_lock = (val & (1 << 0)) ? 1 : 0; + fec_lock = (val & (1 << 2)) ? 1 : 0; + viterbi_lock = (val & (1 << 3)) ? 1 : 0; + + *locked = mpeg_lock && fec_lock && viterbi_lock; + + lg_dbg("(%d) %s%s%s\n", *locked, + mpeg_lock ? "mpeg lock " : "", + fec_lock ? "fec lock " : "", + viterbi_lock ? "viterbi lock" : ""); + break; + case VSB_8: + default: + ret = -EINVAL; + } +fail: + return ret; +} + +static int lgdt3305_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + struct lgdt3305_state *state = fe->demodulator_priv; + u8 val; + int ret, signal, inlock, nofecerr, snrgood, + cr_lock, fec_lock, sync_lock; + + *status = 0; + + ret = lgdt3305_read_reg(state, LGDT3305_GEN_STATUS, &val); + if (lg_fail(ret)) + goto fail; + + signal = (val & (1 << 4)) ? 1 : 0; + inlock = (val & (1 << 3)) ? 0 : 1; + sync_lock = (val & (1 << 2)) ? 1 : 0; + nofecerr = (val & (1 << 1)) ? 1 : 0; + snrgood = (val & (1 << 0)) ? 1 : 0; + + lg_dbg("%s%s%s%s%s\n", + signal ? "SIGNALEXIST " : "", + inlock ? "INLOCK " : "", + sync_lock ? "SYNCLOCK " : "", + nofecerr ? "NOFECERR " : "", + snrgood ? "SNRGOOD " : ""); + + ret = lgdt3305_read_cr_lock_status(state, &cr_lock); + if (lg_fail(ret)) + goto fail; + + if (signal) + *status |= FE_HAS_SIGNAL; + if (cr_lock) + *status |= FE_HAS_CARRIER; + if (nofecerr) + *status |= FE_HAS_VITERBI; + if (sync_lock) + *status |= FE_HAS_SYNC; + + switch (state->current_modulation) { + case QAM_256: + case QAM_64: + ret = lgdt3305_read_fec_lock_status(state, &fec_lock); + if (lg_fail(ret)) + goto fail; + + if (fec_lock) + *status |= FE_HAS_LOCK; + break; + case VSB_8: + if (inlock) + *status |= FE_HAS_LOCK; + break; + default: + ret = -EINVAL; + } +fail: + return ret; +} + +/* ------------------------------------------------------------------------ */ + +/* borrowed from lgdt330x.c */ +static u32 calculate_snr(u32 mse, u32 c) +{ + if (mse == 0) /* no signal */ + return 0; + + mse = intlog10(mse); + if (mse > c) { + /* Negative SNR, which is possible, but realisticly the + demod will lose lock before the signal gets this bad. The + API only allows for unsigned values, so just return 0 */ + return 0; + } + return 10*(c - mse); +} + +static int lgdt3305_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + struct lgdt3305_state *state = fe->demodulator_priv; + u32 noise; /* noise value */ + u32 c; /* per-modulation SNR calculation constant */ + + switch (state->current_modulation) { + case VSB_8: +#ifdef USE_PTMSE + /* Use Phase Tracker Mean-Square Error Register */ + /* SNR for ranges from -13.11 to +44.08 */ + noise = ((read_reg(state, LGDT3305_PT_MSE_1) & 0x07) << 16) | + (read_reg(state, LGDT3305_PT_MSE_2) << 8) | + (read_reg(state, LGDT3305_PT_MSE_3) & 0xff); + c = 73957994; /* log10(25*32^2)*2^24 */ +#else + /* Use Equalizer Mean-Square Error Register */ + /* SNR for ranges from -16.12 to +44.08 */ + noise = ((read_reg(state, LGDT3305_EQ_MSE_1) & 0x0f) << 16) | + (read_reg(state, LGDT3305_EQ_MSE_2) << 8) | + (read_reg(state, LGDT3305_EQ_MSE_3) & 0xff); + c = 73957994; /* log10(25*32^2)*2^24 */ +#endif + break; + case QAM_64: + case QAM_256: + noise = (read_reg(state, LGDT3305_CR_MSE_1) << 8) | + (read_reg(state, LGDT3305_CR_MSE_2) & 0xff); + + c = (state->current_modulation == QAM_64) ? + 97939837 : 98026066; + /* log10(688128)*2^24 and log10(696320)*2^24 */ + break; + default: + return -EINVAL; + } + state->snr = calculate_snr(noise, c); +#if 0 + /* convert from 8.24 fixed-point to 8.8 */ + *snr = (state->snr) >> 16; +#else + /*report SNR in dB * 10 */ + *snr = (state->snr / ((1 << 24) / 10)); +#endif + lg_dbg("noise = 0x%08x, snr = %d.%02d dB\n", noise, + state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16); + + return 0; +} + +static int lgdt3305_read_signal_strength(struct dvb_frontend *fe, + u16 *strength) +{ + /* borrowed from lgdt330x.c + * + * Calculate strength from SNR up to 35dB + * Even though the SNR can go higher than 35dB, + * there is some comfort factor in having a range of + * strong signals that can show at 100% + */ + struct lgdt3305_state *state = fe->demodulator_priv; + u16 snr; + int ret; + + *strength = 0; + + ret = fe->ops.read_snr(fe, &snr); + if (lg_fail(ret)) + goto fail; + /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */ + /* scale the range 0 - 35*2^24 into 0 - 65535 */ + if (state->snr >= 8960 * 0x10000) + *strength = 0xffff; + else + *strength = state->snr / 8960; +fail: + return ret; +} + +/* ------------------------------------------------------------------------ */ + +static int lgdt3305_read_ber(struct dvb_frontend *fe, u32 *ber) +{ +#if 0 + struct lgdt3305_state *state = fe->demodulator_priv; + u32 period, biterror; + u8 bertperd; + + bertperd = read_reg(state, LGDT3305_BERT_PERIOD) & 0x1f; + if (bertperd < 4) + bertperd = 4; + period = (1 << bertperd); + + biterror = + (read_reg(state, LGDT3305_BERT_ERROR_COUNT_1) << 24) | + (read_reg(state, LGDT3305_BERT_ERROR_COUNT_2) << 16) | + (read_reg(state, LGDT3305_BERT_ERROR_COUNT_3) << 8) | + (read_reg(state, LGDT3305_BERT_ERROR_COUNT_4) & 0xff); + + *ber = (biterror) / period; + + lg_dbg("biterror = %d, period = %d, ber = 0x%x\n", + biterror, period, *ber); +#else + *ber = 0; +#endif + return 0; +} + +static int lgdt3305_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + struct lgdt3305_state *state = fe->demodulator_priv; + + *ucblocks = + (read_reg(state, LGDT3305_FEC_PKT_ERR_1) << 8) | + (read_reg(state, LGDT3305_FEC_PKT_ERR_2) & 0xff); + + return 0; +} + +static int lgdt3305_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings + *fe_tune_settings) +{ + fe_tune_settings->min_delay_ms = 500; + lg_dbg("\n"); + return 0; +} + +static void lgdt3305_release(struct dvb_frontend *fe) +{ + struct lgdt3305_state *state = fe->demodulator_priv; + lg_dbg("\n"); + kfree(state); +} + +static struct dvb_frontend_ops lgdt3305_ops; + +struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config, + struct i2c_adapter *i2c_adap) +{ + struct lgdt3305_state *state = NULL; + int ret; + u8 val; + + lg_dbg("(%d-%04x)\n", + i2c_adap ? i2c_adapter_id(i2c_adap) : 0, + config ? config->i2c_addr : 0); + + state = kzalloc(sizeof(struct lgdt3305_state), GFP_KERNEL); + if (state == NULL) + goto fail; + + state->cfg = config; + state->i2c_adap = i2c_adap; + + memcpy(&state->frontend.ops, &lgdt3305_ops, + sizeof(struct dvb_frontend_ops)); + state->frontend.demodulator_priv = state; + + /* verify that we're talking to a lg dt3305 */ + ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_2, &val); + if ((lg_fail(ret)) | (val == 0)) + goto fail; + ret = lgdt3305_write_reg(state, 0x0808, 0x80); + if (lg_fail(ret)) + goto fail; + ret = lgdt3305_read_reg(state, 0x0808, &val); + if ((lg_fail(ret)) | (val != 0x80)) + goto fail; + ret = lgdt3305_write_reg(state, 0x0808, 0x00); + if (lg_fail(ret)) + goto fail; + + state->current_frequency = -1; + state->current_modulation = -1; + + return &state->frontend; +fail: + lg_warn("unable to detect LGDT3305 hardware\n"); + state->frontend.demodulator_priv = NULL; + kfree(state); + return NULL; +} +EXPORT_SYMBOL(lgdt3305_attach); + +static struct dvb_frontend_ops lgdt3305_ops = { + .info = { + .name = "LG Electronics LGDT3305 VSB/QAM Frontend", + .type = FE_ATSC, + .frequency_min = 54000000, + .frequency_max = 858000000, + .frequency_stepsize = 62500, + .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB + }, + .i2c_gate_ctrl = lgdt3305_i2c_gate_ctrl, + .init = lgdt3305_init, + .sleep = lgdt3305_sleep, + .set_frontend = lgdt3305_set_parameters, + .get_frontend = lgdt3305_get_frontend, + .get_tune_settings = lgdt3305_get_tune_settings, + .read_status = lgdt3305_read_status, + .read_ber = lgdt3305_read_ber, + .read_signal_strength = lgdt3305_read_signal_strength, + .read_snr = lgdt3305_read_snr, + .read_ucblocks = lgdt3305_read_ucblocks, + .release = lgdt3305_release, +}; + +MODULE_DESCRIPTION("LG Electronics LGDT3305 ATSC/QAM-B Demodulator Driver"); +MODULE_AUTHOR("Michael Krufky"); +MODULE_LICENSE("GPL"); + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff --git a/linux/drivers/media/dvb/frontends/lgdt3305.h b/linux/drivers/media/dvb/frontends/lgdt3305.h new file mode 100644 index 000000000..4fa6e52d1 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/lgdt3305.h @@ -0,0 +1,85 @@ +/* + * Support for LGDT3305 - VSB/QAM + * + * Copyright (C) 2008, 2009 Michael Krufky + * + * 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 _LGDT3305_H_ +#define _LGDT3305_H_ + +#include +#include "dvb_frontend.h" + + +enum lgdt3305_mpeg_mode { + LGDT3305_MPEG_PARALLEL = 0, + LGDT3305_MPEG_SERIAL = 1, +}; + +enum lgdt3305_tp_clock_edge { + LGDT3305_TPCLK_RISING_EDGE = 0, + LGDT3305_TPCLK_FALLING_EDGE = 1, +}; + +enum lgdt3305_tp_valid_polarity { + LGDT3305_TP_VALID_LOW = 0, + LGDT3305_TP_VALID_HIGH = 1, +}; + +struct lgdt3305_config { + u8 i2c_addr; + + /* user defined IF frequency in KHz */ + u16 qam_if_khz; + u16 vsb_if_khz; + + /* AGC Power reference - defaults are used if left unset */ + u16 usref_8vsb; /* default: 0x32c4 */ + u16 usref_qam64; /* default: 0x5400 */ + u16 usref_qam256; /* default: 0x2a80 */ + + /* disable i2c repeater - 0:repeater enabled 1:repeater disabled */ + int deny_i2c_rptr:1; + + /* spectral inversion - 0:disabled 1:enabled */ + int spectral_inversion:1; + + /* use RF AGC loop - 0:disabled 1:enabled */ + int rf_agc_loop:1; + + enum lgdt3305_mpeg_mode mpeg_mode; + enum lgdt3305_tp_clock_edge tpclk_edge; + enum lgdt3305_tp_valid_polarity tpvalid_polarity; +}; + +#if defined(CONFIG_DVB_LGDT3305) || (defined(CONFIG_DVB_LGDT3305_MODULE) && \ + defined(MODULE)) +extern +struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config, + struct i2c_adapter *i2c_adap); +#else +static inline +struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config, + struct i2c_adapter *i2c_adap) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* CONFIG_DVB_LGDT3305 */ + +#endif /* _LGDT3305_H_ */ -- cgit v1.2.3 From dbfa06467e0da3deae2924fb49ff0c2898162da7 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 13 Jan 2009 09:55:40 +0100 Subject: gspca - sonixj: Cleanup code. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 225 +++++++++++++++---------------- 1 file changed, 111 insertions(+), 114 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index f4fb45fb3..89301e1e3 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -243,89 +243,86 @@ static const struct v4l2_pix_format vga_mode[] = { .priv = 0}, }; -/*Data from sn9c102p+hv71331r */ -static const __u8 sn_hv7131[] = { +/*Data from sn9c102p+hv7131r */ +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, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, -/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +/* reg18 reg19 reg1a reg1b */ + 0x0a, 0x00, 0x00, 0x00 }; -static const __u8 sn_mi0360[] = { +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, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, -/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +/* reg18 reg19 reg1a reg1b */ + 0x06, 0x00, 0x00, 0x00 }; -static const __u8 sn_mo4000[] = { +static const u8 sn_mo4000[0x1c] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18, + 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18, /* reg8 reg9 rega regb regc regd rege regf */ 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, -/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +/* reg18 reg19 reg1a reg1b */ + 0x08, 0x00, 0x00, 0x00 }; -static const __u8 sn_om6802[] = { +static const u8 sn_om6802[0x1c] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20, /* reg8 reg9 rega regb regc regd rege regf */ 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40, -/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf, - 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef, - 0xf7 +/* reg18 reg19 reg1a reg1b */ + 0x05, 0x00, 0x00, 0x00 }; -static const __u8 sn_ov7630[] = { +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, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2, -/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ - 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00 +/* reg18 reg19 reg1a reg1b */ + 0x0b, 0x00, 0x00, 0x00 }; -static const __u8 sn_ov7648[] = { +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, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00, -/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ - 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00 +/* reg18 reg19 reg1a reg1b */ + 0x0b, 0x00, 0x00, 0x00 }; -static const __u8 sn_ov7660[] = { +static const u8 sn_ov7660[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, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, -/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* reg18 reg19 reg1a reg1b */ + 0x07, 0x00, 0x00, 0x00 }; /* sequence specific to the sensors - !! index = SENSOR_xxx */ -static const __u8 *sn_tb[] = { +static const u8 *sn_tb[] = { sn_hv7131, sn_mi0360, sn_mo4000, @@ -348,88 +345,88 @@ static const __u8 reg84[] = { 0x00, 0x00, 0x00 /* YUV offsets */ }; static const __u8 hv7131r_sensor_init[][8] = { - {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, - {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10}, - {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10}, - {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10}, - {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, - - {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, - {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, - {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10}, - {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10}, - {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10}, - {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10}, - {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */ - {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */ - - {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, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10}, - - {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, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10}, + {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, + {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10}, + {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10}, +/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */ + {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10}, +/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */ + + {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, + {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10}, + {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10}, + {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10}, + {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10}, + {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */ + {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */ + + {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, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10}, + + {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, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10}, {} }; static const __u8 mi0360_sensor_init[][8] = { - {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, - {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10}, - {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10}, - {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10}, - {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10}, - {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10}, - {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10}, - {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10}, - {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10}, - {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10}, - {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10}, - {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10}, - - {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10}, - {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10}, - {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10}, - {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10}, - {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10}, - - {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */ - {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10}, - {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10}, - {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */ - - {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10}, - {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */ -/* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */ -/* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */ - {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */ - {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */ + {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, + {0xb1, 0x5d, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10}, + {0xb1, 0x5d, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10}, + {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10}, + {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10}, + {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10}, + {0xd1, 0x5d, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10}, + {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10}, + {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10}, + {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10}, + {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10}, + {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10}, + + {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10}, + {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10}, + {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10}, + {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10}, + {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10}, + + {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */ + {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10}, + {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, + {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */ + + {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10}, + {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */ +/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */ +/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */ + {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */ + {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */ {} }; static const __u8 mo4000_sensor_init[][8] = { @@ -680,15 +677,15 @@ static const __u8 ov7660_sensor_init[][8] = { static const __u8 qtable4[] = { 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06, - 0x06, 0x08, 0x0A, 0x11, - 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15, + 0x06, 0x08, 0x0a, 0x11, + 0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x15, 0x0f, 0x0f, 0x0c, 0x11, 0x19, 0x15, 0x19, 0x19, 0x17, 0x15, - 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17, - 0x21, 0x2E, 0x21, 0x23, - 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32, - 0x25, 0x29, 0x2C, 0x29, - 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B, - 0x17, 0x1B, 0x29, 0x29, + 0x17, 0x17, 0x1b, 0x1d, 0x25, 0x21, 0x1b, 0x1d, 0x23, 0x1d, 0x17, 0x17, + 0x21, 0x2e, 0x21, 0x23, + 0x27, 0x29, 0x2c, 0x2c, 0x2c, 0x19, 0x1f, 0x30, 0x32, 0x2e, 0x29, 0x32, + 0x25, 0x29, 0x2c, 0x29, + 0x06, 0x08, 0x08, 0x0a, 0x08, 0x0a, 0x13, 0x0a, 0x0a, 0x13, 0x29, 0x1b, + 0x17, 0x1b, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, -- cgit v1.2.3 From bb88bf784a8d66e5ef9285053fa68cf64750384d Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 13 Jan 2009 10:07:59 +0100 Subject: gspca - main: Cleanup code. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/gspca.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index a68b1a969..7d26c5de5 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -49,8 +49,6 @@ MODULE_LICENSE("GPL"); #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 5, 0) -static int video_nr = -1; - #ifdef GSPCA_DEBUG int gspca_debug = D_ERR | D_PROBE; EXPORT_SYMBOL(gspca_debug); @@ -129,7 +127,7 @@ 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 */ + u8 *data; /* address of data in the iso message */ int i, len, st; cam_pkt_op pkt_scan; @@ -169,7 +167,7 @@ static void fill_frame(struct gspca_dev *gspca_dev, /* let the packet be analyzed by the subdriver */ PDEBUG(D_PACK, "packet [%d] o:%d l:%d", i, urb->iso_frame_desc[i].offset, len); - data = (__u8 *) urb->transfer_buffer + data = (u8 *) urb->transfer_buffer + urb->iso_frame_desc[i].offset; pkt_scan(gspca_dev, frame, data, len); } @@ -185,11 +183,11 @@ static void fill_frame(struct gspca_dev *gspca_dev, * * Analyse each packet and call the subdriver for copy to the frame buffer. */ -static void isoc_irq(struct urb *urb #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) - , struct pt_regs *regs +static void isoc_irq(struct urb *urb, struct pt_regs *regs) +#else +static void isoc_irq(struct urb *urb) #endif -) { struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; @@ -202,11 +200,11 @@ static void isoc_irq(struct urb *urb /* * bulk message interrupt from the USB device */ -static void bulk_irq(struct urb *urb #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) - , struct pt_regs *regs +static void bulk_irq(struct urb *urb, struct pt_regs *regs) +#else +static void bulk_irq(struct urb *urb) #endif -) { struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; struct gspca_frame *frame; @@ -1923,7 +1921,7 @@ int gspca_dev_probe(struct usb_interface *intf, gspca_dev->present = 1; ret = video_register_device(&gspca_dev->vdev, VFL_TYPE_GRABBER, - video_nr); + -1); if (ret < 0) { err("video_register_device err %d", ret); goto out; -- cgit v1.2.3 From 6c4ccc0cd8e4160824698caa2bf36b96716a6a04 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 14 Jan 2009 16:17:59 +0000 Subject: lnbp21: documentation about the system register From: Hans Werner Here is a patch which adds some documentation about meanings of the the lnbp21 system register bits. Signed-off-by: Hans Werner Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/lnbp21.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/lnbp21.h b/linux/drivers/media/dvb/frontends/lnbp21.h index 8fe094bd9..b87458874 100644 --- a/linux/drivers/media/dvb/frontends/lnbp21.h +++ b/linux/drivers/media/dvb/frontends/lnbp21.h @@ -28,14 +28,14 @@ #define _LNBP21_H /* system register bits */ -#define LNBP21_OLF 0x01 -#define LNBP21_OTF 0x02 -#define LNBP21_EN 0x04 -#define LNBP21_VSEL 0x08 -#define LNBP21_LLC 0x10 -#define LNBP21_TEN 0x20 -#define LNBP21_ISEL 0x40 -#define LNBP21_PCL 0x80 +#define LNBP21_OLF 0x01 /* [R-only] 0=OK; 1=over current limit flag*/ +#define LNBP21_OTF 0x02 /* [R-only] 0=OK; 1=over temperature flag (150degC typ) */ +#define LNBP21_EN 0x04 /* [RW] 0=disable LNB power, enable loopthrough; 1=enable LNB power, disable loopthrough*/ +#define LNBP21_VSEL 0x08 /* [RW] 0=low voltage (13/14V, vert pol); 1=high voltage (18/19V,horiz pol) */ +#define LNBP21_LLC 0x10 /* [RW] increase LNB voltage by 1V: 0=13/18V; 1=14/19V */ +#define LNBP21_TEN 0x20 /* [RW] 0=tone controlled by DSQIN pin; 1=tone enable, disable DSQIN */ +#define LNBP21_ISEL 0x40 /* [RW] current limit select 0:Iout=500-650mA,Isc=300mA ; 1:Iout=400-550mA,Isc=200mA*/ +#define LNBP21_PCL 0x80 /* [RW] short-circuit prot: 0=pulsed (dynamic) curr limiting; 1=static curr limiting*/ #include -- cgit v1.2.3 From d80710822834998a63193a0ac525fab462363ecc Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 15 Jan 2009 10:11:49 +0100 Subject: gspca - mars: Bad interface/altsetting since 0a10a0e906be. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/mars.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/mars.c b/linux/drivers/media/video/gspca/mars.c index a91e69c40..c5a19b5bc 100644 --- a/linux/drivers/media/video/gspca/mars.c +++ b/linux/drivers/media/video/gspca/mars.c @@ -176,7 +176,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->colors = COLOR_DEF; sd->gamma = GAMMA_DEF; sd->sharpness = SHARPNESS_DEF; - gspca_dev->iface = 9; /* use the altsetting 08 */ + gspca_dev->nbalt = 9; /* use the altsetting 08 */ return 0; } -- cgit v1.2.3 From 5ec2fc0e30871584087a29363e0a50ac4abf1854 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 15 Jan 2009 12:01:32 +0100 Subject: gspca - sonixj: Gamma control added. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 68 +++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 89301e1e3..a30ae785b 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -44,6 +44,7 @@ struct sd { __u8 autogain; __u8 blue; __u8 red; + u8 gamma; __u8 vflip; /* ov7630 only */ __u8 infrared; /* mi0360 only */ @@ -78,6 +79,8 @@ static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val); static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val); static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getgamma(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_setvflip(struct gspca_dev *gspca_dev, __s32 val); @@ -158,6 +161,20 @@ static struct ctrl sd_ctrls[] = { .set = sd_setred_balance, .get = sd_getred_balance, }, + { + { + .id = V4L2_CID_GAMMA, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gamma", + .minimum = 0, + .maximum = 40, + .step = 1, +#define GAMMA_DEF 20 + .default_value = GAMMA_DEF, + }, + .set = sd_setgamma, + .get = sd_getgamma, + }, #define AUTOGAIN_IDX 5 { { @@ -332,11 +349,18 @@ static const u8 *sn_tb[] = { sn_ov7660 }; -static const __u8 gamma_def[] = { +static const __u8 gamma_def[17] = { 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff }; +#if 0 +static const __u8 gamma_hv7131[17] = { + 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d, + 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5 +}; +#endif + /* color matrix and offsets */ static const __u8 reg84[] = { 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */ @@ -1035,6 +1059,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->colors = COLOR_DEF; sd->blue = BLUE_BALANCE_DEF; sd->red = RED_BALANCE_DEF; + sd->gamma = GAMMA_DEF; sd->autogain = AUTOGAIN_DEF; sd->ag_cnt = -1; sd->vflip = VFLIP_DEF; @@ -1239,6 +1264,22 @@ static void setredblue(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x06, sd->blue); } +static void setgamma(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int i; + u8 gamma[17]; + static const u8 delta[17] = { + 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a, + 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00 + }; + + for (i = 0; i < sizeof gamma; i++) + gamma[i] = gamma_def[i] + + delta[i] * (sd->gamma - GAMMA_DEF) / 32; + reg_w(gspca_dev, 0x20, gamma, sizeof gamma); +} + static void setautogain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1326,7 +1367,12 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */ reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */ reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]); - reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def); +#if 0 + if (sd->sensor == SENSOR_HV7131R) + reg_w(gspca_dev, 0x20, gamma_hv7131, sizeof gamma_hv7131); + else +#endif + setgamma(gspca_dev); for (i = 0; i < 8; i++) reg_w(gspca_dev, 0x84, reg84, sizeof reg84); switch (sd->sensor) { @@ -1656,6 +1702,24 @@ static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->gamma = val; + if (gspca_dev->streaming) + setgamma(gspca_dev); + return 0; +} + +static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->gamma; + return 0; +} + static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; -- cgit v1.2.3 From 473e801c172a3223775ab624c4fb22441f5abab8 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 15 Jan 2009 13:34:55 +0100 Subject: gspca - spca500: Abnormal error message when starting ClickSmart310. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/spca500.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/spca500.c b/linux/drivers/media/video/gspca/spca500.c index 61b127022..94caba63b 100644 --- a/linux/drivers/media/video/gspca/spca500.c +++ b/linux/drivers/media/video/gspca/spca500.c @@ -728,7 +728,8 @@ static int sd_start(struct gspca_dev *gspca_dev) write_vector(gspca_dev, spca500_visual_defaults); spca500_setmode(gspca_dev, xmult, ymult); /* enable drop packet */ - reg_w(gspca_dev, 0x00, 0x850a, 0x0001); + err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001); + if (err < 0) PDEBUG(D_ERR, "failed to enable drop packet"); reg_w(gspca_dev, 0x00, 0x8880, 3); err = spca50x_setup_qtable(gspca_dev, -- cgit v1.2.3 From 03bcc8695fb4334e4e30d03a9dc0867361615c1a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 16 Feb 2009 15:27:44 -0300 Subject: Revert changeset aa3e5cc1d833 From: Mauro Carvalho Chehab On Mon, 02 Feb 2009, Hartmut wrote: This change set is wrong. The affected functions cannot be called from an interrupt context, because they may process large buffers. In this case, interrupts are disabled for a long time. Functions, like dvb_dmx_swfilter_packets(), could be called only from a tasklet. This change set does hide some strong design bugs in dm1105.c and au0828-dvb.c. Please revert this change set and do fix the bugs in dm1105.c and au0828-dvb.c (and other files). On Sun, 15 Feb 2009, Oliver Endriss wrote: This changeset _must_ be reverted! It breaks all kernels since 2.6.27 for applications which use DVB and require a low interrupt latency. It is a very bad idea to call the demuxer to process data buffers with interrupts disabled! On Mon, 16 Feb 2009, Trent Piepho wrote: I agree, this is bad. The demuxer is far too much work to be done with IRQs off. IMHO, even doing it under a spin-lock is excessive. It should be a mutex. Drivers should use a work-queue to feed the demuxer. Thank you for testing this changeset and discovering the issues on it. Priority: high CC: Trent Piepho CC: Hartmut CC: Oliver Endriss CC: Andreas Oberritter Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-core/dmxdev.c | 16 +++++++--------- linux/drivers/media/dvb/dvb-core/dvb_demux.c | 16 ++++++---------- 2 files changed, 13 insertions(+), 19 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.c b/linux/drivers/media/dvb/dvb-core/dmxdev.c index cc143929a..c35fbb8d8 100644 --- a/linux/drivers/media/dvb/dvb-core/dmxdev.c +++ b/linux/drivers/media/dvb/dvb-core/dmxdev.c @@ -364,16 +364,15 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, enum dmx_success success) { struct dmxdev_filter *dmxdevfilter = filter->priv; - unsigned long flags; int ret; if (dmxdevfilter->buffer.error) { wake_up(&dmxdevfilter->buffer.queue); return 0; } - spin_lock_irqsave(&dmxdevfilter->dev->lock, flags); + spin_lock(&dmxdevfilter->dev->lock); if (dmxdevfilter->state != DMXDEV_STATE_GO) { - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); return 0; } del_timer(&dmxdevfilter->timer); @@ -392,7 +391,7 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, } if (dmxdevfilter->params.sec.flags & DMX_ONESHOT) dmxdevfilter->state = DMXDEV_STATE_DONE; - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); wake_up(&dmxdevfilter->buffer.queue); return 0; } @@ -404,12 +403,11 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, { struct dmxdev_filter *dmxdevfilter = feed->priv; struct dvb_ringbuffer *buffer; - unsigned long flags; int ret; - spin_lock_irqsave(&dmxdevfilter->dev->lock, flags); + spin_lock(&dmxdevfilter->dev->lock); if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) { - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); return 0; } @@ -419,7 +417,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, else buffer = &dmxdevfilter->dev->dvr_buffer; if (buffer->error) { - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); wake_up(&buffer->queue); return 0; } @@ -430,7 +428,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, dvb_ringbuffer_flush(buffer); buffer->error = ret; } - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); wake_up(&buffer->queue); return 0; } diff --git a/linux/drivers/media/dvb/dvb-core/dvb_demux.c b/linux/drivers/media/dvb/dvb-core/dvb_demux.c index a2c1fd5d2..e2eca0b1f 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_demux.c @@ -399,9 +399,7 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count) { - unsigned long flags; - - spin_lock_irqsave(&demux->lock, flags); + spin_lock(&demux->lock); while (count--) { if (buf[0] == 0x47) @@ -409,17 +407,16 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, buf += 188; } - spin_unlock_irqrestore(&demux->lock, flags); + spin_unlock(&demux->lock); } EXPORT_SYMBOL(dvb_dmx_swfilter_packets); void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) { - unsigned long flags; int p = 0, i, j; - spin_lock_irqsave(&demux->lock, flags); + spin_lock(&demux->lock); if (demux->tsbufp) { i = demux->tsbufp; @@ -452,18 +449,17 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) } bailout: - spin_unlock_irqrestore(&demux->lock, flags); + spin_unlock(&demux->lock); } EXPORT_SYMBOL(dvb_dmx_swfilter); void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) { - unsigned long flags; int p = 0, i, j; u8 tmppack[188]; - spin_lock_irqsave(&demux->lock, flags); + spin_lock(&demux->lock); if (demux->tsbufp) { i = demux->tsbufp; @@ -504,7 +500,7 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) } bailout: - spin_unlock_irqrestore(&demux->lock, flags); + spin_unlock(&demux->lock); } EXPORT_SYMBOL(dvb_dmx_swfilter_204); -- cgit v1.2.3 From 6d5737990907617f67f5d8a9633ed16c8714171d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 16 Feb 2009 15:54:29 -0300 Subject: v4l2-framework.txt: Whitespace clenups From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/Documentation/video4linux/v4l2-framework.txt | 48 +++++++++++----------- 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'linux') diff --git a/linux/Documentation/video4linux/v4l2-framework.txt b/linux/Documentation/video4linux/v4l2-framework.txt index a6005257a..48cdf8624 100644 --- a/linux/Documentation/video4linux/v4l2-framework.txt +++ b/linux/Documentation/video4linux/v4l2-framework.txt @@ -531,11 +531,11 @@ struct v4l2_device *v4l2_dev = vdev->v4l2_dev; video buffer helper functions ----------------------------- -The v4l2 core API provides a standard method for dealing with video -buffers. Those methods allow a driver to implement read(), mmap() and +The v4l2 core API provides a standard method for dealing with video +buffers. Those methods allow a driver to implement read(), mmap() and overlay() on a consistent way. -There are currently methods for using video buffers on devices that +There are currently methods for using video buffers on devices that supports DMA with scatter/gather method (videobuf-dma-sg), DMA with linear access (videobuf-dma-contig), and vmalloced buffers, mostly used on USB drivers (videobuf-vmalloc). @@ -544,50 +544,50 @@ Any driver using videobuf should provide operations (callbacks) for four handlers: ops->buf_setup - calculates the size of the video buffers and avoid they - to waste more than some maximum limit of RAM; + to waste more than some maximum limit of RAM; ops->buf_prepare - fills the video buffer structs and calls videobuf_iolock() to alloc and prepare mmaped memory; ops->buf_queue - advices the driver that another buffer were - requested (by read() or by QBUF); + requested (by read() or by QBUF); ops->buf_release - frees any buffer that were allocated. In order to use it, the driver need to have a code (generally called at interrupt context) that will properly handle the buffer request lists, announcing that a new buffer were filled. -The irq handling code should handle the videobuf task lists, in order -to advice videobuf that a new frame were filled, in order to honor to a +The irq handling code should handle the videobuf task lists, in order +to advice videobuf that a new frame were filled, in order to honor to a request. The code is generally like this one: - if (list_empty(&dma_q->active)) + if (list_empty(&dma_q->active)) return; - buf = list_entry(dma_q->active.next, struct vbuffer, vb.queue); + buf = list_entry(dma_q->active.next, struct vbuffer, vb.queue); - if (!waitqueue_active(&buf->vb.done)) + if (!waitqueue_active(&buf->vb.done)) return; /* Some logic to handle the buf may be needed here */ - list_del(&buf->vb.queue); - do_gettimeofday(&buf->vb.ts); - wake_up(&buf->vb.done); + list_del(&buf->vb.queue); + do_gettimeofday(&buf->vb.ts); + wake_up(&buf->vb.done); -Those are the videobuffer functions used on drivers, implemented on +Those are the videobuffer functions used on drivers, implemented on videobuf-core: - Videobuf init functions videobuf_queue_sg_init() - Initializes the videobuf infrastructure. This function should be - called before any other videobuf function on drivers that uses DMA + Initializes the videobuf infrastructure. This function should be + called before any other videobuf function on drivers that uses DMA Scatter/Gather buffers. videobuf_queue_dma_contig_init - Initializes the videobuf infrastructure. This function should be - called before any other videobuf function on drivers that need DMA + Initializes the videobuf infrastructure. This function should be + called before any other videobuf function on drivers that need DMA contiguous buffers. videobuf_queue_vmalloc_init() - Initializes the videobuf infrastructure. This function should be + Initializes the videobuf infrastructure. This function should be called before any other videobuf function on USB (and other drivers) that need a vmalloced type of videobuf. @@ -607,12 +607,12 @@ videobuf-core: Stops video handling, ends mmap and frees mmap and other buffers. - V4L2 api functions. Those functions correspond to VIDIOC_foo ioctls: - videobuf_reqbufs(), videobuf_querybuf(), videobuf_qbuf(), + videobuf_reqbufs(), videobuf_querybuf(), videobuf_qbuf(), videobuf_dqbuf(), videobuf_streamon(), videobuf_streamoff(). - V4L1 api function (corresponds to VIDIOCMBUF ioctl): videobuf_cgmbuf() - This function is used to provide backward compatibility with V4L1 + This function is used to provide backward compatibility with V4L1 API. - Some help functions for read()/poll() operations: @@ -623,7 +623,7 @@ videobuf-core: videobuf_poll_stream() polling help function -The better way to understand it is to take a look at vivi driver. One -of the main reasons for vivi is to be a videobuf usage example. the -vivi_thread_tick() does the task that the IRQ callback would do on PCI +The better way to understand it is to take a look at vivi driver. One +of the main reasons for vivi is to be a videobuf usage example. the +vivi_thread_tick() does the task that the IRQ callback would do on PCI drivers (or the irq callback on USB). -- cgit v1.2.3 From 7c429cdbe8e7fa93d0c24d10749fe2a2bdd5e524 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 15 Jan 2009 21:58:55 +0900 Subject: saa7134: fix Avermedia E506R composite input From: Tim Farrington Make correction to composite input plus svideo input to Avermedia E506R Signed-off-by: Tim Farrington Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-cards.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c index 01cc9543f..e565d437b 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -4362,13 +4362,13 @@ struct saa7134_board saa7134_boards[] = { .amux = TV, .tv = 1, }, { - .name = name_comp, - .vmux = 0, + .name = name_comp1, + .vmux = 3, .amux = LINE1, }, { .name = name_svideo, .vmux = 8, - .amux = LINE1, + .amux = LINE2, } }, .radio = { .name = name_radio, -- cgit v1.2.3 From cbcab20c894ef4986a6dc8fd9797c6fa83fcd249 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 16 Jan 2009 09:28:38 +0100 Subject: Add Mars-Semi MR97310A format From: Kyle Guinn The MR97310A is a dual-mode webcam controller that provides compressed BGGR Bayer frames. The decompression algorithm for still images is the same as for video, and is currently implemented in libgphoto2. Priority: normal Signed-off-by: Kyle Guinn Signed-off-by: Jean-Francois Moine --- linux/include/linux/videodev2.h | 1 + 1 file changed, 1 insertion(+) (limited to 'linux') diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index b0c501074..e5be28ac6 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -344,6 +344,7 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_SPCA508 v4l2_fourcc('S', '5', '0', '8') /* YUVY per line */ #define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */ #define V4L2_PIX_FMT_PAC207 v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */ +#define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */ #define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */ #define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */ -- cgit v1.2.3 From f849265ace360a44941e106a3a0b6072f422df40 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 16 Jan 2009 09:36:14 +0100 Subject: gspca - mr97310a: New subdriver. From: Kyle Guinn This patch adds support for USB webcams based on the MR97310A chip. It was tested with an Aiptek PenCam VGA+ webcam. Priority: normal Signed-off-by: Kyle Guinn Signed-off-by: Jean-Francois Moine --- linux/Documentation/video4linux/gspca.txt | 1 + linux/drivers/media/video/gspca/Kconfig | 9 + linux/drivers/media/video/gspca/Makefile | 98 ++++---- linux/drivers/media/video/gspca/gspca.c | 1 + linux/drivers/media/video/gspca/mr97310a.c | 378 +++++++++++++++++++++++++++++ 5 files changed, 439 insertions(+), 48 deletions(-) create mode 100644 linux/drivers/media/video/gspca/mr97310a.c (limited to 'linux') diff --git a/linux/Documentation/video4linux/gspca.txt b/linux/Documentation/video4linux/gspca.txt index 1c58a7630..af80c3344 100644 --- a/linux/Documentation/video4linux/gspca.txt +++ b/linux/Documentation/video4linux/gspca.txt @@ -193,6 +193,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:0111 Aiptek PenCam VGA+ sunplus 08ca:2008 Aiptek Mini PenCam 2 M sunplus 08ca:2010 Aiptek PocketCam 3M sunplus 08ca:2016 Aiptek PocketCam 2 Mega diff --git a/linux/drivers/media/video/gspca/Kconfig b/linux/drivers/media/video/gspca/Kconfig index ee6a691df..11c5d2fc2 100644 --- a/linux/drivers/media/video/gspca/Kconfig +++ b/linux/drivers/media/video/gspca/Kconfig @@ -56,6 +56,15 @@ config USB_GSPCA_MARS To compile this driver as a module, choose M here: the module will be called gspca_mars. +config USB_GSPCA_MR97310A + tristate "Mars-Semi MR97310A USB Camera Driver" + depends on VIDEO_V4L2 && USB_GSPCA + help + Say Y here if you want support for cameras based on the MR97310A chip. + + To compile this driver as a module, choose M here: the + module will be called gspca_mr97310a. + config USB_GSPCA_OV519 tristate "OV519 USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA diff --git a/linux/drivers/media/video/gspca/Makefile b/linux/drivers/media/video/gspca/Makefile index bd8d9ee40..b3cbcc176 100644 --- a/linux/drivers/media/video/gspca/Makefile +++ b/linux/drivers/media/video/gspca/Makefile @@ -1,50 +1,52 @@ -obj-$(CONFIG_USB_GSPCA) += gspca_main.o -obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o -obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o -obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o -obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.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_PAC7311) += gspca_pac7311.o -obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o -obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o -obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o -obj-$(CONFIG_USB_GSPCA_SPCA501) += gspca_spca501.o -obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o -obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o -obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o -obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o -obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o -obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.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 -obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o +obj-$(CONFIG_USB_GSPCA) += gspca_main.o +obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o +obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o +obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o +obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o +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_PAC7311) += gspca_pac7311.o +obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o +obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o +obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o +obj-$(CONFIG_USB_GSPCA_SPCA501) += gspca_spca501.o +obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o +obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o +obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o +obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o +obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o +obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.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 +obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o -gspca_main-objs := gspca.o -gspca_conex-objs := conex.o -gspca_etoms-objs := etoms.o -gspca_finepix-objs := finepix.o -gspca_mars-objs := mars.o -gspca_ov519-objs := ov519.o -gspca_ov534-objs := ov534.o -gspca_pac207-objs := pac207.o -gspca_pac7311-objs := pac7311.o -gspca_sonixb-objs := sonixb.o -gspca_sonixj-objs := sonixj.o -gspca_spca500-objs := spca500.o -gspca_spca501-objs := spca501.o -gspca_spca505-objs := spca505.o -gspca_spca506-objs := spca506.o -gspca_spca508-objs := spca508.o -gspca_spca561-objs := spca561.o -gspca_stk014-objs := stk014.o -gspca_sunplus-objs := sunplus.o -gspca_t613-objs := t613.o -gspca_tv8532-objs := tv8532.o -gspca_vc032x-objs := vc032x.o -gspca_zc3xx-objs := zc3xx.o +gspca_main-objs := gspca.o +gspca_conex-objs := conex.o +gspca_etoms-objs := etoms.o +gspca_finepix-objs := finepix.o +gspca_mars-objs := mars.o +gspca_mr97310a-objs := mr97310a.o +gspca_ov519-objs := ov519.o +gspca_ov534-objs := ov534.o +gspca_pac207-objs := pac207.o +gspca_pac7311-objs := pac7311.o +gspca_sonixb-objs := sonixb.o +gspca_sonixj-objs := sonixj.o +gspca_spca500-objs := spca500.o +gspca_spca501-objs := spca501.o +gspca_spca505-objs := spca505.o +gspca_spca506-objs := spca506.o +gspca_spca508-objs := spca508.o +gspca_spca561-objs := spca561.o +gspca_stk014-objs := stk014.o +gspca_sunplus-objs := sunplus.o +gspca_t613-objs := t613.o +gspca_tv8532-objs := tv8532.o +gspca_vc032x-objs := vc032x.o +gspca_zc3xx-objs := zc3xx.o -obj-$(CONFIG_USB_M5602) += m5602/ -obj-$(CONFIG_USB_STV06XX) += stv06xx/ +obj-$(CONFIG_USB_M5602) += m5602/ +obj-$(CONFIG_USB_STV06XX) += stv06xx/ diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index 7d26c5de5..d394e06b8 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -329,6 +329,7 @@ static int gspca_is_compressed(__u32 format) case V4L2_PIX_FMT_JPEG: case V4L2_PIX_FMT_SPCA561: case V4L2_PIX_FMT_PAC207: + case V4L2_PIX_FMT_MR97310A: return 1; } return 0; diff --git a/linux/drivers/media/video/gspca/mr97310a.c b/linux/drivers/media/video/gspca/mr97310a.c new file mode 100644 index 000000000..24180bf0c --- /dev/null +++ b/linux/drivers/media/video/gspca/mr97310a.c @@ -0,0 +1,378 @@ +/* + * Mars MR97310A library + * + * Copyright (C) 2009 Kyle Guinn + * + * 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 + */ + +#define MODULE_NAME "mr97310a" + +#include "gspca.h" + +MODULE_AUTHOR("Kyle Guinn "); +MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + u8 sof_read; + u8 header_read; +}; + +/* V4L2 controls supported by the driver */ +static struct ctrl sd_ctrls[] = { +}; + +static const struct v4l2_pix_format vga_mode[] = { + {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, + .bytesperline = 160, + .sizeimage = 160 * 120, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 4}, + {176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, + .bytesperline = 176, + .sizeimage = 176 * 144, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 3}, + {320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 2}, + {352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, + .bytesperline = 352, + .sizeimage = 352 * 288, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1}, + {640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, +}; + +/* the bytes to write are in gspca_dev->usb_buf */ +static int reg_w(struct gspca_dev *gspca_dev, int len) +{ + int rc; + + rc = usb_bulk_msg(gspca_dev->dev, + usb_sndbulkpipe(gspca_dev->dev, 4), + gspca_dev->usb_buf, len, 0, 500); + if (rc < 0) + PDEBUG(D_ERR, "reg write [%02x] error %d", + gspca_dev->usb_buf[0], rc); + return rc; +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct cam *cam; + + cam = &gspca_dev->cam; + cam->cam_mode = vga_mode; + cam->nmodes = ARRAY_SIZE(vga_mode); + return 0; +} + +/* this function is called at probe and resume time */ +static int sd_init(struct gspca_dev *gspca_dev) +{ + return 0; +} + +static int sd_start(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 *data = gspca_dev->usb_buf; + int err_code; + + sd->sof_read = 0; + + /* Note: register descriptions guessed from MR97113A driver */ + + data[0] = 0x01; + data[1] = 0x01; + err_code = reg_w(gspca_dev, 2); + if (err_code < 0) + return err_code; + + data[0] = 0x00; + data[1] = 0x0d; + data[2] = 0x01; + data[5] = 0x2b; + data[7] = 0x00; + data[9] = 0x50; /* reg 8, no scale down */ + data[10] = 0xc0; + + switch (gspca_dev->width) { + case 160: + data[9] |= 0x0c; /* reg 8, 4:1 scale down */ + /* fall thru */ + case 320: + data[9] |= 0x04; /* reg 8, 2:1 scale down */ + /* fall thru */ + case 640: + default: + data[3] = 0x50; /* reg 2, H size */ + data[4] = 0x78; /* reg 3, V size */ + data[6] = 0x04; /* reg 5, H start */ + data[8] = 0x03; /* reg 7, V start */ + break; + + case 176: + data[9] |= 0x04; /* reg 8, 2:1 scale down */ + /* fall thru */ + case 352: + data[3] = 0x2c; /* reg 2, H size */ + data[4] = 0x48; /* reg 3, V size */ + data[6] = 0x94; /* reg 5, H start */ + data[8] = 0x63; /* reg 7, V start */ + break; + } + + err_code = reg_w(gspca_dev, 11); + if (err_code < 0) + return err_code; + + data[0] = 0x0a; + data[1] = 0x80; + err_code = reg_w(gspca_dev, 2); + if (err_code < 0) + return err_code; + + data[0] = 0x14; + data[1] = 0x0a; + err_code = reg_w(gspca_dev, 2); + if (err_code < 0) + return err_code; + + data[0] = 0x1b; + data[1] = 0x00; + err_code = reg_w(gspca_dev, 2); + if (err_code < 0) + return err_code; + + data[0] = 0x15; + data[1] = 0x16; + err_code = reg_w(gspca_dev, 2); + if (err_code < 0) + return err_code; + + data[0] = 0x16; + data[1] = 0x10; + err_code = reg_w(gspca_dev, 2); + if (err_code < 0) + return err_code; + + data[0] = 0x17; + data[1] = 0x3a; + err_code = reg_w(gspca_dev, 2); + if (err_code < 0) + return err_code; + + data[0] = 0x18; + data[1] = 0x68; + err_code = reg_w(gspca_dev, 2); + if (err_code < 0) + return err_code; + + data[0] = 0x1f; + data[1] = 0x00; + data[2] = 0x02; + data[3] = 0x06; + data[4] = 0x59; + data[5] = 0x0c; + data[6] = 0x16; + data[7] = 0x00; + data[8] = 0x07; + data[9] = 0x00; + data[10] = 0x01; + err_code = reg_w(gspca_dev, 11); + if (err_code < 0) + return err_code; + + data[0] = 0x1f; + data[1] = 0x04; + data[2] = 0x11; + data[3] = 0x01; + err_code = reg_w(gspca_dev, 4); + if (err_code < 0) + return err_code; + + data[0] = 0x1f; + data[1] = 0x00; + data[2] = 0x0a; + data[3] = 0x00; + data[4] = 0x01; + data[5] = 0x00; + data[6] = 0x00; + data[7] = 0x01; + data[8] = 0x00; + data[9] = 0x0a; + err_code = reg_w(gspca_dev, 10); + if (err_code < 0) + return err_code; + + data[0] = 0x1f; + data[1] = 0x04; + data[2] = 0x11; + data[3] = 0x01; + err_code = reg_w(gspca_dev, 4); + if (err_code < 0) + return err_code; + + data[0] = 0x1f; + data[1] = 0x00; + data[2] = 0x12; + data[3] = 0x00; + data[4] = 0x63; + data[5] = 0x00; + data[6] = 0x70; + data[7] = 0x00; + data[8] = 0x01; + err_code = reg_w(gspca_dev, 10); + if (err_code < 0) + return err_code; + + data[0] = 0x1f; + data[1] = 0x04; + data[2] = 0x11; + data[3] = 0x01; + err_code = reg_w(gspca_dev, 4); + if (err_code < 0) + return err_code; + + data[0] = 0x00; + data[1] = 0x4d; /* ISOC transfering enable... */ + err_code = reg_w(gspca_dev, 2); + return err_code; +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + int result; + + gspca_dev->usb_buf[0] = 1; + gspca_dev->usb_buf[1] = 0; + result = reg_w(gspca_dev, 2); + if (result < 0) + PDEBUG(D_ERR, "Camera Stop failed"); +} + +/* Include pac common sof detection functions */ +#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 */ +{ + struct sd *sd = (struct sd *) gspca_dev; + unsigned char *sof; + + sof = pac_find_sof(gspca_dev, data, len); + if (sof) { + int n; + + /* finish decoding current frame */ + n = sof - data; + if (n > sizeof pac_sof_marker) + n -= sizeof pac_sof_marker; + else + n = 0; + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + data, n); + sd->header_read = 0; + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0); + len -= sof - data; + data = sof; + } + if (sd->header_read < 7) { + int needed; + + /* skip the rest of the header */ + needed = 7 - sd->header_read; + if (len <= needed) { + sd->header_read += len; + return; + } + data += needed; + len -= needed; + sd->header_read = 7; + } + + gspca_frame_add(gspca_dev, INTER_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, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +static const __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x08ca, 0x0111)}, + {} +}; +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) +{ + if (usb_register(&sd_driver) < 0) + return -1; + 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); -- cgit v1.2.3 From 3f72fef8e0c14f63c1c530cd571a89491f997650 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 16 Jan 2009 12:57:28 +0100 Subject: gspca - spca561: Optimize the isoc scanning function. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/spca561.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/spca561.c b/linux/drivers/media/video/gspca/spca561.c index b991ddde5..bcc8e863d 100644 --- a/linux/drivers/media/video/gspca/spca561.c +++ b/linux/drivers/media/video/gspca/spca561.c @@ -141,7 +141,6 @@ static const struct v4l2_pix_format sif_072a_mode[] = { #define SPCA561_OFFSET_WIN1GBAVE 14 #define SPCA561_OFFSET_FREQ 15 #define SPCA561_OFFSET_VSYNC 16 -#define SPCA561_OFFSET_DATA 1 #define SPCA561_INDEX_I2C_BASE 0x8800 #define SPCA561_SNAPBIT 0x20 #define SPCA561_SNAPCTRL 0x40 @@ -873,12 +872,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; - switch (data[0]) { /* sequence number */ + len--; + switch (*data++) { /* sequence number */ case 0: /* start of frame */ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); - data += SPCA561_OFFSET_DATA; - len -= SPCA561_OFFSET_DATA; if (data[1] & 0x10) { /* compressed bayer */ gspca_frame_add(gspca_dev, FIRST_PACKET, @@ -899,8 +897,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, case 0xff: /* drop (empty mpackets) */ return; } - data++; - len--; gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); } -- cgit v1.2.3 From 44db8c2b6b0e80127bb8876565234ce97f3c8628 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 16 Jan 2009 20:24:28 +0100 Subject: gspca - spca561: Fix bugs and rewrite the init/start of the rev72a. From: Jean-Francois Moine The bugs were in the first init sequence of the sensor. The rewrite is adapted from a ms-win trace. Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/spca561.c | 160 ++++++++++-------------------- 1 file changed, 50 insertions(+), 110 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/spca561.c b/linux/drivers/media/video/gspca/spca561.c index bcc8e863d..f92cb0e4a 100644 --- a/linux/drivers/media/video/gspca/spca561.c +++ b/linux/drivers/media/video/gspca/spca561.c @@ -145,33 +145,34 @@ static const struct v4l2_pix_format sif_072a_mode[] = { #define SPCA561_SNAPBIT 0x20 #define SPCA561_SNAPCTRL 0x40 -static const __u16 rev72a_init_data1[][2] = { +static const u16 rev72a_reset[][2] = { {0x0000, 0x8114}, /* Software GPIO output data */ {0x0001, 0x8114}, /* Software GPIO output data */ {0x0000, 0x8112}, /* Some kind of reset */ + {} +}; +static const __u16 rev72a_init_data1[][2] = { {0x0003, 0x8701}, /* PCLK clock delay adjustment */ {0x0001, 0x8703}, /* HSYNC from cmos inverted */ {0x0011, 0x8118}, /* Enable and conf sensor */ {0x0001, 0x8118}, /* Conf sensor */ {0x0092, 0x8804}, /* I know nothing about these */ {0x0010, 0x8802}, /* 0x88xx registers, so I won't */ - {0x000d, 0x8805}, /* sensor default setting */ {} }; -static const __u16 rev72a_init_sensor1[][2] = { - /* ms-win values */ - {0x0001, 0x0018}, /* 0x01 <- 0x0d */ - {0x0002, 0x0065}, /* 0x02 <- 0x18 */ - {0x0004, 0x0121}, /* 0x04 <- 0x0165 */ - {0x0005, 0x00aa}, /* 0x05 <- 0x21 */ - {0x0007, 0x0004}, /* 0x07 <- 0xaa */ - {0x0020, 0x1502}, /* 0x20 <- 0x1504 */ - {0x0039, 0x0010}, /* 0x39 <- 0x02 */ - {0x0035, 0x0049}, /* 0x35 <- 0x10 */ - {0x0009, 0x100b}, /* 0x09 <- 0x1049 */ - {0x0028, 0x000f}, /* 0x28 <- 0x0b */ - {0x003b, 0x003c}, /* 0x3b <- 0x0f */ - {0x003c, 0x0000}, /* 0x3c <- 0x00 */ +static const u16 rev72a_init_sensor1[][2] = { + {0x0001, 0x000d}, + {0x0002, 0x0018}, + {0x0004, 0x0165}, + {0x0005, 0x0021}, + {0x0007, 0x00aa}, + {0x0020, 0x1504}, + {0x0039, 0x0002}, + {0x0035, 0x0010}, + {0x0009, 0x1049}, + {0x0028, 0x000b}, + {0x003b, 0x000f}, + {0x003c, 0x0000}, {} }; static const __u16 rev72a_init_data2[][2] = { @@ -189,15 +190,23 @@ static const __u16 rev72a_init_data2[][2] = { {0x0002, 0x8201}, /* Output address for r/w serial EEPROM */ {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */ {0x0001, 0x8200}, /* OprMode to be executed by hardware */ +#if 0 {0x0007, 0x8201}, /* Output address for r/w serial EEPROM */ {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */ {0x0001, 0x8200}, /* OprMode to be executed by hardware */ {0x0010, 0x8660}, /* Compensation memory stuff */ {0x0018, 0x8660}, /* Compensation memory stuff */ - +#endif +#if 1 +/* from ms-win */ + {0x0000, 0x8611}, /* R offset for white balance */ + {0x00fd, 0x8612}, /* Gr offset for white balance */ + {0x0003, 0x8613}, /* B offset for white balance */ +#else {0x0004, 0x8611}, /* R offset for white balance */ {0x0004, 0x8612}, /* Gr offset for white balance */ {0x0007, 0x8613}, /* B offset for white balance */ +#endif {0x0000, 0x8614}, /* Gb offset for white balance */ #if 1 /* from ms-win */ @@ -212,8 +221,8 @@ static const __u16 rev72a_init_data2[][2] = { {0x008c, 0x8654}, /* Gb gain for white balance */ #endif {0x0002, 0x8502}, /* Maximum average bit rate stuff */ - {0x0011, 0x8802}, + {0x0087, 0x8700}, /* Set master clock (96Mhz????) */ {0x0081, 0x8702}, /* Master clock output enable */ @@ -224,106 +233,28 @@ static const __u16 rev72a_init_data2[][2] = { {0x0003, 0x865c}, /* Vertical offset for valid lines */ {} }; -static const __u16 rev72a_init_sensor2[][2] = { - /* ms-win values */ - {0x0003, 0x0121}, /* 0x03 <- 0x01 0x21 //289 */ - {0x0004, 0x0165}, /* 0x04 <- 0x01 0x65 //357 */ - {0x0005, 0x002f}, /* 0x05 <- 0x2f */ - {0x0006, 0x0000}, /* 0x06 <- 0 */ - {0x000a, 0x0002}, /* 0x0a <- 2 */ - {0x0009, 0x1061}, /* 0x09 <- 0x1061 */ - {0x0035, 0x0014}, /* 0x35 <- 0x14 */ +static const u16 rev72a_init_sensor2[][2] = { + {0x0003, 0x0121}, + {0x0004, 0x0165}, + {0x0005, 0x002f}, /* blanking control column */ + {0x0006, 0x0000}, /* blanking mode row*/ + {0x000a, 0x0002}, + {0x0009, 0x1061}, /* setexposure times && pixel clock + * 0001 0 | 000 0110 0001 */ + {0x0035, 0x0014}, {} }; +#if 0 static const __u16 rev72a_init_data3[][2] = { - {0x0030, 0x8112}, /* ISO and drop packet enable */ -/*fixme: should stop here*/ - {0x0000, 0x8112}, /* Some kind of reset ???? */ - {0x0009, 0x8118}, /* Enable sensor and set standby */ - {0x0000, 0x8114}, /* Software GPIO output data */ - {0x0000, 0x8114}, /* Software GPIO output data */ - {0x0001, 0x8114}, /* Software GPIO output data */ - {0x0000, 0x8112}, /* Some kind of reset ??? */ - {0x0003, 0x8701}, - {0x0001, 0x8703}, - {0x0011, 0x8118}, - {0x0001, 0x8118}, - /***************/ - {0x0092, 0x8804}, - {0x0010, 0x8802}, - {0x000d, 0x8805}, - {0x0001, 0x8801}, - {0x0000, 0x8800}, - {0x0018, 0x8805}, - {0x0002, 0x8801}, - {0x0000, 0x8800}, - {0x0065, 0x8805}, - {0x0004, 0x8801}, - {0x0001, 0x8800}, - {0x0021, 0x8805}, - {0x0005, 0x8801}, - {0x0000, 0x8800}, - {0x00aa, 0x8805}, - {0x0007, 0x8801}, /* mode 0xaa */ - {0x0000, 0x8800}, - {0x0004, 0x8805}, - {0x0020, 0x8801}, - {0x0015, 0x8800}, /* mode 0x0415 */ - {0x0002, 0x8805}, - {0x0039, 0x8801}, - {0x0000, 0x8800}, - {0x0010, 0x8805}, - {0x0035, 0x8801}, - {0x0000, 0x8800}, - {0x0049, 0x8805}, - {0x0009, 0x8801}, - {0x0010, 0x8800}, - {0x000b, 0x8805}, - {0x0028, 0x8801}, - {0x0000, 0x8800}, - {0x000f, 0x8805}, - {0x003b, 0x8801}, - {0x0000, 0x8800}, - {0x0000, 0x8805}, - {0x003c, 0x8801}, - {0x0000, 0x8800}, - {0x0002, 0x8502}, - {0x0039, 0x8801}, - {0x0000, 0x8805}, - {0x0000, 0x8800}, - {0x0087, 0x8700}, /* overwrite by start */ {0x0081, 0x8702}, {0x0000, 0x8500}, /* {0x0010, 0x8500}, -- Previous line was this */ {0x0002, 0x865b}, {0x0003, 0x865c}, - /***************/ - {0x0003, 0x8801}, /* 0x121-> 289 */ - {0x0021, 0x8805}, - {0x0001, 0x8800}, - {0x0004, 0x8801}, /* 0x165 -> 357 */ - {0x0065, 0x8805}, - {0x0001, 0x8800}, - {0x0005, 0x8801}, /* 0x2f //blanking control colonne */ - {0x002f, 0x8805}, - {0x0000, 0x8800}, - {0x0006, 0x8801}, /* 0x00 //blanking mode row */ - {0x0000, 0x8805}, - {0x0000, 0x8800}, - {0x000a, 0x8801}, /* 0x01 //0x02 */ - {0x0001, 0x8805}, - {0x0000, 0x8800}, - {0x0009, 0x8801}, /* 0x1061 - setexposure times && pixel clock - * 0001 0 | 000 0110 0001 */ - {0x0061, 0x8805}, /* 61 31 */ - {0x0008, 0x8800}, /* 08 */ - {0x0035, 0x8801}, /* 0x14 - set gain general */ - {0x001f, 0x8805}, /* 0x14 */ - {0x0000, 0x8800}, - {0x000e, 0x8112}, /* white balance - was 30 */ {} }; +#endif /******************** QC Express etch2 stuff ********************/ static const __u16 Pb100_1map8300[][2] = { @@ -466,6 +397,7 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg) reg_r(gspca_dev, 0x8803, 1); if (!gspca_dev->usb_buf[0]) return; + msleep(10); } while (--retry); } @@ -485,6 +417,7 @@ static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode) reg_r(gspca_dev, 0x8805, 1); return ((int) value << 8) | gspca_dev->usb_buf[0]; } + msleep(10); } while (--retry); return -1; } @@ -577,11 +510,13 @@ static int sd_init_12a(struct gspca_dev *gspca_dev) static int sd_init_72a(struct gspca_dev *gspca_dev) { PDEBUG(D_STREAM, "Chip revision: 072a"); + write_vector(gspca_dev, rev72a_reset); + msleep(200); write_vector(gspca_dev, rev72a_init_data1); write_sensor_72a(gspca_dev, rev72a_init_sensor1); write_vector(gspca_dev, rev72a_init_data2); write_sensor_72a(gspca_dev, rev72a_init_sensor2); - write_vector(gspca_dev, rev72a_init_data3); + reg_w_val(gspca_dev->dev, 0x8112, 0x30); return 0; } @@ -736,6 +671,11 @@ static int sd_start_72a(struct gspca_dev *gspca_dev) int Clck; int mode; + write_vector(gspca_dev, rev72a_reset); + msleep(200); + write_vector(gspca_dev, rev72a_init_data1); + write_sensor_72a(gspca_dev, rev72a_init_sensor1); + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; switch (mode) { default: @@ -752,11 +692,11 @@ static int sd_start_72a(struct gspca_dev *gspca_dev) } reg_w_val(dev, 0x8500, mode); /* mode */ reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ - reg_w_val(dev, 0x8112, 0x10 | 0x20); + write_sensor_72a(gspca_dev, rev72a_init_sensor2); setcontrast(gspca_dev); /* setbrightness(gspca_dev); * fixme: bad values */ - setwhite(gspca_dev); setautogain(gspca_dev); + reg_w_val(dev, 0x8112, 0x10 | 0x20); return 0; } -- cgit v1.2.3 From 20efecf448cb947333d934e1ae183c04f2c252f5 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 17 Jan 2009 08:32:32 +0100 Subject: gspca - mr97310a: Fix camera initialization copy/paste bugs. From: Kyle Guinn Priority: normal Signed-off-by: Kyle Guinn Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/mr97310a.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/mr97310a.c b/linux/drivers/media/video/gspca/mr97310a.c index 24180bf0c..3a5ddff8f 100644 --- a/linux/drivers/media/video/gspca/mr97310a.c +++ b/linux/drivers/media/video/gspca/mr97310a.c @@ -247,8 +247,8 @@ static int sd_start(struct gspca_dev *gspca_dev) data[5] = 0x00; data[6] = 0x70; data[7] = 0x00; - data[8] = 0x01; - err_code = reg_w(gspca_dev, 10); + data[8] = 0x00; + err_code = reg_w(gspca_dev, 9); if (err_code < 0) return err_code; -- cgit v1.2.3 From 5da98ad023d302d16ec64a0c6dfbf7028cb6e878 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 17 Jan 2009 08:46:38 +0100 Subject: gspca - main: Have 3 URBs instead of 2 for ISOC transfers. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/gspca.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index d394e06b8..ed129db3d 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -41,7 +41,10 @@ #include "gspca.h" /* global values */ -#define DEF_NURBS 2 /* default number of URBs */ +#define DEF_NURBS 3 /* default number of URBs */ +#if DEF_NURBS > MAX_NURBS +#error "DEF_NURBS too big" +#endif MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("GSPCA USB Camera Driver"); -- cgit v1.2.3 From c1c20ef1d4eb6515fd12b715aade9be9012a0723 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 18 Jan 2009 18:24:52 +0100 Subject: gspca - spca561: Fix image problem in the 352x288 mode of rev72a. From: Jean-Francois Moine With the wrong clock value, the image had two moving colored lines. Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/spca561.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/spca561.c b/linux/drivers/media/video/gspca/spca561.c index f92cb0e4a..c8dd036a6 100644 --- a/linux/drivers/media/video/gspca/spca561.c +++ b/linux/drivers/media/video/gspca/spca561.c @@ -679,8 +679,10 @@ static int sd_start_72a(struct gspca_dev *gspca_dev) mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; switch (mode) { default: -/* case 0: - case 1: */ + case 0: + Clck = 0x27; /* ms-win 0x87 */ + break; + case 1: Clck = 0x25; break; case 2: @@ -690,8 +692,9 @@ static int sd_start_72a(struct gspca_dev *gspca_dev) Clck = 0x21; break; } - reg_w_val(dev, 0x8500, mode); /* mode */ reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ + reg_w_val(dev, 0x8702, 0x81); + reg_w_val(dev, 0x8500, mode); /* mode */ write_sensor_72a(gspca_dev, rev72a_init_sensor2); setcontrast(gspca_dev); /* setbrightness(gspca_dev); * fixme: bad values */ -- cgit v1.2.3 From 7987027f994d1a996d966798c87d222c639cb911 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 18 Jan 2009 23:31:26 +0000 Subject: DVB: negative internal->sub_range won't get noticed From: Roel Kluin internal->sub_range is unsigned, a negative won't get noticed. Signed-off-by: Roel Kluin Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/stb0899_algo.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/stb0899_algo.c b/linux/drivers/media/dvb/frontends/stb0899_algo.c index 3d13968a7..71037dc67 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_algo.c +++ b/linux/drivers/media/dvb/frontends/stb0899_algo.c @@ -467,13 +467,14 @@ static void next_sub_range(struct stb0899_state *state) if (internal->sub_dir > 0) { old_sub_range = internal->sub_range; - internal->sub_range = MIN((internal->srch_range / 2) - + if (internal->tuner_offst + internal->sub_range / 2 >= + internal->srch_range / 2) + internal->sub_range = 0; + else + internal->sub_range = MIN((internal->srch_range / 2) - (internal->tuner_offst + internal->sub_range / 2), internal->sub_range); - if (internal->sub_range < 0) - internal->sub_range = 0; - internal->tuner_offst += (old_sub_range + internal->sub_range) / 2; } -- cgit v1.2.3 From efa0fa9346bc7dd58e925951e9dae18a0aed1f34 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 18 Jan 2009 23:10:49 -0500 Subject: saa7134: enable digital tv support for Hauppauge WinTV-HVR1120 From: Michael Krufky Priority: normal Signed-off-by: Michael Krufky --- linux/Documentation/video4linux/CARDLIST.saa7134 | 2 +- linux/drivers/media/video/saa7134/Kconfig | 3 ++ linux/drivers/media/video/saa7134/saa7134-cards.c | 4 ++- linux/drivers/media/video/saa7134/saa7134-dvb.c | 44 +++++++++++++++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/Documentation/video4linux/CARDLIST.saa7134 b/linux/Documentation/video4linux/CARDLIST.saa7134 index 626820e51..6dacf2825 100644 --- a/linux/Documentation/video4linux/CARDLIST.saa7134 +++ b/linux/Documentation/video4linux/CARDLIST.saa7134 @@ -153,5 +153,5 @@ 152 -> Asus Tiger Rev:1.00 [1043:4857] 153 -> Kworld Plus TV Analog Lite PCI [17de:7128] 154 -> Avermedia AVerTV GO 007 FM Plus [1461:f31d] -155 -> Hauppauge WinTV-HVR1120 [0070:6706,0070:6708] +155 -> Hauppauge WinTV-HVR1120 ATSC/QAM-Hybrid [0070:6706,0070:6708] 156 -> Hauppauge WinTV-HVR1110r3 [0070:6707,0070:6709,0070:670a] diff --git a/linux/drivers/media/video/saa7134/Kconfig b/linux/drivers/media/video/saa7134/Kconfig index 51f17c82b..e62b29967 100644 --- a/linux/drivers/media/video/saa7134/Kconfig +++ b/linux/drivers/media/video/saa7134/Kconfig @@ -42,6 +42,9 @@ config VIDEO_SAA7134_DVB select DVB_MT312 if !DVB_FE_CUSTOMISE select DVB_LNBP21 if !DVB_FE_CUSTOMISE select DVB_ZL10353 if !DVB_FE_CUSTOMISE + select DVB_LGDT3305 if !DVB_FE_CUSTOMISE + select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE ---help--- This adds support for DVB cards based on the Philips saa7134 chip. diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c index 09697c0f1..e8efc883c 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -3332,13 +3332,15 @@ struct saa7134_board saa7134_boards[] = { }, }, [SAA7134_BOARD_HAUPPAUGE_HVR1120] = { - .name = "Hauppauge WinTV-HVR1120", + .name = "Hauppauge WinTV-HVR1120 ATSC/QAM-Hybrid", .audio_clock = 0x00187de7, .tuner_type = TUNER_PHILIPS_TDA8290, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .tuner_config = 3, + .mpeg = SAA7134_MPEG_DVB, + .ts_type = SAA7134_MPEG_TS_SERIAL, .gpiomask = 0x0800100, /* GPIO 21 is an INPUT */ .inputs = {{ .name = name_tv, diff --git a/linux/drivers/media/video/saa7134/saa7134-dvb.c b/linux/drivers/media/video/saa7134/saa7134-dvb.c index 7745cad95..085589998 100644 --- a/linux/drivers/media/video/saa7134/saa7134-dvb.c +++ b/linux/drivers/media/video/saa7134/saa7134-dvb.c @@ -48,6 +48,9 @@ #include "isl6405.h" #include "lnbp21.h" #include "tuner-simple.h" +#include "tda18271.h" +#include "lgdt3305.h" +#include "tda8290.h" #include "zl10353.h" @@ -963,6 +966,34 @@ static struct zl10036_config avertv_a700_tuner = { .tuner_address = 0x60, }; +static struct lgdt3305_config hcw_lgdt3305_config = { + .i2c_addr = 0x0e, + .mpeg_mode = LGDT3305_MPEG_SERIAL, + .tpclk_edge = LGDT3305_TPCLK_RISING_EDGE, + .tpvalid_polarity = LGDT3305_TP_VALID_HIGH, + .deny_i2c_rptr = 1, + .spectral_inversion = 1, + .qam_if_khz = 4000, + .vsb_if_khz = 3250, +}; + +static struct tda18271_std_map hauppauge_tda18271_std_map = { + .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4, + .if_lvl = 1, .rfagc_top = 0x58, }, + .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 5, + .if_lvl = 1, .rfagc_top = 0x58, }, +}; + +static struct tda18271_config hcw_tda18271_config = { + .std_map = &hauppauge_tda18271_std_map, + .gate = TDA18271_GATE_ANALOG, + .config = 3, +}; + +static struct tda829x_config tda829x_no_probe = { + .probe_tuner = TDA829X_DONT_PROBE, +}; + /* ================================================================== * Core code */ @@ -1089,6 +1120,19 @@ static int dvb_init(struct saa7134_dev *dev) &tda827x_cfg_1) < 0) goto dettach_frontend; break; + case SAA7134_BOARD_HAUPPAUGE_HVR1120: + fe0->dvb.frontend = dvb_attach(lgdt3305_attach, + &hcw_lgdt3305_config, + &dev->i2c_adap); + if (fe0->dvb.frontend) { + 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, + &hcw_tda18271_config); + } + break; case SAA7134_BOARD_ASUSTeK_P7131_DUAL: if (configure_tda827x_fe(dev, &asus_p7131_dual_config, &tda827x_cfg_0) < 0) -- cgit v1.2.3 From 292c5119045c438520490bda073ed74ba4c9cf36 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 28 Feb 2009 17:16:22 -0500 Subject: mxl5007t: remove analog tuning code From: Michael Krufky Analog doesn't work in this driver yet. This code just adds extra bloat, so remove it for now. Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/common/tuners/mxl5007t.c | 131 --------------------------- 1 file changed, 131 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/common/tuners/mxl5007t.c b/linux/drivers/media/common/tuners/mxl5007t.c index c7aa69df1..5d14eb334 100644 --- a/linux/drivers/media/common/tuners/mxl5007t.c +++ b/linux/drivers/media/common/tuners/mxl5007t.c @@ -68,15 +68,8 @@ MODULE_PARM_DESC(debug, "set debug level"); enum mxl5007t_mode { MxL_MODE_OTA_DVBT_ATSC = 0, - MxL_MODE_OTA_NTSC_PAL_GH = 1, - MxL_MODE_OTA_PAL_IB = 2, - MxL_MODE_OTA_PAL_D_SECAM_KL = 3, MxL_MODE_OTA_ISDBT = 4, MxL_MODE_CABLE_DIGITAL = 0x10, - MxL_MODE_CABLE_NTSC_PAL_GH = 0x11, - MxL_MODE_CABLE_PAL_IB = 0x12, - MxL_MODE_CABLE_PAL_D_SECAM_KL = 0x13, - MxL_MODE_CABLE_SCTE40 = 0x14, }; enum mxl5007t_chip_version { @@ -240,56 +233,12 @@ static void mxl5007t_set_mode_bits(struct mxl5007t_state *state, set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06); set_reg_bits(state->tab_init, 0x35, 0xff, 0x12); break; - case MxL_MODE_OTA_NTSC_PAL_GH: - set_reg_bits(state->tab_init, 0x16, 0x70, 0x00); - set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); - break; - case MxL_MODE_OTA_PAL_IB: - set_reg_bits(state->tab_init, 0x16, 0x70, 0x10); - set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); - break; - case MxL_MODE_OTA_PAL_D_SECAM_KL: - set_reg_bits(state->tab_init, 0x16, 0x70, 0x20); - set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); - break; case MxL_MODE_CABLE_DIGITAL: set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); set_reg_bits(state->tab_init_cable, 0x72, 0xff, 8 - if_diff_out_level); set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); break; - case MxL_MODE_CABLE_NTSC_PAL_GH: - set_reg_bits(state->tab_init, 0x16, 0x70, 0x00); - set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); - set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); - set_reg_bits(state->tab_init_cable, 0x72, 0xff, - 8 - if_diff_out_level); - set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); - break; - case MxL_MODE_CABLE_PAL_IB: - set_reg_bits(state->tab_init, 0x16, 0x70, 0x10); - set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); - set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); - set_reg_bits(state->tab_init_cable, 0x72, 0xff, - 8 - if_diff_out_level); - set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); - break; - case MxL_MODE_CABLE_PAL_D_SECAM_KL: - set_reg_bits(state->tab_init, 0x16, 0x70, 0x20); - set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); - set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); - set_reg_bits(state->tab_init_cable, 0x72, 0xff, - 8 - if_diff_out_level); - set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); - break; - case MxL_MODE_CABLE_SCTE40: - set_reg_bits(state->tab_init_cable, 0x36, 0xff, 0x08); - set_reg_bits(state->tab_init_cable, 0x68, 0xff, 0xbc); - set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); - set_reg_bits(state->tab_init_cable, 0x72, 0xff, - 8 - if_diff_out_level); - set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); - break; default: mxl_fail(-EINVAL); } @@ -757,85 +706,6 @@ fail: return ret; } -static int mxl5007t_set_analog_params(struct dvb_frontend *fe, - struct analog_parameters *params) -{ - struct mxl5007t_state *state = fe->tuner_priv; - enum mxl5007t_bw_mhz bw = 0; /* FIXME */ - enum mxl5007t_mode cbl_mode; - enum mxl5007t_mode ota_mode; - char *mode_name; - int ret; - u32 freq = params->frequency * 62500; - -#if 0 - if (params->mode == V4L2_TUNER_RADIO) { - freq = freq / 1000; - mode_name = "fm"; - } else -#else -#define cable 1 -#endif - if (params->std & V4L2_STD_MN) { - cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH; - ota_mode = MxL_MODE_OTA_NTSC_PAL_GH; - mode_name = "MN"; - } else if (params->std & V4L2_STD_B) { - cbl_mode = MxL_MODE_CABLE_PAL_IB; - ota_mode = MxL_MODE_OTA_PAL_IB; - mode_name = "B"; - } else if (params->std & V4L2_STD_GH) { - cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH; - ota_mode = MxL_MODE_OTA_NTSC_PAL_GH; - mode_name = "GH"; - } else if (params->std & V4L2_STD_PAL_I) { - cbl_mode = MxL_MODE_CABLE_PAL_IB; - ota_mode = MxL_MODE_OTA_PAL_IB; - mode_name = "I"; - } else if (params->std & V4L2_STD_DK) { - cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL; - ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL; - mode_name = "DK"; - } else if (params->std & V4L2_STD_SECAM_L) { - cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL; - ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL; - mode_name = "L"; - } else if (params->std & V4L2_STD_SECAM_LC) { - cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL; - ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL; - mode_name = "L'"; - } else { - mode_name = "xx"; - /* FIXME */ - cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH; - ota_mode = MxL_MODE_OTA_NTSC_PAL_GH; - } - mxl_debug("setting mxl5007 to system %s", mode_name); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - mutex_lock(&state->lock); - - ret = mxl5007t_tuner_init(state, cable ? cbl_mode : ota_mode); - if (mxl_fail(ret)) - goto fail; - - ret = mxl5007t_tuner_rf_tune(state, freq, bw); - if (mxl_fail(ret)) - goto fail; - - state->frequency = freq; - state->bandwidth = 0; -fail: - mutex_unlock(&state->lock); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - return ret; -} - /* ------------------------------------------------------------------------- */ static int mxl5007t_init(struct dvb_frontend *fe) @@ -928,7 +798,6 @@ static struct dvb_tuner_ops mxl5007t_tuner_ops = { .init = mxl5007t_init, .sleep = mxl5007t_sleep, .set_params = mxl5007t_set_params, - .set_analog_params = mxl5007t_set_analog_params, .get_status = mxl5007t_get_status, .get_frequency = mxl5007t_get_frequency, .get_bandwidth = mxl5007t_get_bandwidth, -- cgit v1.2.3 From adfdbfcc476847ad0ea239eb72e52d4a7905563f Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 28 Feb 2009 17:34:25 -0500 Subject: mxl5007t: remove function mxl5007t_check_rf_input_power From: Michael Krufky This function does not work properly and is not necessary - remove it for now. Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/common/tuners/mxl5007t.c | 29 ---------------------------- 1 file changed, 29 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/common/tuners/mxl5007t.c b/linux/drivers/media/common/tuners/mxl5007t.c index 5d14eb334..202b5cb8f 100644 --- a/linux/drivers/media/common/tuners/mxl5007t.c +++ b/linux/drivers/media/common/tuners/mxl5007t.c @@ -582,36 +582,12 @@ fail: return ret; } -static int mxl5007t_check_rf_input_power(struct mxl5007t_state *state, - s32 *rf_input_level) -{ - u8 d1, d2; - int ret; - - ret = mxl5007t_read_reg(state, 0xb7, &d1); - if (mxl_fail(ret)) - goto fail; - - ret = mxl5007t_read_reg(state, 0xbf, &d2); - if (mxl_fail(ret)) - goto fail; - - d2 = d2 >> 4; - if (d2 > 7) - d2 += 0xf0; - - *rf_input_level = (s32)(d1 + d2 - 113); -fail: - return ret; -} - /* ------------------------------------------------------------------------- */ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status) { struct mxl5007t_state *state = fe->tuner_priv; int rf_locked, ref_locked; - s32 rf_input_level = 0; int ret; if (fe->ops.i2c_gate_ctrl) @@ -622,11 +598,6 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status) goto fail; mxl_debug("%s%s", rf_locked ? "rf locked " : "", ref_locked ? "ref locked" : ""); - - ret = mxl5007t_check_rf_input_power(state, &rf_input_level); - if (mxl_fail(ret)) - goto fail; - mxl_debug("rf input power: %d", rf_input_level); fail: if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); -- cgit v1.2.3 From 8115a43de9b2f7435d67a93f1a0ecc56cac9b023 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 28 Feb 2009 17:42:59 -0500 Subject: mxl5007t: mxl5007t_get_status should report if tuner is locked From: Michael Krufky report TUNER_STATUS_LOCKED if rf_locked or ref_locked Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/common/tuners/mxl5007t.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/common/tuners/mxl5007t.c b/linux/drivers/media/common/tuners/mxl5007t.c index 202b5cb8f..3db661fc1 100644 --- a/linux/drivers/media/common/tuners/mxl5007t.c +++ b/linux/drivers/media/common/tuners/mxl5007t.c @@ -587,8 +587,9 @@ fail: static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status) { struct mxl5007t_state *state = fe->tuner_priv; - int rf_locked, ref_locked; - int ret; + int rf_locked, ref_locked, ret; + + *status = 0; if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); @@ -598,6 +599,9 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status) goto fail; mxl_debug("%s%s", rf_locked ? "rf locked " : "", ref_locked ? "ref locked" : ""); + + if ((rf_locked) || (ref_locked)) + *status |= TUNER_STATUS_LOCKED; fail: if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); -- cgit v1.2.3 From 467e08a9b7c0b26e98d671eed326c970dce57479 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 28 Feb 2009 17:56:30 -0500 Subject: mxl5007t: warn when unknown revisions are detected From: Michael Krufky Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/common/tuners/mxl5007t.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux') diff --git a/linux/drivers/media/common/tuners/mxl5007t.c b/linux/drivers/media/common/tuners/mxl5007t.c index 3db661fc1..66e6b9992 100644 --- a/linux/drivers/media/common/tuners/mxl5007t.c +++ b/linux/drivers/media/common/tuners/mxl5007t.c @@ -814,6 +814,7 @@ static int mxl5007t_get_chip_id(struct mxl5007t_state *state) goto fail; #else name = "MxL5007T"; + printk(KERN_WARNING "%s: unknown rev (%02x)\n", __func__, id); id = MxL_UNKNOWN_ID; #endif } -- cgit v1.2.3 From b27d5325f66fc4d7305c88d7e992f99bab5917cd Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 28 Feb 2009 20:55:55 -0500 Subject: mxl5007t: fix devname for hybrid_tuner_request_state From: Michael Krufky Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/common/tuners/mxl5007t.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/common/tuners/mxl5007t.c b/linux/drivers/media/common/tuners/mxl5007t.c index 66e6b9992..a20b2cb70 100644 --- a/linux/drivers/media/common/tuners/mxl5007t.c +++ b/linux/drivers/media/common/tuners/mxl5007t.c @@ -842,7 +842,7 @@ struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, mutex_lock(&mxl5007t_list_mutex); instance = hybrid_tuner_request_state(struct mxl5007t_state, state, hybrid_tuner_instance_list, - i2c, addr, "mxl5007"); + i2c, addr, "mxl5007t"); switch (instance) { case 0: goto fail; -- cgit v1.2.3 From e5dc06e370609b1a5afa136d98170ff9a9125a6d Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 18 Jan 2009 23:11:49 -0500 Subject: mxl5007t: update driver for MxL 5007T V4 From: Michael Krufky Priority: normal Signed-off-by: Michael Krufky Signed-off-by: Asaf Fishov --- linux/drivers/media/common/tuners/mxl5007t.c | 268 ++++++++++++++------------- 1 file changed, 135 insertions(+), 133 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/common/tuners/mxl5007t.c b/linux/drivers/media/common/tuners/mxl5007t.c index a20b2cb70..09d93144d 100644 --- a/linux/drivers/media/common/tuners/mxl5007t.c +++ b/linux/drivers/media/common/tuners/mxl5007t.c @@ -1,7 +1,7 @@ /* * mxl5007t.c - driver for the MaxLinear MxL5007T silicon tuner * - * Copyright (C) 2008 Michael Krufky + * Copyright (C) 2008, 2009 Michael Krufky * * 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 @@ -67,15 +67,17 @@ MODULE_PARM_DESC(debug, "set debug level"); #define MHz 1000000 enum mxl5007t_mode { - MxL_MODE_OTA_DVBT_ATSC = 0, - MxL_MODE_OTA_ISDBT = 4, - MxL_MODE_CABLE_DIGITAL = 0x10, + MxL_MODE_ISDBT = 0, + MxL_MODE_DVBT = 1, + MxL_MODE_ATSC = 2, + MxL_MODE_CABLE = 0x10, }; enum mxl5007t_chip_version { MxL_UNKNOWN_ID = 0x00, MxL_5007_V1_F1 = 0x11, MxL_5007_V1_F2 = 0x12, + MxL_5007_V4 = 0x14, MxL_5007_V2_100_F1 = 0x21, MxL_5007_V2_100_F2 = 0x22, MxL_5007_V2_200_F1 = 0x23, @@ -90,67 +92,61 @@ struct reg_pair_t { /* ------------------------------------------------------------------------- */ static struct reg_pair_t init_tab[] = { - { 0x0b, 0x44 }, /* XTAL */ - { 0x0c, 0x60 }, /* IF */ - { 0x10, 0x00 }, /* MISC */ - { 0x12, 0xca }, /* IDAC */ - { 0x16, 0x90 }, /* MODE */ - { 0x32, 0x38 }, /* MODE Analog/Digital */ - { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */ - { 0x2c, 0x34 }, /* OVERRIDE */ - { 0x4d, 0x40 }, /* OVERRIDE */ - { 0x7f, 0x02 }, /* OVERRIDE */ - { 0x9a, 0x52 }, /* OVERRIDE */ - { 0x48, 0x5a }, /* OVERRIDE */ - { 0x76, 0x1a }, /* OVERRIDE */ - { 0x6a, 0x48 }, /* OVERRIDE */ - { 0x64, 0x28 }, /* OVERRIDE */ - { 0x66, 0xe6 }, /* OVERRIDE */ - { 0x35, 0x0e }, /* OVERRIDE */ - { 0x7e, 0x01 }, /* OVERRIDE */ - { 0x83, 0x00 }, /* OVERRIDE */ - { 0x04, 0x0b }, /* OVERRIDE */ - { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */ + { 0x02, 0x06 }, + { 0x03, 0x48 }, + { 0x05, 0x04 }, + { 0x06, 0x10 }, + { 0x2e, 0x15 }, /* OVERRIDE */ + { 0x30, 0x10 }, /* OVERRIDE */ + { 0x45, 0x58 }, /* OVERRIDE */ + { 0x48, 0x19 }, /* OVERRIDE */ + { 0x52, 0x03 }, /* OVERRIDE */ + { 0x53, 0x44 }, /* OVERRIDE */ + { 0x6a, 0x4b }, /* OVERRIDE */ + { 0x76, 0x00 }, /* OVERRIDE */ + { 0x78, 0x18 }, /* OVERRIDE */ + { 0x7a, 0x17 }, /* OVERRIDE */ + { 0x85, 0x06 }, /* OVERRIDE */ + { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */ { 0, 0 } }; static struct reg_pair_t init_tab_cable[] = { - { 0x0b, 0x44 }, /* XTAL */ - { 0x0c, 0x60 }, /* IF */ - { 0x10, 0x00 }, /* MISC */ - { 0x12, 0xca }, /* IDAC */ - { 0x16, 0x90 }, /* MODE */ - { 0x32, 0x38 }, /* MODE A/D */ - { 0x71, 0x3f }, /* TOP1 */ - { 0x72, 0x3f }, /* TOP2 */ - { 0x74, 0x3f }, /* TOP3 */ - { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */ - { 0x2c, 0x34 }, /* OVERRIDE */ - { 0x4d, 0x40 }, /* OVERRIDE */ - { 0x7f, 0x02 }, /* OVERRIDE */ - { 0x9a, 0x52 }, /* OVERRIDE */ - { 0x48, 0x5a }, /* OVERRIDE */ - { 0x76, 0x1a }, /* OVERRIDE */ - { 0x6a, 0x48 }, /* OVERRIDE */ - { 0x64, 0x28 }, /* OVERRIDE */ - { 0x66, 0xe6 }, /* OVERRIDE */ - { 0x35, 0x0e }, /* OVERRIDE */ - { 0x7e, 0x01 }, /* OVERRIDE */ - { 0x04, 0x0b }, /* OVERRIDE */ - { 0x68, 0xb4 }, /* OVERRIDE */ - { 0x36, 0x00 }, /* OVERRIDE */ - { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */ + { 0x02, 0x06 }, + { 0x03, 0x48 }, + { 0x05, 0x04 }, + { 0x06, 0x10 }, + { 0x09, 0x3f }, + { 0x0a, 0x3f }, + { 0x0b, 0x3f }, + { 0x2e, 0x15 }, /* OVERRIDE */ + { 0x30, 0x10 }, /* OVERRIDE */ + { 0x45, 0x58 }, /* OVERRIDE */ + { 0x48, 0x19 }, /* OVERRIDE */ + { 0x52, 0x03 }, /* OVERRIDE */ + { 0x53, 0x44 }, /* OVERRIDE */ + { 0x6a, 0x4b }, /* OVERRIDE */ + { 0x76, 0x00 }, /* OVERRIDE */ + { 0x78, 0x18 }, /* OVERRIDE */ + { 0x7a, 0x17 }, /* OVERRIDE */ + { 0x85, 0x06 }, /* OVERRIDE */ + { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */ { 0, 0 } }; /* ------------------------------------------------------------------------- */ static struct reg_pair_t reg_pair_rftune[] = { - { 0x11, 0x00 }, /* abort tune */ - { 0x13, 0x15 }, - { 0x14, 0x40 }, - { 0x15, 0x0e }, - { 0x11, 0x02 }, /* start tune */ + { 0x0f, 0x00 }, /* abort tune */ + { 0x0c, 0x15 }, + { 0x0d, 0x40 }, + { 0x0e, 0x0e }, + { 0x1f, 0x87 }, /* OVERRIDE */ + { 0x20, 0x1f }, /* OVERRIDE */ + { 0x21, 0x87 }, /* OVERRIDE */ + { 0x22, 0x1f }, /* OVERRIDE */ + { 0x80, 0x01 }, /* freq dependent */ + { 0x0f, 0x01 }, /* start tune */ { 0, 0 } }; @@ -225,19 +221,20 @@ static void mxl5007t_set_mode_bits(struct mxl5007t_state *state, s32 if_diff_out_level) { switch (mode) { - case MxL_MODE_OTA_DVBT_ATSC: - set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06); - set_reg_bits(state->tab_init, 0x35, 0xff, 0x0e); + case MxL_MODE_ATSC: + set_reg_bits(state->tab_init, 0x06, 0x1f, 0x12); break; - case MxL_MODE_OTA_ISDBT: - set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06); - set_reg_bits(state->tab_init, 0x35, 0xff, 0x12); + case MxL_MODE_DVBT: + set_reg_bits(state->tab_init, 0x06, 0x1f, 0x11); break; - case MxL_MODE_CABLE_DIGITAL: - set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); - set_reg_bits(state->tab_init_cable, 0x72, 0xff, + case MxL_MODE_ISDBT: + set_reg_bits(state->tab_init, 0x06, 0x1f, 0x10); + break; + case MxL_MODE_CABLE: + set_reg_bits(state->tab_init_cable, 0x09, 0xff, 0xc1); + set_reg_bits(state->tab_init_cable, 0x0a, 0xff, 8 - if_diff_out_level); - set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); + set_reg_bits(state->tab_init_cable, 0x0b, 0xff, 0x17); break; default: mxl_fail(-EINVAL); @@ -256,43 +253,43 @@ static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state, val = 0x00; break; case MxL_IF_4_5_MHZ: - val = 0x20; + val = 0x02; break; case MxL_IF_4_57_MHZ: - val = 0x30; + val = 0x03; break; case MxL_IF_5_MHZ: - val = 0x40; + val = 0x04; break; case MxL_IF_5_38_MHZ: - val = 0x50; + val = 0x05; break; case MxL_IF_6_MHZ: - val = 0x60; + val = 0x06; break; case MxL_IF_6_28_MHZ: - val = 0x70; + val = 0x07; break; case MxL_IF_9_1915_MHZ: - val = 0x80; + val = 0x08; break; case MxL_IF_35_25_MHZ: - val = 0x90; + val = 0x09; break; case MxL_IF_36_15_MHZ: - val = 0xa0; + val = 0x0a; break; case MxL_IF_44_MHZ: - val = 0xb0; + val = 0x0b; break; default: mxl_fail(-EINVAL); return; } - set_reg_bits(state->tab_init, 0x0c, 0xf0, val); + set_reg_bits(state->tab_init, 0x02, 0x0f, val); /* set inverted IF or normal IF */ - set_reg_bits(state->tab_init, 0x0c, 0x08, invert_if ? 0x08 : 0x00); + set_reg_bits(state->tab_init, 0x02, 0x10, invert_if ? 0x10 : 0x00); return; } @@ -300,56 +297,68 @@ static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state, static void mxl5007t_set_xtal_freq_bits(struct mxl5007t_state *state, enum mxl5007t_xtal_freq xtal_freq) { - u8 val; - switch (xtal_freq) { case MxL_XTAL_16_MHZ: - val = 0x00; /* select xtal freq & Ref Freq */ + /* select xtal freq & ref freq */ + set_reg_bits(state->tab_init, 0x03, 0xf0, 0x00); + set_reg_bits(state->tab_init, 0x05, 0x0f, 0x00); break; case MxL_XTAL_20_MHZ: - val = 0x11; + set_reg_bits(state->tab_init, 0x03, 0xf0, 0x10); + set_reg_bits(state->tab_init, 0x05, 0x0f, 0x01); break; case MxL_XTAL_20_25_MHZ: - val = 0x22; + set_reg_bits(state->tab_init, 0x03, 0xf0, 0x20); + set_reg_bits(state->tab_init, 0x05, 0x0f, 0x02); break; case MxL_XTAL_20_48_MHZ: - val = 0x33; + set_reg_bits(state->tab_init, 0x03, 0xf0, 0x30); + set_reg_bits(state->tab_init, 0x05, 0x0f, 0x03); break; case MxL_XTAL_24_MHZ: - val = 0x44; + set_reg_bits(state->tab_init, 0x03, 0xf0, 0x40); + set_reg_bits(state->tab_init, 0x05, 0x0f, 0x04); break; case MxL_XTAL_25_MHZ: - val = 0x55; + set_reg_bits(state->tab_init, 0x03, 0xf0, 0x50); + set_reg_bits(state->tab_init, 0x05, 0x0f, 0x05); break; case MxL_XTAL_25_14_MHZ: - val = 0x66; + set_reg_bits(state->tab_init, 0x03, 0xf0, 0x60); + set_reg_bits(state->tab_init, 0x05, 0x0f, 0x06); break; case MxL_XTAL_27_MHZ: - val = 0x77; + set_reg_bits(state->tab_init, 0x03, 0xf0, 0x70); + set_reg_bits(state->tab_init, 0x05, 0x0f, 0x07); break; case MxL_XTAL_28_8_MHZ: - val = 0x88; + set_reg_bits(state->tab_init, 0x03, 0xf0, 0x80); + set_reg_bits(state->tab_init, 0x05, 0x0f, 0x08); break; case MxL_XTAL_32_MHZ: - val = 0x99; + set_reg_bits(state->tab_init, 0x03, 0xf0, 0x90); + set_reg_bits(state->tab_init, 0x05, 0x0f, 0x09); break; case MxL_XTAL_40_MHZ: - val = 0xaa; + set_reg_bits(state->tab_init, 0x03, 0xf0, 0xa0); + set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0a); break; case MxL_XTAL_44_MHZ: - val = 0xbb; + set_reg_bits(state->tab_init, 0x03, 0xf0, 0xb0); + set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0b); break; case MxL_XTAL_48_MHZ: - val = 0xcc; + set_reg_bits(state->tab_init, 0x03, 0xf0, 0xc0); + set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0c); break; case MxL_XTAL_49_3811_MHZ: - val = 0xdd; + set_reg_bits(state->tab_init, 0x03, 0xf0, 0xd0); + set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0d); break; default: mxl_fail(-EINVAL); return; } - set_reg_bits(state->tab_init, 0x0b, 0xff, val); return; } @@ -366,16 +375,11 @@ static struct reg_pair_t *mxl5007t_calc_init_regs(struct mxl5007t_state *state, mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if); mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz); - set_reg_bits(state->tab_init, 0x10, 0x40, cfg->loop_thru_enable << 6); - - set_reg_bits(state->tab_init, 0xd8, 0x08, cfg->clk_out_enable << 3); + set_reg_bits(state->tab_init, 0x04, 0x01, cfg->loop_thru_enable); + set_reg_bits(state->tab_init, 0x03, 0x08, cfg->clk_out_enable << 3); + set_reg_bits(state->tab_init, 0x03, 0x07, cfg->clk_out_amp); - set_reg_bits(state->tab_init, 0x10, 0x07, cfg->clk_out_amp); - - /* set IDAC to automatic mode control by AGC */ - set_reg_bits(state->tab_init, 0x12, 0x80, 0x00); - - if (mode >= MxL_MODE_CABLE_DIGITAL) { + if (mode >= MxL_MODE_CABLE) { copy_reg_bits(state->tab_init, state->tab_init_cable); return state->tab_init_cable; } else @@ -401,7 +405,7 @@ static void mxl5007t_set_bw_bits(struct mxl5007t_state *state, * and DIG_MODEINDEX_CSF */ break; case MxL_BW_7MHz: - val = 0x21; + val = 0x2a; break; case MxL_BW_8MHz: val = 0x3f; @@ -410,7 +414,7 @@ static void mxl5007t_set_bw_bits(struct mxl5007t_state *state, mxl_fail(-EINVAL); return; } - set_reg_bits(state->tab_rftune, 0x13, 0x3f, val); + set_reg_bits(state->tab_rftune, 0x0c, 0x3f, val); return; } @@ -447,8 +451,11 @@ reg_pair_t *mxl5007t_calc_rf_tune_regs(struct mxl5007t_state *state, if (temp > 7812) dig_rf_freq++; - set_reg_bits(state->tab_rftune, 0x14, 0xff, (u8)dig_rf_freq); - set_reg_bits(state->tab_rftune, 0x15, 0xff, (u8)(dig_rf_freq >> 8)); + set_reg_bits(state->tab_rftune, 0x0d, 0xff, (u8) dig_rf_freq); + set_reg_bits(state->tab_rftune, 0x0e, 0xff, (u8) (dig_rf_freq >> 8)); + + if (rf_freq >= 333000000) + set_reg_bits(state->tab_rftune, 0x80, 0x40, 0x40); return state->tab_rftune; } @@ -505,9 +512,10 @@ static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val) static int mxl5007t_soft_reset(struct mxl5007t_state *state) { u8 d = 0xff; - struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0, - .buf = &d, .len = 1 }; - + struct i2c_msg msg = { + .addr = state->i2c_props.addr, .flags = 0, + .buf = &d, .len = 1 + }; int ret = i2c_transfer(state->i2c_props.adap, &msg, 1); if (ret != 1) { @@ -534,9 +542,6 @@ static int mxl5007t_tuner_init(struct mxl5007t_state *state, if (mxl_fail(ret)) goto fail; mdelay(1); - - ret = mxl5007t_write_reg(state, 0x2c, 0x35); - mxl_fail(ret); fail: return ret; } @@ -569,7 +574,7 @@ static int mxl5007t_synth_lock_status(struct mxl5007t_state *state, *rf_locked = 0; *ref_locked = 0; - ret = mxl5007t_read_reg(state, 0xcf, &d); + ret = mxl5007t_read_reg(state, 0xd8, &d); if (mxl_fail(ret)) goto fail; @@ -624,11 +629,11 @@ static int mxl5007t_set_params(struct dvb_frontend *fe, switch (params->u.vsb.modulation) { case VSB_8: case VSB_16: - mode = MxL_MODE_OTA_DVBT_ATSC; + mode = MxL_MODE_ATSC; break; case QAM_64: case QAM_256: - mode = MxL_MODE_CABLE_DIGITAL; + mode = MxL_MODE_CABLE; break; default: mxl_err("modulation not set!"); @@ -650,7 +655,7 @@ static int mxl5007t_set_params(struct dvb_frontend *fe, mxl_err("bandwidth not set!"); return -EINVAL; } - mode = MxL_MODE_OTA_DVBT_ATSC; + mode = MxL_MODE_DVBT; } else { mxl_err("modulation type not supported!"); return -EINVAL; @@ -687,18 +692,14 @@ static int mxl5007t_init(struct dvb_frontend *fe) { struct mxl5007t_state *state = fe->tuner_priv; int ret; - u8 d; if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - ret = mxl5007t_read_reg(state, 0x05, &d); - if (mxl_fail(ret)) - goto fail; - - ret = mxl5007t_write_reg(state, 0x05, d | 0x01); + /* wake from standby */ + ret = mxl5007t_write_reg(state, 0x01, 0x01); mxl_fail(ret); -fail: + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); @@ -709,18 +710,16 @@ static int mxl5007t_sleep(struct dvb_frontend *fe) { struct mxl5007t_state *state = fe->tuner_priv; int ret; - u8 d; if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - ret = mxl5007t_read_reg(state, 0x05, &d); - if (mxl_fail(ret)) - goto fail; - - ret = mxl5007t_write_reg(state, 0x05, d & ~0x01); + /* enter standby mode */ + ret = mxl5007t_write_reg(state, 0x01, 0x00); mxl_fail(ret); -fail: + ret = mxl5007t_write_reg(state, 0x0f, 0x00); + mxl_fail(ret); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); @@ -785,7 +784,7 @@ static int mxl5007t_get_chip_id(struct mxl5007t_state *state) int ret; u8 id; - ret = mxl5007t_read_reg(state, 0xd3, &id); + ret = mxl5007t_read_reg(state, 0xd9, &id); if (mxl_fail(ret)) goto fail; @@ -808,6 +807,9 @@ static int mxl5007t_get_chip_id(struct mxl5007t_state *state) case MxL_5007_V2_200_F2: name = "MxL5007.v2.200.f2"; break; + case MxL_5007_V4: + name = "MxL5007T.v4"; + break; default: #if 0 ret = -EINVAL; @@ -885,7 +887,7 @@ EXPORT_SYMBOL_GPL(mxl5007t_attach); MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver"); MODULE_AUTHOR("Michael Krufky "); MODULE_LICENSE("GPL"); -MODULE_VERSION("0.1"); +MODULE_VERSION("0.2"); /* * Overrides for Emacs so that we follow Linus's tabbing style. -- cgit v1.2.3 From ea09aea560cb0eabd0221c64177257a11e3e6d83 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 18 Jan 2009 23:12:55 -0500 Subject: dib0700: add support for Hauppauge ATSC MiniCard From: Michael Krufky Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/Kconfig | 2 + linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 99 +++++++++++++++++++++++ linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 2 + 3 files changed, 103 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index 64fa1d182..b899d509a 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -73,11 +73,13 @@ config DVB_USB_DIB0700 select DVB_DIB7000M if !DVB_FE_CUSTOMISE select DVB_DIB3000MC if !DVB_FE_CUSTOMISE select DVB_S5H1411 if !DVB_FE_CUSTOMISE + select DVB_LGDT3305 if !DVB_FE_CUSTOMISE select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMIZE select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMIZE help Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The USB bridge is also present in devices having the DiB7700 DVB-T-USB diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c index 8877215cb..d8901f7a8 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -17,6 +17,8 @@ #include "xc5000.h" #include "s5h1411.h" #include "dib0070.h" +#include "lgdt3305.h" +#include "mxl5007t.h" static int force_lna_activation; module_param(force_lna_activation, int, 0644); @@ -1370,6 +1372,76 @@ static int xc5000_tuner_attach(struct dvb_usb_adapter *adap) == NULL ? -ENODEV : 0; } +static struct lgdt3305_config hcw_lgdt3305_config = { + .i2c_addr = 0x0e, + .mpeg_mode = LGDT3305_MPEG_PARALLEL, + .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE, + .tpvalid_polarity = LGDT3305_TP_VALID_LOW, + .deny_i2c_rptr = 0, + .spectral_inversion = 1, + .qam_if_khz = 6000, + .vsb_if_khz = 6000, + .usref_8vsb = 0x0500, +}; + +static struct mxl5007t_config hcw_mxl5007t_config = { + .xtal_freq_hz = MxL_XTAL_25_MHZ, + .if_freq_hz = MxL_IF_6_MHZ, + .invert_if = 1, +#if 0 + .loop_thru_enable = 1, + .clk_out_enable = 1, +#endif +}; + +/* TIGER-ATSC map: + GPIO0 - LNA_CTR (H: LNA power enabled, L: LNA power disabled) + GPIO1 - ANT_SEL (H: VPA, L: MCX) + GPIO4 - SCL2 + GPIO6 - EN_TUNER + GPIO7 - SDA2 + GPIO10 - DEM_RST + + MXL is behind LG's i2c repeater. LG is on SCL2/SDA2 gpios on the DIB + */ +static int lgdt3305_frontend_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_state *st = adap->dev->priv; + + /* Make use of the new i2c functions from FW 1.20 */ + st->fw_use_new_i2c_api = 1; + + st->disable_streaming_master_mode = 1; + + /* fe power enable */ + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); + msleep(30); + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(30); + + /* demod reset */ + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(30); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + msleep(30); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(30); + + adap->fe = dvb_attach(lgdt3305_attach, + &hcw_lgdt3305_config, + &adap->dev->i2c_adap); + + return adap->fe == NULL ? -ENODEV : 0; +} + +static int mxl5007t_tuner_attach(struct dvb_usb_adapter *adap) +{ + return dvb_attach(mxl5007t_attach, adap->fe, + &adap->dev->i2c_adap, 0x60, + &hcw_mxl5007t_config) == NULL ? -ENODEV : 0; +} + + /* DVB-USB and USB stuff follows */ struct usb_device_id dib0700_usb_id_table[] = { /* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) }, @@ -1421,6 +1493,8 @@ struct usb_device_id dib0700_usb_id_table[] = { USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) }, { USB_DEVICE(USB_VID_SONY, USB_PID_SONY_PLAYTV) }, /* 45 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_PD378S) }, + { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC) }, + { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -1796,6 +1870,31 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_key_map = dib0700_rc_keys, .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), .rc_query = dib0700_rc_query + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + .num_adapters = 1, + .adapter = { + { + .frontend_attach = lgdt3305_frontend_attach, + .tuner_attach = mxl5007t_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + + .size_of_priv = sizeof(struct + dib0700_adapter_state), + }, + }, + + .num_device_descs = 2, + .devices = { + { "Hauppauge ATSC MiniCard (B200)", + { &dib0700_usb_id_table[46], NULL }, + { NULL }, + }, + { "Hauppauge ATSC MiniCard (B210)", + { &dib0700_usb_id_table[47], NULL }, + { NULL }, + }, + }, }, }; diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 6d70576ad..3dfb27174 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -151,6 +151,8 @@ #define USB_PID_HAUPPAUGE_MYTV_T 0x7080 #define USB_PID_HAUPPAUGE_NOVA_TD_STICK 0x9580 #define USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009 0x5200 +#define USB_PID_HAUPPAUGE_TIGER_ATSC 0xb200 +#define USB_PID_HAUPPAUGE_TIGER_ATSC_B210 0xb210 #define USB_PID_AVERMEDIA_EXPRESS 0xb568 #define USB_PID_AVERMEDIA_VOLAR 0xa807 #define USB_PID_AVERMEDIA_VOLAR_2 0xb808 -- cgit v1.2.3 From 50c744a56e58435409f4f5c647e603ca0b727e7f Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 19 Jan 2009 11:37:33 +0100 Subject: gspca - sonixj: Cleanup code. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 184 +++++++++++++++---------------- 1 file changed, 92 insertions(+), 92 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index a30ae785b..abe26dc7f 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -36,28 +36,28 @@ struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ atomic_t avg_lum; - unsigned int exposure; - - __u16 brightness; - __u8 contrast; - __u8 colors; - __u8 autogain; - __u8 blue; - __u8 red; + u32 exposure; + + u16 brightness; + u8 contrast; + u8 colors; + u8 autogain; + u8 blue; + u8 red; u8 gamma; - __u8 vflip; /* ov7630 only */ - __u8 infrared; /* mi0360 only */ + u8 vflip; /* ov7630 only */ + u8 infrared; /* mi0360 only */ - __s8 ag_cnt; + s8 ag_cnt; #define AG_CNT_START 13 - __u8 bridge; + u8 bridge; #define BRIDGE_SN9C102P 0 #define BRIDGE_SN9C105 1 #define BRIDGE_SN9C110 2 #define BRIDGE_SN9C120 3 #define BRIDGE_SN9C325 4 - __u8 sensor; /* Type of image sensor chip */ + u8 sensor; /* Type of image sensor chip */ #define SENSOR_HV7131R 0 #define SENSOR_MI0360 1 #define SENSOR_MO4000 2 @@ -65,7 +65,7 @@ struct sd { #define SENSOR_OV7630 4 #define SENSOR_OV7648 5 #define SENSOR_OV7660 6 - __u8 i2c_base; + u8 i2c_base; }; /* V4L2 controls supported by the driver */ @@ -349,26 +349,26 @@ static const u8 *sn_tb[] = { sn_ov7660 }; -static const __u8 gamma_def[17] = { +static const u8 gamma_def[17] = { 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff }; #if 0 -static const __u8 gamma_hv7131[17] = { +static const u8 gamma_hv7131[17] = { 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d, 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5 }; #endif /* color matrix and offsets */ -static const __u8 reg84[] = { +static const u8 reg84[] = { 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */ 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */ 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */ 0x00, 0x00, 0x00 /* YUV offsets */ }; -static const __u8 hv7131r_sensor_init[][8] = { +static const u8 hv7131r_sensor_init[][8] = { {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10}, {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10}, @@ -399,9 +399,9 @@ static const __u8 hv7131r_sensor_init[][8] = { {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10}, {} }; -static const __u8 mi0360_sensor_init[][8] = { +static const u8 mi0360_sensor_init[][8] = { {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10}, + {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, {0xb1, 0x5d, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10}, {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10}, @@ -422,7 +422,7 @@ static const __u8 mi0360_sensor_init[][8] = { {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10}, - {0xd1, 0x5d, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10}, + {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10}, {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10}, {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10}, @@ -453,7 +453,7 @@ static const __u8 mi0360_sensor_init[][8] = { {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */ {} }; -static const __u8 mo4000_sensor_init[][8] = { +static const u8 mo4000_sensor_init[][8] = { {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, @@ -476,7 +476,7 @@ static const __u8 mo4000_sensor_init[][8] = { {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, {} }; -static __u8 om6802_sensor_init[][8] = { +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}, @@ -510,7 +510,7 @@ static __u8 om6802_sensor_init[][8] = { /* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */ {} }; -static const __u8 ov7630_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 */ @@ -564,7 +564,7 @@ static const __u8 ov7630_sensor_init[][8] = { {} }; -static const __u8 ov7648_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 */ {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, @@ -610,7 +610,7 @@ static const __u8 ov7648_sensor_init[][8] = { {} }; -static const __u8 ov7660_sensor_init[][8] = { +static const u8 ov7660_sensor_init[][8] = { {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ /* (delay 20ms) */ {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, @@ -699,28 +699,28 @@ static const __u8 ov7660_sensor_init[][8] = { {} }; -static const __u8 qtable4[] = { - 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06, - 0x06, 0x08, 0x0a, 0x11, - 0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x15, 0x0f, 0x0f, 0x0c, 0x11, 0x19, 0x15, - 0x19, 0x19, 0x17, 0x15, - 0x17, 0x17, 0x1b, 0x1d, 0x25, 0x21, 0x1b, 0x1d, 0x23, 0x1d, 0x17, 0x17, - 0x21, 0x2e, 0x21, 0x23, - 0x27, 0x29, 0x2c, 0x2c, 0x2c, 0x19, 0x1f, 0x30, 0x32, 0x2e, 0x29, 0x32, - 0x25, 0x29, 0x2c, 0x29, - 0x06, 0x08, 0x08, 0x0a, 0x08, 0x0a, 0x13, 0x0a, 0x0a, 0x13, 0x29, 0x1b, - 0x17, 0x1b, 0x29, 0x29, - 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, - 0x29, 0x29, 0x29, 0x29, - 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, - 0x29, 0x29, 0x29, 0x29, - 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, - 0x29, 0x29, 0x29, 0x29 +static const u8 qtable4[] = { + 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, + 0x06, 0x06, 0x08, 0x06, 0x06, 0x08, 0x0a, 0x11, + 0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x15, 0x0f, 0x0f, + 0x0c, 0x11, 0x19, 0x15, 0x19, 0x19, 0x17, 0x15, + 0x17, 0x17, 0x1b, 0x1d, 0x25, 0x21, 0x1b, 0x1d, + 0x23, 0x1d, 0x17, 0x17, 0x21, 0x2e, 0x21, 0x23, + 0x27, 0x29, 0x2c, 0x2c, 0x2c, 0x19, 0x1f, 0x30, + 0x32, 0x2e, 0x29, 0x32, 0x25, 0x29, 0x2c, 0x29, + 0x06, 0x08, 0x08, 0x0a, 0x08, 0x0a, 0x13, 0x0a, + 0x0a, 0x13, 0x29, 0x1b, 0x17, 0x1b, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29 }; /* read bytes to gspca_dev->usb_buf */ static void reg_r(struct gspca_dev *gspca_dev, - __u16 value, int len) + u16 value, int len) { #ifdef GSPCA_DEBUG if (len > USB_BUF_SZ) { @@ -739,8 +739,8 @@ static void reg_r(struct gspca_dev *gspca_dev, } static void reg_w1(struct gspca_dev *gspca_dev, - __u16 value, - __u8 data) + u16 value, + u8 data) { PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data); gspca_dev->usb_buf[0] = data; @@ -754,8 +754,8 @@ static void reg_w1(struct gspca_dev *gspca_dev, 500); } static void reg_w(struct gspca_dev *gspca_dev, - __u16 value, - const __u8 *buffer, + u16 value, + const u8 *buffer, int len) { PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..", @@ -777,7 +777,7 @@ static void reg_w(struct gspca_dev *gspca_dev, } /* I2C write 1 byte */ -static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val) +static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -802,7 +802,7 @@ static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val) /* I2C write 8 bytes */ static void i2c_w8(struct gspca_dev *gspca_dev, - const __u8 *buffer) + const u8 *buffer) { memcpy(gspca_dev->usb_buf, buffer, 8); usb_control_msg(gspca_dev->dev, @@ -816,10 +816,10 @@ static void i2c_w8(struct gspca_dev *gspca_dev, } /* read 5 bytes in gspca_dev->usb_buf */ -static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg) +static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg) { struct sd *sd = (struct sd *) gspca_dev; - __u8 mode[8]; + u8 mode[8]; mode[0] = 0x81 | 0x10; mode[1] = sd->i2c_base; @@ -861,15 +861,15 @@ static int probesensor(struct gspca_dev *gspca_dev) } static int configure_gpio(struct gspca_dev *gspca_dev, - const __u8 *sn9c1xx) + const u8 *sn9c1xx) { struct sd *sd = (struct sd *) gspca_dev; - const __u8 *reg9a; - static const __u8 reg9a_def[] = + const u8 *reg9a; + static const u8 reg9a_def[] = {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; - static const __u8 reg9a_sn9c325[] = + static const u8 reg9a_sn9c325[] = {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; - static const __u8 regd4[] = {0x60, 0x00, 0x00}; + static const u8 regd4[] = {0x60, 0x00, 0x00}; reg_w1(gspca_dev, 0xf1, 0x00); #if 1 @@ -945,7 +945,7 @@ static int 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 */ + static const u8 SetSensorClk[] = /* 0x08 Mclk */ { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 }; while (hv7131r_sensor_init[i][0]) { @@ -1073,8 +1073,8 @@ 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; - __u8 regGpio[] = { 0x29, 0x74 }; - __u8 regF1; + u8 regGpio[] = { 0x29, 0x74 }; + u8 regF1; /* setup a selector by bridge */ reg_w1(gspca_dev, 0xf1, 0x01); @@ -1114,20 +1114,14 @@ static int sd_init(struct gspca_dev *gspca_dev) return 0; } -static unsigned int setexposure(struct gspca_dev *gspca_dev, - unsigned int expo) +static u32 setexposure(struct gspca_dev *gspca_dev, + u32 expo) { struct sd *sd = (struct sd *) gspca_dev; - static const __u8 doit[] = /* update sensor */ - { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 }; - static const __u8 sensorgo[] = /* sensor on */ - { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 }; - static const __u8 gainMo[] = - { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d }; switch (sd->sensor) { case SENSOR_HV7131R: { - __u8 Expodoit[] = + u8 Expodoit[] = { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 }; Expodoit[3] = expo >> 16; @@ -1137,8 +1131,12 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev, break; } case SENSOR_MI0360: { - __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */ + u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */ { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 }; + static const u8 doit[] = /* update sensor */ + { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 }; + static const u8 sensorgo[] = /* sensor on */ + { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 }; if (expo > 0x0635) expo = 0x0635; @@ -1152,10 +1150,12 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev, break; } case SENSOR_MO4000: { - __u8 expoMof[] = + u8 expoMof[] = { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 }; - __u8 expoMo10[] = + u8 expoMo10[] = { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 }; + static const u8 gainMo[] = + { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d }; if (expo > 0x1fff) expo = 0x1fff; @@ -1174,7 +1174,7 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev, break; } case SENSOR_OM6802: { - __u8 gainOm[] = + u8 gainOm[] = { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 }; if (expo > 0x03ff) @@ -1195,7 +1195,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; unsigned int expo; - __u8 k2; + u8 k2; k2 = ((int) sd->brightness - 0x8000) >> 10; switch (sd->sensor) { @@ -1225,8 +1225,8 @@ static void setbrightness(struct gspca_dev *gspca_dev) static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - __u8 k2; - __u8 contrast[6]; + u8 k2; + u8 contrast[6]; k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */ contrast[0] = (k2 + 1) / 2; /* red */ @@ -1242,8 +1242,8 @@ static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int i, v; - __u8 reg8a[12]; /* U & V gains */ - static __s16 uv[6] = { /* same as reg84 in signed decimal */ + u8 reg8a[12]; /* U & V gains */ + static s16 uv[6] = { /* same as reg84 in signed decimal */ -24, -38, 64, /* UR UG UB */ 62, -51, -9 /* VR VG VB */ }; @@ -1317,13 +1317,13 @@ static int sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int i; - __u8 reg1, reg17, reg18; - const __u8 *sn9c1xx; + u8 reg1, reg17, reg18; + const u8 *sn9c1xx; int mode; - static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; - static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; - static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ - static const __u8 CE_ov76xx[] = + static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; + static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; + static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ + static const u8 CE_ov76xx[] = { 0x32, 0xdd, 0x32, 0xdd }; sn9c1xx = sn_tb[(int) sd->sensor]; @@ -1487,14 +1487,14 @@ static int sd_start(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - static const __u8 stophv7131[] = + static const u8 stophv7131[] = { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 }; - static const __u8 stopmi0360[] = + static const u8 stopmi0360[] = { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 }; - static const __u8 stopov7648[] = + static const u8 stopov7648[] = { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 }; - __u8 data; - const __u8 *sn9c1xx; + u8 data; + const u8 *sn9c1xx; data = 0x0b; switch (sd->sensor) { @@ -1530,8 +1530,8 @@ static void do_autogain(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int delta; int expotimes; - __u8 luma_mean = 130; - __u8 luma_delta = 20; + u8 luma_mean = 130; + u8 luma_delta = 20; /* Thanks S., without your advice, autobright should not work :) */ if (sd->ag_cnt < 0) @@ -1573,7 +1573,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) /* 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; -- cgit v1.2.3 From e2dece7b3a29cf172128e7a3481940322ca5df20 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 19 Jan 2009 11:01:24 +0000 Subject: KWorld ATSC 115 all static From: Mauro Carvalho Chehab saa7134: Fix tuner access on Kworld ATSC110 -- 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 Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-cards.c | 46 +++++++++++++++-------- linux/drivers/media/video/saa7134/saa7134.h | 23 ++++++++++-- 2 files changed, 49 insertions(+), 20 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c index 7740c1601..9ad47eba4 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -5995,6 +5995,32 @@ static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data) /* ----------------------------------------------------------- */ +static void nxt200x_gate_ctrl(struct saa7134_dev *dev, int open) +{ + /* enable tuner */ + int i; + static const u8 buffer [][2] = { + { 0x10, 0x12 }, + { 0x13, 0x04 }, + { 0x16, 0x00 }, + { 0x14, 0x04 }, + { 0x17, 0x00 }, + }; + + dev->i2c_client.addr = 0x0a; + + /* FIXME: don't know how to close the i2c gate on NXT200x */ + if (!open) + return; + + for (i = 0; i < ARRAY_SIZE(buffer); i++) + if (2 != i2c_master_send(&dev->i2c_client, + &buffer[i][0], ARRAY_SIZE(buffer[0]))) + printk(KERN_WARNING + "%s: Unable to enable tuner(%i).\n", + dev->name, i); +} + int saa7134_board_init1(struct saa7134_dev *dev) { /* Always print gpio, often manufacturers encode tuner type and other info. */ @@ -6192,6 +6218,10 @@ int saa7134_board_init1(struct saa7134_dev *dev) "are supported for now.\n", dev->name, card(dev).name, dev->name); break; + case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI: + case SAA7134_BOARD_KWORLD_ATSC110: + dev->gate_ctrl = nxt200x_gate_ctrl; + break; } return 0; } @@ -6453,22 +6483,6 @@ int saa7134_board_init2(struct saa7134_dev *dev) i2c_transfer(&dev->i2c_adap, &msg, 1); break; } - case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI: - case SAA7134_BOARD_KWORLD_ATSC110: - { - /* enable tuner */ - int i; - static const u8 buffer [] = { 0x10, 0x12, 0x13, 0x04, 0x16, - 0x00, 0x14, 0x04, 0x17, 0x00 }; - dev->i2c_client.addr = 0x0a; - for (i = 0; i < 5; i++) - if (2 != i2c_master_send(&dev->i2c_client, - &buffer[i*2], 2)) - printk(KERN_WARNING - "%s: Unable to enable tuner(%i).\n", - dev->name, i); - break; - } case SAA7134_BOARD_VIDEOMATE_DVBT_200: case SAA7134_BOARD_VIDEOMATE_DVBT_200A: /* The T200 and the T200A share the same pci id. Consequently, diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h index 9e3b37c73..040f447c6 100644 --- a/linux/drivers/media/video/saa7134/saa7134.h +++ b/linux/drivers/media/video/saa7134/saa7134.h @@ -594,6 +594,7 @@ struct saa7134_dev { int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage); int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg); #endif + void (*gate_ctrl)(struct saa7134_dev *dev, int open); }; /* ----------------------------------------------------------- */ @@ -623,10 +624,24 @@ struct saa7134_dev { V4L2_STD_PAL_60) #define GRP_EMPRESS (1) -#define saa_call_all(dev, o, f, args...) \ - v4l2_device_call_all(&(dev)->v4l2_dev, 0, o, f , ##args) -#define saa_call_empress(dev, o, f, args...) \ - v4l2_device_call_until_err(&(dev)->v4l2_dev, GRP_EMPRESS, o, f , ##args) +#define saa_call_all(dev, o, f, args...) do { \ + if (dev->gate_ctrl) \ + dev->gate_ctrl(dev, 1); \ + v4l2_device_call_all(&(dev)->v4l2_dev, 0, o, f , ##args); \ + if (dev->gate_ctrl) \ + dev->gate_ctrl(dev, 0); \ +} while (0) + +#define saa_call_empress(dev, o, f, args...) ({ \ + long _rc; \ + if (dev->gate_ctrl) \ + dev->gate_ctrl(dev, 1); \ + _rc = v4l2_device_call_until_err(&(dev)->v4l2_dev, \ + GRP_EMPRESS, o, f , ##args); \ + if (dev->gate_ctrl) \ + dev->gate_ctrl(dev, 0); \ + _rc; \ +}) /* ----------------------------------------------------------- */ /* saa7134-core.c */ -- cgit v1.2.3 From 52f0176e96723bde788c5dcbab7fa5318f8feece Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Mon, 19 Jan 2009 10:31:55 -0200 Subject: em28xx: Add entry for GADMEI TVR200 From: Douglas Schilling Landgraf Added entry for GADMEI TVR200. Thanks to Yohanes Nugroho for testing and data collection. Priority: normal Signed-off-by: Douglas Schilling Landgraf --- linux/Documentation/video4linux/CARDLIST.em28xx | 1 + linux/drivers/media/video/em28xx/em28xx-cards.c | 20 ++++++++++++++++++++ linux/drivers/media/video/em28xx/em28xx.h | 1 + 3 files changed, 22 insertions(+) (limited to 'linux') diff --git a/linux/Documentation/video4linux/CARDLIST.em28xx b/linux/Documentation/video4linux/CARDLIST.em28xx index 75bded8a4..f7a7f48f4 100644 --- a/linux/Documentation/video4linux/CARDLIST.em28xx +++ b/linux/Documentation/video4linux/CARDLIST.em28xx @@ -58,3 +58,4 @@ 58 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041] 60 -> Hauppauge WinTV HVR 850 (em2883) [2040:651f] 61 -> Pixelview PlayTV Box 4 USB 2.0 (em2820/em2840) + 62 -> Gadmei TVR200 (em2820/em2840) diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index 60eae02b0..be788b5df 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -196,6 +196,25 @@ struct em28xx_board em28xx_boards[] = { .amux = EM28XX_AMUX_LINE_IN, } }, }, + [EM2820_BOARD_GADMEI_TVR200] = { + .name = "Gadmei TVR200", + .tuner_type = TUNER_LG_PAL_NEW_TAPC, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA711X, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = EM28XX_AMUX_LINE_IN, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = EM28XX_AMUX_LINE_IN, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = EM28XX_AMUX_LINE_IN, + } }, + }, [EM2820_BOARD_TERRATEC_CINERGY_250] = { .name = "Terratec Cinergy 250 USB", .tuner_type = TUNER_LG_PAL_NEW_TAPC, @@ -1418,6 +1437,7 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = { {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC}, {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC}, {0x1ba50080, EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA, TUNER_ABSENT}, + {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC}, }; int em28xx_tuner_callback(void *ptr, int component, int command, int arg) diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index bc5ebbe61..1e2ffea54 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -99,6 +99,7 @@ #define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58 #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60 #define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2 61 +#define EM2820_BOARD_GADMEI_TVR200 62 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v1.2.3 From 81918f1cd02153ce200d15d7113932aa42a270e6 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 19 Jan 2009 19:18:44 +0100 Subject: gspca - zc3xx: Sensor adcm2700 added. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/zc3xx.c | 454 +++++++++++++++++++++++++------- 1 file changed, 362 insertions(+), 92 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index fcfced0c2..cdd50a54c 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -48,25 +48,26 @@ struct sd { signed char sensor; /* Type of image sensor chip */ /* !! values used in different tables */ -#define SENSOR_CS2102 0 -#define SENSOR_CS2102K 1 -#define SENSOR_GC0305 2 -#define SENSOR_HDCS2020b 3 -#define SENSOR_HV7131B 4 -#define SENSOR_HV7131C 5 -#define SENSOR_ICM105A 6 -#define SENSOR_MC501CB 7 -#define SENSOR_OV7620 8 -/*#define SENSOR_OV7648 8 - same values */ -#define SENSOR_OV7630C 9 -#define SENSOR_PAS106 10 -#define SENSOR_PAS202B 11 -#define SENSOR_PB0330 12 -#define SENSOR_PO2030 13 -#define SENSOR_TAS5130CK 14 -#define SENSOR_TAS5130CXX 15 -#define SENSOR_TAS5130C_VF0250 16 -#define SENSOR_MAX 17 +#define SENSOR_ADCM2700 0 +#define SENSOR_CS2102 1 +#define SENSOR_CS2102K 2 +#define SENSOR_GC0305 3 +#define SENSOR_HDCS2020b 4 +#define SENSOR_HV7131B 5 +#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 unsigned short chip_revision; }; @@ -206,6 +207,241 @@ struct usb_action { __u16 idx; }; +static const struct usb_action adcm2700_Initial[] = { + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ + {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ + {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */ + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ + {0xa0, 0xd8, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d8,cc */ + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ + {0xa0, 0xde, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,de,cc */ + {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */ + {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */ + {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ + {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */ + {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ + {0xa0, 0x58, ZC3XX_R116_RGAIN}, /* 01,16,58,cc */ + {0xa0, 0x5a, ZC3XX_R118_BGAIN}, /* 01,18,5a,cc */ + {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ + {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */ + {0xbb, 0x00, 0x0408}, /* 04,00,08,bb */ + {0xdd, 0x00, 0x0200}, /* 00,02,00,dd */ + {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */ + {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ + {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */ + {0xbb, 0xe0, 0x0c2e}, /* 0c,e0,2e,bb */ + {0xbb, 0x01, 0x2000}, /* 20,01,00,bb */ + {0xbb, 0x96, 0x2400}, /* 24,96,00,bb */ + {0xbb, 0x06, 0x1006}, /* 10,06,06,bb */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ + {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ + {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ + {0xbb, 0x5f, 0x2090}, /* 20,5f,90,bb */ + {0xbb, 0x01, 0x8000}, /* 80,01,00,bb */ + {0xbb, 0x09, 0x8400}, /* 84,09,00,bb */ + {0xbb, 0x86, 0x0002}, /* 00,86,02,bb */ + {0xbb, 0xe6, 0x0401}, /* 04,e6,01,bb */ + {0xbb, 0x86, 0x0802}, /* 08,86,02,bb */ + {0xbb, 0xe6, 0x0c01}, /* 0c,e6,01,bb */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ + {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ + {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xaa, 0xfe, 0x0020}, /* 00,fe,20,aa */ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ + {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ + {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ + {0xbb, 0x04, 0x0400}, /* 04,04,00,bb */ + {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ + {0xbb, 0x01, 0x0400}, /* 04,01,00,bb */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ + {0xbb, 0x41, 0x2803}, /* 28,41,03,bb */ + {0xbb, 0x40, 0x2c03}, /* 2c,40,03,bb */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ + {} +}; +static const struct usb_action adcm2700_InitialScale[] = { + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ + {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ + {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */ + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ + {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */ + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ + {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d8,cc */ + {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */ + {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */ + {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ + {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */ + {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ + {0xa0, 0x58, ZC3XX_R116_RGAIN}, /* 01,16,58,cc */ + {0xa0, 0x5a, ZC3XX_R118_BGAIN}, /* 01,18,5a,cc */ + {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ + {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */ + {0xbb, 0x00, 0x0408}, /* 04,00,08,bb */ + {0xdd, 0x00, 0x0200}, /* 00,02,00,dd */ + {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */ + {0xdd, 0x00, 0x0050}, /* 00,00,50,dd */ + {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */ + {0xbb, 0xe0, 0x0c2e}, /* 0c,e0,2e,bb */ + {0xbb, 0x01, 0x2000}, /* 20,01,00,bb */ + {0xbb, 0x96, 0x2400}, /* 24,96,00,bb */ + {0xbb, 0x06, 0x1006}, /* 10,06,06,bb */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ + {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ + {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ + {0xbb, 0x5f, 0x2090}, /* 20,5f,90,bb */ + {0xbb, 0x01, 0x8000}, /* 80,01,00,bb */ + {0xbb, 0x09, 0x8400}, /* 84,09,00,bb */ + {0xbb, 0x88, 0x0002}, /* 00,88,02,bb */ + {0xbb, 0xe6, 0x0401}, /* 04,e6,01,bb */ + {0xbb, 0x88, 0x0802}, /* 08,88,02,bb */ + {0xbb, 0xe6, 0x0c01}, /* 0c,e6,01,bb */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ + {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ + {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xaa, 0xfe, 0x0020}, /* 00,fe,20,aa */ + /*******/ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ + {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ + {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ + {0xbb, 0x04, 0x0400}, /* 04,04,00,bb */ + {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ + {0xbb, 0x01, 0x0400}, /* 04,01,00,bb */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ + {0xbb, 0x41, 0x2803}, /* 28,41,03,bb */ + {0xbb, 0x40, 0x2c03}, /* 2c,40,03,bb */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ + {} +}; +static const struct usb_action adcm2700_50HZ[] = { + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ + {0xbb, 0x05, 0x8400}, /* 84,05,00,bb */ + {0xbb, 0xd0, 0xb007}, /* b0,d0,07,bb */ + {0xbb, 0xa0, 0xb80f}, /* b8,a0,0f,bb */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ + {0xaa, 0x26, 0x00d0}, /* 00,26,d0,aa */ + {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */ + {} +}; +static const struct usb_action adcm2700_50HZScale[] = { + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ + {0xbb, 0x05, 0x8400}, /* 84,05,00,bb */ + {0xbb, 0xd0, 0xb007}, /* b0,d0,07,bb */ + {0xbb, 0xa0, 0xb80f}, /* b8,a0,0f,bb */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ + {0xaa, 0x26, 0x00d0}, /* 00,26,d0,aa */ + {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */ + {} +}; +static const struct usb_action adcm2700_60HZ[] = { + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ + {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */ + {0xbb, 0x82, 0xb006}, /* b0,82,06,bb */ + {0xbb, 0x04, 0xb80d}, /* b8,04,0d,bb */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ + {0xaa, 0x26, 0x0057}, /* 00,26,57,aa */ + {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */ + {} +}; +static const struct usb_action adcm2700_60HZScale[] = { + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ + {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */ + {0xbb, 0x82, 0xb006}, /* b0,82,06,bb */ + {0xbb, 0x04, 0xb80d}, /* b8,04,0d,bb */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ + {0xaa, 0x26, 0x0057}, /* 00,26,57,aa */ + {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */ + {} +}; +static const struct usb_action adcm2700_NoFliker[] = { + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ + {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */ + {0xbb, 0x05, 0xb000}, /* b0,05,00,bb */ + {0xbb, 0xa0, 0xb801}, /* b8,a0,01,bb */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ + {} +}; +static const struct usb_action adcm2700_NoFlikerScale[] = { + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ + {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */ + {0xbb, 0x05, 0xb000}, /* b0,05,00,bb */ + {0xbb, 0xa0, 0xb801}, /* b8,a0,01,bb */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ + {} +}; static const struct usb_action cs2102_Initial[] = { {0xa1, 0x01, 0x0008}, {0xa1, 0x01, 0x0008}, @@ -6291,8 +6527,8 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev, __u8 retbyte; __u16 retval; - reg_w_i(gspca_dev->dev, reg, 0x92); - reg_w_i(gspca_dev->dev, 0x02, 0x90); /* <- read command */ + reg_w_i(gspca_dev->dev, reg, 0x0092); + reg_w_i(gspca_dev->dev, 0x02, 0x0090); /* <- read command */ msleep(25); retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ @@ -6337,6 +6573,12 @@ static void usb_exchange(struct gspca_dev *gspca_dev, action->idx & 0xff, /* valL */ action->idx >> 8); /* valH */ break; + case 0xbb: + i2c_write(gspca_dev, + action->idx >> 8, /* reg */ + action->idx & 0xff, /* valL */ + action->val); /* valH */ + break; default: /* case 0xdd: * delay */ msleep(action->val / 64 + 10); @@ -6352,6 +6594,8 @@ static void setmatrix(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int i; const __u8 *matrix; + static const u8 adcm2700_matrix[9] = + {0x66, 0xed, 0xed, 0xed, 0x66, 0xed, 0xed, 0xed, 0x66}; static const __u8 gc0305_matrix[9] = {0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50}; static const __u8 ov7620_matrix[9] = @@ -6363,23 +6607,24 @@ static void setmatrix(struct gspca_dev *gspca_dev) static const __u8 vf0250_matrix[9] = {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b}; static const __u8 *matrix_tb[SENSOR_MAX] = { - NULL, /* SENSOR_CS2102 0 */ - NULL, /* SENSOR_CS2102K 1 */ - gc0305_matrix, /* SENSOR_GC0305 2 */ - NULL, /* SENSOR_HDCS2020b 3 */ - NULL, /* SENSOR_HV7131B 4 */ - NULL, /* SENSOR_HV7131C 5 */ - NULL, /* SENSOR_ICM105A 6 */ - NULL, /* SENSOR_MC501CB 7 */ - ov7620_matrix, /* SENSOR_OV7620 8 */ - NULL, /* SENSOR_OV7630C 9 */ - NULL, /* SENSOR_PAS106 10 */ - pas202b_matrix, /* SENSOR_PAS202B 11 */ - NULL, /* SENSOR_PB0330 12 */ - po2030_matrix, /* SENSOR_PO2030 13 */ - NULL, /* SENSOR_TAS5130CK 14 */ - NULL, /* SENSOR_TAS5130CXX 15 */ - vf0250_matrix, /* SENSOR_TAS5130C_VF0250 16 */ + adcm2700_matrix, /* SENSOR_ADCM2700 0 */ + NULL, /* SENSOR_CS2102 1 */ + NULL, /* SENSOR_CS2102K 2 */ + gc0305_matrix, /* SENSOR_GC0305 3 */ + NULL, /* SENSOR_HDCS2020b 4 */ + NULL, /* SENSOR_HV7131B 5 */ + 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 */ + NULL, /* SENSOR_TAS5130CXX 16 */ + vf0250_matrix, /* SENSOR_TAS5130C_VF0250 17 */ }; matrix = matrix_tb[sd->sensor]; @@ -6395,6 +6640,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) __u8 brightness; switch (sd->sensor) { + case SENSOR_ADCM2700: case SENSOR_GC0305: case SENSOR_OV7620: case SENSOR_PO2030: @@ -6579,71 +6825,75 @@ static int setlightfreq(struct gspca_dev *gspca_dev) int i, mode; const struct usb_action *zc3_freq; static const struct usb_action *freq_tb[SENSOR_MAX][6] = { -/* SENSOR_CS2102 0 */ +/* SENSOR_ADCM2700 0 */ + {adcm2700_NoFlikerScale, adcm2700_NoFliker, + adcm2700_50HZScale, adcm2700_50HZ, + adcm2700_60HZScale, adcm2700_60HZ}, +/* SENSOR_CS2102 1 */ {cs2102_NoFliker, cs2102_NoFlikerScale, cs2102_50HZ, cs2102_50HZScale, cs2102_60HZ, cs2102_60HZScale}, -/* SENSOR_CS2102K 1 */ +/* SENSOR_CS2102K 2 */ {cs2102_NoFliker, cs2102_NoFlikerScale, NULL, NULL, /* currently disabled */ NULL, NULL}, -/* SENSOR_GC0305 2 */ +/* SENSOR_GC0305 3 */ {gc0305_NoFliker, gc0305_NoFliker, gc0305_50HZ, gc0305_50HZ, gc0305_60HZ, gc0305_60HZ}, -/* SENSOR_HDCS2020b 3 */ +/* SENSOR_HDCS2020b 4 */ {hdcs2020b_NoFliker, hdcs2020b_NoFliker, hdcs2020b_50HZ, hdcs2020b_50HZ, hdcs2020b_60HZ, hdcs2020b_60HZ}, -/* SENSOR_HV7131B 4 */ +/* SENSOR_HV7131B 5 */ {hv7131b_NoFlikerScale, hv7131b_NoFliker, hv7131b_50HZScale, hv7131b_50HZ, hv7131b_60HZScale, hv7131b_60HZ}, -/* SENSOR_HV7131C 5 */ +/* SENSOR_HV7131C 6 */ {NULL, NULL, NULL, NULL, NULL, NULL}, -/* SENSOR_ICM105A 6 */ +/* SENSOR_ICM105A 7 */ {icm105a_NoFliker, icm105a_NoFlikerScale, icm105a_50HZ, icm105a_50HZScale, icm105a_60HZ, icm105a_60HZScale}, -/* SENSOR_MC501CB 7 */ +/* SENSOR_MC501CB 8 */ {MC501CB_NoFliker, MC501CB_NoFlikerScale, MC501CB_50HZ, MC501CB_50HZScale, MC501CB_60HZ, MC501CB_60HZScale}, -/* SENSOR_OV7620 8 */ +/* SENSOR_OV7620 9 */ {OV7620_NoFliker, OV7620_NoFliker, OV7620_50HZ, OV7620_50HZ, OV7620_60HZ, OV7620_60HZ}, -/* SENSOR_OV7630C 9 */ +/* SENSOR_OV7630C 10 */ {NULL, NULL, NULL, NULL, NULL, NULL}, -/* SENSOR_PAS106 10 */ +/* SENSOR_PAS106 11 */ {pas106b_NoFliker, pas106b_NoFliker, pas106b_50HZ, pas106b_50HZ, pas106b_60HZ, pas106b_60HZ}, -/* SENSOR_PAS202B 11 */ +/* SENSOR_PAS202B 12 */ {pas202b_NoFlikerScale, pas202b_NoFliker, pas202b_50HZScale, pas202b_50HZ, pas202b_60HZScale, pas202b_60HZ}, -/* SENSOR_PB0330 12 */ +/* SENSOR_PB0330 13 */ {pb0330_NoFliker, pb0330_NoFlikerScale, pb0330_50HZ, pb0330_50HZScale, pb0330_60HZ, pb0330_60HZScale}, -/* SENSOR_PO2030 13 */ +/* SENSOR_PO2030 14 */ {PO2030_NoFliker, PO2030_NoFliker, PO2030_50HZ, PO2030_50HZ, PO2030_60HZ, PO2030_60HZ}, -/* SENSOR_TAS5130CK 14 */ +/* SENSOR_TAS5130CK 15 */ {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale, tas5130cxx_50HZ, tas5130cxx_50HZScale, tas5130cxx_60HZ, tas5130cxx_60HZScale}, -/* SENSOR_TAS5130CXX 15 */ +/* SENSOR_TAS5130CXX 16 */ {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale, tas5130cxx_50HZ, tas5130cxx_50HZScale, tas5130cxx_60HZ, tas5130cxx_60HZScale}, -/* SENSOR_TAS5130C_VF0250 16 */ +/* SENSOR_TAS5130C_VF0250 17 */ {tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale, tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale, tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale}, @@ -6697,6 +6947,7 @@ static void send_unknown(struct usb_device *dev, int sensor) reg_w(dev, 0x0c, 0x003b); reg_w(dev, 0x08, 0x0038); break; + case SENSOR_ADCM2700: case SENSOR_GC0305: case SENSOR_OV7620: case SENSOR_PB0330: @@ -6954,7 +7205,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) retword = i2c_read(gspca_dev, 0x01); if (retword != 0) { PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword); - return 0x0a; /* ?? */ + return retword; /* 0x6200/0x6100?? */ } return -1; } @@ -6998,23 +7249,24 @@ static int sd_config(struct gspca_dev *gspca_dev, int sensor; int vga = 1; /* 1: vga, 0: sif */ static const __u8 gamma[SENSOR_MAX] = { - 5, /* SENSOR_CS2102 0 */ - 5, /* SENSOR_CS2102K 1 */ - 4, /* SENSOR_GC0305 2 */ - 4, /* SENSOR_HDCS2020b 3 */ - 4, /* SENSOR_HV7131B 4 */ - 4, /* SENSOR_HV7131C 5 */ - 4, /* SENSOR_ICM105A 6 */ - 4, /* SENSOR_MC501CB 7 */ - 3, /* SENSOR_OV7620 8 */ - 4, /* SENSOR_OV7630C 9 */ - 4, /* SENSOR_PAS106 10 */ - 4, /* SENSOR_PAS202B 11 */ - 4, /* SENSOR_PB0330 12 */ - 4, /* SENSOR_PO2030 13 */ - 4, /* SENSOR_TAS5130CK 14 */ - 4, /* SENSOR_TAS5130CXX 15 */ - 3, /* SENSOR_TAS5130C_VF0250 16 */ + 4, /* SENSOR_ADCM2700 0 */ + 5, /* SENSOR_CS2102 1 */ + 5, /* SENSOR_CS2102K 2 */ + 4, /* SENSOR_GC0305 3 */ + 4, /* SENSOR_HDCS2020b 4 */ + 4, /* SENSOR_HV7131B 5 */ + 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 */ + 4, /* SENSOR_TAS5130CXX 16 */ + 3, /* SENSOR_TAS5130C_VF0250 17 */ }; /* define some sensors from the vendor/product */ @@ -7022,7 +7274,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->sensor = id->driver_info; sensor = zcxx_probeSensor(gspca_dev); if (sensor >= 0) - PDEBUG(D_PROBE, "probe sensor -> %02x", sensor); + PDEBUG(D_PROBE, "probe sensor -> %04x", sensor); if ((unsigned) force_sensor < SENSOR_MAX) { sd->sensor = force_sensor; PDEBUG(D_PROBE, "sensor forced to %d", force_sensor); @@ -7114,6 +7366,12 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->sensor = SENSOR_PO2030; sd->sharpness = 0; /* from win traces */ break; + case 0x6100: + case 0x6200: + PDEBUG(D_PROBE, "Find Sensor ADCM2700"); + sd->sensor = SENSOR_ADCM2700; + send_unknown(gspca_dev->dev, sd->sensor); + break; case 0x7620: PDEBUG(D_PROBE, "Find Sensor OV7620"); sd->sensor = SENSOR_OV7620; @@ -7183,25 +7441,26 @@ static int sd_start(struct gspca_dev *gspca_dev) const struct usb_action *zc3_init; int mode; static const struct usb_action *init_tb[SENSOR_MAX][2] = { - {cs2102_InitialScale, cs2102_Initial}, /* 0 */ - {cs2102K_InitialScale, cs2102K_Initial}, /* 1 */ - {gc0305_Initial, gc0305_InitialScale}, /* 2 */ - {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 3 */ - {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 4 */ - {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 5 */ - {icm105axx_InitialScale, icm105axx_Initial}, /* 6 */ - {MC501CB_InitialScale, MC501CB_Initial}, /* 7 */ - {OV7620_mode0, OV7620_mode1}, /* 8 */ - {ov7630c_InitialScale, ov7630c_Initial}, /* 9 */ - {pas106b_InitialScale, pas106b_Initial}, /* 10 */ - {pas202b_Initial, pas202b_InitialScale}, /* 11 */ - {pb0330xx_InitialScale, pb0330xx_Initial}, /* 12 */ + {adcm2700_Initial, adcm2700_InitialScale}, /* 0 */ + {cs2102_InitialScale, cs2102_Initial}, /* 1 */ + {cs2102K_InitialScale, cs2102K_Initial}, /* 2 */ + {gc0305_Initial, gc0305_InitialScale}, /* 3 */ + {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 4 */ + {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 5 */ + {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}, /* 13 */ - {tas5130CK_InitialScale, tas5130CK_Initial}, /* 14 */ - {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 15 */ + {PO2030_mode0, PO2030_mode1}, /* 14 */ + {tas5130CK_InitialScale, tas5130CK_Initial}, /* 15 */ + {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 16 */ {tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial}, - /* 16 */ + /* 17 */ }; mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; @@ -7230,11 +7489,12 @@ static int sd_start(struct gspca_dev *gspca_dev) usb_exchange(gspca_dev, zc3_init); switch (sd->sensor) { + case SENSOR_ADCM2700: case SENSOR_GC0305: case SENSOR_OV7620: case SENSOR_PO2030: case SENSOR_TAS5130C_VF0250: - msleep(100); /* ?? */ +/* msleep(100); * ?? */ reg_r(gspca_dev, 0x0002); /* --> 0x40 */ reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ reg_w(dev, 0x15, 0x01ae); @@ -7247,6 +7507,7 @@ static int sd_start(struct gspca_dev *gspca_dev) setmatrix(gspca_dev); setbrightness(gspca_dev); switch (sd->sensor) { + case SENSOR_ADCM2700: case SENSOR_OV7620: reg_r(gspca_dev, 0x0008); reg_w(dev, 0x00, 0x0008); @@ -7280,6 +7541,8 @@ static int sd_start(struct gspca_dev *gspca_dev) } setmatrix(gspca_dev); /* one more time? */ switch (sd->sensor) { + case SENSOR_ADCM2700: + break; case SENSOR_OV7620: case SENSOR_PAS202B: reg_r(gspca_dev, 0x0180); /* from win */ @@ -7292,6 +7555,13 @@ static int sd_start(struct gspca_dev *gspca_dev) setlightfreq(gspca_dev); switch (sd->sensor) { + case SENSOR_ADCM2700: + reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ + reg_w(dev, 0x15, 0x01ae); + reg_w(dev, 0x02, 0x0180); + /* ms-win + */ + reg_w(dev, 0x40, 0x0117); + break; case SENSOR_GC0305: reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ reg_w(dev, 0x15, 0x01ae); -- cgit v1.2.3 From abb1079c763e18e9ce439cb735be87aa23d8475c Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 20 Jan 2009 09:12:34 +0100 Subject: gspca - zc3xx: Bad probe of the sensor adcm2700. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/zc3xx.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index cdd50a54c..278db1648 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -7089,6 +7089,7 @@ static const struct sensor_by_chipset_revision chipset_revision_sensor[] = { {0x8001, 0x13}, {0x8000, 0x14}, /* CS2102K */ {0x8400, 0x15}, /* TAS5130K */ + {0x4001, 0x16}, /* ADCM2700 */ }; static int vga_3wr_probe(struct gspca_dev *gspca_dev) @@ -7205,7 +7206,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) retword = i2c_read(gspca_dev, 0x01); if (retword != 0) { PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword); - return retword; /* 0x6200/0x6100?? */ + return retword; } return -1; } @@ -7353,6 +7354,10 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->chip_revision); sd->sensor = SENSOR_TAS5130CK; break; + case 0x16: + PDEBUG(D_PROBE, "Find Sensor ADCM2700"); + sd->sensor = SENSOR_ADCM2700; + break; case 0x29: PDEBUG(D_PROBE, "Find Sensor GC0305"); sd->sensor = SENSOR_GC0305; @@ -7366,12 +7371,6 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->sensor = SENSOR_PO2030; sd->sharpness = 0; /* from win traces */ break; - case 0x6100: - case 0x6200: - PDEBUG(D_PROBE, "Find Sensor ADCM2700"); - sd->sensor = SENSOR_ADCM2700; - send_unknown(gspca_dev->dev, sd->sensor); - break; case 0x7620: PDEBUG(D_PROBE, "Find Sensor OV7620"); sd->sensor = SENSOR_OV7620; @@ -7381,7 +7380,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->sensor = SENSOR_OV7620; /* same sensor (?) */ break; default: - PDEBUG(D_ERR|D_PROBE, "Unknown sensor %02x", sensor); + PDEBUG(D_ERR|D_PROBE, "Unknown sensor %04x", sensor); return -EINVAL; } } -- cgit v1.2.3 From 154e87c5249bd7b21435aad636a109ad9c7ec039 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 20 Jan 2009 12:14:17 +0100 Subject: gspca - zc3xx: Remove duplicated sequence of sensor cs2102k. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/zc3xx.c | 205 +------------------------------- 1 file changed, 3 insertions(+), 202 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index 278db1648..85497ea1f 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -1113,7 +1113,7 @@ static const struct usb_action cs2102K_Initial[] = { }; static const struct usb_action cs2102K_InitialScale[] = { - {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, @@ -1130,6 +1130,7 @@ static const struct usb_action cs2102K_InitialScale[] = { {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, +/*fixme: next sequence = i2c exchanges*/ {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR}, {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, @@ -1313,207 +1314,6 @@ static const struct usb_action cs2102K_InitialScale[] = { {0xa0, 0x60, ZC3XX_R116_RGAIN}, {0xa0, 0x40, ZC3XX_R117_GGAIN}, {0xa0, 0x4c, ZC3XX_R118_BGAIN}, - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, - {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, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, - {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, - {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x0A, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x0B, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x0C, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x7b, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x0D, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0xA3, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x03, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x08, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x0E, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x0C, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x78, ZC3XX_R18D_YTARGET}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, - {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xa0, 0x00, 0x01ad}, - {0xa0, 0x01, 0x01b1}, - {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x60, ZC3XX_R116_RGAIN}, - {0xa0, 0x40, ZC3XX_R117_GGAIN}, - {0xa0, 0x4c, ZC3XX_R118_BGAIN}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {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, 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}, - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, - {0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x0f, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0x19, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0x1f, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x60, ZC3XX_R116_RGAIN}, - {0xa0, 0x40, ZC3XX_R117_GGAIN}, - {0xa0, 0x4c, ZC3XX_R118_BGAIN}, {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, @@ -1570,6 +1370,7 @@ static const struct usb_action cs2102K_InitialScale[] = { {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, +/*fixme:what does the next sequence?*/ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, -- cgit v1.2.3 From 5b8037b48a2ec01ef6b8cb460a96db73d5d276ba Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 20 Jan 2009 14:02:35 +0100 Subject: gspca - zc3xx: Remove some useless tables of sensor adcm2700. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/zc3xx.c | 43 +++------------------------------ 1 file changed, 3 insertions(+), 40 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index 85497ea1f..300bbd00c 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -381,19 +381,6 @@ static const struct usb_action adcm2700_50HZ[] = { {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */ {} }; -static const struct usb_action adcm2700_50HZScale[] = { - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xbb, 0x05, 0x8400}, /* 84,05,00,bb */ - {0xbb, 0xd0, 0xb007}, /* b0,d0,07,bb */ - {0xbb, 0xa0, 0xb80f}, /* b8,a0,0f,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ - {0xaa, 0x26, 0x00d0}, /* 00,26,d0,aa */ - {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */ - {} -}; static const struct usb_action adcm2700_60HZ[] = { {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ @@ -407,19 +394,6 @@ static const struct usb_action adcm2700_60HZ[] = { {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */ {} }; -static const struct usb_action adcm2700_60HZScale[] = { - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */ - {0xbb, 0x82, 0xb006}, /* b0,82,06,bb */ - {0xbb, 0x04, 0xb80d}, /* b8,04,0d,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ - {0xaa, 0x26, 0x0057}, /* 00,26,57,aa */ - {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */ - {} -}; static const struct usb_action adcm2700_NoFliker[] = { {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ @@ -431,17 +405,6 @@ static const struct usb_action adcm2700_NoFliker[] = { {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ {} }; -static const struct usb_action adcm2700_NoFlikerScale[] = { - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */ - {0xbb, 0x05, 0xb000}, /* b0,05,00,bb */ - {0xbb, 0xa0, 0xb801}, /* b8,a0,01,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ - {} -}; static const struct usb_action cs2102_Initial[] = { {0xa1, 0x01, 0x0008}, {0xa1, 0x01, 0x0008}, @@ -6627,9 +6590,9 @@ static int setlightfreq(struct gspca_dev *gspca_dev) const struct usb_action *zc3_freq; static const struct usb_action *freq_tb[SENSOR_MAX][6] = { /* SENSOR_ADCM2700 0 */ - {adcm2700_NoFlikerScale, adcm2700_NoFliker, - adcm2700_50HZScale, adcm2700_50HZ, - adcm2700_60HZScale, adcm2700_60HZ}, + {adcm2700_NoFliker, adcm2700_NoFliker, + adcm2700_50HZ, adcm2700_50HZ, + adcm2700_60HZ, adcm2700_60HZ}, /* SENSOR_CS2102 1 */ {cs2102_NoFliker, cs2102_NoFlikerScale, cs2102_50HZ, cs2102_50HZScale, -- cgit v1.2.3 From f88d225f8dce1992c01bb023055f4b626861663c Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 20 Jan 2009 20:21:44 +0100 Subject: gspca - main: Avoid error on set interface on disconnection. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/gspca.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index ed129db3d..f5fad6905 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -675,7 +675,8 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev) && gspca_dev->sd_desc->stopN) gspca_dev->sd_desc->stopN(gspca_dev); destroy_urbs(gspca_dev); - gspca_set_alt0(gspca_dev); + if (gspca_dev->present) + gspca_set_alt0(gspca_dev); if (gspca_dev->sd_desc->stop0) gspca_dev->sd_desc->stop0(gspca_dev); PDEBUG(D_STREAM, "stream off OK"); -- cgit v1.2.3 From 48bd5d0791a4bfa37b864d064447083d18ec9030 Mon Sep 17 00:00:00 2001 From: Thierry MERLE Date: Tue, 20 Jan 2009 21:40:44 +0100 Subject: usbvision: use usb_make_path to report bus info From: Thierry MERLE usb_make_path reports canonical bus info. Use it when reporting bus info in VIDIOC_QUERYCAP. Priority: normal Signed-off-by: Thierry MERLE --- linux/drivers/media/video/usbvision/usbvision-video.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c index 47d672da5..334c77d91 100644 --- a/linux/drivers/media/video/usbvision/usbvision-video.c +++ b/linux/drivers/media/video/usbvision/usbvision-video.c @@ -526,8 +526,7 @@ static int vidioc_querycap (struct file *file, void *priv, strlcpy(vc->card, usbvision_device_data[usbvision->DevModel].ModelString, sizeof(vc->card)); - strlcpy(vc->bus_info, dev_name(&usbvision->dev->dev), - sizeof(vc->bus_info)); + usb_make_path(usbvision->dev, vc->bus_info, sizeof(vc->bus_info)); vc->version = USBVISION_DRIVER_VERSION; vc->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO | -- cgit v1.2.3 From 8d9ad37755717f75c8616e05eb949fc7c9311ae7 Mon Sep 17 00:00:00 2001 From: Thierry MERLE Date: Tue, 20 Jan 2009 22:01:33 +0100 Subject: em28xx: use usb_make_path to report bus info From: Thierry MERLE usb_make_path reports canonical bus info. Use it when reporting bus info in VIDIOC_QUERYCAP. Priority: normal Signed-off-by: Thierry MERLE --- linux/drivers/media/video/em28xx/em28xx-video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index 58a16fe8f..50c3af538 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -1360,7 +1360,7 @@ static int vidioc_querycap(struct file *file, void *priv, strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); - strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info)); + usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); cap->version = EM28XX_VERSION_CODE; @@ -1548,7 +1548,7 @@ static int radio_querycap(struct file *file, void *priv, strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); - strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info)); + usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); cap->version = EM28XX_VERSION_CODE; cap->capabilities = V4L2_CAP_TUNER; -- cgit v1.2.3 From 84a2c3b589a287878dce4e2b7380b9250bc56392 Mon Sep 17 00:00:00 2001 From: Thierry MERLE Date: Tue, 27 Jan 2009 20:53:23 +0100 Subject: uvcvideo: use usb_make_path to report bus info From: Thierry MERLE usb_make_path reports canonical bus info. Use it when reporting bus info in VIDIOC_QUERYCAP. Priority: normal Signed-off-by: Thierry MERLE Acked-by: Laurent Pinchart --- linux/drivers/media/video/uvc/uvc_v4l2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/uvc/uvc_v4l2.c b/linux/drivers/media/video/uvc/uvc_v4l2.c index 9130349f4..0baa59f61 100644 --- a/linux/drivers/media/video/uvc/uvc_v4l2.c +++ b/linux/drivers/media/video/uvc/uvc_v4l2.c @@ -494,8 +494,8 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) memset(cap, 0, sizeof *cap); strlcpy(cap->driver, "uvcvideo", sizeof cap->driver); strlcpy(cap->card, vdev->name, sizeof cap->card); - strlcpy(cap->bus_info, video->dev->udev->bus->bus_name, - sizeof cap->bus_info); + usb_make_path(video->dev->udev, + cap->bus_info, sizeof(cap->bus_info)); cap->version = DRIVER_VERSION_NUMBER; if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) cap->capabilities = V4L2_CAP_VIDEO_CAPTURE -- cgit v1.2.3 From 66be1e92cb9080a37ed87cba444d46cc84ea4f9b Mon Sep 17 00:00:00 2001 From: Thierry MERLE Date: Tue, 20 Jan 2009 22:19:25 +0100 Subject: s2255drv: use usb_make_path to report bus info From: Thierry MERLE usb_make_path reports canonical bus info. Use it when reporting bus info in VIDIOC_QUERYCAP. Priority: normal Signed-off-by: Thierry MERLE --- linux/drivers/media/video/s2255drv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/s2255drv.c b/linux/drivers/media/video/s2255drv.c index ffa2928b2..edfac2f9e 100644 --- a/linux/drivers/media/video/s2255drv.c +++ b/linux/drivers/media/video/s2255drv.c @@ -847,8 +847,7 @@ static int vidioc_querycap(struct file *file, void *priv, struct s2255_dev *dev = fh->dev; strlcpy(cap->driver, "s2255", sizeof(cap->driver)); strlcpy(cap->card, "s2255", sizeof(cap->card)); - strlcpy(cap->bus_info, dev_name(&dev->udev->dev), - sizeof(cap->bus_info)); + usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); cap->version = S2255_VERSION; cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; return 0; -- cgit v1.2.3 From a341145919a0d3bf91e657926a06bebca10a94ba Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 20 Jan 2009 15:34:43 -0600 Subject: V4L2: Add COLORFX user control From: Sergio Aguirre This is a common feature on many cameras. the options are: Default colors, B & W, Sepia Signed-off-by: Sergio Aguirre Signed-off-by: Mauro Carvalho Chehab --- linux/include/linux/videodev2.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index e5be28ac6..6969c3086 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -880,8 +880,15 @@ enum v4l2_power_line_frequency { #define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28) #define V4L2_CID_CHROMA_AGC (V4L2_CID_BASE+29) #define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30) +#define V4L2_CID_COLORFX (V4L2_CID_BASE+31) +enum v4l2_colorfx { + V4L2_COLORFX_NONE = 0, + V4L2_COLORFX_BW = 1, + V4L2_COLORFX_SEPIA = 2, +}; + /* last CID + 1 */ -#define V4L2_CID_LASTP1 (V4L2_CID_BASE+31) +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+32) /* MPEG-class control IDs defined by V4L2 */ #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) -- cgit v1.2.3 From cb5519edc2f73b4d39f212db0bd33f91bf789168 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Tue, 20 Jan 2009 23:37:20 -0500 Subject: dib0700: enable IR receiver in Nova TD usb stick (52009) From: Arne Luehrs Adds the IR data structure to the configuration datastructure of the Hauppauge WinTV Nova-TD USB stick (52009) Provided remote control is the same as theone provided with the Nova-T500 Card. Priority: normal Signed-off-by: Arne Luehrs Signed-off-by: Devin Heitmueller --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c index 635d30a55..a56b9ef3c 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1683,7 +1683,11 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[43], NULL }, { NULL }, } - } + }, + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = dib0700_rc_keys, + .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), + .rc_query = dib0700_rc_query }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, .num_adapters = 1, -- cgit v1.2.3 From 4b68b614c42107356972a9cb52d1f78b4b08465c Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Tue, 20 Jan 2009 23:40:04 -0500 Subject: dib0700: fix i2c error message to make data type clear From: Devin Heitmueller Make it clear that the address is in hex format. Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/dvb/dvb-usb/dib0700_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_core.c b/linux/drivers/media/dvb/dvb-usb/dib0700_core.c index 807bff0e1..46c425643 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -211,7 +211,8 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap, /* special thing in the current firmware: when length is zero the read-failed */ if ((len = dib0700_ctrl_rd(d, buf, msg[i].len + 2, msg[i+1].buf, msg[i+1].len)) <= 0) { - deb_info("I2C read failed on address %x\n", msg[i].addr); + deb_info("I2C read failed on address 0x%02x\n", + msg[i].addr); break; } -- cgit v1.2.3 From 7b223cea2628e4f6f6c21ede380a96f48e3f6f98 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Tue, 20 Jan 2009 23:55:45 -0500 Subject: dib0700: Report dib0700_i2c_enumeration failures From: Devin Heitmueller Make it clear that a failure in dib0700_i2c_enumeration is a fatal condition and we cannot continue. If the failure occurs, do not attempt to attach to the tuner. Problem Noticed the issue when debugging an i2c issue a YUAN High-Tech STK7700PH for user Roshan Karki . Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 37 ++++++++++++++++++----- 1 file changed, 30 insertions(+), 7 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c index a56b9ef3c..f291fb55f 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -262,7 +262,12 @@ static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap) msleep(10); dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10); - dib7000p_i2c_enumeration(&adap->dev->i2c_adap,1,18,stk7700d_dib7000p_mt2266_config); + if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + stk7700d_dib7000p_mt2266_config) + != 0) { + err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); + return -ENODEV; + } } adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1), @@ -284,7 +289,12 @@ static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap) dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib7000p_i2c_enumeration(&adap->dev->i2c_adap,2,18,stk7700d_dib7000p_mt2266_config); + if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, + stk7700d_dib7000p_mt2266_config) + != 0) { + err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); + return -ENODEV; + } } adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1), @@ -421,8 +431,12 @@ static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap) dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); msleep(10); - dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, - &stk7700ph_dib7700_xc3028_config); + if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + &stk7700ph_dib7700_xc3028_config) != 0) { + err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + __func__); + return -ENODEV; + } adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7700ph_dib7700_xc3028_config); @@ -1187,8 +1201,12 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap) msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, - &dib7070p_dib7000p_config); + if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + &dib7070p_dib7000p_config) != 0) { + err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + __func__); + return -ENODEV; + } adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &dib7070p_dib7000p_config); @@ -1244,7 +1262,12 @@ static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap) msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, stk7070pd_dib7000p_config); + if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, + stk7070pd_dib7000p_config) != 0) { + err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + __func__); + return -ENODEV; + } adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]); return adap->fe == NULL ? -ENODEV : 0; -- cgit v1.2.3 From 8754073a6ad9ca6fc1e6fd4743e64954b199a716 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 21 Jan 2009 19:32:26 +0100 Subject: gspca - main: Use usb_make_path() for VIDIOC_QUERYCAP. From: Thierry MERLE Priority: normal Signed-off-by: Thierry MERLE Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/gspca.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index f5fad6905..c3ea5339c 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -970,8 +970,7 @@ static int vidioc_querycap(struct file *file, void *priv, le16_to_cpu(gspca_dev->dev->descriptor.idVendor), le16_to_cpu(gspca_dev->dev->descriptor.idProduct)); } - strncpy(cap->bus_info, gspca_dev->dev->bus->bus_name, - sizeof cap->bus_info); + usb_make_path(gspca_dev->dev, cap->bus_info, sizeof(cap->bus_info)); cap->version = DRIVER_VERSION_NUMBER; cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING -- cgit v1.2.3 From e6d0b23f4968d16496be910dbd74ded05741dd6c Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 22 Jan 2009 11:18:48 +0100 Subject: gspca - t613: Cleanup and optimize code. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/t613.c | 379 ++++++++++++++++----------------- 1 file changed, 182 insertions(+), 197 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/t613.c b/linux/drivers/media/video/gspca/t613.c index af704242a..d2a5aea12 100644 --- a/linux/drivers/media/video/gspca/t613.c +++ b/linux/drivers/media/video/gspca/t613.c @@ -37,18 +37,18 @@ MODULE_LICENSE("GPL"); struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - unsigned char brightness; - unsigned char contrast; - unsigned char colors; - unsigned char autogain; - unsigned char gamma; - unsigned char sharpness; - unsigned char freq; - unsigned char whitebalance; - unsigned char mirror; - unsigned char effect; - - __u8 sensor; + u8 brightness; + u8 contrast; + u8 colors; + u8 autogain; + u8 gamma; + u8 sharpness; + u8 freq; + u8 whitebalance; + u8 mirror; + u8 effect; + + u8 sensor; #define SENSOR_TAS5130A 0 #define SENSOR_OM6802 1 }; @@ -78,7 +78,6 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, struct v4l2_querymenu *menu); static struct ctrl sd_ctrls[] = { -#define SD_BRIGHTNESS 0 { { .id = V4L2_CID_BRIGHTNESS, @@ -87,12 +86,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 14, .step = 1, - .default_value = 8, +#define BRIGHTNESS_DEF 8 + .default_value = BRIGHTNESS_DEF, }, .set = sd_setbrightness, .get = sd_getbrightness, }, -#define SD_CONTRAST 1 { { .id = V4L2_CID_CONTRAST, @@ -101,12 +100,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 0x0d, .step = 1, - .default_value = 0x07, +#define CONTRAST_DEF 0x07 + .default_value = CONTRAST_DEF, }, .set = sd_setcontrast, .get = sd_getcontrast, }, -#define SD_COLOR 2 { { .id = V4L2_CID_SATURATION, @@ -115,7 +114,8 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 0x0f, .step = 1, - .default_value = 0x05, +#define COLORS_DEF 0x05 + .default_value = COLORS_DEF, }, .set = sd_setcolors, .get = sd_getcolors, @@ -135,7 +135,6 @@ static struct ctrl sd_ctrls[] = { .set = sd_setgamma, .get = sd_getgamma, }, -#define SD_AUTOGAIN 4 { { .id = V4L2_CID_GAIN, /* here, i activate only the lowlight, @@ -146,12 +145,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 1, .step = 1, - .default_value = 0x01, +#define AUTOGAIN_DEF 0x01 + .default_value = AUTOGAIN_DEF, }, .set = sd_setlowlight, .get = sd_getlowlight, }, -#define SD_MIRROR 5 { { .id = V4L2_CID_HFLIP, @@ -160,12 +159,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 1, .step = 1, - .default_value = 0, +#define MIRROR_DEF 0 + .default_value = MIRROR_DEF, }, .set = sd_setflip, .get = sd_getflip }, -#define SD_LIGHTFREQ 6 { { .id = V4L2_CID_POWER_LINE_FREQUENCY, @@ -174,12 +173,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 1, /* 1 -> 0x50, 2->0x60 */ .maximum = 2, .step = 1, - .default_value = 1, +#define FREQ_DEF 1 + .default_value = FREQ_DEF, }, .set = sd_setfreq, .get = sd_getfreq}, -#define SD_WHITE_BALANCE 7 { { .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, @@ -188,12 +187,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 1, .step = 1, - .default_value = 0, +#define WHITE_BALANCE_DEF 0 + .default_value = WHITE_BALANCE_DEF, }, .set = sd_setwhitebalance, .get = sd_getwhitebalance }, -#define SD_SHARPNESS 8 /* (aka definition on win) */ { { .id = V4L2_CID_SHARPNESS, @@ -202,12 +201,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 15, .step = 1, - .default_value = 0x06, +#define SHARPNESS_DEF 0x06 + .default_value = SHARPNESS_DEF, }, .set = sd_setsharpness, .get = sd_getsharpness, }, -#define SD_EFFECTS 9 { { .id = V4L2_CID_EFFECTS, @@ -216,7 +215,8 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 4, .step = 1, - .default_value = 0, +#define EFFECTS_DEF 0 + .default_value = EFFECTS_DEF, }, .set = sd_seteffect, .get = sd_geteffect @@ -263,28 +263,22 @@ static const struct v4l2_pix_format vga_mode_t16[] = { /* sensor specific data */ struct additional_sensor_data { - const __u8 data1[20]; - const __u8 data2[18]; - const __u8 data3[18]; - const __u8 data4[4]; - const __u8 data5[6]; - const __u8 stream[4]; + const u8 data1[10]; + const u8 data2[9]; + const u8 data3[9]; + const u8 data4[4]; + const u8 data5[6]; + const u8 stream[4]; }; const static struct additional_sensor_data sensor_data[] = { { /* TAS5130A */ .data1 = - {0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, - 0xd4, 0xbb, 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27, - 0xd8, 0xc8, 0xd9, 0xfc}, + {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27, + 0xc8, 0xfc}, .data2 = - {0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, - 0xe4, 0xa8, 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8, - 0xe8, 0xe0}, - .data3 = - {0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, - 0xcb, 0xa8, 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8, - 0xcf, 0xe0}, + {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8, + 0xe0}, .data4 = /* Freq (50/60Hz). Splitted for test purpose */ {0x66, 0x00, 0xa8, 0xe8}, .data5 = @@ -294,17 +288,11 @@ const static struct additional_sensor_data sensor_data[] = { }, { /* OM6802 */ .data1 = - {0xd0, 0xc2, 0xd1, 0x28, 0xd2, 0x0f, 0xd3, 0x22, - 0xd4, 0xcd, 0xd5, 0x27, 0xd6, 0x2c, 0xd7, 0x06, - 0xd8, 0xb3, 0xd9, 0xfc}, + {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06, + 0xb3, 0xfc}, .data2 = - {0xe0, 0x80, 0xe1, 0xff, 0xe2, 0xff, 0xe3, 0x80, - 0xe4, 0xff, 0xe5, 0xff, 0xe6, 0x80, 0xe7, 0xff, - 0xe8, 0xff}, - .data3 = - {0xc7, 0x80, 0xc8, 0xff, 0xc9, 0xff, 0xca, 0x80, - 0xcb, 0xff, 0xcc, 0xff, 0xcd, 0x80, 0xce, 0xff, - 0xcf, 0xff}, + {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff, + 0xff}, .data4 = /*Freq (50/60Hz). Splitted for test purpose */ {0x66, 0xca, 0xa8, 0xf0 }, .data5 = /* this could be removed later */ @@ -317,7 +305,7 @@ const static struct additional_sensor_data sensor_data[] = { #define MAX_EFFECTS 7 /* easily done by soft, this table could be removed, * i keep it here just in case */ -static const __u8 effects_table[MAX_EFFECTS][6] = { +static const u8 effects_table[MAX_EFFECTS][6] = { {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */ {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */ {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */ @@ -327,90 +315,58 @@ static const __u8 effects_table[MAX_EFFECTS][6] = { {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */ }; -static const __u8 gamma_table[GAMMA_MAX][34] = { - {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85, /* 0 */ - 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9, - 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb, - 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8, - 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x33, 0x92, 0x5a, 0x93, 0x75, /* 1 */ - 0x94, 0x85, 0x95, 0x93, 0x96, 0xa1, 0x97, 0xad, - 0x98, 0xb7, 0x99, 0xc2, 0x9a, 0xcb, 0x9b, 0xd4, - 0x9c, 0xde, 0x9D, 0xe7, 0x9e, 0xf0, 0x9f, 0xf7, - 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x2f, 0x92, 0x51, 0x93, 0x6b, /* 2 */ - 0x94, 0x7c, 0x95, 0x8a, 0x96, 0x99, 0x97, 0xa6, - 0x98, 0xb1, 0x99, 0xbc, 0x9a, 0xc6, 0x9b, 0xd0, - 0x9c, 0xdb, 0x9d, 0xe4, 0x9e, 0xed, 0x9f, 0xf6, - 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60, /* 3 */ - 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9e, - 0x98, 0xaa, 0x99, 0xb5, 0x9a, 0xbf, 0x9b, 0xcb, - 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5, - 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x23, 0x92, 0x3f, 0x93, 0x55, /* 4 */ - 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95, - 0x98, 0xa2, 0x99, 0xad, 0x9a, 0xb9, 0x9b, 0xc6, - 0x9c, 0xd2, 0x9d, 0xde, 0x9e, 0xe9, 0x9f, 0xf4, - 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x1b, 0x92, 0x33, 0x93, 0x48, /* 5 */ - 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87, - 0x98, 0x96, 0x99, 0xa3, 0x9a, 0xb1, 0x9b, 0xbe, - 0x9c, 0xcc, 0x9d, 0xda, 0x9e, 0xe7, 0x9f, 0xf3, - 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20, /* 6 */ - 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67, - 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa, - 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee, - 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26, /* 7 */ - 0x94, 0x38, 0x95, 0x4a, 0x96, 0x60, 0x97, 0x70, - 0x98, 0x80, 0x99, 0x90, 0x9a, 0xa0, 0x9b, 0xb0, - 0x9c, 0xc0, 0x9D, 0xd0, 0x9e, 0xe0, 0x9f, 0xf0, - 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35, /* 8 */ - 0x94, 0x47, 0x95, 0x5a, 0x96, 0x69, 0x97, 0x79, - 0x98, 0x88, 0x99, 0x97, 0x9a, 0xa7, 0x9b, 0xb6, - 0x9c, 0xc4, 0x9d, 0xd3, 0x9e, 0xe0, 0x9f, 0xf0, - 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40, /* 9 */ - 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84, - 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, - 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0, - 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x18, 0x92, 0x2b, 0x93, 0x44, /* 10 */ - 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8e, - 0x98, 0x9c, 0x99, 0xaa, 0x9a, 0xb7, 0x9b, 0xc4, - 0x9c, 0xd0, 0x9d, 0xd8, 0x9e, 0xe2, 0x9f, 0xf0, - 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x1a, 0x92, 0x34, 0x93, 0x52, /* 11 */ - 0x94, 0x66, 0x95, 0x7e, 0x96, 0x8D, 0x97, 0x9B, - 0x98, 0xa8, 0x99, 0xb4, 0x9a, 0xc0, 0x9b, 0xcb, - 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5, - 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x3f, 0x92, 0x5a, 0x93, 0x6e, /* 12 */ - 0x94, 0x7f, 0x95, 0x8e, 0x96, 0x9c, 0x97, 0xa8, - 0x98, 0xb4, 0x99, 0xbf, 0x9a, 0xc9, 0x9b, 0xd3, - 0x9c, 0xdc, 0x9d, 0xe5, 0x9e, 0xee, 0x9f, 0xf6, - 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x54, 0x92, 0x6f, 0x93, 0x83, /* 13 */ - 0x94, 0x93, 0x95, 0xa0, 0x96, 0xad, 0x97, 0xb7, - 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdc, - 0x9c, 0xe4, 0x9d, 0xeb, 0x9e, 0xf2, 0x9f, 0xf9, - 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x6e, 0x92, 0x88, 0x93, 0x9a, /* 14 */ - 0x94, 0xa8, 0x95, 0xb3, 0x96, 0xbd, 0x97, 0xc6, - 0x98, 0xcf, 0x99, 0xd6, 0x9a, 0xdd, 0x9b, 0xe3, - 0x9c, 0xe9, 0x9d, 0xef, 0x9e, 0xf4, 0x9f, 0xfa, - 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x93, 0x92, 0xa8, 0x93, 0xb7, /* 15 */ - 0x94, 0xc1, 0x95, 0xca, 0x96, 0xd2, 0x97, 0xd8, - 0x98, 0xde, 0x99, 0xe3, 0x9a, 0xe8, 0x9b, 0xed, - 0x9c, 0xf1, 0x9d, 0xf5, 0x9e, 0xf8, 0x9f, 0xfc, - 0xa0, 0xff} +static const u8 gamma_table[GAMMA_MAX][17] = { + {0x00, 0x3e, 0x69, 0x85, 0x95, 0xa1, 0xae, 0xb9, /* 0 */ + 0xc2, 0xcb, 0xd4, 0xdb, 0xe3, 0xea, 0xf1, 0xf8, + 0xff}, + {0x00, 0x33, 0x5a, 0x75, 0x85, 0x93, 0xa1, 0xad, /* 1 */ + 0xb7, 0xc2, 0xcb, 0xd4, 0xde, 0xe7, 0xf0, 0xf7, + 0xff}, + {0x00, 0x2f, 0x51, 0x6b, 0x7c, 0x8a, 0x99, 0xa6, /* 2 */ + 0xb1, 0xbc, 0xc6, 0xd0, 0xdb, 0xe4, 0xed, 0xf6, + 0xff}, + {0x00, 0x29, 0x48, 0x60, 0x72, 0x81, 0x90, 0x9e, /* 3 */ + 0xaa, 0xb5, 0xbf, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5, + 0xff}, + {0x00, 0x23, 0x3f, 0x55, 0x68, 0x77, 0x86, 0x95, /* 4 */ + 0xa2, 0xad, 0xb9, 0xc6, 0xd2, 0xde, 0xe9, 0xf4, + 0xff}, + {0x00, 0x1b, 0x33, 0x48, 0x59, 0x69, 0x79, 0x87, /* 5 */ + 0x96, 0xa3, 0xb1, 0xbe, 0xcc, 0xda, 0xe7, 0xf3, + 0xff}, + {0x00, 0x02, 0x10, 0x20, 0x32, 0x40, 0x57, 0x67, /* 6 */ + 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, + 0xff}, + {0x00, 0x02, 0x14, 0x26, 0x38, 0x4a, 0x60, 0x70, /* 7 */ + 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, + 0xff}, + {0x00, 0x10, 0x22, 0x35, 0x47, 0x5a, 0x69, 0x79, /* 8 */ + 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe0, 0xf0, + 0xff}, + {0x00, 0x10, 0x26, 0x40, 0x54, 0x65, 0x75, 0x84, /* 9 */ + 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd6, 0xe0, 0xf0, + 0xff}, + {0x00, 0x18, 0x2b, 0x44, 0x60, 0x70, 0x80, 0x8e, /* 10 */ + 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xd8, 0xe2, 0xf0, + 0xff}, + {0x00, 0x1a, 0x34, 0x52, 0x66, 0x7e, 0x8D, 0x9B, /* 11 */ + 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5, + 0xff}, + {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */ + 0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6, + 0xff}, + {0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7, /* 13 */ + 0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9, + 0xff}, + {0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6, /* 14 */ + 0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa, + 0xff}, + {0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8, /* 15 */ + 0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc, + 0xff} }; -static const __u8 tas5130a_sensor_init[][8] = { +static const u8 tas5130a_sensor_init[][8] = { {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09}, {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09}, {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}, @@ -418,11 +374,11 @@ static const __u8 tas5130a_sensor_init[][8] = { {}, }; -static __u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07}; +static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07}; /* read 1 byte */ -static int reg_r(struct gspca_dev *gspca_dev, - __u16 index) +static u8 reg_r(struct gspca_dev *gspca_dev, + u16 index) { usb_control_msg(gspca_dev->dev, usb_rcvctrlpipe(gspca_dev->dev, 0), @@ -435,7 +391,7 @@ static int reg_r(struct gspca_dev *gspca_dev, } static void reg_w(struct gspca_dev *gspca_dev, - __u16 index) + u16 index) { usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), @@ -446,7 +402,7 @@ static void reg_w(struct gspca_dev *gspca_dev, } static void reg_w_buf(struct gspca_dev *gspca_dev, - const __u8 *buffer, __u16 len) + const u8 *buffer, u16 len) { if (len <= USB_BUF_SZ) { memcpy(gspca_dev->usb_buf, buffer, len); @@ -457,7 +413,7 @@ static void reg_w_buf(struct gspca_dev *gspca_dev, 0x01, 0, gspca_dev->usb_buf, len, 500); } else { - __u8 *tmpbuf; + u8 *tmpbuf; tmpbuf = kmalloc(len, GFP_KERNEL); memcpy(tmpbuf, buffer, len); @@ -471,14 +427,41 @@ static void reg_w_buf(struct gspca_dev *gspca_dev, } } +/* write values to consecutive registers */ +static void reg_w_ixbuf(struct gspca_dev *gspca_dev, + u8 reg, + const u8 *buffer, u16 len) +{ + int i; + u8 *p, *tmpbuf; + + if (len * 2 <= USB_BUF_SZ) + p = tmpbuf = gspca_dev->usb_buf; + else + p = tmpbuf = kmalloc(len * 2, GFP_KERNEL); + i = len; + while (--i >= 0) { + *p++ = reg++; + *p++ = *buffer++; + } + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), + 0, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0x01, 0, + tmpbuf, len * 2, 500); + if (len * 2 > USB_BUF_SZ) + kfree(tmpbuf); +} + /* Reported as OM6802*/ static void om6802_sensor_init(struct gspca_dev *gspca_dev) { int i; - const __u8 *p; - __u8 byte; - __u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05}; - static const __u8 sensor_init[] = { + const u8 *p; + u8 byte; + u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05}; + static const u8 sensor_init[] = { 0xdf, 0x6d, 0xdd, 0x18, 0x5a, 0xe0, @@ -542,15 +525,16 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = vga_mode_t16; cam->nmodes = ARRAY_SIZE(vga_mode_t16); - sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; - sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; - sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; + sd->brightness = BRIGHTNESS_DEF; + sd->contrast = CONTRAST_DEF; + sd->colors = COLORS_DEF; sd->gamma = GAMMA_DEF; - sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value; - sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value; - sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value; - sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value; - sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value; + sd->autogain = AUTOGAIN_DEF; + sd->mirror = MIRROR_DEF; + sd->freq = FREQ_DEF; + sd->whitebalance = WHITE_BALANCE_DEF; + sd->sharpness = SHARPNESS_DEF; + sd->effect = EFFECTS_DEF; return 0; } @@ -558,7 +542,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; unsigned int brightness; - __u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 }; + u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 }; brightness = sd->brightness; if (brightness < 7) { @@ -575,7 +559,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; unsigned int contrast = sd->contrast; - __u16 reg_to_write; + u16 reg_to_write; if (contrast < 7) reg_to_write = 0x8ea9 - contrast * 0x200; @@ -588,7 +572,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - __u16 reg_to_write; + u16 reg_to_write; reg_to_write = 0x80bb + sd->colors * 0x100; /* was 0xc0 */ reg_w(gspca_dev, reg_to_write); @@ -599,14 +583,15 @@ static void setgamma(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; PDEBUG(D_CONF, "Gamma: %d", sd->gamma); - reg_w_buf(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]); + reg_w_ixbuf(gspca_dev, 0x90, + gamma_table[sd->gamma], sizeof gamma_table[0]); } static void setwhitebalance(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - __u8 white_balance[8] = + u8 white_balance[8] = {0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38}; if (sd->whitebalance) @@ -618,7 +603,7 @@ static void setwhitebalance(struct gspca_dev *gspca_dev) static void setsharpness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - __u16 reg_to_write; + u16 reg_to_write; reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness; @@ -634,18 +619,18 @@ static int sd_init(struct gspca_dev *gspca_dev) * to see the initial parameters.*/ struct sd *sd = (struct sd *) gspca_dev; int i; - __u8 byte, test_byte; + u8 byte, test_byte; - static const __u8 read_indexs[] = + static const u8 read_indexs[] = { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5, - 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 }; - static const __u8 n1[] = + 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 }; + static const u8 n1[] = {0x08, 0x03, 0x09, 0x03, 0x12, 0x04}; - static const __u8 n2[] = + static const u8 n2[] = {0x08, 0x00}; - static const __u8 n3[] = + static const u8 n3[] = {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04}; - static const __u8 n4[] = + static const u8 n4[] = {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c, 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68, 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1, @@ -655,10 +640,10 @@ static int sd_init(struct gspca_dev *gspca_dev) 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68, 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40, 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46}; - static const __u8 nset9[4] = - { 0x0b, 0x04, 0x0a, 0x78 }; - static const __u8 nset8[6] = + static const u8 nset8[6] = { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 }; + static const u8 nset9[4] = + { 0x0b, 0x04, 0x0a, 0x78 }; byte = reg_r(gspca_dev, 0x06); test_byte = reg_r(gspca_dev, 0x07); @@ -703,11 +688,11 @@ static int sd_init(struct gspca_dev *gspca_dev) reg_r(gspca_dev, 0x0080); reg_w(gspca_dev, 0x2c80); - reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1, + reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1, sizeof sensor_data[sd->sensor].data1); - reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3, - sizeof sensor_data[sd->sensor].data3); - reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2, + reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2, + sizeof sensor_data[sd->sensor].data2); + reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2, sizeof sensor_data[sd->sensor].data2); reg_w(gspca_dev, 0x3880); @@ -734,11 +719,11 @@ static int sd_init(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x2880); - reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1, + reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1, sizeof sensor_data[sd->sensor].data1); - reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3, - sizeof sensor_data[sd->sensor].data3); - reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2, + reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2, + sizeof sensor_data[sd->sensor].data2); + reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2, sizeof sensor_data[sd->sensor].data2); return 0; @@ -747,7 +732,7 @@ static int sd_init(struct gspca_dev *gspca_dev) static void setflip(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - __u8 flipcmd[8] = + u8 flipcmd[8] = {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}; if (sd->mirror) @@ -777,7 +762,7 @@ static void seteffect(struct gspca_dev *gspca_dev) static void setlightfreq(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 }; + u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 }; if (sd->freq == 2) /* 60hz */ freq[1] = 0x00; @@ -790,17 +775,17 @@ static void setlightfreq(struct gspca_dev *gspca_dev) static void poll_sensor(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - static const __u8 poll1[] = + static const u8 poll1[] = {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82, 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34, 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01, 0x60, 0x14}; - static const __u8 poll2[] = + static const u8 poll2[] = {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9, 0x73, 0x02, 0x73, 0x02, 0x60, 0x14}; - static const __u8 poll3[] = + static const u8 poll3[] = {0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d}; - static const __u8 poll4[] = + static const u8 poll4[] = {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f, 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c, 0xc2, 0x80, 0xc3, 0x10}; @@ -818,13 +803,14 @@ static int sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int i, mode; - __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 }; - static const __u8 t3[] = - { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06, - 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 }; + u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 }; + static const u8 t3[] = + { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 }; mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv; switch (mode) { + case 0: /* 640x480 (0x00) */ + break; case 1: /* 352x288 */ t2[1] = 0x40; break; @@ -834,11 +820,10 @@ static int sd_start(struct gspca_dev *gspca_dev) case 3: /* 176x144 */ t2[1] = 0x50; break; - case 4: /* 160x120 */ + default: +/* case 4: * 160x120 */ t2[1] = 0x20; break; - default: /* 640x480 (0x00) */ - break; } if (sd->sensor == SENSOR_TAS5130A) { @@ -860,7 +845,7 @@ static int sd_start(struct gspca_dev *gspca_dev) sizeof sensor_data[sd->sensor].data4); reg_r(gspca_dev, 0x0012); reg_w_buf(gspca_dev, t2, sizeof t2); - reg_w_buf(gspca_dev, t3, sizeof t3); + reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3); reg_w(gspca_dev, 0x0013); msleep(15); reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream, @@ -894,10 +879,10 @@ 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 */ { - static __u8 ffd9[] = { 0xff, 0xd9 }; + static u8 ffd9[] = { 0xff, 0xd9 }; if (data[0] == 0x5a) { /* Control Packet, after this came the header again, -- cgit v1.2.3 From 3a14d6c633bf72b65fddd71938bd39f2cf646863 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 22 Jan 2009 12:25:16 +0100 Subject: gspca - t613: New unknown sensor added. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/t613.c | 178 ++++++++++++++++++++++----------- 1 file changed, 120 insertions(+), 58 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/t613.c b/linux/drivers/media/video/gspca/t613.c index d2a5aea12..798a75e8e 100644 --- a/linux/drivers/media/video/gspca/t613.c +++ b/linux/drivers/media/video/gspca/t613.c @@ -49,8 +49,9 @@ struct sd { u8 effect; u8 sensor; -#define SENSOR_TAS5130A 0 -#define SENSOR_OM6802 1 +#define SENSOR_OM6802 0 +#define SENSOR_OTHER 1 +#define SENSOR_TAS5130A 2 }; /* V4L2 controls supported by the driver */ @@ -272,6 +273,34 @@ struct additional_sensor_data { }; const static struct additional_sensor_data sensor_data[] = { + { /* OM6802 */ + .data1 = + {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06, + 0xb3, 0xfc}, + .data2 = + {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff, + 0xff}, + .data4 = /*Freq (50/60Hz). Splitted for test purpose */ + {0x66, 0xca, 0xa8, 0xf0}, + .data5 = /* this could be removed later */ + {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23}, + .stream = + {0x0b, 0x04, 0x0a, 0x78}, + }, + { /* OTHER */ + .data1 = + {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a, + 0xe8, 0xfc}, + .data2 = + {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96, + 0xd9}, + .data4 = + {0x66, 0x00, 0xa8, 0xa8}, + .data5 = + {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69}, + .stream = + {0x0b, 0x04, 0x0a, 0x00}, + }, { /* TAS5130A */ .data1 = {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27, @@ -286,20 +315,6 @@ const static struct additional_sensor_data sensor_data[] = { .stream = {0x0b, 0x04, 0x0a, 0x40}, }, - { /* OM6802 */ - .data1 = - {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06, - 0xb3, 0xfc}, - .data2 = - {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff, - 0xff}, - .data4 = /*Freq (50/60Hz). Splitted for test purpose */ - {0x66, 0xca, 0xa8, 0xf0 }, - .data5 = /* this could be removed later */ - {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23}, - .stream = - {0x0b, 0x04, 0x0a, 0x78}, - } }; #define MAX_EFFECTS 7 @@ -619,7 +634,9 @@ static int sd_init(struct gspca_dev *gspca_dev) * to see the initial parameters.*/ struct sd *sd = (struct sd *) gspca_dev; int i; - u8 byte, test_byte; + u16 sensor_id; + u8 test_byte; + u16 reg80, reg8e; static const u8 read_indexs[] = { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5, @@ -628,8 +645,10 @@ static int sd_init(struct gspca_dev *gspca_dev) {0x08, 0x03, 0x09, 0x03, 0x12, 0x04}; static const u8 n2[] = {0x08, 0x00}; - static const u8 n3[] = + static const u8 n3[6] = {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04}; + static const u8 n3_other[6] = + {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00}; static const u8 n4[] = {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c, 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68, @@ -640,40 +659,61 @@ static int sd_init(struct gspca_dev *gspca_dev) 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68, 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40, 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46}; + static const u8 n4_other[] = + {0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69, + 0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68, + 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8, + 0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8, + 0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56, + 0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5, + 0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0, + 0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00}; static const u8 nset8[6] = { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 }; + static const u8 nset8_other[6] = + { 0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00 }; static const u8 nset9[4] = { 0x0b, 0x04, 0x0a, 0x78 }; + static const u8 nset9_other[4] = + { 0x0b, 0x04, 0x0a, 0x00 }; - byte = reg_r(gspca_dev, 0x06); - test_byte = reg_r(gspca_dev, 0x07); - if (byte == 0x08 && test_byte == 0x07) { - PDEBUG(D_CONF, "sensor om6802"); - sd->sensor = SENSOR_OM6802; - } else if (byte == 0x08 && test_byte == 0x01) { + sensor_id = (reg_r(gspca_dev, 0x06) << 8) + | reg_r(gspca_dev, 0x07); + switch (sensor_id) { + case 0x0801: PDEBUG(D_CONF, "sensor tas5130a"); sd->sensor = SENSOR_TAS5130A; - } else { - PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte); - sd->sensor = SENSOR_TAS5130A; + break; + case 0x0803: + PDEBUG(D_CONF, "sensor om6802"); + sd->sensor = SENSOR_OTHER; + break; + case 0x0807: + PDEBUG(D_CONF, "sensor om6802"); + sd->sensor = SENSOR_OM6802; + break; + default: + PDEBUG(D_CONF, "unknown sensor %04x", sensor_id); + return -1; } - reg_w_buf(gspca_dev, n1, sizeof n1); - test_byte = 0; - i = 5; - while (--i >= 0) { - reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset); - test_byte = reg_r(gspca_dev, 0x0063); - msleep(100); - if (test_byte == 0x17) - break; /* OK */ - } - if (i < 0) { - err("Bad sensor reset %02x", test_byte); -/* return -EIO; */ + if (sd->sensor != SENSOR_OTHER) { + reg_w_buf(gspca_dev, n1, sizeof n1); + i = 5; + while (--i >= 0) { + reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset); + test_byte = reg_r(gspca_dev, 0x0063); + msleep(100); + if (test_byte == 0x17) + break; /* OK */ + } + if (i < 0) { + err("Bad sensor reset %02x", test_byte); +/* return -EIO; */ /*fixme: test - continue */ + } + reg_w_buf(gspca_dev, n2, sizeof n2); } - reg_w_buf(gspca_dev, n2, sizeof n2); i = 0; while (read_indexs[i] != 0x00) { @@ -683,10 +723,20 @@ static int sd_init(struct gspca_dev *gspca_dev) i++; } - reg_w_buf(gspca_dev, n3, sizeof n3); - reg_w_buf(gspca_dev, n4, sizeof n4); - reg_r(gspca_dev, 0x0080); - reg_w(gspca_dev, 0x2c80); + if (sd->sensor != SENSOR_OTHER) { + reg_w_buf(gspca_dev, n3, sizeof n3); + reg_w_buf(gspca_dev, n4, sizeof n4); + reg_r(gspca_dev, 0x0080); + reg_w(gspca_dev, 0x2c80); + reg80 = 0x3880; + reg8e = 0x338e; + } else { + reg_w_buf(gspca_dev, n3_other, sizeof n3_other); + reg_w_buf(gspca_dev, n4_other, sizeof n4_other); + sd->gamma = 5; + reg80 = 0xac80; + reg8e = 0xb88e; + } reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1, sizeof sensor_data[sd->sensor].data1); @@ -695,9 +745,9 @@ static int sd_init(struct gspca_dev *gspca_dev) reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2, sizeof sensor_data[sd->sensor].data2); - reg_w(gspca_dev, 0x3880); - reg_w(gspca_dev, 0x3880); - reg_w(gspca_dev, 0x338e); + reg_w(gspca_dev, reg80); + reg_w(gspca_dev, reg80); + reg_w(gspca_dev, reg8e); setbrightness(gspca_dev); setcontrast(gspca_dev); @@ -714,10 +764,14 @@ static int sd_init(struct gspca_dev *gspca_dev) sizeof sensor_data[sd->sensor].data4); reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5, sizeof sensor_data[sd->sensor].data5); - reg_w_buf(gspca_dev, nset8, sizeof nset8); - reg_w_buf(gspca_dev, nset9, sizeof nset9); - - reg_w(gspca_dev, 0x2880); + if (sd->sensor != SENSOR_OTHER) { + reg_w_buf(gspca_dev, nset8, sizeof nset8); + reg_w_buf(gspca_dev, nset9, sizeof nset9); + reg_w(gspca_dev, 0x2880); + } else { + reg_w_buf(gspca_dev, nset8_other, sizeof nset8_other); + reg_w_buf(gspca_dev, nset9_other, sizeof nset9_other); + } reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1, sizeof sensor_data[sd->sensor].data1); @@ -790,7 +844,7 @@ static void poll_sensor(struct gspca_dev *gspca_dev) 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c, 0xc2, 0x80, 0xc3, 0x10}; - if (sd->sensor != SENSOR_TAS5130A) { + if (sd->sensor == SENSOR_OM6802) { PDEBUG(D_STREAM, "[Sensor requires polling]"); reg_w_buf(gspca_dev, poll1, sizeof poll1); reg_w_buf(gspca_dev, poll2, sizeof poll2); @@ -826,7 +880,14 @@ static int sd_start(struct gspca_dev *gspca_dev) break; } - if (sd->sensor == SENSOR_TAS5130A) { + switch (sd->sensor) { + case SENSOR_OM6802: + om6802_sensor_init(gspca_dev); + break; + case SENSOR_OTHER: + break; + default: +/* case SENSOR_TAS5130A: */ i = 0; while (tas5130a_sensor_init[i][0] != 0) { reg_w_buf(gspca_dev, tas5130a_sensor_init[i], @@ -838,8 +899,7 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w_buf(gspca_dev, tas5130a_sensor_init[3], sizeof tas5130a_sensor_init[0]); reg_w(gspca_dev, 0x3c80); - } else { - om6802_sensor_init(gspca_dev); + break; } reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4, sizeof sensor_data[sd->sensor].data4); @@ -873,8 +933,10 @@ static void sd_stopN(struct gspca_dev *gspca_dev) msleep(20); reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream, sizeof sensor_data[sd->sensor].stream); - msleep(20); - reg_w(gspca_dev, 0x0309); + if (sd->sensor != SENSOR_OTHER) { + msleep(20); + reg_w(gspca_dev, 0x0309); + } } static void sd_pkt_scan(struct gspca_dev *gspca_dev, -- cgit v1.2.3 From b6e6f2807f9efd8215629375465ce34edafd8fdf Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 22 Jan 2009 16:53:56 +0100 Subject: gspca - t613: Bad returned value when no known sensor found. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/t613.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/t613.c b/linux/drivers/media/video/gspca/t613.c index 798a75e8e..9c777381a 100644 --- a/linux/drivers/media/video/gspca/t613.c +++ b/linux/drivers/media/video/gspca/t613.c @@ -694,7 +694,7 @@ static int sd_init(struct gspca_dev *gspca_dev) break; default: PDEBUG(D_CONF, "unknown sensor %04x", sensor_id); - return -1; + return -EINVAL; } if (sd->sensor != SENSOR_OTHER) { -- cgit v1.2.3 From 2a1d27571baf1a57cad9a8bd089cf262e1e3d4c9 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 22 Jan 2009 18:56:42 +0100 Subject: gspca - spca505: Cleanup and optimize code. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/spca505.c | 498 +++++++++++++----------------- 1 file changed, 208 insertions(+), 290 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/spca505.c b/linux/drivers/media/video/gspca/spca505.c index d997cdedc..c99bf6261 100644 --- a/linux/drivers/media/video/gspca/spca505.c +++ b/linux/drivers/media/video/gspca/spca505.c @@ -31,9 +31,9 @@ MODULE_LICENSE("GPL"); struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - unsigned char brightness; + u8 brightness; - char subtype; + u8 subtype; #define IntelPCCameraPro 0 #define Nxultra 1 }; @@ -43,7 +43,6 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { -#define SD_BRIGHTNESS 0 { { .id = V4L2_CID_BRIGHTNESS, @@ -52,7 +51,8 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 255, .step = 1, - .default_value = 127, +#define BRIGHTNESS_DEF 127 + .default_value = BRIGHTNESS_DEF, }, .set = sd_setbrightness, .get = sd_getbrightness, @@ -104,296 +104,224 @@ static const struct v4l2_pix_format vga_mode[] = { /* * Data to initialize a SPCA505. Common to the CCD and external modes */ -static const __u16 spca505_init_data[][3] = { - /* line bmRequest,value,index */ - /* 1819 */ +static const u8 spca505_init_data[][3] = { + /* bmRequest,value,index */ {SPCA50X_REG_GLOBAL, SPCA50X_GMISC3_SAA7113RST, SPCA50X_GLOBAL_MISC3}, /* Sensor reset */ - /* 1822 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3}, - /* 1825 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1}, + {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3}, + {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1}, /* Block USB reset */ - /* 1828 */ {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL, - SPCA50X_GLOBAL_MISC0}, + {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL, SPCA50X_GLOBAL_MISC0}, - /* 1831 */ {0x5, 0x01, 0x10}, + {0x05, 0x01, 0x10}, /* Maybe power down some stuff */ - /* 1834 */ {0x5, 0x0f, 0x11}, + {0x05, 0x0f, 0x11}, /* Setup internal CCD ? */ - /* 1837 */ {0x6, 0x10, 0x08}, - /* 1840 */ {0x6, 0x00, 0x09}, - /* 1843 */ {0x6, 0x00, 0x0a}, - /* 1846 */ {0x6, 0x00, 0x0b}, - /* 1849 */ {0x6, 0x10, 0x0c}, - /* 1852 */ {0x6, 0x00, 0x0d}, - /* 1855 */ {0x6, 0x00, 0x0e}, - /* 1858 */ {0x6, 0x00, 0x0f}, - /* 1861 */ {0x6, 0x10, 0x10}, - /* 1864 */ {0x6, 0x02, 0x11}, - /* 1867 */ {0x6, 0x00, 0x12}, - /* 1870 */ {0x6, 0x04, 0x13}, - /* 1873 */ {0x6, 0x02, 0x14}, - /* 1876 */ {0x6, 0x8a, 0x51}, - /* 1879 */ {0x6, 0x40, 0x52}, - /* 1882 */ {0x6, 0xb6, 0x53}, - /* 1885 */ {0x6, 0x3d, 0x54}, + {0x06, 0x10, 0x08}, + {0x06, 0x00, 0x09}, + {0x06, 0x00, 0x0a}, + {0x06, 0x00, 0x0b}, + {0x06, 0x10, 0x0c}, + {0x06, 0x00, 0x0d}, + {0x06, 0x00, 0x0e}, + {0x06, 0x00, 0x0f}, + {0x06, 0x10, 0x10}, + {0x06, 0x02, 0x11}, + {0x06, 0x00, 0x12}, + {0x06, 0x04, 0x13}, + {0x06, 0x02, 0x14}, + {0x06, 0x8a, 0x51}, + {0x06, 0x40, 0x52}, + {0x06, 0xb6, 0x53}, + {0x06, 0x3d, 0x54}, {} }; /* * Data to initialize the camera using the internal CCD */ -static const __u16 spca505_open_data_ccd[][3] = { - /* line bmRequest,value,index */ +static const u8 spca505_open_data_ccd[][3] = { + /* bmRequest,value,index */ /* Internal CCD data set */ - /* 1891 */ {0x3, 0x04, 0x01}, + {0x03, 0x04, 0x01}, /* This could be a reset */ - /* 1894 */ {0x3, 0x00, 0x01}, + {0x03, 0x00, 0x01}, /* Setup compression and image registers. 0x6 and 0x7 seem to be related to H&V hold, and are resolution mode specific */ - /* 1897 */ {0x4, 0x10, 0x01}, + {0x04, 0x10, 0x01}, /* DIFF(0x50), was (0x10) */ - /* 1900 */ {0x4, 0x00, 0x04}, - /* 1903 */ {0x4, 0x00, 0x05}, - /* 1906 */ {0x4, 0x20, 0x06}, - /* 1909 */ {0x4, 0x20, 0x07}, + {0x04, 0x00, 0x04}, + {0x04, 0x00, 0x05}, + {0x04, 0x20, 0x06}, + {0x04, 0x20, 0x07}, - /* 1912 */ {0x8, 0x0a, 0x00}, + {0x08, 0x0a, 0x00}, /* DIFF (0x4a), was (0xa) */ - /* 1915 */ {0x5, 0x00, 0x10}, - /* 1918 */ {0x5, 0x00, 0x11}, - /* 1921 */ {0x5, 0x00, 0x00}, + {0x05, 0x00, 0x10}, + {0x05, 0x00, 0x11}, + {0x05, 0x00, 0x00}, /* DIFF not written */ - /* 1924 */ {0x5, 0x00, 0x01}, + {0x05, 0x00, 0x01}, /* DIFF not written */ - /* 1927 */ {0x5, 0x00, 0x02}, + {0x05, 0x00, 0x02}, /* DIFF not written */ - /* 1930 */ {0x5, 0x00, 0x03}, + {0x05, 0x00, 0x03}, /* DIFF not written */ - /* 1933 */ {0x5, 0x00, 0x04}, + {0x05, 0x00, 0x04}, /* DIFF not written */ - /* 1936 */ {0x5, 0x80, 0x05}, + {0x05, 0x80, 0x05}, /* DIFF not written */ - /* 1939 */ {0x5, 0xe0, 0x06}, + {0x05, 0xe0, 0x06}, /* DIFF not written */ - /* 1942 */ {0x5, 0x20, 0x07}, + {0x05, 0x20, 0x07}, /* DIFF not written */ - /* 1945 */ {0x5, 0xa0, 0x08}, + {0x05, 0xa0, 0x08}, /* DIFF not written */ - /* 1948 */ {0x5, 0x0, 0x12}, + {0x05, 0x0, 0x12}, /* DIFF not written */ - /* 1951 */ {0x5, 0x02, 0x0f}, + {0x05, 0x02, 0x0f}, /* DIFF not written */ - /* 1954 */ {0x5, 0x10, 0x46}, + {0x05, 0x10, 0x46}, /* DIFF not written */ - /* 1957 */ {0x5, 0x8, 0x4a}, + {0x05, 0x8, 0x4a}, /* DIFF not written */ - /* 1960 */ {0x3, 0x08, 0x03}, + {0x03, 0x08, 0x03}, /* DIFF (0x3,0x28,0x3) */ - /* 1963 */ {0x3, 0x08, 0x01}, - /* 1966 */ {0x3, 0x0c, 0x03}, + {0x03, 0x08, 0x01}, + {0x03, 0x0c, 0x03}, /* DIFF not written */ - /* 1969 */ {0x3, 0x21, 0x00}, + {0x03, 0x21, 0x00}, /* DIFF (0x39) */ /* Extra block copied from init to hopefully ensure CCD is in a sane state */ - /* 1837 */ {0x6, 0x10, 0x08}, - /* 1840 */ {0x6, 0x00, 0x09}, - /* 1843 */ {0x6, 0x00, 0x0a}, - /* 1846 */ {0x6, 0x00, 0x0b}, - /* 1849 */ {0x6, 0x10, 0x0c}, - /* 1852 */ {0x6, 0x00, 0x0d}, - /* 1855 */ {0x6, 0x00, 0x0e}, - /* 1858 */ {0x6, 0x00, 0x0f}, - /* 1861 */ {0x6, 0x10, 0x10}, - /* 1864 */ {0x6, 0x02, 0x11}, - /* 1867 */ {0x6, 0x00, 0x12}, - /* 1870 */ {0x6, 0x04, 0x13}, - /* 1873 */ {0x6, 0x02, 0x14}, - /* 1876 */ {0x6, 0x8a, 0x51}, - /* 1879 */ {0x6, 0x40, 0x52}, - /* 1882 */ {0x6, 0xb6, 0x53}, - /* 1885 */ {0x6, 0x3d, 0x54}, + {0x06, 0x10, 0x08}, + {0x06, 0x00, 0x09}, + {0x06, 0x00, 0x0a}, + {0x06, 0x00, 0x0b}, + {0x06, 0x10, 0x0c}, + {0x06, 0x00, 0x0d}, + {0x06, 0x00, 0x0e}, + {0x06, 0x00, 0x0f}, + {0x06, 0x10, 0x10}, + {0x06, 0x02, 0x11}, + {0x06, 0x00, 0x12}, + {0x06, 0x04, 0x13}, + {0x06, 0x02, 0x14}, + {0x06, 0x8a, 0x51}, + {0x06, 0x40, 0x52}, + {0x06, 0xb6, 0x53}, + {0x06, 0x3d, 0x54}, /* End of extra block */ - /* 1972 */ {0x6, 0x3f, 0x1}, + {0x06, 0x3f, 0x1}, /* Block skipped */ - /* 1975 */ {0x6, 0x10, 0x02}, - /* 1978 */ {0x6, 0x64, 0x07}, - /* 1981 */ {0x6, 0x10, 0x08}, - /* 1984 */ {0x6, 0x00, 0x09}, - /* 1987 */ {0x6, 0x00, 0x0a}, - /* 1990 */ {0x6, 0x00, 0x0b}, - /* 1993 */ {0x6, 0x10, 0x0c}, - /* 1996 */ {0x6, 0x00, 0x0d}, - /* 1999 */ {0x6, 0x00, 0x0e}, - /* 2002 */ {0x6, 0x00, 0x0f}, - /* 2005 */ {0x6, 0x10, 0x10}, - /* 2008 */ {0x6, 0x02, 0x11}, - /* 2011 */ {0x6, 0x00, 0x12}, - /* 2014 */ {0x6, 0x04, 0x13}, - /* 2017 */ {0x6, 0x02, 0x14}, - /* 2020 */ {0x6, 0x8a, 0x51}, - /* 2023 */ {0x6, 0x40, 0x52}, - /* 2026 */ {0x6, 0xb6, 0x53}, - /* 2029 */ {0x6, 0x3d, 0x54}, - /* 2032 */ {0x6, 0x60, 0x57}, - /* 2035 */ {0x6, 0x20, 0x58}, - /* 2038 */ {0x6, 0x15, 0x59}, - /* 2041 */ {0x6, 0x05, 0x5a}, - - /* 2044 */ {0x5, 0x01, 0xc0}, - /* 2047 */ {0x5, 0x10, 0xcb}, - /* 2050 */ {0x5, 0x80, 0xc1}, + {0x06, 0x10, 0x02}, + {0x06, 0x64, 0x07}, + {0x06, 0x10, 0x08}, + {0x06, 0x00, 0x09}, + {0x06, 0x00, 0x0a}, + {0x06, 0x00, 0x0b}, + {0x06, 0x10, 0x0c}, + {0x06, 0x00, 0x0d}, + {0x06, 0x00, 0x0e}, + {0x06, 0x00, 0x0f}, + {0x06, 0x10, 0x10}, + {0x06, 0x02, 0x11}, + {0x06, 0x00, 0x12}, + {0x06, 0x04, 0x13}, + {0x06, 0x02, 0x14}, + {0x06, 0x8a, 0x51}, + {0x06, 0x40, 0x52}, + {0x06, 0xb6, 0x53}, + {0x06, 0x3d, 0x54}, + {0x06, 0x60, 0x57}, + {0x06, 0x20, 0x58}, + {0x06, 0x15, 0x59}, + {0x06, 0x05, 0x5a}, + + {0x05, 0x01, 0xc0}, + {0x05, 0x10, 0xcb}, + {0x05, 0x80, 0xc1}, /* */ - /* 2053 */ {0x5, 0x0, 0xc2}, + {0x05, 0x0, 0xc2}, /* 4 was 0 */ - /* 2056 */ {0x5, 0x00, 0xca}, - /* 2059 */ {0x5, 0x80, 0xc1}, + {0x05, 0x00, 0xca}, + {0x05, 0x80, 0xc1}, /* */ - /* 2062 */ {0x5, 0x04, 0xc2}, - /* 2065 */ {0x5, 0x00, 0xca}, - /* 2068 */ {0x5, 0x0, 0xc1}, + {0x05, 0x04, 0xc2}, + {0x05, 0x00, 0xca}, + {0x05, 0x0, 0xc1}, /* */ - /* 2071 */ {0x5, 0x00, 0xc2}, - /* 2074 */ {0x5, 0x00, 0xca}, - /* 2077 */ {0x5, 0x40, 0xc1}, + {0x05, 0x00, 0xc2}, + {0x05, 0x00, 0xca}, + {0x05, 0x40, 0xc1}, /* */ - /* 2080 */ {0x5, 0x17, 0xc2}, - /* 2083 */ {0x5, 0x00, 0xca}, - /* 2086 */ {0x5, 0x80, 0xc1}, + {0x05, 0x17, 0xc2}, + {0x05, 0x00, 0xca}, + {0x05, 0x80, 0xc1}, /* */ - /* 2089 */ {0x5, 0x06, 0xc2}, - /* 2092 */ {0x5, 0x00, 0xca}, - /* 2095 */ {0x5, 0x80, 0xc1}, + {0x05, 0x06, 0xc2}, + {0x05, 0x00, 0xca}, + {0x05, 0x80, 0xc1}, /* */ - /* 2098 */ {0x5, 0x04, 0xc2}, - /* 2101 */ {0x5, 0x00, 0xca}, + {0x05, 0x04, 0xc2}, + {0x05, 0x00, 0xca}, - /* 2104 */ {0x3, 0x4c, 0x3}, - /* 2107 */ {0x3, 0x18, 0x1}, + {0x03, 0x4c, 0x3}, + {0x03, 0x18, 0x1}, - /* 2110 */ {0x6, 0x70, 0x51}, - /* 2113 */ {0x6, 0xbe, 0x53}, - /* 2116 */ {0x6, 0x71, 0x57}, - /* 2119 */ {0x6, 0x20, 0x58}, - /* 2122 */ {0x6, 0x05, 0x59}, - /* 2125 */ {0x6, 0x15, 0x5a}, + {0x06, 0x70, 0x51}, + {0x06, 0xbe, 0x53}, + {0x06, 0x71, 0x57}, + {0x06, 0x20, 0x58}, + {0x06, 0x05, 0x59}, + {0x06, 0x15, 0x5a}, - /* 2128 */ {0x4, 0x00, 0x08}, + {0x04, 0x00, 0x08}, /* Compress = OFF (0x1 to turn on) */ - /* 2131 */ {0x4, 0x12, 0x09}, - /* 2134 */ {0x4, 0x21, 0x0a}, - /* 2137 */ {0x4, 0x10, 0x0b}, - /* 2140 */ {0x4, 0x21, 0x0c}, - /* 2143 */ {0x4, 0x05, 0x00}, + {0x04, 0x12, 0x09}, + {0x04, 0x21, 0x0a}, + {0x04, 0x10, 0x0b}, + {0x04, 0x21, 0x0c}, + {0x04, 0x05, 0x00}, /* was 5 (Image Type ? ) */ - /* 2146 */ {0x4, 0x00, 0x01}, - - /* 2149 */ {0x6, 0x3f, 0x01}, - - /* 2152 */ {0x4, 0x00, 0x04}, - /* 2155 */ {0x4, 0x00, 0x05}, - /* 2158 */ {0x4, 0x40, 0x06}, - /* 2161 */ {0x4, 0x40, 0x07}, - - /* 2164 */ {0x6, 0x1c, 0x17}, - /* 2167 */ {0x6, 0xe2, 0x19}, - /* 2170 */ {0x6, 0x1c, 0x1b}, - /* 2173 */ {0x6, 0xe2, 0x1d}, - /* 2176 */ {0x6, 0xaa, 0x1f}, - /* 2179 */ {0x6, 0x70, 0x20}, - - /* 2182 */ {0x5, 0x01, 0x10}, - /* 2185 */ {0x5, 0x00, 0x11}, - /* 2188 */ {0x5, 0x01, 0x00}, - /* 2191 */ {0x5, 0x05, 0x01}, - /* 2194 */ {0x5, 0x00, 0xc1}, - /* */ - /* 2197 */ {0x5, 0x00, 0xc2}, - /* 2200 */ {0x5, 0x00, 0xca}, + {0x04, 0x00, 0x01}, - /* 2203 */ {0x6, 0x70, 0x51}, - /* 2206 */ {0x6, 0xbe, 0x53}, - {} -}; + {0x06, 0x3f, 0x01}, -#if 0 -/* - * Data to initialize the camera in external video mode - */ -static const __u16 spca505_open_data_ext[][3] = { - /* line bmRequest,value,index */ - /* External video input dataset */ - /* 0808 */ {0x3, 0x04, 0x01}, - /* 0809 */ {0x3, 0x00, 0x01}, - - /* 0810 */ {0x4, 0x50, 0x01}, - /* 0811 */ {0x4, 0x00, 0x04}, - /* 0812 */ {0x4, 0x0a, 0x05}, - /* 0813 */ {0x4, 0x20, 0x06}, - /* 0814 */ {0x4, 0x20, 0x07}, - - /* 0815 */ {0x8, 0x4a, 0x00}, - - /* 0816 */ {0x5, 0x00, 0x10}, - /* 0817 */ {0x5, 0x00, 0x11}, - - /* 0818 */ {0x3, 0x08, 0x03}, - /* 0819 */ {0x3, 0x28, 0x03}, - /* 0820 */ {0x3, 0x08, 0x01}, - /* 0821 */ {0x3, 0x39, 0x00}, - - /* 0822 */ {0x5, 0x01, 0xc0}, - /* 0823 */ {0x5, 0x10, 0xcb}, - /* 0824 */ {0x5, 0x80, 0xc1}, - /* 0825 */ {0x5, 0x05, 0xc2}, - /* 0826 */ {0x5, 0x00, 0xca}, - /* 0827 */ {0x5, 0x00, 0xc1}, - /* 0828 */ {0x5, 0x01, 0xc2}, - /* 0829 */ {0x5, 0x00, 0xca}, - /* 0830 */ {0x5, 0x01, 0x10}, - /* 0831 */ {0x5, 0x0f, 0x11}, - {} -}; + {0x04, 0x00, 0x04}, + {0x04, 0x00, 0x05}, + {0x04, 0x40, 0x06}, + {0x04, 0x40, 0x07}, -/* - * Additional data needed to initialze the camera in external mode - */ -static const __u16 spca505_open_data2[][3] = { - /* line bmRequest,value,index */ - /* 1384 */ {0x3, 0x68, 0x03}, - /* 1385 */ {0x3, 0x10, 0x01}, - /* 1386 */ {0x8, 0x4a, 0x00}, - /* 1387 */ {0x4, 0x00, 0x08}, - /* was 1 COMPRESSION ENABLE ! */ - /* 1388 */ {0x4, 0x12, 0x09}, - /* Think these are the compression registers */ - /* 1389 */ {0x4, 0x21, 0x0a}, - /* 1390 */ {0x4, 0x10, 0x0b}, - /* 1391 */ {0x4, 0x21, 0x0c}, - /* 1392 */ {0x4, 0x05, 0x00}, - /* This may be the picture type code (5=160x120 as YUV4:2:0) */ - /* 1393 */ {0x4, 0x00, 0x01}, - /* 1394 */ {0x6, 0x3f, 0x01}, - /* 1395 */ {0x4, 0x00, 0x04}, - /* 1396 */ {0x4, 0x0a, 0x05}, - /* 1397 */ {0x4, 0x40, 0x06}, - /* was 40 */ - /* 1398 */ {0x4, 0x40, 0x07}, - /* was 50 */ - /* 1399 */ {0x4, 0x02, 0x05}, - /* 1400 */ {0x4, 0x00, 0x04}, + {0x06, 0x1c, 0x17}, + {0x06, 0xe2, 0x19}, + {0x06, 0x1c, 0x1b}, + {0x06, 0xe2, 0x1d}, + {0x06, 0xaa, 0x1f}, + {0x06, 0x70, 0x20}, + + {0x05, 0x01, 0x10}, + {0x05, 0x00, 0x11}, + {0x05, 0x01, 0x00}, + {0x05, 0x05, 0x01}, + {0x05, 0x00, 0xc1}, + /* */ + {0x05, 0x00, 0xc2}, + {0x05, 0x00, 0xca}, + + {0x06, 0x70, 0x51}, + {0x06, 0xbe, 0x53}, {} }; -#endif + /* - Made by Tomasz Zablocki (skalamandra@poczta.onet.pl) + * Made by Tomasz Zablocki (skalamandra@poczta.onet.pl) * SPCA505b chip based cameras initialization data - * */ /* jfm */ #define initial_brightness 0x7f /* 0x0(white)-0xff(black) */ @@ -401,7 +329,7 @@ static const __u16 spca505_open_data2[][3] = { /* * Data to initialize a SPCA505. Common to the CCD and external modes */ -static const __u16 spca505b_init_data[][3] = { +static const u8 spca505b_init_data[][3] = { /* start */ {0x02, 0x00, 0x00}, /* init */ {0x02, 0x00, 0x01}, @@ -465,7 +393,7 @@ static const __u16 spca505b_init_data[][3] = { /* * Data to initialize the camera using the internal CCD */ -static const __u16 spca505b_open_data_ccd[][3] = { +static const u8 spca505b_open_data_ccd[][3] = { /* {0x02,0x00,0x00}, */ {0x03, 0x04, 0x01}, /* rst */ @@ -494,8 +422,8 @@ static const __u16 spca505b_open_data_ccd[][3] = { {0x05, 0x00, 0x11}, {0x05, 0x00, 0x12}, {0x05, 0x6f, 0x00}, - {0x05, initial_brightness >> 6, 0x00}, - {0x05, initial_brightness << 2, 0x01}, + {0x05, (u8) (initial_brightness >> 6), 0x00}, + {0x05, (u8) (initial_brightness << 2), 0x01}, {0x05, 0x00, 0x02}, {0x05, 0x01, 0x03}, {0x05, 0x00, 0x04}, @@ -505,7 +433,7 @@ static const __u16 spca505b_open_data_ccd[][3] = { {0x05, 0xa0, 0x08}, {0x05, 0x00, 0x12}, {0x05, 0x02, 0x0f}, - {0x05, 128, 0x14}, /* max exposure off (0=on) */ + {0x05, 0x80, 0x14}, /* max exposure off (0=on) */ {0x05, 0x01, 0xb0}, {0x05, 0x01, 0xbf}, {0x03, 0x02, 0x06}, @@ -628,27 +556,27 @@ static const __u16 spca505b_open_data_ccd[][3] = { {0x06, 0x5f, 0x1f}, {0x06, 0x32, 0x20}, - {0x05, initial_brightness >> 6, 0x00}, - {0x05, initial_brightness << 2, 0x01}, + {0x05, (u8) (initial_brightness >> 6), 0x00}, + {0x05, (u8) (initial_brightness << 2), 0x01}, {0x05, 0x06, 0xc1}, {0x05, 0x58, 0xc2}, - {0x05, 0x0, 0xca}, - {0x05, 0x0, 0x11}, + {0x05, 0x00, 0xca}, + {0x05, 0x00, 0x11}, {} }; static int reg_write(struct usb_device *dev, - __u16 reg, __u16 index, __u16 value) + u16 req, u16 index, u16 value) { int ret; ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - reg, + req, USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, NULL, 0, 500); - PDEBUG(D_PACK, "reg write: 0x%02x,0x%02x:0x%02x, 0x%x", - reg, index, value, ret); + 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; @@ -656,42 +584,34 @@ static int reg_write(struct usb_device *dev, /* returns: negative is error, pos or zero is data */ static int reg_read(struct gspca_dev *gspca_dev, - __u16 reg, /* bRequest */ - __u16 index, /* wIndex */ - __u16 length) /* wLength (1 or 2 only) */ + u16 req, /* bRequest */ + u16 index) /* wIndex */ { int ret; - gspca_dev->usb_buf[1] = 0; ret = usb_control_msg(gspca_dev->dev, usb_rcvctrlpipe(gspca_dev->dev, 0), - reg, + req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - (__u16) 0, /* value */ - (__u16) index, - gspca_dev->usb_buf, length, + 0, /* value */ + index, + gspca_dev->usb_buf, 2, 500); /* timeout */ - if (ret < 0) { - PDEBUG(D_ERR, "reg_read err %d", ret); - return -1; - } + if (ret < 0) + return ret; return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; } static int write_vector(struct gspca_dev *gspca_dev, - const __u16 data[][3]) + const u8 data[][3]) { struct usb_device *dev = gspca_dev->dev; int ret, i = 0; - while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { + while (data[i][0] != 0) { ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); - if (ret < 0) { - PDEBUG(D_ERR, - "Register write failed for 0x%x,0x%x,0x%x", - data[i][0], data[i][1], data[i][2]); + if (ret < 0) return ret; - } i++; } return 0; @@ -708,10 +628,10 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = vga_mode; sd->subtype = id->driver_info; if (sd->subtype != IntelPCCameraPro) - cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; + cam->nmodes = ARRAY_SIZE(vga_mode); else /* no 640x480 for IntelPCCameraPro */ - cam->nmodes = sizeof vga_mode / sizeof vga_mode[0] - 1; - sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + cam->nmodes = ARRAY_SIZE(vga_mode) - 1; + sd->brightness = BRIGHTNESS_DEF; if (sd->subtype == Nxultra) { if (write_vector(gspca_dev, spca505b_init_data)) @@ -729,30 +649,28 @@ static int sd_init(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int ret; - PDEBUG(D_STREAM, "Initializing SPCA505"); if (sd->subtype == Nxultra) write_vector(gspca_dev, spca505b_open_data_ccd); else write_vector(gspca_dev, spca505_open_data_ccd); - ret = reg_read(gspca_dev, 6, 0x16, 2); + ret = reg_read(gspca_dev, 0x06, 0x16); if (ret < 0) { - PDEBUG(D_ERR|D_STREAM, - "register read failed for after vector read err = %d", + PDEBUG(D_ERR|D_CONF, + "register read failed err: %d", ret); - return -EIO; + return ret; } - PDEBUG(D_STREAM, - "After vector read returns : 0x%x should be 0x0101", - ret & 0xffff); - - ret = reg_write(gspca_dev->dev, 6, 0x16, 0x0a); - if (ret < 0) { - PDEBUG(D_ERR, "register write failed for (6,0xa,0x16) err=%d", - ret); - return -EIO; + if (ret != 0x0101) { + PDEBUG(D_ERR|D_CONF, + "After vector read returns 0x%04x should be 0x0101", + ret); } - reg_write(gspca_dev->dev, 5, 0xc2, 18); + + ret = reg_write(gspca_dev->dev, 0x06, 0x16, 0x0a); + if (ret < 0) + return ret; + reg_write(gspca_dev->dev, 0x05, 0xc2, 18); return 0; } @@ -818,15 +736,15 @@ static void sd_stop0(struct gspca_dev *gspca_dev) /* This maybe reset or power control */ reg_write(gspca_dev->dev, 0x03, 0x03, 0x20); - reg_write(gspca_dev->dev, 0x03, 0x01, 0x0); - reg_write(gspca_dev->dev, 0x03, 0x00, 0x1); - reg_write(gspca_dev->dev, 0x05, 0x10, 0x1); - reg_write(gspca_dev->dev, 0x05, 0x11, 0xf); + reg_write(gspca_dev->dev, 0x03, 0x01, 0x00); + reg_write(gspca_dev->dev, 0x03, 0x00, 0x01); + reg_write(gspca_dev->dev, 0x05, 0x10, 0x01); + reg_write(gspca_dev->dev, 0x05, 0x11, 0x0f); } 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]) { @@ -839,7 +757,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, data, len); break; case 0xff: /* drop */ -/* gspca_dev->last_packet_type = DISCARD_PACKET; */ break; default: data += 1; @@ -853,10 +770,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + u8 brightness = sd->brightness; - __u8 brightness = sd->brightness; - reg_write(gspca_dev->dev, 5, 0x00, (255 - brightness) >> 6); - reg_write(gspca_dev->dev, 5, 0x01, (255 - brightness) << 2); + reg_write(gspca_dev->dev, 0x05, 0x00, (255 - brightness) >> 6); + reg_write(gspca_dev->dev, 0x05, 0x01, (255 - brightness) << 2); } @@ -923,6 +840,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 From 97bfa7bcab320242823e8d3c6933b691c82a8be9 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Fri, 23 Jan 2009 17:11:14 +0200 Subject: af9015: remove dual_mode module param From: Antti Palosaari Remove dual_mode module param. Possible 2nd FE seems not to be buggy any more and therefore can be enabled as default. Priority: normal Signed-off-by: Antti Palosaari --- linux/drivers/media/dvb/dvb-usb/af9015.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.c b/linux/drivers/media/dvb/dvb-usb/af9015.c index b1f231781..5d4f070c3 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.c +++ b/linux/drivers/media/dvb/dvb-usb/af9015.c @@ -37,9 +37,6 @@ MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); static int dvb_usb_af9015_remote; module_param_named(remote, dvb_usb_af9015_remote, int, 0644); MODULE_PARM_DESC(remote, "select remote"); -static int dvb_usb_af9015_dual_mode; -module_param_named(dual_mode, dvb_usb_af9015_dual_mode, int, 0644); -MODULE_PARM_DESC(dual_mode, "enable dual mode"); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); static DEFINE_MUTEX(af9015_usb_mutex); @@ -839,9 +836,6 @@ static int af9015_read_config(struct usb_device *udev) goto error; af9015_config.dual_mode = val; deb_info("%s: TS mode:%d\n", __func__, af9015_config.dual_mode); - /* disable dual mode by default because it is buggy */ - if (!dvb_usb_af9015_dual_mode) - af9015_config.dual_mode = 0; /* Set adapter0 buffer size according to USB port speed, adapter1 buffer size can be static because it is enabled only USB2.0 */ -- cgit v1.2.3 From 4de91ec44b5304ed77f6f65118680f0e70b83c9d Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 23 Jan 2009 18:42:03 +0100 Subject: gspca - spca505: Simplify and add the brightness in start. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/spca505.c | 81 +++++++++++++------------------ 1 file changed, 34 insertions(+), 47 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/spca505.c b/linux/drivers/media/video/gspca/spca505.c index c99bf6261..b9139b1ed 100644 --- a/linux/drivers/media/video/gspca/spca505.c +++ b/linux/drivers/media/video/gspca/spca505.c @@ -64,12 +64,12 @@ static const struct v4l2_pix_format vga_mode[] = { .bytesperline = 160, .sizeimage = 160 * 120 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 5}, + .priv = 4}, {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, .bytesperline = 176, .sizeimage = 176 * 144 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 4}, + .priv = 3}, {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, .bytesperline = 320, .sizeimage = 320 * 240 * 3 / 2, @@ -93,6 +93,7 @@ static const struct v4l2_pix_format vga_mode[] = { #define SPCA50X_USB_CTRL 0x00 /* spca505 */ #define SPCA50X_CUSB_ENABLE 0x01 /* spca505 */ + #define SPCA50X_REG_GLOBAL 0x03 /* spca505 */ #define SPCA50X_GMISC0_IDSEL 0x01 /* Global control device ID select spca505 */ #define SPCA50X_GLOBAL_MISC0 0x00 /* Global control miscellaneous 0 spca505 */ @@ -101,6 +102,9 @@ static const struct v4l2_pix_format vga_mode[] = { #define SPCA50X_GLOBAL_MISC3 0x03 /* 505 */ #define SPCA50X_GMISC3_SAA7113RST 0x20 /* Not sure about this one spca505 */ +/* Image format and compression control */ +#define SPCA50X_REG_COMPRESS 0x04 + /* * Data to initialize a SPCA505. Common to the CCD and external modes */ @@ -670,55 +674,48 @@ static int sd_init(struct gspca_dev *gspca_dev) ret = reg_write(gspca_dev->dev, 0x06, 0x16, 0x0a); if (ret < 0) return ret; - reg_write(gspca_dev->dev, 0x05, 0xc2, 18); + reg_write(gspca_dev->dev, 0x05, 0xc2, 0x12); return 0; } +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + u8 brightness = sd->brightness; + + reg_write(gspca_dev->dev, 0x05, 0x00, (255 - brightness) >> 6); + reg_write(gspca_dev->dev, 0x05, 0x01, (255 - brightness) << 2); +} + static int sd_start(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; - int ret; + int ret, mode; + static u8 mode_tb[][3] = { + /* r00 r06 r07 */ + {0x00, 0x10, 0x10}, /* 640x480 */ + {0x01, 0x1a, 0x1a}, /* 352x288 */ + {0x02, 0x1c, 0x1d}, /* 320x240 */ + {0x04, 0x34, 0x34}, /* 176x144 */ + {0x05, 0x40, 0x40} /* 160x120 */ + }; /* necessary because without it we can see stream * only once after loading module */ /* stopping usb registers Tomasz change */ - reg_write(dev, 0x02, 0x0, 0x0); - switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { - case 0: - reg_write(dev, 0x04, 0x00, 0x00); - reg_write(dev, 0x04, 0x06, 0x10); - reg_write(dev, 0x04, 0x07, 0x10); - break; - case 1: - reg_write(dev, 0x04, 0x00, 0x01); - reg_write(dev, 0x04, 0x06, 0x1a); - reg_write(dev, 0x04, 0x07, 0x1a); - break; - case 2: - reg_write(dev, 0x04, 0x00, 0x02); - reg_write(dev, 0x04, 0x06, 0x1c); - reg_write(dev, 0x04, 0x07, 0x1d); - break; - case 4: - reg_write(dev, 0x04, 0x00, 0x04); - reg_write(dev, 0x04, 0x06, 0x34); - reg_write(dev, 0x04, 0x07, 0x34); - break; - default: -/* case 5: */ - reg_write(dev, 0x04, 0x00, 0x05); - reg_write(dev, 0x04, 0x06, 0x40); - reg_write(dev, 0x04, 0x07, 0x40); - break; - } -/* Enable ISO packet machine - should we do this here or in ISOC init ? */ + reg_write(dev, 0x02, 0x00, 0x00); + + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; + reg_write(dev, SPCA50X_REG_COMPRESS, 0x00, mode_tb[mode][0]); + reg_write(dev, SPCA50X_REG_COMPRESS, 0x06, mode_tb[mode][1]); + reg_write(dev, SPCA50X_REG_COMPRESS, 0x07, mode_tb[mode][2]); + ret = reg_write(dev, SPCA50X_REG_USB, SPCA50X_USB_CTRL, SPCA50X_CUSB_ENABLE); -/* reg_write(dev, 0x5, 0x0, 0x0); */ -/* reg_write(dev, 0x5, 0x0, 0x1); */ -/* reg_write(dev, 0x5, 0x11, 0x2); */ + setbrightness(gspca_dev); + return ret; } @@ -767,16 +764,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, } } -static void setbrightness(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 brightness = sd->brightness; - - reg_write(gspca_dev->dev, 0x05, 0x00, (255 - brightness) >> 6); - reg_write(gspca_dev->dev, 0x05, 0x01, (255 - brightness) << 2); - -} - static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; -- cgit v1.2.3 From fd237d0264b616b7a22369b14e56952e2bc306c5 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Fri, 23 Jan 2009 13:28:10 -0500 Subject: sms1xxx: add missing usb id 2040:2011 From: Michael Krufky Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/siano/sms-cards.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/dvb/siano/sms-cards.c b/linux/drivers/media/dvb/siano/sms-cards.c index 4307e4e8a..79f5715c0 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.c +++ b/linux/drivers/media/dvb/siano/sms-cards.c @@ -46,6 +46,8 @@ struct usb_device_id smsusb_id_table[] = { .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, { USB_DEVICE(0x2040, 0x2010), .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, + { USB_DEVICE(0x2040, 0x2011), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, { USB_DEVICE(0x2040, 0x2019), .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, { USB_DEVICE(0x2040, 0x5500), -- cgit v1.2.3 From 3b3a0da046f354c968c609f25969e0acbf01ce93 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sat, 24 Jan 2009 00:23:23 +0200 Subject: af9015: New remote RM-KS for Avermedia Volar-X From: Jose Alberto Reguero The new Avermedia Volar-X is shipped with a new remote(RM-KS). The attached patch add a new option to the remote parameter of dvb_usb_af9015 for this remote. Priority: normal Signed-off-by: Felipe Morales Moreno Signed-off-by: Jose Alberto Reguero Signed-off-by: Antti Palosaari --- linux/drivers/media/dvb/dvb-usb/af9015.c | 10 ++++++++++ linux/drivers/media/dvb/dvb-usb/af9015.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.c b/linux/drivers/media/dvb/dvb-usb/af9015.c index 5d4f070c3..e518d47fe 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.c +++ b/linux/drivers/media/dvb/dvb-usb/af9015.c @@ -748,6 +748,16 @@ static int af9015_read_config(struct usb_device *udev) af9015_config.ir_table_size = ARRAY_SIZE(af9015_ir_table_digittrade); break; + case AF9015_REMOTE_AVERMEDIA_KS: + af9015_properties[i].rc_key_map = + af9015_rc_keys_avermedia; + af9015_properties[i].rc_key_map_size = + ARRAY_SIZE(af9015_rc_keys_avermedia); + af9015_config.ir_table = + af9015_ir_table_avermedia_ks; + af9015_config.ir_table_size = + ARRAY_SIZE(af9015_ir_table_avermedia_ks); + break; } } else { switch (le16_to_cpu(udev->descriptor.idVendor)) { diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.h b/linux/drivers/media/dvb/dvb-usb/af9015.h index 21c7782f4..00e257146 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.h +++ b/linux/drivers/media/dvb/dvb-usb/af9015.h @@ -124,6 +124,7 @@ enum af9015_remote { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, AF9015_REMOTE_MYGICTV_U718, AF9015_REMOTE_DIGITTRADE_DVB_T, + AF9015_REMOTE_AVERMEDIA_KS, }; /* Leadtek WinFast DTV Dongle Gold */ @@ -597,6 +598,36 @@ static u8 af9015_ir_table_avermedia[] = { 0x03, 0xfc, 0x03, 0xfc, 0x0e, 0x05, 0x00, }; +static u8 af9015_ir_table_avermedia_ks[] = { + 0x05, 0xfa, 0x01, 0xfe, 0x12, 0x05, 0x00, + 0x05, 0xfa, 0x02, 0xfd, 0x0e, 0x05, 0x00, + 0x05, 0xfa, 0x03, 0xfc, 0x0d, 0x05, 0x00, + 0x05, 0xfa, 0x04, 0xfb, 0x2e, 0x05, 0x00, + 0x05, 0xfa, 0x05, 0xfa, 0x2d, 0x05, 0x00, + 0x05, 0xfa, 0x06, 0xf9, 0x10, 0x05, 0x00, + 0x05, 0xfa, 0x07, 0xf8, 0x0f, 0x05, 0x00, + 0x05, 0xfa, 0x08, 0xf7, 0x3d, 0x05, 0x00, + 0x05, 0xfa, 0x09, 0xf6, 0x1e, 0x05, 0x00, + 0x05, 0xfa, 0x0a, 0xf5, 0x1f, 0x05, 0x00, + 0x05, 0xfa, 0x0b, 0xf4, 0x20, 0x05, 0x00, + 0x05, 0xfa, 0x0c, 0xf3, 0x21, 0x05, 0x00, + 0x05, 0xfa, 0x0d, 0xf2, 0x22, 0x05, 0x00, + 0x05, 0xfa, 0x0e, 0xf1, 0x23, 0x05, 0x00, + 0x05, 0xfa, 0x0f, 0xf0, 0x24, 0x05, 0x00, + 0x05, 0xfa, 0x10, 0xef, 0x25, 0x05, 0x00, + 0x05, 0xfa, 0x11, 0xee, 0x26, 0x05, 0x00, + 0x05, 0xfa, 0x12, 0xed, 0x27, 0x05, 0x00, + 0x05, 0xfa, 0x13, 0xec, 0x04, 0x05, 0x00, + 0x05, 0xfa, 0x15, 0xea, 0x0a, 0x05, 0x00, + 0x05, 0xfa, 0x16, 0xe9, 0x11, 0x05, 0x00, + 0x05, 0xfa, 0x17, 0xe8, 0x15, 0x05, 0x00, + 0x05, 0xfa, 0x18, 0xe7, 0x16, 0x05, 0x00, + 0x05, 0xfa, 0x1c, 0xe3, 0x05, 0x05, 0x00, + 0x05, 0xfa, 0x1d, 0xe2, 0x09, 0x05, 0x00, + 0x05, 0xfa, 0x4d, 0xb2, 0x3f, 0x05, 0x00, + 0x05, 0xfa, 0x56, 0xa9, 0x3e, 0x05, 0x00 +}; + /* Digittrade DVB-T USB Stick */ static struct dvb_usb_rc_key af9015_rc_keys_digittrade[] = { { 0x01, 0x0f, KEY_LAST }, /* RETURN */ -- cgit v1.2.3 From 5c23c4c25b7a5368c45f7ee2c0c5dedaf6af346a Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 24 Jan 2009 11:45:14 +0100 Subject: gspca - main: Fix memory leak when USB disconnection while streaming. From: Jean-Francois Moine Resetting the streaming flag on disconnection prevented the URBs to be freed when streaming was active. Also, USBs cannot be killed after disconnection (oops in [usbcore] unlink1). Priority: high Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/gspca.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index c3ea5339c..4756175e4 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -434,7 +434,8 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) break; gspca_dev->urb[i] = NULL; - usb_kill_urb(urb); + if (!gspca_dev->present) + usb_kill_urb(urb); if (urb->transfer_buffer != NULL) usb_buffer_free(gspca_dev->dev, urb->transfer_buffer_length, @@ -1952,7 +1953,6 @@ void gspca_disconnect(struct usb_interface *intf) struct gspca_dev *gspca_dev = usb_get_intfdata(intf); gspca_dev->present = 0; - gspca_dev->streaming = 0; usb_set_intfdata(intf, NULL); -- cgit v1.2.3 From 4f88214011b62804c9a7ddb4de27f4a9c798cbea Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 24 Jan 2009 19:42:50 +0100 Subject: gspca - spca505: Move some sequences from probe to streamon. From: Jean-Francois Moine The webcams worked only one time after connection. Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/spca505.c | 49 +++++++++++++++---------------- 1 file changed, 24 insertions(+), 25 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/spca505.c b/linux/drivers/media/video/gspca/spca505.c index b9139b1ed..4fc54d8b8 100644 --- a/linux/drivers/media/video/gspca/spca505.c +++ b/linux/drivers/media/video/gspca/spca505.c @@ -650,31 +650,6 @@ 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) { - struct sd *sd = (struct sd *) gspca_dev; - int ret; - - if (sd->subtype == Nxultra) - write_vector(gspca_dev, spca505b_open_data_ccd); - else - write_vector(gspca_dev, spca505_open_data_ccd); - ret = reg_read(gspca_dev, 0x06, 0x16); - - if (ret < 0) { - PDEBUG(D_ERR|D_CONF, - "register read failed err: %d", - ret); - return ret; - } - if (ret != 0x0101) { - PDEBUG(D_ERR|D_CONF, - "After vector read returns 0x%04x should be 0x0101", - ret); - } - - ret = reg_write(gspca_dev->dev, 0x06, 0x16, 0x0a); - if (ret < 0) - return ret; - reg_write(gspca_dev->dev, 0x05, 0xc2, 0x12); return 0; } @@ -689,6 +664,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) static int sd_start(struct gspca_dev *gspca_dev) { + struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; int ret, mode; static u8 mode_tb[][3] = { @@ -700,6 +676,29 @@ static int sd_start(struct gspca_dev *gspca_dev) {0x05, 0x40, 0x40} /* 160x120 */ }; + if (sd->subtype == Nxultra) + write_vector(gspca_dev, spca505b_open_data_ccd); + else + write_vector(gspca_dev, spca505_open_data_ccd); + ret = reg_read(gspca_dev, 0x06, 0x16); + + if (ret < 0) { + PDEBUG(D_ERR|D_CONF, + "register read failed err: %d", + ret); + return ret; + } + if (ret != 0x0101) { + PDEBUG(D_ERR|D_CONF, + "After vector read returns 0x%04x should be 0x0101", + ret); + } + + ret = reg_write(gspca_dev->dev, 0x06, 0x16, 0x0a); + if (ret < 0) + return ret; + reg_write(gspca_dev->dev, 0x05, 0xc2, 0x12); + /* necessary because without it we can see stream * only once after loading module */ /* stopping usb registers Tomasz change */ -- cgit v1.2.3 From f3b075290eb618e3d7ff24aabb83c0c3b95ac5ea Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 25 Jan 2009 13:53:09 -0200 Subject: em28xx: Correct mailing list From: Alexey Klimov Move development mail-list to linux-media on vger.kernel.org. Priority: normal Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/video/em28xx/em28xx-cards.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index be788b5df..608fa86e4 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -1699,7 +1699,7 @@ static int em28xx_hint_board(struct em28xx *dev) em28xx_errdev("If the board were missdetected, " "please email this log to:\n"); em28xx_errdev("\tV4L Mailing List " - " \n"); + " \n"); em28xx_errdev("Board detected as %s\n", em28xx_boards[dev->model].name); @@ -1731,7 +1731,7 @@ static int em28xx_hint_board(struct em28xx *dev) em28xx_errdev("If the board were missdetected, " "please email this log to:\n"); em28xx_errdev("\tV4L Mailing List " - " \n"); + " \n"); em28xx_errdev("Board detected as %s\n", em28xx_boards[dev->model].name); @@ -1744,7 +1744,7 @@ static int em28xx_hint_board(struct em28xx *dev) em28xx_errdev("You may try to use card= insmod option to " "workaround that.\n"); em28xx_errdev("Please send an email with this log to:\n"); - em28xx_errdev("\tV4L Mailing List \n"); + em28xx_errdev("\tV4L Mailing List \n"); em28xx_errdev("Board eeprom hash is 0x%08lx\n", dev->hash); em28xx_errdev("Board i2c devicelist hash is 0x%08lx\n", dev->i2c_hash); -- cgit v1.2.3 From 2bdbada7bd67bed564b828c8fe56530d0bd9a7ef Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 25 Jan 2009 14:08:07 -0200 Subject: em28xx: Fix for fail to submit URB with IRQs and Pre-emption Disabled From: Robert Krakora Trace: (Provided by Douglas) BUG: sleeping function called from invalid context at drivers/usb/core/urb.c:558 in_atomic():0, irqs_disabled():1 Pid: 4918, comm: sox Not tainted 2.6.27.5 #1 [] __might_sleep+0xc6/0xcb [] usb_kill_urb+0x1a/0xd8 [] ? __kmalloc+0x9b/0xfc [] ? __kmalloc+0xb8/0xfc [] ? usb_alloc_urb+0xf/0x31 [] em28xx_isoc_audio_deinit+0x2f/0x6c [em28xx_alsa] [] em28xx_cmd+0x1aa/0x1c5 [em28xx_alsa] [] snd_em28xx_capture_trigger+0x53/0x68 [em28xx_alsa] [] snd_pcm_do_start+0x1c/0x23 [snd_pcm] [] snd_pcm_action_single+0x25/0x4b [snd_pcm] [] snd_pcm_action+0x6a/0x76 [snd_pcm] [] snd_pcm_start+0x14/0x16 [snd_pcm] [] snd_pcm_lib_read1+0x66/0x273 [snd_pcm] [] ? snd_pcm_kernel_ioctl+0x46/0x5f [snd_pcm] [] snd_pcm_lib_read+0xbf/0xcd [snd_pcm] [] ? snd_pcm_lib_read_transfer+0x0/0xaf [snd_pcm] [] snd_pcm_oss_read3+0x99/0xdc [snd_pcm_oss] [] snd_pcm_oss_read2+0xa3/0xbf [snd_pcm_oss] [] ? _cond_resched+0x8/0x32 [] snd_pcm_oss_read+0x106/0x150 [snd_pcm_oss] [] ? snd_pcm_oss_read+0x0/0x150 [snd_pcm_oss] [] vfs_read+0x81/0xdc [] sys_read+0x3b/0x60 [] sysenter_do_call+0x12/0x34 ======================= The culprit in the trace is snd_pcm_action() which invokes a spin lock which disables pre-emption which disables an IRQ which causes the __might_sleep() function to fail the irqs_disabled() test. Since pre-emption is enabled then it is safe to de-allocate the memory if you first unlink each URB. In this instance you are safe since pre-emption is disabled. If pre-emption and irqs are not disabled then call usb_kill_urb(), else call usb_unlink_urb(). Thanks to Douglas for tracking down this bug originally!!! Priority: high Signed-off-by: Robert Krakora [dougsland@redhat.com: Fixed codyingstyle] Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/video/em28xx/em28xx-audio.c | 9 ++++++--- linux/drivers/media/video/em28xx/em28xx-core.c | 7 +++++-- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-audio.c b/linux/drivers/media/video/em28xx/em28xx-audio.c index 62dab8696..c64cd42a8 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -63,12 +63,15 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev) dprintk("Stopping isoc\n"); for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { - usb_kill_urb(dev->adev.urb[i]); + if (!irqs_disabled()) + usb_kill_urb(dev->adev.urb[i]); + else + usb_unlink_urb(dev->adev.urb[i]); usb_free_urb(dev->adev.urb[i]); dev->adev.urb[i] = NULL; - kfree(dev->adev.transfer_buffer[i]); - dev->adev.transfer_buffer[i] = NULL; + kfree(dev->adev.transfer_buffer[i]); + dev->adev.transfer_buffer[i] = NULL; } return 0; diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c index 5cf99aaf7..15d86bc97 100644 --- a/linux/drivers/media/video/em28xx/em28xx-core.c +++ b/linux/drivers/media/video/em28xx/em28xx-core.c @@ -869,8 +869,11 @@ void em28xx_uninit_isoc(struct em28xx *dev) for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { urb = dev->isoc_ctl.urb[i]; if (urb) { - usb_kill_urb(urb); - usb_unlink_urb(urb); + if (!irqs_disabled()) + usb_kill_urb(urb); + else + usb_unlink_urb(urb); + if (dev->isoc_ctl.transfer_buffer[i]) { usb_buffer_free(dev->udev, urb->transfer_buffer_length, -- cgit v1.2.3 From 145b0afdeec944d42cf79d579885475c46ba54e6 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 25 Jan 2009 18:37:26 +0100 Subject: gspca - pac207: Webcam 093a:2474 added. From: Lierdakil Priority: normal Signed-off-by: Lierdakil Signed-off-by: Jean-Francois Moine --- linux/Documentation/video4linux/gspca.txt | 1 + linux/drivers/media/video/gspca/pac207.c | 1 + 2 files changed, 2 insertions(+) (limited to 'linux') diff --git a/linux/Documentation/video4linux/gspca.txt b/linux/Documentation/video4linux/gspca.txt index af80c3344..3136c8028 100644 --- a/linux/Documentation/video4linux/gspca.txt +++ b/linux/Documentation/video4linux/gspca.txt @@ -216,6 +216,7 @@ pac207 093a:2468 PAC207 pac207 093a:2470 Genius GF112 pac207 093a:2471 Genius VideoCam ge111 pac207 093a:2472 Genius VideoCam ge110 +pac207 093a:2474 Genius iLook 111 pac207 093a:2476 Genius e-Messenger 112 pac7311 093a:2600 PAC7311 Typhoon pac7311 093a:2601 Philips SPC 610 NC diff --git a/linux/drivers/media/video/gspca/pac207.c b/linux/drivers/media/video/gspca/pac207.c index 93616cebf..95a97ab68 100644 --- a/linux/drivers/media/video/gspca/pac207.c +++ b/linux/drivers/media/video/gspca/pac207.c @@ -535,6 +535,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x093a, 0x2470)}, {USB_DEVICE(0x093a, 0x2471)}, {USB_DEVICE(0x093a, 0x2472)}, + {USB_DEVICE(0x093a, 0x2474)}, {USB_DEVICE(0x093a, 0x2476)}, {USB_DEVICE(0x145f, 0x013a)}, {USB_DEVICE(0x2001, 0xf115)}, -- cgit v1.2.3 From 1c4acbfba514ff97e939c530ec86a0c95ec8e656 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 25 Jan 2009 16:12:29 -0200 Subject: em28xx: fix spaces From: Douglas Schilling Landgraf Fixed spaces Priority: normal Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/video/em28xx/em28xx-audio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-audio.c b/linux/drivers/media/video/em28xx/em28xx-audio.c index c64cd42a8..ebbc64b3a 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -470,9 +470,9 @@ static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream snd_pcm_uframes_t hwptr_done; dev = snd_pcm_substream_chip(substream); - spin_lock_irqsave(&dev->adev.slock, flags); + spin_lock_irqsave(&dev->adev.slock, flags); hwptr_done = dev->adev.hwptr_done_capture; - spin_unlock_irqrestore(&dev->adev.slock, flags); + spin_unlock_irqrestore(&dev->adev.slock, flags); return hwptr_done; } -- cgit v1.2.3 From 6af1615ac94a5752ea7bf0b3e02ebe2030a32f0e Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 25 Jan 2009 20:19:23 -0200 Subject: em28xx: Add check before call em28xx_isoc_audio_deinit() From: Douglas Schilling Landgraf Just call em28xx_isoc_audio_deinit() if em28xx sent a usb_submit(). Priority: normal Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/video/em28xx/em28xx-audio.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-audio.c b/linux/drivers/media/video/em28xx/em28xx-audio.c index ebbc64b3a..fcf21a614 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -62,7 +62,7 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev) int i; dprintk("Stopping isoc\n"); - for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { + for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { if (!irqs_disabled()) usb_kill_urb(dev->adev.urb[i]); else @@ -74,6 +74,7 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev) dev->adev.transfer_buffer[i] = NULL; } + dev->isoc_ctl.num_bufs = 0; return 0; } @@ -178,6 +179,8 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) dprintk("Starting isoc transfers\n"); + dev->isoc_ctl.num_bufs = 0; + for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { struct urb *urb; int j, k; @@ -219,10 +222,19 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC); if (errCode) { - em28xx_isoc_audio_deinit(dev); + if (dev->isoc_ctl.num_bufs == 0) { + usb_free_urb(dev->adev.urb[i]); + dev->adev.urb[i] = NULL; + kfree(dev->adev.transfer_buffer[i]); + dev->adev.transfer_buffer[i] = NULL; + } else + em28xx_isoc_audio_deinit(dev); return errCode; } + mutex_lock(&dev->lock); + dev->isoc_ctl.num_bufs++; + mutex_unlock(&dev->lock); } return 0; -- cgit v1.2.3 From 32ff0a94de197313d0c1838ab4ad3a051064b292 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 25 Jan 2009 23:00:16 +0000 Subject: struct device - replace bus_id with dev_name(), dev_set_name() From: Kay Sievers Acked-by: Greg Kroah-Hartman Signed-off-by: Kay Sievers Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/radio-tea5764.c | 3 ++- linux/drivers/media/video/v4l2-device.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-tea5764.c b/linux/drivers/media/radio/radio-tea5764.c index 328fa50ca..9194a70aa 100644 --- a/linux/drivers/media/radio/radio-tea5764.c +++ b/linux/drivers/media/radio/radio-tea5764.c @@ -302,7 +302,8 @@ static int vidioc_querycap(struct file *file, void *priv, strlcpy(v->driver, dev->dev.driver->name, sizeof(v->driver)); strlcpy(v->card, dev->name, sizeof(v->card)); - snprintf(v->bus_info, sizeof(v->bus_info), "I2C:%s", dev->dev.bus_id); + snprintf(v->bus_info, sizeof(v->bus_info), + "I2C:%s", dev_name(&dev->dev)); v->version = RADIO_VERSION; v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; return 0; diff --git a/linux/drivers/media/video/v4l2-device.c b/linux/drivers/media/video/v4l2-device.c index cf9d4c7f5..8a4b74f31 100644 --- a/linux/drivers/media/video/v4l2-device.c +++ b/linux/drivers/media/video/v4l2-device.c @@ -34,7 +34,7 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev) spin_lock_init(&v4l2_dev->lock); v4l2_dev->dev = dev; snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s", - dev->driver->name, dev->bus_id); + dev->driver->name, dev_name(dev)); dev_set_drvdata(dev, v4l2_dev); return 0; } -- cgit v1.2.3 From d7274e08881bc13ea807d8c6c91f8461aadfdcdb Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 25 Jan 2009 21:05:58 -0200 Subject: v4l/dvb: use usb_make_path in usb-radio drivers From: Alexey Klimov Place usb_make_path in dsbr100.c, radio-mr800.c, radio-si470x.c that used when reporting bus_info information in vidioc_querycap. Priority: normal Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/radio/dsbr100.c | 4 +++- linux/drivers/media/radio/radio-mr800.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/dsbr100.c b/linux/drivers/media/radio/dsbr100.c index bb3f5a855..0516711f8 100644 --- a/linux/drivers/media/radio/dsbr100.c +++ b/linux/drivers/media/radio/dsbr100.c @@ -393,9 +393,11 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf) static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *v) { + struct dsbr100_device *radio = video_drvdata(file); + strlcpy(v->driver, "dsbr100", sizeof(v->driver)); strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof(v->card)); - sprintf(v->bus_info, "USB"); + usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info)); v->version = RADIO_VERSION; v->capabilities = V4L2_CAP_TUNER; return 0; diff --git a/linux/drivers/media/radio/radio-mr800.c b/linux/drivers/media/radio/radio-mr800.c index 6b1794989..ebd10cb2e 100644 --- a/linux/drivers/media/radio/radio-mr800.c +++ b/linux/drivers/media/radio/radio-mr800.c @@ -316,9 +316,11 @@ 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); + strlcpy(v->driver, "radio-mr800", sizeof(v->driver)); strlcpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card)); - sprintf(v->bus_info, "USB"); + usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info)); v->version = RADIO_VERSION; v->capabilities = V4L2_CAP_TUNER; return 0; -- cgit v1.2.3 From 5a1184d7147ed7f62ac148a6fd5b414fd6fae7ee Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 25 Jan 2009 21:07:28 -0200 Subject: radio-mr800: fix radio->muted and radio->stereo From: Alexey Klimov Move radio->muted and radio->stereo in section where radio mutex is locked to avoid possible race condition problems or access to memory. Thanks to David Ellingsworth for pointing to this weak place in driver. Priority: high Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/radio/radio-mr800.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-mr800.c b/linux/drivers/media/radio/radio-mr800.c index ebd10cb2e..4aa51a282 100644 --- a/linux/drivers/media/radio/radio-mr800.c +++ b/linux/drivers/media/radio/radio-mr800.c @@ -197,10 +197,10 @@ static int amradio_start(struct amradio_device *radio) return retval; } - mutex_unlock(&radio->lock); - radio->muted = 0; + mutex_unlock(&radio->lock); + return retval; } @@ -233,10 +233,10 @@ static int amradio_stop(struct amradio_device *radio) return retval; } - mutex_unlock(&radio->lock); - radio->muted = 1; + mutex_unlock(&radio->lock); + return retval; } @@ -287,10 +287,10 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) return retval; } - mutex_unlock(&radio->lock); - radio->stereo = 0; + mutex_unlock(&radio->lock); + return retval; } -- cgit v1.2.3 From b1d07a100a489df3cd03e3dc629d76bebce559f7 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Mon, 26 Jan 2009 01:07:59 -0500 Subject: s5h1409: Perform s5h1409 soft reset after tuning From: Devin Heitmueller Just like with the s5h1411, the s5h1409 needs a soft-reset in order for it to know that the tuner has been told to change frequencies. This change changes the behavior from "random tuning times between 500ms to complete tuning lock failures" to "tuning lock consistently within 700ms". Thanks to Robert Krakora for doing initial testing of the patch on the KWorld 330U. Thanks to Andy Walls for doing testing of the patch on the HVR-1600. Thanks to Michael Krufky for doing additional testing. Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/s5h1409.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/s5h1409.c b/linux/drivers/media/dvb/frontends/s5h1409.c index cf4d8936b..3e08d985d 100644 --- a/linux/drivers/media/dvb/frontends/s5h1409.c +++ b/linux/drivers/media/dvb/frontends/s5h1409.c @@ -545,9 +545,6 @@ static int s5h1409_set_frontend(struct dvb_frontend *fe, s5h1409_enable_modulation(fe, p->u.vsb.modulation); - /* Allow the demod to settle */ - msleep(100); - if (fe->ops.tuner_ops.set_params) { if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); @@ -562,6 +559,10 @@ static int s5h1409_set_frontend(struct dvb_frontend *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); + return 0; } -- cgit v1.2.3 From 4c1cb43c04ca0444e3dcb8113386c5fe84324496 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 26 Jan 2009 09:29:06 +0100 Subject: gspca - zc3xx: Do work the sensor adcm2700. From: Jean-Francois Moine The lack of the green color is fixed by sensor sequences closer to the ms-win traces. Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/zc3xx.c | 55 ++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 11 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index 300bbd00c..b93573f66 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -210,7 +210,11 @@ struct usb_action { static const struct usb_action adcm2700_Initial[] = { {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */ +#if 1 /*jfm*/ + {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ +#else {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ +#endif {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ @@ -230,7 +234,11 @@ static const struct usb_action adcm2700_Initial[] = { {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */ +#if 1 /*jfm-mswin*/ + {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */ +#else {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */ +#endif {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ @@ -269,6 +277,15 @@ static const struct usb_action adcm2700_Initial[] = { {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ {0xaa, 0xfe, 0x0020}, /* 00,fe,20,aa */ +/*mswin+*/ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, + {0xaa, 0xfe, 0x0002}, + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, + {0xaa, 0xb4, 0xcd37}, + {0xaa, 0xa4, 0x0004}, + {0xaa, 0xa8, 0x0007}, + {0xaa, 0xac, 0x0004}, +/*mswin-*/ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ @@ -290,7 +307,11 @@ static const struct usb_action adcm2700_Initial[] = { static const struct usb_action adcm2700_InitialScale[] = { {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ +#if 1 /*jfm*/ + {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ +#else {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ +#endif {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ @@ -310,7 +331,11 @@ static const struct usb_action adcm2700_InitialScale[] = { {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */ +#if 1 /*jfm-mswin*/ + {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */ +#else {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */ +#endif {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ @@ -338,9 +363,17 @@ static const struct usb_action adcm2700_InitialScale[] = { {0xbb, 0x5f, 0x2090}, /* 20,5f,90,bb */ {0xbb, 0x01, 0x8000}, /* 80,01,00,bb */ {0xbb, 0x09, 0x8400}, /* 84,09,00,bb */ +#if 1 /*jfm-mswin*/ + {0xbb, 0x86, 0x0002}, /* 00,88,02,bb */ +#else {0xbb, 0x88, 0x0002}, /* 00,88,02,bb */ +#endif {0xbb, 0xe6, 0x0401}, /* 04,e6,01,bb */ +#if 1 /*jfm-mswin*/ + {0xbb, 0x86, 0x0802}, /* 08,88,02,bb */ +#else {0xbb, 0x88, 0x0802}, /* 08,88,02,bb */ +#endif {0xbb, 0xe6, 0x0c01}, /* 0c,e6,01,bb */ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ @@ -6359,7 +6392,9 @@ static void setmatrix(struct gspca_dev *gspca_dev) int i; const __u8 *matrix; static const u8 adcm2700_matrix[9] = - {0x66, 0xed, 0xed, 0xed, 0x66, 0xed, 0xed, 0xed, 0x66}; +/* {0x66, 0xed, 0xed, 0xed, 0x66, 0xed, 0xed, 0xed, 0x66}; */ +/*ms-win*/ + {0x74, 0xed, 0xed, 0xed, 0x74, 0xed, 0xed, 0xed, 0x74}; static const __u8 gc0305_matrix[9] = {0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50}; static const __u8 ov7620_matrix[9] = @@ -6404,7 +6439,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) __u8 brightness; switch (sd->sensor) { - case SENSOR_ADCM2700: case SENSOR_GC0305: case SENSOR_OV7620: case SENSOR_PO2030: @@ -6413,8 +6447,11 @@ static void setbrightness(struct gspca_dev *gspca_dev) /*fixme: is it really write to 011d and 018d for all other sensors? */ brightness = sd->brightness; reg_w(gspca_dev->dev, brightness, 0x011d); - if (sd->sensor == SENSOR_HV7131B) + switch (sd->sensor) { + case SENSOR_ADCM2700: + case SENSOR_HV7131B: return; + } if (brightness < 0x70) brightness += 0x10; else @@ -6554,6 +6591,7 @@ static void setquality(struct gspca_dev *gspca_dev) __u8 frxt; switch (sd->sensor) { + case SENSOR_ADCM2700: case SENSOR_GC0305: case SENSOR_HV7131B: case SENSOR_OV7620: @@ -7304,8 +7342,6 @@ static int sd_start(struct gspca_dev *gspca_dev) } setmatrix(gspca_dev); /* one more time? */ switch (sd->sensor) { - case SENSOR_ADCM2700: - break; case SENSOR_OV7620: case SENSOR_PAS202B: reg_r(gspca_dev, 0x0180); /* from win */ @@ -7347,19 +7383,16 @@ static int sd_start(struct gspca_dev *gspca_dev) setautogain(gspca_dev); switch (sd->sensor) { - case SENSOR_PAS202B: - reg_w(dev, 0x00, 0x0007); /* (from win traces) */ - break; case SENSOR_PO2030: msleep(500); reg_r(gspca_dev, 0x0008); reg_r(gspca_dev, 0x0007); + /*fall thru*/ + case SENSOR_PAS202B: reg_w(dev, 0x00, 0x0007); /* (from win traces) */ - reg_w(dev, 0x02, 0x0008); + reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING); break; } - if (sd->sensor == SENSOR_PAS202B) - reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING); return 0; } -- cgit v1.2.3 From bd16f634ca88082a992fd51a9f2a94b83ead6a78 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 26 Jan 2009 23:13:05 +0100 Subject: saa7146: fix VIDIOC_ENUMSTD. From: Hans Verkuil The previous conversion to video_ioctl2 broke VIDIOC_ENUMSTD. This is now fixed. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/common/saa7146_fops.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/common/saa7146_fops.c b/linux/drivers/media/common/saa7146_fops.c index 4384bd16c..c6cc8574a 100644 --- a/linux/drivers/media/common/saa7146_fops.c +++ b/linux/drivers/media/common/saa7146_fops.c @@ -512,6 +512,7 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, struct saa7146_vv *vv = dev->vv_data; struct video_device *vfd; int err; + int i; DEB_EE(("dev:%p, name:'%s', type:%d\n",dev,name,type)); @@ -521,9 +522,11 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, return -ENOMEM; vfd->fops = &video_fops; - vfd->ioctl_ops = dev->ext_vv_data ? &dev->ext_vv_data->ops : - &saa7146_video_ioctl_ops; + vfd->ioctl_ops = &dev->ext_vv_data->ops; vfd->release = video_device_release; + vfd->tvnorms = 0; + for (i = 0; i < dev->ext_vv_data->num_stds; i++) + vfd->tvnorms |= dev->ext_vv_data->stds[i].id; strlcpy(vfd->name, name, sizeof(vfd->name)); video_set_drvdata(vfd, dev); -- cgit v1.2.3 From fb3a9246d433dda2f7ace056abb2574ed3a9da42 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 27 Jan 2009 06:02:41 +0000 Subject: tw9910: color format check is added on set_fmt From: Kuninori Morimoto Signed-off-by: Kuninori Morimoto Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/tw9910.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/tw9910.c b/linux/drivers/media/video/tw9910.c index c670b23a1..4593cdea7 100644 --- a/linux/drivers/media/video/tw9910.c +++ b/linux/drivers/media/video/tw9910.c @@ -645,6 +645,19 @@ static int tw9910_set_fmt(struct soc_camera_device *icd, __u32 pixfmt, struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); int ret = -EINVAL; u8 val; + int i; + + /* + * check color format + */ + for (i = 0 ; i < ARRAY_SIZE(tw9910_color_fmt) ; i++) { + if (pixfmt == tw9910_color_fmt[i].fourcc) { + ret = 0; + break; + } + } + if (ret < 0) + goto tw9910_set_fmt_error; /* * select suitable norm -- cgit v1.2.3 From 662705dd5c574972df7a0698fe912f845ac54475 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 27 Jan 2009 10:20:34 +0100 Subject: cx25840: ignore TUNER_SET_CONFIG in the command callback. From: Hans Verkuil These days TUNER_SET_CONFIG is broadcast to the other i2c devices and that triggers a fw load on the cx25840. Ignore this command since cx25840 isn't a tuner and you really do not want to load the firmware that early. Priority: high Signed-off-by: Hans Verkuil --- linux/drivers/media/video/cx25840/cx25840-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx25840/cx25840-core.c b/linux/drivers/media/video/cx25840/cx25840-core.c index 6d324002a..57e80717f 100644 --- a/linux/drivers/media/video/cx25840/cx25840-core.c +++ b/linux/drivers/media/video/cx25840/cx25840-core.c @@ -1412,7 +1412,7 @@ static int cx25840_log_status(struct v4l2_subdev *sd) static int cx25840_command(struct i2c_client *client, unsigned cmd, void *arg) { /* ignore this command */ - if (cmd == TUNER_SET_TYPE_ADDR) + if (cmd == TUNER_SET_TYPE_ADDR || cmd == TUNER_SET_CONFIG) return 0; /* Old-style drivers rely on initialization on first use, so -- cgit v1.2.3 From 2ce6b1f573b3b082749e3559d5cc6becff654172 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 29 Jan 2009 08:02:15 -0200 Subject: v4l2-device.c: Fix compilation with older kernels From: Mauro Carvalho Chehab Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/v4l2-device.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux') diff --git a/linux/drivers/media/video/v4l2-device.c b/linux/drivers/media/video/v4l2-device.c index 8a4b74f31..e84925976 100644 --- a/linux/drivers/media/video/v4l2-device.c +++ b/linux/drivers/media/video/v4l2-device.c @@ -23,6 +23,7 @@ #include #include #include +#include "compat.h" int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev) { -- cgit v1.2.3 From 562378e1f982f3a817c81594e61d40ffa05fac7d Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 28 Jan 2009 16:32:58 -0800 Subject: bttv: norm value should be unsigned From: Trent Piepho The norm value in the driver is an index into an array and the the driver doesn't allow it to be negative or otherwise invalid. It should be unsigned but wasn't in all places. Fix some structs and functions to have the norm be unsigned. Get rid of useless checks for "< 0". Most of the driver code can't handle a norm value that's out of range, so change some ">= BTTV_TVNORMS" checks to BUG_ON(). There's no point in silently ignoring invalid driver state just to crash because of it later. Priority: normal Reported-by: Roel Kluin Signed-off-by: Trent Piepho --- linux/drivers/media/video/bt8xx/bttv-cards.c | 2 +- linux/drivers/media/video/bt8xx/bttv-driver.c | 13 +++++-------- linux/drivers/media/video/bt8xx/bttv-vbi.c | 2 +- linux/drivers/media/video/bt8xx/bttv.h | 2 +- linux/drivers/media/video/bt8xx/bttvp.h | 9 +++++---- 5 files changed, 13 insertions(+), 15 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c index e0bfbbc74..9dd7add53 100644 --- a/linux/drivers/media/video/bt8xx/bttv-cards.c +++ b/linux/drivers/media/video/bt8xx/bttv-cards.c @@ -4131,7 +4131,7 @@ static void __devinit avermedia_eeprom(struct bttv *btv) } /* used on Voodoo TV/FM (Voodoo 200), S0 wired to 0x10000 */ -void bttv_tda9880_setnorm(struct bttv *btv, int norm) +void bttv_tda9880_setnorm(struct bttv *btv, unsigned int norm) { /* fix up our card entry */ if(norm==V4L2_STD_NTSC) { diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index c02c0ec80..41cf151d8 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -1300,7 +1300,7 @@ bttv_crop_calc_limits(struct bttv_crop *c) } static void -bttv_crop_reset(struct bttv_crop *c, int norm) +bttv_crop_reset(struct bttv_crop *c, unsigned int norm) { c->rect = bttv_tvnorms[norm].cropcap.defrect; bttv_crop_calc_limits(c); @@ -1313,16 +1313,13 @@ set_tvnorm(struct bttv *btv, unsigned int norm) const struct bttv_tvnorm *tvnorm; v4l2_std_id id; - if (norm < 0 || norm >= BTTV_TVNORMS) - return -EINVAL; + BUG_ON(norm >= BTTV_TVNORMS); + BUG_ON(btv->tvnorm >= BTTV_TVNORMS); tvnorm = &bttv_tvnorms[norm]; - if (btv->tvnorm < 0 || - btv->tvnorm >= BTTV_TVNORMS || - 0 != memcmp(&bttv_tvnorms[btv->tvnorm].cropcap, - &tvnorm->cropcap, - sizeof (tvnorm->cropcap))) { + if (!memcmp(&bttv_tvnorms[btv->tvnorm].cropcap, &tvnorm->cropcap, + sizeof (tvnorm->cropcap))) { bttv_crop_reset(&btv->crop[0], norm); btv->crop[1] = btv->crop[0]; /* current = default */ diff --git a/linux/drivers/media/video/bt8xx/bttv-vbi.c b/linux/drivers/media/video/bt8xx/bttv-vbi.c index 6819e21a3..e79a402fa 100644 --- a/linux/drivers/media/video/bt8xx/bttv-vbi.c +++ b/linux/drivers/media/video/bt8xx/bttv-vbi.c @@ -411,7 +411,7 @@ int bttv_g_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt) return 0; } -void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, int norm) +void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm) { const struct bttv_tvnorm *tvnorm; unsigned int real_samples_per_line; diff --git a/linux/drivers/media/video/bt8xx/bttv.h b/linux/drivers/media/video/bt8xx/bttv.h index 0c07dc9b7..d8b41ae24 100644 --- a/linux/drivers/media/video/bt8xx/bttv.h +++ b/linux/drivers/media/video/bt8xx/bttv.h @@ -266,7 +266,7 @@ extern void bttv_init_card2(struct bttv *btv); /* card-specific funtions */ extern void tea5757_set_freq(struct bttv *btv, unsigned short freq); -extern void bttv_tda9880_setnorm(struct bttv *btv, int norm); +extern void bttv_tda9880_setnorm(struct bttv *btv, unsigned int norm); /* extra tweaks for some chipsets */ extern void bttv_check_chipset(void); diff --git a/linux/drivers/media/video/bt8xx/bttvp.h b/linux/drivers/media/video/bt8xx/bttvp.h index 92961e130..71289d832 100644 --- a/linux/drivers/media/video/bt8xx/bttvp.h +++ b/linux/drivers/media/video/bt8xx/bttvp.h @@ -137,7 +137,7 @@ struct bttv_buffer { /* bttv specific */ const struct bttv_format *fmt; - int tvnorm; + unsigned int tvnorm; int btformat; int btswap; struct bttv_geometry geo; @@ -156,7 +156,7 @@ struct bttv_buffer_set { }; struct bttv_overlay { - int tvnorm; + unsigned int tvnorm; struct v4l2_rect w; enum v4l2_field field; struct v4l2_clip *clips; @@ -176,7 +176,7 @@ struct bttv_vbi_fmt { }; /* bttv-vbi.c */ -void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, int norm); +void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm); struct bttv_crop { /* A cropping rectangle in struct bttv_tvnorm.cropcap units. */ @@ -380,7 +380,8 @@ struct bttv { unsigned int audio; unsigned int mute; unsigned long freq; - int tvnorm,hue,contrast,bright,saturation; + unsigned int tvnorm; + int hue, contrast, bright, saturation; struct v4l2_framebuffer fbuf; unsigned int field_count; -- cgit v1.2.3 From 4a49903c6320c8ba9dfe2c139103166f75594f49 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 28 Jan 2009 16:32:59 -0800 Subject: bttv: Fix TDA9880 norm setting code From: Trent Piepho The code to set the norm for the TDA9880 analog demod was comparing btv->norm, an index into the bttv driver's norm array, to V4L2_STD_NTSC, which is a bit flag that's part of the V4L2 API. This doesn't work of course and results in the PAL path always being taken. What's more, it modified the bttv_tvcards[] entries for cards using the TDA9880. This is wrong because changing the norm on one card will also affect other cards of the same type. Writing to bttv_tvcards is also bad because it should be read-only or even devinitdata. Changing the norm would also cause the audio to become unmuted. Have the code get called for both norm setting and audio input setting (which where the gpios are set) to avoid needed to modify bttv_tvcards. Priority: normal Signed-off-by: Trent Piepho --- linux/drivers/media/video/bt8xx/bttv-cards.c | 37 +++++++++++++-------------- linux/drivers/media/video/bt8xx/bttv-driver.c | 13 ++++++++-- linux/drivers/media/video/bt8xx/bttv.h | 2 +- 3 files changed, 30 insertions(+), 22 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c index 9dd7add53..89203525f 100644 --- a/linux/drivers/media/video/bt8xx/bttv-cards.c +++ b/linux/drivers/media/video/bt8xx/bttv-cards.c @@ -4130,27 +4130,26 @@ static void __devinit avermedia_eeprom(struct bttv *btv) btv->has_remote ? "yes" : "no"); } -/* used on Voodoo TV/FM (Voodoo 200), S0 wired to 0x10000 */ -void bttv_tda9880_setnorm(struct bttv *btv, unsigned int norm) +/* + * For Voodoo TV/FM and Voodoo 200. These cards' tuners use a TDA9880 + * analog demod, which is not I2C controlled like the newer and more common + * TDA9887 series. Instead is has two tri-state input pins, S0 and S1, + * that control the IF for the video and audio. Apparently, bttv GPIO + * 0x10000 is connected to S0. S0 low selects a 38.9 MHz VIF for B/G/D/K/I + * (i.e., PAL) while high selects 45.75 MHz for M/N (i.e., NTSC). + */ +u32 bttv_tda9880_setnorm(struct bttv *btv, u32 gpiobits) { - /* fix up our card entry */ - if(norm==V4L2_STD_NTSC) { - bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomux[TVAUDIO_INPUT_TUNER]=0x957fff; - bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomute=0x957fff; - bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomux[TVAUDIO_INPUT_TUNER]=0x957fff; - bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomute=0x957fff; - dprintk("bttv_tda9880_setnorm to NTSC\n"); - } - else { - bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomux[TVAUDIO_INPUT_TUNER]=0x947fff; - bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomute=0x947fff; - bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomux[TVAUDIO_INPUT_TUNER]=0x947fff; - bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomute=0x947fff; - dprintk("bttv_tda9880_setnorm to PAL\n"); + + if (btv->audio == TVAUDIO_INPUT_TUNER) { + if (bttv_tvnorms[btv->tvnorm].v4l2_id & V4L2_STD_MN) + gpiobits |= 0x10000; + else + gpiobits &= ~0x10000; } - /* set GPIO according */ - gpio_bits(bttv_tvcards[btv->c.type].gpiomask, - bttv_tvcards[btv->c.type].gpiomux[btv->audio]); + + gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpiobits); + return gpiobits; } diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index 41cf151d8..f72c6ffea 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -1197,13 +1197,22 @@ audio_mux(struct bttv *btv, int input, int mute) gpio_val = bttv_tvcards[btv->c.type].gpiomute; else gpio_val = bttv_tvcards[btv->c.type].gpiomux[input]; + + switch (btv->c.type) { + case BTTV_BOARD_VOODOOTV_FM: + case BTTV_BOARD_VOODOOTV_200: + gpio_val = bttv_tda9880_setnorm(btv, gpio_val); + break; + + default: + gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val); + } #if 0 printk("bttv%d: amux: input=%d mute=%d signal=%s gpio_mux=%d irq=%s\n", btv->c.nr, input, mute, signal ? "yes" : "no", gpio_val, in_interrupt() ? "yes" : "no"); #endif - gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val); if (bttv_gpio) bttv_gpio_tracking(btv, audio_modes[mute ? 4 : input]); if (in_interrupt()) @@ -1342,7 +1351,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm) switch (btv->c.type) { case BTTV_BOARD_VOODOOTV_FM: case BTTV_BOARD_VOODOOTV_200: - bttv_tda9880_setnorm(btv,norm); + bttv_tda9880_setnorm(btv, gpio_read()); break; #if 0 case BTTV_BOARD_OSPREY540: diff --git a/linux/drivers/media/video/bt8xx/bttv.h b/linux/drivers/media/video/bt8xx/bttv.h index d8b41ae24..17b2add83 100644 --- a/linux/drivers/media/video/bt8xx/bttv.h +++ b/linux/drivers/media/video/bt8xx/bttv.h @@ -266,7 +266,7 @@ extern void bttv_init_card2(struct bttv *btv); /* card-specific funtions */ extern void tea5757_set_freq(struct bttv *btv, unsigned short freq); -extern void bttv_tda9880_setnorm(struct bttv *btv, unsigned int norm); +extern u32 bttv_tda9880_setnorm(struct bttv *btv, u32 gpiobits); /* extra tweaks for some chipsets */ extern void bttv_check_chipset(void); -- cgit v1.2.3 From f030fca37c310181b3fce820ab359bb8eceed0e2 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 28 Jan 2009 16:32:59 -0800 Subject: bttv: make tuner card info more consistent From: Trent Piepho The bttv card database structure had a "tuner" field that was the input number of the tuner input or UNSET for no tuner. However, the only values it could ever be are 0 and UNSET. Having a tuner on an input other than 0 didn't work and was never used. There is also a "tuner_type" field that can be set to TUNER_ABSENT to indicate no tuner, which makes "tuner = UNSET" redundant. In many cases, tuner_type was set to UNSET when there was no tuner, which isn't quite correct. tuner_type == UNSET is supposed to mean the tuner type isn't yet known. So, I changed cards where "tuner == UNSET" to always have tuner_type of TUNER_ABSENT. At this point the tuner field is redundant, so I deleted it. I have the card setup code set the card's tuner_type (not the card type's tuner_type!) to TUNER_ABSENT if it hasn't yet been set at the end of the setup code. Various places that check if the card has a tuner will now look for this instead of checking the card type's "tuner" field. Also autoload the tuner module before issuing the TUNER_SET_TYPE_ADDR I2C client call instead of after issuing it. Overall, on ia32 this decreases compiled code size by about 24 bytes and reduces the data size by 640 bytes. Priority: normal Signed-off-by: Trent Piepho --- linux/drivers/media/video/bt8xx/bttv-cards.c | 285 ++++++-------------------- linux/drivers/media/video/bt8xx/bttv-driver.c | 15 +- linux/drivers/media/video/bt8xx/bttv-i2c.c | 6 +- linux/drivers/media/video/bt8xx/bttv.h | 1 - 4 files changed, 77 insertions(+), 230 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c index 89203525f..3c9349f2c 100644 --- a/linux/drivers/media/video/bt8xx/bttv-cards.c +++ b/linux/drivers/media/video/bt8xx/bttv-cards.c @@ -322,7 +322,6 @@ struct tvcard bttv_tvcards[] = { .name = " *** UNKNOWN/GENERIC *** ", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .muxsel = { 2, 3, 1, 0 }, .tuner_type = UNSET, @@ -333,7 +332,6 @@ struct tvcard bttv_tvcards[] = { .name = "MIRO PCTV", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, @@ -348,7 +346,6 @@ struct tvcard bttv_tvcards[] = { .name = "Hauppauge (bt848)", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 7, .muxsel = { 2, 3, 1, 1 }, @@ -363,7 +360,6 @@ struct tvcard bttv_tvcards[] = { .name = "STB, Gateway P/N 6000699 (bt848)", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 7, .muxsel = { 2, 3, 1, 1 }, @@ -383,7 +379,6 @@ struct tvcard bttv_tvcards[] = { .name = "Intel Create and Share PCI/ Smart Video Recorder III", .video_inputs = 4, .audio_inputs = 0, - .tuner = UNSET, .svhs = 2, .gpiomask = 0, .muxsel = { 2, 3, 1, 1 }, @@ -397,7 +392,6 @@ struct tvcard bttv_tvcards[] = { .name = "Diamond DTV2000", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 3, .muxsel = { 2, 3, 1, 0 }, @@ -412,7 +406,6 @@ struct tvcard bttv_tvcards[] = { .name = "AVerMedia TVPhone", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 3, .muxsel = { 2, 3, 1, 1 }, .gpiomask = 0x0f, @@ -429,13 +422,12 @@ struct tvcard bttv_tvcards[] = { .name = "MATRIX-Vision MV-Delta", .video_inputs = 5, .audio_inputs = 1, - .tuner = UNSET, .svhs = 3, .gpiomask = 0, .muxsel = { 2, 3, 1, 0, 0 }, .gpiomux = { 0 }, .needs_tvaudio = 1, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -445,7 +437,6 @@ struct tvcard bttv_tvcards[] = { .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0xc00, .muxsel = { 2, 3, 1, 1 }, @@ -461,7 +452,6 @@ struct tvcard bttv_tvcards[] = { .name = "IMS/IXmicro TurboTV", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 3, .muxsel = { 2, 3, 1, 1 }, @@ -476,7 +466,6 @@ struct tvcard bttv_tvcards[] = { .name = "Hauppauge (bt878)", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x0f, /* old: 7 */ .muxsel = { 2, 0, 1, 1 }, @@ -492,7 +481,6 @@ struct tvcard bttv_tvcards[] = { .name = "MIRO PCTV pro", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x3014f, .muxsel = { 2, 3, 1, 1 }, @@ -509,7 +497,6 @@ struct tvcard bttv_tvcards[] = { .name = "ADS Technologies Channel Surfer TV (bt848)", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, @@ -523,7 +510,6 @@ struct tvcard bttv_tvcards[] = { .name = "AVerMedia TVCapture 98", .video_inputs = 3, .audio_inputs = 4, - .tuner = 0, .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, @@ -541,7 +527,6 @@ struct tvcard bttv_tvcards[] = { .name = "Aimslab Video Highway Xtreme (VHX)", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 7, .muxsel = { 2, 3, 1, 1 }, @@ -557,7 +542,6 @@ struct tvcard bttv_tvcards[] = { .name = "Zoltrix TV-Max", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, @@ -574,7 +558,6 @@ struct tvcard bttv_tvcards[] = { .name = "Prolink Pixelview PlayTV (bt878)", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x01fe00, .muxsel = { 2, 3, 1, 1 }, @@ -596,7 +579,6 @@ struct tvcard bttv_tvcards[] = { .name = "Leadtek WinView 601", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x8300f8, .muxsel = { 2, 3, 1, 1,0 }, @@ -613,7 +595,6 @@ struct tvcard bttv_tvcards[] = { .name = "AVEC Intercapture", .video_inputs = 3, .audio_inputs = 2, - .tuner = 0, .svhs = 2, .gpiomask = 0, .muxsel = { 2, 3, 1, 1 }, @@ -627,13 +608,12 @@ struct tvcard bttv_tvcards[] = { .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)", .video_inputs = 4, .audio_inputs = 1, - .tuner = UNSET, .svhs = UNSET, .gpiomask = 0x8dff00, .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0 }, .no_msp34xx = 1, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -643,7 +623,6 @@ struct tvcard bttv_tvcards[] = { .name = "CEI Raffles Card", .video_inputs = 3, .audio_inputs = 3, - .tuner = 0, .svhs = 2, .muxsel = { 2, 3, 1, 1 }, .tuner_type = UNSET, @@ -654,7 +633,6 @@ struct tvcard bttv_tvcards[] = { .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50", .video_inputs = 4, .audio_inputs = 2, /* tuner, line in */ - .tuner = 0, .svhs = 2, .gpiomask = 0x1800, .muxsel = { 2, 3, 1, 1 }, @@ -669,7 +647,6 @@ struct tvcard bttv_tvcards[] = { .name = "Askey CPH050/ Phoebe Tv Master + FM", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0xc00, .muxsel = { 2, 3, 1, 1 }, @@ -685,7 +662,6 @@ struct tvcard bttv_tvcards[] = { .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = UNSET, .gpiomask = 7, .muxsel = { 2, 3, -1 }, @@ -703,7 +679,6 @@ struct tvcard bttv_tvcards[] = { .name = "Askey CPH05X/06X (bt878) [many vendors]", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0xe00, .muxsel = { 2, 3, 1, 1 }, @@ -720,7 +695,6 @@ struct tvcard bttv_tvcards[] = { .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x1f0fff, .muxsel = { 2, 3, 1, 1 }, @@ -736,7 +710,6 @@ struct tvcard bttv_tvcards[] = { .name = "Hauppauge WinCam newer (bt878)", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 3, .gpiomask = 7, .muxsel = { 2, 0, 1, 1 }, @@ -751,7 +724,6 @@ struct tvcard bttv_tvcards[] = { .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50", .video_inputs = 4, .audio_inputs = 2, - .tuner = 0, .svhs = 2, .gpiomask = 0x1800, .muxsel = { 2, 3, 1, 1 }, @@ -768,7 +740,6 @@ struct tvcard bttv_tvcards[] = { .name = "Terratec TerraTV+ Version 1.1 (bt878)", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x1f0fff, .muxsel = { 2, 3, 1, 1 }, @@ -816,13 +787,12 @@ struct tvcard bttv_tvcards[] = { .name = "Imagenation PXC200", .video_inputs = 5, .audio_inputs = 1, - .tuner = UNSET, .svhs = 1, /* was: 4 */ .gpiomask = 0, .muxsel = { 2, 3, 1, 0, 0}, .gpiomux = { 0 }, .needs_tvaudio = 1, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .muxsel_hook = PXC200_muxsel, @@ -832,7 +802,6 @@ struct tvcard bttv_tvcards[] = { .name = "Lifeview FlyVideo 98 LR50", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x1800, /* 0x8dfe00 */ .muxsel = { 2, 3, 1, 1 }, @@ -847,7 +816,6 @@ struct tvcard bttv_tvcards[] = { .name = "Formac iProTV, Formac ProTV I (bt848)", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 3, .gpiomask = 1, .muxsel = { 2, 3, 1, 1 }, @@ -863,7 +831,6 @@ struct tvcard bttv_tvcards[] = { .name = "Intel Create and Share PCI/ Smart Video Recorder III", .video_inputs = 4, .audio_inputs = 0, - .tuner = UNSET, .svhs = 2, .gpiomask = 0, .muxsel = { 2, 3, 1, 1 }, @@ -877,7 +844,6 @@ struct tvcard bttv_tvcards[] = { .name = "Terratec TerraTValue Version Bt878", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0xffff00, .muxsel = { 2, 3, 1, 1 }, @@ -893,7 +859,6 @@ struct tvcard bttv_tvcards[] = { .name = "Leadtek WinFast 2000/ WinFast 2000 XP", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .muxsel = { 2, 3, 1, 1, 0 }, /* TV, CVid, SVid, CVid over SVid connector */ #if 0 @@ -929,7 +894,6 @@ struct tvcard bttv_tvcards[] = { .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II", .video_inputs = 4, .audio_inputs = 3, - .tuner = 0, .svhs = 2, .gpiomask = 0x1800, .muxsel = { 2, 3, 1, 1 }, @@ -946,7 +910,6 @@ struct tvcard bttv_tvcards[] = { .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner", .video_inputs = 4, .audio_inputs = 3, - .tuner = 0, .svhs = 2, .gpiomask = 0x1800, .muxsel = { 2, 3, 1, 1 }, @@ -962,7 +925,6 @@ struct tvcard bttv_tvcards[] = { .name = "Prolink PixelView PlayTV pro", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0xff, .muxsel = { 2, 3, 1, 1 }, @@ -978,7 +940,6 @@ struct tvcard bttv_tvcards[] = { .name = "Askey CPH06X TView99", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x551e00, .muxsel = { 2, 3, 1, 0 }, @@ -995,7 +956,6 @@ struct tvcard bttv_tvcards[] = { .name = "Pinnacle PCTV Studio/Rave", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x03000F, .muxsel = { 2, 3, 1, 1 }, @@ -1013,7 +973,6 @@ struct tvcard bttv_tvcards[] = { .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 7, .muxsel = { 2, 3, 1, 1 }, @@ -1031,7 +990,6 @@ struct tvcard bttv_tvcards[] = { .name = "AVerMedia TVPhone 98", .video_inputs = 3, .audio_inputs = 4, - .tuner = 0, .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, @@ -1048,7 +1006,6 @@ struct tvcard bttv_tvcards[] = { .name = "ProVideo PV951", /* pic16c54 */ .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0, .muxsel = { 2, 3, 1, 1}, @@ -1064,7 +1021,6 @@ struct tvcard bttv_tvcards[] = { .name = "Little OnAir TV", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0xe00b, .muxsel = { 2, 3, 1, 1 }, @@ -1081,7 +1037,6 @@ struct tvcard bttv_tvcards[] = { .name = "Sigma TVII-FM", .video_inputs = 2, .audio_inputs = 1, - .tuner = 0, .svhs = UNSET, .gpiomask = 3, .muxsel = { 2, 3, 1, 1 }, @@ -1097,14 +1052,13 @@ struct tvcard bttv_tvcards[] = { .name = "MATRIX-Vision MV-Delta 2", .video_inputs = 5, .audio_inputs = 1, - .tuner = UNSET, .svhs = 3, .gpiomask = 0, .muxsel = { 2, 3, 1, 0, 0 }, .gpiomux = { 0 }, .no_msp34xx = 1, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -1112,7 +1066,6 @@ struct tvcard bttv_tvcards[] = { .name = "Zoltrix Genie TV/FM", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0xbcf03f, .muxsel = { 2, 3, 1, 1 }, @@ -1128,7 +1081,6 @@ struct tvcard bttv_tvcards[] = { .name = "Terratec TV/Radio+", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x70000, .muxsel = { 2, 3, 1, 1 }, @@ -1148,7 +1100,6 @@ struct tvcard bttv_tvcards[] = { .name = "Askey CPH03x/ Dynalink Magic TView", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, @@ -1164,7 +1115,6 @@ struct tvcard bttv_tvcards[] = { .name = "IODATA GV-BCTV3/PCI", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x010f00, .muxsel = {2, 3, 0, 0 }, @@ -1180,7 +1130,6 @@ struct tvcard bttv_tvcards[] = { .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP", .video_inputs = 5, .audio_inputs = 1, - .tuner = 0, .svhs = 3, .gpiomask = 0xAA0000, .muxsel = { 2,3,1,1,-1 }, @@ -1207,7 +1156,6 @@ struct tvcard bttv_tvcards[] = { .name = "Eagle Wireless Capricorn2 (bt878A)", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 7, .muxsel = { 2, 0, 1, 1 }, @@ -1225,7 +1173,6 @@ struct tvcard bttv_tvcards[] = { .name = "Pinnacle PCTV Studio Pro", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 3, .gpiomask = 0x03000F, .muxsel = { 2, 3, 1, 1 }, @@ -1252,7 +1199,6 @@ struct tvcard bttv_tvcards[] = { .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS", .video_inputs = 4, .audio_inputs = 3, - .tuner = 0, .svhs = 2, .gpiomask = 0x1c, .muxsel = { 2, 3, 1, 1 }, @@ -1274,7 +1220,6 @@ struct tvcard bttv_tvcards[] = { .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x18e0, .muxsel = { 2, 3, 1, 1 }, @@ -1295,7 +1240,6 @@ struct tvcard bttv_tvcards[] = { .name = "Askey CPH031/ BESTBUY Easy TV", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0xF, .muxsel = { 2, 3, 1, 0 }, @@ -1314,7 +1258,6 @@ struct tvcard bttv_tvcards[] = { .name = "Lifeview FlyVideo 98FM LR50", .video_inputs = 4, .audio_inputs = 3, - .tuner = 0, .svhs = 2, .gpiomask = 0x1800, .muxsel = { 2, 3, 1, 1 }, @@ -1332,7 +1275,6 @@ struct tvcard bttv_tvcards[] = { .name = "GrandTec 'Grand Video Capture' (Bt848)", .video_inputs = 2, .audio_inputs = 0, - .tuner = UNSET, .svhs = 1, .gpiomask = 0, .muxsel = { 3, 1 }, @@ -1340,7 +1282,7 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_35, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -1349,7 +1291,6 @@ struct tvcard bttv_tvcards[] = { .name = "Askey CPH060/ Phoebe TV Master Only (No FM)", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0xe00, .muxsel = { 2, 3, 1, 1}, @@ -1366,7 +1307,6 @@ struct tvcard bttv_tvcards[] = { .name = "Askey CPH03x TV Capturer", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x03000F, .muxsel = { 2, 3, 1, 0 }, @@ -1384,7 +1324,6 @@ struct tvcard bttv_tvcards[] = { .name = "Modular Technology MM100PCTV", .video_inputs = 2, .audio_inputs = 2, - .tuner = 0, .svhs = UNSET, .gpiomask = 11, .muxsel = { 2, 3, 1, 1 }, @@ -1400,7 +1339,6 @@ struct tvcard bttv_tvcards[] = { .name = "AG Electronics GMV1", .video_inputs = 2, .audio_inputs = 0, - .tuner = UNSET, .svhs = 1, .gpiomask = 0xF, .muxsel = { 2, 2 }, @@ -1408,7 +1346,7 @@ struct tvcard bttv_tvcards[] = { .no_msp34xx = 1, .needs_tvaudio = 0, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -1419,7 +1357,6 @@ struct tvcard bttv_tvcards[] = { .name = "Askey CPH061/ BESTBUY Easy TV (bt878)", .video_inputs = 3, .audio_inputs = 2, - .tuner = 0, .svhs = 2, .gpiomask = 0xFF, .muxsel = { 2, 3, 1, 0 }, @@ -1436,7 +1373,6 @@ struct tvcard bttv_tvcards[] = { .name = "ATI TV-Wonder", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0xf03f, .muxsel = { 2, 3, 1, 0 }, @@ -1454,7 +1390,6 @@ struct tvcard bttv_tvcards[] = { .name = "ATI TV-Wonder VE", .video_inputs = 2, .audio_inputs = 1, - .tuner = 0, .svhs = UNSET, .gpiomask = 1, .muxsel = { 2, 3, 0, 1 }, @@ -1470,7 +1405,6 @@ struct tvcard bttv_tvcards[] = { .name = "Lifeview FlyVideo 2000S LR90", .video_inputs = 3, .audio_inputs = 3, - .tuner = 0, .svhs = 2, .gpiomask = 0x18e0, .muxsel = { 2, 3, 0, 1 }, @@ -1492,7 +1426,6 @@ struct tvcard bttv_tvcards[] = { .name = "Terratec TValueRadio", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0xffff00, .muxsel = { 2, 3, 1, 1 }, @@ -1510,7 +1443,6 @@ struct tvcard bttv_tvcards[] = { .name = "IODATA GV-BCTV4/PCI", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x010f00, .muxsel = {2, 3, 0, 0 }, @@ -1530,7 +1462,6 @@ struct tvcard bttv_tvcards[] = { * sound problems with this card. */ .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = UNSET, .gpiomask = 0x4f8a00, /* 0x100000: 1=MSP enabled (0=disable again) @@ -1552,7 +1483,6 @@ struct tvcard bttv_tvcards[] = { * sound problems with this card. */ .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = UNSET, .gpiomask = 0x4f8a00, /* 0x100000: 1=MSP enabled (0=disable again) @@ -1573,8 +1503,7 @@ struct tvcard bttv_tvcards[] = { .name = "Active Imaging AIMMS", .video_inputs = 1, .audio_inputs = 0, - .tuner = UNSET, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .pll = PLL_28, @@ -1586,7 +1515,6 @@ struct tvcard bttv_tvcards[] = { .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)", .video_inputs = 3, .audio_inputs = 4, - .tuner = 0, .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, @@ -1610,12 +1538,11 @@ struct tvcard bttv_tvcards[] = { .name = "Lifeview FlyVideo 98EZ (capture only) LR51", .video_inputs = 4, .audio_inputs = 0, - .tuner = UNSET, .svhs = 2, .muxsel = { 2, 3, 1, 1 }, /* AV1, AV2, SVHS, CVid adapter on SVHS */ .pll = PLL_28, .no_msp34xx = 1, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -1626,7 +1553,6 @@ struct tvcard bttv_tvcards[] = { .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x3f, .muxsel = { 2, 3, 1, 1 }, @@ -1656,13 +1582,12 @@ struct tvcard bttv_tvcards[] = { .name = "Sensoray 311", .video_inputs = 5, .audio_inputs = 0, - .tuner = UNSET, .svhs = 4, .gpiomask = 0, .muxsel = { 2, 3, 1, 0, 0 }, .gpiomux = { 0 }, .needs_tvaudio = 0, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -1671,7 +1596,6 @@ struct tvcard bttv_tvcards[] = { .name = "RemoteVision MX (RV605)", .video_inputs = 16, .audio_inputs = 0, - .tuner = UNSET, .svhs = UNSET, .gpiomask = 0x00, .gpiomask2 = 0x07ff, @@ -1679,7 +1603,7 @@ struct tvcard bttv_tvcards[] = { 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 }, .no_msp34xx = 1, .no_tda9875 = 1, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .muxsel_hook = rv605_muxsel, @@ -1688,7 +1612,6 @@ struct tvcard bttv_tvcards[] = { .name = "Powercolor MTV878/ MTV878R/ MTV878F", .video_inputs = 3, .audio_inputs = 2, - .tuner = 0, .svhs = 2, .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */ .muxsel = { 2, 1, 1, }, @@ -1708,7 +1631,6 @@ struct tvcard bttv_tvcards[] = { .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x140007, .muxsel = { 2, 3, 1, 1 }, @@ -1723,7 +1645,6 @@ struct tvcard bttv_tvcards[] = { .name = "GrandTec Multi Capture Card (Bt878)", .video_inputs = 4, .audio_inputs = 0, - .tuner = UNSET, .svhs = UNSET, .gpiomask = 0, .muxsel = { 2, 3, 1, 0 }, @@ -1731,7 +1652,7 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -1739,7 +1660,6 @@ struct tvcard bttv_tvcards[] = { .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF", .video_inputs = 4, .audio_inputs = 3, - .tuner = 0, .svhs = 2, .gpiomask = 7, .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */ @@ -1787,7 +1707,6 @@ struct tvcard bttv_tvcards[] = { .name = "Hauppauge WinTV PVR", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .muxsel = { 2, 0, 1, 1 }, .needs_tvaudio = 1, @@ -1803,7 +1722,6 @@ struct tvcard bttv_tvcards[] = { .name = "IODATA GV-BCTV5/PCI", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x0f0f80, .muxsel = {2, 3, 1, 0 }, @@ -1821,11 +1739,10 @@ struct tvcard bttv_tvcards[] = { .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */ .video_inputs = 4, /* id-inputs-clock */ .audio_inputs = 0, - .tuner = UNSET, .svhs = 3, .muxsel = { 3, 2, 0, 1 }, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .no_msp34xx = 1, @@ -1836,11 +1753,10 @@ struct tvcard bttv_tvcards[] = { .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */ .video_inputs = 3, .audio_inputs = 0, - .tuner = UNSET, .svhs = 2, .muxsel = { 2, 3, 1 }, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .no_msp34xx = 1, @@ -1853,11 +1769,10 @@ struct tvcard bttv_tvcards[] = { .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */ .video_inputs = 2, .audio_inputs = 0, - .tuner = UNSET, .svhs = 1, .muxsel = { 3, 1 }, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .no_msp34xx = 1, @@ -1868,11 +1783,10 @@ struct tvcard bttv_tvcards[] = { .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */ .video_inputs = 1, .audio_inputs = 0, - .tuner = UNSET, .svhs = UNSET, .muxsel = { 0 }, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .no_msp34xx = 1, @@ -1883,11 +1797,10 @@ struct tvcard bttv_tvcards[] = { .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */ .video_inputs = 2, .audio_inputs = 0, - .tuner = UNSET, .svhs = 1, .muxsel = { 0, 1 }, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .no_msp34xx = 1, @@ -1898,11 +1811,10 @@ struct tvcard bttv_tvcards[] = { .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */ .video_inputs = 1, .audio_inputs = 1, - .tuner = UNSET, .svhs = UNSET, .muxsel = { 0 }, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .no_msp34xx = 1, @@ -1915,11 +1827,10 @@ struct tvcard bttv_tvcards[] = { .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */ .video_inputs = 2, .audio_inputs = 1, - .tuner = UNSET, .svhs = 1, .muxsel = { 0, 1 }, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .no_msp34xx = 1, @@ -1930,11 +1841,10 @@ struct tvcard bttv_tvcards[] = { .name = "Osprey 210/220/230", /* 0x1(A|B)-04C0-C1 */ .video_inputs = 2, .audio_inputs = 1, - .tuner = UNSET, .svhs = 1, .muxsel = { 2, 3 }, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .no_msp34xx = 1, @@ -1945,11 +1855,10 @@ struct tvcard bttv_tvcards[] = { .name = "Osprey 500", /* 500 */ .video_inputs = 2, .audio_inputs = 1, - .tuner = UNSET, .svhs = 1, .muxsel = { 2, 3 }, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .no_msp34xx = 1, @@ -1960,14 +1869,13 @@ struct tvcard bttv_tvcards[] = { .name = "Osprey 540", /* 540 */ .video_inputs = 4, .audio_inputs = 1, - .tuner = UNSET, #if 0 /* TODO ... */ .svhs = OSPREY540_SVID_ANALOG, .muxsel = { [OSPREY540_COMP_ANALOG] = 2, [OSPREY540_SVID_ANALOG] = 3, }, #endif .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .no_msp34xx = 1, @@ -1984,11 +1892,10 @@ struct tvcard bttv_tvcards[] = { .name = "Osprey 2000", /* 2000 */ .video_inputs = 2, .audio_inputs = 1, - .tuner = UNSET, .svhs = 1, .muxsel = { 2, 3 }, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .no_msp34xx = 1, @@ -2000,8 +1907,7 @@ struct tvcard bttv_tvcards[] = { .name = "IDS Eagle", .video_inputs = 4, .audio_inputs = 0, - .tuner = UNSET, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .svhs = UNSET, @@ -2017,8 +1923,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 2, .audio_inputs = 0, .svhs = 1, - .tuner = UNSET, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .no_msp34xx = 1, @@ -2033,7 +1938,6 @@ struct tvcard bttv_tvcards[] = { .name = "Formac ProTV II (bt878)", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 3, .gpiomask = 2, /* TV, Comp1, Composite over SVID con, SVID */ @@ -2058,7 +1962,6 @@ struct tvcard bttv_tvcards[] = { .name = "MachTV", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = UNSET, .gpiomask = 7, .muxsel = { 2, 3, 1, 1}, @@ -2074,7 +1977,6 @@ struct tvcard bttv_tvcards[] = { .name = "Euresys Picolo", .video_inputs = 3, .audio_inputs = 0, - .tuner = UNSET, .svhs = 2, .gpiomask = 0, .no_msp34xx = 1, @@ -2082,7 +1984,7 @@ struct tvcard bttv_tvcards[] = { .no_tda7432 = 1, .muxsel = { 2, 0, 1}, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -2091,7 +1993,6 @@ struct tvcard bttv_tvcards[] = { .name = "ProVideo PV150", /* 0x4f */ .video_inputs = 2, .audio_inputs = 0, - .tuner = UNSET, .svhs = UNSET, .gpiomask = 0, .muxsel = { 2, 3 }, @@ -2099,7 +2000,7 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -2109,7 +2010,6 @@ struct tvcard bttv_tvcards[] = { .name = "AD-TVK503", /* 0x63 */ .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x001e8007, .muxsel = { 2, 3, 1, 0 }, @@ -2130,7 +2030,6 @@ struct tvcard bttv_tvcards[] = { .name = "Hercules Smart TV Stereo", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x00, .muxsel = { 2, 3, 1, 1 }, @@ -2154,7 +2053,6 @@ struct tvcard bttv_tvcards[] = { .name = "Pace TV & Radio Card", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .muxsel = { 2, 3, 1, 1 }, /* Tuner, CVid, SVid, CVid over SVid connector */ .gpiomask = 0, @@ -2177,8 +2075,7 @@ struct tvcard bttv_tvcards[] = { .name = "IVC-200", .video_inputs = 1, .audio_inputs = 0, - .tuner = UNSET, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .svhs = UNSET, @@ -2190,8 +2087,7 @@ struct tvcard bttv_tvcards[] = { .name = "IVCE-8784", .video_inputs = 1, .audio_inputs = 0, - .tuner = UNSET, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .svhs = UNSET, @@ -2203,7 +2099,6 @@ struct tvcard bttv_tvcards[] = { .name = "Grand X-Guard / Trust 814PCI", .video_inputs = 16, .audio_inputs = 0, - .tuner = UNSET, .svhs = UNSET, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2221,14 +2116,13 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_NEBULA_DIGITV] = { .name = "Nebula Electronics DigiTV", .video_inputs = 1, - .tuner = UNSET, .svhs = UNSET, .muxsel = { 2, 3, 1, 0 }, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .has_dvb = 1, @@ -2241,7 +2135,6 @@ struct tvcard bttv_tvcards[] = { .name = "ProVideo PV143", .video_inputs = 4, .audio_inputs = 0, - .tuner = UNSET, .svhs = UNSET, .gpiomask = 0, .muxsel = { 2, 3, 1, 0 }, @@ -2249,7 +2142,7 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -2258,14 +2151,13 @@ struct tvcard bttv_tvcards[] = { .name = "PHYTEC VD-009-X1 VD-011 MiniDIN (bt878)", .video_inputs = 4, .audio_inputs = 0, - .tuner = UNSET, /* card has no tuner */ .svhs = 3, .gpiomask = 0x00, .muxsel = { 2, 3, 1, 0 }, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 0, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -2273,14 +2165,13 @@ struct tvcard bttv_tvcards[] = { .name = "PHYTEC VD-009-X1 VD-011 Combi (bt878)", .video_inputs = 4, .audio_inputs = 0, - .tuner = UNSET, /* card has no tuner */ .svhs = 3, .gpiomask = 0x00, .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 0, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -2290,7 +2181,6 @@ struct tvcard bttv_tvcards[] = { .name = "PHYTEC VD-009 MiniDIN (bt878)", .video_inputs = 10, .audio_inputs = 0, - .tuner = UNSET, /* card has no tuner */ .svhs = 9, .gpiomask = 0x00, .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio @@ -2300,7 +2190,7 @@ struct tvcard bttv_tvcards[] = { .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 1, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -2308,7 +2198,6 @@ struct tvcard bttv_tvcards[] = { .name = "PHYTEC VD-009 Combi (bt878)", .video_inputs = 10, .audio_inputs = 0, - .tuner = UNSET, /* card has no tuner */ .svhs = 9, .gpiomask = 0x00, .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio @@ -2318,7 +2207,7 @@ struct tvcard bttv_tvcards[] = { .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 1, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -2326,8 +2215,7 @@ struct tvcard bttv_tvcards[] = { .name = "IVC-100", .video_inputs = 4, .audio_inputs = 0, - .tuner = UNSET, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .svhs = UNSET, @@ -2340,8 +2228,7 @@ struct tvcard bttv_tvcards[] = { .name = "IVC-120G", .video_inputs = 16, .audio_inputs = 0, /* card has no audio */ - .tuner = UNSET, /* card has no tuner */ - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .svhs = UNSET, /* card has no svhs */ @@ -2361,7 +2248,6 @@ struct tvcard bttv_tvcards[] = { .name = "pcHDTV HD-2000 TV", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .muxsel = { 2, 3, 1, 0 }, .tuner_type = TUNER_PHILIPS_FCV1236D, @@ -2385,7 +2271,6 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 3, .audio_inputs = 0, .svhs = 1, - .tuner = UNSET, .muxsel = { 3, 1, 1, 3 }, /* Vid In, SVid In, Vid over SVid in connector */ .no_msp34xx = 1, .no_tda9875 = 1, @@ -2399,7 +2284,6 @@ struct tvcard bttv_tvcards[] = { .name = "Teppro TEV-560/InterVision IV-560", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 3, .muxsel = { 2, 3, 1, 1 }, @@ -2416,9 +2300,8 @@ struct tvcard bttv_tvcards[] = { .name = "SIMUS GVC1100", .video_inputs = 4, .audio_inputs = 0, - .tuner = UNSET, .svhs = UNSET, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .pll = PLL_28, @@ -2430,7 +2313,6 @@ struct tvcard bttv_tvcards[] = { /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */ .name = "NGS NGSTV+", .video_inputs = 3, - .tuner = 0, .svhs = 2, .gpiomask = 0x008007, .muxsel = { 2, 3, 0, 0 }, @@ -2447,14 +2329,13 @@ struct tvcard bttv_tvcards[] = { .name = "LMLBT4", .video_inputs = 4, /* IN1,IN2,IN3,IN4 */ .audio_inputs = 0, - .tuner = UNSET, .svhs = UNSET, .muxsel = { 2, 3, 1, 0 }, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, .needs_tvaudio = 0, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -2463,7 +2344,6 @@ struct tvcard bttv_tvcards[] = { .name = "Tekram M205 PRO", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -2482,7 +2362,6 @@ struct tvcard bttv_tvcards[] = { .name = "Conceptronic CONTVFMi", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x008007, .muxsel = { 2, 3, 1, 1 }, @@ -2504,7 +2383,6 @@ struct tvcard bttv_tvcards[] = { .name = "Euresys Picolo Tetra", .video_inputs = 4, .audio_inputs = 0, - .tuner = UNSET, .svhs = UNSET, .gpiomask = 0, .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/ @@ -2516,7 +2394,7 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .needs_tvaudio = 0, .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/ - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -2526,7 +2404,6 @@ struct tvcard bttv_tvcards[] = { .name = "Spirit TV Tuner", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x0000000f, .muxsel = { 2, 1, 1 }, @@ -2542,7 +2419,6 @@ struct tvcard bttv_tvcards[] = { .name = "AVerMedia AVerTV DVB-T 771", .video_inputs = 2, .svhs = 1, - .tuner = UNSET, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -2561,14 +2437,13 @@ struct tvcard bttv_tvcards[] = { /* Based on the Nebula card data - added remote and new card number - BTTV_BOARD_AVDVBT_761, see also ir-kbd-gpio.c */ .name = "AverMedia AverTV DVB-T 761", .video_inputs = 2, - .tuner = UNSET, .svhs = 1, .muxsel = { 3, 1, 2, 0 }, /* Comp0, S-Video, ?, ? */ .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .has_dvb = 1, @@ -2580,7 +2455,6 @@ struct tvcard bttv_tvcards[] = { .name = "MATRIX Vision Sigma-SQ", .video_inputs = 16, .audio_inputs = 0, - .tuner = UNSET, .svhs = UNSET, .gpiomask = 0x0, .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, @@ -2589,7 +2463,7 @@ struct tvcard bttv_tvcards[] = { .gpiomux = { 0 }, .no_msp34xx = 1, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -2598,7 +2472,6 @@ struct tvcard bttv_tvcards[] = { .name = "MATRIX Vision Sigma-SLC", .video_inputs = 4, .audio_inputs = 0, - .tuner = UNSET, .svhs = UNSET, .gpiomask = 0x0, .muxsel = { 2, 2, 2, 2 }, @@ -2606,7 +2479,7 @@ struct tvcard bttv_tvcards[] = { .gpiomux = { 0 }, .no_msp34xx = 1, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -2617,7 +2490,6 @@ struct tvcard bttv_tvcards[] = { .name = "APAC Viewcomp 878(AMAX)", .video_inputs = 2, .audio_inputs = 1, - .tuner = 0, .svhs = UNSET, .gpiomask = 0xFF, .muxsel = { 2, 3, 1, 1 }, @@ -2636,14 +2508,13 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_DVICO_DVBT_LITE] = { /* Chris Pascoe */ .name = "DViCO FusionHDTV DVB-T Lite", - .tuner = UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, .pll = PLL_28, .no_video = 1, .has_dvb = 1, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -2652,7 +2523,6 @@ struct tvcard bttv_tvcards[] = { .name = "V-Gear MyVCD", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x3f, .muxsel = {2, 3, 1, 0 }, @@ -2673,7 +2543,6 @@ struct tvcard bttv_tvcards[] = { .name = "Super TV Tuner", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .muxsel = { 2, 3, 1, 0 }, .tuner_type = TUNER_PHILIPS_NTSC, @@ -2689,14 +2558,13 @@ struct tvcard bttv_tvcards[] = { .name = "Tibet Systems 'Progress DVR' CS16", .video_inputs = 16, .audio_inputs = 0, - .tuner = UNSET, .svhs = UNSET, .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, .pll = PLL_28, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .muxsel_hook = tibetCS16_muxsel, @@ -2716,8 +2584,7 @@ struct tvcard bttv_tvcards[] = { .name = "Kodicom 4400R (master)", .video_inputs = 16, .audio_inputs = 0, - .tuner = UNSET, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .svhs = UNSET, @@ -2748,8 +2615,7 @@ struct tvcard bttv_tvcards[] = { .name = "Kodicom 4400R (slave)", .video_inputs = 16, .audio_inputs = 0, - .tuner = UNSET, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .svhs = UNSET, @@ -2769,7 +2635,6 @@ struct tvcard bttv_tvcards[] = { .name = "Adlink RTV24", .video_inputs = 4, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .muxsel = { 2, 3, 1, 0 }, .tuner_type = UNSET, @@ -2781,7 +2646,6 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = { /* Michael Krufky */ .name = "DViCO FusionHDTV 5 Lite", - .tuner = 0, .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */ .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -2803,7 +2667,6 @@ struct tvcard bttv_tvcards[] = { .name = "Acorp Y878F", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x01fe00, .muxsel = { 2, 3, 1, 1 }, @@ -2821,7 +2684,6 @@ struct tvcard bttv_tvcards[] = { .name = "Conceptronic CTVFMi v2", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x001c0007, .muxsel = { 2, 3, 1, 1 }, @@ -2840,7 +2702,6 @@ struct tvcard bttv_tvcards[] = { .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)", .video_inputs = 5, .audio_inputs = 1, - .tuner = 0, .svhs = 3, .gpiomask = 0x01fe00, .muxsel = { 2,3,1,1,-1 }, @@ -2860,7 +2721,6 @@ struct tvcard bttv_tvcards[] = { .name = "Prolink PixelView PlayTV MPEG2 PV-M4900", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x3f, .muxsel = { 2, 3, 1, 1 }, @@ -2891,14 +2751,13 @@ struct tvcard bttv_tvcards[] = { .name = "Osprey 440", .video_inputs = 4, .audio_inputs = 2, /* this is meaningless */ - .tuner = UNSET, .svhs = UNSET, .muxsel = { 2, 3, 0, 1 }, /* 3,0,1 are guesses */ .gpiomask = 0x303, .gpiomute = 0x000, /* int + 32kHz */ .gpiomux = { 0, 0, 0x000, 0x100}, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .no_msp34xx = 1, @@ -2910,7 +2769,6 @@ struct tvcard bttv_tvcards[] = { .name = "Asound Skyeye PCTV", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, @@ -2927,7 +2785,6 @@ struct tvcard bttv_tvcards[] = { .name = "Sabrent TV-FM (bttv version)", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x108007, .muxsel = { 2, 3, 1, 1 }, @@ -2945,14 +2802,13 @@ struct tvcard bttv_tvcards[] = { .name = "Hauppauge ImpactVCB (bt878)", .video_inputs = 4, .audio_inputs = 0, - .tuner = UNSET, .svhs = UNSET, .gpiomask = 0x0f, /* old: 7 */ .muxsel = { 0, 1, 3, 2 }, /* Composite 0-3 */ .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -2967,7 +2823,6 @@ struct tvcard bttv_tvcards[] = { .name = "MagicTV", /* rebranded MachTV */ .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 7, .muxsel = { 2, 3, 1, 1 }, @@ -2984,10 +2839,9 @@ struct tvcard bttv_tvcards[] = { .name = "SSAI Security Video Interface", .video_inputs = 4, .audio_inputs = 0, - .tuner = UNSET, .svhs = UNSET, .muxsel = { 0, 1, 2, 3 }, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -2995,17 +2849,15 @@ struct tvcard bttv_tvcards[] = { .name = "SSAI Ultrasound Video Interface", .video_inputs = 2, .audio_inputs = 0, - .tuner = UNSET, .svhs = 1, .muxsel = { 2, 0, 1, 3 }, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, /* ---- card 0x94---------------------------------- */ [BTTV_BOARD_DVICO_FUSIONHDTV_2] = { .name = "DViCO FusionHDTV 2", - .tuner = 0, .tuner_type = TUNER_PHILIPS_FCV1236D, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -3025,7 +2877,6 @@ struct tvcard bttv_tvcards[] = { .name = "Typhoon TV-Tuner PCI (50684)", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x3014f, .muxsel = { 2, 3, 1, 1 }, @@ -3042,7 +2893,6 @@ struct tvcard bttv_tvcards[] = { .name = "Geovision GV-600", .video_inputs = 16, .audio_inputs = 0, - .tuner = UNSET, .svhs = UNSET, .gpiomask = 0x0, .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, @@ -3051,7 +2901,7 @@ struct tvcard bttv_tvcards[] = { .gpiomux = { 0 }, .no_msp34xx = 1, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -3062,7 +2912,6 @@ struct tvcard bttv_tvcards[] = { .name = "Kozumi KTV-01C", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, .gpiomask = 0x008007, .muxsel = { 2, 3, 1, 1 }, @@ -3088,7 +2937,6 @@ struct tvcard bttv_tvcards[] = { .name = "Encore ENL TV-FM-2", .video_inputs = 3, .audio_inputs = 1, - .tuner = 0, .svhs = 2, /* bit 6 -> IR disabled bit 18/17 = 00 -> mute @@ -3112,14 +2960,13 @@ struct tvcard bttv_tvcards[] = { .name = "PHYTEC VD-012 (bt878)", .video_inputs = 4, .audio_inputs = 0, - .tuner = UNSET, /* card has no tuner */ .svhs = UNSET, /* card has no s-video */ .gpiomask = 0x00, .muxsel = { 0, 2, 3, 1 }, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 0, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -3128,14 +2975,13 @@ struct tvcard bttv_tvcards[] = { .name = "PHYTEC VD-012-X1 (bt878)", .video_inputs = 4, .audio_inputs = 0, - .tuner = UNSET, /* card has no tuner */ .svhs = 3, .gpiomask = 0x00, .muxsel = { 2, 3, 1 }, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 0, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, }, @@ -3144,14 +2990,13 @@ struct tvcard bttv_tvcards[] = { .name = "PHYTEC VD-012-X2 (bt878)", .video_inputs = 4, .audio_inputs = 0, - .tuner = UNSET, /* card has no tuner */ .svhs = 3, .gpiomask = 0x00, .muxsel = { 3, 2, 1 }, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 0, .pll = PLL_28, - .tuner_type = UNSET, + .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, } @@ -3725,13 +3570,12 @@ void __devinit bttv_init_card2(struct bttv *btv) addr = bttv_tvcards[btv->c.type].tuner_addr; if (UNSET != bttv_tvcards[btv->c.type].tuner_type) - if(UNSET == btv->tuner_type) + if (UNSET == btv->tuner_type) btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type; if (UNSET != tuner[btv->c.nr]) btv->tuner_type = tuner[btv->c.nr]; - if (btv->tuner_type == TUNER_ABSENT || - bttv_tvcards[btv->c.type].tuner == UNSET) + if (btv->tuner_type == TUNER_ABSENT) printk(KERN_INFO "bttv%d: tuner absent\n", btv->c.nr); else if(btv->tuner_type == UNSET) printk(KERN_WARNING "bttv%d: tuner type unset\n", btv->c.nr); @@ -3739,13 +3583,23 @@ void __devinit bttv_init_card2(struct bttv *btv) printk(KERN_INFO "bttv%d: tuner type=%d\n", btv->c.nr, btv->tuner_type); - if (btv->tuner_type != UNSET) { + if (UNSET == btv->tuner_type) + btv->tuner_type = TUNER_ABSENT; + + if (btv->tuner_type != TUNER_ABSENT) { struct tuner_setup tun_setup; + /* Load tuner module before issuing tuner config call! */ + if (autoload) + request_module("tuner"); + tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV; tun_setup.type = btv->tuner_type; tun_setup.addr = addr; + if (bttv_tvcards[btv->c.type].has_radio) + tun_setup.mode_mask |= T_RADIO; + bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup); } @@ -3778,7 +3632,7 @@ void __devinit bttv_init_card2(struct bttv *btv) if (!autoload) return; - if (bttv_tvcards[btv->c.type].tuner == UNSET) + if (btv->tuner_type == TUNER_ABSENT) return; /* no tuner or related drivers to load */ /* try to detect audio/fader chips */ @@ -3800,9 +3654,6 @@ void __devinit bttv_init_card2(struct bttv *btv) if (bttv_tvcards[btv->c.type].needs_tvaudio) request_module("tvaudio"); - - if (btv->tuner_type != UNSET && btv->tuner_type != TUNER_ABSENT) - request_module("tuner"); } diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index f72c6ffea..53be29350 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -1384,8 +1384,8 @@ set_input(struct bttv *btv, unsigned int input, unsigned int norm) } else { video_mux(btv,input); } - audio_input(btv,(input == bttv_tvcards[btv->c.type].tuner ? - TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN)); + audio_input(btv, (btv->tuner_type != TUNER_ABSENT && input == 0) ? + TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN); set_tvnorm(btv, norm); } @@ -1935,7 +1935,7 @@ static int bttv_enum_input(struct file *file, void *priv, i->type = V4L2_INPUT_TYPE_CAMERA; i->audioset = 1; - if (i->index == bttv_tvcards[btv->c.type].tuner) { + if (btv->tuner_type != TUNER_ABSENT && i->index == 0) { sprintf(i->name, "Television"); i->type = V4L2_INPUT_TYPE_TUNER; i->tuner = 0; @@ -1999,7 +1999,7 @@ static int bttv_s_tuner(struct file *file, void *priv, if (0 != err) return err; - if (UNSET == bttv_tvcards[btv->c.type].tuner) + if (btv->tuner_type == TUNER_ABSENT) return -EINVAL; if (0 != t->index) @@ -2693,8 +2693,7 @@ static int bttv_querycap(struct file *file, void *priv, if (no_overlay <= 0) cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; - if (bttv_tvcards[btv->c.type].tuner != UNSET && - bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT) + if (btv->tuner_type != TUNER_ABSENT) cap->capabilities |= V4L2_CAP_TUNER; return 0; } @@ -2977,7 +2976,7 @@ static int bttv_g_tuner(struct file *file, void *priv, struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; - if (UNSET == bttv_tvcards[btv->c.type].tuner) + if (btv->tuner_type == TUNER_ABSENT) return -EINVAL; if (0 != t->index) return -EINVAL; @@ -3537,7 +3536,7 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; - if (UNSET == bttv_tvcards[btv->c.type].tuner) + if (btv->tuner_type == TUNER_ABSENT) return -EINVAL; if (0 != t->index) return -EINVAL; diff --git a/linux/drivers/media/video/bt8xx/bttv-i2c.c b/linux/drivers/media/video/bt8xx/bttv-i2c.c index 558572589..66fc4e480 100644 --- a/linux/drivers/media/video/bt8xx/bttv-i2c.c +++ b/linux/drivers/media/video/bt8xx/bttv-i2c.c @@ -289,12 +289,10 @@ static int attach_inform(struct i2c_client *client) btv->i2c_msp34xx_client = client; if (client->driver->id == I2C_DRIVERID_TVAUDIO) btv->i2c_tvaudio_client = client; - if (btv->tuner_type != UNSET) { + if (btv->tuner_type != TUNER_ABSENT) { struct tuner_setup tun_setup; - if ((addr==ADDR_UNSET) || - (addr==client->addr)) { - + if (addr == ADDR_UNSET || addr == client->addr) { tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV | T_RADIO; tun_setup.type = btv->tuner_type; tun_setup.addr = addr; diff --git a/linux/drivers/media/video/bt8xx/bttv.h b/linux/drivers/media/video/bt8xx/bttv.h index 17b2add83..1fee79c55 100644 --- a/linux/drivers/media/video/bt8xx/bttv.h +++ b/linux/drivers/media/video/bt8xx/bttv.h @@ -217,7 +217,6 @@ struct tvcard char *name; unsigned int video_inputs; unsigned int audio_inputs; - unsigned int tuner; unsigned int svhs; unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO u32 gpiomask; -- cgit v1.2.3 From b4ac56eed1e1ef734166e5e63c7cd20e0523dac5 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 28 Jan 2009 16:32:59 -0800 Subject: bttv: store card database more efficiently From: Trent Piepho The bttv card database is quite large and the data structure used to store it wasn't very efficient. Most of the field are only used at card initialization time so it doesn't matter if they aren't efficient to access. Overall the changes reduce code size by 60 bytes in ia32. The data size is decreased by 5024 byes. It is probably even more for 64-bit kernels. Move the fields in the struct around to be sorted from largest to smallest. This saves on padding space used for alignment. Get rid of the unused digital_mode field. Leave the setting as a comment in the few cards entries that set it, in case someone ever writes the code. Get rid of the unused audio_inputs field. Leave the values in the card entries in case someone ever writes code that might use it. Get ride of the unused radio_addr field. No card entries even set it to anything interesting so it's not left as comments. All the code that used it was removed in commit v2.6.14-3466-g291d1d7 from Nov 8th 2005. Reduce video_inputs to u8 as no card has more than 255 inputs (the most is 16). Change tuner_addr to u8. I2C addresses are only seven bits and 255 means ADDR_UNSET, so everything fits. Make has_radio a one bit flag. Make the pll setting a two bit field. Reduce svhs to four bits as no card has an s-video input above 9. Change the value for no s-video input from UNSET (which is -1U and out of range of four bits) to NO_SVHS (which is now 15). Priority: normal Signed-off-by: Trent Piepho --- linux/drivers/media/video/bt8xx/bttv-cards.c | 626 ++++++++++----------------- linux/drivers/media/video/bt8xx/bttv.h | 40 +- 2 files changed, 249 insertions(+), 417 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c index 3c9349f2c..c6cdf79e8 100644 --- a/linux/drivers/media/video/bt8xx/bttv-cards.c +++ b/linux/drivers/media/video/bt8xx/bttv-cards.c @@ -321,17 +321,15 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_UNKNOWN] = { .name = " *** UNKNOWN/GENERIC *** ", .video_inputs = 4, - .audio_inputs = 1, .svhs = 2, .muxsel = { 2, 3, 1, 0 }, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_MIRO] = { .name = "MIRO PCTV", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, @@ -340,12 +338,11 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_HAUPPAUGE] = { .name = "Hauppauge (bt848)", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 7, .muxsel = { 2, 3, 1, 1 }, @@ -354,12 +351,11 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_STB] = { .name = "STB, Gateway P/N 6000699 (bt848)", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 7, .muxsel = { 2, 3, 1, 1 }, @@ -369,7 +365,6 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .pll = PLL_28, .has_radio = 1, }, @@ -378,7 +373,7 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_INTEL] = { .name = "Intel Create and Share PCI/ Smart Video Recorder III", .video_inputs = 4, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .svhs = 2, .gpiomask = 0, .muxsel = { 2, 3, 1, 1 }, @@ -386,12 +381,11 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_DIAMOND] = { .name = "Diamond DTV2000", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 3, .muxsel = { 2, 3, 1, 0 }, @@ -400,12 +394,11 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_AVERMEDIA] = { .name = "AVerMedia TVPhone", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 3, .muxsel = { 2, 3, 1, 1 }, .gpiomask = 0x0f, @@ -414,14 +407,13 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .audio_mode_gpio= avermedia_tvphone_audio, .has_remote = 1, }, [BTTV_BOARD_MATRIX_VISION] = { .name = "MATRIX-Vision MV-Delta", .video_inputs = 5, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 3, .gpiomask = 0, .muxsel = { 2, 3, 1, 0, 0 }, @@ -429,14 +421,13 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, /* ---- card 0x08 ---------------------------------- */ [BTTV_BOARD_FLYVIDEO] = { .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xc00, .muxsel = { 2, 3, 1, 1 }, @@ -446,12 +437,11 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_TURBOTV] = { .name = "IMS/IXmicro TurboTV", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 3, .muxsel = { 2, 3, 1, 1 }, @@ -460,12 +450,11 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_HAUPPAUGE878] = { .name = "Hauppauge (bt878)", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x0f, /* old: 7 */ .muxsel = { 2, 0, 1, 1 }, @@ -475,12 +464,11 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_MIROPRO] = { .name = "MIRO PCTV pro", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x3014f, .muxsel = { 2, 3, 1, 1 }, @@ -489,14 +477,13 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, /* ---- card 0x0c ---------------------------------- */ [BTTV_BOARD_ADSTECH_TV] = { .name = "ADS Technologies Channel Surfer TV (bt848)", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, @@ -504,12 +491,11 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_AVERMEDIA98] = { .name = "AVerMedia TVCapture 98", .video_inputs = 3, - .audio_inputs = 4, + /* .audio_inputs= 4, */ .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, @@ -519,14 +505,13 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .audio_mode_gpio= avermedia_tv_stereo_audio, .no_gpioirq = 1, }, [BTTV_BOARD_VHX] = { .name = "Aimslab Video Highway Xtreme (VHX)", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 7, .muxsel = { 2, 3, 1, 1 }, @@ -536,12 +521,11 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_ZOLTRIX] = { .name = "Zoltrix TV-Max", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, @@ -550,14 +534,13 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, /* ---- card 0x10 ---------------------------------- */ [BTTV_BOARD_PIXVIEWPLAYTV] = { .name = "Prolink Pixelview PlayTV (bt878)", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x01fe00, .muxsel = { 2, 3, 1, 1 }, @@ -573,12 +556,11 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_WINVIEW_601] = { .name = "Leadtek WinView 601", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x8300f8, .muxsel = { 2, 3, 1, 1,0 }, @@ -587,14 +569,13 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .volume_gpio = winview_volume, .has_radio = 1, }, [BTTV_BOARD_AVEC_INTERCAP] = { .name = "AVEC Intercapture", .video_inputs = 3, - .audio_inputs = 2, + /* .audio_inputs= 2, */ .svhs = 2, .gpiomask = 0, .muxsel = { 2, 3, 1, 1 }, @@ -602,37 +583,34 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_LIFE_FLYKIT] = { .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)", .video_inputs = 4, - .audio_inputs = 1, - .svhs = UNSET, + /* .audio_inputs= 1, */ + .svhs = NO_SVHS, .gpiomask = 0x8dff00, .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0 }, .no_msp34xx = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, /* ---- card 0x14 ---------------------------------- */ [BTTV_BOARD_CEI_RAFFLES] = { .name = "CEI Raffles Card", .video_inputs = 3, - .audio_inputs = 3, + /* .audio_inputs= 3, */ .svhs = 2, .muxsel = { 2, 3, 1, 1 }, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_CONFERENCETV] = { .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50", .video_inputs = 4, - .audio_inputs = 2, /* tuner, line in */ + /* .audio_inputs= 2, tuner, line in */ .svhs = 2, .gpiomask = 0x1800, .muxsel = { 2, 3, 1, 1 }, @@ -641,12 +619,11 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_PHOEBE_TVMAS] = { .name = "Askey CPH050/ Phoebe Tv Master + FM", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xc00, .muxsel = { 2, 3, 1, 1 }, @@ -656,29 +633,27 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_MODTEC_205] = { .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878", .video_inputs = 3, - .audio_inputs = 1, - .svhs = UNSET, + /* .audio_inputs= 1, */ + .svhs = NO_SVHS, .gpiomask = 7, .muxsel = { 2, 3, -1 }, - .digital_mode = DIGITAL_MODE_CAMERA, + /* .digital_mode= DIGITAL_MODE_CAMERA, */ .gpiomux = { 0, 0, 0, 0 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ALPS_TSBB5_PAL_I, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, /* ---- card 0x18 ---------------------------------- */ [BTTV_BOARD_MAGICTVIEW061] = { .name = "Askey CPH05X/06X (bt878) [many vendors]", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xe00, .muxsel = { 2, 3, 1, 1 }, @@ -688,13 +663,12 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .has_remote = 1, }, [BTTV_BOARD_VOBIS_BOOSTAR] = { .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x1f0fff, .muxsel = { 2, 3, 1, 1 }, @@ -703,13 +677,12 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .audio_mode_gpio= terratv_audio, }, [BTTV_BOARD_HAUPPAUG_WCAM] = { .name = "Hauppauge WinCam newer (bt878)", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 3, .gpiomask = 7, .muxsel = { 2, 0, 1, 1 }, @@ -718,12 +691,11 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_MAXI] = { .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50", .video_inputs = 4, - .audio_inputs = 2, + /* .audio_inputs= 2, */ .svhs = 2, .gpiomask = 0x1800, .muxsel = { 2, 3, 1, 1 }, @@ -732,14 +704,13 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_SECAM, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, /* ---- card 0x1c ---------------------------------- */ [BTTV_BOARD_TERRATV] = { .name = "Terratec TerraTV+ Version 1.1 (bt878)", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x1f0fff, .muxsel = { 2, 3, 1, 1 }, @@ -748,7 +719,6 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .audio_mode_gpio= terratv_audio, /* GPIO wiring: External 20 pin connector (for Active Radio Upgrade board) @@ -786,7 +756,7 @@ struct tvcard bttv_tvcards[] = { /* Jannik Fritsch */ .name = "Imagenation PXC200", .video_inputs = 5, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 1, /* was: 4 */ .gpiomask = 0, .muxsel = { 2, 3, 1, 0, 0}, @@ -794,14 +764,13 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .muxsel_hook = PXC200_muxsel, }, [BTTV_BOARD_FLYVIDEO_98] = { .name = "Lifeview FlyVideo 98 LR50", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x1800, /* 0x8dfe00 */ .muxsel = { 2, 3, 1, 1 }, @@ -810,12 +779,11 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_IPROTV] = { .name = "Formac iProTV, Formac ProTV I (bt848)", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 3, .gpiomask = 1, .muxsel = { 2, 3, 1, 1 }, @@ -823,14 +791,13 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, /* ---- card 0x20 ---------------------------------- */ [BTTV_BOARD_INTEL_C_S_PCI] = { .name = "Intel Create and Share PCI/ Smart Video Recorder III", .video_inputs = 4, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .svhs = 2, .gpiomask = 0, .muxsel = { 2, 3, 1, 1 }, @@ -838,12 +805,11 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_TERRATVALUE] = { .name = "Terratec TerraTValue Version Bt878", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xffff00, .muxsel = { 2, 3, 1, 1 }, @@ -853,12 +819,11 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_WINFAST2000] = { .name = "Leadtek WinFast 2000/ WinFast 2000 XP", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .muxsel = { 2, 3, 1, 1, 0 }, /* TV, CVid, SVid, CVid over SVid connector */ #if 0 @@ -886,14 +851,13 @@ struct tvcard bttv_tvcards[] = { .has_radio = 1, .tuner_type = TUNER_PHILIPS_PAL, /* default for now, gpio reads BFFF06 for Pal bg+dk */ .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .audio_mode_gpio= winfast2000_audio, .has_remote = 1, }, [BTTV_BOARD_CHRONOS_VS2] = { .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II", .video_inputs = 4, - .audio_inputs = 3, + /* .audio_inputs= 3, */ .svhs = 2, .gpiomask = 0x1800, .muxsel = { 2, 3, 1, 1 }, @@ -902,14 +866,13 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, /* ---- card 0x24 ---------------------------------- */ [BTTV_BOARD_TYPHOON_TVIEW] = { .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner", .video_inputs = 4, - .audio_inputs = 3, + /* .audio_inputs= 3, */ .svhs = 2, .gpiomask = 0x1800, .muxsel = { 2, 3, 1, 1 }, @@ -918,13 +881,12 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .has_radio = 1, }, [BTTV_BOARD_PXELVWPLTVPRO] = { .name = "Prolink PixelView PlayTV pro", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xff, .muxsel = { 2, 3, 1, 1 }, @@ -934,12 +896,11 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_MAGICTVIEW063] = { .name = "Askey CPH06X TView99", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x551e00, .muxsel = { 2, 3, 1, 0 }, @@ -949,13 +910,12 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .has_remote = 1, }, [BTTV_BOARD_PINNACLE] = { .name = "Pinnacle PCTV Studio/Rave", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x03000F, .muxsel = { 2, 3, 1, 1 }, @@ -965,14 +925,13 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, /* ---- card 0x28 ---------------------------------- */ [BTTV_BOARD_STB2] = { .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 7, .muxsel = { 2, 3, 1, 1 }, @@ -982,14 +941,13 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .pll = PLL_28, .has_radio = 1, }, [BTTV_BOARD_AVPHONE98] = { .name = "AVerMedia TVPhone 98", .video_inputs = 3, - .audio_inputs = 4, + /* .audio_inputs= 4, */ .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, @@ -998,14 +956,13 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .has_radio = 1, .audio_mode_gpio= avermedia_tvphone_audio, }, [BTTV_BOARD_PV951] = { .name = "ProVideo PV951", /* pic16c54 */ .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0, .muxsel = { 2, 3, 1, 1}, @@ -1015,12 +972,11 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_ONAIR_TV] = { .name = "Little OnAir TV", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xe00b, .muxsel = { 2, 3, 1, 1 }, @@ -1029,15 +985,14 @@ struct tvcard bttv_tvcards[] = { .no_msp34xx = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, /* ---- card 0x2c ---------------------------------- */ [BTTV_BOARD_SIGMA_TVII_FM] = { .name = "Sigma TVII-FM", .video_inputs = 2, - .audio_inputs = 1, - .svhs = UNSET, + /* .audio_inputs= 1, */ + .svhs = NO_SVHS, .gpiomask = 3, .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 1, 1, 0, 2 }, @@ -1046,12 +1001,11 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_NONE, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_MATRIX_VISION2] = { .name = "MATRIX-Vision MV-Delta 2", .video_inputs = 5, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 3, .gpiomask = 0, .muxsel = { 2, 3, 1, 0, 0 }, @@ -1060,12 +1014,11 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_ZOLTRIX_GENIE] = { .name = "Zoltrix Genie TV/FM", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xbcf03f, .muxsel = { 2, 3, 1, 1 }, @@ -1075,12 +1028,11 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_TEMIC_4039FR5_NTSC, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_TERRATVRADIO] = { .name = "Terratec TV/Radio+", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x70000, .muxsel = { 2, 3, 1, 1 }, @@ -1091,7 +1043,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_35, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .has_radio = 1, }, @@ -1099,7 +1050,7 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_DYNALINK] = { .name = "Askey CPH03x/ Dynalink Magic TView", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, @@ -1109,12 +1060,11 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_GVBCTV3PCI] = { .name = "IODATA GV-BCTV3/PCI", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x010f00, .muxsel = {2, 3, 0, 0 }, @@ -1123,24 +1073,22 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_ALPS_TSHC6_NTSC, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .audio_mode_gpio= gvbctv3pci_audio, }, [BTTV_BOARD_PXELVWPLTVPAK] = { .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP", .video_inputs = 5, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 3, .gpiomask = 0xAA0000, - .muxsel = { 2,3,1,1,-1 }, - .digital_mode = DIGITAL_MODE_CAMERA, + .muxsel = { 2, 3, 1, 1, -1 }, + /* .digital_mode= DIGITAL_MODE_CAMERA, */ .gpiomux = { 0x20000, 0, 0x80000, 0x80000 }, .gpiomute = 0xa8000, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .has_remote = 1, /* GPIO wiring: (different from Rev.4C !) GPIO17: U4.A0 (first hef4052bt) @@ -1155,7 +1103,7 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_EAGLE] = { .name = "Eagle Wireless Capricorn2 (bt878A)", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 7, .muxsel = { 2, 0, 1, 1 }, @@ -1164,7 +1112,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = UNSET /* TUNER_ALPS_TMDH2_NTSC */, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, /* ---- card 0x34 ---------------------------------- */ @@ -1172,7 +1119,7 @@ struct tvcard bttv_tvcards[] = { /* David Härdeman */ .name = "Pinnacle PCTV Studio Pro", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 3, .gpiomask = 0x03000F, .muxsel = { 2, 3, 1, 1 }, @@ -1191,14 +1138,13 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_TVIEW_RDS_FM] = { /* Claas Langbehn , Sven Grothklags */ .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS", .video_inputs = 4, - .audio_inputs = 3, + /* .audio_inputs= 3, */ .svhs = 2, .gpiomask = 0x1c, .muxsel = { 2, 3, 1, 1 }, @@ -1208,7 +1154,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .has_radio = 1, }, [BTTV_BOARD_LIFETEC_9415] = { @@ -1219,7 +1164,7 @@ struct tvcard bttv_tvcards[] = { options tuner type=5 */ .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x18e0, .muxsel = { 2, 3, 1, 1 }, @@ -1232,14 +1177,13 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_BESTBUY_EASYTV] = { /* Miguel Angel Alvarez old Easy TV BT848 version (model CPH031) */ .name = "Askey CPH031/ BESTBUY Easy TV", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xF, .muxsel = { 2, 3, 1, 0 }, @@ -1249,7 +1193,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, /* ---- card 0x38 ---------------------------------- */ @@ -1257,7 +1200,7 @@ struct tvcard bttv_tvcards[] = { /* Gordon Heydon */ .name = "Askey CPH060/ Phoebe TV Master Only (No FM)", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xe00, .muxsel = { 2, 3, 1, 1}, @@ -1300,13 +1241,12 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_TEMIC_4036FY5_NTSC, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_ASKEY_CPH03X] = { /* Matti Mottus */ .name = "Askey CPH03x TV Capturer", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x03000F, .muxsel = { 2, 3, 1, 0 }, @@ -1315,7 +1255,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, /* ---- card 0x3c ---------------------------------- */ @@ -1323,8 +1262,8 @@ struct tvcard bttv_tvcards[] = { /* Philip Blundell */ .name = "Modular Technology MM100PCTV", .video_inputs = 2, - .audio_inputs = 2, - .svhs = UNSET, + /* .audio_inputs= 2, */ + .svhs = NO_SVHS, .gpiomask = 11, .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 2, 0, 0, 1 }, @@ -1332,13 +1271,12 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_35, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_GMV1] = { /* Adrian Cox @@ -1356,7 +1293,7 @@ struct tvcard bttv_tvcards[] = { special thanks to Informatica Mieres for providing the card */ .name = "Askey CPH061/ BESTBUY Easy TV (bt878)", .video_inputs = 3, - .audio_inputs = 2, + /* .audio_inputs= 2, */ .svhs = 2, .gpiomask = 0xFF, .muxsel = { 2, 3, 1, 0 }, @@ -1366,13 +1303,12 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_ATI_TVWONDER] = { /* Lukas Gebauer */ .name = "ATI TV-Wonder", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xf03f, .muxsel = { 2, 3, 1, 0 }, @@ -1381,7 +1317,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, /* ---- card 0x40 ---------------------------------- */ @@ -1389,8 +1324,8 @@ struct tvcard bttv_tvcards[] = { /* Lukas Gebauer */ .name = "ATI TV-Wonder VE", .video_inputs = 2, - .audio_inputs = 1, - .svhs = UNSET, + /* .audio_inputs= 1, */ + .svhs = NO_SVHS, .gpiomask = 1, .muxsel = { 2, 3, 0, 1 }, .gpiomux = { 0, 0, 1, 0 }, @@ -1398,13 +1333,12 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_FLYVIDEO2000] = { /* DeeJay */ .name = "IODATA GV-BCTV4/PCI", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x010f00, .muxsel = {2, 3, 0, 0 }, @@ -1451,7 +1383,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_SHARP_2U5JF5540_NTSC, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .audio_mode_gpio= gvbctv3pci_audio, }, @@ -1461,8 +1392,8 @@ struct tvcard bttv_tvcards[] = { /* try "insmod msp3400 simple=0" if you have * sound problems with this card. */ .video_inputs = 4, - .audio_inputs = 1, - .svhs = UNSET, + /* .audio_inputs= 1, */ + .svhs = NO_SVHS, .gpiomask = 0x4f8a00, /* 0x100000: 1=MSP enabled (0=disable again) * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */ @@ -1473,7 +1404,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = { 2, 3 ,0 ,1 }, .tuner_type = TUNER_MT2032, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .pll = PLL_28, .has_radio = 1, }, @@ -1482,8 +1412,8 @@ struct tvcard bttv_tvcards[] = { /* try "insmod msp3400 simple=0" if you have * sound problems with this card. */ .video_inputs = 4, - .audio_inputs = 1, - .svhs = UNSET, + /* .audio_inputs= 1, */ + .svhs = NO_SVHS, .gpiomask = 0x4f8a00, /* 0x100000: 1=MSP enabled (0=disable again) * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */ @@ -1494,7 +1424,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = { 2, 3 ,0 ,1 }, .tuner_type = TUNER_MT2032, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .pll = PLL_28, .has_radio = 1, }, @@ -1502,10 +1431,9 @@ struct tvcard bttv_tvcards[] = { /* Philip Blundell */ .name = "Active Imaging AIMMS", .video_inputs = 1, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .pll = PLL_28, .muxsel = { 2 }, .gpiomask = 0 @@ -1514,7 +1442,7 @@ struct tvcard bttv_tvcards[] = { /* Tomasz Pyra */ .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)", .video_inputs = 3, - .audio_inputs = 4, + /* .audio_inputs= 4, */ .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, @@ -1524,7 +1452,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_LG_PAL_I_FM, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .has_remote = 1, /* GPIO wiring: GPIO0: U4.A0 (hef4052bt) @@ -1537,14 +1464,13 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_FLYVIDEO98EZ] = { .name = "Lifeview FlyVideo 98EZ (capture only) LR51", .video_inputs = 4, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .svhs = 2, .muxsel = { 2, 3, 1, 1 }, /* AV1, AV2, SVHS, CVid adapter on SVHS */ .pll = PLL_28, .no_msp34xx = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, /* ---- card 0x48 ---------------------------------- */ @@ -1552,7 +1478,7 @@ struct tvcard bttv_tvcards[] = { /* Dariusz Kowalewski */ .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x3f, .muxsel = { 2, 3, 1, 1 }, @@ -1564,7 +1490,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .audio_mode_gpio= pvbt878p9b_audio, /* Note: not all cards have stereo */ .has_radio = 1, /* Note: not all cards have radio */ .has_remote = 1, @@ -1581,7 +1506,7 @@ struct tvcard bttv_tvcards[] = { /* you must jumper JP5 for the card to work */ .name = "Sensoray 311", .video_inputs = 5, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .svhs = 4, .gpiomask = 0, .muxsel = { 2, 3, 1, 0, 0 }, @@ -1589,14 +1514,13 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_RV605] = { /* Miguel Freitas */ .name = "RemoteVision MX (RV605)", .video_inputs = 16, - .audio_inputs = 0, - .svhs = UNSET, + /* .audio_inputs= 0, */ + .svhs = NO_SVHS, .gpiomask = 0x00, .gpiomask2 = 0x07ff, .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03, @@ -1605,13 +1529,12 @@ struct tvcard bttv_tvcards[] = { .no_tda9875 = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .muxsel_hook = rv605_muxsel, }, [BTTV_BOARD_POWERCLR_MTV878] = { .name = "Powercolor MTV878/ MTV878R/ MTV878F", .video_inputs = 3, - .audio_inputs = 2, + /* .audio_inputs= 2, */ .svhs = 2, .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */ .muxsel = { 2, 1, 1, }, @@ -1620,7 +1543,6 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .pll = PLL_28, .has_radio = 1, }, @@ -1630,7 +1552,7 @@ struct tvcard bttv_tvcards[] = { /* Masaki Suzuki */ .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x140007, .muxsel = { 2, 3, 1, 1 }, @@ -1638,14 +1560,13 @@ struct tvcard bttv_tvcards[] = { .gpiomute = 4, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .audio_mode_gpio= windvr_audio, }, [BTTV_BOARD_GRANDTEC_MULTI] = { .name = "GrandTec Multi Capture Card (Bt878)", .video_inputs = 4, - .audio_inputs = 0, - .svhs = UNSET, + /* .audio_inputs= 0, */ + .svhs = NO_SVHS, .gpiomask = 0, .muxsel = { 2, 3, 1, 0 }, .gpiomux = { 0 }, @@ -1654,12 +1575,11 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_KWORLD] = { .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF", .video_inputs = 4, - .audio_inputs = 3, + /* .audio_inputs= 3, */ .svhs = 2, .gpiomask = 7, .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */ @@ -1676,7 +1596,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and radio signal strength indicators work fine. */ .has_radio = 1, @@ -1694,26 +1613,24 @@ struct tvcard bttv_tvcards[] = { /* Arthur Tetzlaff-Deas, DSP Design Ltd */ .name = "DSP Design TCVIDEO", .video_inputs = 4, - .svhs = UNSET, + .svhs = NO_SVHS, .muxsel = { 2, 3, 1, 0 }, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, /* ---- card 0x50 ---------------------------------- */ [BTTV_BOARD_HAUPPAUGEPVR] = { .name = "Hauppauge WinTV PVR", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .muxsel = { 2, 0, 1, 1 }, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .gpiomask = 7, .gpiomux = {7}, @@ -1721,7 +1638,7 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_GVBCTV5PCI] = { .name = "IODATA GV-BCTV5/PCI", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x0f0f80, .muxsel = {2, 3, 1, 0 }, @@ -1731,20 +1648,18 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC_M, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .audio_mode_gpio= gvbctv5pci_audio, .has_radio = 1, }, [BTTV_BOARD_OSPREY1x0] = { .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */ .video_inputs = 4, /* id-inputs-clock */ - .audio_inputs = 0, + /* .audio_inputs= 0, */ .svhs = 3, .muxsel = { 3, 2, 0, 1 }, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1752,13 +1667,12 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY1x0_848] = { .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */ .video_inputs = 3, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .svhs = 2, .muxsel = { 2, 3, 1 }, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1768,13 +1682,12 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY101_848] = { .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */ .video_inputs = 2, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .svhs = 1, .muxsel = { 3, 1 }, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1782,13 +1695,12 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY1x1] = { .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */ .video_inputs = 1, - .audio_inputs = 0, - .svhs = UNSET, + /* .audio_inputs= 0, */ + .svhs = NO_SVHS, .muxsel = { 0 }, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1796,13 +1708,12 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY1x1_SVID] = { .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */ .video_inputs = 2, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .svhs = 1, .muxsel = { 0, 1 }, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1810,13 +1721,12 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY2xx] = { .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */ .video_inputs = 1, - .audio_inputs = 1, - .svhs = UNSET, + /* .audio_inputs= 1, */ + .svhs = NO_SVHS, .muxsel = { 0 }, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1826,13 +1736,12 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY2x0_SVID] = { .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */ .video_inputs = 2, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 1, .muxsel = { 0, 1 }, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1840,13 +1749,12 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY2x0] = { .name = "Osprey 210/220/230", /* 0x1(A|B)-04C0-C1 */ .video_inputs = 2, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 1, .muxsel = { 2, 3 }, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1854,13 +1762,12 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY500] = { .name = "Osprey 500", /* 500 */ .video_inputs = 2, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 1, .muxsel = { 2, 3 }, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1868,7 +1775,7 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY540] = { .name = "Osprey 540", /* 540 */ .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ #if 0 /* TODO ... */ .svhs = OSPREY540_SVID_ANALOG, .muxsel = { [OSPREY540_COMP_ANALOG] = 2, @@ -1877,7 +1784,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1891,13 +1797,12 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY2000] = { .name = "Osprey 2000", /* 2000 */ .video_inputs = 2, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 1, .muxsel = { 2, 3 }, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */ @@ -1906,11 +1811,10 @@ struct tvcard bttv_tvcards[] = { /* M G Berberich */ .name = "IDS Eagle", .video_inputs = 4, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .svhs = UNSET, + .svhs = NO_SVHS, .gpiomask = 0, .muxsel = { 0, 1, 2, 3 }, .muxsel_hook = eagle_muxsel, @@ -1921,11 +1825,10 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_PINNACLESAT] = { .name = "Pinnacle PCTV Sat", .video_inputs = 2, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .svhs = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1937,7 +1840,7 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_FORMAC_PROTV] = { .name = "Formac ProTV II (bt878)", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 3, .gpiomask = 2, /* TV, Comp1, Composite over SVID con, SVID */ @@ -1947,7 +1850,6 @@ struct tvcard bttv_tvcards[] = { .has_radio = 1, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, /* sound routing: GPIO=0x00,0x01,0x03: mute (?) 0x02: both TV and radio (tuner: FM1216/I) @@ -1961,8 +1863,8 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_MACHTV] = { .name = "MachTV", .video_inputs = 3, - .audio_inputs = 1, - .svhs = UNSET, + /* .audio_inputs= 1, */ + .svhs = NO_SVHS, .gpiomask = 7, .muxsel = { 2, 3, 1, 1}, .gpiomux = { 0, 1, 2, 3}, @@ -1970,13 +1872,12 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .pll = PLL_28, }, [BTTV_BOARD_EURESYS_PICOLO] = { .name = "Euresys Picolo", .video_inputs = 3, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .svhs = 2, .gpiomask = 0, .no_msp34xx = 1, @@ -1986,14 +1887,13 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_PV150] = { /* Luc Van Hoeylandt */ .name = "ProVideo PV150", /* 0x4f */ .video_inputs = 2, - .audio_inputs = 0, - .svhs = UNSET, + /* .audio_inputs= 0, */ + .svhs = NO_SVHS, .gpiomask = 0, .muxsel = { 2, 3 }, .gpiomux = { 0 }, @@ -2002,14 +1902,13 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_AD_TVK503] = { /* Hiroshi Takekawa */ /* This card lacks subsystem ID */ .name = "AD-TVK503", /* 0x63 */ .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x001e8007, .muxsel = { 2, 3, 1, 0 }, @@ -2021,7 +1920,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .audio_mode_gpio= adtvk503_audio, }, @@ -2029,7 +1927,7 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_HERCULES_SM_TV] = { .name = "Hercules Smart TV Stereo", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x00, .muxsel = { 2, 3, 1, 1 }, @@ -2038,7 +1936,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, /* Notes: - card lacks subsystem ID - stereo variant w/ daughter board with tda9874a @0xb0 @@ -2052,7 +1949,7 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_PACETV] = { .name = "Pace TV & Radio Card", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .muxsel = { 2, 3, 1, 1 }, /* Tuner, CVid, SVid, CVid over SVid connector */ .gpiomask = 0, @@ -2060,7 +1957,6 @@ struct tvcard bttv_tvcards[] = { .no_tda7432 = 1, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .has_radio = 1, .pll = PLL_28, /* Bt878, Bt832, FI1246 tuner; no pci subsystem id @@ -2074,11 +1970,10 @@ struct tvcard bttv_tvcards[] = { /* Chris Willing */ .name = "IVC-200", .video_inputs = 1, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .svhs = UNSET, + .svhs = NO_SVHS, .gpiomask = 0xdf, .muxsel = { 2 }, .pll = PLL_28, @@ -2086,11 +1981,10 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_IVCE8784] = { .name = "IVCE-8784", .video_inputs = 1, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .svhs = UNSET, + .svhs = NO_SVHS, .gpiomask = 0xdf, .muxsel = { 2 }, .pll = PLL_28, @@ -2098,11 +1992,10 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_XGUARD] = { .name = "Grand X-Guard / Trust 814PCI", .video_inputs = 16, - .audio_inputs = 0, - .svhs = UNSET, + /* .audio_inputs= 0, */ + .svhs = NO_SVHS, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .gpiomask2 = 0xff, .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 }, .muxsel_hook = xguard_muxsel, @@ -2116,7 +2009,7 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_NEBULA_DIGITV] = { .name = "Nebula Electronics DigiTV", .video_inputs = 1, - .svhs = UNSET, + .svhs = NO_SVHS, .muxsel = { 2, 3, 1, 0 }, .no_msp34xx = 1, .no_tda9875 = 1, @@ -2124,7 +2017,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .has_dvb = 1, .has_remote = 1, .gpiomask = 0x1b, @@ -2134,8 +2026,8 @@ struct tvcard bttv_tvcards[] = { /* Jorge Boncompte - DTI2 */ .name = "ProVideo PV143", .video_inputs = 4, - .audio_inputs = 0, - .svhs = UNSET, + /* .audio_inputs= 0, */ + .svhs = NO_SVHS, .gpiomask = 0, .muxsel = { 2, 3, 1, 0 }, .gpiomux = { 0 }, @@ -2144,13 +2036,12 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_VD009X1_VD011_MINIDIN] = { /* M.Klahr@phytec.de */ .name = "PHYTEC VD-009-X1 VD-011 MiniDIN (bt878)", .video_inputs = 4, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .svhs = 3, .gpiomask = 0x00, .muxsel = { 2, 3, 1, 0 }, @@ -2159,12 +2050,11 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_VD009X1_VD011_COMBI] = { .name = "PHYTEC VD-009-X1 VD-011 Combi (bt878)", .video_inputs = 4, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .svhs = 3, .gpiomask = 0x00, .muxsel = { 2, 3, 1, 1 }, @@ -2173,14 +2063,13 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, /* ---- card 0x6c ---------------------------------- */ [BTTV_BOARD_VD009_MINIDIN] = { .name = "PHYTEC VD-009 MiniDIN (bt878)", .video_inputs = 10, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .svhs = 9, .gpiomask = 0x00, .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio @@ -2192,12 +2081,11 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_VD009_COMBI] = { .name = "PHYTEC VD-009 Combi (bt878)", .video_inputs = 10, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .svhs = 9, .gpiomask = 0x00, .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio @@ -2209,16 +2097,14 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_IVC100] = { .name = "IVC-100", .video_inputs = 4, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .svhs = UNSET, + .svhs = NO_SVHS, .gpiomask = 0xdf, .muxsel = { 2, 3, 1, 0 }, .pll = PLL_28, @@ -2227,11 +2113,10 @@ struct tvcard bttv_tvcards[] = { /* IVC-120G - Alan Garfield */ .name = "IVC-120G", .video_inputs = 16, - .audio_inputs = 0, /* card has no audio */ + /* .audio_inputs= 0, */ .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .svhs = UNSET, /* card has no svhs */ + .svhs = NO_SVHS, /* card has no svhs */ .needs_tvaudio = 0, .no_msp34xx = 1, .no_tda9875 = 1, @@ -2247,12 +2132,11 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_PC_HDTV] = { .name = "pcHDTV HD-2000 TV", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .muxsel = { 2, 3, 1, 0 }, .tuner_type = TUNER_PHILIPS_FCV1236D, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .has_dvb = 1, }, [BTTV_BOARD_TWINHAN_DST] = { @@ -2262,14 +2146,13 @@ struct tvcard bttv_tvcards[] = { .no_tda7432 = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .no_video = 1, .has_dvb = 1, }, [BTTV_BOARD_WINFASTVC100] = { .name = "Winfast VC100", .video_inputs = 3, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .svhs = 1, .muxsel = { 3, 1, 1, 3 }, /* Vid In, SVid In, Vid over SVid in connector */ .no_msp34xx = 1, @@ -2277,13 +2160,12 @@ struct tvcard bttv_tvcards[] = { .no_tda7432 = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .pll = PLL_28, }, [BTTV_BOARD_TEV560] = { .name = "Teppro TEV-560/InterVision IV-560", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 3, .muxsel = { 2, 3, 1, 1 }, @@ -2291,7 +2173,6 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .pll = PLL_35, }, @@ -2299,11 +2180,10 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_SIMUS_GVC1100] = { .name = "SIMUS GVC1100", .video_inputs = 4, - .audio_inputs = 0, - .svhs = UNSET, + /* .audio_inputs= 0, */ + .svhs = NO_SVHS, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .pll = PLL_28, .muxsel = { 2, 2, 2, 2 }, .gpiomask = 0x3F, @@ -2321,15 +2201,14 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .has_remote = 1, }, [BTTV_BOARD_LMLBT4] = { /* http://linuxmedialabs.com */ .name = "LMLBT4", .video_inputs = 4, /* IN1,IN2,IN3,IN4 */ - .audio_inputs = 0, - .svhs = UNSET, + /* .audio_inputs= 0, */ + .svhs = NO_SVHS, .muxsel = { 2, 3, 1, 0 }, .no_msp34xx = 1, .no_tda9875 = 1, @@ -2337,16 +2216,14 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_TEKRAM_M205] = { /* Helmroos Harri */ .name = "Tekram M205 PRO", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .svhs = 2, .needs_tvaudio = 0, .gpiomask = 0x68, @@ -2361,7 +2238,7 @@ struct tvcard bttv_tvcards[] = { /* bt878 TV + FM without subsystem ID */ .name = "Conceptronic CONTVFMi", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x008007, .muxsel = { 2, 3, 1, 1 }, @@ -2371,7 +2248,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .has_remote = 1, .has_radio = 1, }, @@ -2382,8 +2258,8 @@ struct tvcard bttv_tvcards[] = { /*0x79 in bttv.h*/ .name = "Euresys Picolo Tetra", .video_inputs = 4, - .audio_inputs = 0, - .svhs = UNSET, + /* .audio_inputs= 0, */ + .svhs = NO_SVHS, .gpiomask = 0, .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/ .no_msp34xx = 1, @@ -2396,21 +2272,19 @@ struct tvcard bttv_tvcards[] = { .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/ .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_SPIRIT_TV] = { /* Spirit TV Tuner from http://spiritmodems.com.au */ /* Stafford Goodsell */ .name = "Spirit TV Tuner", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x0000000f, .muxsel = { 2, 1, 1 }, .gpiomux = { 0x02, 0x00, 0x00, 0x00 }, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, }, @@ -2421,7 +2295,6 @@ struct tvcard bttv_tvcards[] = { .svhs = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .muxsel = { 3 , 3 }, .no_msp34xx = 1, .no_tda9875 = 1, @@ -2445,43 +2318,40 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .has_dvb = 1, .no_gpioirq = 1, .has_remote = 1, }, [BTTV_BOARD_MATRIX_VISIONSQ] = { /* andre.schwarz@matrix-vision.de */ - .name = "MATRIX Vision Sigma-SQ", - .video_inputs = 16, - .audio_inputs = 0, - .svhs = UNSET, - .gpiomask = 0x0, - .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3 }, - .muxsel_hook = sigmaSQ_muxsel, - .gpiomux = { 0 }, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, + .name = "MATRIX Vision Sigma-SQ", + .video_inputs = 16, + /* .audio_inputs= 0, */ + .svhs = NO_SVHS, + .gpiomask = 0x0, + .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3 }, + .muxsel_hook = sigmaSQ_muxsel, + .gpiomux = { 0 }, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = TUNER_ABSENT, + .tuner_addr = ADDR_UNSET, }, [BTTV_BOARD_MATRIX_VISIONSLC] = { /* andre.schwarz@matrix-vision.de */ - .name = "MATRIX Vision Sigma-SLC", - .video_inputs = 4, - .audio_inputs = 0, - .svhs = UNSET, - .gpiomask = 0x0, - .muxsel = { 2, 2, 2, 2 }, - .muxsel_hook = sigmaSLC_muxsel, - .gpiomux = { 0 }, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, + .name = "MATRIX Vision Sigma-SLC", + .video_inputs = 4, + /* .audio_inputs= 0, */ + .svhs = NO_SVHS, + .gpiomask = 0x0, + .muxsel = { 2, 2, 2, 2 }, + .muxsel_hook = sigmaSLC_muxsel, + .gpiomux = { 0 }, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = TUNER_ABSENT, + .tuner_addr = ADDR_UNSET, }, /* BTTV_BOARD_APAC_VIEWCOMP */ [BTTV_BOARD_APAC_VIEWCOMP] = { @@ -2489,8 +2359,8 @@ struct tvcard bttv_tvcards[] = { /* bt878 TV + FM 0x00000000 subsystem ID */ .name = "APAC Viewcomp 878(AMAX)", .video_inputs = 2, - .audio_inputs = 1, - .svhs = UNSET, + /* .audio_inputs= 1, */ + .svhs = NO_SVHS, .gpiomask = 0xFF, .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 2, 0, 0, 0 }, @@ -2499,7 +2369,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */ .has_radio = 1, /* not every card has radio */ }, @@ -2516,13 +2385,12 @@ struct tvcard bttv_tvcards[] = { .has_dvb = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_VGEAR_MYVCD] = { /* Steven */ .name = "V-Gear MyVCD", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x3f, .muxsel = {2, 3, 1, 0 }, @@ -2532,7 +2400,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC_M, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .has_radio = 0, #if 0 .has_remote = 1, @@ -2542,12 +2409,11 @@ struct tvcard bttv_tvcards[] = { /* Rick C */ .name = "Super TV Tuner", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .muxsel = { 2, 3, 1, 0 }, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .gpiomask = 0x008007, .gpiomux = { 0, 0x000001,0,0 }, .needs_tvaudio = 1, @@ -2557,8 +2423,8 @@ struct tvcard bttv_tvcards[] = { /* Chris Fanning */ .name = "Tibet Systems 'Progress DVR' CS16", .video_inputs = 16, - .audio_inputs = 0, - .svhs = UNSET, + /* .audio_inputs= 0, */ + .svhs = NO_SVHS, .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, .pll = PLL_28, .no_msp34xx = 1, @@ -2566,7 +2432,6 @@ struct tvcard bttv_tvcards[] = { .no_tda7432 = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .muxsel_hook = tibetCS16_muxsel, }, [BTTV_BOARD_KODICOM_4400R] = { @@ -2583,11 +2448,10 @@ struct tvcard bttv_tvcards[] = { */ .name = "Kodicom 4400R (master)", .video_inputs = 16, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .svhs = UNSET, + .svhs = NO_SVHS, /* GPIO bits 0-9 used for analog switch: * 00 - 03: camera selector * 04 - 06: channel (controller) selector @@ -2614,11 +2478,10 @@ struct tvcard bttv_tvcards[] = { */ .name = "Kodicom 4400R (slave)", .video_inputs = 16, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .svhs = UNSET, + .svhs = NO_SVHS, .gpiomask = 0x010000, .no_gpioirq = 1, .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, @@ -2634,12 +2497,11 @@ struct tvcard bttv_tvcards[] = { /* Adlink RTV24 with special unlock codes */ .name = "Adlink RTV24", .video_inputs = 4, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .muxsel = { 2, 3, 1, 0 }, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .pll = PLL_28, }, /* ---- card 0x87---------------------------------- */ @@ -2648,9 +2510,8 @@ struct tvcard bttv_tvcards[] = { .name = "DViCO FusionHDTV 5 Lite", .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */ .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .muxsel = { 2, 3, 1 }, .gpiomask = 0x00e00007, @@ -2666,7 +2527,7 @@ struct tvcard bttv_tvcards[] = { /* Mauro Carvalho Chehab */ .name = "Acorp Y878F", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x01fe00, .muxsel = { 2, 3, 1, 1 }, @@ -2676,14 +2537,13 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_YMEC_TVF66T5_B_DFF, .tuner_addr = 0xc1 >>1, - .radio_addr = 0xc1 >>1, .has_radio = 1, }, /* ---- card 0x89 ---------------------------------- */ [BTTV_BOARD_CONCEPTRONIC_CTVFMI2] = { .name = "Conceptronic CTVFMi v2", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x001c0007, .muxsel = { 2, 3, 1, 1 }, @@ -2693,34 +2553,32 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_TENA_9533_DI, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .has_remote = 1, .has_radio = 1, }, /* ---- card 0x8a ---------------------------------- */ [BTTV_BOARD_PV_BT878P_2E] = { - .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)", - .video_inputs = 5, - .audio_inputs = 1, - .svhs = 3, - .gpiomask = 0x01fe00, - .muxsel = { 2,3,1,1,-1 }, - .digital_mode = DIGITAL_MODE_CAMERA, - .gpiomux = { 0x00400, 0x10400, 0x04400, 0x80000 }, - .gpiomute = 0x12400, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_LG_PAL_FM, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .has_remote = 1, + .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)", + .video_inputs = 5, + /* .audio_inputs= 1, */ + .svhs = 3, + .gpiomask = 0x01fe00, + .muxsel = { 2, 3, 1, 1, -1 }, + /* .digital_mode= DIGITAL_MODE_CAMERA, */ + .gpiomux = { 0x00400, 0x10400, 0x04400, 0x80000 }, + .gpiomute = 0x12400, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = TUNER_LG_PAL_FM, + .tuner_addr = ADDR_UNSET, + .has_remote = 1, }, /* ---- card 0x8b ---------------------------------- */ [BTTV_BOARD_PV_M4900] = { /* Sérgio Fortier */ .name = "Prolink PixelView PlayTV MPEG2 PV-M4900", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x3f, .muxsel = { 2, 3, 1, 1 }, @@ -2730,7 +2588,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_YMEC_TVF_5533MF, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .has_radio = 1, .has_remote = 1, }, @@ -2750,8 +2607,8 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY440] = { .name = "Osprey 440", .video_inputs = 4, - .audio_inputs = 2, /* this is meaningless */ - .svhs = UNSET, + /* .audio_inputs= 2, */ + .svhs = NO_SVHS, .muxsel = { 2, 3, 0, 1 }, /* 3,0,1 are guesses */ .gpiomask = 0x303, .gpiomute = 0x000, /* int + 32kHz */ @@ -2759,7 +2616,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -2768,7 +2624,7 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_ASOUND_SKYEYE] = { .name = "Asound Skyeye PCTV", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 15, .muxsel = { 2, 3, 1, 1 }, @@ -2778,13 +2634,12 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, /* ---- card 0x8e ---------------------------------- */ [BTTV_BOARD_SABRENT_TVFM] = { .name = "Sabrent TV-FM (bttv version)", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x108007, .muxsel = { 2, 3, 1, 1 }, @@ -2801,8 +2656,8 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_HAUPPAUGE_IMPACTVCB] = { .name = "Hauppauge ImpactVCB (bt878)", .video_inputs = 4, - .audio_inputs = 0, - .svhs = UNSET, + /* .audio_inputs= 0, */ + .svhs = NO_SVHS, .gpiomask = 0x0f, /* old: 7 */ .muxsel = { 0, 1, 3, 2 }, /* Composite 0-3 */ .no_msp34xx = 1, @@ -2810,7 +2665,6 @@ struct tvcard bttv_tvcards[] = { .no_tda7432 = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_MACHTV_MAGICTV] = { /* Julian Calaby @@ -2822,7 +2676,7 @@ struct tvcard bttv_tvcards[] = { .name = "MagicTV", /* rebranded MachTV */ .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 7, .muxsel = { 2, 3, 1, 1 }, @@ -2830,7 +2684,6 @@ struct tvcard bttv_tvcards[] = { .gpiomute = 4, .tuner_type = TUNER_TEMIC_4009FR5_PAL, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .pll = PLL_28, .has_radio = 1, .has_remote = 1, @@ -2838,31 +2691,28 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_SSAI_SECURITY] = { .name = "SSAI Security Video Interface", .video_inputs = 4, - .audio_inputs = 0, - .svhs = UNSET, + /* .audio_inputs= 0, */ + .svhs = NO_SVHS, .muxsel = { 0, 1, 2, 3 }, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_SSAI_ULTRASOUND] = { .name = "SSAI Ultrasound Video Interface", .video_inputs = 2, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .svhs = 1, .muxsel = { 2, 0, 1, 3 }, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, /* ---- card 0x94---------------------------------- */ [BTTV_BOARD_DVICO_FUSIONHDTV_2] = { .name = "DViCO FusionHDTV 2", .tuner_type = TUNER_PHILIPS_FCV1236D, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .muxsel = { 2, 3, 1 }, .gpiomask = 0x00e00007, @@ -2876,7 +2726,7 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_TYPHOON_TVTUNERPCI] = { .name = "Typhoon TV-Tuner PCI (50684)", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x3014f, .muxsel = { 2, 3, 1, 1 }, @@ -2886,24 +2736,22 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_GEOVISION_GV600] = { /* emhn@usb.ve */ - .name = "Geovision GV-600", - .video_inputs = 16, - .audio_inputs = 0, - .svhs = UNSET, - .gpiomask = 0x0, - .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2 }, - .muxsel_hook = geovision_muxsel, - .gpiomux = { 0 }, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, + .name = "Geovision GV-600", + .video_inputs = 16, + /* .audio_inputs= 0, */ + .svhs = NO_SVHS, + .gpiomask = 0x0, + .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2 }, + .muxsel_hook = geovision_muxsel, + .gpiomux = { 0 }, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = TUNER_ABSENT, + .tuner_addr = ADDR_UNSET, }, [BTTV_BOARD_KOZUMI_KTV_01C] = { /* Mauro Lacy @@ -2911,7 +2759,7 @@ struct tvcard bttv_tvcards[] = { .name = "Kozumi KTV-01C", .video_inputs = 3, - .audio_inputs = 1, + /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x008007, .muxsel = { 2, 3, 1, 1 }, @@ -2926,7 +2774,6 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* TCL MK3 */ .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .pll = PLL_28, .has_radio = 1, .has_remote = 1, @@ -2936,7 +2783,7 @@ struct tvcard bttv_tvcards[] = { Mauro Carvalho Chehab IR disabled bit 18/17 = 00 -> mute @@ -2950,7 +2797,6 @@ struct tvcard bttv_tvcards[] = { .gpiomute = 0, .tuner_type = TUNER_TCL_MF02GIP_5N, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, .pll = PLL_28, .has_radio = 1, .has_remote = 1, @@ -2959,8 +2805,8 @@ struct tvcard bttv_tvcards[] = { /* D.Heer@Phytec.de */ .name = "PHYTEC VD-012 (bt878)", .video_inputs = 4, - .audio_inputs = 0, - .svhs = UNSET, /* card has no s-video */ + /* .audio_inputs= 0, */ + .svhs = NO_SVHS, .gpiomask = 0x00, .muxsel = { 0, 2, 3, 1 }, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ @@ -2968,13 +2814,12 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_VD012_X1] = { /* D.Heer@Phytec.de */ .name = "PHYTEC VD-012-X1 (bt878)", .video_inputs = 4, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .svhs = 3, .gpiomask = 0x00, .muxsel = { 2, 3, 1 }, @@ -2983,13 +2828,12 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_VD012_X2] = { /* D.Heer@Phytec.de */ .name = "PHYTEC VD-012-X2 (bt878)", .video_inputs = 4, - .audio_inputs = 0, + /* .audio_inputs= 0, */ .svhs = 3, .gpiomask = 0x00, .muxsel = { 3, 2, 1 }, @@ -2998,7 +2842,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, } }; @@ -3612,7 +3455,8 @@ void __devinit bttv_init_card2(struct bttv *btv) bttv_call_i2c_clients(btv, TUNER_SET_CONFIG, &tda9887_cfg); } - btv->svhs = bttv_tvcards[btv->c.type].svhs; + btv->svhs = bttv_tvcards[btv->c.type].svhs == NO_SVHS ? + UNSET : bttv_tvcards[btv->c.type].svhs; if (svhs[btv->c.nr] != UNSET) btv->svhs = svhs[btv->c.nr]; if (remote[btv->c.nr] != UNSET) diff --git a/linux/drivers/media/video/bt8xx/bttv.h b/linux/drivers/media/video/bt8xx/bttv.h index 1fee79c55..6ba19f45b 100644 --- a/linux/drivers/media/video/bt8xx/bttv.h +++ b/linux/drivers/media/video/bt8xx/bttv.h @@ -193,10 +193,6 @@ #define WINVIEW_PT2254_DATA 0x20 #define WINVIEW_PT2254_STROBE 0x80 -/* digital_mode */ -#define DIGITAL_MODE_VIDEO 1 -#define DIGITAL_MODE_CAMERA 2 - struct bttv_core { /* device structs */ struct pci_dev *pci; @@ -212,19 +208,24 @@ struct bttv_core { struct bttv; -struct tvcard -{ +struct tvcard { char *name; - unsigned int video_inputs; - unsigned int audio_inputs; - unsigned int svhs; - unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO + void (*volume_gpio)(struct bttv *btv, __u16 volume); + void (*audio_mode_gpio)(struct bttv *btv, struct v4l2_tuner *tuner, int set); + void (*muxsel_hook)(struct bttv *btv, unsigned int input); + u32 gpiomask; u32 muxsel[16]; u32 gpiomux[4]; /* Tuner, Radio, external, internal */ u32 gpiomute; /* GPIO mute setting */ u32 gpiomask2; /* GPIO MUX mask */ + unsigned int tuner_type; + u8 tuner_addr; + u8 video_inputs; /* Number of inputs */ + unsigned int svhs:4; /* Which input is s-video */ +#define NO_SVHS 15 + /* i2c audio flags */ unsigned int no_msp34xx:1; unsigned int no_tda9875:1; @@ -232,28 +233,15 @@ struct tvcard unsigned int needs_tvaudio:1; unsigned int msp34xx_alt:1; - /* flag: video pci function is unused */ - unsigned int no_video:1; + unsigned int no_video:1; /* video pci function is unused */ unsigned int has_dvb:1; unsigned int has_remote:1; + unsigned int has_radio:1; unsigned int no_gpioirq:1; - - /* other settings */ - unsigned int pll; + unsigned int pll:2; #define PLL_NONE 0 #define PLL_28 1 #define PLL_35 2 - - unsigned int tuner_type; - unsigned int tuner_addr; - unsigned int radio_addr; - - unsigned int has_radio; - - void (*volume_gpio)(struct bttv *btv, __u16 volume); - void (*audio_mode_gpio)(struct bttv *btv, struct v4l2_tuner *tuner, int set); - - void (*muxsel_hook)(struct bttv *btv, unsigned int input); }; extern struct tvcard bttv_tvcards[]; -- cgit v1.2.3 From e418d7277c31fd429d55fb0b1686c5b61bda06cb Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 28 Jan 2009 16:32:59 -0800 Subject: bttv: rework the way digital inputs are indicated From: Trent Piepho The code was using a muxsel value of -1U to indicate a digital input. A couple places in were checking of muxsel < 0 to detect this, which doesn't work of course because muxsel is unsigned and can't be negative. Only a couple cards had digital inputs and it was always the last one, so for the card database create a one bit field that indicates the last input is digital. On init, this is used to set a new field in the bttv struct to the digital input's number or UNSET for none. This makes it easier to check if the current input is digital. Priority: normal Signed-off-by: Trent Piepho --- linux/drivers/media/video/bt8xx/bttv-cards.c | 11 ++++++++--- linux/drivers/media/video/bt8xx/bttv-driver.c | 2 +- linux/drivers/media/video/bt8xx/bttv-risc.c | 4 ++-- linux/drivers/media/video/bt8xx/bttv.h | 9 +++++---- linux/drivers/media/video/bt8xx/bttvp.h | 2 +- 5 files changed, 17 insertions(+), 11 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c index c6cdf79e8..b5eb8fecc 100644 --- a/linux/drivers/media/video/bt8xx/bttv-cards.c +++ b/linux/drivers/media/video/bt8xx/bttv-cards.c @@ -639,8 +639,9 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 3, /* .audio_inputs= 1, */ .svhs = NO_SVHS, + .has_dig_in = 1, .gpiomask = 7, - .muxsel = { 2, 3, -1 }, + .muxsel = { 2, 3, 0 }, /* input 2 is digital */ /* .digital_mode= DIGITAL_MODE_CAMERA, */ .gpiomux = { 0, 0, 0, 0 }, .no_msp34xx = 1, @@ -1080,8 +1081,9 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 5, /* .audio_inputs= 1, */ .svhs = 3, + .has_dig_in = 1, .gpiomask = 0xAA0000, - .muxsel = { 2, 3, 1, 1, -1 }, + .muxsel = { 2, 3, 1, 1, 0 }, /* input 4 is digital */ /* .digital_mode= DIGITAL_MODE_CAMERA, */ .gpiomux = { 0x20000, 0, 0x80000, 0x80000 }, .gpiomute = 0xa8000, @@ -2562,8 +2564,9 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 5, /* .audio_inputs= 1, */ .svhs = 3, + .has_dig_in = 1, .gpiomask = 0x01fe00, - .muxsel = { 2, 3, 1, 1, -1 }, + .muxsel = { 2, 3, 1, 1, 0 }, /* in 4 is digital */ /* .digital_mode= DIGITAL_MODE_CAMERA, */ .gpiomux = { 0x00400, 0x10400, 0x04400, 0x80000 }, .gpiomute = 0x12400, @@ -3455,6 +3458,8 @@ void __devinit bttv_init_card2(struct bttv *btv) bttv_call_i2c_clients(btv, TUNER_SET_CONFIG, &tda9887_cfg); } + btv->dig = bttv_tvcards[btv->c.type].has_dig_in ? + bttv_tvcards[btv->c.type].video_inputs - 1 : UNSET; btv->svhs = bttv_tvcards[btv->c.type].svhs == NO_SVHS ? UNSET : bttv_tvcards[btv->c.type].svhs; if (svhs[btv->c.nr] != UNSET) diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index 53be29350..fb57f00bd 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -1058,7 +1058,7 @@ static void bt848A_set_timing(struct bttv *btv) int table_idx = bttv_tvnorms[btv->tvnorm].sram; int fsc = bttv_tvnorms[btv->tvnorm].Fsc; - if (UNSET == bttv_tvcards[btv->c.type].muxsel[btv->input]) { + if (btv->input == btv->dig) { dprintk("bttv%d: load digital timing table (table_idx=%d)\n", btv->c.nr,table_idx); diff --git a/linux/drivers/media/video/bt8xx/bttv-risc.c b/linux/drivers/media/video/bt8xx/bttv-risc.c index 310924f77..1b9a6ab62 100644 --- a/linux/drivers/media/video/bt8xx/bttv-risc.c +++ b/linux/drivers/media/video/bt8xx/bttv-risc.c @@ -341,7 +341,7 @@ bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo, int totalwidth = tvnorm->totalwidth; int scaledtwidth = tvnorm->scaledtwidth; - if (bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) { + if (btv->input == btv->dig) { swidth = 720; totalwidth = 858; scaledtwidth = 858; @@ -395,7 +395,7 @@ bttv_calc_geo (struct bttv * btv, && crop->width == tvnorm->cropcap.defrect.width && crop->height == tvnorm->cropcap.defrect.height && width <= tvnorm->swidth /* see PAL-Nc et al */) - || bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) { + || btv->input == btv->dig) { bttv_calc_geo_old(btv, geo, width, height, both_fields, tvnorm); return; diff --git a/linux/drivers/media/video/bt8xx/bttv.h b/linux/drivers/media/video/bt8xx/bttv.h index 6ba19f45b..b6a753423 100644 --- a/linux/drivers/media/video/bt8xx/bttv.h +++ b/linux/drivers/media/video/bt8xx/bttv.h @@ -225,6 +225,10 @@ struct tvcard { u8 video_inputs; /* Number of inputs */ unsigned int svhs:4; /* Which input is s-video */ #define NO_SVHS 15 + unsigned int pll:2; +#define PLL_NONE 0 +#define PLL_28 1 +#define PLL_35 2 /* i2c audio flags */ unsigned int no_msp34xx:1; @@ -237,11 +241,8 @@ struct tvcard { unsigned int has_dvb:1; unsigned int has_remote:1; unsigned int has_radio:1; + unsigned int has_dig_in:1; /* Has digital input (always last input) */ unsigned int no_gpioirq:1; - unsigned int pll:2; -#define PLL_NONE 0 -#define PLL_28 1 -#define PLL_35 2 }; extern struct tvcard bttv_tvcards[]; diff --git a/linux/drivers/media/video/bt8xx/bttvp.h b/linux/drivers/media/video/bt8xx/bttvp.h index 71289d832..f888e0e59 100644 --- a/linux/drivers/media/video/bt8xx/bttvp.h +++ b/linux/drivers/media/video/bt8xx/bttvp.h @@ -331,7 +331,7 @@ struct bttv { unsigned int cardid; /* pci subsystem id (bt878 based ones) */ unsigned int tuner_type; /* tuner chip type */ unsigned int tda9887_conf; - unsigned int svhs; + unsigned int svhs, dig; struct bttv_pll_info pll; int triton1; int gpioirq; -- cgit v1.2.3 From 6eb8a20025c969225acb07f03bf2f6ddb4b70493 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 28 Jan 2009 16:32:59 -0800 Subject: bttv: clean up mux code for IVC-120G From: Trent Piepho The card data for BTTV_BOARD_IVC120 set muxsel to a bunch of bogus values (1 to 16), which the common mux code would use to set the Bt878's mux to some random value. Then the custom code in ivc120_muxsel() would change the Bt878's mux to the right value (always MUX0). Better to just make the muxsel data correct (all zeros, easy!) and get the mux right to begin with. Then the extra Bt878 mux setting code in ivc120_muxsel() can be eliminated (the rest of the code for the IVC-120G's external mux is still there of course). This will help me clean up muxsel for some other changes. It should also get rid of an unnecessary mux switch when changing from certain inputs to certain other inputs on the IVC-120G. Priority: normal Signed-off-by: Trent Piepho CC: Alan Garfield --- linux/drivers/media/video/bt8xx/bttv-cards.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c index b5eb8fecc..9e74fc100 100644 --- a/linux/drivers/media/video/bt8xx/bttv-cards.c +++ b/linux/drivers/media/video/bt8xx/bttv-cards.c @@ -2124,8 +2124,7 @@ struct tvcard bttv_tvcards[] = { .no_tda9875 = 1, .no_tda7432 = 1, .gpiomask = 0x00, - .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }, + .muxsel = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, .muxsel_hook = ivc120_muxsel, .pll = PLL_28, }, @@ -4496,8 +4495,7 @@ static void ivc120_muxsel(struct bttv *btv, unsigned int input) bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x02, ((matrix == 2) ? 0x03 : 0x00), 1); /* 9-12 */ - /* Selects MUX0 for input on the 878 */ - btaor((0)<<5, ~(3<<5), BT848_IFORM); + /* 878's MUX0 is already selected for input via muxsel values */ } -- cgit v1.2.3 From da23cfa879b6b08672c49c8c538876a977394199 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 28 Jan 2009 16:32:59 -0800 Subject: bttv: fix external mux for PHYTEC VD-009 From: Trent Piepho Old versions of the bttv driver would use the high nibble of an input's muxsel value to program the GPIO lines enabled via gpiomask2. Apparently this was supposed to be for switching external audio muxes. Anyway, the code that did this was removed sometime in the pre-git 2.6 series. These phytec boards used this feature to control an external video mux and I guess no one noticed when they removed the code. So add a muxsel_hook for these boards that does the necessary gpio setting. BTW, I doubt the needs_tvaudio setting for these cards is correct. Priority: normal Signed-off-by: Trent Piepho CC: Dirk Heer --- linux/drivers/media/video/bt8xx/bttv-cards.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c index 9e74fc100..105358be9 100644 --- a/linux/drivers/media/video/bt8xx/bttv-cards.c +++ b/linux/drivers/media/video/bt8xx/bttv-cards.c @@ -74,6 +74,8 @@ static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input); static void geovision_muxsel(struct bttv *btv, unsigned int input); +static void phytec_muxsel(struct bttv *btv, unsigned int input); + static int terratec_active_radio_upgrade(struct bttv *btv); static int tea5757_read(struct bttv *btv); static int tea5757_write(struct bttv *btv, int value); @@ -2074,10 +2076,9 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 0, */ .svhs = 9, .gpiomask = 0x00, - .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio - via the upper nibble of muxsel. here: used for - xternal video-mux */ - .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 }, + .gpiomask2 = 0x03, /* used for external vodeo mux */ + .muxsel = { 2, 2, 2, 2, 3, 3, 3, 3, 1, 0 }, + .muxsel_hook = phytec_muxsel, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 1, .pll = PLL_28, @@ -2090,10 +2091,9 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 0, */ .svhs = 9, .gpiomask = 0x00, - .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio - via the upper nibble of muxsel. here: used for - xternal video-mux */ - .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 }, + .gpiomask2 = 0x03, /* used for external vodeo mux */ + .muxsel = { 2, 2, 2, 2, 3, 3, 3, 3, 1, 1 }, + .muxsel_hook = phytec_muxsel, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 1, .pll = PLL_28, @@ -4579,6 +4579,16 @@ static void PXC200_muxsel(struct bttv *btv, unsigned int input) printk(KERN_DEBUG "bttv%d: setting input channel to:%d\n", btv->c.nr,(int)mux); } +static void phytec_muxsel(struct bttv *btv, unsigned int input) +{ + unsigned int mux = input % 4; + + if (input == btv->svhs) + mux = 0; + + gpio_bits(0x3, mux); +} + /* ----------------------------------------------------------------------- */ /* motherboard chipset specific stuff */ -- cgit v1.2.3 From a905506813537c4bad63dd73c94a04d6a71f777e Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 28 Jan 2009 16:32:59 -0800 Subject: bttv: fix external mux for RemoteVision MX From: Trent Piepho Old versions of the bttv driver would use the high nibble of an input's muxsel value to program the GPIO lines enabled via gpiomask2. Apparently this was supposed to be for switching external audio muxes. Anyway, the code that did this was removed sometime in the pre-git 2.6 series. The RemoteVision MX board used this feature to control an external video mux and I guess no one noticed when they removed the code. Move the extra gpio mux data out of the high nibble of muxsel and to rv605_muxsel(), then have that function set the gpio lines with it. From looking at the CD22M3494E datasheet, it seems like the mdelay(1) is a much longer delay than necessary. It looks like only around 20 ns is necessary. Priority: normal Signed-off-by: Trent Piepho CC: Miguel Freitas --- linux/drivers/media/video/bt8xx/bttv-cards.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c index 105358be9..cf7794de8 100644 --- a/linux/drivers/media/video/bt8xx/bttv-cards.c +++ b/linux/drivers/media/video/bt8xx/bttv-cards.c @@ -1527,8 +1527,7 @@ struct tvcard bttv_tvcards[] = { .svhs = NO_SVHS, .gpiomask = 0x00, .gpiomask2 = 0x07ff, - .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03, - 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 }, + .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, .no_msp34xx = 1, .no_tda9875 = 1, .tuner_type = TUNER_ABSENT, @@ -4229,6 +4228,11 @@ void tea5757_set_freq(struct bttv *btv, unsigned short freq) */ static void rv605_muxsel(struct bttv *btv, unsigned int input) { + static const u8 muxgpio[] = { 0x3, 0x1, 0x2, 0x4, 0xf, 0x7, 0xe, 0x0, + 0xd, 0xb, 0xc, 0x6, 0x9, 0x5, 0x8, 0xa }; + + gpio_bits(0x07f, muxgpio[input]); + /* reset all conections */ gpio_bits(0x200,0x200); mdelay(1); @@ -4236,7 +4240,6 @@ static void rv605_muxsel(struct bttv *btv, unsigned int input) mdelay(1); /* create a new connection */ - gpio_bits(0x480,0x080); gpio_bits(0x480,0x480); mdelay(1); gpio_bits(0x480,0x080); -- cgit v1.2.3 From 8a03ebcf3ee0e413a978ac074dcc4064ed94b681 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 28 Jan 2009 16:32:59 -0800 Subject: bttv: clean up mux code for IDS Eagle From: Trent Piepho This card apparently uses an external mux and the Bt878's mux should always be set to MUX2. The values for the external mux control bits were stored in the muxsel field. This meant that when changing inputs the driver would switch the Bt878's mux to whatever value the external mux was supposed to be set to, then eagle_muxsel() would switch it back to MUX2 and program the external mux. This creates an unnecessary switch of the Bt878's mux. So change muxsel to be 2 for each input. The external mux bits are just "input&3" so they don't really need to be stored anywhere. This also eliminates the last non-standard use of the muxsel data. Priority: normal Signed-off-by: Trent Piepho CC: M G Berberich --- linux/drivers/media/video/bt8xx/bttv-cards.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c index cf7794de8..dad17a8e5 100644 --- a/linux/drivers/media/video/bt8xx/bttv-cards.c +++ b/linux/drivers/media/video/bt8xx/bttv-cards.c @@ -1819,7 +1819,7 @@ struct tvcard bttv_tvcards[] = { .tuner_addr = ADDR_UNSET, .svhs = NO_SVHS, .gpiomask = 0, - .muxsel = { 0, 1, 2, 3 }, + .muxsel = { 2, 2, 2, 2 }, .muxsel_hook = eagle_muxsel, .no_msp34xx = 1, .no_tda9875 = 1, @@ -3138,8 +3138,7 @@ static void init_ids_eagle(struct bttv *btv) * has its own multiplexer */ static void eagle_muxsel(struct bttv *btv, unsigned int input) { - btaor((2)<<5, ~(3<<5), BT848_IFORM); - gpio_bits(3,bttv_tvcards[btv->c.type].muxsel[input&7]); + gpio_bits(3, input & 3); #if 0 /* svhs */ -- cgit v1.2.3 From c945cec9c8d31064b500e0dff54cd4b3b7ec5136 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 28 Jan 2009 16:32:59 -0800 Subject: bttv: shrink muxsel data in card database From: Trent Piepho Over half of the card database was used to store muxsel data. 64 bytes were used to store one 32 bit word for each of up to 16 inputs. The Bt8x8 only has two bits to control its mux, so muxsel data for 16 inputs will fit into a single 32 bit word. There were a couple cards that had special muxsel data that didn't fit in two bits, but I cleaned them up in earlier patches. Unfortunately, C doesn't allow us to have an array of bit fields. This makes initializing the structure more of a pain. But with some cpp magic, we can do it by changing: .muxsel = { 2, 3, 0, 1 }, .muxsel = { 2, 2, 2, 2, 3, 3, 3, 3, 1, 1 }, Into: .muxsel = MUXSEL(2, 3, 0, 1), .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 1), That's not so bad. MUXSEL is a fancy macro that packs the arguments (of which there can be one to sixteen!) into a single word two bits at a time. It's a compile time constant (a variadic function wouldn't be) so we can use it to initialize the structure. It's important the the arguments to the macro only be plain decimal integers. Stuff like "0x01", "(2)", or "MUX3" won't work properly. I also created an accessor function, bttv_muxsel(btv, input), that gets the mux bits for the selected input. It makes it cleaner to change the way the muxsel data is stored. This patch doesn't change the code size and decreases the datasegment by 9440 bytes. Priority: normal Signed-off-by: Trent Piepho --- linux/drivers/media/video/bt8xx/bttv-cards.c | 316 +++++++++++++------------- linux/drivers/media/video/bt8xx/bttv-driver.c | 2 +- linux/drivers/media/video/bt8xx/bttv.h | 30 ++- linux/drivers/media/video/bt8xx/bttvp.h | 6 + 4 files changed, 195 insertions(+), 159 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c index dad17a8e5..a2719c6bd 100644 --- a/linux/drivers/media/video/bt8xx/bttv-cards.c +++ b/linux/drivers/media/video/bt8xx/bttv-cards.c @@ -324,7 +324,7 @@ struct tvcard bttv_tvcards[] = { .name = " *** UNKNOWN/GENERIC *** ", .video_inputs = 4, .svhs = 2, - .muxsel = { 2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -334,7 +334,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 15, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 10, .needs_tvaudio = 1, @@ -347,7 +347,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 7, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, .needs_tvaudio = 1, @@ -360,7 +360,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 7, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 4, 0, 2, 3 }, .gpiomute = 1, .no_msp34xx = 1, @@ -378,7 +378,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 0, */ .svhs = 2, .gpiomask = 0, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0 }, .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, @@ -390,7 +390,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 3, - .muxsel = { 2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0, 1, 0, 1 }, .gpiomute = 3, .needs_tvaudio = 1, @@ -402,7 +402,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 3, /* .audio_inputs= 1, */ .svhs = 3, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomask = 0x0f, .gpiomux = { 0x0c, 0x04, 0x08, 0x04 }, /* 0x04 for some cards ?? */ @@ -418,7 +418,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 3, .gpiomask = 0, - .muxsel = { 2, 3, 1, 0, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0, 0), .gpiomux = { 0 }, .needs_tvaudio = 1, .tuner_type = TUNER_ABSENT, @@ -432,7 +432,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xc00, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0xc00, 0x800, 0x400 }, .gpiomute = 0xc00, .needs_tvaudio = 1, @@ -446,7 +446,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 3, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 1, 1, 2, 3 }, .needs_tvaudio = 0, .pll = PLL_28, @@ -459,7 +459,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x0f, /* old: 7 */ - .muxsel = { 2, 0, 1, 1 }, + .muxsel = MUXSEL(2, 0, 1, 1), .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, .needs_tvaudio = 1, @@ -473,7 +473,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x3014f, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20001,0x10001, 0, 0 }, .gpiomute = 10, .needs_tvaudio = 1, @@ -488,7 +488,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 15, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 13, 14, 11, 7 }, .needs_tvaudio = 1, .tuner_type = UNSET, @@ -500,7 +500,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 4, */ .svhs = 2, .gpiomask = 15, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 13, 14, 11, 7 }, .needs_tvaudio = 1, .msp34xx_alt = 1, @@ -516,7 +516,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 7, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */ .gpiomute = 4, .needs_tvaudio = 1, @@ -530,7 +530,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 15, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 1, 0 }, .gpiomute = 10, .needs_tvaudio = 1, @@ -545,7 +545,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x01fe00, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), #if 0 /* old */ .gpiomux = { 0x01c000, 0, 0x018000, 0x014000, 0x002000 }, @@ -565,7 +565,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x8300f8, - .muxsel = { 2, 3, 1, 1,0 }, + .muxsel = MUXSEL(2, 3, 1, 1, 0), .gpiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 }, .gpiomute = 0xcfa007, .needs_tvaudio = 1, @@ -580,7 +580,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 2, */ .svhs = 2, .gpiomask = 0, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 1, 0, 0, 0 }, .needs_tvaudio = 1, .tuner_type = UNSET, @@ -592,7 +592,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = NO_SVHS, .gpiomask = 0x8dff00, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0 }, .no_msp34xx = 1, .tuner_type = TUNER_ABSENT, @@ -605,7 +605,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 3, /* .audio_inputs= 3, */ .svhs = 2, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -615,7 +615,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 2, tuner, line in */ .svhs = 2, .gpiomask = 0x1800, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, .gpiomute = 0x1800, .pll = PLL_28, @@ -628,7 +628,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xc00, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 0x800, 0x400 }, .gpiomute = 0xc00, .needs_tvaudio = 1, @@ -643,7 +643,7 @@ struct tvcard bttv_tvcards[] = { .svhs = NO_SVHS, .has_dig_in = 1, .gpiomask = 7, - .muxsel = { 2, 3, 0 }, /* input 2 is digital */ + .muxsel = MUXSEL(2, 3, 0), /* input 2 is digital */ /* .digital_mode= DIGITAL_MODE_CAMERA, */ .gpiomux = { 0, 0, 0, 0 }, .no_msp34xx = 1, @@ -659,7 +659,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xe00, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = {0x400, 0x400, 0x400, 0x400 }, .gpiomute = 0xc00, .needs_tvaudio = 1, @@ -674,7 +674,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x1f0fff, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20000, 0x30000, 0x10000, 0 }, .gpiomute = 0x40000, .needs_tvaudio = 0, @@ -688,7 +688,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 3, .gpiomask = 7, - .muxsel = { 2, 0, 1, 1 }, + .muxsel = MUXSEL(2, 0, 1, 1), .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, .needs_tvaudio = 1, @@ -701,7 +701,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 2, */ .svhs = 2, .gpiomask = 0x1800, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, .gpiomute = 0x1800, .pll = PLL_28, @@ -716,7 +716,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x1f0fff, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20000, 0x30000, 0x10000, 0x00000 }, .gpiomute = 0x40000, .needs_tvaudio = 0, @@ -762,7 +762,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 1, /* was: 4 */ .gpiomask = 0, - .muxsel = { 2, 3, 1, 0, 0}, + .muxsel = MUXSEL(2, 3, 1, 0, 0), .gpiomux = { 0 }, .needs_tvaudio = 1, .tuner_type = TUNER_ABSENT, @@ -776,7 +776,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x1800, /* 0x8dfe00 */ - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0x0800, 0x1000, 0x1000 }, .gpiomute = 0x1800, .pll = PLL_28, @@ -789,7 +789,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 3, .gpiomask = 1, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 1, 0, 0, 0 }, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -803,7 +803,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 0, */ .svhs = 2, .gpiomask = 0, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0 }, .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, @@ -815,7 +815,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xffff00, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x500, 0, 0x300, 0x900 }, .gpiomute = 0x900, .needs_tvaudio = 1, @@ -828,7 +828,8 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 4, /* .audio_inputs= 1, */ .svhs = 2, - .muxsel = { 2, 3, 1, 1, 0 }, /* TV, CVid, SVid, CVid over SVid connector */ + /* TV, CVid, SVid, CVid over SVid connector */ + .muxsel = MUXSEL(2, 3, 1, 1, 0), #if 0 .gpiomask = 0xc33000, .gpiomux = { 0x422000,0x1000,0x0000,0x620000,0x800000 }, @@ -863,7 +864,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 3, */ .svhs = 2, .gpiomask = 0x1800, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, .gpiomute = 0x1800, .pll = PLL_28, @@ -878,7 +879,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 3, */ .svhs = 2, .gpiomask = 0x1800, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, .gpiomute = 0x1800, .pll = PLL_28, @@ -892,7 +893,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xff, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x21, 0x20, 0x24, 0x2c }, .gpiomute = 0x29, .no_msp34xx = 1, @@ -906,7 +907,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x551e00, - .muxsel = { 2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0x551400, 0x551200, 0, 0 }, .gpiomute = 0x551c00, .needs_tvaudio = 1, @@ -921,7 +922,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x03000F, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0xd0001, 0, 0 }, .gpiomute = 1, .needs_tvaudio = 0, @@ -937,7 +938,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 7, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 4, 0, 2, 3 }, .gpiomute = 1, .no_msp34xx = 1, @@ -953,7 +954,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 4, */ .svhs = 2, .gpiomask = 15, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 13, 4, 11, 7 }, .needs_tvaudio = 1, .pll = PLL_28, @@ -968,7 +969,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0, - .muxsel = { 2, 3, 1, 1}, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 0, 0}, .needs_tvaudio = 1, .no_msp34xx = 1, @@ -982,7 +983,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xe00b, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0xff9ff6, 0xff9ff6, 0xff1ff7, 0 }, .gpiomute = 0xff3ffc, .no_msp34xx = 1, @@ -997,7 +998,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = NO_SVHS, .gpiomask = 3, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 1, 1, 0, 2 }, .gpiomute = 3, .no_msp34xx = 1, @@ -1011,7 +1012,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 3, .gpiomask = 0, - .muxsel = { 2, 3, 1, 0, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0, 0), .gpiomux = { 0 }, .no_msp34xx = 1, .pll = PLL_28, @@ -1024,7 +1025,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xbcf03f, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0 }, .gpiomute = 0xbcb03f, .no_msp34xx = 1, @@ -1038,7 +1039,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x70000, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20000, 0x30000, 0x10000, 0 }, .gpiomute = 0x40000, .needs_tvaudio = 1, @@ -1056,7 +1057,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 15, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = {2,0,0,0 }, .gpiomute = 1, .needs_tvaudio = 1, @@ -1070,7 +1071,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x010f00, - .muxsel = {2, 3, 0, 0 }, + .muxsel = MUXSEL(2, 3, 0, 0), .gpiomux = {0x10000, 0, 0x10000, 0 }, .no_msp34xx = 1, .pll = PLL_28, @@ -1085,7 +1086,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 3, .has_dig_in = 1, .gpiomask = 0xAA0000, - .muxsel = { 2, 3, 1, 1, 0 }, /* input 4 is digital */ + .muxsel = MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */ /* .digital_mode= DIGITAL_MODE_CAMERA, */ .gpiomux = { 0x20000, 0, 0x80000, 0x80000 }, .gpiomute = 0xa8000, @@ -1110,7 +1111,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 7, - .muxsel = { 2, 0, 1, 1 }, + .muxsel = MUXSEL(2, 0, 1, 1), .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, .pll = PLL_28, @@ -1126,7 +1127,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 3, .gpiomask = 0x03000F, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 1, 0xd0001, 0, 0 }, .gpiomute = 10, /* sound path (5 sources): @@ -1151,7 +1152,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 3, */ .svhs = 2, .gpiomask = 0x1c, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 0x10, 8 }, .gpiomute = 4, .needs_tvaudio = 1, @@ -1171,7 +1172,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x18e0, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x0000,0x0800,0x1000,0x1000 }, .gpiomute = 0x18e0, /* For cards with tda9820/tda9821: @@ -1190,7 +1191,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xF, - .muxsel = { 2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 10, .needs_tvaudio = 0, @@ -1207,7 +1208,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 3, */ .svhs = 2, .gpiomask = 0x1800, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, .gpiomute = 0x1800, .pll = PLL_28, @@ -1223,7 +1224,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 0, */ .svhs = 1, .gpiomask = 0, - .muxsel = { 3, 1 }, + .muxsel = MUXSEL(3, 1), .gpiomux = { 0 }, .needs_tvaudio = 0, .no_msp34xx = 1, @@ -1238,7 +1239,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xe00, - .muxsel = { 2, 3, 1, 1}, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x400, 0x400, 0x400, 0x400 }, .gpiomute = 0x800, .needs_tvaudio = 1, @@ -1253,7 +1254,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x03000F, - .muxsel = { 2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 1, .pll = PLL_28, @@ -1269,7 +1270,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 2, */ .svhs = NO_SVHS, .gpiomask = 11, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0, 0, 1 }, .gpiomute = 8, .pll = PLL_35, @@ -1283,7 +1284,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 0, */ .svhs = 1, .gpiomask = 0xF, - .muxsel = { 2, 2 }, + .muxsel = MUXSEL(2, 2), .gpiomux = { }, .no_msp34xx = 1, .needs_tvaudio = 0, @@ -1300,7 +1301,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 2, */ .svhs = 2, .gpiomask = 0xFF, - .muxsel = { 2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 1, 0, 4, 4 }, .gpiomute = 9, .needs_tvaudio = 0, @@ -1315,7 +1316,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xf03f, - .muxsel = { 2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0xbffe, 0, 0xbfff, 0 }, .gpiomute = 0xbffe, .pll = PLL_28, @@ -1331,7 +1332,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = NO_SVHS, .gpiomask = 1, - .muxsel = { 2, 3, 0, 1 }, + .muxsel = MUXSEL(2, 3, 0, 1), .gpiomux = { 0, 0, 1, 0 }, .no_msp34xx = 1, .pll = PLL_28, @@ -1345,7 +1346,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 3, */ .svhs = 2, .gpiomask = 0x18e0, - .muxsel = { 2, 3, 0, 1 }, + .muxsel = MUXSEL(2, 3, 0, 1), /* Radio changed from 1e80 to 0x800 to make FlyVideo2000S in .hu happy (gm)*/ /* -dk-???: set mute=0x1800 for tda9874h daughterboard */ @@ -1365,7 +1366,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0xffff00, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x500, 0x500, 0x300, 0x900 }, .gpiomute = 0x900, .needs_tvaudio = 1, @@ -1381,7 +1382,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x010f00, - .muxsel = {2, 3, 0, 0 }, + .muxsel = MUXSEL(2, 3, 0, 0), .gpiomux = {0x10000, 0, 0x10000, 0 }, .no_msp34xx = 1, .pll = PLL_28, @@ -1405,7 +1406,7 @@ struct tvcard bttv_tvcards[] = { .gpiomute = 0x947fff, /* tvtuner, radio, external,internal, mute, stereo * tuner, Composit, SVid, Composit-on-Svid-adapter */ - .muxsel = { 2, 3 ,0 ,1 }, + .muxsel = MUXSEL(2, 3, 0, 1), .tuner_type = TUNER_MT2032, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -1425,7 +1426,7 @@ struct tvcard bttv_tvcards[] = { .gpiomute = 0x947fff, /* tvtuner, radio, external,internal, mute, stereo * tuner, Composit, SVid, Composit-on-Svid-adapter */ - .muxsel = { 2, 3 ,0 ,1 }, + .muxsel = MUXSEL(2, 3, 0, 1), .tuner_type = TUNER_MT2032, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -1439,7 +1440,7 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .pll = PLL_28, - .muxsel = { 2 }, + .muxsel = MUXSEL(2), .gpiomask = 0 }, [BTTV_BOARD_PV_BT878P_PLUS] = { @@ -1449,7 +1450,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 4, */ .svhs = 2, .gpiomask = 15, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 11, 7 }, /* TV and Radio with same GPIO ! */ .gpiomute = 13, .needs_tvaudio = 1, @@ -1470,7 +1471,8 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 4, /* .audio_inputs= 0, */ .svhs = 2, - .muxsel = { 2, 3, 1, 1 }, /* AV1, AV2, SVHS, CVid adapter on SVHS */ + /* AV1, AV2, SVHS, CVid adapter on SVHS */ + .muxsel = MUXSEL(2, 3, 1, 1), .pll = PLL_28, .no_msp34xx = 1, .tuner_type = TUNER_ABSENT, @@ -1485,7 +1487,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x3f, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x01, 0x00, 0x03, 0x03 }, .gpiomute = 0x09, .needs_tvaudio = 1, @@ -1513,7 +1515,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 0, */ .svhs = 4, .gpiomask = 0, - .muxsel = { 2, 3, 1, 0, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0, 0), .gpiomux = { 0 }, .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, @@ -1527,7 +1529,7 @@ struct tvcard bttv_tvcards[] = { .svhs = NO_SVHS, .gpiomask = 0x00, .gpiomask2 = 0x07ff, - .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3), .no_msp34xx = 1, .no_tda9875 = 1, .tuner_type = TUNER_ABSENT, @@ -1540,7 +1542,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 2, */ .svhs = 2, .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */ - .muxsel = { 2, 1, 1, }, + .muxsel = MUXSEL(2, 1, 1), .gpiomux = { 0, 1, 2, 2 }, .gpiomute = 4, .needs_tvaudio = 0, @@ -1558,7 +1560,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x140007, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, .tuner_type = TUNER_PHILIPS_NTSC, @@ -1571,7 +1573,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 0, */ .svhs = NO_SVHS, .gpiomask = 0, - .muxsel = { 2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0 }, .needs_tvaudio = 0, .no_msp34xx = 1, @@ -1585,7 +1587,8 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 3, */ .svhs = 2, .gpiomask = 7, - .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */ + /* Tuner, SVid, SVHS, SVid to SVHS connector */ + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 4, 4 },/* Yes, this tuner uses the same audio output for TV and FM radio! * This card lacks external Audio In, so we mute it on Ext. & Int. * The PCB can take a sbx1637/sbx1673, wiring unknown. @@ -1617,7 +1620,7 @@ struct tvcard bttv_tvcards[] = { .name = "DSP Design TCVIDEO", .video_inputs = 4, .svhs = NO_SVHS, - .muxsel = { 2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -1629,7 +1632,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 4, /* .audio_inputs= 1, */ .svhs = 2, - .muxsel = { 2, 0, 1, 1 }, + .muxsel = MUXSEL(2, 0, 1, 1), .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, @@ -1644,7 +1647,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x0f0f80, - .muxsel = {2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = {0x030000, 0x010000, 0, 0 }, .gpiomute = 0x020000, .no_msp34xx = 1, @@ -1659,7 +1662,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 4, /* id-inputs-clock */ /* .audio_inputs= 0, */ .svhs = 3, - .muxsel = { 3, 2, 0, 1 }, + .muxsel = MUXSEL(3, 2, 0, 1), .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -1672,7 +1675,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 3, /* .audio_inputs= 0, */ .svhs = 2, - .muxsel = { 2, 3, 1 }, + .muxsel = MUXSEL(2, 3, 1), .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -1687,7 +1690,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 2, /* .audio_inputs= 0, */ .svhs = 1, - .muxsel = { 3, 1 }, + .muxsel = MUXSEL(3, 1), .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -1700,7 +1703,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 1, /* .audio_inputs= 0, */ .svhs = NO_SVHS, - .muxsel = { 0 }, + .muxsel = MUXSEL(0), .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -1713,7 +1716,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 2, /* .audio_inputs= 0, */ .svhs = 1, - .muxsel = { 0, 1 }, + .muxsel = MUXSEL(0, 1), .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -1726,7 +1729,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 1, /* .audio_inputs= 1, */ .svhs = NO_SVHS, - .muxsel = { 0 }, + .muxsel = MUXSEL(0), .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -1741,7 +1744,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 2, /* .audio_inputs= 1, */ .svhs = 1, - .muxsel = { 0, 1 }, + .muxsel = MUXSEL(0, 1), .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -1754,7 +1757,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 2, /* .audio_inputs= 1, */ .svhs = 1, - .muxsel = { 2, 3 }, + .muxsel = MUXSEL(2, 3), .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -1767,7 +1770,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 2, /* .audio_inputs= 1, */ .svhs = 1, - .muxsel = { 2, 3 }, + .muxsel = MUXSEL(2, 3), .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -1802,7 +1805,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 2, /* .audio_inputs= 1, */ .svhs = 1, - .muxsel = { 2, 3 }, + .muxsel = MUXSEL(2, 3), .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -1819,7 +1822,7 @@ struct tvcard bttv_tvcards[] = { .tuner_addr = ADDR_UNSET, .svhs = NO_SVHS, .gpiomask = 0, - .muxsel = { 2, 2, 2, 2 }, + .muxsel = MUXSEL(2, 2, 2, 2), .muxsel_hook = eagle_muxsel, .no_msp34xx = 1, .no_tda9875 = 1, @@ -1835,7 +1838,7 @@ struct tvcard bttv_tvcards[] = { .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, - .muxsel = { 3, 1 }, + .muxsel = MUXSEL(3, 1), .pll = PLL_28, .no_gpioirq = 1, .has_dvb = 1, @@ -1847,7 +1850,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 3, .gpiomask = 2, /* TV, Comp1, Composite over SVID con, SVID */ - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 2, 0, 0 }, .pll = PLL_28, .has_radio = 1, @@ -1869,7 +1872,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = NO_SVHS, .gpiomask = 7, - .muxsel = { 2, 3, 1, 1}, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 3}, .gpiomute = 4, .needs_tvaudio = 1, @@ -1886,7 +1889,7 @@ struct tvcard bttv_tvcards[] = { .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, - .muxsel = { 2, 0, 1}, + .muxsel = MUXSEL(2, 0, 1), .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -1898,7 +1901,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 0, */ .svhs = NO_SVHS, .gpiomask = 0, - .muxsel = { 2, 3 }, + .muxsel = MUXSEL(2, 3), .gpiomux = { 0 }, .needs_tvaudio = 0, .no_msp34xx = 1, @@ -1914,7 +1917,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x001e8007, - .muxsel = { 2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), /* Tuner, Radio, external, internal, off, on */ .gpiomux = { 0x08, 0x0f, 0x0a, 0x08 }, .gpiomute = 0x0f, @@ -1933,7 +1936,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x00, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_28, @@ -1954,7 +1957,8 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 4, /* .audio_inputs= 1, */ .svhs = 2, - .muxsel = { 2, 3, 1, 1 }, /* Tuner, CVid, SVid, CVid over SVid connector */ + /* Tuner, CVid, SVid, CVid over SVid connector */ + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomask = 0, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1978,7 +1982,7 @@ struct tvcard bttv_tvcards[] = { .tuner_addr = ADDR_UNSET, .svhs = NO_SVHS, .gpiomask = 0xdf, - .muxsel = { 2 }, + .muxsel = MUXSEL(2), .pll = PLL_28, }, [BTTV_BOARD_IVCE8784] = { @@ -1989,7 +1993,7 @@ struct tvcard bttv_tvcards[] = { .tuner_addr = ADDR_UNSET, .svhs = NO_SVHS, .gpiomask = 0xdf, - .muxsel = { 2 }, + .muxsel = MUXSEL(2), .pll = PLL_28, }, [BTTV_BOARD_XGUARD] = { @@ -2000,7 +2004,7 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .gpiomask2 = 0xff, - .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 }, + .muxsel = MUXSEL(2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0), .muxsel_hook = xguard_muxsel, .no_msp34xx = 1, .no_tda9875 = 1, @@ -2013,7 +2017,7 @@ struct tvcard bttv_tvcards[] = { .name = "Nebula Electronics DigiTV", .video_inputs = 1, .svhs = NO_SVHS, - .muxsel = { 2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -2032,7 +2036,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 0, */ .svhs = NO_SVHS, .gpiomask = 0, - .muxsel = { 2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0 }, .needs_tvaudio = 0, .no_msp34xx = 1, @@ -2047,7 +2051,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 0, */ .svhs = 3, .gpiomask = 0x00, - .muxsel = { 2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 0, .pll = PLL_28, @@ -2060,7 +2064,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 0, */ .svhs = 3, .gpiomask = 0x00, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 0, .pll = PLL_28, @@ -2076,7 +2080,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 9, .gpiomask = 0x00, .gpiomask2 = 0x03, /* used for external vodeo mux */ - .muxsel = { 2, 2, 2, 2, 3, 3, 3, 3, 1, 0 }, + .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 0), .muxsel_hook = phytec_muxsel, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 1, @@ -2091,7 +2095,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 9, .gpiomask = 0x00, .gpiomask2 = 0x03, /* used for external vodeo mux */ - .muxsel = { 2, 2, 2, 2, 3, 3, 3, 3, 1, 1 }, + .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 1), .muxsel_hook = phytec_muxsel, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 1, @@ -2107,7 +2111,7 @@ struct tvcard bttv_tvcards[] = { .tuner_addr = ADDR_UNSET, .svhs = NO_SVHS, .gpiomask = 0xdf, - .muxsel = { 2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), .pll = PLL_28, }, [BTTV_BOARD_IVC120] = { @@ -2123,7 +2127,7 @@ struct tvcard bttv_tvcards[] = { .no_tda9875 = 1, .no_tda7432 = 1, .gpiomask = 0x00, - .muxsel = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + .muxsel = MUXSEL(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), .muxsel_hook = ivc120_muxsel, .pll = PLL_28, }, @@ -2134,7 +2138,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 4, /* .audio_inputs= 1, */ .svhs = 2, - .muxsel = { 2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), .tuner_type = TUNER_PHILIPS_FCV1236D, .tuner_addr = ADDR_UNSET, .has_dvb = 1, @@ -2154,7 +2158,8 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 3, /* .audio_inputs= 0, */ .svhs = 1, - .muxsel = { 3, 1, 1, 3 }, /* Vid In, SVid In, Vid over SVid in connector */ + /* Vid In, SVid In, Vid over SVid in connector */ + .muxsel = MUXSEL(3, 1, 1, 3), .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -2168,7 +2173,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 3, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 1, 1, 1, 1 }, .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_PAL, @@ -2185,7 +2190,7 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .pll = PLL_28, - .muxsel = { 2, 2, 2, 2 }, + .muxsel = MUXSEL(2, 2, 2, 2), .gpiomask = 0x3F, .muxsel_hook = gvc1100_muxsel, }, @@ -2195,7 +2200,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 3, .svhs = 2, .gpiomask = 0x008007, - .muxsel = { 2, 3, 0, 0 }, + .muxsel = MUXSEL(2, 3, 0, 0), .gpiomux = { 0, 0, 0, 0 }, .gpiomute = 0x000003, .pll = PLL_28, @@ -2209,7 +2214,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 4, /* IN1,IN2,IN3,IN4 */ /* .audio_inputs= 0, */ .svhs = NO_SVHS, - .muxsel = { 2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -2227,7 +2232,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .needs_tvaudio = 0, .gpiomask = 0x68, - .muxsel = { 2, 3, 1 }, + .muxsel = MUXSEL(2, 3, 1), .gpiomux = { 0x68, 0x68, 0x61, 0x61 }, .pll = PLL_28, }, @@ -2241,7 +2246,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x008007, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 2 }, .gpiomute = 3, .needs_tvaudio = 0, @@ -2265,7 +2270,8 @@ struct tvcard bttv_tvcards[] = { .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, - .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/ + /*878A input is always MUX0, see above.*/ + .muxsel = MUXSEL(2, 2, 2, 2), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .pll = PLL_28, .needs_tvaudio = 0, @@ -2281,7 +2287,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x0000000f, - .muxsel = { 2, 1, 1 }, + .muxsel = MUXSEL(2, 1, 1), .gpiomux = { 0x02, 0x00, 0x00, 0x00 }, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, @@ -2295,7 +2301,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .muxsel = { 3 , 3 }, + .muxsel = MUXSEL(3, 3), .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -2311,7 +2317,7 @@ struct tvcard bttv_tvcards[] = { .name = "AverMedia AverTV DVB-T 761", .video_inputs = 2, .svhs = 1, - .muxsel = { 3, 1, 2, 0 }, /* Comp0, S-Video, ?, ? */ + .muxsel = MUXSEL(3, 1, 2, 0), /* Comp0, S-Video, ?, ? */ .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -2329,8 +2335,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 0, */ .svhs = NO_SVHS, .gpiomask = 0x0, - .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3 }, + .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3), .muxsel_hook = sigmaSQ_muxsel, .gpiomux = { 0 }, .no_msp34xx = 1, @@ -2345,7 +2350,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 0, */ .svhs = NO_SVHS, .gpiomask = 0x0, - .muxsel = { 2, 2, 2, 2 }, + .muxsel = MUXSEL(2, 2, 2, 2), .muxsel_hook = sigmaSLC_muxsel, .gpiomux = { 0 }, .no_msp34xx = 1, @@ -2362,7 +2367,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = NO_SVHS, .gpiomask = 0xFF, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 10, .needs_tvaudio = 0, @@ -2393,7 +2398,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x3f, - .muxsel = {2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = {0x31, 0x31, 0x31, 0x31 }, .gpiomute = 0x31, .no_msp34xx = 1, @@ -2411,7 +2416,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 4, /* .audio_inputs= 1, */ .svhs = 2, - .muxsel = { 2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, .gpiomask = 0x008007, @@ -2425,7 +2430,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 16, /* .audio_inputs= 0, */ .svhs = NO_SVHS, - .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, + .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), .pll = PLL_28, .no_msp34xx = 1, .no_tda9875 = 1, @@ -2462,7 +2467,7 @@ struct tvcard bttv_tvcards[] = { */ .gpiomask = 0x0003ff, .no_gpioirq = 1, - .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3), .pll = PLL_28, .no_msp34xx = 1, .no_tda7432 = 1, @@ -2484,7 +2489,7 @@ struct tvcard bttv_tvcards[] = { .svhs = NO_SVHS, .gpiomask = 0x010000, .no_gpioirq = 1, - .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3), .pll = PLL_28, .no_msp34xx = 1, .no_tda7432 = 1, @@ -2499,7 +2504,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 4, /* .audio_inputs= 1, */ .svhs = 2, - .muxsel = { 2, 3, 1, 0 }, + .muxsel = MUXSEL(2, 3, 1, 0), .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -2513,7 +2518,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 3, /* .audio_inputs= 1, */ .svhs = 2, - .muxsel = { 2, 3, 1 }, + .muxsel = MUXSEL(2, 3, 1), .gpiomask = 0x00e00007, .gpiomux = { 0x00400005, 0, 0x00000001, 0 }, .gpiomute = 0x00c00007, @@ -2530,7 +2535,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x01fe00, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 }, .gpiomute = 0x002000, .needs_tvaudio = 1, @@ -2546,7 +2551,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x001c0007, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 2 }, .gpiomute = 3, .needs_tvaudio = 0, @@ -2564,7 +2569,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 3, .has_dig_in = 1, .gpiomask = 0x01fe00, - .muxsel = { 2, 3, 1, 1, 0 }, /* in 4 is digital */ + .muxsel = MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */ /* .digital_mode= DIGITAL_MODE_CAMERA, */ .gpiomux = { 0x00400, 0x10400, 0x04400, 0x80000 }, .gpiomute = 0x12400, @@ -2582,7 +2587,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x3f, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x21, 0x20, 0x24, 0x2c }, .gpiomute = 0x29, .no_msp34xx = 1, @@ -2610,7 +2615,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 4, /* .audio_inputs= 2, */ .svhs = NO_SVHS, - .muxsel = { 2, 3, 0, 1 }, /* 3,0,1 are guesses */ + .muxsel = MUXSEL(2, 3, 0, 1), /* 3,0,1 are guesses */ .gpiomask = 0x303, .gpiomute = 0x000, /* int + 32kHz */ .gpiomux = { 0, 0, 0x000, 0x100}, @@ -2628,7 +2633,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 15, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 1, .needs_tvaudio = 1, @@ -2643,7 +2648,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x108007, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 100000, 100002, 100002, 100000 }, .no_msp34xx = 1, .no_tda9875 = 1, @@ -2660,7 +2665,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 0, */ .svhs = NO_SVHS, .gpiomask = 0x0f, /* old: 7 */ - .muxsel = { 0, 1, 3, 2 }, /* Composite 0-3 */ + .muxsel = MUXSEL(0, 1, 3, 2), /* Composite 0-3 */ .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -2680,7 +2685,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 7, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, .tuner_type = TUNER_TEMIC_4009FR5_PAL, @@ -2694,7 +2699,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 4, /* .audio_inputs= 0, */ .svhs = NO_SVHS, - .muxsel = { 0, 1, 2, 3 }, + .muxsel = MUXSEL(0, 1, 2, 3), .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -2703,7 +2708,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 2, /* .audio_inputs= 0, */ .svhs = 1, - .muxsel = { 2, 0, 1, 3 }, + .muxsel = MUXSEL(2, 0, 1, 3), .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -2715,7 +2720,7 @@ struct tvcard bttv_tvcards[] = { .video_inputs = 3, /* .audio_inputs= 1, */ .svhs = 2, - .muxsel = { 2, 3, 1 }, + .muxsel = MUXSEL(2, 3, 1), .gpiomask = 0x00e00007, .gpiomux = { 0x00400005, 0, 0x00000001, 0 }, .gpiomute = 0x00c00007, @@ -2730,7 +2735,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x3014f, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20001,0x10001, 0, 0 }, .gpiomute = 10, .needs_tvaudio = 1, @@ -2745,8 +2750,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 0, */ .svhs = NO_SVHS, .gpiomask = 0x0, - .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2 }, + .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), .muxsel_hook = geovision_muxsel, .gpiomux = { 0 }, .no_msp34xx = 1, @@ -2763,7 +2767,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .gpiomask = 0x008007, - .muxsel = { 2, 3, 1, 1 }, + .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 2 }, /* CONTVFMi */ #if 0 .gpiomux = { 0, 1, 2, 3 }, /* MagicTV */ @@ -2793,7 +2797,7 @@ struct tvcard bttv_tvcards[] = { 11 -> internal audio input */ .gpiomask = 0x060040, - .muxsel = { 2, 3, 3 }, + .muxsel = MUXSEL(2, 3, 3), .gpiomux = { 0x60000, 0x60000, 0x20000, 0x20000 }, .gpiomute = 0, .tuner_type = TUNER_TCL_MF02GIP_5N, @@ -2809,7 +2813,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 0, */ .svhs = NO_SVHS, .gpiomask = 0x00, - .muxsel = { 0, 2, 3, 1 }, + .muxsel = MUXSEL(0, 2, 3, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 0, .pll = PLL_28, @@ -2823,7 +2827,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 0, */ .svhs = 3, .gpiomask = 0x00, - .muxsel = { 2, 3, 1 }, + .muxsel = MUXSEL(2, 3, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 0, .pll = PLL_28, @@ -2837,7 +2841,7 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 0, */ .svhs = 3, .gpiomask = 0x00, - .muxsel = { 3, 2, 1 }, + .muxsel = MUXSEL(3, 2, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 0, .pll = PLL_28, diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index fb57f00bd..bdbd9b97a 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -1160,7 +1160,7 @@ video_mux(struct bttv *btv, unsigned int input) btand(~BT848_CONTROL_COMP, BT848_E_CONTROL); btand(~BT848_CONTROL_COMP, BT848_O_CONTROL); } - mux = bttv_tvcards[btv->c.type].muxsel[input] & 3; + mux = bttv_muxsel(btv, input); btaor(mux<<5, ~(3<<5), BT848_IFORM); dprintk(KERN_DEBUG "bttv%d: video mux: input=%d mux=%d\n", btv->c.nr,input,mux); diff --git a/linux/drivers/media/video/bt8xx/bttv.h b/linux/drivers/media/video/bt8xx/bttv.h index b6a753423..3a065b8a4 100644 --- a/linux/drivers/media/video/bt8xx/bttv.h +++ b/linux/drivers/media/video/bt8xx/bttv.h @@ -207,15 +207,16 @@ struct bttv_core { struct bttv; - struct tvcard { char *name; void (*volume_gpio)(struct bttv *btv, __u16 volume); void (*audio_mode_gpio)(struct bttv *btv, struct v4l2_tuner *tuner, int set); void (*muxsel_hook)(struct bttv *btv, unsigned int input); + /* MUX bits for each input, two bits per input starting with the LSB */ + u32 muxsel; /* Use MUXSEL() to set */ + u32 gpiomask; - u32 muxsel[16]; u32 gpiomux[4]; /* Tuner, Radio, external, internal */ u32 gpiomute; /* GPIO mute setting */ u32 gpiomask2; /* GPIO MUX mask */ @@ -247,6 +248,31 @@ struct tvcard { extern struct tvcard bttv_tvcards[]; +/* + * This bit of cpp voodoo is used to create a macro with a variable number of + * arguments (1 to 16). It will pack each argument into a word two bits at a + * time. It can't be a function because it needs to be compile time constant to + * initialize structures. Since each argument must fit in two bits, it's ok + * that they are changed to octal. One should not use hex number, macros, or + * anything else with this macro. Just use plain integers from 0 to 3. + */ +#define _MUXSELf(a) 0##a << 30 +#define _MUXSELe(a, b...) 0##a << 28 | _MUXSELf(b) +#define _MUXSELd(a, b...) 0##a << 26 | _MUXSELe(b) +#define _MUXSELc(a, b...) 0##a << 24 | _MUXSELd(b) +#define _MUXSELb(a, b...) 0##a << 22 | _MUXSELc(b) +#define _MUXSELa(a, b...) 0##a << 20 | _MUXSELb(b) +#define _MUXSEL9(a, b...) 0##a << 18 | _MUXSELa(b) +#define _MUXSEL8(a, b...) 0##a << 16 | _MUXSEL9(b) +#define _MUXSEL7(a, b...) 0##a << 14 | _MUXSEL8(b) +#define _MUXSEL6(a, b...) 0##a << 12 | _MUXSEL7(b) +#define _MUXSEL5(a, b...) 0##a << 10 | _MUXSEL6(b) +#define _MUXSEL4(a, b...) 0##a << 8 | _MUXSEL5(b) +#define _MUXSEL3(a, b...) 0##a << 6 | _MUXSEL4(b) +#define _MUXSEL2(a, b...) 0##a << 4 | _MUXSEL3(b) +#define _MUXSEL1(a, b...) 0##a << 2 | _MUXSEL2(b) +#define MUXSEL(a, b...) (a | _MUXSEL1(b)) + /* identification / initialization of the card */ extern void bttv_idcard(struct bttv *btv); extern void bttv_init_card1(struct bttv *btv); diff --git a/linux/drivers/media/video/bt8xx/bttvp.h b/linux/drivers/media/video/bt8xx/bttvp.h index f888e0e59..b5eaf03ae 100644 --- a/linux/drivers/media/video/bt8xx/bttvp.h +++ b/linux/drivers/media/video/bt8xx/bttvp.h @@ -466,6 +466,12 @@ struct bttv { extern unsigned int bttv_num; extern struct bttv bttvs[BTTV_MAX]; +static inline unsigned int bttv_muxsel(const struct bttv *btv, + unsigned int input) +{ + return (bttv_tvcards[btv->c.type].muxsel >> (input * 2)) & 3; +} + #endif #define btwrite(dat,adr) writel((dat), btv->bt848_mmio+(adr)) -- cgit v1.2.3 From e2b4212172d81f17f5e4741766f032d06e83ce4f Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 28 Jan 2009 16:32:59 -0800 Subject: bttv: dynamically allocate device data From: Trent Piepho The bttv driver had static array of structures for up to 16 possible bttv devices, even though few users have more than one or two. The structures were quite large and this resulted in a huge BSS segment. Change the driver to allocate the bttv device data dynamically, which changes "struct bttv bttvs[BTTV_MAX]" to "struct bttv *bttvs[BTTV_MAX]". It would be nice to get ride of "bttvs" entirely but there are some complications with gpio access from the audio & mpeg drivers. To help bttvs removal along anyway, I changed the open() methods use the video device's drvdata to get the driver data instead of looking it up in the bttvs array. This is also more efficient. Some WARN_ON()s are added in cases the device node exists by the bttv device doesn't, which I don't think should be possible. The gpio access functions need to check if bttvs[card] is NULL now. Though calling them on a non-existent card in the first place is wrong, but hard to solve given the fundamental problems in how the gpio access code works. This patch reduces the bss size by 66560 bytes on ia32. Overall change is a reduction of 66398 bytes, as the WARN_ON()s add some 198 bytes. Priority: normal Signed-off-by: Trent Piepho --- linux/drivers/media/video/bt8xx/bttv-driver.c | 45 ++++++++++----------------- linux/drivers/media/video/bt8xx/bttv-if.c | 18 ++++++++--- linux/drivers/media/video/bt8xx/bttvp.h | 2 +- 3 files changed, 31 insertions(+), 34 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index bdbd9b97a..ab202761b 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -58,7 +58,7 @@ unsigned int bttv_num; /* number of Bt848s in use */ -struct bttv bttvs[BTTV_MAX]; +struct bttv *bttvs[BTTV_MAX]; unsigned int bttv_debug; unsigned int bttv_verbose = 1; @@ -3245,29 +3245,19 @@ err: static int bttv_open(struct file *file) { int minor = video_devdata(file)->minor; - struct bttv *btv = NULL; + struct bttv *btv = video_drvdata(file); struct bttv_fh *fh; enum v4l2_buf_type type = 0; - unsigned int i; dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor); lock_kernel(); - for (i = 0; i < bttv_num; i++) { - if (bttvs[i].video_dev && - bttvs[i].video_dev->minor == minor) { - btv = &bttvs[i]; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - break; - } - if (bttvs[i].vbi_dev && - bttvs[i].vbi_dev->minor == minor) { - btv = &bttvs[i]; - type = V4L2_BUF_TYPE_VBI_CAPTURE; - break; - } - } - if (NULL == btv) { + if (btv->video_dev->minor == minor) { + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + } else if (btv->vbi_dev->minor == minor) { + type = V4L2_BUF_TYPE_VBI_CAPTURE; + } else { + WARN_ON(1); unlock_kernel(); return -ENODEV; } @@ -3457,20 +3447,14 @@ static struct video_device bttv_video_template = { static int radio_open(struct file *file) { int minor = video_devdata(file)->minor; - struct bttv *btv = NULL; + struct bttv *btv = video_drvdata(file); struct bttv_fh *fh; - unsigned int i; dprintk("bttv: open minor=%d\n",minor); lock_kernel(); - for (i = 0; i < bttv_num; i++) { - if (bttvs[i].radio_dev && bttvs[i].radio_dev->minor == minor) { - btv = &bttvs[i]; - break; - } - } - if (NULL == btv) { + WARN_ON(btv->radio_dev && btv->radio_dev->minor != minor); + if (!btv->radio_dev || btv->radio_dev->minor != minor) { unlock_kernel(); return -ENODEV; } @@ -4235,6 +4219,7 @@ static struct video_device *vdev_init(struct bttv *btv, vfd->parent = &btv->c.pci->dev; vfd->release = video_device_release; vfd->debug = bttv_debug; + video_set_drvdata(vfd, btv); snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)", btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "", type_name, bttv_tvcards[btv->c.type].name); @@ -4349,8 +4334,7 @@ static int __devinit bttv_probe(struct pci_dev *dev, if (bttv_num == BTTV_MAX) return -ENOMEM; printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num); - btv=&bttvs[bttv_num]; - memset(btv,0,sizeof(*btv)); + bttvs[bttv_num] = btv = kzalloc(sizeof(*btv), GFP_KERNEL); btv->c.nr = bttv_num; sprintf(btv->c.name,"bttv%d",btv->c.nr); @@ -4554,6 +4538,9 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev) pci_resource_len(btv->c.pci,0)); pci_set_drvdata(pci_dev, NULL); + bttvs[btv->c.nr] = NULL; + kfree(btv); + return; } diff --git a/linux/drivers/media/video/bt8xx/bttv-if.c b/linux/drivers/media/video/bt8xx/bttv-if.c index ecf07988c..a6a540dc9 100644 --- a/linux/drivers/media/video/bt8xx/bttv-if.c +++ b/linux/drivers/media/video/bt8xx/bttv-if.c @@ -47,7 +47,10 @@ struct pci_dev* bttv_get_pcidev(unsigned int card) { if (card >= bttv_num) return NULL; - return bttvs[card].c.pci; + if (!bttvs[card]) + return NULL; + + return bttvs[card]->c.pci; } @@ -59,7 +62,10 @@ int bttv_gpio_enable(unsigned int card, unsigned long mask, unsigned long data) return -EINVAL; } - btv = &bttvs[card]; + btv = bttvs[card]; + if (!btv) + return -ENODEV; + gpio_inout(mask,data); if (bttv_gpio) bttv_gpio_tracking(btv,"extern enable"); @@ -74,7 +80,9 @@ int bttv_read_gpio(unsigned int card, unsigned long *data) return -EINVAL; } - btv = &bttvs[card]; + btv = bttvs[card]; + if (!btv) + return -ENODEV; if(btv->shutdown) { return -ENODEV; @@ -94,7 +102,9 @@ int bttv_write_gpio(unsigned int card, unsigned long mask, unsigned long data) return -EINVAL; } - btv = &bttvs[card]; + btv = bttvs[card]; + if (!btv) + return -ENODEV; /* prior setting BT848_GPIO_REG_INP is (probably) not needed because direct input is set on init */ diff --git a/linux/drivers/media/video/bt8xx/bttvp.h b/linux/drivers/media/video/bt8xx/bttvp.h index b5eaf03ae..20b1ad68a 100644 --- a/linux/drivers/media/video/bt8xx/bttvp.h +++ b/linux/drivers/media/video/bt8xx/bttvp.h @@ -464,7 +464,7 @@ struct bttv { /* our devices */ #define BTTV_MAX 32 extern unsigned int bttv_num; -extern struct bttv bttvs[BTTV_MAX]; +extern struct bttv *bttvs[BTTV_MAX]; static inline unsigned int bttv_muxsel(const struct bttv *btv, unsigned int input) -- cgit v1.2.3 From 9cbec50918322f2de1c4b1879c4d5fc5e5064be9 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 29 Jan 2009 08:59:45 +0100 Subject: gspca - sonixj: Sensor mt9v111 added. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 223 +++++++++++++++++++++++++++---- 1 file changed, 196 insertions(+), 27 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index abe26dc7f..33cbd7945 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -46,7 +46,7 @@ struct sd { u8 red; u8 gamma; u8 vflip; /* ov7630 only */ - u8 infrared; /* mi0360 only */ + u8 infrared; /* mt9v111 only */ s8 ag_cnt; #define AG_CNT_START 13 @@ -61,10 +61,11 @@ struct sd { #define SENSOR_HV7131R 0 #define SENSOR_MI0360 1 #define SENSOR_MO4000 2 -#define SENSOR_OM6802 3 -#define SENSOR_OV7630 4 -#define SENSOR_OV7648 5 -#define SENSOR_OV7660 6 +#define SENSOR_MT9V111 3 +#define SENSOR_OM6802 4 +#define SENSOR_OV7630 5 +#define SENSOR_OV7648 6 +#define SENSOR_OV7660 7 u8 i2c_base; }; @@ -206,7 +207,7 @@ static struct ctrl sd_ctrls[] = { .set = sd_setvflip, .get = sd_getvflip, }, -/* mi0360 only */ +/* mt9v111 only */ #define INFRARED_IDX 7 { { @@ -228,18 +229,20 @@ static struct ctrl sd_ctrls[] = { static __u32 ctrl_dis[] = { (1 << INFRARED_IDX) | (1 << VFLIP_IDX), /* SENSOR_HV7131R 0 */ - (1 << VFLIP_IDX), + (1 << INFRARED_IDX) | (1 << VFLIP_IDX), /* SENSOR_MI0360 1 */ (1 << INFRARED_IDX) | (1 << VFLIP_IDX), /* SENSOR_MO4000 2 */ + (1 << AUTOGAIN_IDX), + /* SENSOR_MT9V111 3 */ (1 << INFRARED_IDX) | (1 << VFLIP_IDX), - /* SENSOR_OM6802 3 */ + /* SENSOR_OM6802 4 */ (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX), - /* SENSOR_OV7630 4 */ + /* SENSOR_OV7630 5 */ (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), - /* SENSOR_OV7648 5 */ + /* SENSOR_OV7648 6 */ (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), - /* SENSOR_OV7660 6 */ + /* SENSOR_OV7660 7 */ }; static const struct v4l2_pix_format vga_mode[] = { @@ -294,6 +297,17 @@ static const u8 sn_mo4000[0x1c] = { 0x08, 0x00, 0x00, 0x00 }; +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, +/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ + 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40, +/* reg18 reg19 reg1a reg1b */ + 0x06, 0x00, 0x00, 0x00 +}; + static const u8 sn_om6802[0x1c] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20, @@ -343,6 +357,7 @@ static const u8 *sn_tb[] = { sn_hv7131, sn_mi0360, sn_mo4000, + sn_mt9v111, sn_om6802, sn_ov7630, sn_ov7648, @@ -355,7 +370,7 @@ static const u8 gamma_def[17] = { }; #if 0 -static const u8 gamma_hv7131[17] = { +static const u8 gamma_hv7131r[17] = { 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d, 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5 }; @@ -402,7 +417,7 @@ static const u8 hv7131r_sensor_init[][8] = { static const u8 mi0360_sensor_init[][8] = { {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10}, {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10}, {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10}, @@ -476,6 +491,38 @@ static const u8 mo4000_sensor_init[][8] = { {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, {} }; +static const u8 mt9v111_sensor_init[][8] = { + {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */ + /* delay 20 ms */ + {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 */ + {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */ + {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */ + {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */ + {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */ + {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */ + {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */ + {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */ + {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */ + {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */ + {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */ + {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}, + /*******/ + {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xb1, 0x5c, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10}, /* shutter width */ + {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */ + {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */ + /*******/ + {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */ + {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */ + {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */ + {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */ + {} +}; static const u8 om6802_sensor_init[][8] = { {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10}, {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10}, @@ -742,7 +789,7 @@ static void reg_w1(struct gspca_dev *gspca_dev, u16 value, u8 data) { - PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data); + PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data); gspca_dev->usb_buf[0] = data; usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), @@ -758,7 +805,7 @@ static void reg_w(struct gspca_dev *gspca_dev, const u8 *buffer, int len) { - PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..", + PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..", value, buffer[0], buffer[1]); #ifdef GSPCA_DEBUG if (len > USB_BUF_SZ) { @@ -838,7 +885,7 @@ static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg) reg_r(gspca_dev, 0x0a, 5); } -static int probesensor(struct gspca_dev *gspca_dev) +static int hv7131r_probe(struct gspca_dev *gspca_dev) { i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */ msleep(10); @@ -860,6 +907,52 @@ static int probesensor(struct gspca_dev *gspca_dev) return -ENODEV; } +static int mi0360_probe(struct gspca_dev *gspca_dev) +{ + int i, j; + u16 val; + static const u8 probe_tb[][4][8] = { + { + {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, + {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10} + }, + { + {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, + {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, + {} + }, + }; + + for (i = 0; i < ARRAY_SIZE(probe_tb); i++) { + reg_w1(gspca_dev, 0x17, 0x62); + reg_w1(gspca_dev, 0x01, 0x08); + for (j = 0; j < 3; j++) + i2c_w8(gspca_dev, probe_tb[i][j]); + msleep(2); + reg_r(gspca_dev, 0x0a, 5); + val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; + if (probe_tb[i][3][0] != 0) + i2c_w8(gspca_dev, probe_tb[i][3]); + reg_w1(gspca_dev, 0x01, 0x29); + reg_w1(gspca_dev, 0x17, 0x42); + if (val != 0xffff) + break; + } + switch (val) { + case 0x823a: + PDEBUG(D_PROBE, "Sensor mt9v111"); + return SENSOR_MT9V111; + case 0x8243: + PDEBUG(D_PROBE, "Sensor mi0360"); + return SENSOR_MI0360; + } + PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val); + return SENSOR_MI0360; +} + static int configure_gpio(struct gspca_dev *gspca_dev, const u8 *sn9c1xx) { @@ -897,6 +990,12 @@ static int configure_gpio(struct gspca_dev *gspca_dev, reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); switch (sd->sensor) { + case SENSOR_MT9V111: + reg_w1(gspca_dev, 0x01, 0x61); + reg_w1(gspca_dev, 0x17, 0x61); + reg_w1(gspca_dev, 0x01, 0x60); + reg_w1(gspca_dev, 0x01, 0x40); + break; case SENSOR_OM6802: reg_w1(gspca_dev, 0x02, 0x71); reg_w1(gspca_dev, 0x01, 0x42); @@ -934,7 +1033,7 @@ static int configure_gpio(struct gspca_dev *gspca_dev, reg_w1(gspca_dev, 0x17, 0x61); reg_w1(gspca_dev, 0x01, 0x42); if (sd->sensor == SENSOR_HV7131R) { - if (probesensor(gspca_dev) < 0) + if (hv7131r_probe(gspca_dev) < 0) return -ENODEV; } break; @@ -975,6 +1074,19 @@ static void mo4000_InitSensor(struct gspca_dev *gspca_dev) } } +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; @@ -1092,11 +1204,21 @@ static int sd_init(struct gspca_dev *gspca_dev) case BRIDGE_SN9C105: if (regF1 != 0x11) return -ENODEV; + if (sd->sensor == SENSOR_MI0360) { + sd->sensor = mi0360_probe(gspca_dev); + if (sd->sensor == SENSOR_MT9V111) + sd->i2c_base = 0x5c; + } reg_w(gspca_dev, 0x01, regGpio, 2); break; case BRIDGE_SN9C120: if (regF1 != 0x12) return -ENODEV; + if (sd->sensor == SENSOR_MI0360) { + sd->sensor = mi0360_probe(gspca_dev); + if (sd->sensor == SENSOR_MT9V111) + sd->i2c_base = 0x5c; + } regGpio[1] = 0x70; reg_w(gspca_dev, 0x01, regGpio, 2); break; @@ -1131,7 +1253,7 @@ static u32 setexposure(struct gspca_dev *gspca_dev, break; } case SENSOR_MI0360: { - u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */ + u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */ { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 }; static const u8 doit[] = /* update sensor */ { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 }; @@ -1167,12 +1289,35 @@ static u32 setexposure(struct gspca_dev *gspca_dev, | ((expo & 0x0003) << 4); i2c_w8(gspca_dev, expoMo10); i2c_w8(gspca_dev, gainMo); - PDEBUG(D_CONF, "set exposure %d", + PDEBUG(D_FRAM, "set exposure %d", ((expoMo10[3] & 0x07) << 10) | (expoMof[3] << 2) | ((expoMo10[3] & 0x30) >> 4)); break; } + case SENSOR_MT9V111: { + u8 expo_c1[] = + { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 }; +#if 0 + static const u8 c2[] = + { 0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10 }; + static const u8 c3[] = + { 0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10 }; +#endif + + if (expo > 0x0280) + expo = 0x0280; + else if (expo < 0x0040) + expo = 0x0040; + expo_c1[3] = expo >> 8; + expo_c1[4] = expo; + i2c_w8(gspca_dev, expo_c1); +#if 0 + i2c_w8(gspca_dev, expo_c2); + i2c_w8(gspca_dev, expo_c3); +#endif + break; + } case SENSOR_OM6802: { u8 gainOm[] = { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 }; @@ -1184,7 +1329,7 @@ static u32 setexposure(struct gspca_dev *gspca_dev, gainOm[3] = expo >> 2; i2c_w8(gspca_dev, gainOm); reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f); - PDEBUG(D_CONF, "set exposure %d", gainOm[3]); + PDEBUG(D_FRAM, "set exposure %d", gainOm[3]); break; } } @@ -1212,6 +1357,10 @@ static void setbrightness(struct gspca_dev *gspca_dev) expo = sd->brightness >> 4; sd->exposure = setexposure(gspca_dev, expo); break; + case SENSOR_MT9V111: + expo = sd->brightness >> 8; + sd->exposure = setexposure(gspca_dev, expo); + break; case SENSOR_OM6802: expo = sd->brightness >> 6; sd->exposure = setexposure(gspca_dev, expo); @@ -1219,7 +1368,8 @@ static void setbrightness(struct gspca_dev *gspca_dev) break; } - reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */ + if (sd->sensor != SENSOR_MT9V111) + reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */ } static void setcontrast(struct gspca_dev *gspca_dev) @@ -1342,6 +1492,9 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0xc9, 0x3c); reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); switch (sd->sensor) { + case SENSOR_MT9V111: + reg17 = 0xe0; + break; case SENSOR_OV7630: reg17 = 0xe2; break; @@ -1368,14 +1521,18 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */ reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]); #if 0 - if (sd->sensor == SENSOR_HV7131R) - reg_w(gspca_dev, 0x20, gamma_hv7131, sizeof gamma_hv7131); + if (sd->sensor == SENSOR_HV7131R || sd->sensor == SENSOR_MT9V111) + reg_w(gspca_dev, 0x20, gamma_hv7131r, sizeof gamma_hv7131r); else #endif setgamma(gspca_dev); for (i = 0; i < 8; i++) reg_w(gspca_dev, 0x84, reg84, sizeof reg84); switch (sd->sensor) { + case SENSOR_MT9V111: + reg_w1(gspca_dev, 0x9a, 0x07); + reg_w1(gspca_dev, 0x99, 0x59); + break; case SENSOR_OV7648: reg_w1(gspca_dev, 0x9a, 0x0a); reg_w1(gspca_dev, 0x99, 0x60); @@ -1415,6 +1572,14 @@ static int sd_start(struct gspca_dev *gspca_dev) /* reg1 = 0x06; * 640 clk 24Mz (done) */ } break; + case SENSOR_MT9V111: + mt9v111_InitSensor(gspca_dev); + if (mode) { + reg1 = 0x04; /* 320 clk 48Mhz */ + } else { +/* reg1 = 0x06; * 640 clk 24Mz (done) */ + reg17 = 0xe2; + } case SENSOR_OM6802: om6802_InitSensor(gspca_dev); reg17 = 0x64; /* 640 MCKSIZE */ @@ -1463,17 +1628,19 @@ static int sd_start(struct gspca_dev *gspca_dev) reg18 = sn9c1xx[0x18] | (mode << 4); reg_w1(gspca_dev, 0x18, reg18 | 0x40); - reg_w(gspca_dev, 0x100, qtable4, 0x40); - reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40); + reg_w(gspca_dev, 0x0100, qtable4, 0x40); + reg_w(gspca_dev, 0x0140, qtable4 + 0x40, 0x40); reg_w1(gspca_dev, 0x18, reg18); reg_w1(gspca_dev, 0x17, reg17); reg_w1(gspca_dev, 0x01, reg1); switch (sd->sensor) { - case SENSOR_MI0360: +#if 0 + case SENSOR_MT9V111: setinfrared(sd); break; +#endif case SENSOR_OV7630: setvflip(sd); break; @@ -1509,6 +1676,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) case SENSOR_OV7648: i2c_w8(gspca_dev, stopov7648); /* fall thru */ + case SENSOR_MT9V111: case SENSOR_OV7630: data = 0x29; break; @@ -1556,6 +1724,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) default: /* case SENSOR_MO4000: */ /* case SENSOR_MI0360: */ +/* case SENSOR_MT9V111: */ /* case SENSOR_OM6802: */ expotimes = sd->exposure; expotimes += (luma_mean - delta) >> 6; @@ -1812,7 +1981,7 @@ static const __devinitdata struct usb_device_id device_table[] = { /* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */ {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)}, /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */ - {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)}, + {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MT9V111, 0x5c)}, /* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */ /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */ {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)}, -- cgit v1.2.3 From a8eaa7e616a35998734938d8fe45740de2a40644 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 29 Jan 2009 09:32:23 +0100 Subject: gspca - vc032x: Webcam 041e:405b added and mi1310_soc updated. From: Jean-Francois Moine The mi1310_soc sequences come from the ms-win driver C0130Dev.inf. Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/vc032x.c | 479 +++++++++++++++++++------------ 1 file changed, 296 insertions(+), 183 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/vc032x.c b/linux/drivers/media/video/gspca/vc032x.c index a615cc402..01d886d06 100644 --- a/linux/drivers/media/video/gspca/vc032x.c +++ b/linux/drivers/media/video/gspca/vc032x.c @@ -400,92 +400,208 @@ static const __u8 mi0360_initQVGA_JPG[][4] = { static const __u8 mi1310_socinitVGA_JPG[][4] = { {0xb0, 0x03, 0x19, 0xcc}, {0xb0, 0x04, 0x02, 0xcc}, - {0xb3, 0x00, 0x64, 0xcc}, - {0xb3, 0x00, 0x65, 0xcc}, - {0xb3, 0x05, 0x00, 0xcc}, - {0xb3, 0x06, 0x00, 0xcc}, + {0xb3, 0x00, 0x24, 0xcc}, + {0xb3, 0x00, 0x25, 0xcc}, + {0xb3, 0x05, 0x01, 0xcc}, + {0xb3, 0x06, 0x03, 0xcc}, + {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc}, {0xb3, 0x35, 0xdd, 0xcc}, - {0xb3, 0x02, 0x00, 0xcc}, {0xb3, 0x03, 0x0a, 0xcc}, - {0xb3, 0x04, 0x05, 0xcc}, + {0xb3, 0x04, 0x0d, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x03, 0xcc}, - {0xb3, 0x23, 0xc0, 0xcc}, + {0xb3, 0x22, 0x01, 0xcc}, + {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x04, 0xcc}, - {0xb3, 0x17, 0xff, 0xcc}, - {0xb3, 0x00, 0x65, 0xcc}, - {0xb8, 0x00, 0x00, 0xcc}, - {0xbc, 0x00, 0xd0, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, - {0xf0, 0x00, 0x02, 0xbb}, - {0xc8, 0x9f, 0x0b, 0xbb}, - {0x5b, 0x00, 0x01, 0xbb}, - {0x2f, 0xde, 0x20, 0xbb}, + {0xb3, 0x16, 0x02, 0xcc}, + {0xb3, 0x17, 0x7f, 0xcc}, + {0xb8, 0x01, 0x7d, 0xcc}, + {0xb8, 0x81, 0x09, 0xcc}, + {0xb8, 0x27, 0x20, 0xcc}, + {0xb8, 0x26, 0x80, 0xcc}, + {0xb3, 0x00, 0x25, 0xcc}, + {0xb8, 0x00, 0x13, 0xcc}, + {0xbc, 0x00, 0x71, 0xcc}, + {0xb8, 0x81, 0x01, 0xcc}, + {0xb8, 0x2c, 0x5a, 0xcc}, + {0xb8, 0x2d, 0xff, 0xcc}, + {0xb8, 0x2e, 0xee, 0xcc}, + {0xb8, 0x2f, 0xfb, 0xcc}, + {0xb8, 0x30, 0x52, 0xcc}, + {0xb8, 0x31, 0xf8, 0xcc}, + {0xb8, 0x32, 0xf1, 0xcc}, + {0xb8, 0x33, 0xff, 0xcc}, + {0xb8, 0x34, 0x54, 0xcc}, + {0xb8, 0x35, 0x00, 0xcc}, + {0xb8, 0x36, 0x00, 0xcc}, + {0xb8, 0x37, 0x00, 0xcc}, {0xf0, 0x00, 0x00, 0xbb}, - {0x20, 0x03, 0x02, 0xbb}, + {0x00, 0x01, 0x00, 0xdd}, + {0x0d, 0x00, 0x09, 0xbb}, + {0x0d, 0x00, 0x08, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, - {0x05, 0x00, 0x07, 0xbb}, - {0x34, 0x00, 0x00, 0xbb}, - {0x35, 0xff, 0x00, 0xbb}, - {0xdc, 0x07, 0x02, 0xbb}, - {0xdd, 0x3c, 0x18, 0xbb}, - {0xde, 0x92, 0x6d, 0xbb}, - {0xdf, 0xcd, 0xb1, 0xbb}, - {0xe0, 0xff, 0xe7, 0xbb}, - {0x06, 0xf0, 0x0d, 0xbb}, - {0x06, 0x70, 0x0e, 0xbb}, - {0x4c, 0x00, 0x01, 0xbb}, - {0x4d, 0x00, 0x01, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x2e, 0x0c, 0x55, 0xbb}, - {0x21, 0xb6, 0x6e, 0xbb}, - {0x36, 0x30, 0x10, 0xbb}, - {0x37, 0x00, 0xc1, 0xbb}, + {0x00, 0x01, 0x00, 0xdd}, + {0x06, 0x00, 0x14, 0xbb}, + {0x3a, 0x10, 0x00, 0xbb}, + {0x00, 0x00, 0x10, 0xdd}, + {0x9b, 0x10, 0x00, 0xbb}, + {0x00, 0x00, 0x10, 0xdd}, {0xf0, 0x00, 0x00, 0xbb}, - {0x07, 0x00, 0x84, 0xbb}, - {0x08, 0x02, 0x4a, 0xbb}, - {0x05, 0x01, 0x10, 0xbb}, - {0x06, 0x00, 0x39, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x58, 0x02, 0x67, 0xbb}, - {0x57, 0x02, 0x00, 0xbb}, - {0x5a, 0x02, 0x67, 0xbb}, - {0x59, 0x02, 0x00, 0xbb}, - {0x5c, 0x12, 0x0d, 0xbb}, - {0x5d, 0x16, 0x11, 0xbb}, - {0x39, 0x06, 0x18, 0xbb}, - {0x3a, 0x06, 0x18, 0xbb}, - {0x3b, 0x06, 0x18, 0xbb}, - {0x3c, 0x06, 0x18, 0xbb}, - {0x64, 0x7b, 0x5b, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x36, 0x30, 0x10, 0xbb}, - {0x37, 0x00, 0xc0, 0xbb}, - {0xbc, 0x0e, 0x00, 0xcc}, - {0xbc, 0x0f, 0x05, 0xcc}, - {0xbc, 0x10, 0xc0, 0xcc}, - {0xbc, 0x11, 0x03, 0xcc}, + {0x00, 0x01, 0x00, 0xdd}, + {0x2b, 0x00, 0x28, 0xbb}, + {0x2c, 0x00, 0x30, 0xbb}, + {0x2d, 0x00, 0x30, 0xbb}, + {0x2e, 0x00, 0x28, 0xbb}, + {0x41, 0x00, 0xd7, 0xbb}, + {0x09, 0x02, 0x3a, 0xbb}, + {0x0c, 0x00, 0x00, 0xbb}, + {0x20, 0x00, 0x00, 0xbb}, + {0x05, 0x00, 0x8c, 0xbb}, + {0x06, 0x00, 0x32, 0xbb}, + {0x07, 0x00, 0xc6, 0xbb}, + {0x08, 0x00, 0x19, 0xbb}, + {0x24, 0x80, 0x6f, 0xbb}, + {0xc8, 0x00, 0x0f, 0xbb}, + {0x20, 0x00, 0x0f, 0xbb}, {0xb6, 0x00, 0x00, 0xcc}, {0xb6, 0x03, 0x02, 0xcc}, {0xb6, 0x02, 0x80, 0xcc}, {0xb6, 0x05, 0x01, 0xcc}, {0xb6, 0x04, 0xe0, 0xcc}, - {0xb6, 0x12, 0xf8, 0xcc}, - {0xb6, 0x13, 0x25, 0xcc}, + {0xb6, 0x12, 0x78, 0xcc}, {0xb6, 0x18, 0x02, 0xcc}, {0xb6, 0x17, 0x58, 0xcc}, {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, {0xb6, 0x23, 0x0b, 0xcc}, + {0xb3, 0x02, 0x02, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc}, {0xbf, 0xc1, 0x04, 0xcc}, - {0xbf, 0xcc, 0x00, 0xcc}, + {0xbf, 0xcc, 0x10, 0xcc}, + {0xb9, 0x12, 0x00, 0xcc}, + {0xb9, 0x13, 0x0a, 0xcc}, + {0xb9, 0x14, 0x0a, 0xcc}, + {0xb9, 0x15, 0x0a, 0xcc}, + {0xb9, 0x16, 0x0a, 0xcc}, + {0xb9, 0x18, 0x00, 0xcc}, + {0xb9, 0x19, 0x0f, 0xcc}, + {0xb9, 0x1a, 0x0f, 0xcc}, + {0xb9, 0x1b, 0x0f, 0xcc}, + {0xb9, 0x1c, 0x0f, 0xcc}, + {0xb8, 0x8e, 0x00, 0xcc}, + {0xb8, 0x8f, 0xff, 0xcc}, + {0xb3, 0x01, 0x41, 0xcc}, + {0x03, 0x03, 0xc0, 0xbb}, + {0x06, 0x00, 0x10, 0xbb}, + {0xb6, 0x12, 0xf8, 0xcc}, + {0xb8, 0x0c, 0x20, 0xcc}, + {0xb8, 0x0d, 0x70, 0xcc}, + {0xb6, 0x13, 0x13, 0xcc}, + {0x2f, 0x00, 0xC0, 0xbb}, + {0xb8, 0xa0, 0x12, 0xcc}, + {}, +}; +static const __u8 mi1310_socinitQVGA_JPG[][4] = { + {0xb0, 0x03, 0x19, 0xcc}, + {0xb0, 0x04, 0x02, 0xcc}, + {0xb3, 0x00, 0x24, 0xcc}, + {0xb3, 0x00, 0x25, 0xcc}, + {0xb3, 0x05, 0x01, 0xcc}, + {0xb3, 0x06, 0x03, 0xcc}, + {0xb3, 0x5c, 0x01, 0xcc}, + {0xb3, 0x08, 0x01, 0xcc}, + {0xb3, 0x09, 0x0c, 0xcc}, + {0xb3, 0x34, 0x02, 0xcc}, + {0xb3, 0x35, 0xdd, 0xcc}, + {0xb3, 0x03, 0x0a, 0xcc}, + {0xb3, 0x04, 0x0d, 0xcc}, + {0xb3, 0x20, 0x00, 0xcc}, + {0xb3, 0x21, 0x00, 0xcc}, + {0xb3, 0x22, 0x01, 0xcc}, + {0xb3, 0x23, 0xe0, 0xcc}, + {0xb3, 0x14, 0x00, 0xcc}, + {0xb3, 0x15, 0x00, 0xcc}, + {0xb3, 0x16, 0x02, 0xcc}, + {0xb3, 0x17, 0x7f, 0xcc}, + {0xb8, 0x01, 0x7d, 0xcc}, + {0xb8, 0x81, 0x09, 0xcc}, + {0xb8, 0x27, 0x20, 0xcc}, + {0xb8, 0x26, 0x80, 0xcc}, + {0xb3, 0x00, 0x25, 0xcc}, + {0xb8, 0x00, 0x13, 0xcc}, + {0xbc, 0x00, 0xd1, 0xcc}, + {0xb8, 0x81, 0x01, 0xcc}, + {0xb8, 0x2c, 0x5a, 0xcc}, + {0xb8, 0x2d, 0xff, 0xcc}, + {0xb8, 0x2e, 0xee, 0xcc}, + {0xb8, 0x2f, 0xfb, 0xcc}, + {0xb8, 0x30, 0x52, 0xcc}, + {0xb8, 0x31, 0xf8, 0xcc}, + {0xb8, 0x32, 0xf1, 0xcc}, + {0xb8, 0x33, 0xff, 0xcc}, + {0xb8, 0x34, 0x54, 0xcc}, + {0xb8, 0x35, 0x00, 0xcc}, + {0xb8, 0x36, 0x00, 0xcc}, + {0xb8, 0x37, 0x00, 0xcc}, + {0xf0, 0x00, 0x00, 0xbb}, + {0x00, 0x01, 0x00, 0xdd}, + {0x0d, 0x00, 0x09, 0xbb}, + {0x0d, 0x00, 0x08, 0xbb}, + {0xf0, 0x00, 0x01, 0xbb}, + {0x00, 0x01, 0x00, 0xdd}, + {0x06, 0x00, 0x14, 0xbb}, + {0x3a, 0x10, 0x00, 0xbb}, + {0x00, 0x00, 0x10, 0xdd}, + {0x9b, 0x10, 0x00, 0xbb}, + {0x00, 0x00, 0x10, 0xdd}, + {0xf0, 0x00, 0x00, 0xbb}, + {0x00, 0x01, 0x00, 0xdd}, + {0x2b, 0x00, 0x28, 0xbb}, + {0x2c, 0x00, 0x30, 0xbb}, + {0x2d, 0x00, 0x30, 0xbb}, + {0x2e, 0x00, 0x28, 0xbb}, + {0x41, 0x00, 0xd7, 0xbb}, + {0x09, 0x02, 0x3a, 0xbb}, + {0x0c, 0x00, 0x00, 0xbb}, + {0x20, 0x00, 0x00, 0xbb}, + {0x05, 0x00, 0x8c, 0xbb}, + {0x06, 0x00, 0x32, 0xbb}, + {0x07, 0x00, 0xc6, 0xbb}, + {0x08, 0x00, 0x19, 0xbb}, + {0x24, 0x80, 0x6f, 0xbb}, + {0xc8, 0x00, 0x0f, 0xbb}, + {0x20, 0x00, 0x0f, 0xbb}, + {0xb6, 0x00, 0x00, 0xcc}, + {0xb6, 0x03, 0x01, 0xcc}, + {0xb6, 0x02, 0x40, 0xcc}, + {0xb6, 0x05, 0x00, 0xcc}, + {0xb6, 0x04, 0xf0, 0xcc}, + {0xb6, 0x12, 0x78, 0xcc}, + {0xb6, 0x18, 0x00, 0xcc}, + {0xb6, 0x17, 0x96, 0xcc}, + {0xb6, 0x16, 0x00, 0xcc}, + {0xb6, 0x22, 0x12, 0xcc}, + {0xb6, 0x23, 0x0b, 0xcc}, + {0xb3, 0x02, 0x02, 0xcc}, + {0xbf, 0xc0, 0x39, 0xcc}, + {0xbf, 0xc1, 0x04, 0xcc}, + {0xbf, 0xcc, 0x10, 0xcc}, + {0xb9, 0x12, 0x00, 0xcc}, + {0xb9, 0x13, 0x0a, 0xcc}, + {0xb9, 0x14, 0x0a, 0xcc}, + {0xb9, 0x15, 0x0a, 0xcc}, + {0xb9, 0x16, 0x0a, 0xcc}, + {0xb9, 0x18, 0x00, 0xcc}, + {0xb9, 0x19, 0x0f, 0xcc}, + {0xb9, 0x1a, 0x0f, 0xcc}, + {0xb9, 0x1b, 0x0f, 0xcc}, + {0xb9, 0x1c, 0x0f, 0xcc}, + {0xb8, 0x8e, 0x00, 0xcc}, + {0xb8, 0x8f, 0xff, 0xcc}, {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc}, {0xbc, 0x04, 0x18, 0xcc}, @@ -496,132 +612,126 @@ static const __u8 mi1310_socinitVGA_JPG[][4] = { {0xbc, 0x0a, 0x10, 0xcc}, {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xf0, 0x00, 0x01, 0xbb}, - {0x80, 0x00, 0x03, 0xbb}, - {0x81, 0xc7, 0x14, 0xbb}, - {0x82, 0xeb, 0xe8, 0xbb}, - {0x83, 0xfe, 0xf4, 0xbb}, - {0x84, 0xcd, 0x10, 0xbb}, - {0x85, 0xf3, 0xee, 0xbb}, - {0x86, 0xff, 0xf1, 0xbb}, - {0x87, 0xcd, 0x10, 0xbb}, - {0x88, 0xf3, 0xee, 0xbb}, - {0x89, 0x01, 0xf1, 0xbb}, - {0x8a, 0xe5, 0x17, 0xbb}, - {0x8b, 0xe8, 0xe2, 0xbb}, - {0x8c, 0xf7, 0xed, 0xbb}, - {0x8d, 0x00, 0xff, 0xbb}, - {0x8e, 0xec, 0x10, 0xbb}, - {0x8f, 0xf0, 0xed, 0xbb}, - {0x90, 0xf9, 0xf2, 0xbb}, - {0x91, 0x00, 0x00, 0xbb}, - {0x92, 0xe9, 0x0d, 0xbb}, - {0x93, 0xf4, 0xf2, 0xbb}, - {0x94, 0xfb, 0xf5, 0xbb}, - {0x95, 0x00, 0xff, 0xbb}, - {0xb6, 0x0f, 0x08, 0xbb}, - {0xb7, 0x3d, 0x16, 0xbb}, - {0xb8, 0x0c, 0x04, 0xbb}, - {0xb9, 0x1c, 0x07, 0xbb}, - {0xba, 0x0a, 0x03, 0xbb}, - {0xbb, 0x1b, 0x09, 0xbb}, - {0xbc, 0x17, 0x0d, 0xbb}, - {0xbd, 0x23, 0x1d, 0xbb}, - {0xbe, 0x00, 0x28, 0xbb}, - {0xbf, 0x11, 0x09, 0xbb}, - {0xc0, 0x16, 0x15, 0xbb}, - {0xc1, 0x00, 0x1b, 0xbb}, - {0xc2, 0x0e, 0x07, 0xbb}, - {0xc3, 0x14, 0x10, 0xbb}, - {0xc4, 0x00, 0x17, 0xbb}, - {0x06, 0x74, 0x8e, 0xbb}, - {0xf0, 0x00, 0x01, 0xbb}, - {0x06, 0xf4, 0x8e, 0xbb}, - {0x00, 0x00, 0x50, 0xdd}, - {0x06, 0x74, 0x8e, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x24, 0x50, 0x20, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x34, 0x0c, 0x50, 0xbb}, {0xb3, 0x01, 0x41, 0xcc}, - {0xf0, 0x00, 0x00, 0xbb}, {0x03, 0x03, 0xc0, 0xbb}, + {0x06, 0x00, 0x10, 0xbb}, + {0xb6, 0x12, 0xf8, 0xcc}, + {0xb8, 0x0c, 0x20, 0xcc}, + {0xb8, 0x0d, 0x70, 0xcc}, + {0xb6, 0x13, 0x13, 0xcc}, + {0x2f, 0x00, 0xC0, 0xbb}, + {0xb8, 0xa0, 0x12, 0xcc}, {}, }; -static const __u8 mi1310_socinitQVGA_JPG[][4] = { - {0xb0, 0x03, 0x19, 0xcc}, {0xb0, 0x04, 0x02, 0xcc}, - {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, - {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x00, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x34, 0x02, 0xcc}, {0xb3, 0x35, 0xdd, 0xcc}, - {0xb3, 0x02, 0x00, 0xcc}, {0xb3, 0x03, 0x0a, 0xcc}, - {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x03, 0xcc}, - {0xb3, 0x23, 0xc0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, {0xb3, 0x16, 0x04, 0xcc}, - {0xb3, 0x17, 0xff, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, - {0xb8, 0x00, 0x00, 0xcc}, {0xbc, 0x00, 0xf0, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x02, 0xbb}, - {0xc8, 0x9f, 0x0b, 0xbb}, {0x5b, 0x00, 0x01, 0xbb}, - {0x2f, 0xde, 0x20, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, - {0x20, 0x03, 0x02, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, - {0x05, 0x00, 0x07, 0xbb}, {0x34, 0x00, 0x00, 0xbb}, - {0x35, 0xff, 0x00, 0xbb}, {0xdc, 0x07, 0x02, 0xbb}, - {0xdd, 0x3c, 0x18, 0xbb}, {0xde, 0x92, 0x6d, 0xbb}, - {0xdf, 0xcd, 0xb1, 0xbb}, {0xe0, 0xff, 0xe7, 0xbb}, - {0x06, 0xf0, 0x0d, 0xbb}, {0x06, 0x70, 0x0e, 0xbb}, - {0x4c, 0x00, 0x01, 0xbb}, {0x4d, 0x00, 0x01, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x2e, 0x0c, 0x55, 0xbb}, - {0x21, 0xb6, 0x6e, 0xbb}, {0x36, 0x30, 0x10, 0xbb}, - {0x37, 0x00, 0xc1, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, - {0x07, 0x00, 0x84, 0xbb}, {0x08, 0x02, 0x4a, 0xbb}, - {0x05, 0x01, 0x10, 0xbb}, {0x06, 0x00, 0x39, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x58, 0x02, 0x67, 0xbb}, - {0x57, 0x02, 0x00, 0xbb}, {0x5a, 0x02, 0x67, 0xbb}, - {0x59, 0x02, 0x00, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb}, - {0x5d, 0x16, 0x11, 0xbb}, {0x39, 0x06, 0x18, 0xbb}, - {0x3a, 0x06, 0x18, 0xbb}, {0x3b, 0x06, 0x18, 0xbb}, - {0x3c, 0x06, 0x18, 0xbb}, {0x64, 0x7b, 0x5b, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x30, 0x10, 0xbb}, - {0x37, 0x00, 0xc0, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc}, - {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc}, - {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc}, - {0xb6, 0x03, 0x01, 0xcc}, {0xb6, 0x02, 0x40, 0xcc}, - {0xb6, 0x05, 0x00, 0xcc}, {0xb6, 0x04, 0xf0, 0xcc}, - {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x25, 0xcc}, - {0xb6, 0x18, 0x00, 0xcc}, {0xb6, 0x17, 0x96, 0xcc}, - {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, - {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc}, - {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, {0xf0, 0x00, 0x01, 0xbb}, - {0x80, 0x00, 0x03, 0xbb}, {0x81, 0xc7, 0x14, 0xbb}, - {0x82, 0xeb, 0xe8, 0xbb}, {0x83, 0xfe, 0xf4, 0xbb}, - {0x84, 0xcd, 0x10, 0xbb}, {0x85, 0xf3, 0xee, 0xbb}, - {0x86, 0xff, 0xf1, 0xbb}, {0x87, 0xcd, 0x10, 0xbb}, - {0x88, 0xf3, 0xee, 0xbb}, {0x89, 0x01, 0xf1, 0xbb}, - {0x8a, 0xe5, 0x17, 0xbb}, {0x8b, 0xe8, 0xe2, 0xbb}, - {0x8c, 0xf7, 0xed, 0xbb}, {0x8d, 0x00, 0xff, 0xbb}, - {0x8e, 0xec, 0x10, 0xbb}, {0x8f, 0xf0, 0xed, 0xbb}, - {0x90, 0xf9, 0xf2, 0xbb}, {0x91, 0x00, 0x00, 0xbb}, - {0x92, 0xe9, 0x0d, 0xbb}, {0x93, 0xf4, 0xf2, 0xbb}, - {0x94, 0xfb, 0xf5, 0xbb}, {0x95, 0x00, 0xff, 0xbb}, - {0xb6, 0x0f, 0x08, 0xbb}, {0xb7, 0x3d, 0x16, 0xbb}, - {0xb8, 0x0c, 0x04, 0xbb}, {0xb9, 0x1c, 0x07, 0xbb}, - {0xba, 0x0a, 0x03, 0xbb}, {0xbb, 0x1b, 0x09, 0xbb}, - {0xbc, 0x17, 0x0d, 0xbb}, {0xbd, 0x23, 0x1d, 0xbb}, - {0xbe, 0x00, 0x28, 0xbb}, {0xbf, 0x11, 0x09, 0xbb}, - {0xc0, 0x16, 0x15, 0xbb}, {0xc1, 0x00, 0x1b, 0xbb}, - {0xc2, 0x0e, 0x07, 0xbb}, {0xc3, 0x14, 0x10, 0xbb}, - {0xc4, 0x00, 0x17, 0xbb}, {0x06, 0x74, 0x8e, 0xbb}, - {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0xf4, 0x8e, 0xbb}, - {0x00, 0x00, 0x50, 0xdd}, {0x06, 0x74, 0x8e, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x24, 0x50, 0x20, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x34, 0x0c, 0x50, 0xbb}, - {0xb3, 0x01, 0x41, 0xcc}, {0xf0, 0x00, 0x00, 0xbb}, - {0x03, 0x03, 0xc0, 0xbb}, - {}, +#if 0 +static const u8 mi1310_soc_InitSXGA_JPG[][4] = { + {0xb0, 0x03, 0x19, 0xcc}, + {0xb0, 0x04, 0x02, 0xcc}, + {0xb3, 0x00, 0x24, 0xcc}, + {0xb3, 0x00, 0x25, 0xcc}, + {0xb3, 0x05, 0x00, 0xcc}, + {0xb3, 0x06, 0x01, 0xcc}, + {0xb3, 0x5c, 0x01, 0xcc}, + {0xb3, 0x08, 0x01, 0xcc}, + {0xb3, 0x09, 0x0c, 0xcc}, + {0xb3, 0x34, 0x02, 0xcc}, + {0xb3, 0x35, 0xdd, 0xcc}, + {0xb3, 0x03, 0x0a, 0xcc}, + {0xb3, 0x04, 0x0d, 0xcc}, + {0xb3, 0x20, 0x00, 0xcc}, + {0xb3, 0x21, 0x00, 0xcc}, + {0xb3, 0x22, 0x04, 0xcc}, + {0xb3, 0x23, 0x00, 0xcc}, + {0xb3, 0x14, 0x00, 0xcc}, + {0xb3, 0x15, 0x00, 0xcc}, + {0xb3, 0x16, 0x04, 0xcc}, + {0xb3, 0x17, 0xff, 0xcc}, + {0xb8, 0x01, 0x7d, 0xcc}, + {0xb8, 0x81, 0x09, 0xcc}, + {0xb8, 0x27, 0x20, 0xcc}, + {0xb8, 0x26, 0x80, 0xcc}, + {0xb8, 0x06, 0x00, 0xcc}, + {0xb8, 0x07, 0x05, 0xcc}, + {0xb8, 0x08, 0x00, 0xcc}, + {0xb8, 0x09, 0x04, 0xcc}, + {0xb3, 0x00, 0x25, 0xcc}, + {0xb8, 0x00, 0x11, 0xcc}, + {0xbc, 0x00, 0x71, 0xcc}, + {0xb8, 0x81, 0x01, 0xcc}, + {0xb8, 0x2c, 0x5a, 0xcc}, + {0xb8, 0x2d, 0xff, 0xcc}, + {0xb8, 0x2e, 0xee, 0xcc}, + {0xb8, 0x2f, 0xfb, 0xcc}, + {0xb8, 0x30, 0x52, 0xcc}, + {0xb8, 0x31, 0xf8, 0xcc}, + {0xb8, 0x32, 0xf1, 0xcc}, + {0xb8, 0x33, 0xff, 0xcc}, + {0xb8, 0x34, 0x54, 0xcc}, + {0xf0, 0x00, 0x00, 0xbb}, + {0x00, 0x01, 0x00, 0xdd}, + {0x0d, 0x00, 0x09, 0xbb}, + {0x0d, 0x00, 0x08, 0xbb}, + {0xf0, 0x00, 0x01, 0xbb}, + {0x00, 0x01, 0x00, 0xdd}, + {0x06, 0x00, 0x14, 0xbb}, + {0x3a, 0x10, 0x00, 0xbb}, + {0x00, 0x00, 0x10, 0xdd}, + {0x9b, 0x10, 0x00, 0xbb}, + {0x00, 0x00, 0x10, 0xdd}, + {0xf0, 0x00, 0x00, 0xbb}, + {0x00, 0x01, 0x00, 0xdd}, + {0x2b, 0x00, 0x28, 0xbb}, + {0x2c, 0x00, 0x30, 0xbb}, + {0x2d, 0x00, 0x30, 0xbb}, + {0x2e, 0x00, 0x28, 0xbb}, + {0x41, 0x00, 0xd7, 0xbb}, + {0x09, 0x02, 0x3a, 0xbb}, + {0x0c, 0x00, 0x00, 0xbb}, + {0x20, 0x00, 0x00, 0xbb}, + {0x05, 0x00, 0x8c, 0xbb}, + {0x06, 0x00, 0x32, 0xbb}, + {0x07, 0x00, 0xc6, 0xbb}, + {0x08, 0x00, 0x19, 0xbb}, + {0x24, 0x80, 0x6f, 0xbb}, + {0xc8, 0x00, 0x0f, 0xbb}, + {0x20, 0x00, 0x03, 0xbb}, + {0xb6, 0x00, 0x00, 0xcc}, + {0xb6, 0x03, 0x05, 0xcc}, + {0xb6, 0x02, 0x00, 0xcc}, + {0xb6, 0x05, 0x04, 0xcc}, + {0xb6, 0x04, 0x00, 0xcc}, + {0xb6, 0x12, 0xf8, 0xcc}, + {0xb6, 0x18, 0x0a, 0xcc}, + {0xb6, 0x17, 0x00, 0xcc}, + {0xb6, 0x16, 0x00, 0xcc}, + {0xb6, 0x22, 0x12, 0xcc}, + {0xb6, 0x23, 0x0b, 0xcc}, + {0xb3, 0x02, 0x02, 0xcc}, + {0xbf, 0xc0, 0x39, 0xcc}, + {0xbf, 0xc1, 0x04, 0xcc}, + {0xbf, 0xcc, 0x10, 0xcc}, + {0xb9, 0x12, 0x00, 0xcc}, + {0xb9, 0x13, 0x14, 0xcc}, + {0xb9, 0x14, 0x14, 0xcc}, + {0xb9, 0x15, 0x14, 0xcc}, + {0xb9, 0x16, 0x14, 0xcc}, + {0xb9, 0x18, 0x00, 0xcc}, + {0xb9, 0x19, 0x1e, 0xcc}, + {0xb9, 0x1a, 0x1e, 0xcc}, + {0xb9, 0x1b, 0x1e, 0xcc}, + {0xb9, 0x1c, 0x1e, 0xcc}, + {0xb3, 0x01, 0x41, 0xcc}, + {0xb8, 0x8e, 0x00, 0xcc}, + {0xb8, 0x8f, 0xff, 0xcc}, + {0xb6, 0x12, 0xf8, 0xcc}, + {0xb8, 0x0c, 0x20, 0xcc}, + {0xb8, 0x0d, 0x70, 0xcc}, + {0xb6, 0x13, 0x13, 0xcc}, + {0x2f, 0x00, 0xC0, 0xbb}, + {0xb8, 0xa0, 0x12, 0xcc}, + {} }; +#endif static const __u8 mi1320_gamma[17] = { 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, @@ -2208,6 +2318,8 @@ static int sd_start(struct gspca_dev *gspca_dev) } break; case SENSOR_MI1310_SOC: + GammaT = mi1320_gamma; + MatrixT = mi0360_matrix; if (mode) { /* 320x240 */ usb_exchange(gspca_dev, mi1310_socinitQVGA_JPG); @@ -2449,6 +2561,7 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x041e, 0x405b), .driver_info = BRIDGE_VC0321}, {USB_DEVICE(0x046d, 0x0892), .driver_info = BRIDGE_VC0321}, {USB_DEVICE(0x046d, 0x0896), .driver_info = BRIDGE_VC0321}, {USB_DEVICE(0x046d, 0x0897), .driver_info = BRIDGE_VC0321}, -- cgit v1.2.3 From 10a9a21ccf74b5ff6c15d4e15f929fc5d08377a7 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 29 Jan 2009 10:02:37 +0100 Subject: gspca - documentation: Add the webcam 041e:405b. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/Documentation/video4linux/gspca.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'linux') diff --git a/linux/Documentation/video4linux/gspca.txt b/linux/Documentation/video4linux/gspca.txt index 3136c8028..12c8ff705 100644 --- a/linux/Documentation/video4linux/gspca.txt +++ b/linux/Documentation/video4linux/gspca.txt @@ -32,6 +32,7 @@ spca561 041e:403b Creative Webcam Vista (VF0010) zc3xx 041e:4051 Creative Live!Cam Notebook Pro (VF0250) ov519 041e:4052 Creative Live! VISTA IM zc3xx 041e:4053 Creative Live!Cam Video IM +vc032x 041e:405b Creative Live! Cam Notebook Ultra (VC0130) ov519 041e:405f Creative Live! VISTA VF0330 ov519 041e:4060 Creative Live! VISTA VF0350 ov519 041e:4061 Creative Live! VISTA VF0400 -- cgit v1.2.3 From 1ce2c6a963dd54733741c029136430693485f8cd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 29 Jan 2009 10:23:18 +0100 Subject: gspca: fix compiler warning From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/gspca/t613.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/t613.c b/linux/drivers/media/video/gspca/t613.c index 9c777381a..adec0767c 100644 --- a/linux/drivers/media/video/gspca/t613.c +++ b/linux/drivers/media/video/gspca/t613.c @@ -635,7 +635,7 @@ static int sd_init(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int i; u16 sensor_id; - u8 test_byte; + u8 test_byte = 0; u16 reg80, reg8e; static const u8 read_indexs[] = -- cgit v1.2.3 From 68a6fa1ae421b7c28eb6b8365f3adfd08007e7b7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 29 Jan 2009 09:11:45 -0200 Subject: backport changes on files not maintained here From: Mauro Carvalho Chehab kernel-sync: Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/firmware/Makefile | 5 +++- linux/include/linux/i2c-id.h | 61 -------------------------------------------- 2 files changed, 4 insertions(+), 62 deletions(-) (limited to 'linux') diff --git a/linux/firmware/Makefile b/linux/firmware/Makefile index 205f822a3..6b398f25c 100644 --- a/linux/firmware/Makefile +++ b/linux/firmware/Makefile @@ -37,6 +37,8 @@ fw-shipped-$(CONFIG_CHELSIO_T3) += cxgb3/t3b_psram-1.1.0.bin \ cxgb3/t3c_psram-1.1.0.bin \ cxgb3/t3fw-7.0.0.bin fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin +fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \ + e100/d102e_ucode.bin fw-shipped-$(CONFIG_SMCTR) += tr_smctr.bin fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \ @@ -76,7 +78,8 @@ fw-shipped- += keyspan/mpr.fw keyspan/usa18x.fw keyspan/usa19.fw \ keyspan/usa28.fw keyspan/usa28xa.fw keyspan/usa28xb.fw \ keyspan/usa28x.fw keyspan/usa49w.fw keyspan/usa49wlc.fw endif -fw-shipped-$(CONFIG_USB_SERIAL_TI) += ti_3410.fw ti_5052.fw +fw-shipped-$(CONFIG_USB_SERIAL_TI) += ti_3410.fw ti_5052.fw \ + mts_cdma.fw mts_gsm.fw mts_edge.fw fw-shipped-$(CONFIG_USB_SERIAL_EDGEPORT) += edgeport/boot.fw edgeport/boot2.fw \ edgeport/down.fw edgeport/down2.fw fw-shipped-$(CONFIG_USB_SERIAL_EDGEPORT_TI) += edgeport/down3.bin diff --git a/linux/include/linux/i2c-id.h b/linux/include/linux/i2c-id.h index 01d67ba9e..1ffc23bc5 100644 --- a/linux/include/linux/i2c-id.h +++ b/linux/include/linux/i2c-id.h @@ -40,9 +40,7 @@ #define I2C_DRIVERID_SAA7185B 13 /* video encoder */ #define I2C_DRIVERID_SAA7110 22 /* video decoder */ #define I2C_DRIVERID_SAA5249 24 /* SAA5249 and compatibles */ -#define I2C_DRIVERID_PCF8583 25 /* real time clock */ #define I2C_DRIVERID_TDA7432 27 /* Stereo sound processor */ -#define I2C_DRIVERID_TVMIXER 28 /* Mixer driver for tv cards */ #define I2C_DRIVERID_TVAUDIO 29 /* Generic TV sound driver */ #define I2C_DRIVERID_TDA9875 32 /* TV sound decoder chip */ #define I2C_DRIVERID_BT819 40 /* video decoder */ @@ -54,7 +52,6 @@ #define I2C_DRIVERID_SAA7191 57 /* video decoder */ #define I2C_DRIVERID_INDYCAM 58 /* SGI IndyCam */ #define I2C_DRIVERID_OVCAMCHIP 61 /* OmniVision CMOS image sens. */ -#define I2C_DRIVERID_MAX6900 63 /* MAX6900 real-time clock */ #define I2C_DRIVERID_SAA6752HS 67 /* MPEG2 encoder */ #define I2C_DRIVERID_TVEEPROM 68 /* TV EEPROM */ #define I2C_DRIVERID_WM8775 69 /* wm8775 audio processor */ @@ -62,23 +59,16 @@ #define I2C_DRIVERID_CX25840 71 /* cx2584x video encoder */ #define I2C_DRIVERID_SAA7127 72 /* saa7127 video encoder */ #define I2C_DRIVERID_SAA711X 73 /* saa711x video encoders */ -#define I2C_DRIVERID_AKITAIOEXP 74 /* IO Expander on Sharp SL-C1000 */ #define I2C_DRIVERID_INFRARED 75 /* I2C InfraRed on Video boards */ #define I2C_DRIVERID_TVP5150 76 /* TVP5150 video decoder */ #define I2C_DRIVERID_WM8739 77 /* wm8739 audio processor */ #define I2C_DRIVERID_UPD64083 78 /* upd64083 video processor */ #define I2C_DRIVERID_UPD64031A 79 /* upd64031a video processor */ #define I2C_DRIVERID_SAA717X 80 /* saa717x video encoder */ -#define I2C_DRIVERID_DS1672 81 /* Dallas/Maxim DS1672 RTC */ #define I2C_DRIVERID_BT866 85 /* Conexant bt866 video encoder */ #define I2C_DRIVERID_KS0127 86 /* Samsung ks0127 video decoder */ #define I2C_DRIVERID_TLV320AIC23B 87 /* TI TLV320AIC23B audio codec */ -#define I2C_DRIVERID_WM8731 89 /* Wolfson WM8731 audio codec */ -#define I2C_DRIVERID_WM8750 90 /* Wolfson WM8750 audio codec */ -#define I2C_DRIVERID_WM8753 91 /* Wolfson WM8753 audio codec */ -#define I2C_DRIVERID_LM4857 92 /* LM4857 Audio Amplifier */ #define I2C_DRIVERID_VP27SMPX 93 /* Panasonic VP27s tuner internal MPX */ -#define I2C_DRIVERID_CS4270 94 /* Cirrus Logic 4270 audio codec */ #define I2C_DRIVERID_M52790 95 /* Mitsubishi M52790SP/FP AV switch */ #define I2C_DRIVERID_CS5345 96 /* cs5345 audio processor */ @@ -89,74 +79,23 @@ */ /* --- Bit algorithm adapters */ -#define I2C_HW_B_LP 0x010000 /* Parallel port Philips style */ #define I2C_HW_B_BT848 0x010005 /* BT848 video boards */ -#define I2C_HW_B_VIA 0x010007 /* Via vt82c586b */ -#define I2C_HW_B_HYDRA 0x010008 /* Apple Hydra Mac I/O */ -#define I2C_HW_B_I810 0x01000a /* Intel I810 */ -#define I2C_HW_B_VOO 0x01000b /* 3dfx Voodoo 3 / Banshee */ -#define I2C_HW_B_SCX200 0x01000e /* Nat'l Semi SCx200 I2C */ #define I2C_HW_B_RIVA 0x010010 /* Riva based graphics cards */ -#define I2C_HW_B_IOC 0x010011 /* IOC bit-wiggling */ -#define I2C_HW_B_IXP2000 0x010016 /* GPIO on IXP2000 systems */ #define I2C_HW_B_ZR36067 0x010019 /* Zoran-36057/36067 based boards */ -#define I2C_HW_B_PCILYNX 0x01001a /* TI PCILynx I2C adapter */ #define I2C_HW_B_CX2388x 0x01001b /* connexant 2388x based tv cards */ -#define I2C_HW_B_NVIDIA 0x01001c /* nvidia framebuffer driver */ -#define I2C_HW_B_SAVAGE 0x01001d /* savage framebuffer driver */ -#define I2C_HW_B_RADEON 0x01001e /* radeon framebuffer driver */ #define I2C_HW_B_EM28XX 0x01001f /* em28xx video capture cards */ #define I2C_HW_B_CX2341X 0x010020 /* Conexant CX2341X MPEG encoder cards */ -#define I2C_HW_B_INTELFB 0x010021 /* intel framebuffer driver */ #define I2C_HW_B_CX23885 0x010022 /* conexant 23885 based tv cards (bus1) */ #define I2C_HW_B_AU0828 0x010023 /* auvitek au0828 usb bridge */ -/* --- PCF 8584 based algorithms */ -#define I2C_HW_P_ELEK 0x020002 /* Elektor ISA Bus inteface card */ - -/* --- PCA 9564 based algorithms */ -#define I2C_HW_A_ISA 0x1a0000 /* generic ISA Bus interface card */ - -/* --- PowerPC on-chip adapters */ -#define I2C_HW_OCP 0x120000 /* IBM on-chip I2C adapter */ - -/* --- Broadcom SiByte adapters */ -#define I2C_HW_SIBYTE 0x150000 - /* --- SGI adapters */ #define I2C_HW_SGI_VINO 0x160000 -/* --- XSCALE on-chip adapters */ -#define I2C_HW_IOP3XX 0x140000 - -/* --- Au1550 PSC adapters adapters */ -#define I2C_HW_AU1550_PSC 0x1b0000 - /* --- SMBus only adapters */ -#define I2C_HW_SMBUS_PIIX4 0x040000 -#define I2C_HW_SMBUS_ALI15X3 0x040001 -#define I2C_HW_SMBUS_VIA2 0x040002 -#define I2C_HW_SMBUS_I801 0x040004 -#define I2C_HW_SMBUS_AMD756 0x040005 -#define I2C_HW_SMBUS_SIS5595 0x040006 -#define I2C_HW_SMBUS_ALI1535 0x040007 -#define I2C_HW_SMBUS_SIS630 0x040008 -#define I2C_HW_SMBUS_SIS96X 0x040009 -#define I2C_HW_SMBUS_AMD8111 0x04000a -#define I2C_HW_SMBUS_SCX200 0x04000b -#define I2C_HW_SMBUS_NFORCE2 0x04000c #define I2C_HW_SMBUS_W9968CF 0x04000d #define I2C_HW_SMBUS_OV511 0x04000e /* OV511(+) USB 1.1 webcam ICs */ #define I2C_HW_SMBUS_OV518 0x04000f /* OV518(+) USB 1.1 webcam ICs */ #define I2C_HW_SMBUS_CAFE 0x040012 /* Marvell 88ALP01 "CAFE" cam */ -#define I2C_HW_SMBUS_ALI1563 0x040013 - -/* --- MCP107 adapter */ -#define I2C_HW_MPC107 0x0d0000 - -/* --- Embedded adapters */ -#define I2C_HW_MV64XXX 0x190000 -#define I2C_HW_BLACKFIN 0x190001 /* ADI Blackfin I2C TWI driver */ /* --- Miscellaneous adapters */ #define I2C_HW_SAA7146 0x060000 /* SAA7146 video decoder bus */ -- cgit v1.2.3 From b1ccf703c9015bc3257716ffccd33ca147f7a1a8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 29 Jan 2009 09:30:59 -0200 Subject: gspca: version.h is needed in order to compile upstream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Mauro Carvalho Chehab drivers/media/video/gspca/gspca.c: In function ‘vidioc_querycap’: drivers/media/video/gspca/gspca.c:963: error: implicit declaration of function ‘KERNEL_VERSION’ kernel-sync: CC: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/gspca/gspca.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index a68b1a969..1a6c61f71 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -21,6 +21,7 @@ #define MODULE_NAME "gspca" #include +#include #include #include #include -- cgit v1.2.3 From 27b887c94f4f9a8e646d1915fe86783153b01f80 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 29 Jan 2009 10:56:56 -0200 Subject: backport changes on stb0899_algo per request From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/stb0899_algo.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/stb0899_algo.c b/linux/drivers/media/dvb/frontends/stb0899_algo.c index 71037dc67..3d13968a7 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_algo.c +++ b/linux/drivers/media/dvb/frontends/stb0899_algo.c @@ -467,14 +467,13 @@ static void next_sub_range(struct stb0899_state *state) if (internal->sub_dir > 0) { old_sub_range = internal->sub_range; - if (internal->tuner_offst + internal->sub_range / 2 >= - internal->srch_range / 2) - internal->sub_range = 0; - else - internal->sub_range = MIN((internal->srch_range / 2) - + internal->sub_range = MIN((internal->srch_range / 2) - (internal->tuner_offst + internal->sub_range / 2), internal->sub_range); + if (internal->sub_range < 0) + internal->sub_range = 0; + internal->tuner_offst += (old_sub_range + internal->sub_range) / 2; } -- cgit v1.2.3 From bc9c580f08d66911d5f49c0c0627f69b06a169d7 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 29 Jan 2009 20:03:19 +0100 Subject: gspca - sonixj: Bad sensor definition of the webcams 0c45:60c0. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 33cbd7945..a16f21be3 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -1981,7 +1981,7 @@ static const __devinitdata struct usb_device_id device_table[] = { /* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */ {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)}, /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */ - {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MT9V111, 0x5c)}, + {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)}, /* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */ /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */ {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)}, -- cgit v1.2.3 From 5d9421a2aa921a698637f5c8fc09b473a19eb075 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 29 Jan 2009 20:09:13 +0100 Subject: v4l2: fix incorrect hue range check From: Hans Verkuil A hue of -128 was rejected due to an incorrect range check, which was faithfully copy-and-pasted into four drivers... Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/cx18/cx18-av-core.c | 2 +- linux/drivers/media/video/cx25840/cx25840-core.c | 2 +- linux/drivers/media/video/saa7115.c | 2 +- linux/drivers/media/video/saa717x.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-av-core.c b/linux/drivers/media/video/cx18/cx18-av-core.c index 0b1c84b4d..780125002 100644 --- a/linux/drivers/media/video/cx18/cx18-av-core.c +++ b/linux/drivers/media/video/cx18/cx18-av-core.c @@ -548,7 +548,7 @@ static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl) break; case V4L2_CID_HUE: - if (ctrl->value < -127 || ctrl->value > 127) { + if (ctrl->value < -128 || ctrl->value > 127) { CX18_ERR("invalid hue setting %d\n", ctrl->value); return -ERANGE; } diff --git a/linux/drivers/media/video/cx25840/cx25840-core.c b/linux/drivers/media/video/cx25840/cx25840-core.c index 57e80717f..d70dcd028 100644 --- a/linux/drivers/media/video/cx25840/cx25840-core.c +++ b/linux/drivers/media/video/cx25840/cx25840-core.c @@ -782,7 +782,7 @@ static int cx25840_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) break; case V4L2_CID_HUE: - if (ctrl->value < -127 || ctrl->value > 127) { + if (ctrl->value < -128 || ctrl->value > 127) { v4l_err(client, "invalid hue setting %d\n", ctrl->value); return -ERANGE; } diff --git a/linux/drivers/media/video/saa7115.c b/linux/drivers/media/video/saa7115.c index 40b0196e6..9fbb93775 100644 --- a/linux/drivers/media/video/saa7115.c +++ b/linux/drivers/media/video/saa7115.c @@ -779,7 +779,7 @@ static int saa711x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) break; case V4L2_CID_HUE: - if (ctrl->value < -127 || ctrl->value > 127) { + if (ctrl->value < -128 || ctrl->value > 127) { v4l2_err(sd, "invalid hue setting %d\n", ctrl->value); return -ERANGE; } diff --git a/linux/drivers/media/video/saa717x.c b/linux/drivers/media/video/saa717x.c index 2fdac2e5c..b53ede210 100644 --- a/linux/drivers/media/video/saa717x.c +++ b/linux/drivers/media/video/saa717x.c @@ -937,7 +937,7 @@ static int saa717x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) break; case V4L2_CID_HUE: - if (ctrl->value < -127 || ctrl->value > 127) { + if (ctrl->value < -128 || ctrl->value > 127) { v4l2_err(sd, "invalid hue setting %d\n", ctrl->value); return -ERANGE; } -- cgit v1.2.3 From b0dced387dcc08db2201c56536a7c1799ba2bb53 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 29 Jan 2009 20:21:12 +0100 Subject: v4l: remove unused I2C_DRIVERIDs. From: Hans Verkuil I2C_DRIVERIDs are phased out. Remove those that are unused at the moment. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/cs53l32a.c | 1 - linux/drivers/media/video/m52790.c | 1 - linux/drivers/media/video/saa5246a.c | 1 - linux/drivers/media/video/saa5249.c | 1 - linux/drivers/media/video/saa717x.c | 1 - linux/drivers/media/video/tda7432.c | 1 - linux/drivers/media/video/tda9840.c | 1 - linux/drivers/media/video/tda9875.c | 1 - linux/drivers/media/video/tea6415c.c | 1 - linux/drivers/media/video/tea6420.c | 1 - linux/drivers/media/video/tlv320aic23b.c | 1 - linux/drivers/media/video/tvmixer.c | 1 - linux/drivers/media/video/tvp5150.c | 1 - linux/drivers/media/video/upd64031a.c | 1 - linux/drivers/media/video/upd64083.c | 1 - linux/drivers/media/video/vp27smpx.c | 1 - linux/drivers/media/video/wm8739.c | 1 - 17 files changed, 17 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cs53l32a.c b/linux/drivers/media/video/cs53l32a.c index 842a8e4ed..c8b5fa157 100644 --- a/linux/drivers/media/video/cs53l32a.c +++ b/linux/drivers/media/video/cs53l32a.c @@ -225,7 +225,6 @@ MODULE_DEVICE_TABLE(i2c, cs53l32a_id); #endif static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "cs53l32a", - .driverid = I2C_DRIVERID_CS53L32A, .command = cs53l32a_command, .remove = cs53l32a_remove, .probe = cs53l32a_probe, diff --git a/linux/drivers/media/video/m52790.c b/linux/drivers/media/video/m52790.c index af179cf4b..982ab4268 100644 --- a/linux/drivers/media/video/m52790.c +++ b/linux/drivers/media/video/m52790.c @@ -222,7 +222,6 @@ MODULE_DEVICE_TABLE(i2c, m52790_id); #endif static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "m52790", - .driverid = I2C_DRIVERID_M52790, .command = m52790_command, .probe = m52790_probe, .remove = m52790_remove, diff --git a/linux/drivers/media/video/saa5246a.c b/linux/drivers/media/video/saa5246a.c index cb8a92e5f..be23b5bd5 100644 --- a/linux/drivers/media/video/saa5246a.c +++ b/linux/drivers/media/video/saa5246a.c @@ -1101,7 +1101,6 @@ MODULE_DEVICE_TABLE(i2c, saa5246a_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "saa5246a", - .driverid = I2C_DRIVERID_SAA5249, .probe = saa5246a_probe, .remove = saa5246a_remove, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) diff --git a/linux/drivers/media/video/saa5249.c b/linux/drivers/media/video/saa5249.c index 9102c6cea..eeb0edea4 100644 --- a/linux/drivers/media/video/saa5249.c +++ b/linux/drivers/media/video/saa5249.c @@ -627,7 +627,6 @@ MODULE_DEVICE_TABLE(i2c, saa5249_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "saa5249", - .driverid = I2C_DRIVERID_SAA5249, .probe = saa5249_probe, .remove = saa5249_remove, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) diff --git a/linux/drivers/media/video/saa717x.c b/linux/drivers/media/video/saa717x.c index b53ede210..3ad43f6b3 100644 --- a/linux/drivers/media/video/saa717x.c +++ b/linux/drivers/media/video/saa717x.c @@ -1539,7 +1539,6 @@ MODULE_DEVICE_TABLE(i2c, saa717x_id); #endif static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "saa717x", - .driverid = I2C_DRIVERID_SAA717X, .command = saa717x_command, .probe = saa717x_probe, .remove = saa717x_remove, diff --git a/linux/drivers/media/video/tda7432.c b/linux/drivers/media/video/tda7432.c index 64a90a71b..30f6f8a38 100644 --- a/linux/drivers/media/video/tda7432.c +++ b/linux/drivers/media/video/tda7432.c @@ -501,7 +501,6 @@ MODULE_DEVICE_TABLE(i2c, tda7432_id); #endif static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tda7432", - .driverid = I2C_DRIVERID_TDA7432, .command = tda7432_command, .probe = tda7432_probe, .remove = tda7432_remove, diff --git a/linux/drivers/media/video/tda9840.c b/linux/drivers/media/video/tda9840.c index 62e257161..d2178ad78 100644 --- a/linux/drivers/media/video/tda9840.c +++ b/linux/drivers/media/video/tda9840.c @@ -265,7 +265,6 @@ MODULE_DEVICE_TABLE(i2c, tda9840_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tda9840", - .driverid = I2C_DRIVERID_TDA9840, .command = tda9840_command, .probe = tda9840_probe, .remove = tda9840_remove, diff --git a/linux/drivers/media/video/tda9875.c b/linux/drivers/media/video/tda9875.c index 8e9c905e4..892d25a40 100644 --- a/linux/drivers/media/video/tda9875.c +++ b/linux/drivers/media/video/tda9875.c @@ -417,7 +417,6 @@ MODULE_DEVICE_TABLE(i2c, tda9875_id); #endif static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tda9875", - .driverid = I2C_DRIVERID_TDA9875, .command = tda9875_command, .probe = tda9875_probe, .remove = tda9875_remove, diff --git a/linux/drivers/media/video/tea6415c.c b/linux/drivers/media/video/tea6415c.c index 0f589842c..2e57dd281 100644 --- a/linux/drivers/media/video/tea6415c.c +++ b/linux/drivers/media/video/tea6415c.c @@ -194,7 +194,6 @@ MODULE_DEVICE_TABLE(i2c, tea6415c_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tea6415c", - .driverid = I2C_DRIVERID_TEA6415C, .command = tea6415c_command, .probe = tea6415c_probe, .remove = tea6415c_remove, diff --git a/linux/drivers/media/video/tea6420.c b/linux/drivers/media/video/tea6420.c index b5f8342e0..023952ae7 100644 --- a/linux/drivers/media/video/tea6420.c +++ b/linux/drivers/media/video/tea6420.c @@ -174,7 +174,6 @@ MODULE_DEVICE_TABLE(i2c, tea6420_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tea6420", - .driverid = I2C_DRIVERID_TEA6420, .command = tea6420_command, .probe = tea6420_probe, .remove = tea6420_remove, diff --git a/linux/drivers/media/video/tlv320aic23b.c b/linux/drivers/media/video/tlv320aic23b.c index ecc3a4ef6..46671fb87 100644 --- a/linux/drivers/media/video/tlv320aic23b.c +++ b/linux/drivers/media/video/tlv320aic23b.c @@ -211,7 +211,6 @@ MODULE_DEVICE_TABLE(i2c, tlv320aic23b_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tlv320aic23b", - .driverid = I2C_DRIVERID_TLV320AIC23B, .command = tlv320aic23b_command, .probe = tlv320aic23b_probe, .remove = tlv320aic23b_remove, diff --git a/linux/drivers/media/video/tvmixer.c b/linux/drivers/media/video/tvmixer.c index fd2e902ea..ae25f0d16 100644 --- a/linux/drivers/media/video/tvmixer.c +++ b/linux/drivers/media/video/tvmixer.c @@ -223,7 +223,6 @@ static struct i2c_driver driver = { .driver = { .name = "tvmixer", }, - .id = I2C_DRIVERID_TVMIXER, #ifndef I2C_DF_DUMMY .detach_adapter = tvmixer_adapters, #endif diff --git a/linux/drivers/media/video/tvp5150.c b/linux/drivers/media/video/tvp5150.c index f968e8941..e1046ed3f 100644 --- a/linux/drivers/media/video/tvp5150.c +++ b/linux/drivers/media/video/tvp5150.c @@ -1195,7 +1195,6 @@ MODULE_DEVICE_TABLE(i2c, tvp5150_id); #endif static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tvp5150", - .driverid = I2C_DRIVERID_TVP5150, .command = tvp5150_command, .probe = tvp5150_probe, .remove = tvp5150_remove, diff --git a/linux/drivers/media/video/upd64031a.c b/linux/drivers/media/video/upd64031a.c index 9d20ff69d..0fd1c9312 100644 --- a/linux/drivers/media/video/upd64031a.c +++ b/linux/drivers/media/video/upd64031a.c @@ -275,7 +275,6 @@ MODULE_DEVICE_TABLE(i2c, upd64031a_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "upd64031a", - .driverid = I2C_DRIVERID_UPD64031A, .command = upd64031a_command, .probe = upd64031a_probe, .remove = upd64031a_remove, diff --git a/linux/drivers/media/video/upd64083.c b/linux/drivers/media/video/upd64083.c index a897d0856..aed167493 100644 --- a/linux/drivers/media/video/upd64083.c +++ b/linux/drivers/media/video/upd64083.c @@ -247,7 +247,6 @@ MODULE_DEVICE_TABLE(i2c, upd64083_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "upd64083", - .driverid = I2C_DRIVERID_UPD64083, .command = upd64083_command, .probe = upd64083_probe, .remove = upd64083_remove, diff --git a/linux/drivers/media/video/vp27smpx.c b/linux/drivers/media/video/vp27smpx.c index b3b3ee61d..3104d0e1f 100644 --- a/linux/drivers/media/video/vp27smpx.c +++ b/linux/drivers/media/video/vp27smpx.c @@ -217,7 +217,6 @@ MODULE_DEVICE_TABLE(i2c, vp27smpx_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "vp27smpx", - .driverid = I2C_DRIVERID_VP27SMPX, .command = vp27smpx_command, .probe = vp27smpx_probe, .remove = vp27smpx_remove, diff --git a/linux/drivers/media/video/wm8739.c b/linux/drivers/media/video/wm8739.c index ac81c6442..df7d6a094 100644 --- a/linux/drivers/media/video/wm8739.c +++ b/linux/drivers/media/video/wm8739.c @@ -351,7 +351,6 @@ MODULE_DEVICE_TABLE(i2c, wm8739_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "wm8739", - .driverid = I2C_DRIVERID_WM8739, .command = wm8739_command, .probe = wm8739_probe, .remove = wm8739_remove, -- cgit v1.2.3 From b34bef7d48726a37eea205ac8fafccadd6c23b67 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 29 Jan 2009 20:34:25 +0100 Subject: gspca - vc032x: Add resolution 1280x1024 for sensor mi1310_soc. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/vc032x.c | 108 ++++++++++++++----------------- 1 file changed, 50 insertions(+), 58 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/vc032x.c b/linux/drivers/media/video/gspca/vc032x.c index 01d886d06..45ece4a45 100644 --- a/linux/drivers/media/video/gspca/vc032x.c +++ b/linux/drivers/media/video/gspca/vc032x.c @@ -149,6 +149,11 @@ static const struct v4l2_pix_format vc0323_mode[] = { .sizeimage = 640 * 480 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 0}, + {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, /* mi1310_soc only */ + .bytesperline = 1280, + .sizeimage = 1280 * 1024 * 1 / 4 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 2}, }; static const struct v4l2_pix_format svga_mode[] = { @@ -623,7 +628,6 @@ static const __u8 mi1310_socinitQVGA_JPG[][4] = { {0xb8, 0xa0, 0x12, 0xcc}, {}, }; -#if 0 static const u8 mi1310_soc_InitSXGA_JPG[][4] = { {0xb0, 0x03, 0x19, 0xcc}, {0xb0, 0x04, 0x02, 0xcc}, @@ -731,7 +735,6 @@ static const u8 mi1310_soc_InitSXGA_JPG[][4] = { {0xb8, 0xa0, 0x12, 0xcc}, {} }; -#endif static const __u8 mi1320_gamma[17] = { 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, @@ -2157,7 +2160,10 @@ static int sd_config(struct gspca_dev *gspca_dev, } else { if (sensor != SENSOR_PO1200) { cam->cam_mode = vc0323_mode; - cam->nmodes = ARRAY_SIZE(vc0323_mode); + if (sd->sensor != SENSOR_MI1310_SOC) + cam->nmodes = ARRAY_SIZE(vc0323_mode); + else /* no SXGA */ + cam->nmodes = ARRAY_SIZE(vc0323_mode) - 1; } else { cam->cam_mode = svga_mode; cam->nmodes = ARRAY_SIZE(svga_mode); @@ -2259,6 +2265,7 @@ static void setsharpness(struct gspca_dev *gspca_dev) static int sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + const __u8 (*init)[4]; const __u8 *GammaT = NULL; const __u8 *MatrixT = NULL; int mode; @@ -2276,96 +2283,81 @@ static int sd_start(struct gspca_dev *gspca_dev) case SENSOR_HV7131R: GammaT = hv7131r_gamma; MatrixT = hv7131r_matrix; - if (mode) { - /* 320x240 */ - usb_exchange(gspca_dev, hv7131r_initQVGA_data); - } else { - /* 640x480 */ - usb_exchange(gspca_dev, hv7131r_initVGA_data); - } + if (mode) + init = hv7131r_initQVGA_data; /* 320x240 */ + else + init = hv7131r_initVGA_data; /* 640x480 */ break; case SENSOR_OV7660: GammaT = ov7660_gamma; MatrixT = ov7660_matrix; - if (mode) { - /* 320x240 */ - usb_exchange(gspca_dev, ov7660_initQVGA_data); - } else { - /* 640x480 */ - usb_exchange(gspca_dev, ov7660_initVGA_data); - } + if (mode) + init = ov7660_initQVGA_data; /* 320x240 */ + else + init = ov7660_initVGA_data; /* 640x480 */ break; case SENSOR_OV7670: /*GammaT = ov7660_gamma; */ /*MatrixT = ov7660_matrix; */ - if (mode) { - /* 320x240 */ - usb_exchange(gspca_dev, ov7670_initQVGA_JPG); - } else { - /* 640x480 */ - usb_exchange(gspca_dev, ov7670_initVGA_JPG); - } + if (mode) + init = ov7670_initQVGA_JPG; /* 320x240 */ + else + init = ov7670_initVGA_JPG; /* 640x480 */ break; case SENSOR_MI0360: GammaT = mi1320_gamma; MatrixT = mi0360_matrix; - if (mode) { - /* 320x240 */ - usb_exchange(gspca_dev, mi0360_initQVGA_JPG); - } else { - /* 640x480 */ - usb_exchange(gspca_dev, mi0360_initVGA_JPG); - } + if (mode) + init = mi0360_initQVGA_JPG; /* 320x240 */ + else + init = mi0360_initVGA_JPG; /* 640x480 */ break; case SENSOR_MI1310_SOC: GammaT = mi1320_gamma; MatrixT = mi0360_matrix; - if (mode) { - /* 320x240 */ - usb_exchange(gspca_dev, mi1310_socinitQVGA_JPG); - } else { - /* 640x480 */ - usb_exchange(gspca_dev, mi1310_socinitVGA_JPG); + switch (mode) { + case 1: + init = mi1310_socinitQVGA_JPG; /* 320x240 */ + break; + case 0: + init = mi1310_socinitVGA_JPG; /* 640x480 */ + break; + default: + init = mi1310_soc_InitSXGA_JPG; /* 1280xq024 */ + break; } break; case SENSOR_MI1320: GammaT = mi1320_gamma; MatrixT = mi1320_matrix; - if (mode) { - /* 320x240 */ - usb_exchange(gspca_dev, mi1320_initQVGA_data); - } else { - /* 640x480 */ - usb_exchange(gspca_dev, mi1320_initVGA_data); - } + if (mode) + init = mi1320_initQVGA_data; /* 320x240 */ + else + init = mi1320_initVGA_data; /* 640x480 */ break; case SENSOR_PO3130NC: GammaT = po3130_gamma; MatrixT = po3130_matrix; - if (mode) { - /* 320x240 */ - usb_exchange(gspca_dev, po3130_initQVGA_data); - } else { - /* 640x480 */ - usb_exchange(gspca_dev, po3130_initVGA_data); - } - usb_exchange(gspca_dev, po3130_rundata); + if (mode) + init = po3130_initQVGA_data; /* 320x240 */ + else + init = po3130_initVGA_data; /* 640x480 */ + usb_exchange(gspca_dev, init); + init = po3130_rundata; break; - case SENSOR_PO1200: + default: +/* case SENSOR_PO1200: */ GammaT = po1200_gamma; MatrixT = po1200_matrix; - usb_exchange(gspca_dev, po1200_initVGA_data); + init = po1200_initVGA_data; break; - default: - PDEBUG(D_PROBE, "Damned !! no sensor found Bye"); - return -EMEDIUMTYPE; } + usb_exchange(gspca_dev, init); if (GammaT && MatrixT) { put_tab_to_reg(gspca_dev, GammaT, 17, 0xb84a); put_tab_to_reg(gspca_dev, GammaT, 17, 0xb85b); put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c); put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c); - /* Seem SHARPNESS */ /* reg_w(gspca_dev->dev, 0xa0, 0x80, 0xb80a); -- cgit v1.2.3 From f1ee371d5b7780d8c85202d55a6602f61abb50b6 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Fri, 30 Jan 2009 02:57:07 +0200 Subject: Bug fix: Restore HVR-4000 tuning. From: Igor M. Liplianin Some cards uses cx24116 LNB_DC pin for LNB power control, some not uses, some uses it different way, like HVR-4000. Signed-off-by: Igor M. Liplianin Tested-by : Edgar Hucek --- linux/drivers/media/dvb/frontends/cx24116.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/cx24116.c b/linux/drivers/media/dvb/frontends/cx24116.c index db1e1e4ea..8301a9865 100644 --- a/linux/drivers/media/dvb/frontends/cx24116.c +++ b/linux/drivers/media/dvb/frontends/cx24116.c @@ -1184,7 +1184,12 @@ static int cx24116_initfe(struct dvb_frontend *fe) if (ret != 0) return ret; - return cx24116_diseqc_init(fe); + ret = cx24116_diseqc_init(fe); + if (ret != 0) + return ret; + + /* HVR-4000 needs this */ + return cx24116_set_voltage(fe, SEC_VOLTAGE_13); } /* -- cgit v1.2.3 From 173b6c4977dc5d99c1273fe0e139dc6d5d6f7d6e Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 30 Jan 2009 16:14:02 +0100 Subject: gspca - sonixj: Bad initialization of sensor mt9v111. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index a16f21be3..5b5e526d8 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -1580,6 +1580,7 @@ static int sd_start(struct gspca_dev *gspca_dev) /* reg1 = 0x06; * 640 clk 24Mz (done) */ reg17 = 0xe2; } + break; case SENSOR_OM6802: om6802_InitSensor(gspca_dev); reg17 = 0x64; /* 640 MCKSIZE */ -- cgit v1.2.3 From 1a68aa3086f7f370d97adff8c3de35669c02f6f5 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 30 Jan 2009 20:21:45 -0500 Subject: cx18: Defer A/V core initialization until a valid cx18_av_cmd arrives From: Andy Walls Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-av-core.c | 40 ++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 7 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-av-core.c b/linux/drivers/media/video/cx18/cx18-av-core.c index 0b1c84b4d..50979d333 100644 --- a/linux/drivers/media/video/cx18/cx18-av-core.c +++ b/linux/drivers/media/video/cx18/cx18-av-core.c @@ -680,19 +680,45 @@ static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt) /* ----------------------------------------------------------------------- */ +static int valid_av_cmd(unsigned int cmd) +{ + switch (cmd) { + /* All commands supported by cx18_av_cmd() */ + case VIDIOC_INT_DECODE_VBI_LINE: + case VIDIOC_INT_AUDIO_CLOCK_FREQ: + case VIDIOC_STREAMON: + case VIDIOC_STREAMOFF: + case VIDIOC_LOG_STATUS: + case VIDIOC_G_CTRL: + case VIDIOC_S_CTRL: + case VIDIOC_QUERYCTRL: + case VIDIOC_G_STD: + case VIDIOC_S_STD: + case AUDC_SET_RADIO: + case VIDIOC_INT_G_VIDEO_ROUTING: + case VIDIOC_INT_S_VIDEO_ROUTING: + case VIDIOC_INT_G_AUDIO_ROUTING: + case VIDIOC_INT_S_AUDIO_ROUTING: + case VIDIOC_S_FREQUENCY: + case VIDIOC_G_TUNER: + case VIDIOC_S_TUNER: + case VIDIOC_G_FMT: + case VIDIOC_S_FMT: + case VIDIOC_INT_RESET: + return 1; + default: + return 0; + } + return 0; +} + int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg) { struct cx18_av_state *state = &cx->av_state; struct v4l2_tuner *vt = arg; struct v4l2_routing *route = arg; - /* ignore these commands */ - switch (cmd) { - case TUNER_SET_TYPE_ADDR: - return 0; - } - - if (!state->is_initialized) { + if (!state->is_initialized && valid_av_cmd(cmd)) { CX18_DEBUG_INFO("cmd %08x triggered fw load\n", cmd); /* initialize on first use */ state->is_initialized = 1; -- cgit v1.2.3 From bb9067ce37544bf82eebcee5ce959dcef1720113 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 30 Jan 2009 20:39:26 -0500 Subject: cx18: Smarter verification of CX18_AUDIO_ENABLE register writes From: Andy Walls The CX18_AUDIO_ENABLE register usually never reads back what was just written under normal circumstances. Perform better checking that a write went to the register as expected with a specification of what bits to verify. Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-audio.c | 3 +-- linux/drivers/media/video/cx18/cx18-av-firmware.c | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-audio.c b/linux/drivers/media/video/cx18/cx18-audio.c index 57beddf0a..d19bd778c 100644 --- a/linux/drivers/media/video/cx18/cx18-audio.c +++ b/linux/drivers/media/video/cx18/cx18-audio.c @@ -64,8 +64,7 @@ int cx18_audio_set_io(struct cx18 *cx) val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30; val |= (audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 : (audio_input << 4); - cx18_write_reg(cx, val | 0xb00, CX18_AUDIO_ENABLE); - cx18_vapi(cx, CX18_APU_RESETAI, 1, 0); + cx18_write_reg_expect(cx, val | 0xb00, CX18_AUDIO_ENABLE, val, 0x30); return 0; } diff --git a/linux/drivers/media/video/cx18/cx18-av-firmware.c b/linux/drivers/media/video/cx18/cx18-av-firmware.c index b374c74d3..940ea9352 100644 --- a/linux/drivers/media/video/cx18/cx18-av-firmware.c +++ b/linux/drivers/media/video/cx18/cx18-av-firmware.c @@ -131,7 +131,8 @@ int cx18_av_loadfw(struct cx18 *cx) v = cx18_read_reg(cx, CX18_AUDIO_ENABLE); /* If bit 11 is 1, clear bit 10 */ if (v & 0x800) - cx18_write_reg(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE); + cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE, + 0, 0x400); /* Enable WW auto audio standard detection */ v = cx18_av_read4(cx, CXADEC_STD_DET_CTL); -- cgit v1.2.3 From a5bbba89bd5698bdbde479d385a44a7b9bdecb70 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 30 Jan 2009 20:48:40 -0500 Subject: cx18: Normalize APU after second APU firmware load From: Andy Walls Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-driver.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-driver.c b/linux/drivers/media/video/cx18/cx18-driver.c index fe2324ef2..f48d18f69 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.c +++ b/linux/drivers/media/video/cx18/cx18-driver.c @@ -1085,6 +1085,19 @@ int cx18_init_on_first_open(struct cx18 *cx) return -ENXIO; } + /* + * The second firmware load requires us to normalize the APU state, + * or the audio for the first analog capture will be badly incorrect. + * + * I can't seem to call APU_RESETAI and have it succeed without the + * APU capturing audio, so we start and stop it here to do the reset + */ + + /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */ + cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0); + cx18_vapi(cx, CX18_APU_RESETAI, 0); + cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG); + vf.tuner = 0; vf.type = V4L2_TUNER_ANALOG_TV; vf.frequency = 6400; /* the tuner 'baseline' frequency */ -- cgit v1.2.3 From adbc75d3cf3691d649c8dac1f32ee21f332f0f4c Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 30 Jan 2009 22:33:02 -0500 Subject: cx18: Clean-up and enable sliced VBI handling From: Andy Walls Removed legacy ivtv state variables, added comments, and cleaned up sliced VBI related code. Enabled sliced VBI. Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-av-core.c | 11 +- linux/drivers/media/video/cx18/cx18-av-vbi.c | 92 ++++++++++++---- linux/drivers/media/video/cx18/cx18-cards.c | 8 +- linux/drivers/media/video/cx18/cx18-cards.h | 3 +- linux/drivers/media/video/cx18/cx18-controls.c | 4 +- linux/drivers/media/video/cx18/cx18-driver.c | 49 +-------- linux/drivers/media/video/cx18/cx18-driver.h | 142 ++++++++++++++++++------- linux/drivers/media/video/cx18/cx18-fileops.c | 54 +++++++--- linux/drivers/media/video/cx18/cx18-ioctl.c | 23 +--- linux/drivers/media/video/cx18/cx18-streams.c | 45 ++++++-- linux/drivers/media/video/cx18/cx18-vbi.c | 58 +++++++--- 11 files changed, 311 insertions(+), 178 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-av-core.c b/linux/drivers/media/video/cx18/cx18-av-core.c index 0b1c84b4d..5279b8e45 100644 --- a/linux/drivers/media/video/cx18/cx18-av-core.c +++ b/linux/drivers/media/video/cx18/cx18-av-core.c @@ -169,9 +169,14 @@ static void cx18_av_initialize(struct cx18 *cx) /* Set VGA_TRACK_RANGE to 0x20 */ cx18_av_and_or4(cx, CXADEC_DFE_CTRL2, 0xFFFF00FF, 0x00002000); - /* Enable VBI capture */ - cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253F); - /* cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253E); */ + /* + * Initial VBI setup + * VIP-1.1, 10 bit mode, enable Raw, disable sliced, + * don't clamp raw samples when codes are in use, 4 byte user D-words, + * programmed IDID, RP code V bit transition on VBLANK, data during + * blanking intervals + */ + cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010252e); /* Set the video input. The setting in MODE_CTRL gets lost when we do the above setup */ diff --git a/linux/drivers/media/video/cx18/cx18-av-vbi.c b/linux/drivers/media/video/cx18/cx18-av-vbi.c index 1527ea4f6..72325d774 100644 --- a/linux/drivers/media/video/cx18/cx18-av-vbi.c +++ b/linux/drivers/media/video/cx18/cx18-av-vbi.c @@ -24,6 +24,52 @@ #include "cx18-driver.h" +/* + * For sliced VBI output, we set up to use VIP-1.1, 10-bit mode, + * NN counts 4 bytes Dwords, an IDID of 0x00 0x80 or one with the VBI line #. + * Thus, according to the VIP-2 Spec, our VBI ancillary data lines + * (should!) look like: + * 4 byte EAV code: 0xff 0x00 0x00 0xRP + * unknown number of possible idle bytes + * 3 byte Anc data preamble: 0x00 0xff 0xff + * 1 byte data identifier: ne010iii (parity bits, 010, DID bits) + * 1 byte secondary data id: nessssss (parity bits, SDID bits) + * 1 byte data word count: necccccc (parity bits, NN Dword count) + * 2 byte Internal DID: 0x00 0x80 (programmed value) + * 4*NN data bytes + * 1 byte checksum + * Fill bytes needed to fil out to 4*NN bytes of payload + * + * The RP codes for EAVs when in VIP-1.1 mode, not in raw mode, & + * in the vertical blanking interval are: + * 0xb0 (Task 0 VerticalBlank HorizontalBlank 0 0 0 0) + * 0xf0 (Task EvenField VerticalBlank HorizontalBlank 0 0 0 0) + * + * Since the V bit is only allowed to toggle in the EAV RP code, just + * before the first active region line and for active lines, they are: + * 0x90 (Task 0 0 HorizontalBlank 0 0 0 0) + * 0xd0 (Task EvenField 0 HorizontalBlank 0 0 0 0) + * + * The user application DID bytes we care about are: + * 0x91 (1 0 010 0 !ActiveLine AncDataPresent) + * 0x55 (0 1 010 2ndField !ActiveLine AncDataPresent) + * + */ +static const u8 sliced_vbi_did[2] = { 0x91, 0x55 }; + +struct vbi_anc_data { + /* u8 eav[4]; */ + /* u8 idle[]; Variable number of idle bytes */ + u8 preamble[3]; + u8 did; + u8 sdid; + u8 data_count; + u8 idid[2]; + u8 payload[1]; /* 4*data_count of payload */ + /* u8 checksum; */ + /* u8 fill[]; Variable number of fill bytes */ +}; + static int odd_parity(u8 c) { c ^= (c >> 4); @@ -96,7 +142,7 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg) 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ 0, V4L2_SLICED_WSS_625, 0, /* 4 */ V4L2_SLICED_CAPTION_525, /* 6 */ - 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ + V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 - unlike cx25840 */ 0, 0, 0, 0 }; int is_pal = !(state->std & V4L2_STD_525_60); @@ -220,47 +266,53 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg) case VIDIOC_INT_DECODE_VBI_LINE: { struct v4l2_decode_vbi_line *vbi = arg; - u8 *p = vbi->p; - int id1, id2, l, err = 0; - - if (p[0] || p[1] != 0xff || p[2] != 0xff || - (p[3] != 0x55 && p[3] != 0x91)) { + u8 *p; + struct vbi_anc_data *anc = (struct vbi_anc_data *) vbi->p; + int did, sdid, l, err = 0; + + /* + * Check for the ancillary data header for sliced VBI + */ + if (anc->preamble[0] || + anc->preamble[1] != 0xff || anc->preamble[2] != 0xff || + (anc->did != sliced_vbi_did[0] && + anc->did != sliced_vbi_did[1])) { vbi->line = vbi->type = 0; break; } - p += 4; - id1 = p[-1]; - id2 = p[0] & 0xf; - l = p[2] & 0x3f; + did = anc->did; + sdid = anc->sdid & 0xf; + l = anc->idid[0] & 0x3f; l += state->vbi_line_offset; - p += 4; + p = anc->payload; - switch (id2) { + /* Decode the SDID set by the slicer */ + switch (sdid) { case 1: - id2 = V4L2_SLICED_TELETEXT_B; + sdid = V4L2_SLICED_TELETEXT_B; break; case 4: - id2 = V4L2_SLICED_WSS_625; + sdid = V4L2_SLICED_WSS_625; break; case 6: - id2 = V4L2_SLICED_CAPTION_525; + sdid = V4L2_SLICED_CAPTION_525; err = !odd_parity(p[0]) || !odd_parity(p[1]); break; - case 9: - id2 = V4L2_SLICED_VPS; + case 7: /* Differs from cx25840 */ + sdid = V4L2_SLICED_VPS; if (decode_vps(p, p) != 0) err = 1; break; default: - id2 = 0; + sdid = 0; err = 1; break; } - vbi->type = err ? 0 : id2; + vbi->type = err ? 0 : sdid; vbi->line = err ? 0 : l; - vbi->is_second_field = err ? 0 : (id1 == 0x55); + vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]); vbi->p = p; break; } diff --git a/linux/drivers/media/video/cx18/cx18-cards.c b/linux/drivers/media/video/cx18/cx18-cards.c index 53217cf45..c0177ce39 100644 --- a/linux/drivers/media/video/cx18/cx18-cards.c +++ b/linux/drivers/media/video/cx18/cx18-cards.c @@ -51,7 +51,7 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = { static const struct cx18_card cx18_card_hvr1600_esmt = { .type = CX18_CARD_HVR_1600_ESMT, .name = "Hauppauge HVR-1600", - .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", + .comment = "Simultaneous Digital and Analog TV capture supported\n", .v4l2_capabilities = CX18_CAP_ENCODER, .hw_audio_ctrl = CX18_HW_CX23418, .hw_muxer = CX18_HW_CS5345, @@ -97,7 +97,7 @@ static const struct cx18_card cx18_card_hvr1600_esmt = { static const struct cx18_card cx18_card_hvr1600_samsung = { .type = CX18_CARD_HVR_1600_SAMSUNG, .name = "Hauppauge HVR-1600 (Preproduction)", - .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", + .comment = "Simultaneous Digital and Analog TV capture supported\n", .v4l2_capabilities = CX18_CAP_ENCODER, .hw_audio_ctrl = CX18_HW_CX23418, .hw_muxer = CX18_HW_CS5345, @@ -152,7 +152,7 @@ static const struct cx18_card_pci_info cx18_pci_h900[] = { static const struct cx18_card cx18_card_h900 = { .type = CX18_CARD_COMPRO_H900, .name = "Compro VideoMate H900", - .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", + .comment = "Analog TV capture supported\n", .v4l2_capabilities = CX18_CAP_ENCODER, .hw_audio_ctrl = CX18_HW_CX23418, .hw_all = CX18_HW_TUNER, @@ -249,7 +249,7 @@ static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = { static const struct cx18_card cx18_card_cnxt_raptor_pal = { .type = CX18_CARD_CNXT_RAPTOR_PAL, .name = "Conexant Raptor PAL/SECAM", - .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", + .comment = "Analog TV capture supported\n", .v4l2_capabilities = CX18_CAP_ENCODER, .hw_audio_ctrl = CX18_HW_CX23418, .hw_muxer = CX18_HW_GPIO, diff --git a/linux/drivers/media/video/cx18/cx18-cards.h b/linux/drivers/media/video/cx18/cx18-cards.h index 6fa7bcb42..f8ee29f10 100644 --- a/linux/drivers/media/video/cx18/cx18-cards.h +++ b/linux/drivers/media/video/cx18/cx18-cards.h @@ -49,8 +49,7 @@ /* V4L2 capability aliases */ #define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \ V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | \ - V4L2_CAP_VBI_CAPTURE) -/* | V4L2_CAP_SLICED_VBI_CAPTURE) not yet */ + V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE) struct cx18_card_video_input { u8 video_type; /* video input type */ diff --git a/linux/drivers/media/video/cx18/cx18-controls.c b/linux/drivers/media/video/cx18/cx18-controls.c index 17edf305d..6af4d5c19 100644 --- a/linux/drivers/media/video/cx18/cx18-controls.c +++ b/linux/drivers/media/video/cx18/cx18-controls.c @@ -178,8 +178,8 @@ static int cx18_setup_vbi_fmt(struct cx18 *cx, enum v4l2_mpeg_stream_vbi_fmt fmt int i; for (i = 0; i < CX18_VBI_FRAMES; i++) { - /* Yuck, hardcoded. Needs to be a define */ - cx->vbi.sliced_mpeg_data[i] = kmalloc(2049, GFP_KERNEL); + cx->vbi.sliced_mpeg_data[i] = + kmalloc(CX18_SLICED_MPEG_DATA_BUFSZ, GFP_KERNEL); if (cx->vbi.sliced_mpeg_data[i] == NULL) { while (--i >= 0) { kfree(cx->vbi.sliced_mpeg_data[i]); diff --git a/linux/drivers/media/video/cx18/cx18-driver.c b/linux/drivers/media/video/cx18/cx18-driver.c index fe2324ef2..f3a50f673 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.c +++ b/linux/drivers/media/video/cx18/cx18-driver.c @@ -593,7 +593,8 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) (cx->params.video_temporal_filter_mode << 1) | (cx->params.video_median_filter_type << 2); cx->params.port = CX2341X_PORT_MEMORY; - cx->params.capabilities = CX2341X_CAP_HAS_TS | CX2341X_CAP_HAS_AC3; + cx->params.capabilities = + CX2341X_CAP_HAS_TS | CX2341X_CAP_HAS_AC3 | CX2341X_CAP_HAS_SLICED_VBI; init_waitqueue_head(&cx->cap_w); init_waitqueue_head(&cx->mb_apu_waitq); init_waitqueue_head(&cx->mb_cpu_waitq); @@ -603,49 +604,6 @@ 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; - /* - * The VBI line sizes depend on the pixel clock and the horiz rate - * - * (1/Fh)*(2*Fp) = Samples/line - * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples - * - * Sliced VBI is sent as ancillary data during horizontal blanking - * Raw VBI is sent as active video samples during vertcal blanking - * - * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line - * length of 720 pixels @ 4:2:2 sampling. Thus... - * - * For systems that use a 15.734 kHz horizontal rate, such as - * NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have: - * - * (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line = - * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples - * - * For systems that use a 15.625 kHz horizontal rate, such as - * PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have: - * - * (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line = - * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples - * - */ - - /* FIXME: init these based on tuner std & modify when std changes */ - /* CX18-AV-Core number of VBI samples output per horizontal line */ - cx->vbi.raw_decoder_line_size = 1444; /* 4 byte SAV + 2 * 720 */ - cx->vbi.sliced_decoder_line_size = 272; /* 60 Hz: 268+4, 50 Hz: 280+4 */ - - /* CX18-AV-Core VBI samples/line possibly rounded up */ - cx->vbi.raw_size = 1444; /* Real max size is 1444 */ - cx->vbi.sliced_size = 284; /* Real max size is 284 */ - - /* - * CX18-AV-Core SAV/EAV RP codes in VIP 1.x mode - * Task Field VerticalBlank HorizontalBlank 0 0 0 0 - */ - cx->vbi.raw_decoder_sav_odd_field = 0x20; /* V */ - cx->vbi.raw_decoder_sav_even_field = 0x60; /* FV */ - cx->vbi.sliced_decoder_sav_odd_field = 0xB0; /* T VH - actually EAV */ - cx->vbi.sliced_decoder_sav_even_field = 0xF0; /* TFVH - actually EAV */ return 0; } @@ -678,7 +636,6 @@ static void __devinit cx18_init_struct2(struct cx18 *cx) cx->av_state.aud_input = CX18_AV_AUDIO8; cx->av_state.audclk_freq = 48000; cx->av_state.audmode = V4L2_TUNER_MODE_LANG1; - /* FIXME - 8 is NTSC value, investigate */ cx->av_state.vbi_line_offset = 8; } @@ -943,7 +900,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, * suboptimal, as the CVBS and SVideo inputs could use a different std * and the buffer could end up being too small in that case. */ - vbi_buf_size = cx->vbi.raw_size * (cx->is_60hz ? 24 : 36) / 2; + vbi_buf_size = vbi_active_samples * (cx->is_60hz ? 24 : 36) / 2; cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size; if (cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] < 0) diff --git a/linux/drivers/media/video/cx18/cx18-driver.h b/linux/drivers/media/video/cx18/cx18-driver.h index 3a21013cd..d2829f576 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.h +++ b/linux/drivers/media/video/cx18/cx18-driver.h @@ -319,59 +319,121 @@ struct cx18_open_id { /* forward declaration of struct defined in cx18-cards.h */ struct cx18_card; +/* + * A note about "sliced" VBI data as implemented in this driver: + * + * Currently we collect the sliced VBI in the form of Ancillary Data + * packets, inserted by the AV core decoder/digitizer/slicer in the + * horizontal blanking region of the VBI lines, in "raw" mode as far as + * the Encoder is concerned. We don't ever tell the Encoder itself + * to provide sliced VBI. (AV Core: sliced mode - Encoder: raw mode) + * + * We then process the ancillary data ourselves to send the sliced data + * to the user application directly or build up MPEG-2 private stream 1 + * packets to splice into (only!) MPEG-2 PS streams for the user app. + * + * (That's how ivtv essentially does it.) + * + * The Encoder should be able to extract certain sliced VBI data for + * us and provide it in a separate stream or splice it into any type of + * MPEG PS or TS stream, but this isn't implemented yet. + */ + +/* + * Number of "raw" VBI samples per horizontal line we tell the Encoder to + * grab from the decoder/digitizer/slicer output for raw or sliced VBI. + * It depends on the pixel clock and the horiz rate: + * + * (1/Fh)*(2*Fp) = Samples/line + * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples + * + * Sliced VBI data is sent as ancillary data during horizontal blanking + * Raw VBI is sent as active video samples during vertcal blanking + * + * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line + * length of 720 pixels @ 4:2:2 sampling. Thus... + * + * For systems that use a 15.734 kHz horizontal rate, such as + * NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have: + * + * (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line = + * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples + * + * For systems that use a 15.625 kHz horizontal rate, such as + * PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have: + * + * (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line = + * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples + */ +static const u32 vbi_active_samples = 1444; /* 4 byte SAV + 720 Y + 720 U/V */ +static const u32 vbi_hblank_samples_60Hz = 272; /* 4 byte EAV + 268 anc/fill */ +static const u32 vbi_hblank_samples_50Hz = 284; /* 4 byte EAV + 280 anc/fill */ #define CX18_VBI_FRAMES 32 -/* VBI data */ struct vbi_info { - u32 enc_size; - u32 frame; - u8 cc_data_odd[256]; - u8 cc_data_even[256]; - int cc_pos; - u8 cc_no_update; - u8 vps[5]; - u8 vps_found; - int wss; - u8 wss_found; - u8 wss_no_update; - u32 raw_decoder_line_size; - u8 raw_decoder_sav_odd_field; - u8 raw_decoder_sav_even_field; - u32 sliced_decoder_line_size; - u8 sliced_decoder_sav_odd_field; - u8 sliced_decoder_sav_even_field; + /* Current state of v4l2 VBI settings for this device */ struct v4l2_format in; - /* convenience pointer to sliced struct in vbi_in union */ - struct v4l2_sliced_vbi_format *sliced_in; - u32 service_set_in; - int insert_mpeg; + struct v4l2_sliced_vbi_format *sliced_in; /* pointer to in.fmt.sliced */ + u32 count; /* Count of VBI data lines: 60 Hz: 12 or 50 Hz: 18 */ + u32 start[2]; /* First VBI data line per field: 10 & 273 or 6 & 318 */ - /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines. - One for /dev/vbi0 and one for /dev/vbi8 */ - struct v4l2_sliced_vbi_data sliced_data[36]; + u32 frame; /* Count of VBI buffers/frames received from Encoder */ - /* Buffer for VBI data inserted into MPEG stream. - The first byte is a dummy byte that's never used. - The next 16 bytes contain the MPEG header for the VBI data, - the remainder is the actual VBI data. - The max size accepted by the MPEG VBI reinsertion turns out - to be 1552 bytes, which happens to be 4 + (1 + 42) * (2 * 18) bytes, - where 4 is a four byte header, 42 is the max sliced VBI payload, 1 is - a single line header byte and 2 * 18 is the number of VBI lines per frame. + /* + * Vars for creation and insertion of MPEG Private Stream 1 packets + * of sliced VBI data into an MPEG PS + */ - However, it seems that the data must be 1K aligned, so we have to - pad the data until the 1 or 2 K boundary. + /* Boolean: create and insert Private Stream 1 packets into the PS */ + int insert_mpeg; + + /* + * Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines. + * Used in cx18-vbi.c only for collecting sliced data, and as a source + * during conversion of sliced VBI data into MPEG Priv Stream 1 packets. + * We don't need to save state here, but the array may have been a bit + * too big (2304 bytes) to alloc from the stack. + */ + struct v4l2_sliced_vbi_data sliced_data[36]; - This pointer array will allocate 2049 bytes to store each VBI frame. */ + /* + * A ring buffer of driver-generated MPEG-2 PS + * Program Pack/Private Stream 1 packets for sliced VBI data insertion + * into the MPEG PS stream. + * + * In each sliced_mpeg_data[] buffer is: + * 16 byte MPEG-2 PS Program Pack Header + * 16 byte MPEG-2 Private Stream 1 PES Header + * 4 byte magic number: "itv0" or "ITV0" + * 4 byte first field line mask, if "itv0" + * 4 byte second field line mask, if "itv0" + * 36 lines, if "ITV0"; or <36 lines, if "itv0"; of sliced VBI data + * + * Each line in the payload is + * 1 byte line header derived from the SDID (WSS, CC, VPS, etc.) + * 42 bytes of line data + * + * That's a maximum 1552 bytes of payload in the Private Stream 1 packet + * which is the payload size a PVR-350 (CX23415) MPEG decoder will + * accept for VBI data. So, including the headers, it's a maximum 1584 + * bytes total. + */ +#define CX18_SLICED_MPEG_DATA_MAXSZ 1584 + /* copy_vbi_buf() needs 8 temp bytes on the end for the worst case */ +#define CX18_SLICED_MPEG_DATA_BUFSZ (CX18_SLICED_MPEG_DATA_MAXSZ+8) u8 *sliced_mpeg_data[CX18_VBI_FRAMES]; u32 sliced_mpeg_size[CX18_VBI_FRAMES]; - struct cx18_buffer sliced_mpeg_buf; + + /* Count of Program Pack/Program Stream 1 packets inserted into PS */ u32 inserted_frame; - u32 start[2], count; - u32 raw_size; - u32 sliced_size; + /* + * A dummy driver stream transfer 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_buffer sliced_mpeg_buf; }; /* Per cx23418, per I2C bus private algo callback data */ diff --git a/linux/drivers/media/video/cx18/cx18-fileops.c b/linux/drivers/media/video/cx18/cx18-fileops.c index 36c380b66..7d979ea28 100644 --- a/linux/drivers/media/video/cx18/cx18-fileops.c +++ b/linux/drivers/media/video/cx18/cx18-fileops.c @@ -209,9 +209,9 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, *err = 0; while (1) { if (s->type == CX18_ENC_STREAM_TYPE_MPG) { -#if 0 /* Process pending program info updates and pending VBI data */ +#if 0 cx18_update_pgm_info(cx); #endif @@ -298,6 +298,20 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s, len = ucount; if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG && !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) { + /* + * Try to find a good splice point in the PS, just before + * an MPEG-2 Program Pack start code, and provide only + * up to that point to the user, so it's easy to insert VBI data + * the next time around. + */ + /* FIXME - This only works for an MPEG-2 PS, not a TS */ + /* + * An MPEG-2 Program Stream (PS) is a series of + * MPEG-2 Program Packs terminated by an + * MPEG Program End Code after the last Program Pack. + * A Program Pack may hold a PS System Header packet and any + * number of Program Elementary Stream (PES) Packets + */ const char *start = buf->buf + buf->readpos; const char *p = start + 1; const u8 *q; @@ -305,38 +319,54 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s, int stuffing, i; while (start + len > p) { + /* Scan for a 0 to find a potential MPEG-2 start code */ q = memchr(p, 0, start + len - p); if (q == NULL) break; p = q + 1; + /* + * Keep looking if not a + * MPEG-2 Pack header start code: 0x00 0x00 0x01 0xba + * or MPEG-2 video PES start code: 0x00 0x00 0x01 0xe0 + */ if ((char *)q + 15 >= buf->buf + buf->bytesused || q[1] != 0 || q[2] != 1 || q[3] != ch) continue; + + /* If expecting the primary video PES */ if (!cx->search_pack_header) { + /* Continue if it couldn't be a PES packet */ if ((q[6] & 0xc0) != 0x80) continue; - if (((q[7] & 0xc0) == 0x80 && - (q[9] & 0xf0) == 0x20) || - ((q[7] & 0xc0) == 0xc0 && - (q[9] & 0xf0) == 0x30)) { - ch = 0xba; + /* Check if a PTS or PTS & DTS follow */ + if (((q[7] & 0xc0) == 0x80 && /* PTS only */ + (q[9] & 0xf0) == 0x20) || /* PTS only */ + ((q[7] & 0xc0) == 0xc0 && /* PTS & DTS */ + (q[9] & 0xf0) == 0x30)) { /* DTS follows */ + /* Assume we found the video PES hdr */ + ch = 0xba; /* next want a Program Pack*/ cx->search_pack_header = 1; - p = q + 9; + p = q + 9; /* Skip this video PES hdr */ } continue; } + + /* We may have found a Program Pack start code */ + + /* Get the count of stuffing bytes & verify them */ stuffing = q[13] & 7; /* all stuffing bytes must be 0xff */ for (i = 0; i < stuffing; i++) if (q[14 + i] != 0xff) break; - if (i == stuffing && - (q[4] & 0xc4) == 0x44 && - (q[12] & 3) == 3 && - q[14 + stuffing] == 0 && + if (i == stuffing && /* right number of stuffing bytes*/ + (q[4] & 0xc4) == 0x44 && /* marker check */ + (q[12] & 3) == 3 && /* marker check */ + q[14 + stuffing] == 0 && /* PES Pack or Sys Hdr */ q[15 + stuffing] == 0 && q[16 + stuffing] == 1) { - cx->search_pack_header = 0; + /* 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); break; diff --git a/linux/drivers/media/video/cx18/cx18-ioctl.c b/linux/drivers/media/video/cx18/cx18-ioctl.c index 4a49b0819..645c41937 100644 --- a/linux/drivers/media/video/cx18/cx18-ioctl.c +++ b/linux/drivers/media/video/cx18/cx18-ioctl.c @@ -102,7 +102,6 @@ void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) } } -#if 0 static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) { int f, l; @@ -116,7 +115,6 @@ static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) } return set != 0; } -#endif u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt) { @@ -165,7 +163,7 @@ static int cx18_g_fmt_vbi_cap(struct file *file, void *fh, vbifmt->sampling_rate = 27000000; vbifmt->offset = 248; - vbifmt->samples_per_line = cx->vbi.raw_decoder_line_size - 4; + vbifmt->samples_per_line = vbi_active_samples - 4; vbifmt->sample_format = V4L2_PIX_FMT_GREY; vbifmt->start[0] = cx->vbi.start[0]; vbifmt->start[1] = cx->vbi.start[1]; @@ -179,8 +177,6 @@ static int cx18_g_fmt_vbi_cap(struct file *file, void *fh, static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) { -#if 0 - /* Supported by the cx23418 but not yet implemented. */ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; @@ -192,9 +188,6 @@ static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh, cx18_av_cmd(cx, VIDIOC_G_FMT, fmt); vbifmt->service_set = cx18_get_service_set(vbifmt); return 0; -#else - return -EINVAL; -#endif } static int cx18_try_fmt_vid_cap(struct file *file, void *fh, @@ -224,8 +217,6 @@ static int cx18_try_fmt_vbi_cap(struct file *file, void *fh, static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) { -#if 0 - /* Supported by the cx23418 but not yet implemented. */ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; @@ -238,9 +229,6 @@ static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh, check_service_set(vbifmt, cx->is_50hz); vbifmt->service_set = cx18_get_service_set(vbifmt); return 0; -#else - return -EINVAL; -#endif } static int cx18_s_fmt_vid_cap(struct file *file, void *fh, @@ -296,8 +284,6 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh, static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) { -#if 0 - /* Supported by the cx23418 but not yet implemented. */ struct cx18_open_id *id = fh; struct cx18 *cx = id->cx; int ret; @@ -320,9 +306,6 @@ static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh, cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in)); return 0; -#else - return -EINVAL; -#endif } static int cx18_g_chip_ident(struct file *file, void *fh, @@ -620,7 +603,6 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std) cx->vbi.count = cx->is_50hz ? 18 : 12; cx->vbi.start[0] = cx->is_50hz ? 6 : 10; cx->vbi.start[1] = cx->is_50hz ? 318 : 273; - cx->vbi.sliced_decoder_line_size = cx->is_60hz ? 272 : 284; CX18_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long) cx->std); @@ -671,8 +653,6 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) static int cx18_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap) { -#if 0 - /* Supported by the cx23418 but not yet implemented. */ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; int f, l; @@ -686,7 +666,6 @@ static int cx18_g_sliced_vbi_cap(struct file *file, void *fh, } return 0; } -#endif return -EINVAL; } diff --git a/linux/drivers/media/video/cx18/cx18-streams.c b/linux/drivers/media/video/cx18/cx18-streams.c index 88b101401..bcd786988 100644 --- a/linux/drivers/media/video/cx18/cx18-streams.c +++ b/linux/drivers/media/video/cx18/cx18-streams.c @@ -349,10 +349,6 @@ static void cx18_vbi_setup(struct cx18_stream *s) /* setup VBI registers */ cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in); - /* determine number of lines and total number of VBI bytes. - A raw line takes 1444 bytes: 4 byte SAV code + 2 * 720 - A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal - header, 42 data bytes + checksum (to be confirmed) */ if (raw) { lines = cx->vbi.count * 2; } else { @@ -361,24 +357,53 @@ static void cx18_vbi_setup(struct cx18_stream *s) lines += 2; } - cx->vbi.enc_size = lines * - (raw ? cx->vbi.raw_size : cx->vbi.sliced_size); - data[0] = s->handle; /* Lines per field */ data[1] = (lines / 2) | ((lines / 2) << 16); /* bytes per line */ - data[2] = (raw ? cx->vbi.raw_decoder_line_size - : cx->vbi.sliced_decoder_line_size); + data[2] = (raw ? vbi_active_samples + : (cx->is_60hz ? vbi_hblank_samples_60Hz + : vbi_hblank_samples_50Hz)); /* Every X number of frames a VBI interrupt arrives (frames as in 25 or 30 fps) */ data[3] = 1; - /* Setup VBI for the cx25840 digitizer */ + /* + * Set the SAV/EAV RP codes to look for as start/stop points + * when in VIP-1.1 mode + */ if (raw) { + /* + * Start codes for beginning of "active" line in vertical blank + * 0x20 ( VerticalBlank ) + * 0x60 ( EvenField VerticalBlank ) + */ data[4] = 0x20602060; + /* + * End codes for end of "active" raw lines and regular lines + * 0x30 ( VerticalBlank HorizontalBlank) + * 0x70 ( EvenField VerticalBlank HorizontalBlank) + * 0x90 (Task HorizontalBlank) + * 0xd0 (Task EvenField HorizontalBlank) + */ data[5] = 0x307090d0; } else { + /* + * End codes for active video, we want data in the hblank region + * 0xb0 (Task 0 VerticalBlank HorizontalBlank) + * 0xf0 (Task EvenField VerticalBlank HorizontalBlank) + * + * Since the V bit is only allowed to toggle in the EAV RP code, + * just before the first active region line, these two + * are problematic and we have to ignore them: + * 0x90 (Task HorizontalBlank) + * 0xd0 (Task EvenField HorizontalBlank) + */ data[4] = 0xB0F0B0F0; + /* + * Start codes for beginning of active line in vertical blank + * 0xa0 (Task VerticalBlank ) + * 0xe0 (Task EvenField VerticalBlank ) + */ data[5] = 0xA0E0A0E0; } diff --git a/linux/drivers/media/video/cx18/cx18-vbi.c b/linux/drivers/media/video/cx18/cx18-vbi.c index fb595bd54..38d26c42e 100644 --- a/linux/drivers/media/video/cx18/cx18-vbi.c +++ b/linux/drivers/media/video/cx18/cx18-vbi.c @@ -27,6 +27,16 @@ #include "cx18-queue.h" #include "cx18-av-core.h" +/* + * Raster Reference/Protection (RP) bytes, used in Start/End Active + * Video codes emitted from the digitzer in VIP 1.x mode, that flag the start + * of VBI sample or VBI ancilliary data regions in the digitial ratser line. + * + * Task FieldEven VerticalBlank HorizontalBlank 0 0 0 0 + */ +static const u8 raw_vbi_sav_rp[2] = { 0x20, 0x60 }; /* __V_, _FV_ */ +static const u8 sliced_vbi_eav_rp[2] = { 0xb0, 0xf0 }; /* T_VH, TFVH */ + static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp) { int line = 0; @@ -34,10 +44,17 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp) u32 linemask[2] = { 0, 0 }; unsigned short size; static const u8 mpeg_hdr_data[] = { - 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66, - 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff, - 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80, - 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff + /* MPEG-2 Program Pack */ + 0x00, 0x00, 0x01, 0xba, /* Prog Pack start code */ + 0x44, 0x00, 0x0c, 0x66, 0x24, 0x01, /* SCR, SCR Ext, markers */ + 0x01, 0xd1, 0xd3, /* Mux Rate, markers */ + 0xfa, 0xff, 0xff, /* Res, Suff cnt, Stuff */ + /* MPEG-2 Private Stream 1 PES Packet */ + 0x00, 0x00, 0x01, 0xbd, /* Priv Stream 1 start */ + 0x00, 0x1a, /* length */ + 0x84, 0x80, 0x07, /* flags, hdr data len */ + 0x21, 0x00, 0x5d, 0x63, 0xa7, /* PTS, markers */ + 0xff, 0xff /* stuffing */ }; const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */ int idx = cx->vbi.frame % CX18_VBI_FRAMES; @@ -71,7 +88,7 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp) memcpy(dst + sd + 4, dst + sd + 12, line * 43); size = 4 + ((43 * line + 3) & ~3); } else { - memcpy(dst + sd, "cx0", 4); + memcpy(dst + sd, "itv0", 4); memcpy(dst + sd + 4, &linemask[0], 8); size = 12 + ((43 * line + 3) & ~3); } @@ -90,10 +107,10 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp) Returns new compressed size. */ static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size) { - u32 line_size = cx->vbi.raw_decoder_line_size; + u32 line_size = vbi_active_samples; u32 lines = cx->vbi.count; - u8 sav1 = cx->vbi.raw_decoder_sav_odd_field; - u8 sav2 = cx->vbi.raw_decoder_sav_even_field; + u8 sav1 = raw_vbi_sav_rp[0]; + u8 sav2 = raw_vbi_sav_rp[1]; u8 *q = buf; u8 *p; int i; @@ -115,15 +132,16 @@ static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size) /* Compressed VBI format, all found sliced blocks put next to one another Returns new compressed size */ static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf, - u32 size, u8 sav) + u32 size, u8 eav) { - u32 line_size = cx->vbi.sliced_decoder_line_size; struct v4l2_decode_vbi_line vbi; int i; + u32 line_size = cx->is_60hz ? vbi_hblank_samples_60Hz + : vbi_hblank_samples_50Hz; /* find the first valid line */ for (i = 0; i < size; i++, buf++) { - if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav) + if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == eav) break; } @@ -133,8 +151,8 @@ static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf, for (i = 0; i < size / line_size; i++) { u8 *p = buf + i * line_size; - /* Look for SAV code */ - if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) + /* Look for EAV code */ + if (p[0] != 0xff || p[1] || p[2] || p[3] != eav) continue; vbi.p = p + 4; cx18_av_cmd(cx, VIDIOC_INT_DECODE_VBI_LINE, &vbi); @@ -159,6 +177,12 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, if (streamtype != CX18_ENC_STREAM_TYPE_VBI) return; + /* + * Note the CX23418 provides a 12 byte header, in it's raw VBI + * buffers to us, that we currently throw away: + * 0x3fffffff [4 bytes of something] [4 byte timestamp] + */ + /* Raw VBI data */ if (cx18_raw_vbi(cx)) { u8 type; @@ -173,7 +197,7 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, size = buf->bytesused = compress_raw_buf(cx, p, size); /* second field of the frame? */ - if (type == cx->vbi.raw_decoder_sav_even_field) { + if (type == raw_vbi_sav_rp[1]) { /* Dirty hack needed for backwards compatibility of old VBI software. */ p += size - 4; @@ -187,14 +211,14 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, cx18_buf_swap(buf); /* first field */ - lines = compress_sliced_buf(cx, 0, p, size / 2, - cx->vbi.sliced_decoder_sav_odd_field); + /* compress_sliced_buf() will skip the 12 bytes of header */ + lines = compress_sliced_buf(cx, 0, p, size / 2, sliced_vbi_eav_rp[0]); /* second field */ /* experimentation shows that the second half does not always begin at the exact address. So start a bit earlier (hence 32). */ lines = compress_sliced_buf(cx, lines, p + size / 2 - 32, - size / 2 + 32, cx->vbi.sliced_decoder_sav_even_field); + size / 2 + 32, sliced_vbi_eav_rp[1]); /* always return at least one empty line */ if (lines == 0) { cx->vbi.sliced_data[0].id = 0; -- cgit v1.2.3 From b091f9b9e1a7c7b1485a6bef42a0af1587c59646 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 31 Jan 2009 09:09:33 -0200 Subject: saa7134-alsa: saa7130 doesn't support digital audio From: Mauro Carvalho Chehab Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-alsa.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7134/saa7134-alsa.c b/linux/drivers/media/video/saa7134/saa7134-alsa.c index 5182d958c..eaa03fc07 100644 --- a/linux/drivers/media/video/saa7134/saa7134-alsa.c +++ b/linux/drivers/media/video/saa7134/saa7134-alsa.c @@ -1094,7 +1094,11 @@ static int saa7134_alsa_init(void) list_for_each(list,&saa7134_devlist) { dev = list_entry(list, struct saa7134_dev, devlist); - alsa_device_init(dev); + if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130) + printk(KERN_INFO "%s/alsa: %s doesn't support digital audio\n", + dev->name, saa7134_boards[dev->board].name); + else + alsa_device_init(dev); } if (dev == NULL) -- cgit v1.2.3 From c486f5a8bc4d8eac66b2017d78ce2466c32d1ff9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 31 Jan 2009 09:10:49 -0200 Subject: saa7134-core: remove oss option, since saa7134-oss doesn't exist anymore From: Mauro Carvalho Chehab Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-core.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c index 1ba80210e..527c25087 100644 --- a/linux/drivers/media/video/saa7134/saa7134-core.c +++ b/linux/drivers/media/video/saa7134/saa7134-core.c @@ -58,10 +58,6 @@ static unsigned int alsa; module_param(alsa, int, 0644); MODULE_PARM_DESC(alsa,"enable ALSA DMA sound [dmasound]"); -static unsigned int oss; -module_param(oss, int, 0644); -MODULE_PARM_DESC(oss,"enable OSS DMA sound [dmasound]"); - static unsigned int latency = UNSET; module_param(latency, int, 0444); MODULE_PARM_DESC(latency,"pci latency timer"); @@ -203,8 +199,6 @@ static void request_module_async(struct work_struct *work){ request_module("saa7134-dvb"); if (alsa) request_module("saa7134-alsa"); - if (oss) - request_module("saa7134-oss"); } static void request_submodules(struct saa7134_dev *dev) -- cgit v1.2.3 From 3f7305a1eb510b65eddf1867e6696f56a102b508 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 31 Jan 2009 09:14:24 -0200 Subject: saa7134-core: loading saa7134-alsa is now the default From: Mauro Carvalho Chehab Most boards nowadays supports saa7134-alsa. Even some of they doesn't have any option to wire an audio cable. So, lets load saa7134-alsa by default, if the board is not based on saa7130 and if saa7134-alsa is compiled. Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-core.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c index 527c25087..6e98c992c 100644 --- a/linux/drivers/media/video/saa7134/saa7134-core.c +++ b/linux/drivers/media/video/saa7134/saa7134-core.c @@ -54,9 +54,9 @@ static unsigned int gpio_tracking; module_param(gpio_tracking, int, 0644); MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]"); -static unsigned int alsa; +static unsigned int alsa = 1; module_param(alsa, int, 0644); -MODULE_PARM_DESC(alsa,"enable ALSA DMA sound [dmasound]"); +MODULE_PARM_DESC(alsa,"enable/disable ALSA DMA sound [dmasound]"); static unsigned int latency = UNSET; module_param(latency, int, 0444); @@ -197,8 +197,10 @@ static void request_module_async(struct work_struct *work){ request_module("saa7134-empress"); if (card_is_dvb(dev)) request_module("saa7134-dvb"); - if (alsa) - request_module("saa7134-alsa"); + if (alsa) { + if (dev->pci->device != PCI_DEVICE_ID_PHILIPS_SAA7130) + request_module("saa7134-alsa"); + } } static void request_submodules(struct saa7134_dev *dev) -- cgit v1.2.3 From 29e4b3115eccc5374834648d7c8c19e67a4e1095 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 1 Feb 2009 17:59:42 +0100 Subject: gspca - sonixj: Sensor sp80708 added for webcam 0c45:6143. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 145 +++++++++++++++++++++++++++++-- 1 file changed, 140 insertions(+), 5 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 5b5e526d8..eeedcbc72 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -66,6 +66,7 @@ struct sd { #define SENSOR_OV7630 5 #define SENSOR_OV7648 6 #define SENSOR_OV7660 7 +#define SENSOR_SP80708 8 u8 i2c_base; }; @@ -243,6 +244,8 @@ static __u32 ctrl_dis[] = { /* SENSOR_OV7648 6 */ (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), /* SENSOR_OV7660 7 */ + (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), + /* SENSOR_SP80708 8 */ }; static const struct v4l2_pix_format vga_mode[] = { @@ -352,6 +355,17 @@ static const u8 sn_ov7660[0x1c] = { 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, +/* reg8 reg9 rega regb regc regd rege regf */ + 0x81, 0x18, 0x07, 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 */ + 0x07, 0x00, 0x00, 0x00 +}; + /* sequence specific to the sensors - !! index = SENSOR_xxx */ static const u8 *sn_tb[] = { sn_hv7131, @@ -361,7 +375,8 @@ static const u8 *sn_tb[] = { sn_om6802, sn_ov7630, sn_ov7648, - sn_ov7660 + sn_ov7660, + sn_sp80708 }; static const u8 gamma_def[17] = { @@ -746,6 +761,89 @@ static const u8 ov7660_sensor_init[][8] = { {} }; +static const u8 sp80708_sensor_init[][8] = { + {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10}, + /********/ + {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10}, + {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10}, + {} +}; + static const u8 qtable4[] = { 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06, 0x06, 0x08, 0x0a, 0x11, @@ -1028,6 +1126,14 @@ static int configure_gpio(struct gspca_dev *gspca_dev, } /* fall thru */ #endif + case SENSOR_SP80708: + reg_w1(gspca_dev, 0x01, 0x63); + reg_w1(gspca_dev, 0x17, 0x20); + reg_w1(gspca_dev, 0x01, 0x62); + reg_w1(gspca_dev, 0x01, 0x42); + mdelay(100); + reg_w1(gspca_dev, 0x02, 0x62); + break; default: reg_w1(gspca_dev, 0x01, 0x43); reg_w1(gspca_dev, 0x17, 0x61); @@ -1151,6 +1257,19 @@ static void ov7660_InitSensor(struct gspca_dev *gspca_dev) } } +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) @@ -1424,6 +1543,7 @@ static void setgamma(struct gspca_dev *gspca_dev) 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00 }; + for (i = 0; i < sizeof gamma; i++) gamma[i] = gamma_def[i] + delta[i] * (sd->gamma - GAMMA_DEF) / 32; @@ -1525,7 +1645,8 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x20, gamma_hv7131r, sizeof gamma_hv7131r); else #endif - setgamma(gspca_dev); + setgamma(gspca_dev); + for (i = 0; i < 8; i++) reg_w(gspca_dev, 0x84, reg84, sizeof reg84); switch (sd->sensor) { @@ -1537,6 +1658,10 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x9a, 0x0a); reg_w1(gspca_dev, 0x99, 0x60); break; + case SENSOR_SP80708: + reg_w1(gspca_dev, 0x9a, 0x05); + reg_w1(gspca_dev, 0x99, 0x59); + break; case SENSOR_OV7660: if (sd->bridge == BRIDGE_SN9C120) { reg_w1(gspca_dev, 0x9a, 0x05); @@ -1596,8 +1721,7 @@ static int sd_start(struct gspca_dev *gspca_dev) reg17 = 0x21; /* reg1 = 0x42; * 42 - 46? */ break; - default: -/* case SENSOR_OV7660: */ + case SENSOR_OV7660: ov7660_InitSensor(gspca_dev); if (sd->bridge == BRIDGE_SN9C120) { if (mode) { /* 320x240 - 160x120 */ @@ -1610,6 +1734,17 @@ static int sd_start(struct gspca_dev *gspca_dev) * inverse power down */ } break; + default: +/* case SENSOR_SP80708: */ + sp80708_InitSensor(gspca_dev); + if (mode) { +/*?? reg1 = 0x04; * 320 clk 48Mhz */ + ; + } else { + reg1 = 0x46; /* 640 clk 48Mz */ + reg17 = 0xa2; + } + break; } reg_w(gspca_dev, 0xc0, C0, 6); reg_w(gspca_dev, 0xca, CA, 4); @@ -2012,7 +2147,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)}, /* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */ #endif - {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)}, + {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); -- cgit v1.2.3 From 588027051d313c56ef5cea88111f5c16aed595b2 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 1 Feb 2009 18:20:07 +0100 Subject: gspca - sonixj: Specific gamma tables per sensor. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 34 +++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index eeedcbc72..0a96d6cdc 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -379,17 +379,21 @@ static const u8 *sn_tb[] = { sn_sp80708 }; +/* default gamma table */ static const u8 gamma_def[17] = { 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff }; - -#if 0 -static const u8 gamma_hv7131r[17] = { +/* gamma for sensors HV7131R and MT9V111 */ +static const u8 gamma_spec_1[17] = { 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d, 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5 }; -#endif +/* gamma for sensor SP80708 */ +static const u8 gamma_spec_2[17] = { + 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab, + 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6 +}; /* color matrix and offsets */ static const u8 reg84[] = { @@ -1538,14 +1542,27 @@ static void setgamma(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int i; u8 gamma[17]; + const u8 *gamma_base; static const u8 delta[17] = { 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a, 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00 }; + switch (sd->sensor) { + case SENSOR_HV7131R: + case SENSOR_MT9V111: + gamma_base = gamma_spec_1; + break; + case SENSOR_SP80708: + gamma_base = gamma_spec_2; + break; + default: + gamma_base = gamma_def; + break; + } for (i = 0; i < sizeof gamma; i++) - gamma[i] = gamma_def[i] + gamma[i] = gamma_base[i] + delta[i] * (sd->gamma - GAMMA_DEF) / 32; reg_w(gspca_dev, 0x20, gamma, sizeof gamma); } @@ -1640,11 +1657,7 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */ reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */ reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]); -#if 0 - if (sd->sensor == SENSOR_HV7131R || sd->sensor == SENSOR_MT9V111) - reg_w(gspca_dev, 0x20, gamma_hv7131r, sizeof gamma_hv7131r); - else -#endif + setgamma(gspca_dev); for (i = 0; i < 8; i++) @@ -1739,7 +1752,6 @@ static int sd_start(struct gspca_dev *gspca_dev) sp80708_InitSensor(gspca_dev); if (mode) { /*?? reg1 = 0x04; * 320 clk 48Mhz */ - ; } else { reg1 = 0x46; /* 640 clk 48Mz */ reg17 = 0xa2; -- cgit v1.2.3 From e659d45f04c7de45057e9c86a93c7ca906027026 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 1 Feb 2009 18:26:51 +0100 Subject: gspca - sonixj: Simplify the probe of the sensors mi0360/mt9v111. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 0a96d6cdc..1d33e80a1 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -1009,18 +1009,19 @@ static int hv7131r_probe(struct gspca_dev *gspca_dev) return -ENODEV; } -static int mi0360_probe(struct gspca_dev *gspca_dev) +static void mi0360_probe(struct gspca_dev *gspca_dev) { + struct sd *sd = (struct sd *) gspca_dev; int i, j; u16 val; static const u8 probe_tb[][4][8] = { - { + { /* mi0360 */ {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10} }, - { + { /* mt9v111 */ {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, @@ -1046,13 +1047,16 @@ static int mi0360_probe(struct gspca_dev *gspca_dev) switch (val) { case 0x823a: PDEBUG(D_PROBE, "Sensor mt9v111"); - return SENSOR_MT9V111; + sd->sensor = SENSOR_MT9V111; + sd->i2c_base = 0x5c; + break; case 0x8243: PDEBUG(D_PROBE, "Sensor mi0360"); - return SENSOR_MI0360; + break; + default: + PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val); + break; } - PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val); - return SENSOR_MI0360; } static int configure_gpio(struct gspca_dev *gspca_dev, @@ -1327,21 +1331,15 @@ static int sd_init(struct gspca_dev *gspca_dev) case BRIDGE_SN9C105: if (regF1 != 0x11) return -ENODEV; - if (sd->sensor == SENSOR_MI0360) { - sd->sensor = mi0360_probe(gspca_dev); - if (sd->sensor == SENSOR_MT9V111) - sd->i2c_base = 0x5c; - } + if (sd->sensor == SENSOR_MI0360) + mi0360_probe(gspca_dev); reg_w(gspca_dev, 0x01, regGpio, 2); break; case BRIDGE_SN9C120: if (regF1 != 0x12) return -ENODEV; - if (sd->sensor == SENSOR_MI0360) { - sd->sensor = mi0360_probe(gspca_dev); - if (sd->sensor == SENSOR_MT9V111) - sd->i2c_base = 0x5c; - } + if (sd->sensor == SENSOR_MI0360) + mi0360_probe(gspca_dev); regGpio[1] = 0x70; reg_w(gspca_dev, 0x01, regGpio, 2); break; -- cgit v1.2.3 From 8e4ca258fea621ae40f8e7b33299147fda22c2c9 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 1 Feb 2009 18:48:55 +0100 Subject: gspca - sonixj: Adjust some exchanges with the sensor mt9v111. From: Jean-Francois Moine This patch also enables the autogain for the mt9v111. Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 1d33e80a1..0aa4649bd 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -234,7 +234,11 @@ static __u32 ctrl_dis[] = { /* SENSOR_MI0360 1 */ (1 << INFRARED_IDX) | (1 << VFLIP_IDX), /* SENSOR_MO4000 2 */ +#if 1 + 0, +#else (1 << AUTOGAIN_IDX), +#endif /* SENSOR_MT9V111 3 */ (1 << INFRARED_IDX) | (1 << VFLIP_IDX), /* SENSOR_OM6802 4 */ @@ -517,8 +521,18 @@ static const u8 mt9v111_sensor_init[][8] = { {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */ {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */ {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */ + {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, + {0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10}, + {0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10}, + {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10}, {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */ + {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, + {0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10}, + {0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10}, + {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10}, + {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */ + {0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10}, {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */ {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */ {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */ @@ -532,7 +546,11 @@ static const u8 mt9v111_sensor_init[][8] = { /*******/ {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, +#if 1 + {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10}, +#else {0xb1, 0x5c, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10}, /* shutter width */ +#endif {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */ {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */ /*******/ @@ -1714,7 +1732,7 @@ static int sd_start(struct gspca_dev *gspca_dev) reg1 = 0x04; /* 320 clk 48Mhz */ } else { /* reg1 = 0x06; * 640 clk 24Mz (done) */ - reg17 = 0xe2; + reg17 = 0xc2; } break; case SENSOR_OM6802: -- cgit v1.2.3 From 0b54c23674aba500f0f7dcb646b2db160813d2dc Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 1 Feb 2009 20:15:01 +0100 Subject: gspca - vc032x: Bad revision for the webcam 041e:405b. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/vc032x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/vc032x.c b/linux/drivers/media/video/gspca/vc032x.c index 45ece4a45..4842664a2 100644 --- a/linux/drivers/media/video/gspca/vc032x.c +++ b/linux/drivers/media/video/gspca/vc032x.c @@ -2553,7 +2553,7 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x405b), .driver_info = BRIDGE_VC0321}, + {USB_DEVICE(0x041e, 0x405b), .driver_info = BRIDGE_VC0323}, {USB_DEVICE(0x046d, 0x0892), .driver_info = BRIDGE_VC0321}, {USB_DEVICE(0x046d, 0x0896), .driver_info = BRIDGE_VC0321}, {USB_DEVICE(0x046d, 0x0897), .driver_info = BRIDGE_VC0321}, -- cgit v1.2.3 From d7d02b86ebba841e90992de5bddb169575e682f5 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 1 Feb 2009 14:53:20 -0500 Subject: cx18: Fix coding style of a switch statement per checkpatch.pl From: Andy Walls Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-av-core.c | 50 +++++++++++++-------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-av-core.c b/linux/drivers/media/video/cx18/cx18-av-core.c index 50979d333..e6391bc5a 100644 --- a/linux/drivers/media/video/cx18/cx18-av-core.c +++ b/linux/drivers/media/video/cx18/cx18-av-core.c @@ -683,31 +683,31 @@ static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt) static int valid_av_cmd(unsigned int cmd) { switch (cmd) { - /* All commands supported by cx18_av_cmd() */ - case VIDIOC_INT_DECODE_VBI_LINE: - case VIDIOC_INT_AUDIO_CLOCK_FREQ: - case VIDIOC_STREAMON: - case VIDIOC_STREAMOFF: - case VIDIOC_LOG_STATUS: - case VIDIOC_G_CTRL: - case VIDIOC_S_CTRL: - case VIDIOC_QUERYCTRL: - case VIDIOC_G_STD: - case VIDIOC_S_STD: - case AUDC_SET_RADIO: - case VIDIOC_INT_G_VIDEO_ROUTING: - case VIDIOC_INT_S_VIDEO_ROUTING: - case VIDIOC_INT_G_AUDIO_ROUTING: - case VIDIOC_INT_S_AUDIO_ROUTING: - case VIDIOC_S_FREQUENCY: - case VIDIOC_G_TUNER: - case VIDIOC_S_TUNER: - case VIDIOC_G_FMT: - case VIDIOC_S_FMT: - case VIDIOC_INT_RESET: - return 1; - default: - return 0; + /* All commands supported by cx18_av_cmd() */ + case VIDIOC_INT_DECODE_VBI_LINE: + case VIDIOC_INT_AUDIO_CLOCK_FREQ: + case VIDIOC_STREAMON: + case VIDIOC_STREAMOFF: + case VIDIOC_LOG_STATUS: + case VIDIOC_G_CTRL: + case VIDIOC_S_CTRL: + case VIDIOC_QUERYCTRL: + case VIDIOC_G_STD: + case VIDIOC_S_STD: + case AUDC_SET_RADIO: + case VIDIOC_INT_G_VIDEO_ROUTING: + case VIDIOC_INT_S_VIDEO_ROUTING: + case VIDIOC_INT_G_AUDIO_ROUTING: + case VIDIOC_INT_S_AUDIO_ROUTING: + case VIDIOC_S_FREQUENCY: + case VIDIOC_G_TUNER: + case VIDIOC_S_TUNER: + case VIDIOC_G_FMT: + case VIDIOC_S_FMT: + case VIDIOC_INT_RESET: + return 1; + default: + return 0; } return 0; } -- cgit v1.2.3 From 13e2e59a82953d5b837a02c7115ae6fad1c0f1d4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 14 Feb 2009 23:58:33 +0100 Subject: ivtv: fix decoder crash regression From: Hans Verkuil The video_ioctl2 conversion of ivtv in kernel 2.6.27 introduced a bug causing decoder commands to crash. The decoder commands should have been handled from the video_ioctl2 default handler, ensuring correct mapping of the argument between user and kernel space. Unfortunately they ended up before the video_ioctl2 call, causing random crashes. Thanks to hannes@linus.priv.at for testing and helping me track down the cause! Priority: high Signed-off-by: Hans Verkuil --- linux/drivers/media/video/ivtv/ivtv-ioctl.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c index aa55a3cc4..d7a708ad3 100644 --- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1752,6 +1752,18 @@ static long ivtv_default(struct file *file, void *fh, int cmd, void *arg) break; } + case IVTV_IOC_DMA_FRAME: + case VIDEO_GET_PTS: + case VIDEO_GET_FRAME_COUNT: + case VIDEO_GET_EVENT: + case VIDEO_PLAY: + case VIDEO_STOP: + case VIDEO_FREEZE: + case VIDEO_CONTINUE: + case VIDEO_COMMAND: + case VIDEO_TRY_COMMAND: + return ivtv_decoder_ioctls(file, cmd, (void *)arg); + default: return -EINVAL; } @@ -1794,18 +1806,6 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp, ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); return 0; - case IVTV_IOC_DMA_FRAME: - case VIDEO_GET_PTS: - case VIDEO_GET_FRAME_COUNT: - case VIDEO_GET_EVENT: - case VIDEO_PLAY: - case VIDEO_STOP: - case VIDEO_FREEZE: - case VIDEO_CONTINUE: - case VIDEO_COMMAND: - case VIDEO_TRY_COMMAND: - return ivtv_decoder_ioctls(filp, cmd, (void *)arg); - default: break; } -- cgit v1.2.3 From 337e145d4f292cbeeb8dd95c70ecef641230a657 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 16 Feb 2009 08:25:32 +0100 Subject: ivtv: fix regression in get sliced vbi format From: Hans Verkuil The new v4l2_subdev_call used s_fmt instead of g_fmt. Priority: high Signed-off-by: Hans Verkuil Thanks-to: Andy Walls --- linux/drivers/media/video/ivtv/ivtv-ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c index d7a708ad3..9a0424298 100644 --- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c @@ -391,7 +391,7 @@ static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo return 0; } - v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt); + v4l2_subdev_call(itv->sd_video, video, g_fmt, fmt); vbifmt->service_set = ivtv_get_service_set(vbifmt); return 0; } -- cgit v1.2.3 From fa940b36a68186b4e5b77a5afb929f68603b52bf Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 9 Feb 2009 21:06:49 +0000 Subject: V4L: Storage class should be before const qualifier From: Tobias Klauser The C99 specification states in section 6.11.5: The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Signed-off-by: Tobias Klauser CC: Jean-Francois Moine CC: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/gspca/t613.c | 2 +- linux/drivers/media/video/tcm825x.c | 22 +++++++++++----------- linux/drivers/media/video/tcm825x.h | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/t613.c b/linux/drivers/media/video/gspca/t613.c index adec0767c..c04836ed2 100644 --- a/linux/drivers/media/video/gspca/t613.c +++ b/linux/drivers/media/video/gspca/t613.c @@ -272,7 +272,7 @@ struct additional_sensor_data { const u8 stream[4]; }; -const static struct additional_sensor_data sensor_data[] = { +static const struct additional_sensor_data sensor_data[] = { { /* OM6802 */ .data1 = {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06, diff --git a/linux/drivers/media/video/tcm825x.c b/linux/drivers/media/video/tcm825x.c index 2f823f27a..559ade821 100644 --- a/linux/drivers/media/video/tcm825x.c +++ b/linux/drivers/media/video/tcm825x.c @@ -50,7 +50,7 @@ struct tcm825x_sensor { }; /* list of image formats supported by TCM825X sensor */ -const static struct v4l2_fmtdesc tcm825x_formats[] = { +static const struct v4l2_fmtdesc tcm825x_formats[] = { { .description = "YUYV (YUV 4:2:2), packed", .pixelformat = V4L2_PIX_FMT_UYVY, @@ -76,15 +76,15 @@ const static struct v4l2_fmtdesc tcm825x_formats[] = { * TCM825X register configuration for all combinations of pixel format and * image size */ -const static struct tcm825x_reg subqcif = { 0x20, TCM825X_PICSIZ }; -const static struct tcm825x_reg qcif = { 0x18, TCM825X_PICSIZ }; -const static struct tcm825x_reg cif = { 0x14, TCM825X_PICSIZ }; -const static struct tcm825x_reg qqvga = { 0x0c, TCM825X_PICSIZ }; -const static struct tcm825x_reg qvga = { 0x04, TCM825X_PICSIZ }; -const static struct tcm825x_reg vga = { 0x00, TCM825X_PICSIZ }; +static const struct tcm825x_reg subqcif = { 0x20, TCM825X_PICSIZ }; +static const struct tcm825x_reg qcif = { 0x18, TCM825X_PICSIZ }; +static const struct tcm825x_reg cif = { 0x14, TCM825X_PICSIZ }; +static const struct tcm825x_reg qqvga = { 0x0c, TCM825X_PICSIZ }; +static const struct tcm825x_reg qvga = { 0x04, TCM825X_PICSIZ }; +static const struct tcm825x_reg vga = { 0x00, TCM825X_PICSIZ }; -const static struct tcm825x_reg yuv422 = { 0x00, TCM825X_PICFMT }; -const static struct tcm825x_reg rgb565 = { 0x02, TCM825X_PICFMT }; +static const struct tcm825x_reg yuv422 = { 0x00, TCM825X_PICFMT }; +static const struct tcm825x_reg rgb565 = { 0x02, TCM825X_PICFMT }; /* Our own specific controls */ #define V4L2_CID_ALC V4L2_CID_PRIVATE_BASE @@ -248,10 +248,10 @@ static struct vcontrol { }; -const static struct tcm825x_reg *tcm825x_siz_reg[NUM_IMAGE_SIZES] = +static const struct tcm825x_reg *tcm825x_siz_reg[NUM_IMAGE_SIZES] = { &subqcif, &qqvga, &qcif, &qvga, &cif, &vga }; -const static struct tcm825x_reg *tcm825x_fmt_reg[NUM_PIXEL_FORMATS] = +static const struct tcm825x_reg *tcm825x_fmt_reg[NUM_PIXEL_FORMATS] = { &yuv422, &rgb565 }; /* diff --git a/linux/drivers/media/video/tcm825x.h b/linux/drivers/media/video/tcm825x.h index 770ebacfa..5b7e69682 100644 --- a/linux/drivers/media/video/tcm825x.h +++ b/linux/drivers/media/video/tcm825x.h @@ -188,7 +188,7 @@ struct tcm825x_platform_data { /* Array of image sizes supported by TCM825X. These must be ordered from * smallest image size to largest. */ -const static struct capture_size tcm825x_sizes[] = { +static const struct capture_size tcm825x_sizes[] = { { 128, 96 }, /* subQCIF */ { 160, 120 }, /* QQVGA */ { 176, 144 }, /* QCIF */ -- cgit v1.2.3 From ae420af84b9a311c94b8c41557e700a13fe2f520 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 9 Feb 2009 21:57:06 +0000 Subject: tvp514x: try_count reaches 0, not -1 From: Roel Kluin with while (try_count-- > 0) { ... } try_count reaches 0, not -1. Signed-off-by: Roel Kluin CC: Vaibhav Hiremath Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/tvp514x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tvp514x.c b/linux/drivers/media/video/tvp514x.c index 8e23aa53c..5f4cbc2b2 100644 --- a/linux/drivers/media/video/tvp514x.c +++ b/linux/drivers/media/video/tvp514x.c @@ -686,7 +686,7 @@ static int ioctl_s_routing(struct v4l2_int_device *s, break; /* Input detected */ } - if ((current_std == STD_INVALID) || (try_count < 0)) + if ((current_std == STD_INVALID) || (try_count <= 0)) return -EINVAL; decoder->current_std = current_std; -- cgit v1.2.3 From de8d080a697cf4a8c8c997f7f3b76ea1f49a51bd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 11 Feb 2009 09:34:11 +0000 Subject: V4L/DVB: calibration still successful at 10 From: Roel Kluin With while (i++ < 10) { ... } i can reach 11, so callibration still succeeds at i == 10. Signed-off-by: Roel Kluin Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/tuners/mt2060.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/common/tuners/mt2060.c b/linux/drivers/media/common/tuners/mt2060.c index d1962bb24..1f1fe90cb 100644 --- a/linux/drivers/media/common/tuners/mt2060.c +++ b/linux/drivers/media/common/tuners/mt2060.c @@ -285,7 +285,7 @@ static void mt2060_calibrate(struct mt2060_priv *priv) while (i++ < 10 && mt2060_readreg(priv, REG_MISC_STAT, &b) == 0 && (b & (1 << 6)) == 0) msleep(20); - if (i < 10) { + if (i <= 10) { mt2060_readreg(priv, REG_FM_FREQ, &priv->fmfreq); // now find out, what is fmreq used for :) dprintk("calibration was successful: %d", (int)priv->fmfreq); } else -- cgit v1.2.3 From e07511c36db32bec6bd0fde4e996001b6e5709e0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 12 Feb 2009 18:19:24 +0000 Subject: zoran: fix printk format From: Randy Dunlap Fix printk format warning: drivers/media/video/zoran/zoran_driver.c:345: warning: format '%lx' expects type 'long unsigned int', but argument 5 has type 'phys_addr_t' Signed-off-by: Randy Dunlap Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/zoran/zoran_driver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index 2609f54d7..798745c0a 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -356,9 +356,9 @@ v4l_fbuffer_alloc (struct file *file) SetPageReserved(MAP_NR(mem + off)); dprintk(4, KERN_INFO - "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%lx)\n", + "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%llx)\n", ZR_DEVNAME(zr), i, (unsigned long) mem, - virt_to_bus(mem)); + (unsigned long long)virt_to_bus(mem)); } else { #if defined(CONFIG_BIGPHYS_AREA) /* Use bigphysarea_alloc_pages */ -- cgit v1.2.3 From d5e10736ed6dd53b02e973042f407a3316c28533 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 12 Feb 2009 06:43:11 +0000 Subject: Added support for AVerMedia Cardbus Hybrid remote control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: OldÅ™ich JedliÄka Added support for I2C device at address 0x40 and subaddress 0x0d/0x0b that provides remote control key reading support for AVerMedia Cardbus Hybrid card, possibly for other AVerMedia Cardbus cards. The I2C address 0x40 doesn't like the SAA7134's 0xfd quirk, so it was disabled. Signed-off-by: OldÅ™ich JedliÄka [mchehab@redhat.com: CodingStyle fixes] Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/ir-keymaps.c | 59 +++++++++++++++++++++ linux/drivers/media/video/ir-kbd-i2c.c | 64 +++++++++++++++++++++++ linux/drivers/media/video/saa7134/saa7134-cards.c | 5 ++ linux/drivers/media/video/saa7134/saa7134-i2c.c | 2 +- linux/include/media/ir-common.h | 1 + 5 files changed, 130 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/common/ir-keymaps.c b/linux/drivers/media/common/ir-keymaps.c index 03fabc86c..827e65582 100644 --- a/linux/drivers/media/common/ir-keymaps.c +++ b/linux/drivers/media/common/ir-keymaps.c @@ -154,6 +154,65 @@ IR_KEYTAB_TYPE ir_codes_avermedia_m135a[IR_KEYTAB_SIZE] = { }; EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a); +/* Oldrich Jedlicka */ +IR_KEYTAB_TYPE ir_codes_avermedia_cardbus[IR_KEYTAB_SIZE] = { + [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 */ +}; +EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus); + /* Attila Kondoros */ IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = { diff --git a/linux/drivers/media/video/ir-kbd-i2c.c b/linux/drivers/media/video/ir-kbd-i2c.c index a67bed7d7..a99aea49a 100644 --- a/linux/drivers/media/video/ir-kbd-i2c.c +++ b/linux/drivers/media/video/ir-kbd-i2c.c @@ -16,6 +16,8 @@ * Henry Wong * Mark Schultz * Brian Rogers + * modified for AVerMedia Cardbus by + * Oldrich Jedlicka * * 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 @@ -217,6 +219,46 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) return 1; } +static int get_key_avermedia_cardbus(struct IR_i2c *ir, + u32 *ir_key, u32 *ir_raw) +{ + unsigned char subaddr, key, keygroup; + struct i2c_msg msg[] = { { .addr = ir->c.addr, .flags = 0, + .buf = &subaddr, .len = 1}, + { .addr = ir->c.addr, .flags = I2C_M_RD, + .buf = &key, .len = 1} }; + subaddr = 0x0d; + if (2 != i2c_transfer(ir->c.adapter, msg, 2)) { + dprintk(1, "read error\n"); + return -EIO; + } + + if (key == 0xff) + return 0; + + subaddr = 0x0b; + msg[1].buf = &keygroup; + if (2 != i2c_transfer(ir->c.adapter, msg, 2)) { + dprintk(1, "read error\n"); + return -EIO; + } + + if (keygroup == 0xff) + return 0; + + dprintk(1, "read key 0x%02x/0x%02x\n", key, keygroup); + if (keygroup < 2 || keygroup > 3) { + /* Only a warning */ + dprintk(1, "warning: invalid key group 0x%02x for key 0x%02x\n", + keygroup, key); + } + key |= (keygroup & 1) << 6; + + *ir_key = key; + *ir_raw = key; + return 1; +} + /* ----------------------------------------------------------------------- */ static void ir_key_poll(struct IR_i2c *ir) @@ -369,6 +411,12 @@ static int ir_attach(struct i2c_adapter *adap, int addr, ir_type = IR_TYPE_OTHER; } break; + case 0x40: + name = "AVerMedia Cardbus remote"; + ir->get_key = get_key_avermedia_cardbus; + ir_type = IR_TYPE_OTHER; + ir_codes = ir_codes_avermedia_cardbus; + break; default: /* shouldn't happen */ printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n", addr); @@ -537,6 +585,22 @@ static int ir_probe(struct i2c_adapter *adap) ir_attach(adap, msg.addr, 0, 0); } + /* Special case for AVerMedia Cardbus remote */ + if (adap->id == I2C_HW_SAA7134) { + unsigned char subaddr, data; + struct i2c_msg msg[] = { { .addr = 0x40, .flags = 0, + .buf = &subaddr, .len = 1}, + { .addr = 0x40, .flags = I2C_M_RD, + .buf = &data, .len = 1} }; + subaddr = 0x0d; + rc = i2c_transfer(adap, msg, 2); + dprintk(1, "probe 0x%02x/0x%02x @ %s: %s\n", + msg[0].addr, subaddr, adap->name, + (2 == rc) ? "yes" : "no"); + if (2 == rc) + ir_attach(adap, msg[0].addr, 0, 0); + } + return 0; } diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c index e565d437b..9db045cf5 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -6120,6 +6120,11 @@ int saa7134_board_init1(struct saa7134_dev *dev) msleep(10); break; case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: + saa7134_set_gpio(dev, 23, 0); + msleep(10); + saa7134_set_gpio(dev, 23, 1); + dev->has_remote = SAA7134_REMOTE_I2C; + break; case SAA7134_BOARD_AVERMEDIA_M103: saa7134_set_gpio(dev, 23, 0); msleep(10); diff --git a/linux/drivers/media/video/saa7134/saa7134-i2c.c b/linux/drivers/media/video/saa7134/saa7134-i2c.c index 4b4d5ef76..b77ccb5a0 100644 --- a/linux/drivers/media/video/saa7134/saa7134-i2c.c +++ b/linux/drivers/media/video/saa7134/saa7134-i2c.c @@ -260,7 +260,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap, addr = msgs[i].addr << 1; if (msgs[i].flags & I2C_M_RD) addr |= 1; - if (i > 0 && msgs[i].flags & I2C_M_RD) { + if (i > 0 && msgs[i].flags & I2C_M_RD && msgs[i].addr != 0x40) { /* workaround for a saa7134 i2c bug * needed to talk to the mt352 demux * thanks to pinnacle for the hint */ diff --git a/linux/include/media/ir-common.h b/linux/include/media/ir-common.h index 31e62abb5..135e02270 100644 --- a/linux/include/media/ir-common.h +++ b/linux/include/media/ir-common.h @@ -111,6 +111,7 @@ extern IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_avermedia_m135a[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_avermedia_cardbus[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_pixelview_new[IR_KEYTAB_SIZE]; -- cgit v1.2.3 From e63d9cf5d9e5f269f241490e6e190e8f4d92a5d0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 1 Feb 2009 22:31:54 +0000 Subject: DAB: fix typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Márton Németh Fix typo in "DAB adapters" section in Kconfig. Signed-off-by: Márton Németh Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/Kconfig b/linux/drivers/media/Kconfig index 93ea201f4..223c36ede 100644 --- a/linux/drivers/media/Kconfig +++ b/linux/drivers/media/Kconfig @@ -117,7 +117,7 @@ source "drivers/media/dvb/Kconfig" config DAB boolean "DAB adapters" ---help--- - Allow selecting support for for Digital Audio Broadcasting (DAB) + Allow selecting support for Digital Audio Broadcasting (DAB) Receiver adapters. if DAB -- cgit v1.2.3 From 343fbdd2e3f93d7a107012ecc1413cae5664e096 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 1 Feb 2009 19:42:12 -0500 Subject: cx18: Fix presentation timestamp (PTS) for VBI buffers From: Andy Walls The old code from ivtv used a CX23415/6 PTS, which was simply left at 0 in the cx18 driver. Since the CX23418 gives us what I think is a PTS (or some other 90 kHz clock count) with each VBI buffer, this change has the cx18 driver use that as a PTS. Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-driver.h | 1 - linux/drivers/media/video/cx18/cx18-fileops.c | 4 +--- linux/drivers/media/video/cx18/cx18-vbi.c | 18 ++++++++++-------- linux/drivers/media/video/cx18/cx18-vbi.h | 2 +- 4 files changed, 12 insertions(+), 13 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-driver.h b/linux/drivers/media/video/cx18/cx18-driver.h index d2829f576..0ef099186 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.h +++ b/linux/drivers/media/video/cx18/cx18-driver.h @@ -293,7 +293,6 @@ struct cx18_stream { int dma; /* can be PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE or PCI_DMA_NONE */ - u64 dma_pts; wait_queue_head_t waitq; /* Buffer Stats */ diff --git a/linux/drivers/media/video/cx18/cx18-fileops.c b/linux/drivers/media/video/cx18/cx18-fileops.c index 7d979ea28..c73fbe65b 100644 --- a/linux/drivers/media/video/cx18/cx18-fileops.c +++ b/linux/drivers/media/video/cx18/cx18-fileops.c @@ -224,7 +224,6 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, while ((buf = cx18_dequeue(s_vbi, &s_vbi->q_full))) { /* byteswap and process VBI data */ cx18_process_vbi_data(cx, buf, - s_vbi->dma_pts, s_vbi->type); cx18_stream_put_buf_fw(s_vbi, buf); } @@ -245,8 +244,7 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, cx18_buf_swap(buf); else { /* byteswap and process VBI data */ - cx18_process_vbi_data(cx, buf, - s->dma_pts, s->type); + cx18_process_vbi_data(cx, buf, s->type); } return buf; } diff --git a/linux/drivers/media/video/cx18/cx18-vbi.c b/linux/drivers/media/video/cx18/cx18-vbi.c index 38d26c42e..d6e15e119 100644 --- a/linux/drivers/media/video/cx18/cx18-vbi.c +++ b/linux/drivers/media/video/cx18/cx18-vbi.c @@ -168,27 +168,28 @@ static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf, } void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, - u64 pts_stamp, int streamtype) + int streamtype) { u8 *p = (u8 *) buf->buf; + u32 *q = (u32 *) buf->buf; u32 size = buf->bytesused; + u32 pts; int lines; if (streamtype != CX18_ENC_STREAM_TYPE_VBI) return; + cx18_buf_swap(buf); + /* - * Note the CX23418 provides a 12 byte header, in it's raw VBI - * buffers to us, that we currently throw away: - * 0x3fffffff [4 bytes of something] [4 byte timestamp] + * The CX23418 provides a 12 byte header in it's raw VBI buffers to us: + * 0x3fffffff [4 bytes of something] [4 byte presentation time stamp?] */ /* Raw VBI data */ if (cx18_raw_vbi(cx)) { u8 type; - cx18_buf_swap(buf); - /* Skip 12 bytes of header that gets stuffed in */ size -= 12; memcpy(p, &buf->buf[12], size); @@ -208,7 +209,8 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, } /* Sliced VBI data with data insertion */ - cx18_buf_swap(buf); + + pts = (q[0] == 0x3fffffff) ? q[2] : 0; /* first field */ /* compress_sliced_buf() will skip the 12 bytes of header */ @@ -230,6 +232,6 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, memcpy(p, &cx->vbi.sliced_data[0], size); if (cx->vbi.insert_mpeg) - copy_vbi_data(cx, lines, pts_stamp); + copy_vbi_data(cx, lines, pts); cx->vbi.frame++; } diff --git a/linux/drivers/media/video/cx18/cx18-vbi.h b/linux/drivers/media/video/cx18/cx18-vbi.h index c56ff7d28..e7e1ae427 100644 --- a/linux/drivers/media/video/cx18/cx18-vbi.h +++ b/linux/drivers/media/video/cx18/cx18-vbi.h @@ -22,5 +22,5 @@ */ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, - u64 pts_stamp, int streamtype); + int streamtype); int cx18_used_line(struct cx18 *cx, int line, int field); -- cgit v1.2.3 From 527d5f186187cc1a8c128b0aca06d047e7f753a4 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 1 Feb 2009 21:44:00 -0500 Subject: cx18: Remove an unused spinlock From: Andy Walls Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-driver.c | 2 -- linux/drivers/media/video/cx18/cx18-driver.h | 1 - 2 files changed, 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-driver.c b/linux/drivers/media/video/cx18/cx18-driver.c index f48d18f69..4699cecbe 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.c +++ b/linux/drivers/media/video/cx18/cx18-driver.c @@ -563,8 +563,6 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) mutex_init(&cx->epu2apu_mb_lock); mutex_init(&cx->epu2cpu_mb_lock); - spin_lock_init(&cx->lock); - cx->work_queue = create_singlethread_workqueue(cx->name); if (cx->work_queue == NULL) { CX18_ERR("Unable to create work hander thread\n"); diff --git a/linux/drivers/media/video/cx18/cx18-driver.h b/linux/drivers/media/video/cx18/cx18-driver.h index 3a21013cd..d95c6ace2 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.h +++ b/linux/drivers/media/video/cx18/cx18-driver.h @@ -429,7 +429,6 @@ struct cx18 { unsigned long i_flags; /* global cx18 flags */ atomic_t ana_capturing; /* count number of active analog capture streams */ atomic_t tot_capturing; /* total count number of active capture streams */ - spinlock_t lock; /* lock access to this struct */ int search_pack_header; int open_id; /* incremented each time an open occurs, used as -- cgit v1.2.3 From 3fd8c59cdeaedaa51a5db45b8dbf67dc6b907e19 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 2 Feb 2009 10:33:31 +0100 Subject: gspca - vc032x: Cleanup source, optimize and check i2c_write. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/vc032x.c | 93 +++++++++++++------------------- 1 file changed, 37 insertions(+), 56 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/vc032x.c b/linux/drivers/media/video/gspca/vc032x.c index 4842664a2..1832d241f 100644 --- a/linux/drivers/media/video/gspca/vc032x.c +++ b/linux/drivers/media/video/gspca/vc032x.c @@ -1953,44 +1953,40 @@ static void reg_w(struct usb_device *dev, 500); } -static void read_sensor_register(struct gspca_dev *gspca_dev, - __u16 address, __u16 *value) +static u16 read_sensor_register(struct gspca_dev *gspca_dev, + u16 address) { struct usb_device *dev = gspca_dev->dev; __u8 ldata, mdata, hdata; int retry = 50; - *value = 0; - reg_r(gspca_dev, 0xa1, 0xb33f, 1); - /*PDEBUG(D_PROBE, " I2c Bus Busy Wait 0x%02X ", tmpvalue); */ if (!(gspca_dev->usb_buf[0] & 0x02)) { - PDEBUG(D_ERR, "I2c Bus Busy Wait %d", - gspca_dev->usb_buf[0] & 0x02); - return; + PDEBUG(D_ERR, "I2c Bus Busy Wait %02x", + gspca_dev->usb_buf[0]); + return 0; } reg_w(dev, 0xa0, address, 0xb33a); reg_w(dev, 0xa0, 0x02, 0xb339); - reg_r(gspca_dev, 0xa1, 0xb33b, 1); - while (retry-- && gspca_dev->usb_buf[0]) { + do { + msleep(8); reg_r(gspca_dev, 0xa1, 0xb33b, 1); -/* PDEBUG(D_PROBE, "Read again 0xb33b %d", tmpvalue); */ - msleep(1); - } + } while (retry-- && gspca_dev->usb_buf[0]); + reg_r(gspca_dev, 0xa1, 0xb33e, 1); ldata = gspca_dev->usb_buf[0]; reg_r(gspca_dev, 0xa1, 0xb33d, 1); mdata = gspca_dev->usb_buf[0]; reg_r(gspca_dev, 0xa1, 0xb33c, 1); hdata = gspca_dev->usb_buf[0]; - PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x", - hdata, mdata, ldata); + if (hdata != 0 && mdata != 0 && ldata != 0) + PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x", + hdata, mdata, ldata); reg_r(gspca_dev, 0xa1, 0xb334, 1); if (gspca_dev->usb_buf[0] == 0x02) - *value = (hdata << 8) + mdata; - else - *value = hdata; + return (hdata << 8) + mdata; + return hdata; } static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) @@ -2011,7 +2007,7 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) reg_w(dev, 0xa0, 0x0c, 0xb309); reg_w(dev, 0xa0, ptsensor_info->I2cAdd, 0xb335); reg_w(dev, 0xa0, ptsensor_info->op, 0xb301); - read_sensor_register(gspca_dev, ptsensor_info->IdAdd, &value); + value = read_sensor_register(gspca_dev, ptsensor_info->IdAdd); if (value == ptsensor_info->VpId) return ptsensor_info->sensorId; @@ -2023,13 +2019,16 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) return -1; } -static __u8 i2c_write(struct gspca_dev *gspca_dev, +static void i2c_write(struct gspca_dev *gspca_dev, __u8 reg, const __u8 *val, __u8 size) { struct usb_device *dev = gspca_dev->dev; + int retry; +#ifdef GSPCA_DEBUG if (size > 3 || size < 1) - return -EINVAL; + return; +#endif reg_r(gspca_dev, 0xa1, 0xb33f, 1); reg_w(dev, 0xa0, size, 0xb334); reg_w(dev, 0xa0, reg, 0xb33a); @@ -2041,18 +2040,23 @@ static __u8 i2c_write(struct gspca_dev *gspca_dev, reg_w(dev, 0xa0, val[0], 0xb336); reg_w(dev, 0xa0, val[1], 0xb337); break; - case 3: + default: +/* case 3: */ reg_w(dev, 0xa0, val[0], 0xb336); reg_w(dev, 0xa0, val[1], 0xb337); reg_w(dev, 0xa0, val[2], 0xb338); break; - default: - reg_w(dev, 0xa0, 0x01, 0xb334); - return -EINVAL; } reg_w(dev, 0xa0, 0x01, 0xb339); - reg_r(gspca_dev, 0xa1, 0xb33b, 1); - return gspca_dev->usb_buf[0] == 0; + retry = 4; + do { + reg_r(gspca_dev, 0xa1, 0xb33b, 1); + if (gspca_dev->usb_buf[0] == 0) + break; + msleep(20); + } while (--retry > 0); + if (retry <= 0) + PDEBUG(D_ERR, "i2c_write failed"); } static void put_tab_to_reg(struct gspca_dev *gspca_dev, @@ -2077,7 +2081,7 @@ static void usb_exchange(struct gspca_dev *gspca_dev, return; case 0xcc: /* normal write */ reg_w(dev, 0xa0, data[i][2], - ((data[i][0])<<8) | data[i][1]); + (data[i][0]) << 8 | data[i][1]); break; case 0xaa: /* i2c op */ i2c_write(gspca_dev, data[i][1], &data[i][2], 1); @@ -2094,11 +2098,6 @@ static void usb_exchange(struct gspca_dev *gspca_dev, /*not reached*/ } -/* - "GammaT"=hex:04,17,31,4f,6a,83,99,ad,bf,ce,da,e5,ee,f5,fb,ff,ff - "MatrixT"=hex:60,f9,e5,e7,50,05,f3,e6,66 - */ - static void vc0321_reset(struct gspca_dev *gspca_dev) { reg_w(gspca_dev->dev, 0xa0, 0x00, 0xb04d); @@ -2202,7 +2201,7 @@ static int sd_config(struct gspca_dev *gspca_dev, return 0; } -/* this function is called at probe and time */ +/* this function is called at probe and resume time */ static int sd_init(struct gspca_dev *gspca_dev) { return 0; @@ -2358,27 +2357,7 @@ static int sd_start(struct gspca_dev *gspca_dev) put_tab_to_reg(gspca_dev, GammaT, 17, 0xb85b); put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c); put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c); - /* Seem SHARPNESS */ - /* - reg_w(gspca_dev->dev, 0xa0, 0x80, 0xb80a); - reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80b); - reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80e); - */ - /* all 0x40 ??? do nothing - reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb822); - reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb823); - reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb824); - */ - /* Only works for HV7131R ?? - reg_r (gspca_dev, 0xa1, 0xb881, 1); - reg_w(gspca_dev->dev, 0xa0, 0xfe01, 0xb881); - reg_w(gspca_dev->dev, 0xa0, 0x79, 0xb801); - */ - /* only hv7131r et ov7660 - reg_w(gspca_dev->dev, 0xa0, 0x20, 0xb827); - reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb826); * ISP_GAIN 80 - reg_w(gspca_dev->dev, 0xa0, 0x23, 0xb800); * ISP CTRL_BAS - */ + /* set the led on 0x0892 0x0896 */ if (sd->sensor != SENSOR_PO1200) { reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff); @@ -2528,7 +2507,8 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ strcpy((char *) menu->name, "50 Hz"); return 0; - case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ + default: +/* case 2: * V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ strcpy((char *) menu->name, "60 Hz"); return 0; } @@ -2591,6 +2571,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 From 4b7ea770410dae8b9ca79623e4e36e94dfa86fd4 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 2 Feb 2009 11:43:50 +0100 Subject: gspca - vc032x: Remove the vc0321 reset. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/vc032x.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/vc032x.c b/linux/drivers/media/video/gspca/vc032x.c index 1832d241f..72cbf56c9 100644 --- a/linux/drivers/media/video/gspca/vc032x.c +++ b/linux/drivers/media/video/gspca/vc032x.c @@ -2098,6 +2098,7 @@ static void usb_exchange(struct gspca_dev *gspca_dev, /*not reached*/ } +#if 0 static void vc0321_reset(struct gspca_dev *gspca_dev) { reg_w(gspca_dev->dev, 0xa0, 0x00, 0xb04d); @@ -2106,6 +2107,7 @@ static void vc0321_reset(struct gspca_dev *gspca_dev) reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb003); msleep(100); } +#endif /* this function is called at probe time */ static int sd_config(struct gspca_dev *gspca_dev, @@ -2118,8 +2120,9 @@ static int sd_config(struct gspca_dev *gspca_dev, cam = &gspca_dev->cam; sd->bridge = id->driver_info; - +#if 0 vc0321_reset(gspca_dev); +#endif sensor = vc032x_probe_sensor(gspca_dev); switch (sensor) { case -1: -- cgit v1.2.3 From 2dc910b4909cf078d58c86b8ba22aef60febc2ee Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 2 Feb 2009 19:50:09 +0200 Subject: Add Freescale MC44S803 tuner driver From: Jochen Friedrich Add Freescale MC44S803 tuner driver. Priority: normal Signed-off-by: Jochen Friedrich Signed-off-by: Antti Palosaari --- linux/drivers/media/common/tuners/Kconfig | 8 + linux/drivers/media/common/tuners/Makefile | 1 + linux/drivers/media/common/tuners/mc44s803.c | 371 ++++++++++++++++++++++ linux/drivers/media/common/tuners/mc44s803.h | 46 +++ linux/drivers/media/common/tuners/mc44s803_priv.h | 208 ++++++++++++ 5 files changed, 634 insertions(+) create mode 100644 linux/drivers/media/common/tuners/mc44s803.c create mode 100644 linux/drivers/media/common/tuners/mc44s803.h create mode 100644 linux/drivers/media/common/tuners/mc44s803_priv.h (limited to 'linux') diff --git a/linux/drivers/media/common/tuners/Kconfig b/linux/drivers/media/common/tuners/Kconfig index 6f92beaa5..7969b695c 100644 --- a/linux/drivers/media/common/tuners/Kconfig +++ b/linux/drivers/media/common/tuners/Kconfig @@ -29,6 +29,7 @@ config MEDIA_TUNER select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMIZE select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMIZE menuconfig MEDIA_TUNER_CUSTOMIZE bool "Customize analog and hybrid tuner modules to build" @@ -164,4 +165,11 @@ config MEDIA_TUNER_MXL5007T help A driver for the silicon tuner MxL5007T from MaxLinear. +config MEDIA_TUNER_MC44S803 + tristate "Freescale MC44S803 Low Power CMOS Broadband tuners" + depends on VIDEO_MEDIA && I2C + default m if DVB_FE_CUSTOMISE + help + Say Y here to support the Freescale MC44S803 based tuners + endif # MEDIA_TUNER_CUSTOMIZE diff --git a/linux/drivers/media/common/tuners/Makefile b/linux/drivers/media/common/tuners/Makefile index 4dfbe5b82..4132b2be7 100644 --- a/linux/drivers/media/common/tuners/Makefile +++ b/linux/drivers/media/common/tuners/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o 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 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/frontends diff --git a/linux/drivers/media/common/tuners/mc44s803.c b/linux/drivers/media/common/tuners/mc44s803.c new file mode 100644 index 000000000..20c4485ce --- /dev/null +++ b/linux/drivers/media/common/tuners/mc44s803.c @@ -0,0 +1,371 @@ +/* + * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner + * + * Copyright (c) 2009 Jochen Friedrich + * + * 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 "dvb_frontend.h" + +#include "mc44s803.h" +#include "mc44s803_priv.h" + +#define mc_printk(level, format, arg...) \ + printk(level "mc44s803: " format , ## arg) + +/* Writes a single register */ +static int mc44s803_writereg(struct mc44s803_priv *priv, u32 val) +{ + u8 buf[3]; + struct i2c_msg msg = { + .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 3 + }; + + buf[0] = (val & 0xff0000) >> 16; + buf[1] = (val & 0xff00) >> 8; + buf[2] = (val & 0xff); + + if (i2c_transfer(priv->i2c, &msg, 1) != 1) { + mc_printk(KERN_WARNING, "I2C write failed\n"); + return -EREMOTEIO; + } + return 0; +} + +/* Reads a single register */ +static int mc44s803_readreg(struct mc44s803_priv *priv, u8 reg, u32 *val) +{ + u32 wval; + u8 buf[3]; + int ret; + struct i2c_msg msg[] = { + { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, + .buf = buf, .len = 3 }, + }; + + wval = MC44S803_REG_SM(MC44S803_REG_DATAREG, MC44S803_ADDR) | + MC44S803_REG_SM(reg, MC44S803_D); + + ret = mc44s803_writereg(priv, wval); + if (ret) + return ret; + + if (i2c_transfer(priv->i2c, msg, 1) != 1) { + mc_printk(KERN_WARNING, "I2C read failed\n"); + return -EREMOTEIO; + } + + *val = (buf[0] << 16) | (buf[1] << 8) | buf[2]; + + return 0; +} + +static int mc44s803_release(struct dvb_frontend *fe) +{ + struct mc44s803_priv *priv = fe->tuner_priv; + + fe->tuner_priv = NULL; + kfree(priv); + + return 0; +} + +static int mc44s803_init(struct dvb_frontend *fe) +{ + struct mc44s803_priv *priv = fe->tuner_priv; + u32 val; + int err; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + +/* Reset chip */ + val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR) | + MC44S803_REG_SM(1, MC44S803_RS); + + err = mc44s803_writereg(priv, val); + if (err) + goto exit; + + val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR); + + err = mc44s803_writereg(priv, val); + if (err) + goto exit; + +/* Power Up and Start Osc */ + + val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) | + MC44S803_REG_SM(0xC0, MC44S803_REFOSC) | + MC44S803_REG_SM(1, MC44S803_OSCSEL); + + err = mc44s803_writereg(priv, val); + if (err) + goto exit; + + val = MC44S803_REG_SM(MC44S803_REG_POWER, MC44S803_ADDR) | + MC44S803_REG_SM(0x200, MC44S803_POWER); + + err = mc44s803_writereg(priv, val); + if (err) + goto exit; + + msleep(10); + + val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) | + MC44S803_REG_SM(0x40, MC44S803_REFOSC) | + MC44S803_REG_SM(1, MC44S803_OSCSEL); + + err = mc44s803_writereg(priv, val); + if (err) + goto exit; + + msleep(20); + +/* Setup Mixer */ + + val = MC44S803_REG_SM(MC44S803_REG_MIXER, MC44S803_ADDR) | + MC44S803_REG_SM(1, MC44S803_TRI_STATE) | + MC44S803_REG_SM(0x7F, MC44S803_MIXER_RES); + + err = mc44s803_writereg(priv, val); + if (err) + goto exit; + +/* Setup Cirquit Adjust */ + + val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) | + MC44S803_REG_SM(1, MC44S803_G1) | + MC44S803_REG_SM(1, MC44S803_G3) | + MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) | + MC44S803_REG_SM(1, MC44S803_G6) | + MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) | + MC44S803_REG_SM(0x3, MC44S803_LP) | + MC44S803_REG_SM(1, MC44S803_CLRF) | + MC44S803_REG_SM(1, MC44S803_CLIF); + + err = mc44s803_writereg(priv, val); + if (err) + goto exit; + + val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) | + MC44S803_REG_SM(1, MC44S803_G1) | + MC44S803_REG_SM(1, MC44S803_G3) | + MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) | + MC44S803_REG_SM(1, MC44S803_G6) | + MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) | + MC44S803_REG_SM(0x3, MC44S803_LP); + + err = mc44s803_writereg(priv, val); + if (err) + goto exit; + +/* Setup Digtune */ + + val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) | + MC44S803_REG_SM(3, MC44S803_XOD); + + err = mc44s803_writereg(priv, val); + if (err) + goto exit; + +/* Setup AGC */ + + val = MC44S803_REG_SM(MC44S803_REG_LNAAGC, MC44S803_ADDR) | + MC44S803_REG_SM(1, MC44S803_AT1) | + MC44S803_REG_SM(1, MC44S803_AT2) | + MC44S803_REG_SM(1, MC44S803_AGC_AN_DIG) | + MC44S803_REG_SM(1, MC44S803_AGC_READ_EN) | + MC44S803_REG_SM(1, MC44S803_LNA0); + + err = mc44s803_writereg(priv, val); + if (err) + goto exit; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + return 0; + +exit: + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + mc_printk(KERN_WARNING, "I/O Error\n"); + return err; +} + +static int mc44s803_set_params(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + struct mc44s803_priv *priv = fe->tuner_priv; + u32 r1, r2, n1, n2, lo1, lo2, freq, val; + int err; + + priv->frequency = params->frequency; + + r1 = MC44S803_OSC / 1000000; + r2 = MC44S803_OSC / 100000; + + n1 = (params->frequency + MC44S803_IF1 + 500000) / 1000000; + freq = MC44S803_OSC / r1 * n1; + lo1 = ((60 * n1) + (r1 / 2)) / r1; + freq = freq - params->frequency; + + n2 = (freq - MC44S803_IF2 + 50000) / 100000; + lo2 = ((60 * n2) + (r2 / 2)) / r2; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + val = MC44S803_REG_SM(MC44S803_REG_REFDIV, MC44S803_ADDR) | + MC44S803_REG_SM(r1-1, MC44S803_R1) | + MC44S803_REG_SM(r2-1, MC44S803_R2) | + MC44S803_REG_SM(1, MC44S803_REFBUF_EN); + + err = mc44s803_writereg(priv, val); + if (err) + goto exit; + + val = MC44S803_REG_SM(MC44S803_REG_LO1, MC44S803_ADDR) | + MC44S803_REG_SM(n1-2, MC44S803_LO1); + + err = mc44s803_writereg(priv, val); + if (err) + goto exit; + + val = MC44S803_REG_SM(MC44S803_REG_LO2, MC44S803_ADDR) | + MC44S803_REG_SM(n2-2, MC44S803_LO2); + + err = mc44s803_writereg(priv, val); + if (err) + goto exit; + + val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) | + MC44S803_REG_SM(1, MC44S803_DA) | + MC44S803_REG_SM(lo1, MC44S803_LO_REF) | + MC44S803_REG_SM(1, MC44S803_AT); + + err = mc44s803_writereg(priv, val); + if (err) + goto exit; + + val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) | + MC44S803_REG_SM(2, MC44S803_DA) | + MC44S803_REG_SM(lo2, MC44S803_LO_REF) | + MC44S803_REG_SM(1, MC44S803_AT); + + err = mc44s803_writereg(priv, val); + if (err) + goto exit; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + return 0; + +exit: + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + mc_printk(KERN_WARNING, "I/O Error\n"); + return err; +} + +static int mc44s803_get_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct mc44s803_priv *priv = fe->tuner_priv; + *frequency = priv->frequency; + return 0; +} + +static const struct dvb_tuner_ops mc44s803_tuner_ops = { + .info = { + .name = "Freescale MC44S803", + .frequency_min = 48000000, + .frequency_max = 1000000000, + .frequency_step = 100000, + }, + + .release = mc44s803_release, + .init = mc44s803_init, + .set_params = mc44s803_set_params, + .get_frequency = mc44s803_get_frequency +}; + +/* This functions tries to identify a MC44S803 tuner by reading the ID + register. This is hasty. */ +struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, struct mc44s803_config *cfg) +{ + struct mc44s803_priv *priv; + u32 reg; + u8 id; + int ret; + + reg = 0; + + priv = kzalloc(sizeof(struct mc44s803_priv), GFP_KERNEL); + if (priv == NULL) + return NULL; + + priv->cfg = cfg; + priv->i2c = i2c; + priv->fe = fe; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ + + ret = mc44s803_readreg(priv, MC44S803_REG_ID, ®); + if (ret) + goto error; + + id = MC44S803_REG_MS(reg, MC44S803_ID); + + if (id != 0x14) { + mc_printk(KERN_ERR, "unsupported ID " + "(%x should be 0x14)\n", id); + goto error; + } + + mc_printk(KERN_INFO, "successfully identified (ID = %x)\n", id); + memcpy(&fe->ops.tuner_ops, &mc44s803_tuner_ops, + sizeof(struct dvb_tuner_ops)); + + fe->tuner_priv = priv; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ + + return fe; + +error: + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ + + kfree(priv); + return NULL; +} +EXPORT_SYMBOL(mc44s803_attach); + +MODULE_AUTHOR("Jochen Friedrich"); +MODULE_DESCRIPTION("Freescale MC44S803 silicon tuner driver"); +MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/common/tuners/mc44s803.h b/linux/drivers/media/common/tuners/mc44s803.h new file mode 100644 index 000000000..34f3892d3 --- /dev/null +++ b/linux/drivers/media/common/tuners/mc44s803.h @@ -0,0 +1,46 @@ +/* + * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner + * + * Copyright (c) 2009 Jochen Friedrich + * + * 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 MC44S803_H +#define MC44S803_H + +struct dvb_frontend; +struct i2c_adapter; + +struct mc44s803_config { + u8 i2c_address; + u8 dig_out; +}; + +#if defined(CONFIG_MEDIA_TUNER_MC44S803) || \ + (defined(CONFIG_MEDIA_TUNER_MC44S803_MODULE) && defined(MODULE)) +extern struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, struct mc44s803_config *cfg); +#else +static inline struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, struct mc44s803_config *cfg) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* CONFIG_MEDIA_TUNER_MC44S803 */ + +#endif diff --git a/linux/drivers/media/common/tuners/mc44s803_priv.h b/linux/drivers/media/common/tuners/mc44s803_priv.h new file mode 100644 index 000000000..14a927809 --- /dev/null +++ b/linux/drivers/media/common/tuners/mc44s803_priv.h @@ -0,0 +1,208 @@ +/* + * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner + * + * Copyright (c) 2009 Jochen Friedrich + * + * 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 MC44S803_PRIV_H +#define MC44S803_PRIV_H + +/* This driver is based on the information available in the datasheet + http://www.freescale.com/files/rf_if/doc/data_sheet/MC44S803.pdf + + SPI or I2C Address : 0xc0-0xc6 + + Reg.No | Function + ------------------------------------------- + 00 | Power Down + 01 | Reference Oszillator + 02 | Reference Dividers + 03 | Mixer and Reference Buffer + 04 | Reset/Serial Out + 05 | LO 1 + 06 | LO 2 + 07 | Circuit Adjust + 08 | Test + 09 | Digital Tune + 0A | LNA AGC + 0B | Data Register Address + 0C | Regulator Test + 0D | VCO Test + 0E | LNA Gain/Input Power + 0F | ID Bits + +*/ + +#define MC44S803_OSC 26000000 /* 26 MHz */ +#define MC44S803_IF1 1086000000 /* 1086 MHz */ +#define MC44S803_IF2 36125000 /* 36.125 MHz */ + +#define MC44S803_REG_POWER 0 +#define MC44S803_REG_REFOSC 1 +#define MC44S803_REG_REFDIV 2 +#define MC44S803_REG_MIXER 3 +#define MC44S803_REG_RESET 4 +#define MC44S803_REG_LO1 5 +#define MC44S803_REG_LO2 6 +#define MC44S803_REG_CIRCADJ 7 +#define MC44S803_REG_TEST 8 +#define MC44S803_REG_DIGTUNE 9 +#define MC44S803_REG_LNAAGC 0x0A +#define MC44S803_REG_DATAREG 0x0B +#define MC44S803_REG_REGTEST 0x0C +#define MC44S803_REG_VCOTEST 0x0D +#define MC44S803_REG_LNAGAIN 0x0E +#define MC44S803_REG_ID 0x0F + +/* Register definitions */ +#define MC44S803_ADDR 0x0F +#define MC44S803_ADDR_S 0 +/* REG_POWER */ +#define MC44S803_POWER 0xFFFFF0 +#define MC44S803_POWER_S 4 +/* REG_REFOSC */ +#define MC44S803_REFOSC 0x1FF0 +#define MC44S803_REFOSC_S 4 +#define MC44S803_OSCSEL 0x2000 +#define MC44S803_OSCSEL_S 13 +/* REG_REFDIV */ +#define MC44S803_R2 0x1FF0 +#define MC44S803_R2_S 4 +#define MC44S803_REFBUF_EN 0x2000 +#define MC44S803_REFBUF_EN_S 13 +#define MC44S803_R1 0x7C000 +#define MC44S803_R1_S 14 +/* REG_MIXER */ +#define MC44S803_R3 0x70 +#define MC44S803_R3_S 4 +#define MC44S803_MUX3 0x80 +#define MC44S803_MUX3_S 7 +#define MC44S803_MUX4 0x100 +#define MC44S803_MUX4_S 8 +#define MC44S803_OSC_SCR 0x200 +#define MC44S803_OSC_SCR_S 9 +#define MC44S803_TRI_STATE 0x400 +#define MC44S803_TRI_STATE_S 10 +#define MC44S803_BUF_GAIN 0x800 +#define MC44S803_BUF_GAIN_S 11 +#define MC44S803_BUF_IO 0x1000 +#define MC44S803_BUF_IO_S 12 +#define MC44S803_MIXER_RES 0xFE000 +#define MC44S803_MIXER_RES_S 13 +/* REG_RESET */ +#define MC44S803_RS 0x10 +#define MC44S803_RS_S 4 +#define MC44S803_SO 0x20 +#define MC44S803_SO_S 5 +/* REG_LO1 */ +#define MC44S803_LO1 0xFFF0 +#define MC44S803_LO1_S 4 +/* REG_LO2 */ +#define MC44S803_LO2 0x7FFF0 +#define MC44S803_LO2_S 4 +/* REG_CIRCADJ */ +#define MC44S803_G1 0x20 +#define MC44S803_G1_S 5 +#define MC44S803_G3 0x80 +#define MC44S803_G3_S 7 +#define MC44S803_CIRCADJ_RES 0x300 +#define MC44S803_CIRCADJ_RES_S 8 +#define MC44S803_G6 0x400 +#define MC44S803_G6_S 10 +#define MC44S803_G7 0x800 +#define MC44S803_G7_S 11 +#define MC44S803_S1 0x1000 +#define MC44S803_S1_S 12 +#define MC44S803_LP 0x7E000 +#define MC44S803_LP_S 13 +#define MC44S803_CLRF 0x80000 +#define MC44S803_CLRF_S 19 +#define MC44S803_CLIF 0x100000 +#define MC44S803_CLIF_S 20 +/* REG_TEST */ +/* REG_DIGTUNE */ +#define MC44S803_DA 0xF0 +#define MC44S803_DA_S 4 +#define MC44S803_XOD 0x300 +#define MC44S803_XOD_S 8 +#define MC44S803_RST 0x10000 +#define MC44S803_RST_S 16 +#define MC44S803_LO_REF 0x1FFF00 +#define MC44S803_LO_REF_S 8 +#define MC44S803_AT 0x200000 +#define MC44S803_AT_S 21 +#define MC44S803_MT 0x400000 +#define MC44S803_MT_S 22 +/* REG_LNAAGC */ +#define MC44S803_G 0x3F0 +#define MC44S803_G_S 4 +#define MC44S803_AT1 0x400 +#define MC44S803_AT1_S 10 +#define MC44S803_AT2 0x800 +#define MC44S803_AT2_S 11 +#define MC44S803_HL_GR_EN 0x8000 +#define MC44S803_HL_GR_EN_S 15 +#define MC44S803_AGC_AN_DIG 0x10000 +#define MC44S803_AGC_AN_DIG_S 16 +#define MC44S803_ATTEN_EN 0x20000 +#define MC44S803_ATTEN_EN_S 17 +#define MC44S803_AGC_READ_EN 0x40000 +#define MC44S803_AGC_READ_EN_S 18 +#define MC44S803_LNA0 0x80000 +#define MC44S803_LNA0_S 19 +#define MC44S803_AGC_SEL 0x100000 +#define MC44S803_AGC_SEL_S 20 +#define MC44S803_AT0 0x200000 +#define MC44S803_AT0_S 21 +#define MC44S803_B 0xC00000 +#define MC44S803_B_S 22 +/* REG_DATAREG */ +#define MC44S803_D 0xF0 +#define MC44S803_D_S 4 +/* REG_REGTEST */ +/* REG_VCOTEST */ +/* REG_LNAGAIN */ +#define MC44S803_IF_PWR 0x700 +#define MC44S803_IF_PWR_S 8 +#define MC44S803_RF_PWR 0x3800 +#define MC44S803_RF_PWR_S 11 +#define MC44S803_LNA_GAIN 0xFC000 +#define MC44S803_LNA_GAIN_S 14 +/* REG_ID */ +#define MC44S803_ID 0x3E00 +#define MC44S803_ID_S 9 + +/* Some macros to read/write fields */ + +/* First shift, then mask */ +#define MC44S803_REG_SM(_val, _reg) \ + (((_val) << _reg##_S) & (_reg)) + +/* First mask, then shift */ +#define MC44S803_REG_MS(_val, _reg) \ + (((_val) & (_reg)) >> _reg##_S) + +struct mc44s803_priv { + struct mc44s803_config *cfg; + struct i2c_adapter *i2c; + struct dvb_frontend *fe; + + u32 frequency; +}; + +#endif -- cgit v1.2.3 From f605aeb864167147d6fcf6841b3bb523276bb519 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 2 Feb 2009 19:59:50 +0200 Subject: af9015: add MC44S803 support From: Jochen Friedrich Add MC44S803 support to AF9015 driver. Priority: normal Signed-off-by: Jochen Friedrich Signed-off-by: Antti Palosaari --- linux/drivers/media/dvb/dvb-usb/Kconfig | 1 + linux/drivers/media/dvb/dvb-usb/af9015.c | 40 +++++++++++++++++++++----------- 2 files changed, 28 insertions(+), 13 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index 49f7b20c2..bbddc9fb6 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -297,5 +297,6 @@ config DVB_USB_AF9015 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMIZE select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE help Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.c b/linux/drivers/media/dvb/dvb-usb/af9015.c index e518d47fe..88a365ad9 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.c +++ b/linux/drivers/media/dvb/dvb-usb/af9015.c @@ -27,9 +27,7 @@ #include "qt1010.h" #include "tda18271.h" #include "mxl5005s.h" -#if 0 /* keep */ -#include "mc44s80x.h" -#endif +#include "mc44s803.h" static int dvb_usb_af9015_debug; module_param_named(debug, dvb_usb_af9015_debug, int, 0644); @@ -280,6 +278,21 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. req.data = &msg[i+1].buf[0]; ret = af9015_ctrl_msg(d, &req); i += 2; + } else if (msg[i].flags & I2C_M_RD) { + ret = -EINVAL; + if (msg[i].addr == + af9015_af9013_config[0].demod_address) + goto error; + else + req.cmd = READ_I2C; + req.i2c_addr = msg[i].addr; + req.addr = addr; + req.mbox = mbox; + req.addr_len = addr_len; + req.data_len = msg[i].len; + req.data = &msg[i].buf[0]; + ret = af9015_ctrl_msg(d, &req); + i += 1; } else { if (msg[i].addr == af9015_af9013_config[0].demod_address) @@ -942,7 +955,6 @@ static int af9015_read_config(struct usb_device *udev) switch (val) { case AF9013_TUNER_ENV77H11D5: case AF9013_TUNER_MT2060: - case AF9013_TUNER_MC44S803: case AF9013_TUNER_QT1010: case AF9013_TUNER_UNKNOWN: case AF9013_TUNER_MT2060_2: @@ -955,6 +967,10 @@ static int af9015_read_config(struct usb_device *udev) case AF9013_TUNER_MXL5005R: af9015_af9013_config[i].rf_spec_inv = 0; break; + case AF9013_TUNER_MC44S803: + af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO; + af9015_af9013_config[i].rf_spec_inv = 1; + break; default: warn("tuner id:%d not supported, please report!", val); return -ENODEV; @@ -1142,6 +1158,11 @@ static struct mxl5005s_config af9015_mxl5005_config = { .AgcMasterByte = 0x00, }; +static struct mc44s803_config af9015_mc44s803_config = { + .i2c_address = 0xc0, + .dig_out = 1, +}; + static int af9015_tuner_attach(struct dvb_usb_adapter *adap) { struct af9015_state *state = adap->dev->priv; @@ -1186,15 +1207,8 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap) DVB_PLL_TDA665X) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_MC44S803: -#if 0 /* keep */ - ret = dvb_attach(mc44s80x_attach, adap->fe, i2c_adap) - == NULL ? -ENODEV : 0; -#else - ret = -ENODEV; - info("Freescale MC44S803 tuner found but no driver for that" \ - "tuner. Look at the Linuxtv.org for tuner driver" \ - "status."); -#endif + ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap, + &af9015_mc44s803_config) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_UNKNOWN: default: -- cgit v1.2.3 From c1d676109e87244212120f7ba938d67c3d0571a0 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 2 Feb 2009 20:25:38 +0100 Subject: gspca - some drivers: Fix compilation warnings. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/mr97310a.c | 2 +- linux/drivers/media/video/gspca/sonixj.c | 2 +- linux/drivers/media/video/gspca/spca505.c | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/mr97310a.c b/linux/drivers/media/video/gspca/mr97310a.c index 3a5ddff8f..5ec5ce6e3 100644 --- a/linux/drivers/media/video/gspca/mr97310a.c +++ b/linux/drivers/media/video/gspca/mr97310a.c @@ -73,7 +73,7 @@ static int reg_w(struct gspca_dev *gspca_dev, int len) rc = usb_bulk_msg(gspca_dev->dev, usb_sndbulkpipe(gspca_dev->dev, 4), - gspca_dev->usb_buf, len, 0, 500); + gspca_dev->usb_buf, len, NULL, 500); if (rc < 0) PDEBUG(D_ERR, "reg write [%02x] error %d", gspca_dev->usb_buf[0], rc); diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 0aa4649bd..3be96d9f4 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -1031,7 +1031,7 @@ static void mi0360_probe(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int i, j; - u16 val; + u16 val = 0; static const u8 probe_tb[][4][8] = { { /* mi0360 */ {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, diff --git a/linux/drivers/media/video/gspca/spca505.c b/linux/drivers/media/video/gspca/spca505.c index 4fc54d8b8..2acec58b1 100644 --- a/linux/drivers/media/video/gspca/spca505.c +++ b/linux/drivers/media/video/gspca/spca505.c @@ -426,8 +426,8 @@ static const u8 spca505b_open_data_ccd[][3] = { {0x05, 0x00, 0x11}, {0x05, 0x00, 0x12}, {0x05, 0x6f, 0x00}, - {0x05, (u8) (initial_brightness >> 6), 0x00}, - {0x05, (u8) (initial_brightness << 2), 0x01}, + {0x05, initial_brightness >> 6, 0x00}, + {0x05, (initial_brightness << 2) & 0xff, 0x01}, {0x05, 0x00, 0x02}, {0x05, 0x01, 0x03}, {0x05, 0x00, 0x04}, @@ -560,8 +560,8 @@ static const u8 spca505b_open_data_ccd[][3] = { {0x06, 0x5f, 0x1f}, {0x06, 0x32, 0x20}, - {0x05, (u8) (initial_brightness >> 6), 0x00}, - {0x05, (u8) (initial_brightness << 2), 0x01}, + {0x05, initial_brightness >> 6, 0x00}, + {0x05, (initial_brightness << 2) & 0xff, 0x01}, {0x05, 0x06, 0xc1}, {0x05, 0x58, 0xc2}, {0x05, 0x00, 0xca}, -- cgit v1.2.3 From e086109f0cad2b76f5a32cf18db838e2026712bb Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 4 Feb 2009 19:33:21 +0100 Subject: gspca - main: Destroy the URBs at disconnection time. From: Adam Baker If a device using the gspca framework is unplugged while it is still streaming then the call that is used to free the URBs that have been allocated occurs after the pointer it uses becomes invalid at the end of gspca_disconnect. Make another cleanup call in gspca_disconnect while the pointer is still valid (multiple calls are OK as destroy_urbs checks for pointers already being NULL. Priority: high Signed-off-by: Adam Baker Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/gspca.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index cac937040..64842682e 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -434,6 +434,7 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) if (urb == NULL) break; + BUG_ON(!gspca_dev->dev); gspca_dev->urb[i] = NULL; if (!gspca_dev->present) usb_kill_urb(urb); @@ -1953,8 +1954,12 @@ void gspca_disconnect(struct usb_interface *intf) { struct gspca_dev *gspca_dev = usb_get_intfdata(intf); + mutex_lock(&gspca_dev->usb_lock); gspca_dev->present = 0; + mutex_unlock(&gspca_dev->usb_lock); + destroy_urbs(gspca_dev); + gspca_dev->dev = NULL; usb_set_intfdata(intf, NULL); /* release the device */ -- cgit v1.2.3 From 17f2b6ad963ce70cc8f191dc9def4100e54811f8 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Thu, 5 Feb 2009 09:48:43 -0200 Subject: radio-mr800: codingstyle cleanups From: Alexey Klimov Cleanups of many if-check constructions. Priority: normal Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/radio/radio-mr800.c | 36 +++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 11 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-mr800.c b/linux/drivers/media/radio/radio-mr800.c index 4aa51a282..caa71501a 100644 --- a/linux/drivers/media/radio/radio-mr800.c +++ b/linux/drivers/media/radio/radio-mr800.c @@ -378,13 +378,15 @@ static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); + int retval; /* safety check */ if (radio->removed) return -EIO; radio->curfreq = f->frequency; - if (amradio_setfreq(radio, radio->curfreq) < 0) + retval = amradio_setfreq(radio, radio->curfreq); + if (retval < 0) amradio_dev_warn(&radio->videodev->dev, "set frequency failed\n"); return 0; @@ -443,6 +445,7 @@ 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; /* safety check */ if (radio->removed) @@ -451,13 +454,15 @@ static int vidioc_s_ctrl(struct file *file, void *priv, switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: if (ctrl->value) { - if (amradio_stop(radio) < 0) { + retval = amradio_stop(radio); + if (retval < 0) { amradio_dev_warn(&radio->videodev->dev, "amradio_stop failed\n"); return -1; } } else { - if (amradio_start(radio) < 0) { + retval = amradio_start(radio); + if (retval < 0) { amradio_dev_warn(&radio->videodev->dev, "amradio_start failed\n"); return -1; @@ -508,20 +513,24 @@ 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; lock_kernel(); radio->users = 1; radio->muted = 1; - if (amradio_start(radio) < 0) { + retval = amradio_start(radio); + if (retval < 0) { amradio_dev_warn(&radio->videodev->dev, "radio did not start up properly\n"); radio->users = 0; unlock_kernel(); return -EIO; } - if (amradio_setfreq(radio, radio->curfreq) < 0) + + retval = amradio_setfreq(radio, radio->curfreq); + if (retval < 0) amradio_dev_warn(&radio->videodev->dev, "set frequency failed\n"); @@ -554,8 +563,10 @@ static int usb_amradio_close(struct file *file) static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) { struct amradio_device *radio = usb_get_intfdata(intf); + int retval; - if (amradio_stop(radio) < 0) + retval = amradio_stop(radio); + if (retval < 0) dev_warn(&intf->dev, "amradio_stop failed\n"); dev_info(&intf->dev, "going into suspend..\n"); @@ -567,8 +578,10 @@ 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; - if (amradio_start(radio) < 0) + retval = amradio_start(radio); + if (retval < 0) dev_warn(&intf->dev, "amradio_start failed\n"); dev_info(&intf->dev, "coming out of suspend..\n"); @@ -619,16 +632,16 @@ static struct video_device amradio_videodev_template = { .release = usb_amradio_device_release, }; -/* check if the device is present and register with v4l and -usb if it is */ +/* check if the device is present and register with v4l and usb if it is */ static int usb_amradio_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct amradio_device *radio; + int retval; radio = kmalloc(sizeof(struct amradio_device), GFP_KERNEL); - if (!(radio)) + if (!radio) return -ENOMEM; radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL); @@ -657,7 +670,8 @@ static int usb_amradio_probe(struct usb_interface *intf, mutex_init(&radio->lock); video_set_drvdata(radio->videodev, radio); - if (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_warn(&intf->dev, "could not register video device\n"); video_device_release(radio->videodev); kfree(radio->buffer); -- cgit v1.2.3 From d29804beec15d8395aa769769f49c47b3804773a Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Thu, 5 Feb 2009 09:49:58 -0200 Subject: radio-mr800: place dev_err instead of dev_warn From: Alexey Klimov There should be dev_err message if video_register_device() fails. Correct this situation. Priority: normal Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/radio/radio-mr800.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-mr800.c b/linux/drivers/media/radio/radio-mr800.c index caa71501a..cf26043af 100644 --- a/linux/drivers/media/radio/radio-mr800.c +++ b/linux/drivers/media/radio/radio-mr800.c @@ -672,7 +672,7 @@ static int usb_amradio_probe(struct usb_interface *intf, video_set_drvdata(radio->videodev, radio); retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); if (retval < 0) { - dev_warn(&intf->dev, "could not register video device\n"); + dev_err(&intf->dev, "could not register video device\n"); video_device_release(radio->videodev); kfree(radio->buffer); kfree(radio); -- cgit v1.2.3 From 97f4aaf0e577018bba36f877b081e05c6be0567b Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Thu, 5 Feb 2009 09:51:51 -0200 Subject: radio-mr800: add more dev_err messages in probe From: Alexey Klimov Patch adds 3 dev_err messages in usb_amradio_probe() function. Priority: normal Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/radio/radio-mr800.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-mr800.c b/linux/drivers/media/radio/radio-mr800.c index cf26043af..83f4f2b67 100644 --- a/linux/drivers/media/radio/radio-mr800.c +++ b/linux/drivers/media/radio/radio-mr800.c @@ -641,19 +641,23 @@ static int usb_amradio_probe(struct usb_interface *intf, radio = kmalloc(sizeof(struct amradio_device), GFP_KERNEL); - if (!radio) + if (!radio) { + dev_err(&intf->dev, "kmalloc for amradio_device failed\n"); return -ENOMEM; + } radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL); - if (!(radio->buffer)) { + if (!radio->buffer) { + dev_err(&intf->dev, "kmalloc for radio->buffer failed\n"); kfree(radio); return -ENOMEM; } radio->videodev = video_device_alloc(); - if (!(radio->videodev)) { + if (!radio->videodev) { + dev_err(&intf->dev, "video_device_alloc failed\n"); kfree(radio->buffer); kfree(radio); return -ENOMEM; -- cgit v1.2.3 From b01c0f56c2b1a2db922b500adf902bbcde73e021 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Thu, 5 Feb 2009 09:53:02 -0200 Subject: radio-mr800: move radio start and stop in one function From: Alexey Klimov Patch introduces new amradio_set_mute function. Amradio_start and amradio_stop removed. This makes driver more flexible and it's useful for next changes. Priority: normal Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/radio/radio-mr800.c | 64 +++++++++++---------------------- 1 file changed, 21 insertions(+), 43 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-mr800.c b/linux/drivers/media/radio/radio-mr800.c index 83f4f2b67..5e5aafec1 100644 --- a/linux/drivers/media/radio/radio-mr800.c +++ b/linux/drivers/media/radio/radio-mr800.c @@ -88,6 +88,16 @@ devices, that would be 76 and 91. */ #define FREQ_MAX 108.0 #define FREQ_MUL 16000 +/* + * Commands that device should understand + * List isnt full and will be updated with implementation of new functions + */ +#define AMRADIO_SET_MUTE 0xab + +/* Comfortable defines for amradio_set_mute */ +#define AMRADIO_START 0x00 +#define AMRADIO_STOP 0x01 + /* module parameter */ static int radio_nr = -1; module_param(radio_nr, int, 0); @@ -172,40 +182,8 @@ static struct usb_driver usb_amradio_driver = { .supports_autosuspend = 0, }; -/* switch on radio. Send 8 bytes to device. */ -static int amradio_start(struct amradio_device *radio) -{ - int retval; - int size; - - mutex_lock(&radio->lock); - - radio->buffer[0] = 0x00; - radio->buffer[1] = 0x55; - radio->buffer[2] = 0xaa; - radio->buffer[3] = 0x00; - radio->buffer[4] = 0xab; - radio->buffer[5] = 0x00; - radio->buffer[6] = 0x00; - radio->buffer[7] = 0x00; - - retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), - (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - - if (retval) { - mutex_unlock(&radio->lock); - return retval; - } - - radio->muted = 0; - - mutex_unlock(&radio->lock); - - return retval; -} - -/* switch off radio */ -static int amradio_stop(struct amradio_device *radio) +/* switch on/off the radio. Send 8 bytes to device */ +static int amradio_set_mute(struct amradio_device *radio, char argument) { int retval; int size; @@ -220,8 +198,8 @@ static int amradio_stop(struct amradio_device *radio) radio->buffer[1] = 0x55; radio->buffer[2] = 0xaa; radio->buffer[3] = 0x00; - radio->buffer[4] = 0xab; - radio->buffer[5] = 0x01; + radio->buffer[4] = AMRADIO_SET_MUTE; + radio->buffer[5] = argument; radio->buffer[6] = 0x00; radio->buffer[7] = 0x00; @@ -233,7 +211,7 @@ static int amradio_stop(struct amradio_device *radio) return retval; } - radio->muted = 1; + radio->muted = argument; mutex_unlock(&radio->lock); @@ -454,14 +432,14 @@ static int vidioc_s_ctrl(struct file *file, void *priv, switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: if (ctrl->value) { - retval = amradio_stop(radio); + retval = amradio_set_mute(radio, AMRADIO_STOP); if (retval < 0) { amradio_dev_warn(&radio->videodev->dev, "amradio_stop failed\n"); return -1; } } else { - retval = amradio_start(radio); + retval = amradio_set_mute(radio, AMRADIO_START); if (retval < 0) { amradio_dev_warn(&radio->videodev->dev, "amradio_start failed\n"); @@ -520,7 +498,7 @@ static int usb_amradio_open(struct file *file) radio->users = 1; radio->muted = 1; - retval = amradio_start(radio); + retval = amradio_set_mute(radio, AMRADIO_START); if (retval < 0) { amradio_dev_warn(&radio->videodev->dev, "radio did not start up properly\n"); @@ -550,7 +528,7 @@ static int usb_amradio_close(struct file *file) radio->users = 0; if (!radio->removed) { - retval = amradio_stop(radio); + retval = amradio_set_mute(radio, AMRADIO_STOP); if (retval < 0) amradio_dev_warn(&radio->videodev->dev, "amradio_stop failed\n"); @@ -565,7 +543,7 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) struct amradio_device *radio = usb_get_intfdata(intf); int retval; - retval = amradio_stop(radio); + retval = amradio_set_mute(radio, AMRADIO_STOP); if (retval < 0) dev_warn(&intf->dev, "amradio_stop failed\n"); @@ -580,7 +558,7 @@ static int usb_amradio_resume(struct usb_interface *intf) struct amradio_device *radio = usb_get_intfdata(intf); int retval; - retval = amradio_start(radio); + retval = amradio_set_mute(radio, AMRADIO_START); if (retval < 0) dev_warn(&intf->dev, "amradio_start failed\n"); -- cgit v1.2.3 From ef963eaf3f1b40899c38f9926a867743dbaf11bb Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Thu, 5 Feb 2009 09:54:17 -0200 Subject: radio-mr800: fix amradio_set_freq From: Alexey Klimov Fixing frequency adjustment to provide better diapason(band?) fit. Also, add AMRADIO_SET_FREQ to the list of commands. Priority: normal Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/radio/radio-mr800.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-mr800.c b/linux/drivers/media/radio/radio-mr800.c index 5e5aafec1..f0f0182d4 100644 --- a/linux/drivers/media/radio/radio-mr800.c +++ b/linux/drivers/media/radio/radio-mr800.c @@ -92,6 +92,7 @@ devices, that would be 76 and 91. */ * Commands that device should understand * List isnt full and will be updated with implementation of new functions */ +#define AMRADIO_SET_FREQ 0xa4 #define AMRADIO_SET_MUTE 0xab /* Comfortable defines for amradio_set_mute */ @@ -223,7 +224,7 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) { int retval; int size; - unsigned short freq_send = 0x13 + (freq >> 3) / 25; + unsigned short freq_send = 0x10 + (freq >> 3) / 25; /* safety check */ if (radio->removed) @@ -235,7 +236,7 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) radio->buffer[1] = 0x55; radio->buffer[2] = 0xaa; radio->buffer[3] = 0x03; - radio->buffer[4] = 0xa4; + radio->buffer[4] = AMRADIO_SET_FREQ; radio->buffer[5] = 0x00; radio->buffer[6] = 0x00; radio->buffer[7] = 0x08; -- cgit v1.2.3 From 38f50860e8ac9f600fd8240f54f2fdb753f7bb9f Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Thu, 5 Feb 2009 09:56:07 -0200 Subject: radio-mr800: add stereo support From: Alexey Klimov Patch introduces new amradio_set_stereo function. Driver calls this func to make stereo radio reception. Corrects checking of returned value after usb_bulk_msg. Priority: normal Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/radio/radio-mr800.c | 81 ++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-mr800.c b/linux/drivers/media/radio/radio-mr800.c index f0f0182d4..b6ac1d48d 100644 --- a/linux/drivers/media/radio/radio-mr800.c +++ b/linux/drivers/media/radio/radio-mr800.c @@ -94,11 +94,16 @@ devices, that would be 76 and 91. */ */ #define AMRADIO_SET_FREQ 0xa4 #define AMRADIO_SET_MUTE 0xab +#define AMRADIO_SET_MONO 0xae /* Comfortable defines for amradio_set_mute */ #define AMRADIO_START 0x00 #define AMRADIO_STOP 0x01 +/* Comfortable defines for amradio_set_stereo */ +#define WANT_STEREO 0x00 +#define WANT_MONO 0x01 + /* module parameter */ static int radio_nr = -1; module_param(radio_nr, int, 0); @@ -266,13 +271,49 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) return retval; } - radio->stereo = 0; + mutex_unlock(&radio->lock); + + return retval; +} + +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); + + radio->buffer[0] = 0x00; + radio->buffer[1] = 0x55; + radio->buffer[2] = 0xaa; + radio->buffer[3] = 0x00; + radio->buffer[4] = AMRADIO_SET_MONO; + radio->buffer[5] = argument; + radio->buffer[6] = 0x00; + radio->buffer[7] = 0x00; + + 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; + mutex_unlock(&radio->lock); + return retval; + } + + radio->stereo = 1; mutex_unlock(&radio->lock); return retval; } + + /* USB subsystem interface begins here */ /* handle unplugging of the device, release data structures @@ -310,6 +351,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); + int retval; /* safety check */ if (radio->removed) @@ -321,7 +363,16 @@ static int vidioc_g_tuner(struct file *file, void *priv, /* TODO: Add function which look is signal stereo or not * amradio_getstat(radio); */ - radio->stereo = -1; + +/* we call amradio_set_stereo to set radio->stereo + * Honestly, amradio_getstat should cover this in future and + * 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; v->rangelow = FREQ_MIN * FREQ_MUL; @@ -342,6 +393,7 @@ static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); + int retval; /* safety check */ if (radio->removed) @@ -349,6 +401,25 @@ static int vidioc_s_tuner(struct file *file, void *priv, if (v->index > 0) return -EINVAL; + + /* mono/stereo selector */ + 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; + default: + return -EINVAL; + } + return 0; } @@ -508,6 +579,11 @@ static int usb_amradio_open(struct file *file) return -EIO; } + 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, @@ -649,6 +725,7 @@ static int usb_amradio_probe(struct usb_interface *intf, radio->users = 0; radio->usbdev = interface_to_usbdev(intf); radio->curfreq = 95.16 * FREQ_MUL; + radio->stereo = -1; mutex_init(&radio->lock); -- cgit v1.2.3 From 08e10a545481449933bbb9a40be2dbb4e3a7a40c Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Thu, 5 Feb 2009 09:57:19 -0200 Subject: radio-mr800: add few lost mutex locks From: Alexey Klimov Patch adds two lost mutex locks. Priority: normal Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/radio/radio-mr800.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-mr800.c b/linux/drivers/media/radio/radio-mr800.c index b6ac1d48d..e1c63d76e 100644 --- a/linux/drivers/media/radio/radio-mr800.c +++ b/linux/drivers/media/radio/radio-mr800.c @@ -434,7 +434,10 @@ static int vidioc_s_frequency(struct file *file, void *priv, if (radio->removed) return -EIO; + 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, @@ -602,7 +605,9 @@ static int usb_amradio_close(struct file *file) if (!radio) return -ENODEV; + mutex_lock(&radio->lock); radio->users = 0; + mutex_unlock(&radio->lock); if (!radio->removed) { retval = amradio_set_mute(radio, AMRADIO_STOP); -- cgit v1.2.3 From bf126270efecf5e5531fa1972fc1e9b4b297f835 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Thu, 5 Feb 2009 09:58:31 -0200 Subject: radio-mr800: increase version and add comments From: Alexey Klimov Increase driver version to 0.10, remove old and add new useful comments. Priority: normal Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/radio/radio-mr800.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-mr800.c b/linux/drivers/media/radio/radio-mr800.c index e1c63d76e..60c8c19fc 100644 --- a/linux/drivers/media/radio/radio-mr800.c +++ b/linux/drivers/media/radio/radio-mr800.c @@ -22,7 +22,7 @@ */ /* - * Big thanks to authors of dsbr100.c and radio-si470x.c + * Big thanks to authors and contributors of dsbr100.c and radio-si470x.c * * When work was looked pretty good, i discover this: * http://av-usbradio.sourceforge.net/index.php @@ -30,18 +30,23 @@ * Latest release of theirs project was in 2005. * Probably, this driver could be improved trough using their * achievements (specifications given). - * So, we have smth to begin with. + * Also, Faidon Liambotis wrote nice driver for this radio + * in 2007. He allowed to use his driver to improve current mr800 radio driver. + * http://kerneltrap.org/mailarchive/linux-usb-devel/2007/10/11/342492 * - * History: * Version 0.01: First working version. * It's required to blacklist AverMedia USB Radio * in usbhid/hid-quirks.c + * Version 0.10: A lot of cleanups and fixes: unpluging the device, + * few mutex locks were added, codinstyle issues, etc. + * Added stereo support. Thanks to + * Douglas Schilling Landgraf and + * David Ellingsworth + * for discussion, help and support. * * Many things to do: * - Correct power managment of device (suspend & resume) - * - Make x86 independance (little-endian and big-endian stuff) * - Add code for scanning and smooth tuning - * - Checked and add stereo&mono stuff * - Add code for sensitivity value * - Correct mistakes * - In Japan another FREQ_MIN and FREQ_MAX @@ -63,8 +68,8 @@ /* driver and module definitions */ #define DRIVER_AUTHOR "Alexey Klimov " #define DRIVER_DESC "AverMedia MR 800 USB FM radio driver" -#define DRIVER_VERSION "0.01" -#define RADIO_VERSION KERNEL_VERSION(0, 0, 1) +#define DRIVER_VERSION "0.10" +#define RADIO_VERSION KERNEL_VERSION(0, 1, 0) MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); @@ -312,14 +317,11 @@ static int amradio_set_stereo(struct amradio_device *radio, char argument) return retval; } - - -/* USB subsystem interface begins here */ - -/* handle unplugging of the device, release data structures -if nothing keeps us from doing it. If something is still -keeping us busy, the release callback of v4l will take care -of releasing it. */ +/* Handle unplugging the device. + * We call video_unregister_device in any case. + * The last function called in this procedure is + * usb_amradio_device_release. + */ static void usb_amradio_disconnect(struct usb_interface *intf) { struct amradio_device *radio = usb_get_intfdata(intf); -- cgit v1.2.3 From 2b47bb2b85cbd75eff389304c2b55bebecfb4755 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Thu, 5 Feb 2009 10:00:03 -0200 Subject: radio-mr800: fix checking of retval after usb_bulk_msg From: Alexey Klimov Patch corrects checking of returned value after usb_bulk_msg. Now we also check if number of transferred bytes equals to BUFFER_LENGTH. Priority: normal Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/radio/radio-mr800.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-mr800.c b/linux/drivers/media/radio/radio-mr800.c index 60c8c19fc..c04c8887e 100644 --- a/linux/drivers/media/radio/radio-mr800.c +++ b/linux/drivers/media/radio/radio-mr800.c @@ -217,7 +217,7 @@ 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) { + if (retval < 0 || size != BUFFER_LENGTH) { mutex_unlock(&radio->lock); return retval; } @@ -254,7 +254,7 @@ 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) { + if (retval < 0 || size != BUFFER_LENGTH) { mutex_unlock(&radio->lock); return retval; } @@ -271,7 +271,7 @@ 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) { + if (retval < 0 || size != BUFFER_LENGTH) { mutex_unlock(&radio->lock); return retval; } -- cgit v1.2.3 From 8d372d7b7fad4952e30da202fa0be5905382a8fd Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 5 Feb 2009 19:04:33 +0100 Subject: gspca - sonixj: No vertical flip control for mt9v111. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 3be96d9f4..6c5ec09a5 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -235,9 +235,9 @@ static __u32 ctrl_dis[] = { (1 << INFRARED_IDX) | (1 << VFLIP_IDX), /* SENSOR_MO4000 2 */ #if 1 - 0, + (1 << VFLIP_IDX), #else - (1 << AUTOGAIN_IDX), + (1 << AUTOGAIN_IDX) | (1 << VFLIP_IDX), #endif /* SENSOR_MT9V111 3 */ (1 << INFRARED_IDX) | (1 << VFLIP_IDX), -- cgit v1.2.3 From 1aa4c1b8e3ab0204e2985d4a13d81379b5fb7b02 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 5 Feb 2009 19:12:24 +0100 Subject: gspca - sonixj: Add autogain for ov7630/48 and vflip for ov7648. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 43 ++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 8 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 6c5ec09a5..5cdb643b8 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -45,7 +45,7 @@ struct sd { u8 blue; u8 red; u8 gamma; - u8 vflip; /* ov7630 only */ + u8 vflip; /* ov7630/ov7648 only */ u8 infrared; /* mt9v111 only */ s8 ag_cnt; @@ -192,7 +192,7 @@ static struct ctrl sd_ctrls[] = { .set = sd_setautogain, .get = sd_getautogain, }, -/* ov7630 only */ +/* ov7630/ov7648 only */ #define VFLIP_IDX 6 { { @@ -202,7 +202,7 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 1, .step = 1, -#define VFLIP_DEF 1 +#define VFLIP_DEF 0 /* vflip def = 1 for ov7630 */ .default_value = VFLIP_DEF, }, .set = sd_setvflip, @@ -244,7 +244,7 @@ static __u32 ctrl_dis[] = { /* SENSOR_OM6802 4 */ (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX), /* SENSOR_OV7630 5 */ - (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), + (1 << INFRARED_IDX), /* SENSOR_OV7648 6 */ (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), /* SENSOR_OV7660 7 */ @@ -677,7 +677,8 @@ static const u8 ov7648_sensor_init[][8] = { {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, /*...*/ /* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */ -/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */ +/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN + * set by setvflip */ {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10}, /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */ @@ -1319,7 +1320,10 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->gamma = GAMMA_DEF; sd->autogain = AUTOGAIN_DEF; sd->ag_cnt = -1; - sd->vflip = VFLIP_DEF; + if (sd->sensor != SENSOR_OV7630) + sd->vflip = 0; + else + sd->vflip = 1; sd->infrared = INFRARED_DEF; gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; @@ -1589,16 +1593,39 @@ static void setautogain(struct gspca_dev *gspca_dev) if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX)) return; + switch (sd->sensor) { + case SENSOR_OV7630: + case SENSOR_OV7648: { + u8 comb; + + if (sd->sensor == SENSOR_OV7630) + comb = 0xc0; + else + comb = 0xa0; + if (sd->autogain) + comb |= 0x02; + i2c_w1(&sd->gspca_dev, 0x13, comb); + return; + } + } if (sd->autogain) sd->ag_cnt = AG_CNT_START; else sd->ag_cnt = -1; } +/* ov7630/ov7648 only */ static void setvflip(struct sd *sd) { - i2c_w1(&sd->gspca_dev, 0x75, /* COMN */ - sd->vflip ? 0x82 : 0x02); + u8 comn; + + if (sd->sensor == SENSOR_OV7630) + comn = 0x02; + else + comn = 0x06; + if (sd->vflip) + comn |= 0x80; + i2c_w1(&sd->gspca_dev, 0x75, comn); } static void setinfrared(struct sd *sd) -- cgit v1.2.3 From 1bef7beb0e6804e68c391f35f95c364e9c25bb53 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Thu, 5 Feb 2009 20:37:49 -0500 Subject: cx18: Fix VBI ioctl() handling and Raw/Sliced VBI state management From: Andy Walls More sliced VBI fixes to bring the cx18 driver closer to full V4L2 spec compliance for VBI and to get sliced VBI working better. Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-av-vbi.c | 14 ++-- linux/drivers/media/video/cx18/cx18-ioctl.c | 109 +++++++++++++++++++++------ 2 files changed, 94 insertions(+), 29 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-av-vbi.c b/linux/drivers/media/video/cx18/cx18-av-vbi.c index 72325d774..b5763372a 100644 --- a/linux/drivers/media/video/cx18/cx18-av-vbi.c +++ b/linux/drivers/media/video/cx18/cx18-av-vbi.c @@ -25,8 +25,8 @@ #include "cx18-driver.h" /* - * For sliced VBI output, we set up to use VIP-1.1, 10-bit mode, - * NN counts 4 bytes Dwords, an IDID of 0x00 0x80 or one with the VBI line #. + * For sliced VBI output, we set up to use VIP-1.1, 8-bit mode, + * NN counts 1 byte Dwords, an IDID with the VBI line # in it. * Thus, according to the VIP-2 Spec, our VBI ancillary data lines * (should!) look like: * 4 byte EAV code: 0xff 0x00 0x00 0xRP @@ -35,8 +35,8 @@ * 1 byte data identifier: ne010iii (parity bits, 010, DID bits) * 1 byte secondary data id: nessssss (parity bits, SDID bits) * 1 byte data word count: necccccc (parity bits, NN Dword count) - * 2 byte Internal DID: 0x00 0x80 (programmed value) - * 4*NN data bytes + * 2 byte Internal DID: VBI-line-# 0x80 + * NN data bytes * 1 byte checksum * Fill bytes needed to fil out to 4*NN bytes of payload * @@ -65,7 +65,7 @@ struct vbi_anc_data { u8 sdid; u8 data_count; u8 idid[2]; - u8 payload[1]; /* 4*data_count of payload */ + u8 payload[1]; /* data_count of payload */ /* u8 checksum; */ /* u8 fill[]; Variable number of fill bytes */ }; @@ -215,6 +215,7 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg) cx18_av_write(cx, 0x406, 0x13); cx18_av_write(cx, 0x47f, vbi_offset); + /* Force impossible lines to 0 */ if (is_pal) { for (i = 0; i <= 6; i++) svbi->service_lines[0][i] = @@ -229,6 +230,7 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg) svbi->service_lines[1][i] = 0; } + /* Build register values for requested service lines */ for (i = 7; i <= 23; i++) { for (x = 0; x <= 1; x++) { switch (svbi->service_lines[1-x][i]) { @@ -242,7 +244,7 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg) lcr[i] |= 6 << (4 * x); break; case V4L2_SLICED_VPS: - lcr[i] |= 9 << (4 * x); + lcr[i] |= 7 << (4 * x); /*'840 differs*/ break; } } diff --git a/linux/drivers/media/video/cx18/cx18-ioctl.c b/linux/drivers/media/video/cx18/cx18-ioctl.c index 645c41937..c73c0e6b5 100644 --- a/linux/drivers/media/video/cx18/cx18-ioctl.c +++ b/linux/drivers/media/video/cx18/cx18-ioctl.c @@ -42,6 +42,13 @@ #include #include +static int cx18_vbi_streaming(struct cx18 *cx) +{ + struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI]; + return (s_vbi->handle != CX18_INVALID_TASK_HANDLE) && + test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags); +} + u16 cx18_service2vbi(int type) { switch (type) { @@ -58,12 +65,21 @@ u16 cx18_service2vbi(int type) } } +/* Check if VBI services are allowed on the (field, line) for the video std */ static int valid_service_line(int field, int line, int is_pal) { - return (is_pal && line >= 6 && (line != 23 || field == 0)) || + return (is_pal && line >= 6 && + ((field == 0 && line <= 23) || (field == 1 && line <= 22))) || (!is_pal && line >= 10 && line < 22); } +/* + * For a (field, line, std) and inbound potential set of services for that line, + * return the first valid service of those passed in the incoming set for that + * line in priority order: + * CC, VPS, or WSS over TELETEXT for well known lines + * TELETEXT, before VPS, before CC, before WSS, for other lines + */ static u16 select_service_from_set(int field, int line, u16 set, int is_pal) { u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525); @@ -90,6 +106,10 @@ static u16 select_service_from_set(int field, int line, u16 set, int is_pal) return 0; } +/* + * Expand the service_set of *fmt into valid service_lines for the std, + * and clear the passed in fmt->service_set + */ void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) { u16 set = fmt->service_set; @@ -102,6 +122,10 @@ void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) } } +/* + * Sanitize the service_lines in *fmt per the video std, and return 1 + * if any service_line is left as valid after santization + */ static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) { int f, l; @@ -116,6 +140,7 @@ static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) return set != 0; } +/* Compute the service_set from the assumed valid service_lines of *fmt */ u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt) { int f, l; @@ -162,7 +187,7 @@ static int cx18_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi; vbifmt->sampling_rate = 27000000; - vbifmt->offset = 248; + vbifmt->offset = 248; /* FIXME - slightly wrong for both 50 & 60 Hz */ vbifmt->samples_per_line = vbi_active_samples - 4; vbifmt->sample_format = V4L2_PIX_FMT_GREY; vbifmt->start[0] = cx->vbi.start[0]; @@ -180,12 +205,25 @@ static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; + /* sane, V4L2 spec compliant, defaults */ vbifmt->reserved[0] = 0; vbifmt->reserved[1] = 0; vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines)); + vbifmt->service_set = 0; + + /* + * Fetch the configured service_lines and total service_set from the + * digitizer/slicer. Note, cx18_av_vbi() wipes the passed in + * fmt->fmt.sliced under valid calling conditions + */ + if (cx18_av_cmd(cx, VIDIOC_G_FMT, fmt)) + return -EINVAL; - cx18_av_cmd(cx, VIDIOC_G_FMT, fmt); + /* Ensure V4L2 spec compliant output */ + vbifmt->reserved[0] = 0; + vbifmt->reserved[1] = 0; + vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; vbifmt->service_set = cx18_get_service_set(vbifmt); return 0; } @@ -224,10 +262,12 @@ static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh, vbifmt->reserved[0] = 0; vbifmt->reserved[1] = 0; + /* If given a service set, expand it validly & clear passed in set */ if (vbifmt->service_set) cx18_expand_service_set(vbifmt, cx->is_50hz); - check_service_set(vbifmt, cx->is_50hz); - vbifmt->service_set = cx18_get_service_set(vbifmt); + /* Sanitize the service_lines, and compute the new set if any valid */ + if (check_service_set(vbifmt, cx->is_50hz)) + vbifmt->service_set = cx18_get_service_set(vbifmt); return 0; } @@ -272,12 +312,22 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh, if (ret) return ret; - if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0) + if (!cx18_raw_vbi(cx) && cx18_vbi_streaming(cx)) return -EBUSY; + /* + * Set the digitizer registers for raw active VBI. + * Note cx18_av_vbi_wipes out alot of the passed in fmt under valid + * calling conditions + */ + ret = cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); + if (ret) + return ret; + + /* Store our new v4l2 (non-)sliced VBI state */ cx->vbi.sliced_in->service_set = 0; cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; - cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); + return cx18_g_fmt_vbi_cap(file, fh, fmt); } @@ -293,17 +343,20 @@ static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh, if (ret) return ret; - ret = cx18_try_fmt_sliced_vbi_cap(file, fh, fmt); - if (ret) - return ret; - - if (check_service_set(vbifmt, cx->is_50hz) == 0) - return -EINVAL; + cx18_try_fmt_sliced_vbi_cap(file, fh, fmt); - if (cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0) + if (cx18_raw_vbi(cx) && cx18_vbi_streaming(cx)) return -EBUSY; + /* + * Set the service_lines requested in the digitizer/slicer registers. + * Note, cx18_av_vbi() wipes some "impossible" service lines in the + * passed in fmt->fmt.sliced under valid calling conditions + */ + ret = cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); + if (ret) + return ret; + /* Store our current v4l2 sliced VBI settings */ cx->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; - cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in)); return 0; } @@ -657,16 +710,26 @@ static int cx18_g_sliced_vbi_cap(struct file *file, void *fh, int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; int f, l; - if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { - for (f = 0; f < 2; f++) { - for (l = 0; l < 24; l++) { - if (valid_service_line(f, l, cx->is_50hz)) - cap->service_lines[f][l] = set; - } + if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) + return -EINVAL; + + cap->service_set = 0; + for (f = 0; f < 2; f++) { + for (l = 0; l < 24; l++) { + if (valid_service_line(f, l, cx->is_50hz)) { + /* + * We can find all v4l2 supported vbi services + * for the standard, on a valid line for the std + */ + cap->service_lines[f][l] = set; + cap->service_set |= set; + } else + cap->service_lines[f][l] = 0; } - return 0; } - return -EINVAL; + for (f = 0; f < 3; f++) + cap->reserved[f] = 0; + return 0; } static int cx18_g_enc_index(struct file *file, void *fh, -- cgit v1.2.3 From c25f9358cc7b4f70622195b02aa6b33fb522bce8 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Thu, 5 Feb 2009 23:52:29 -0200 Subject: radio-si470x: use usb_make_path in usb-radio drivers From: Alexey Klimov Place usb_make_path in radio-si470x.c that used when reporting bus_info information in vidioc_querycap. Priority: normal Acked-by: Tobias Lorenz Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/radio/radio-si470x.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index f3cdf3af4..f77a65d2a 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -1202,9 +1202,11 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = { static int si470x_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *capability) { + struct si470x_device *radio = video_drvdata(file); + strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver)); strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); - sprintf(capability->bus_info, "USB"); + usb_make_path(radio->usbdev, capability->bus_info, sizeof(capability->bus_info)); capability->version = DRIVER_KERNEL_VERSION; capability->capabilities = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_TUNER | V4L2_CAP_RADIO; -- cgit v1.2.3 From 891ac17d7e12b75ddf21bea407b502569f94bb3e Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 6 Feb 2009 17:45:23 +0100 Subject: gspca - t613: Bad sensor name in kernel trace when 'other' sensor. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/t613.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/t613.c b/linux/drivers/media/video/gspca/t613.c index adec0767c..1b0fc86c4 100644 --- a/linux/drivers/media/video/gspca/t613.c +++ b/linux/drivers/media/video/gspca/t613.c @@ -685,7 +685,7 @@ static int sd_init(struct gspca_dev *gspca_dev) sd->sensor = SENSOR_TAS5130A; break; case 0x0803: - PDEBUG(D_CONF, "sensor om6802"); + PDEBUG(D_CONF, "sensor 'other'"); sd->sensor = SENSOR_OTHER; break; case 0x0807: -- cgit v1.2.3 From a50f33bc015e6def039a24ead62b4e32d76d44e6 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 6 Feb 2009 18:11:58 +0100 Subject: gspca - t613: Bad debug level when displaying the sensor type. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/t613.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/t613.c b/linux/drivers/media/video/gspca/t613.c index 1b0fc86c4..4891592ea 100644 --- a/linux/drivers/media/video/gspca/t613.c +++ b/linux/drivers/media/video/gspca/t613.c @@ -681,19 +681,19 @@ static int sd_init(struct gspca_dev *gspca_dev) | reg_r(gspca_dev, 0x07); switch (sensor_id) { case 0x0801: - PDEBUG(D_CONF, "sensor tas5130a"); + PDEBUG(D_PROBE, "sensor tas5130a"); sd->sensor = SENSOR_TAS5130A; break; case 0x0803: - PDEBUG(D_CONF, "sensor 'other'"); + PDEBUG(D_PROBE, "sensor 'other'"); sd->sensor = SENSOR_OTHER; break; case 0x0807: - PDEBUG(D_CONF, "sensor om6802"); + PDEBUG(D_PROBE, "sensor om6802"); sd->sensor = SENSOR_OM6802; break; default: - PDEBUG(D_CONF, "unknown sensor %04x", sensor_id); + PDEBUG(D_ERR|D_PROBE, "unknown sensor %04x", sensor_id); return -EINVAL; } -- cgit v1.2.3 From 9e943ca0c659d66896f55dcfa1280f1d22556e78 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 6 Feb 2009 19:12:46 +0100 Subject: gspca - sq905: New subdriver. From: Adam Baker Add initial support for cameras based on the SQ Technologies SQ-905 chipset (USB ID 2770:9120) to V4L2 using the gspca infrastructure. Currently only supports one resolution and doesn't attempt to inform libv4l what image flipping options are needed. Priority: normal Signed-off-by: Adam Baker Signed-off-by: Theodore Kilgore Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/Kconfig | 9 + linux/drivers/media/video/gspca/Makefile | 2 + linux/drivers/media/video/gspca/sq905.c | 438 +++++++++++++++++++++++++++++++ 3 files changed, 449 insertions(+) create mode 100644 linux/drivers/media/video/gspca/sq905.c (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/Kconfig b/linux/drivers/media/video/gspca/Kconfig index 11c5d2fc2..a0f05ef5c 100644 --- a/linux/drivers/media/video/gspca/Kconfig +++ b/linux/drivers/media/video/gspca/Kconfig @@ -176,6 +176,15 @@ config USB_GSPCA_SPCA561 To compile this driver as a module, choose M here: the module will be called gspca_spca561. +config USB_GSPCA_SQ905 + tristate "SQ Technologies SQ905 based USB Camera Driver" + depends on VIDEO_V4L2 && USB_GSPCA + help + Say Y here if you want support for cameras based on the SQ905 chip. + + To compile this driver as a module, choose M here: the + module will be called gspca_sq905. + config USB_GSPCA_STK014 tristate "Syntek DV4000 (STK014) USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA diff --git a/linux/drivers/media/video/gspca/Makefile b/linux/drivers/media/video/gspca/Makefile index b3cbcc176..b6ec61185 100644 --- a/linux/drivers/media/video/gspca/Makefile +++ b/linux/drivers/media/video/gspca/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o +obj-$(CONFIG_USB_GSPCA_SQ905) += gspca_sq905.o obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o @@ -41,6 +42,7 @@ gspca_spca505-objs := spca505.o gspca_spca506-objs := spca506.o gspca_spca508-objs := spca508.o gspca_spca561-objs := spca561.o +gspca_sq905-objs := sq905.o gspca_stk014-objs := stk014.o gspca_sunplus-objs := sunplus.o gspca_t613-objs := t613.o diff --git a/linux/drivers/media/video/gspca/sq905.c b/linux/drivers/media/video/gspca/sq905.c new file mode 100644 index 000000000..dafaed69e --- /dev/null +++ b/linux/drivers/media/video/gspca/sq905.c @@ -0,0 +1,438 @@ +/* + * SQ905 subdriver + * + * Copyright (C) 2008, 2009 Adam Baker and Theodore Kilgore + * + * 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 + */ + +/* + * History and Acknowledgments + * + * The original Linux driver for SQ905 based cameras was written by + * Marcell Lengyel and furter developed by many other contributers + * and is available from http://sourceforge.net/projects/sqcam/ + * + * This driver takes advantage of the reverse engineering work done for + * that driver and for libgphoto2 but shares no code with them. + * + * This driver has used as a base the finepix driver and other gspca + * based drivers and may still contain code fragments taken from those + * drivers. + */ + +#define MODULE_NAME "sq905" + +#include +#include "gspca.h" + +MODULE_AUTHOR("Adam Baker , " + "Theodore Kilgore "); +MODULE_DESCRIPTION("GSPCA/SQ905 USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* Default timeouts, in ms */ +#define SQ905_CMD_TIMEOUT 500 +#define SQ905_DATA_TIMEOUT 1000 + +/* Maximum transfer size to use. */ +#define SQ905_MAX_TRANSFER 0x8000 +#define FRAME_HEADER_LEN 64 + +/* The known modes, or registers. These go in the "value" slot. */ + +/* 00 is "none" obviously */ + +#define SQ905_BULK_READ 0x03 /* precedes any bulk read */ +#define SQ905_COMMAND 0x06 /* precedes the command codes below */ +#define SQ905_PING 0x07 /* when reading an "idling" command */ +#define SQ905_READ_DONE 0xc0 /* ack bulk read completed */ + +/* Some command codes. These go in the "index" slot. */ + +#define SQ905_ID 0xf0 /* asks for model string */ +#define SQ905_CONFIG 0x20 /* gets photo alloc. table, not used here */ +#define SQ905_DATA 0x30 /* accesses photo data, not used here */ +#define SQ905_CLEAR 0xa0 /* clear everything */ +#define SQ905_CAPTURE_LOW 0x60 /* Starts capture at 160x120 */ +#define SQ905_CAPTURE_MED 0x61 /* Starts capture at 320x240 */ +/* note that the capture command also controls the output dimensions */ +/* 0x60 -> 160x120, 0x61 -> 320x240 0x62 -> 640x480 depends on camera */ +/* 0x62 is not correct, at least for some cams. Should be 0x63 ? */ + +/* Structure to hold all of our device specific stuff */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + u8 cam_type; + + /* + * Driver stuff + */ + struct work_struct work_struct; + struct workqueue_struct *work_thread; +}; + +/* The driver only supports 320x240 so far. */ +static struct v4l2_pix_format sq905_mode[1] = { + { 320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0} +}; + +struct cam_type { + u32 ident_word; + char *name; + struct v4l2_pix_format *min_mode; + u8 num_modes; + u8 sensor_flags; +}; + +#define SQ905_FLIP_HORIZ (1 << 0) +#define SQ905_FLIP_VERT (1 << 1) + +/* Last entry is default if nothing else matches */ +static struct cam_type cam_types[] = { + { 0x19010509, "PocketCam", &sq905_mode[0], 1, SQ905_FLIP_HORIZ }, + { 0x32010509, "Magpix", &sq905_mode[0], 1, SQ905_FLIP_HORIZ }, + { 0, "Default", &sq905_mode[0], 1, SQ905_FLIP_HORIZ | SQ905_FLIP_VERT } +}; + +/* + * Send a command to the camera. + */ +static int sq905_command(struct gspca_dev *gspca_dev, u16 index) +{ + int ret; + + gspca_dev->usb_buf[0] = '\0'; + 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_COMMAND, index, gspca_dev->usb_buf, 1, + SQ905_CMD_TIMEOUT); + if (ret < 0) { + PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", + __func__, ret); + return ret; + } + + ret = usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), + USB_REQ_SYNCH_FRAME, /* request */ + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + SQ905_PING, 0, gspca_dev->usb_buf, 1, + SQ905_CMD_TIMEOUT); + if (ret < 0) { + PDEBUG(D_ERR, "%s: usb_control_msg failed 2 (%d)", + __func__, ret); + return ret; + } + + return 0; +} + +/* + * Acknowledge the end of a frame - see warning on sq905_command. + */ +static int sq905_ack_frame(struct gspca_dev *gspca_dev) +{ + int ret; + + gspca_dev->usb_buf[0] = '\0'; + 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_READ_DONE, 0, gspca_dev->usb_buf, 1, + SQ905_CMD_TIMEOUT); + if (ret < 0) { + PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret); + return ret; + } + + return 0; +} + +/* + * 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) +{ + int ret; + int act_len; + + gspca_dev->usb_buf[0] = '\0'; + 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 (ret < 0) { + PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret); + return ret; + } + ret = usb_bulk_msg(gspca_dev->dev, + usb_rcvbulkpipe(gspca_dev->dev, 0x81), + data, size, &act_len, SQ905_DATA_TIMEOUT); + + /* successful, it returns 0, otherwise negative */ + if (ret < 0 || act_len != size) { + PDEBUG(D_ERR, "bulk read fail (%d) len %d/%d", + ret, act_len, size); + return -EIO; + } + return 0; +} + +/* This function is called as a workqueue function and runs whenever the camera + * is streaming data. Because it is a workqueue function it is allowed to sleep + * so we can use synchronous USB calls. To avoid possible collisions with other + * threads attempting to use the camera's USB interface we take the gspca + * usb_lock when performing USB operations. In practice the only thing we need + * to protect against is the usb_set_interface call that gspca makes during + * stream_off as the camera doesn't provide any controls that the user could try + * to change. + */ +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. */ + int discarding; /* true if we failed to get space for frame. */ + int packet_type; + int ret; + u8 *data; + 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; + } + + 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 = sq905_mode[0].sizeimage + FRAME_HEADER_LEN; + header_read = 0; + discarding = 0; + + while (bytes_left > 0) { + 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); + if (ret < 0) + goto quit_stream; + mutex_unlock(&gspca_dev->usb_lock); + PDEBUG(D_STREAM, + "Got %d bytes out of %d for frame", + data_len, bytes_left); + bytes_left -= data_len; + data = buffer; + if (!header_read) { + packet_type = FIRST_PACKET; + /* The first 64 bytes of each frame are + * a header full of FF 00 bytes */ + data += FRAME_HEADER_LEN; + data_len -= FRAME_HEADER_LEN; + header_read = 1; + } else if (bytes_left == 0) { + packet_type = LAST_PACKET; + } else { + packet_type = INTER_PACKET; + } + frame = gspca_get_i_frame(gspca_dev); + if (frame && !discarding) + gspca_frame_add(gspca_dev, packet_type, + frame, data, data_len); + 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; + } +quit_stream: + /* the usb_lock is already acquired */ + if (gspca_dev->present) + sq905_command(gspca_dev, SQ905_CLEAR); + mutex_unlock(&gspca_dev->usb_lock); + kfree(buffer); +} + +/* This function is called at probe time just before sd_init */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct cam *cam = &gspca_dev->cam; + struct sd *dev = (struct sd *) gspca_dev; + + cam->cam_mode = sq905_mode; + cam->nmodes = 1; + /* We don't use the buffer gspca allocates so make it small. */ + cam->bulk_size = 64; + + INIT_WORK(&dev->work_struct, sq905_dostream); + + return 0; +} + +/* called on streamoff with alt==0 and on disconnect */ +/* the usb_lock is held at entry - restore on exit */ +static void sd_stop0(struct gspca_dev *gspca_dev) +{ + struct sd *dev = (struct sd *) gspca_dev; + + /* wait for the work queue to terminate */ + mutex_unlock(&gspca_dev->usb_lock); + /* This waits for sq905_dostream to finish */ + destroy_workqueue(dev->work_thread); + dev->work_thread = NULL; + mutex_lock(&gspca_dev->usb_lock); +} + +/* this function is called at probe and resume time */ +static int sd_init(struct gspca_dev *gspca_dev) +{ + struct sd *dev = (struct sd *) gspca_dev; + u32 ident; + int ret; + + /* connect to the camera and read + * the model ID and process that and put it away. + */ + ret = sq905_command(gspca_dev, SQ905_CLEAR); + if (ret < 0) + return ret; + ret = sq905_command(gspca_dev, SQ905_ID); + if (ret < 0) + return ret; + ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4); + if (ret < 0) + return ret; + /* usb_buf is allocated with kmalloc so is aligned. */ + ident = le32_to_cpup((u32 *)gspca_dev->usb_buf); + ret = sq905_command(gspca_dev, SQ905_CLEAR); + if (ret < 0) + return ret; + dev->cam_type = 0; + while (dev->cam_type < ARRAY_SIZE(cam_types) - 1 && + ident != cam_types[dev->cam_type].ident_word) + dev->cam_type++; + PDEBUG(D_CONF, "SQ905 camera %s, ID %08x detected", + cam_types[dev->cam_type].name, ident); + return 0; +} + +/* Set up for getting frames. */ +static int sd_start(struct gspca_dev *gspca_dev) +{ + struct sd *dev = (struct sd *) gspca_dev; + int ret; + + /* "Open the shutter" and set size, to start capture */ + ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_MED); + if (ret < 0) { + PDEBUG(D_ERR, "Start streaming command failed"); + return ret; + } + + /* Start the workqueue function to do the streaming */ + dev->work_thread = create_singlethread_workqueue(MODULE_NAME); + queue_work(dev->work_thread, &dev->work_struct); + + return 0; +} + +/* Table of supported USB devices */ +static const __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x2770, 0x9120)}, + {} +}; + +MODULE_DEVICE_TABLE(usb, device_table); + +/* sub-driver description */ +static const struct sd_desc sd_desc = { + .name = MODULE_NAME, + .config = sd_config, + .init = sd_init, + .start = sd_start, + .stop0 = sd_stop0, +}; + +/* -- 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); -- cgit v1.2.3 From 66588fb3c835b7f534deb67c863970dcfbccea30 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 6 Feb 2009 16:33:43 -0500 Subject: cx18: Fixes for enforcing when Encoder Raw VBI params can be set From: Andy Walls The Encoder will only allow the Raw VBI parameters, along with a number of other API parameters, to take effect when no analog captures are in progress. These parameters must be set before the first analog capture starts, be it MPEG, VBI, YUV, etc., and cannot be changed until the last one stops. It is not obvious to me what capture channel API parameters are shared and which ones must be set per capture channel, so set them all for every analog capture channel start up. This fixes the driver so that VBI capture can be started up after the MPEG capture is going. Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-ioctl.c | 20 ++++--- linux/drivers/media/video/cx18/cx18-streams.c | 79 ++++++++++++++++++++------- 2 files changed, 71 insertions(+), 28 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-ioctl.c b/linux/drivers/media/video/cx18/cx18-ioctl.c index c73c0e6b5..c023c79cf 100644 --- a/linux/drivers/media/video/cx18/cx18-ioctl.c +++ b/linux/drivers/media/video/cx18/cx18-ioctl.c @@ -42,13 +42,6 @@ #include #include -static int cx18_vbi_streaming(struct cx18 *cx) -{ - struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI]; - return (s_vbi->handle != CX18_INVALID_TASK_HANDLE) && - test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags); -} - u16 cx18_service2vbi(int type) { switch (type) { @@ -312,7 +305,11 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh, if (ret) return ret; - if (!cx18_raw_vbi(cx) && cx18_vbi_streaming(cx)) + /* + * Changing the Encoder's Raw VBI parameters won't have any effect + * if any analog capture is ongoing + */ + if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0) return -EBUSY; /* @@ -345,8 +342,13 @@ static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh, cx18_try_fmt_sliced_vbi_cap(file, fh, fmt); - if (cx18_raw_vbi(cx) && cx18_vbi_streaming(cx)) + /* + * Changing the Encoder's Raw VBI parameters won't have any effect + * if any analog capture is ongoing + */ + if (cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0) return -EBUSY; + /* * Set the service_lines requested in the digitizer/slicer registers. * Note, cx18_av_vbi() wipes some "impossible" service lines in the diff --git a/linux/drivers/media/video/cx18/cx18-streams.c b/linux/drivers/media/video/cx18/cx18-streams.c index bcd786988..f2b6a1410 100644 --- a/linux/drivers/media/video/cx18/cx18-streams.c +++ b/linux/drivers/media/video/cx18/cx18-streams.c @@ -349,6 +349,14 @@ static void cx18_vbi_setup(struct cx18_stream *s) /* setup VBI registers */ cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in); + /* + * Send the CX18_CPU_SET_RAW_VBI_PARAM API command to setup Encoder Raw + * VBI when the first analog capture channel starts, as once it starts + * (e.g. MPEG), we can't effect any change in the Encoder Raw VBI setup + * (i.e. for the VBI capture channels). We also send it for each + * analog capture channel anyway just to make sure we get the proper + * behavior + */ if (raw) { lines = cx->vbi.count * 2; } else { @@ -410,8 +418,7 @@ static void cx18_vbi_setup(struct cx18_stream *s) CX18_DEBUG_INFO("Setup VBI h: %d lines %x bpl %d fr %d %x %x\n", data[0], data[1], data[2], data[3], data[4], data[5]); - if (s->type == CX18_ENC_STREAM_TYPE_VBI) - cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data); + cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data); } struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s, @@ -460,8 +467,8 @@ 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 ts = 0; int captype = 0; + struct cx18_api_func_private priv; if (s->video_dev == NULL && s->dvb.enabled == 0) return -EINVAL; @@ -479,7 +486,6 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) case CX18_ENC_STREAM_TYPE_TS: captype = CAPTURE_CHANNEL_TYPE_TS; - ts = 1; break; case CX18_ENC_STREAM_TYPE_YUV: captype = CAPTURE_CHANNEL_TYPE_YUV; @@ -488,8 +494,16 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) captype = CAPTURE_CHANNEL_TYPE_PCM; break; case CX18_ENC_STREAM_TYPE_VBI: +#ifdef CX18_ENCODER_PARSES_SLICED captype = cx18_raw_vbi(cx) ? CAPTURE_CHANNEL_TYPE_VBI : CAPTURE_CHANNEL_TYPE_SLICED_VBI; +#else + /* + * Currently we set things up so that Sliced VBI from the + * digitizer is handled as Raw VBI by the encoder + */ + captype = CAPTURE_CHANNEL_TYPE_VBI; +#endif cx->vbi.frame = 0; cx->vbi.inserted_frame = 0; memset(cx->vbi.sliced_mpeg_size, @@ -499,10 +513,6 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) return -EINVAL; } - /* mute/unmute video */ - cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, - s->handle, !!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)); - /* Clear Streamoff flags in case left from last capture */ clear_bit(CX18_F_S_STREAMOFF, &s->s_flags); @@ -510,31 +520,62 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) s->handle = data[0]; cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype); - if (atomic_read(&cx->ana_capturing) == 0 && !ts) { - struct cx18_api_func_private priv; - - /* Stuff from Windows, we don't know what it is */ + /* + * For everything but CAPTURE_CHANNEL_TYPE_TS, play it safe and + * set up all the parameters, as it is not obvious which parameters the + * firmware shares across capture channel types and which it does not. + * + * Some of the cx18_vapi() calls below apply to only certain capture + * channel types. We're hoping there's no harm in calling most of them + * anyway, as long as the values are all consistent. Setting some + * shared parameters will have no effect once an analog capture channel + * has started streaming. + */ + if (captype != CAPTURE_CHANNEL_TYPE_TS) { cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0); cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1); cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 8, 0); cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 4, 1); - cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, s->handle, 12); + /* + * Audio related reset according to + * Documentation/video4linux/cx2341x/fw-encoder-api.txt + */ + if (atomic_read(&cx->ana_capturing) == 0) + cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, + s->handle, 12); + + /* + * Number of lines for Field 1 & Field 2 according to + * Documentation/video4linux/cx2341x/fw-encoder-api.txt + * FIXME - currently we set this to 0 & 0 but things seem OK + */ cx18_vapi(cx, CX18_CPU_SET_CAPTURE_LINE_NO, 3, - s->handle, cx->digitizer, cx->digitizer); + s->handle, cx->digitizer, cx->digitizer); - /* Setup VBI */ if (cx->v4l2_cap & V4L2_CAP_VBI_CAPTURE) cx18_vbi_setup(s); - /* assign program index info. - Mask 7: select I/P/B, Num_req: 400 max */ + /* + * assign program index info. + * Mask 7: select I/P/B, Num_req: 400 max + * FIXME - currently we have this hardcoded as disabled + */ cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0); - /* Setup API for Stream */ + /* Call out to the common CX2341x API setup for user controls */ priv.cx = cx; priv.s = s; cx2341x_update(&priv, cx18_api_func, NULL, &cx->params); + + /* + * When starting a capture and we're set for radio, + * ensure the video is muted, despite the user control. + */ + if (!cx->params.video_mute && + test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) + cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle, + (cx->params.video_mute_yuv << 8) | 1); } if (atomic_read(&cx->tot_capturing) == 0) { @@ -578,7 +619,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) } /* you're live! sit back and await interrupts :) */ - if (!ts) + if (captype != CAPTURE_CHANNEL_TYPE_TS) atomic_inc(&cx->ana_capturing); atomic_inc(&cx->tot_capturing); return 0; -- cgit v1.2.3 From 7784b73d36b6f96ba397937b9246610fea511e09 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 6 Feb 2009 23:15:44 -0500 Subject: cx18: Use correct line counts per field in firmware API call From: Andy Walls The driver was incorrectly setting 0 line counts in a firmware API call to set the maximum amount of lines per field. Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-driver.h | 3 --- linux/drivers/media/video/cx18/cx18-streams.c | 5 +++-- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-driver.h b/linux/drivers/media/video/cx18/cx18-driver.h index 0ef099186..20189283a 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.h +++ b/linux/drivers/media/video/cx18/cx18-driver.h @@ -479,9 +479,6 @@ struct cx18 { unsigned long dualwatch_jiffies; u32 dualwatch_stereo_mode; - /* Digitizer type */ - int digitizer; /* 0x00EF = saa7114 0x00FO = saa7115 0x0106 = mic */ - struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */ struct cx18_options options; /* User options */ int stream_buffers[CX18_MAX_STREAMS]; /* # of buffers for each stream */ diff --git a/linux/drivers/media/video/cx18/cx18-streams.c b/linux/drivers/media/video/cx18/cx18-streams.c index f2b6a1410..cec4794bf 100644 --- a/linux/drivers/media/video/cx18/cx18-streams.c +++ b/linux/drivers/media/video/cx18/cx18-streams.c @@ -548,10 +548,11 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) /* * Number of lines for Field 1 & Field 2 according to * Documentation/video4linux/cx2341x/fw-encoder-api.txt - * FIXME - currently we set this to 0 & 0 but things seem OK + * Field 1 is 312 for 625 line systems in BT.656 + * Field 2 is 313 for 625 line systems in BT.656 */ cx18_vapi(cx, CX18_CPU_SET_CAPTURE_LINE_NO, 3, - s->handle, cx->digitizer, cx->digitizer); + s->handle, 312, 313); if (cx->v4l2_cap & V4L2_CAP_VBI_CAPTURE) cx18_vbi_setup(s); -- cgit v1.2.3 From 044e05207bc29e80220289d29bcae6780ec904ac Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 6 Feb 2009 23:31:22 -0500 Subject: cx18: Fix sliced VBI PTS and fix artifacts in last raw line of field From: Andy Walls Fixed an endianess problem with the collection of the PTS from the VBI buffer given to us by the encoder. Also extrapolated the last 12 bytes of the last line of each field, to remove artifacts created by removing the first 12 bytes of each field for raw VBI. Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-vbi.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-vbi.c b/linux/drivers/media/video/cx18/cx18-vbi.c index d6e15e119..d8e7d371c 100644 --- a/linux/drivers/media/video/cx18/cx18-vbi.c +++ b/linux/drivers/media/video/cx18/cx18-vbi.c @@ -179,6 +179,10 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, if (streamtype != CX18_ENC_STREAM_TYPE_VBI) return; + /* + * The CX23418 sends us data that is 32 bit LE swapped, but we want + * the raw VBI bytes in the order they were in the raster line + */ cx18_buf_swap(buf); /* @@ -190,17 +194,27 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, if (cx18_raw_vbi(cx)) { u8 type; - /* Skip 12 bytes of header that gets stuffed in */ + /* + * We've set up to get a field's worth of VBI data at a time. + * Skip 12 bytes of header prefixing the first field or the + * last 12 bytes in the last VBI line from the first field that + * prefixes the second field. + */ size -= 12; memcpy(p, &buf->buf[12], size); type = p[3]; + /* Extrapolate the last 12 bytes of the field's last line */ + memset(&p[size], (int) p[size - 1], 12); + size = buf->bytesused = compress_raw_buf(cx, p, size); - /* second field of the frame? */ if (type == raw_vbi_sav_rp[1]) { - /* Dirty hack needed for backwards - compatibility of old VBI software. */ + /* + * Hack needed for compatibility with old VBI software. + * Write the frame # at the end of the last line of the + * second field + */ p += size - 4; memcpy(p, &cx->vbi.frame, 4); cx->vbi.frame++; @@ -210,7 +224,7 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, /* Sliced VBI data with data insertion */ - pts = (q[0] == 0x3fffffff) ? q[2] : 0; + pts = (be32_to_cpu(q[0] == 0x3fffffff)) ? be32_to_cpu(q[2]) : 0; /* first field */ /* compress_sliced_buf() will skip the 12 bytes of header */ -- cgit v1.2.3 From 40b47e5cc5ca4d00352b85e68426a50b7edae2aa Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 7 Feb 2009 13:47:28 -0500 Subject: cx18: Process Raw VBI on a whole frame basis; fix VBI buffer size From: Andy Walls The cx23418 appears to send Raw VBI buffers with a PTS on a per frame basis, not per field, so process Raw VBI on a whole frame basis and reduce some complexity. Fix VBI buffer size computation to handle a whole frame of Raw VBI for a 625 line system, which is the worst case and will work for 525 lines systems as well. Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-driver.c | 54 +++++++++++----------------- linux/drivers/media/video/cx18/cx18-vbi.c | 31 +++++++--------- 2 files changed, 33 insertions(+), 52 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-driver.c b/linux/drivers/media/video/cx18/cx18-driver.c index f3a50f673..7a256a4fd 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.c +++ b/linux/drivers/media/video/cx18/cx18-driver.c @@ -448,34 +448,38 @@ static void cx18_process_options(struct cx18 *cx) cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufsize; cx->stream_buf_size[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufsize; cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufsize; - cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = 0; /* computed later */ + cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_active_samples * 36; cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufsize; cx->stream_buf_size[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control no data */ - /* Except for VBI ensure stream_buffers & stream_buf_size are valid */ + /* Ensure stream_buffers & stream_buf_size are valid */ for (i = 0; i < CX18_MAX_STREAMS; i++) { - /* User said to use 0 buffers */ - if (cx->stream_buffers[i] == 0) { - cx->options.megabytes[i] = 0; - cx->stream_buf_size[i] = 0; - continue; - } - /* User said to use 0 MB total */ - if (cx->options.megabytes[i] <= 0) { + if (cx->stream_buffers[i] == 0 || /* User said 0 buffers */ + cx->options.megabytes[i] <= 0 || /* User said 0 MB total */ + cx->stream_buf_size[i] <= 0) { /* User said buf size 0 */ cx->options.megabytes[i] = 0; cx->stream_buffers[i] = 0; cx->stream_buf_size[i] = 0; continue; } - /* VBI is computed later or user said buffer has size 0 */ - if (cx->stream_buf_size[i] <= 0) { - if (i != CX18_ENC_STREAM_TYPE_VBI) { - cx->options.megabytes[i] = 0; - cx->stream_buffers[i] = 0; - cx->stream_buf_size[i] = 0; + /* + * VBI is a special case where the stream_buf_size is fixed + * and already in bytes + */ + if (i == CX18_ENC_STREAM_TYPE_VBI) { + if (cx->stream_buffers[i] < 0) { + cx->stream_buffers[i] = + cx->options.megabytes[i] * 1024 * 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 * 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]; @@ -739,7 +743,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, { int retval = 0; int i; - int vbi_buf_size; u32 devtype; struct cx18 *cx; @@ -895,23 +898,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, } cx->params.video_gop_size = cx->is_60hz ? 15 : 12; - /* - * FIXME: setting the buffer size based on the tuner standard is - * suboptimal, as the CVBS and SVideo inputs could use a different std - * and the buffer could end up being too small in that case. - */ - vbi_buf_size = vbi_active_samples * (cx->is_60hz ? 24 : 36) / 2; - cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size; - - if (cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] < 0) - cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] = - cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] * 1024 * 1024 - / vbi_buf_size; - else - cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] = - cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] * vbi_buf_size - / (1024 * 1024); - if (cx->options.radio > 0) cx->v4l2_cap |= V4L2_CAP_RADIO; diff --git a/linux/drivers/media/video/cx18/cx18-vbi.c b/linux/drivers/media/video/cx18/cx18-vbi.c index d8e7d371c..52082d4a1 100644 --- a/linux/drivers/media/video/cx18/cx18-vbi.c +++ b/linux/drivers/media/video/cx18/cx18-vbi.c @@ -103,12 +103,11 @@ 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 field. - Returns new compressed size. */ + after the frame. Returns new compressed size. */ static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size) { u32 line_size = vbi_active_samples; - u32 lines = cx->vbi.count; + u32 lines = cx->vbi.count * 2; u8 sav1 = raw_vbi_sav_rp[0]; u8 sav2 = raw_vbi_sav_rp[1]; u8 *q = buf; @@ -195,30 +194,26 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, u8 type; /* - * We've set up to get a field's worth of VBI data at a time. - * Skip 12 bytes of header prefixing the first field or the - * last 12 bytes in the last VBI line from the first field that - * prefixes the second field. + * We've set up to get a frame's worth of VBI data at a time. + * Skip 12 bytes of header prefixing the first field. */ size -= 12; memcpy(p, &buf->buf[12], size); type = p[3]; - /* Extrapolate the last 12 bytes of the field's last line */ + /* Extrapolate the last 12 bytes of the frame's last line */ memset(&p[size], (int) p[size - 1], 12); + size += 12; size = buf->bytesused = compress_raw_buf(cx, p, size); - if (type == raw_vbi_sav_rp[1]) { - /* - * Hack needed for compatibility with old VBI software. - * Write the frame # at the end of the last line of the - * second field - */ - p += size - 4; - memcpy(p, &cx->vbi.frame, 4); - cx->vbi.frame++; - } + /* + * Hack needed for compatibility with old VBI software. + * Write the frame # at the last 4 bytes of the frame + */ + p += size - 4; + memcpy(p, &cx->vbi.frame, 4); + cx->vbi.frame++; return; } -- cgit v1.2.3 From 41579b5b51a952f7bfaf05f5147f83148a7a3a68 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 8 Feb 2009 03:00:14 -0200 Subject: dsbr100: Add few lost mutex locks. From: Alexey Klimov Patch adds two lost mutex locks. Priority: normal Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/radio/dsbr100.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/radio/dsbr100.c b/linux/drivers/media/radio/dsbr100.c index 0516711f8..155a75341 100644 --- a/linux/drivers/media/radio/dsbr100.c +++ b/linux/drivers/media/radio/dsbr100.c @@ -455,7 +455,10 @@ static int vidioc_s_frequency(struct file *file, void *priv, if (radio->removed) return -EIO; + mutex_lock(&radio->lock); radio->curfreq = f->frequency; + mutex_unlock(&radio->lock); + retval = dsbr100_setfreq(radio, radio->curfreq); if (retval < 0) dev_warn(&radio->usbdev->dev, "Set frequency failed\n"); @@ -606,7 +609,10 @@ static int usb_dsbr100_close(struct file *file) if (!radio) return -ENODEV; + mutex_lock(&radio->lock); radio->users = 0; + mutex_unlock(&radio->lock); + if (!radio->removed) { retval = dsbr100_stop(radio); if (retval < 0) { -- cgit v1.2.3 From f9263f9b94e9a6f28065616efc07eb78d000a662 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 8 Feb 2009 20:40:04 -0500 Subject: cx18: Finally get sliced VBI working - for 525 line 60 Hz systems at least From: Andy Walls Sliced VBI, in the manner that ivtv implements it as a separate data stream, now works for 525 line 60 Hz systems like NTSC-M. It may work for 625 line 50 Hz systems, but I have more engineering work to do, to verify it is operating properly. Sliced data insertion into the MPEG PS should be working, but is untested. Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-av-core.c | 44 ++++++++++++++++++++------- linux/drivers/media/video/cx18/cx18-av-core.h | 19 +++++++++++- linux/drivers/media/video/cx18/cx18-av-vbi.c | 10 +++--- linux/drivers/media/video/cx18/cx18-driver.c | 4 ++- linux/drivers/media/video/cx18/cx18-streams.c | 19 +++++++++--- linux/drivers/media/video/cx18/cx18-vbi.c | 19 +++++++++--- 6 files changed, 88 insertions(+), 27 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-av-core.c b/linux/drivers/media/video/cx18/cx18-av-core.c index 5279b8e45..343ddfd1b 100644 --- a/linux/drivers/media/video/cx18/cx18-av-core.c +++ b/linux/drivers/media/video/cx18/cx18-av-core.c @@ -172,11 +172,11 @@ static void cx18_av_initialize(struct cx18 *cx) /* * Initial VBI setup * VIP-1.1, 10 bit mode, enable Raw, disable sliced, - * don't clamp raw samples when codes are in use, 4 byte user D-words, - * programmed IDID, RP code V bit transition on VBLANK, data during + * don't clamp raw samples when codes are in use, 1 byte user D-words, + * IDID0 has line #, RP code V bit transition on VBLANK, data during * blanking intervals */ - cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010252e); + cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4013252e); /* Set the video input. The setting in MODE_CTRL gets lost when we do the above setup */ @@ -218,6 +218,7 @@ void cx18_av_std_setup(struct cx18 *cx) cx18_av_write(cx, 0x49f, 0x14); if (std & V4L2_STD_625_50) { + /* FIXME - revisit these for Sliced VBI */ hblank = 132; hactive = 720; burst = 93; @@ -241,13 +242,34 @@ void cx18_av_std_setup(struct cx18 *cx) sc = 672351; } } else { + /* + * The following relationships of half line counts should hold: + * 525 = vsync + vactive + vblank656 + * 12 = vblank656 - vblank + * + * vsync: always 6 half-lines of vsync pulses + * vactive: half lines of active video + * vblank656: half lines, after line 3, of blanked video + * vblank: half lines, after line 9, of blanked video + * + * vblank656 starts counting from the falling edge of the first + * vsync pulse (start of line 4) + * vblank starts counting from the after the 6 vsync pulses and + * 6 equalization pulses (start of line 10) + * + * For 525 line systems the driver will extract VBI information + * from lines 10 through 21. To avoid the EAV RP code from + * toggling at the start of hblank at line 22, where sliced VBI + * data from line 21 is stuffed, also treat line 22 as blanked. + */ + vblank656 = 38; /* lines 4 through 22 */ + vblank = 26; /* lines 10 through 22 */ + vactive = 481; /* lines 23 through 262.5 */ + hactive = 720; hblank = 122; - vactive = 487; luma_lpf = 1; uv_lpf = 1; - vblank = 26; - vblank656 = 26; src_decimation = 0x21f; if (std == V4L2_STD_PAL_60) { @@ -330,14 +352,14 @@ void cx18_av_std_setup(struct cx18 *cx) cx18_av_write(cx, 0x47d, 0xff & sc >> 8); cx18_av_write(cx, 0x47e, 0xff & sc >> 16); - /* Sets VBI parameters */ if (std & V4L2_STD_625_50) { - cx18_av_write(cx, 0x47f, 0x01); - state->vbi_line_offset = 5; + state->slicer_line_delay = 1; + state->slicer_line_offset = (6 + state->slicer_line_delay - 2); } else { - cx18_av_write(cx, 0x47f, 0x00); - state->vbi_line_offset = 8; + state->slicer_line_delay = 0; + state->slicer_line_offset = (10 + state->slicer_line_delay - 2); } + cx18_av_write(cx, 0x47f, state->slicer_line_delay); } /* ----------------------------------------------------------------------- */ diff --git a/linux/drivers/media/video/cx18/cx18-av-core.h b/linux/drivers/media/video/cx18/cx18-av-core.h index cf68a6039..d83760cae 100644 --- a/linux/drivers/media/video/cx18/cx18-av-core.h +++ b/linux/drivers/media/video/cx18/cx18-av-core.h @@ -79,11 +79,28 @@ struct cx18_av_state { enum cx18_av_audio_input aud_input; u32 audclk_freq; int audmode; - int vbi_line_offset; int default_volume; u32 id; u32 rev; int is_initialized; + + /* + * The VBI slicer starts operating and counting lines, begining at + * slicer line count of 1, at D lines after the deassertion of VRESET + * This staring field line, S, is 6 or 10 for 625 or 525 line systems. + * Sliced ancillary data captured on VBI slicer line M is sent at the + * beginning of the next VBI slicer line, VBI slicer line count N = M+1. + * Thus when the VBI slicer reports a VBI slicer line number with + * ancillary data, the IDID0 byte indicates VBI slicer line N. + * The actual field line that the captured data comes from is + * L = M+(S+D-1) = N-1+(S+D-1) = N + (S+D-2). + * + * D is the slicer_line_delay value programmed into register 0x47f. + * (S+D-2) is the slicer_line_offset used to convert slicer reported + * line counts to actual field lines. + */ + int slicer_line_delay; + int slicer_line_offset; }; diff --git a/linux/drivers/media/video/cx18/cx18-av-vbi.c b/linux/drivers/media/video/cx18/cx18-av-vbi.c index b5763372a..43267d1af 100644 --- a/linux/drivers/media/video/cx18/cx18-av-vbi.c +++ b/linux/drivers/media/video/cx18/cx18-av-vbi.c @@ -182,7 +182,6 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg) case VIDIOC_S_FMT: { int is_pal = !(state->std & V4L2_STD_525_60); - int vbi_offset = is_pal ? 1 : 0; int i, x; u8 lcr[24]; @@ -199,7 +198,7 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg) cx18_av_std_setup(cx); /* VBI Offset */ - cx18_av_write(cx, 0x47f, vbi_offset); + cx18_av_write(cx, 0x47f, state->slicer_line_delay); cx18_av_write(cx, 0x404, 0x2e); break; } @@ -213,7 +212,7 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg) /* Sliced VBI */ cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */ cx18_av_write(cx, 0x406, 0x13); - cx18_av_write(cx, 0x47f, vbi_offset); + cx18_av_write(cx, 0x47f, state->slicer_line_delay); /* Force impossible lines to 0 */ if (is_pal) { @@ -261,7 +260,8 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg) } cx18_av_write(cx, 0x43c, 0x16); - cx18_av_write(cx, 0x474, is_pal ? 0x2a : 0x22); + /* FIXME - should match vblank set in cx18_av_std_setup() */ + cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26); break; } @@ -286,7 +286,7 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg) did = anc->did; sdid = anc->sdid & 0xf; l = anc->idid[0] & 0x3f; - l += state->vbi_line_offset; + l += state->slicer_line_offset; p = anc->payload; /* Decode the SDID set by the slicer */ diff --git a/linux/drivers/media/video/cx18/cx18-driver.c b/linux/drivers/media/video/cx18/cx18-driver.c index 7a256a4fd..a95ac7795 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.c +++ b/linux/drivers/media/video/cx18/cx18-driver.c @@ -640,7 +640,9 @@ static void __devinit cx18_init_struct2(struct cx18 *cx) cx->av_state.aud_input = CX18_AV_AUDIO8; cx->av_state.audclk_freq = 48000; cx->av_state.audmode = V4L2_TUNER_MODE_LANG1; - cx->av_state.vbi_line_offset = 8; + cx->av_state.slicer_line_delay = 0; + cx->av_state.slicer_line_offset = + (10 + cx->av_state.slicer_line_delay - 2); } static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev, diff --git a/linux/drivers/media/video/cx18/cx18-streams.c b/linux/drivers/media/video/cx18/cx18-streams.c index cec4794bf..e4a70cefc 100644 --- a/linux/drivers/media/video/cx18/cx18-streams.c +++ b/linux/drivers/media/video/cx18/cx18-streams.c @@ -360,9 +360,16 @@ static void cx18_vbi_setup(struct cx18_stream *s) if (raw) { lines = cx->vbi.count * 2; } else { - lines = cx->is_60hz ? 24 : 38; - if (cx->is_60hz) - lines += 2; + /* + * For 525/60 systems, according to the VIP 2 & BT.656 std: + * The EAV RP code's Field bit toggles on line 4, a few lines + * after the Vertcal Blank bit has already toggled. + * Tell the encoder to capture 21-4+1=18 lines per field, + * since we want lines 10 through 21. + * + * FIXME - revisit for 625/50 systems + */ + lines = cx->is_60hz ? (21 - 4 + 1) * 2 : 38; } data[0] = s->handle; @@ -402,9 +409,13 @@ static void cx18_vbi_setup(struct cx18_stream *s) * * Since the V bit is only allowed to toggle in the EAV RP code, * just before the first active region line, these two - * are problematic and we have to ignore them: + * are problematic: * 0x90 (Task HorizontalBlank) * 0xd0 (Task EvenField HorizontalBlank) + * + * We have set the digitzer to consider the first active line + * as part of VerticalBlank as well so we don't have to look for + * these problem codes nor lose the last line of sliced data. */ data[4] = 0xB0F0B0F0; /* diff --git a/linux/drivers/media/video/cx18/cx18-vbi.c b/linux/drivers/media/video/cx18/cx18-vbi.c index 52082d4a1..8e6f4d4af 100644 --- a/linux/drivers/media/video/cx18/cx18-vbi.c +++ b/linux/drivers/media/video/cx18/cx18-vbi.c @@ -221,13 +221,22 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, pts = (be32_to_cpu(q[0] == 0x3fffffff)) ? be32_to_cpu(q[2]) : 0; + /* + * For calls to compress_sliced_buf(), ensure there are an integral + * number of lines by shifting the real data up over the 12 bytes header + * that got stuffed in. + * FIXME - there's a smarter way to do this with pointers, but for some + * reason I can't get it to work correctly right now. + */ + memcpy(p, &buf->buf[12], size-12); + /* first field */ - /* compress_sliced_buf() will skip the 12 bytes of header */ lines = compress_sliced_buf(cx, 0, p, size / 2, sliced_vbi_eav_rp[0]); - /* second field */ - /* experimentation shows that the second half does not always - begin at the exact address. So start a bit earlier - (hence 32). */ + /* + * second field + * In case the second half does not always begin at the exact address, + * start a bit earlier (hence 32). + */ lines = compress_sliced_buf(cx, lines, p + size / 2 - 32, size / 2 + 32, sliced_vbi_eav_rp[1]); /* always return at least one empty line */ -- cgit v1.2.3 From 6eaf346bd10a29047d3a0012f73d377e9ff2df67 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 6 Feb 2009 19:26:02 +0100 Subject: dvb: fix 2.6.16 compile warning From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-core/dvbdev.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c index 4609e3ebd..f6084e19d 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.c +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c @@ -83,7 +83,11 @@ static int dvb_device_open(struct inode *inode, struct file *file) file->private_data = dvbdev; old_fops = file->f_op; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17) file->f_op = fops_get(dvbdev->fops); +#else + file->f_op = (struct file_operations *)fops_get(dvbdev->fops); +#endif if (file->f_op == NULL) { file->f_op = old_fops; goto fail; -- cgit v1.2.3 From 2190a34473772cfc12d3d8cbdd441bbff2a84c25 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 6 Feb 2009 19:31:59 +0100 Subject: ivtv/cx18: fix g_fmt and try_fmt for raw video From: Hans Verkuil The raw video device didn't report the image size correctly. When setting a new image the image height has to be a multiple of 32 lines. Priority: normal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/cx18/cx18-ioctl.c | 17 +++++++++++------ linux/drivers/media/video/ivtv/ivtv-ioctl.c | 14 +++++++++----- 2 files changed, 20 insertions(+), 11 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-ioctl.c b/linux/drivers/media/video/cx18/cx18-ioctl.c index c023c79cf..995e19c23 100644 --- a/linux/drivers/media/video/cx18/cx18-ioctl.c +++ b/linux/drivers/media/video/cx18/cx18-ioctl.c @@ -160,10 +160,8 @@ static int cx18_g_fmt_vid_cap(struct file *file, void *fh, pixfmt->priv = 0; if (id->type == CX18_ENC_STREAM_TYPE_YUV) { pixfmt->pixelformat = V4L2_PIX_FMT_HM12; - /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ - pixfmt->sizeimage = - pixfmt->height * pixfmt->width + - pixfmt->height * (pixfmt->width / 2); + /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */ + pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2; pixfmt->bytesperline = 720; } else { pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; @@ -228,11 +226,18 @@ static int cx18_try_fmt_vid_cap(struct file *file, void *fh, struct cx18 *cx = id->cx; int w = fmt->fmt.pix.width; int h = fmt->fmt.pix.height; + int min_h = 2; w = min(w, 720); - w = max(w, 1); + w = max(w, 2); + if (id->type == CX18_ENC_STREAM_TYPE_YUV) { + /* YUV height must be a multiple of 32 */ + h &= ~0x1f; + min_h = 32; + } h = min(h, cx->is_50hz ? 576 : 480); - h = max(h, 2); + h = max(h, min_h); + cx18_g_fmt_vid_cap(file, fh, fmt); fmt->fmt.pix.width = w; fmt->fmt.pix.height = h; diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c index f6b3ef6e6..779d4110f 100644 --- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c @@ -345,10 +345,8 @@ static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f pixfmt->priv = 0; if (id->type == IVTV_ENC_STREAM_TYPE_YUV) { pixfmt->pixelformat = V4L2_PIX_FMT_HM12; - /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ - pixfmt->sizeimage = - pixfmt->height * pixfmt->width + - pixfmt->height * (pixfmt->width / 2); + /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */ + pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2; pixfmt->bytesperline = 720; } else { pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; @@ -469,11 +467,17 @@ static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format struct ivtv *itv = id->itv; int w = fmt->fmt.pix.width; int h = fmt->fmt.pix.height; + int min_h = 2; w = min(w, 720); w = max(w, 2); + if (id->type == IVTV_ENC_STREAM_TYPE_YUV) { + /* YUV height must be a multiple of 32 */ + h &= ~0x1f; + min_h = 32; + } h = min(h, itv->is_50hz ? 576 : 480); - h = max(h, 2); + h = max(h, min_h); ivtv_g_fmt_vid_cap(file, fh, fmt); fmt->fmt.pix.width = w; fmt->fmt.pix.height = h; -- cgit v1.2.3 From c56f7694e4d231f52e5dd570abf003863813a3c6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 6 Feb 2009 19:35:22 +0100 Subject: doc: update hm12 documentation. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- linux/Documentation/video4linux/cx2341x/README.hm12 | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'linux') diff --git a/linux/Documentation/video4linux/cx2341x/README.hm12 b/linux/Documentation/video4linux/cx2341x/README.hm12 index 0e213ed09..b36148ea0 100644 --- a/linux/Documentation/video4linux/cx2341x/README.hm12 +++ b/linux/Documentation/video4linux/cx2341x/README.hm12 @@ -32,6 +32,10 @@ Y, U and V planes. This code assumes frames of 720x576 (PAL) pixels. The width of a frame is always 720 pixels, regardless of the actual specified width. +If the height is not a multiple of 32 lines, then the captured video is +missing macroblocks at the end and is unusable. So the height must be a +multiple of 32. + -------------------------------------------------------------------------- #include -- cgit v1.2.3 From 721dc4a20bd1636daf1304885f235c8844e2cdda Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 7 Feb 2009 11:02:27 +0100 Subject: ivtv: cleanup naming conventions From: Hans Verkuil Use consistent naming for pci_dev, v4l2_device and video_device. Priority: normal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/ivtv/ivtv-driver.c | 93 +++++++++++++------------- linux/drivers/media/video/ivtv/ivtv-driver.h | 24 +++---- linux/drivers/media/video/ivtv/ivtv-fileops.c | 2 +- linux/drivers/media/video/ivtv/ivtv-firmware.c | 2 +- linux/drivers/media/video/ivtv/ivtv-gpio.c | 4 +- linux/drivers/media/video/ivtv/ivtv-i2c.c | 14 ++-- linux/drivers/media/video/ivtv/ivtv-ioctl.c | 6 +- linux/drivers/media/video/ivtv/ivtv-irq.c | 4 +- linux/drivers/media/video/ivtv/ivtv-queue.c | 8 +-- linux/drivers/media/video/ivtv/ivtv-queue.h | 8 +-- linux/drivers/media/video/ivtv/ivtv-streams.c | 68 +++++++++---------- linux/drivers/media/video/ivtv/ivtv-udma.c | 10 +-- linux/drivers/media/video/ivtv/ivtv-udma.h | 4 +- linux/drivers/media/video/ivtv/ivtv-yuv.c | 6 +- linux/drivers/media/video/ivtv/ivtvfb.c | 6 +- 15 files changed, 129 insertions(+), 130 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.c b/linux/drivers/media/video/ivtv/ivtv-driver.c index 05bba3928..5e90897a2 100644 --- a/linux/drivers/media/video/ivtv/ivtv-driver.c +++ b/linux/drivers/media/video/ivtv/ivtv-driver.c @@ -357,7 +357,7 @@ void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv) static void ivtv_process_eeprom(struct ivtv *itv) { struct tveeprom tv; - int pci_slot = PCI_SLOT(itv->dev->devfn); + int pci_slot = PCI_SLOT(itv->pdev->devfn); ivtv_read_eeprom(itv, &tv); @@ -604,7 +604,7 @@ static void ivtv_process_options(struct ivtv *itv) itv->std = ivtv_parse_std(itv); if (itv->std == 0 && tunertype >= 0) itv->std = tunertype ? V4L2_STD_MN : (V4L2_STD_ALL & ~V4L2_STD_MN); - itv->has_cx23415 = (itv->dev->device == PCI_DEVICE_ID_IVTV15); + itv->has_cx23415 = (itv->pdev->device == PCI_DEVICE_ID_IVTV15); chipname = itv->has_cx23415 ? "cx23415" : "cx23416"; if (itv->options.cardtype == -1) { IVTV_INFO("Ignore card (detected %s based chip)\n", chipname); @@ -617,9 +617,9 @@ static void ivtv_process_options(struct ivtv *itv) IVTV_ERR("Unknown user specified type, trying to autodetect card\n"); } if (itv->card == NULL) { - if (itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE || - itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT1 || - itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT2) { + if (itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE || + itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT1 || + itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT2) { itv->card = ivtv_get_card(itv->has_cx23415 ? IVTV_CARD_PVR_350 : IVTV_CARD_PVR_150); IVTV_INFO("Autodetected Hauppauge card (%s based)\n", chipname); @@ -630,13 +630,13 @@ static void ivtv_process_options(struct ivtv *itv) if (itv->card->pci_list == NULL) continue; for (j = 0; itv->card->pci_list[j].device; j++) { - if (itv->dev->device != + if (itv->pdev->device != itv->card->pci_list[j].device) continue; - if (itv->dev->subsystem_vendor != + if (itv->pdev->subsystem_vendor != itv->card->pci_list[j].subsystem_vendor) continue; - if (itv->dev->subsystem_device != + if (itv->pdev->subsystem_device != itv->card->pci_list[j].subsystem_device) continue; IVTV_INFO("Autodetected %s card (%s based)\n", @@ -650,9 +650,9 @@ done: if (itv->card == NULL) { itv->card = ivtv_get_card(IVTV_CARD_PVR_150); IVTV_ERR("Unknown card: vendor/device: [%04x:%04x]\n", - itv->dev->vendor, itv->dev->device); + itv->pdev->vendor, itv->pdev->device); IVTV_ERR(" subsystem vendor/device: [%04x:%04x]\n", - itv->dev->subsystem_vendor, itv->dev->subsystem_device); + itv->pdev->subsystem_vendor, itv->pdev->subsystem_device); IVTV_ERR(" %s based\n", chipname); IVTV_ERR("Defaulting to %s card\n", itv->card->name); IVTV_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n"); @@ -671,7 +671,7 @@ done: */ static int __devinit ivtv_init_struct1(struct ivtv *itv) { - itv->base_addr = pci_resource_start(itv->dev, 0); + itv->base_addr = pci_resource_start(itv->pdev, 0); itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */ itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */ @@ -682,7 +682,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv) spin_lock_init(&itv->lock); spin_lock_init(&itv->dma_reg_lock); - itv->irq_work_queues = create_singlethread_workqueue(itv->device.name); + itv->irq_work_queues = create_singlethread_workqueue(itv->v4l2_dev.name); if (itv->irq_work_queues == NULL) { IVTV_ERR("Could not create ivtv workqueue\n"); return -1; @@ -770,7 +770,7 @@ static void __devinit ivtv_init_struct2(struct ivtv *itv) itv->audio_input = itv->card->video_inputs[i].audio_index; } -static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev, +static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev, const struct pci_device_id *pci_id) { u16 cmd; @@ -779,11 +779,11 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev, IVTV_DEBUG_INFO("Enabling pci device\n"); - if (pci_enable_device(dev)) { + if (pci_enable_device(pdev)) { IVTV_ERR("Can't enable device!\n"); return -EIO; } - if (pci_set_dma_mask(dev, 0xffffffff)) { + if (pci_set_dma_mask(pdev, 0xffffffff)) { IVTV_ERR("No suitable DMA available.\n"); return -EIO; } @@ -809,11 +809,11 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev, } /* Check for bus mastering */ - pci_read_config_word(dev, PCI_COMMAND, &cmd); + pci_read_config_word(pdev, PCI_COMMAND, &cmd); if (!(cmd & PCI_COMMAND_MASTER)) { IVTV_DEBUG_INFO("Attempting to enable Bus Mastering\n"); - pci_set_master(dev); - pci_read_config_word(dev, PCI_COMMAND, &cmd); + pci_set_master(pdev); + pci_read_config_word(pdev, PCI_COMMAND, &cmd); if (!(cmd & PCI_COMMAND_MASTER)) { IVTV_ERR("Bus Mastering is not enabled\n"); return -ENXIO; @@ -821,26 +821,26 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev, } IVTV_DEBUG_INFO("Bus Mastering Enabled.\n"); - pci_read_config_byte(dev, PCI_CLASS_REVISION, &card_rev); - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency); + pci_read_config_byte(pdev, PCI_CLASS_REVISION, &card_rev); + pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency); if (pci_latency < 64 && ivtv_pci_latency) { IVTV_INFO("Unreasonably low latency timer, " "setting to 64 (was %d)\n", pci_latency); - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency); + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); + pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency); } /* This config space value relates to DMA latencies. The default value 0x8080 is too low however and will lead to DMA errors. 0xffff is the max value which solves these problems. */ - pci_write_config_dword(dev, 0x40, 0xffff); + pci_write_config_dword(pdev, 0x40, 0xffff); IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, " "irq: %d, latency: %d, memory: 0x%lx\n", - itv->dev->device, card_rev, dev->bus->number, - PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), - itv->dev->irq, pci_latency, (unsigned long)itv->base_addr); + pdev->device, card_rev, pdev->bus->number, + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), + pdev->irq, pci_latency, (unsigned long)itv->base_addr); return 0; } @@ -939,7 +939,7 @@ static void ivtv_load_and_init_modules(struct ivtv *itv) } } -static int __devinit ivtv_probe(struct pci_dev *dev, +static int __devinit ivtv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) { int retval = 0; @@ -949,17 +949,17 @@ static int __devinit ivtv_probe(struct pci_dev *dev, itv = kzalloc(sizeof(struct ivtv), GFP_ATOMIC); if (itv == NULL) return -ENOMEM; - itv->dev = dev; + itv->pdev = pdev; itv->instance = atomic_inc_return(&ivtv_instance) - 1; - retval = v4l2_device_register(&dev->dev, &itv->device); + retval = v4l2_device_register(&pdev->dev, &itv->v4l2_dev); if (retval) { kfree(itv); return retval; } /* "ivtv + PCI ID" is a bit of a mouthful, so use "ivtv + instance" instead. */ - snprintf(itv->device.name, sizeof(itv->device.name), + snprintf(itv->v4l2_dev.name, sizeof(itv->v4l2_dev.name), "ivtv%d", itv->instance); IVTV_INFO("Initializing card %d\n", itv->instance); @@ -976,12 +976,11 @@ static int __devinit ivtv_probe(struct pci_dev *dev, IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr); /* PCI Device Setup */ - if ((retval = ivtv_setup_pci(itv, dev, pci_id)) != 0) { - if (retval == -EIO) - goto free_workqueue; - else if (retval == -ENXIO) - goto free_mem; - } + retval = ivtv_setup_pci(itv, pdev, pci_id); + if (retval == -EIO) + goto free_workqueue; + if (retval == -ENXIO) + goto free_mem; /* map io memory */ IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", @@ -1158,8 +1157,8 @@ static int __devinit ivtv_probe(struct pci_dev *dev, ivtv_set_irq_mask(itv, 0xffffffff); /* Register IRQ */ - retval = request_irq(itv->dev->irq, ivtv_irq_handler, - IRQF_SHARED | IRQF_DISABLED, itv->device.name, (void *)itv); + retval = request_irq(itv->pdev->irq, ivtv_irq_handler, + IRQF_SHARED | IRQF_DISABLED, itv->v4l2_dev.name, (void *)itv); if (retval) { IVTV_ERR("Failed to register irq %d\n", retval); goto free_i2c; @@ -1181,7 +1180,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev, free_streams: ivtv_streams_cleanup(itv, 1); free_irq: - free_irq(itv->dev->irq, (void *)itv); + free_irq(itv->pdev->irq, (void *)itv); free_i2c: exit_ivtv_i2c(itv); free_io: @@ -1198,7 +1197,7 @@ err: retval = -ENODEV; IVTV_ERR("Error %d on initialization\n", retval); - v4l2_device_unregister(&itv->device); + v4l2_device_unregister(&itv->v4l2_dev); kfree(itv); return retval; } @@ -1296,10 +1295,10 @@ int ivtv_init_on_first_open(struct ivtv *itv) return 0; } -static void ivtv_remove(struct pci_dev *pci_dev) +static void ivtv_remove(struct pci_dev *pdev) { - struct v4l2_device *dev = dev_get_drvdata(&pci_dev->dev); - struct ivtv *itv = to_ivtv(dev); + struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); + struct ivtv *itv = to_ivtv(v4l2_dev); int i; IVTV_DEBUG_INFO("Removing card\n"); @@ -1340,11 +1339,9 @@ static void ivtv_remove(struct pci_dev *pci_dev) ivtv_streams_cleanup(itv, 1); ivtv_udma_free(itv); - v4l2_device_unregister(&itv->device); - exit_ivtv_i2c(itv); - free_irq(itv->dev->irq, (void *)itv); + free_irq(itv->pdev->irq, (void *)itv); ivtv_iounmap(itv); release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE); @@ -1352,11 +1349,13 @@ static void ivtv_remove(struct pci_dev *pci_dev) if (itv->has_cx23415) release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); - pci_disable_device(itv->dev); + pci_disable_device(itv->pdev); for (i = 0; i < IVTV_VBI_FRAMES; i++) kfree(itv->vbi.sliced_mpeg_data[i]); printk(KERN_INFO "ivtv: Removed %s\n", itv->card_name); + + v4l2_device_unregister(&itv->v4l2_dev); kfree(itv); } diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.h b/linux/drivers/media/video/ivtv/ivtv-driver.h index 03df1cb7d..15779519a 100644 --- a/linux/drivers/media/video/ivtv/ivtv-driver.h +++ b/linux/drivers/media/video/ivtv/ivtv-driver.h @@ -134,7 +134,7 @@ extern int ivtv_debug; #define IVTV_DEBUG(x, type, fmt, args...) \ do { \ if ((x) & ivtv_debug) \ - v4l2_info(&itv->device, " " type ": " fmt , ##args); \ + v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \ } while (0) #define IVTV_DEBUG_WARN(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_WARN, "warn", fmt , ## args) #define IVTV_DEBUG_INFO(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_INFO, "info", fmt , ## args) @@ -150,7 +150,7 @@ extern int ivtv_debug; #define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \ do { \ if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \ - v4l2_info(&itv->device, " " type ": " fmt , ##args); \ + v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \ } while (0) #define IVTV_DEBUG_HI_WARN(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN, "warn", fmt , ## args) #define IVTV_DEBUG_HI_INFO(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_INFO, "info", fmt , ## args) @@ -164,9 +164,9 @@ extern int ivtv_debug; #define IVTV_DEBUG_HI_YUV(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_YUV, "yuv", fmt , ## args) /* Standard kernel messages */ -#define IVTV_ERR(fmt, args...) v4l2_err(&itv->device, fmt , ## args) -#define IVTV_WARN(fmt, args...) v4l2_warn(&itv->device, fmt , ## args) -#define IVTV_INFO(fmt, args...) v4l2_info(&itv->device, fmt , ## args) +#define IVTV_ERR(fmt, args...) v4l2_err(&itv->v4l2_dev, fmt , ## args) +#define IVTV_WARN(fmt, args...) v4l2_warn(&itv->v4l2_dev, fmt , ## args) +#define IVTV_INFO(fmt, args...) v4l2_info(&itv->v4l2_dev, fmt , ## args) /* output modes (cx23415 only) */ #define OUT_NONE 0 @@ -316,7 +316,7 @@ struct ivtv; /* forward reference */ struct ivtv_stream { /* These first four fields are always set, even if the stream is not actually created. */ - struct video_device *v4l2dev; /* NULL when stream not created */ + struct video_device *vdev; /* NULL when stream not created */ struct ivtv *itv; /* for ease of use */ const char *name; /* name of the stream */ int type; /* stream type */ @@ -593,7 +593,7 @@ struct ivtv_card; /* Struct to hold info about ivtv cards */ struct ivtv { /* General fixed card data */ - struct pci_dev *dev; /* PCI device */ + struct pci_dev *pdev; /* PCI device */ const struct ivtv_card *card; /* card information */ const char *card_name; /* full name of the card */ const struct ivtv_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */ @@ -613,7 +613,7 @@ struct ivtv { volatile void __iomem *reg_mem; /* pointer to mapped registers */ struct ivtv_options options; /* user options */ - struct v4l2_device device; + struct v4l2_device v4l2_dev; struct v4l2_subdev sd_gpio; /* GPIO sub-device */ u16 instance; @@ -720,9 +720,9 @@ struct ivtv { struct osd_info *osd_info; /* ivtvfb private OSD info */ }; -static inline struct ivtv *to_ivtv(struct v4l2_device *dev) +static inline struct ivtv *to_ivtv(struct v4l2_device *v4l2_dev) { - return container_of(dev, struct ivtv, device); + return container_of(v4l2_dev, struct ivtv, v4l2_dev); } /* Globals */ @@ -789,7 +789,7 @@ static inline int ivtv_raw_vbi(const struct ivtv *itv) /* Call the specified callback for all subdevs matching hw (if 0, then match them all). Ignore any errors. */ #define ivtv_call_hw(itv, hw, o, f, args...) \ - __v4l2_device_call_subdevs(&(itv)->device, !(hw) || (sd->grp_id & (hw)), o, f , ##args) + __v4l2_device_call_subdevs(&(itv)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args) #define ivtv_call_all(itv, o, f, args...) ivtv_call_hw(itv, 0, o, f , ##args) @@ -797,7 +797,7 @@ static inline int ivtv_raw_vbi(const struct ivtv *itv) match them all). If the callback returns an error other than 0 or -ENOIOCTLCMD, then return with that error code. */ #define ivtv_call_hw_err(itv, hw, o, f, args...) \ - __v4l2_device_call_subdevs_until_err(&(itv)->device, !(hw) || (sd->grp_id & (hw)), o, f , ##args) + __v4l2_device_call_subdevs_until_err(&(itv)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args) #define ivtv_call_all_err(itv, o, f, args...) ivtv_call_hw_err(itv, 0, o, f , ##args) diff --git a/linux/drivers/media/video/ivtv/ivtv-fileops.c b/linux/drivers/media/video/ivtv/ivtv-fileops.c index 617667d1c..cfaacf609 100644 --- a/linux/drivers/media/video/ivtv/ivtv-fileops.c +++ b/linux/drivers/media/video/ivtv/ivtv-fileops.c @@ -991,7 +991,7 @@ 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", - s->v4l2dev->minor); + vdev->minor); mutex_unlock(&itv->serialize_lock); return -ENXIO; } diff --git a/linux/drivers/media/video/ivtv/ivtv-firmware.c b/linux/drivers/media/video/ivtv/ivtv-firmware.c index 6dba55b7e..c1b7ec475 100644 --- a/linux/drivers/media/video/ivtv/ivtv-firmware.c +++ b/linux/drivers/media/video/ivtv/ivtv-firmware.c @@ -52,7 +52,7 @@ static int load_fw_direct(const char *fn, volatile u8 __iomem *mem, struct ivtv int retries = 3; retry: - if (retries && request_firmware(&fw, fn, &itv->dev->dev) == 0) { + if (retries && request_firmware(&fw, fn, &itv->pdev->dev) == 0) { int i; volatile u32 __iomem *dst = (volatile u32 __iomem *)mem; const u32 *src = (const u32 *)fw->data; diff --git a/linux/drivers/media/video/ivtv/ivtv-gpio.c b/linux/drivers/media/video/ivtv/ivtv-gpio.c index dc2850e87..3321983d8 100644 --- a/linux/drivers/media/video/ivtv/ivtv-gpio.c +++ b/linux/drivers/media/video/ivtv/ivtv-gpio.c @@ -384,7 +384,7 @@ int ivtv_gpio_init(struct ivtv *itv) write_reg(itv->card->gpio_init.initial_value | pin, IVTV_REG_GPIO_OUT); write_reg(itv->card->gpio_init.direction | pin, IVTV_REG_GPIO_DIR); v4l2_subdev_init(&itv->sd_gpio, &subdev_ops); - snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->device.name); + snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->v4l2_dev.name); itv->sd_gpio.grp_id = IVTV_HW_GPIO; - return v4l2_device_register_subdev(&itv->device, &itv->sd_gpio); + return v4l2_device_register_subdev(&itv->v4l2_dev, &itv->sd_gpio); } diff --git a/linux/drivers/media/video/ivtv/ivtv-i2c.c b/linux/drivers/media/video/ivtv/ivtv-i2c.c index 41452e111..682377c1a 100644 --- a/linux/drivers/media/video/ivtv/ivtv-i2c.c +++ b/linux/drivers/media/video/ivtv/ivtv-i2c.c @@ -198,14 +198,14 @@ struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw) struct v4l2_subdev *result = NULL; struct v4l2_subdev *sd; - spin_lock(&itv->device.lock); - v4l2_device_for_each_subdev(sd, &itv->device) { + spin_lock(&itv->v4l2_dev.lock); + v4l2_device_for_each_subdev(sd, &itv->v4l2_dev) { if (sd->grp_id == hw) { result = sd; break; } } - spin_unlock(&itv->device.lock); + spin_unlock(&itv->v4l2_dev.lock); return result; } @@ -476,8 +476,8 @@ static int ivtv_read(struct ivtv *itv, unsigned char addr, unsigned char *data, intervening stop condition */ static int ivtv_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) { - struct v4l2_device *drv = i2c_get_adapdata(i2c_adap); - struct ivtv *itv = to_ivtv(drv); + struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap); + struct ivtv *itv = to_ivtv(v4l2_dev); int retval; int i; @@ -617,13 +617,13 @@ int init_ivtv_i2c(struct ivtv *itv) sprintf(itv->i2c_adap.name + strlen(itv->i2c_adap.name), " #%d", itv->instance); - i2c_set_adapdata(&itv->i2c_adap, &itv->device); + i2c_set_adapdata(&itv->i2c_adap, &itv->v4l2_dev); memcpy(&itv->i2c_client, &ivtv_i2c_client_template, sizeof(struct i2c_client)); itv->i2c_client.adapter = &itv->i2c_adap; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) - itv->i2c_adap.dev.parent = &itv->dev->dev; + itv->i2c_adap.dev.parent = &itv->pdev->dev; #endif IVTV_DEBUG_I2C("setting scl and sda to 1\n"); diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c index 779d4110f..aa55a3cc4 100644 --- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c @@ -770,7 +770,7 @@ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vc strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); - snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->dev)); + snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev)); vcap->version = IVTV_DRIVER_VERSION; /* version */ vcap->capabilities = itv->v4l2_cap; /* capabilities */ return 0; @@ -1517,12 +1517,12 @@ static int ivtv_log_status(struct file *file, void *fh) } IVTV_INFO("Tuner: %s\n", test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV"); - cx2341x_log_status(&itv->params, itv->device.name); + cx2341x_log_status(&itv->params, itv->v4l2_dev.name); IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags); for (i = 0; i < IVTV_MAX_STREAMS; i++) { struct ivtv_stream *s = &itv->streams[i]; - if (s->v4l2dev == NULL || s->buffers == 0) + if (s->vdev == NULL || s->buffers == 0) continue; IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, (s->buffers - s->q_free.buffers) * 100 / s->buffers, diff --git a/linux/drivers/media/video/ivtv/ivtv-irq.c b/linux/drivers/media/video/ivtv/ivtv-irq.c index 20e758d29..6dda1dd03 100644 --- a/linux/drivers/media/video/ivtv/ivtv-irq.c +++ b/linux/drivers/media/video/ivtv/ivtv-irq.c @@ -46,7 +46,7 @@ static void ivtv_pio_work_handler(struct ivtv *itv) IVTV_DEBUG_HI_DMA("ivtv_pio_work_handler\n"); if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS || - s->v4l2dev == NULL || !ivtv_use_pio(s)) { + s->vdev == NULL || !ivtv_use_pio(s)) { itv->cur_pio_stream = -1; /* trigger PIO complete user interrupt */ write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44); @@ -115,7 +115,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA int rc; /* sanity checks */ - if (s->v4l2dev == NULL) { + if (s->vdev == NULL) { IVTV_DEBUG_WARN("Stream %s not started\n", s->name); return -1; } diff --git a/linux/drivers/media/video/ivtv/ivtv-queue.c b/linux/drivers/media/video/ivtv/ivtv-queue.c index 71bd13e22..ff7b7dede 100644 --- a/linux/drivers/media/video/ivtv/ivtv-queue.c +++ b/linux/drivers/media/video/ivtv/ivtv-queue.c @@ -230,7 +230,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s) return -ENOMEM; } if (ivtv_might_use_dma(s)) { - s->sg_handle = pci_map_single(itv->dev, s->sg_dma, sizeof(struct ivtv_sg_element), s->dma); + s->sg_handle = pci_map_single(itv->pdev, s->sg_dma, sizeof(struct ivtv_sg_element), s->dma); ivtv_stream_sync_for_cpu(s); } @@ -248,7 +248,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s) } INIT_LIST_HEAD(&buf->list); if (ivtv_might_use_dma(s)) { - buf->dma_handle = pci_map_single(s->itv->dev, + buf->dma_handle = pci_map_single(s->itv->pdev, buf->buf, s->buf_size + 256, s->dma); ivtv_buf_sync_for_cpu(s, buf); } @@ -271,7 +271,7 @@ void ivtv_stream_free(struct ivtv_stream *s) /* empty q_free */ while ((buf = ivtv_dequeue(s, &s->q_free))) { if (ivtv_might_use_dma(s)) - pci_unmap_single(s->itv->dev, buf->dma_handle, + pci_unmap_single(s->itv->pdev, buf->dma_handle, s->buf_size + 256, s->dma); kfree(buf->buf); kfree(buf); @@ -280,7 +280,7 @@ void ivtv_stream_free(struct ivtv_stream *s) /* Free SG Array/Lists */ if (s->sg_dma != NULL) { if (s->sg_handle != IVTV_DMA_UNMAPPED) { - pci_unmap_single(s->itv->dev, s->sg_handle, + pci_unmap_single(s->itv->pdev, s->sg_handle, sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE); s->sg_handle = IVTV_DMA_UNMAPPED; } diff --git a/linux/drivers/media/video/ivtv/ivtv-queue.h b/linux/drivers/media/video/ivtv/ivtv-queue.h index 476556afd..91233839a 100644 --- a/linux/drivers/media/video/ivtv/ivtv-queue.h +++ b/linux/drivers/media/video/ivtv/ivtv-queue.h @@ -53,14 +53,14 @@ static inline int ivtv_use_dma(struct ivtv_stream *s) static inline void ivtv_buf_sync_for_cpu(struct ivtv_stream *s, struct ivtv_buffer *buf) { if (ivtv_use_dma(s)) - pci_dma_sync_single_for_cpu(s->itv->dev, buf->dma_handle, + pci_dma_sync_single_for_cpu(s->itv->pdev, buf->dma_handle, s->buf_size + 256, s->dma); } static inline void ivtv_buf_sync_for_device(struct ivtv_stream *s, struct ivtv_buffer *buf) { if (ivtv_use_dma(s)) - pci_dma_sync_single_for_device(s->itv->dev, buf->dma_handle, + pci_dma_sync_single_for_device(s->itv->pdev, buf->dma_handle, s->buf_size + 256, s->dma); } @@ -82,14 +82,14 @@ void ivtv_stream_free(struct ivtv_stream *s); static inline void ivtv_stream_sync_for_cpu(struct ivtv_stream *s) { if (ivtv_use_dma(s)) - pci_dma_sync_single_for_cpu(s->itv->dev, s->sg_handle, + pci_dma_sync_single_for_cpu(s->itv->pdev, s->sg_handle, sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE); } static inline void ivtv_stream_sync_for_device(struct ivtv_stream *s) { if (ivtv_use_dma(s)) - pci_dma_sync_single_for_device(s->itv->dev, s->sg_handle, + pci_dma_sync_single_for_device(s->itv->pdev, s->sg_handle, sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE); } diff --git a/linux/drivers/media/video/ivtv/ivtv-streams.c b/linux/drivers/media/video/ivtv/ivtv-streams.c index 854a950af..15da01710 100644 --- a/linux/drivers/media/video/ivtv/ivtv-streams.c +++ b/linux/drivers/media/video/ivtv/ivtv-streams.c @@ -137,11 +137,11 @@ static struct { static void ivtv_stream_init(struct ivtv *itv, int type) { struct ivtv_stream *s = &itv->streams[type]; - struct video_device *dev = s->v4l2dev; + struct video_device *vdev = s->vdev; - /* we need to keep v4l2dev, so restore it afterwards */ + /* we need to keep vdev, so restore it afterwards */ memset(s, 0, sizeof(*s)); - s->v4l2dev = dev; + s->vdev = vdev; /* initialize ivtv_stream fields */ s->itv = itv; @@ -172,10 +172,10 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) int num_offset = ivtv_stream_info[type].num_offset; int num = itv->instance + ivtv_first_minor + num_offset; - /* These four fields are always initialized. If v4l2dev == NULL, then + /* These four fields are always initialized. If vdev == NULL, then this stream is not in use. In that case no other fields but these four can be used. */ - s->v4l2dev = NULL; + s->vdev = NULL; s->itv = itv; s->type = type; s->name = ivtv_stream_info[type].name; @@ -197,21 +197,21 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) ivtv_stream_init(itv, type); /* allocate and initialize the v4l2 video device structure */ - s->v4l2dev = video_device_alloc(); - if (s->v4l2dev == NULL) { + s->vdev = video_device_alloc(); + if (s->vdev == NULL) { IVTV_ERR("Couldn't allocate v4l2 video_device for %s\n", s->name); return -ENOMEM; } - snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "%s %s", - itv->device.name, s->name); + snprintf(s->vdev->name, sizeof(s->vdev->name), "%s %s", + itv->v4l2_dev.name, s->name); - s->v4l2dev->num = num; - s->v4l2dev->v4l2_dev = &itv->device; - s->v4l2dev->fops = ivtv_stream_info[type].fops; - s->v4l2dev->release = video_device_release; - s->v4l2dev->tvnorms = V4L2_STD_ALL; - ivtv_set_funcs(s->v4l2dev); + s->vdev->num = num; + s->vdev->v4l2_dev = &itv->v4l2_dev; + s->vdev->fops = ivtv_stream_info[type].fops; + s->vdev->release = video_device_release; + s->vdev->tvnorms = V4L2_STD_ALL; + ivtv_set_funcs(s->vdev); return 0; } @@ -226,7 +226,7 @@ int ivtv_streams_setup(struct ivtv *itv) if (ivtv_prep_dev(itv, type)) break; - if (itv->streams[type].v4l2dev == NULL) + if (itv->streams[type].vdev == NULL) continue; /* Allocate Stream */ @@ -247,28 +247,28 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) int vfl_type = ivtv_stream_info[type].vfl_type; int num; - if (s->v4l2dev == NULL) + if (s->vdev == NULL) return 0; - num = s->v4l2dev->num; + num = s->vdev->num; /* card number + user defined offset + device offset */ if (type != IVTV_ENC_STREAM_TYPE_MPG) { struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG]; - if (s_mpg->v4l2dev) - num = s_mpg->v4l2dev->num + ivtv_stream_info[type].num_offset; + if (s_mpg->vdev) + num = s_mpg->vdev->num + ivtv_stream_info[type].num_offset; } - video_set_drvdata(s->v4l2dev, s); + video_set_drvdata(s->vdev, s); /* Register device. First try the desired minor, then any free one. */ - if (video_register_device(s->v4l2dev, vfl_type, num)) { + if (video_register_device(s->vdev, vfl_type, num)) { IVTV_ERR("Couldn't register v4l2 device for %s kernel number %d\n", s->name, num); - video_device_release(s->v4l2dev); - s->v4l2dev = NULL; + video_device_release(s->vdev); + s->vdev = NULL; return -ENOMEM; } - num = s->v4l2dev->num; + num = s->vdev->num; switch (vfl_type) { case VFL_TYPE_GRABBER: @@ -316,9 +316,9 @@ void ivtv_streams_cleanup(struct ivtv *itv, int unregister) /* Teardown all streams */ for (type = 0; type < IVTV_MAX_STREAMS; type++) { - struct video_device *vdev = itv->streams[type].v4l2dev; + struct video_device *vdev = itv->streams[type].vdev; - itv->streams[type].v4l2dev = NULL; + itv->streams[type].vdev = NULL; if (vdev == NULL) continue; @@ -449,7 +449,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) int captype = 0, subtype = 0; int enable_passthrough = 0; - if (s->v4l2dev == NULL) + if (s->vdev == NULL) return -EINVAL; IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name); @@ -611,7 +611,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) struct cx2341x_mpeg_params *p = &itv->params; int datatype; - if (s->v4l2dev == NULL) + if (s->vdev == NULL) return -EINVAL; IVTV_DEBUG_INFO("Setting some initial decoder settings\n"); @@ -657,7 +657,7 @@ int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset) { struct ivtv *itv = s->itv; - if (s->v4l2dev == NULL) + if (s->vdev == NULL) return -EINVAL; if (test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags)) @@ -705,7 +705,7 @@ void ivtv_stop_all_captures(struct ivtv *itv) for (i = IVTV_MAX_STREAMS - 1; i >= 0; i--) { struct ivtv_stream *s = &itv->streams[i]; - if (s->v4l2dev == NULL) + if (s->vdev == NULL) continue; if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { ivtv_stop_v4l2_encode_stream(s, 0); @@ -720,7 +720,7 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) int cap_type; int stopmode; - if (s->v4l2dev == NULL) + if (s->vdev == NULL) return -EINVAL; /* This function assumes that you are allowed to stop the capture @@ -834,7 +834,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts) { struct ivtv *itv = s->itv; - if (s->v4l2dev == NULL) + if (s->vdev == NULL) return -EINVAL; if (s->type != IVTV_DEC_STREAM_TYPE_YUV && s->type != IVTV_DEC_STREAM_TYPE_MPG) @@ -895,7 +895,7 @@ int ivtv_passthrough_mode(struct ivtv *itv, int enable) struct ivtv_stream *yuv_stream = &itv->streams[IVTV_ENC_STREAM_TYPE_YUV]; struct ivtv_stream *dec_stream = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV]; - if (yuv_stream->v4l2dev == NULL || dec_stream->v4l2dev == NULL) + if (yuv_stream->vdev == NULL || dec_stream->vdev == NULL) return -EINVAL; IVTV_DEBUG_INFO("ivtv ioctl: Select passthrough mode\n"); diff --git a/linux/drivers/media/video/ivtv/ivtv-udma.c b/linux/drivers/media/video/ivtv/ivtv-udma.c index 5d4964b24..c3f8a5eac 100644 --- a/linux/drivers/media/video/ivtv/ivtv-udma.c +++ b/linux/drivers/media/video/ivtv/ivtv-udma.c @@ -94,7 +94,7 @@ void ivtv_udma_alloc(struct ivtv *itv) { if (itv->udma.SG_handle == 0) { /* Map DMA Page Array Buffer */ - itv->udma.SG_handle = pci_map_single(itv->dev, itv->udma.SGarray, + itv->udma.SG_handle = pci_map_single(itv->pdev, itv->udma.SGarray, sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE); ivtv_udma_sync_for_cpu(itv); } @@ -148,7 +148,7 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr, } /* Map SG List */ - dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); + dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); /* Fill SG Array with new values */ ivtv_udma_fill_sg_array (dma, ivtv_dest_addr, 0, -1); @@ -173,7 +173,7 @@ void ivtv_udma_unmap(struct ivtv *itv) /* Unmap Scatterlist */ if (dma->SG_length) { - pci_unmap_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); + pci_unmap_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); dma->SG_length = 0; } /* sync DMA */ @@ -192,13 +192,13 @@ void ivtv_udma_free(struct ivtv *itv) /* Unmap SG Array */ if (itv->udma.SG_handle) { - pci_unmap_single(itv->dev, itv->udma.SG_handle, + pci_unmap_single(itv->pdev, itv->udma.SG_handle, sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE); } /* Unmap Scatterlist */ if (itv->udma.SG_length) { - pci_unmap_sg(itv->dev, itv->udma.SGlist, itv->udma.page_count, PCI_DMA_TODEVICE); + pci_unmap_sg(itv->pdev, itv->udma.SGlist, itv->udma.page_count, PCI_DMA_TODEVICE); } for (i = 0; i < IVTV_DMA_SG_OSD_ENT; i++) { diff --git a/linux/drivers/media/video/ivtv/ivtv-udma.h b/linux/drivers/media/video/ivtv/ivtv-udma.h index df727e23b..ee3c9efb5 100644 --- a/linux/drivers/media/video/ivtv/ivtv-udma.h +++ b/linux/drivers/media/video/ivtv/ivtv-udma.h @@ -35,13 +35,13 @@ void ivtv_udma_start(struct ivtv *itv); static inline void ivtv_udma_sync_for_device(struct ivtv *itv) { - pci_dma_sync_single_for_device((struct pci_dev *)itv->dev, itv->udma.SG_handle, + pci_dma_sync_single_for_device(itv->pdev, itv->udma.SG_handle, sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE); } static inline void ivtv_udma_sync_for_cpu(struct ivtv *itv) { - pci_dma_sync_single_for_cpu((struct pci_dev *)itv->dev, itv->udma.SG_handle, + pci_dma_sync_single_for_cpu(itv->pdev, itv->udma.SG_handle, sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE); } diff --git a/linux/drivers/media/video/ivtv/ivtv-yuv.c b/linux/drivers/media/video/ivtv/ivtv-yuv.c index ee9110737..7912ed6b7 100644 --- a/linux/drivers/media/video/ivtv/ivtv-yuv.c +++ b/linux/drivers/media/video/ivtv/ivtv-yuv.c @@ -103,7 +103,7 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma, dma->page_count = 0; return -ENOMEM; } - dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); + dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); /* Fill SG Array with new values */ ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size); @@ -910,7 +910,7 @@ static void ivtv_yuv_init(struct ivtv *itv) /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */ yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL|__GFP_NOWARN); if (yi->blanking_ptr) { - yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE); + yi->blanking_dmaptr = pci_map_single(itv->pdev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE); } else { yi->blanking_dmaptr = 0; IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n"); @@ -1237,7 +1237,7 @@ void ivtv_yuv_close(struct ivtv *itv) if (yi->blanking_ptr) { kfree(yi->blanking_ptr); yi->blanking_ptr = NULL; - pci_unmap_single(itv->dev, yi->blanking_dmaptr, 720*16, PCI_DMA_TODEVICE); + pci_unmap_single(itv->pdev, yi->blanking_dmaptr, 720*16, PCI_DMA_TODEVICE); } /* Invalidate the old dimension information */ diff --git a/linux/drivers/media/video/ivtv/ivtvfb.c b/linux/drivers/media/video/ivtv/ivtvfb.c index 26b91d2c8..a48fe216b 100644 --- a/linux/drivers/media/video/ivtv/ivtvfb.c +++ b/linux/drivers/media/video/ivtv/ivtvfb.c @@ -1201,12 +1201,12 @@ static int ivtvfb_init_card(struct ivtv *itv) static int __init ivtvfb_callback_init(struct device *dev, void *p) { struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); - struct ivtv *itv = container_of(v4l2_dev, struct ivtv, device); + struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev); if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { if (ivtvfb_init_card(itv) == 0) { IVTVFB_INFO("Framebuffer registered on %s\n", - itv->device.name); + itv->v4l2_dev.name); (*(int *)p)++; } } @@ -1216,7 +1216,7 @@ static int __init ivtvfb_callback_init(struct device *dev, void *p) static int ivtvfb_callback_cleanup(struct device *dev, void *p) { struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); - struct ivtv *itv = container_of(v4l2_dev, struct ivtv, device); + struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev); if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) { -- cgit v1.2.3 From b8e52030ce27c936c72151dfca30fd90e857ebab Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 7 Feb 2009 11:07:04 +0100 Subject: doc: use consistent naming conventions for vdev and v4l2_dev. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- linux/Documentation/video4linux/v4l2-framework.txt | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'linux') diff --git a/linux/Documentation/video4linux/v4l2-framework.txt b/linux/Documentation/video4linux/v4l2-framework.txt index cc3506242..73f9b6423 100644 --- a/linux/Documentation/video4linux/v4l2-framework.txt +++ b/linux/Documentation/video4linux/v4l2-framework.txt @@ -134,7 +134,7 @@ The recommended approach is as follows: static atomic_t drv_instance = ATOMIC_INIT(0); -static int __devinit drv_probe(struct pci_dev *dev, +static int __devinit drv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) { ... @@ -218,7 +218,7 @@ to add new ops and categories. A sub-device driver initializes the v4l2_subdev struct using: - v4l2_subdev_init(subdev, &ops); + v4l2_subdev_init(sd, &ops); Afterwards you need to initialize subdev->name with a unique name and set the module owner. This is done for you if you use the i2c helper functions. @@ -226,7 +226,7 @@ module owner. This is done for you if you use the i2c helper functions. A device (bridge) driver needs to register the v4l2_subdev with the v4l2_device: - int err = v4l2_device_register_subdev(device, subdev); + int err = v4l2_device_register_subdev(v4l2_dev, sd); This can fail if the subdev module disappeared before it could be registered. After this function was called successfully the subdev->dev field points to @@ -234,17 +234,17 @@ the v4l2_device. You can unregister a sub-device using: - v4l2_device_unregister_subdev(subdev); + v4l2_device_unregister_subdev(sd); -Afterwards the subdev module can be unloaded and subdev->dev == NULL. +Afterwards the subdev module can be unloaded and sd->dev == NULL. You can call an ops function either directly: - err = subdev->ops->core->g_chip_ident(subdev, &chip); + err = sd->ops->core->g_chip_ident(sd, &chip); but it is better and easier to use this macro: - err = v4l2_subdev_call(subdev, core, g_chip_ident, &chip); + err = v4l2_subdev_call(sd, core, g_chip_ident, &chip); The macro will to the right NULL pointer checks and returns -ENODEV if subdev is NULL, -ENOIOCTLCMD if either subdev->core or subdev->core->g_chip_ident is @@ -252,12 +252,12 @@ NULL, or the actual result of the subdev->ops->core->g_chip_ident ops. It is also possible to call all or a subset of the sub-devices: - v4l2_device_call_all(dev, 0, core, g_chip_ident, &chip); + v4l2_device_call_all(v4l2_dev, 0, core, g_chip_ident, &chip); Any subdev that does not support this ops is skipped and error results are ignored. If you want to check for errors use this: - err = v4l2_device_call_until_err(dev, 0, core, g_chip_ident, &chip); + err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_chip_ident, &chip); Any error except -ENOIOCTLCMD will exit the loop with that error. If no errors (except -ENOIOCTLCMD) occured, then 0 is returned. @@ -505,8 +505,8 @@ There are a few useful helper functions: You can set/get driver private data in the video_device struct using: -void *video_get_drvdata(struct video_device *dev); -void video_set_drvdata(struct video_device *dev, void *data); +void *video_get_drvdata(struct video_device *vdev); +void video_set_drvdata(struct video_device *vdev, void *data); Note that you can safely call video_set_drvdata() before calling video_register_device(). -- cgit v1.2.3 From 03ba675c15fe86ace9d44dc86d769b6695621e69 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 7 Feb 2009 11:23:40 +0100 Subject: saa7146: implement v4l2_device support. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/common/saa7146_core.c | 17 ++++++++++------- linux/include/media/saa7146.h | 3 +++ 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/common/saa7146_core.c b/linux/drivers/media/common/saa7146_core.c index 9bce837f3..ef11ab98c 100644 --- a/linux/drivers/media/common/saa7146_core.c +++ b/linux/drivers/media/common/saa7146_core.c @@ -367,13 +367,16 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent ERR(("out of memory.\n")); goto out; } + err = v4l2_device_register(&pci->dev, &dev->v4l2_dev); + if (err) + goto err_free; DEB_EE(("pci:%p\n",pci)); err = pci_enable_device(pci); if (err < 0) { ERR(("pci_enable_device() failed.\n")); - goto err_free; + goto err_unreg; } /* enable bus-mastering */ @@ -456,8 +459,6 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent INFO(("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x).\n", dev->mem, dev->revision, pci->irq, pci->subsystem_vendor, pci->subsystem_device)); dev->ext = ext; - pci_set_drvdata(pci, dev); - mutex_init(&dev->lock); spin_lock_init(&dev->int_slock); spin_lock_init(&dev->slock); @@ -481,7 +482,7 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent if (ext->attach(dev, pci_ext)) { DEB_D(("ext->attach() failed for %p. skipping device.\n",dev)); - goto err_unprobe; + goto err_free_i2c; } INIT_LIST_HEAD(&dev->item); @@ -492,8 +493,6 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent out: return err; -err_unprobe: - pci_set_drvdata(pci, NULL); err_free_i2c: pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr, dev->d_i2c.dma_handle); @@ -511,6 +510,8 @@ err_release: pci_release_region(pci, 0); err_disable: pci_disable_device(pci); +err_unreg: + v4l2_device_unregister(&dev->v4l2_dev); err_free: kfree(dev); goto out; @@ -518,7 +519,8 @@ err_free: static void saa7146_remove_one(struct pci_dev *pdev) { - struct saa7146_dev* dev = pci_get_drvdata(pdev); + struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev); + struct saa7146_dev *dev = container_of(v4l2_dev, struct saa7146_dev, v4l2_dev); struct { void *addr; dma_addr_t dma; @@ -532,6 +534,7 @@ static void saa7146_remove_one(struct pci_dev *pdev) DEB_EE(("dev:%p\n",dev)); dev->ext->detach(dev); + v4l2_device_unregister(&dev->v4l2_dev); /* shut down all video dma transfers */ saa7146_write(dev, MC1, 0x00ff0000); diff --git a/linux/include/media/saa7146.h b/linux/include/media/saa7146.h index 8034124f1..689bc8ebd 100644 --- a/linux/include/media/saa7146.h +++ b/linux/include/media/saa7146.h @@ -14,6 +14,7 @@ #include "compat.h" #include #include +#include #include /* for vmalloc() */ #include /* for vmalloc_to_page() */ @@ -111,6 +112,8 @@ struct saa7146_dev struct list_head item; + struct v4l2_device v4l2_dev; + /* different device locks */ spinlock_t slock; struct mutex lock; -- cgit v1.2.3 From 730fafde64c1efd147ec7f58edf1bc0cc24ef24b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 7 Feb 2009 11:38:12 +0100 Subject: saa7146: i2c adapdata now points to v4l2_device. From: Hans Verkuil Prepare for converting to v4l2_subdev. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/common/saa7146_core.c | 2 +- linux/drivers/media/common/saa7146_i2c.c | 5 +++-- linux/include/media/saa7146.h | 5 +++++ 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/common/saa7146_core.c b/linux/drivers/media/common/saa7146_core.c index ef11ab98c..067a1f282 100644 --- a/linux/drivers/media/common/saa7146_core.c +++ b/linux/drivers/media/common/saa7146_core.c @@ -520,7 +520,7 @@ err_free: static void saa7146_remove_one(struct pci_dev *pdev) { struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev); - struct saa7146_dev *dev = container_of(v4l2_dev, struct saa7146_dev, v4l2_dev); + struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev); struct { void *addr; dma_addr_t dma; diff --git a/linux/drivers/media/common/saa7146_i2c.c b/linux/drivers/media/common/saa7146_i2c.c index 255b14551..f275846da 100644 --- a/linux/drivers/media/common/saa7146_i2c.c +++ b/linux/drivers/media/common/saa7146_i2c.c @@ -391,7 +391,8 @@ out: /* utility functions */ static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num) { - struct saa7146_dev* dev = i2c_get_adapdata(adapter); + struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter); + struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev); /* use helper function to transfer data */ return saa7146_i2c_transfer(dev, msg, num, adapter->retries); @@ -423,7 +424,7 @@ int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c if( NULL != i2c_adapter ) { BUG_ON(!i2c_adapter->class); - i2c_set_adapdata(i2c_adapter,dev); + i2c_set_adapdata(i2c_adapter, &dev->v4l2_dev); i2c_adapter->dev.parent = &dev->pci->dev; i2c_adapter->algo = &saa7146_algo; i2c_adapter->algo_data = NULL; diff --git a/linux/include/media/saa7146.h b/linux/include/media/saa7146.h index 689bc8ebd..8cb90d36e 100644 --- a/linux/include/media/saa7146.h +++ b/linux/include/media/saa7146.h @@ -149,6 +149,11 @@ struct saa7146_dev struct saa7146_dma d_rps1; }; +static inline struct saa7146_dev *to_saa7146_dev(struct v4l2_device *v4l2_dev) +{ + return container_of(v4l2_dev, struct saa7146_dev, v4l2_dev); +} + /* from saa7146_i2c.c */ int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c_adapter, u32 bitrate); -- cgit v1.2.3 From 735182acc722237aca3cd7c6e5fde27c965d8334 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 7 Feb 2009 11:45:08 +0100 Subject: saa7146: the adapter class will be NULL when v4l2_subdev is used. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/common/saa7146_i2c.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/common/saa7146_i2c.c b/linux/drivers/media/common/saa7146_i2c.c index f275846da..68674799b 100644 --- a/linux/drivers/media/common/saa7146_i2c.c +++ b/linux/drivers/media/common/saa7146_i2c.c @@ -422,8 +422,12 @@ int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c dev->i2c_bitrate = bitrate; saa7146_i2c_reset(dev); - if( NULL != i2c_adapter ) { + if (i2c_adapter) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) + /* For kernels > 2.6.22 it can actually be NULL + when v4l2_subdev is used. */ BUG_ON(!i2c_adapter->class); +#endif i2c_set_adapdata(i2c_adapter, &dev->v4l2_dev); i2c_adapter->dev.parent = &dev->pci->dev; i2c_adapter->algo = &saa7146_algo; -- cgit v1.2.3 From 24aa05d2510d2f036343fc58aa76658a4a6f66ac Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 7 Feb 2009 15:00:02 +0100 Subject: v4l2: prefill ident and revision from v4l2_dbg_chip_ident. From: Hans Verkuil Drivers that implement this always have to set the ident and revision to V4L2_IDENT_NONE and 0. Do this in the v4l2 core so drivers don't have to do this. Priority: normal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/v4l2-ioctl.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/v4l2-ioctl.c b/linux/drivers/media/video/v4l2-ioctl.c index 165bc9005..ec139df5c 100644 --- a/linux/drivers/media/video/v4l2-ioctl.c +++ b/linux/drivers/media/video/v4l2-ioctl.c @@ -24,6 +24,7 @@ #endif #include #include +#include #include #include "compat.h" @@ -1746,6 +1747,8 @@ static long __video_do_ioctl(struct file *file, if (!ops->vidioc_g_chip_ident) break; + p->ident = V4L2_IDENT_NONE; + p->revision = 0; ret = ops->vidioc_g_chip_ident(file, fh, p); if (!ret) dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision); -- cgit v1.2.3 From 2f363ae420765f2ca6c9a3263649936f10f25138 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 7 Feb 2009 15:18:05 +0100 Subject: saa7146: convert saa7146 and mxb in particular to v4l2_subdev. From: Hans Verkuil Modified mxb to load the i2c modules through v4l2_subdev. So no more probing. Modified tea6415c and tea6420 to use the standard routing ops to do the routing, rather than using private commands. Dropped the private commands from tda9840 (they were never used except during initialization of the module). Added saa7146 support for VIDIOC_DBG_G_CHIP_IDENT. Converted saa5246a and saa5249 to v4l2_subdev. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/common/saa7146_video.c | 25 ++- linux/drivers/media/video/mxb.c | 277 ++++++++++++----------------- linux/drivers/media/video/saa5246a.c | 74 +++++--- linux/drivers/media/video/saa5249.c | 75 +++++--- linux/drivers/media/video/tda9840.c | 79 ++------ linux/drivers/media/video/tda9840.h | 14 -- linux/drivers/media/video/tea6415c.c | 50 +++--- linux/drivers/media/video/tea6415c.h | 12 -- linux/drivers/media/video/tea6420.c | 66 ++++--- linux/drivers/media/video/tea6420.h | 27 +-- linux/include/media/v4l2-chip-ident.h | 18 ++ 11 files changed, 349 insertions(+), 368 deletions(-) delete mode 100644 linux/drivers/media/video/tda9840.h (limited to 'linux') diff --git a/linux/drivers/media/common/saa7146_video.c b/linux/drivers/media/common/saa7146_video.c index a0cf6dacf..6536853c1 100644 --- a/linux/drivers/media/common/saa7146_video.c +++ b/linux/drivers/media/common/saa7146_video.c @@ -1,4 +1,5 @@ #include +#include #include "compat.h" static int max_memory = 32; @@ -210,6 +211,7 @@ static struct v4l2_queryctrl controls[] = { .step = 1, .default_value = 128, .type = V4L2_CTRL_TYPE_INTEGER, + .flags = V4L2_CTRL_FLAG_SLIDER, },{ .id = V4L2_CID_CONTRAST, .name = "Contrast", @@ -218,6 +220,7 @@ static struct v4l2_queryctrl controls[] = { .step = 1, .default_value = 64, .type = V4L2_CTRL_TYPE_INTEGER, + .flags = V4L2_CTRL_FLAG_SLIDER, },{ .id = V4L2_CID_SATURATION, .name = "Saturation", @@ -226,15 +229,16 @@ static struct v4l2_queryctrl controls[] = { .step = 1, .default_value = 64, .type = V4L2_CTRL_TYPE_INTEGER, + .flags = V4L2_CTRL_FLAG_SLIDER, },{ .id = V4L2_CID_VFLIP, - .name = "Vertical flip", + .name = "Vertical Flip", .minimum = 0, .maximum = 1, .type = V4L2_CTRL_TYPE_BOOLEAN, },{ .id = V4L2_CID_HFLIP, - .name = "Horizontal flip", + .name = "Horizontal Flip", .minimum = 0, .maximum = 1, .type = V4L2_CTRL_TYPE_BOOLEAN, @@ -1113,6 +1117,22 @@ static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type ty return err; } +static int vidioc_g_chip_ident(struct file *file, void *__fh, + struct v4l2_dbg_chip_ident *chip) +{ + struct saa7146_fh *fh = __fh; + struct saa7146_dev *dev = fh->dev; + + chip->ident = V4L2_IDENT_NONE; + chip->revision = 0; + if (v4l2_chip_match_host(&chip->match)) { + chip->ident = V4L2_IDENT_SAA7146; + return 0; + } + return v4l2_device_call_until_err(&dev->v4l2_dev, 0, + core, g_chip_ident, chip); +} + #ifdef CONFIG_VIDEO_V4L1_COMPAT static int vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *mbuf) { @@ -1153,6 +1173,7 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = { .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay, .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay, .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, + .vidioc_g_chip_ident = vidioc_g_chip_ident, .vidioc_overlay = vidioc_overlay, .vidioc_g_fbuf = vidioc_g_fbuf, diff --git a/linux/drivers/media/video/mxb.c b/linux/drivers/media/video/mxb.c index e7b94e6b1..fda3b7581 100644 --- a/linux/drivers/media/video/mxb.c +++ b/linux/drivers/media/video/mxb.c @@ -33,9 +33,14 @@ #include "mxb.h" #include "tea6415c.h" #include "tea6420.h" -#include "tda9840.h" -#define I2C_SAA7111 0x24 +#define I2C_SAA5246A 0x11 +#define I2C_SAA7111A 0x24 +#define I2C_TDA9840 0x42 +#define I2C_TEA6415C 0x43 +#define I2C_TEA6420_1 0x4c +#define I2C_TEA6420_2 0x4d +#define I2C_TUNER 0x60 #define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) @@ -80,31 +85,29 @@ static struct { static int video_audio_connect[MXB_INPUTS] = { 0, 1, 3, 3 }; -/* these are the necessary input-output-pins for bringing one audio source -(see above) to the CD-output */ -static struct tea6420_multiplex TEA6420_cd[MXB_AUDIOS+1][2] = - { - {{1,1,0},{1,1,0}}, /* Tuner */ - {{5,1,0},{6,1,0}}, /* AUX 1 */ - {{4,1,0},{6,1,0}}, /* AUX 2 */ - {{3,1,0},{6,1,0}}, /* AUX 3 */ - {{1,1,0},{3,1,0}}, /* Radio */ - {{1,1,0},{2,1,0}}, /* CD-Rom */ - {{6,1,0},{6,1,0}} /* Mute */ - }; - -/* these are the necessary input-output-pins for bringing one audio source -(see above) to the line-output */ -static struct tea6420_multiplex TEA6420_line[MXB_AUDIOS+1][2] = - { - {{2,3,0},{1,2,0}}, - {{5,3,0},{6,2,0}}, - {{4,3,0},{6,2,0}}, - {{3,3,0},{6,2,0}}, - {{2,3,0},{3,2,0}}, - {{2,3,0},{2,2,0}}, - {{6,3,0},{6,2,0}} /* Mute */ - }; +/* These are the necessary input-output-pins for bringing one audio source + (see above) to the CD-output. Note that gain is set to 0 in this table. */ +static struct v4l2_routing TEA6420_cd[MXB_AUDIOS + 1][2] = { + { { 1, 1 }, { 1, 1 } }, /* Tuner */ + { { 5, 1 }, { 6, 1 } }, /* AUX 1 */ + { { 4, 1 }, { 6, 1 } }, /* AUX 2 */ + { { 3, 1 }, { 6, 1 } }, /* AUX 3 */ + { { 1, 1 }, { 3, 1 } }, /* Radio */ + { { 1, 1 }, { 2, 1 } }, /* CD-Rom */ + { { 6, 1 }, { 6, 1 } } /* Mute */ +}; + +/* These are the necessary input-output-pins for bringing one audio source + (see above) to the line-output. Note that gain is set to 0 in this table. */ +static struct v4l2_routing TEA6420_line[MXB_AUDIOS + 1][2] = { + { { 2, 3 }, { 1, 2 } }, + { { 5, 3 }, { 6, 2 } }, + { { 4, 3 }, { 6, 2 } }, + { { 3, 3 }, { 6, 2 } }, + { { 2, 3 }, { 3, 2 } }, + { { 2, 3 }, { 2, 2 } }, + { { 6, 3 }, { 6, 2 } } /* Mute */ +}; #define MAXCONTROLS 1 static struct v4l2_queryctrl mxb_controls[] = { @@ -118,12 +121,12 @@ struct mxb struct i2c_adapter i2c_adapter; - struct i2c_client *saa7111a; - struct i2c_client *tda9840; - struct i2c_client *tea6415c; - struct i2c_client *tuner; - struct i2c_client *tea6420_1; - struct i2c_client *tea6420_2; + struct v4l2_subdev *saa7111a; + struct v4l2_subdev *tda9840; + struct v4l2_subdev *tea6415c; + struct v4l2_subdev *tuner; + struct v4l2_subdev *tea6420_1; + struct v4l2_subdev *tea6420_2; int cur_mode; /* current audio mode (mono, stereo, ...) */ int cur_input; /* current input */ @@ -131,84 +134,54 @@ struct mxb struct v4l2_frequency cur_freq; /* current frequency the tuner is tuned to */ }; -static struct saa7146_extension extension; - -static int mxb_check_clients(struct device *dev, void *data) -{ - struct mxb *mxb = data; - struct i2c_client *client = i2c_verify_client(dev); - - if (!client) - return 0; - - if (I2C_ADDR_TEA6420_1 == client->addr) - mxb->tea6420_1 = client; - if (I2C_ADDR_TEA6420_2 == client->addr) - mxb->tea6420_2 = client; - if (I2C_TEA6415C_2 == client->addr) - mxb->tea6415c = client; - if (I2C_ADDR_TDA9840 == client->addr) - mxb->tda9840 = client; - if (I2C_SAA7111 == client->addr) - mxb->saa7111a = client; - if (0x60 == client->addr) - mxb->tuner = client; +#define saa7111a_call(mxb, o, f, args...) \ + v4l2_subdev_call(mxb->saa7111a, o, f, ##args) +#define tea6420_1_call(mxb, o, f, args...) \ + v4l2_subdev_call(mxb->tea6420_1, o, f, ##args) +#define tea6420_2_call(mxb, o, f, args...) \ + v4l2_subdev_call(mxb->tea6420_2, o, f, ##args) +#define tda9840_call(mxb, o, f, args...) \ + v4l2_subdev_call(mxb->tda9840, o, f, ##args) +#define tea6415c_call(mxb, o, f, args...) \ + v4l2_subdev_call(mxb->tea6415c, o, f, ##args) +#define tuner_call(mxb, o, f, args...) \ + v4l2_subdev_call(mxb->tuner, o, f, ##args) +#define call_all(dev, o, f, args...) \ + v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args) - return 0; -} +static struct saa7146_extension extension; -static int mxb_probe(struct saa7146_dev* dev) +static int mxb_probe(struct saa7146_dev *dev) { - struct mxb* mxb = NULL; - int result; - - result = request_module("saa7115"); - if (result < 0) { - printk("mxb: saa7111 i2c module not available.\n"); - return -ENODEV; - } - result = request_module("tea6420"); - if (result < 0) { - printk("mxb: tea6420 i2c module not available.\n"); - return -ENODEV; - } - result = request_module("tea6415c"); - if (result < 0) { - printk("mxb: tea6415c i2c module not available.\n"); - return -ENODEV; - } - result = request_module("tda9840"); - if (result < 0) { - printk("mxb: tda9840 i2c module not available.\n"); - return -ENODEV; - } - result = request_module("tuner"); - if (result < 0) { - printk("mxb: tuner i2c module not available.\n"); - return -ENODEV; - } + struct mxb *mxb = NULL; mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL); - if( NULL == mxb ) { + if (mxb == NULL) { DEB_D(("not enough kernel memory.\n")); return -ENOMEM; } - mxb->i2c_adapter = (struct i2c_adapter) { - .class = I2C_CLASS_TV_ANALOG, - }; - +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) + mxb->i2c_adapter.class = I2C_CLASS_TV_ANALOG; +#endif snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num); saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); - if(i2c_add_adapter(&mxb->i2c_adapter) < 0) { + if (i2c_add_adapter(&mxb->i2c_adapter) < 0) { DEB_S(("cannot register i2c-device. skipping.\n")); kfree(mxb); return -EFAULT; } - /* loop through all i2c-devices on the bus and look who is there */ - device_for_each_child(&mxb->i2c_adapter.dev, mxb, mxb_check_clients); + mxb->saa7111a = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "saa7115", "saa7111", I2C_SAA7111A); + mxb->tea6420_1 = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tea6420", "tea6420", I2C_TEA6420_1); + mxb->tea6420_2 = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tea6420", "tea6420", I2C_TEA6420_2); + mxb->tea6415c = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tea6415c", "tea6415c", I2C_TEA6415C); + mxb->tda9840 = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tda9840", "tda9840", I2C_TDA9840); + mxb->tuner = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tuner", "tuner", I2C_TUNER); + if (v4l2_i2c_new_subdev(&mxb->i2c_adapter, "saa5246a", "saa5246a", I2C_SAA5246A)) { + printk(KERN_INFO "mxb: found teletext decoder\n"); + } /* check if all devices are present */ if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c || @@ -296,47 +269,45 @@ static int mxb_init_done(struct saa7146_dev* dev) struct v4l2_routing route; int i = 0, err = 0; - struct tea6415c_multiplex vm; /* select video mode in saa7111a */ - mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_S_STD, &std); + saa7111a_call(mxb, tuner, s_std, std); /* select tuner-output on saa7111a */ i = 0; route.input = SAA7115_COMPOSITE0; route.output = SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS; - mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route); + saa7111a_call(mxb, video, s_routing, &route); /* select a tuner type */ tun_setup.mode_mask = T_ANALOG_TV; tun_setup.addr = ADDR_UNSET; tun_setup.type = TUNER_PHILIPS_PAL; - mxb->tuner->driver->command(mxb->tuner, TUNER_SET_TYPE_ADDR, &tun_setup); + tuner_call(mxb, tuner, s_type_addr, &tun_setup); /* tune in some frequency on tuner */ mxb->cur_freq.tuner = 0; mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV; mxb->cur_freq.frequency = freq; - mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, - &mxb->cur_freq); + tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq); /* set a default video standard */ - mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); + tuner_call(mxb, tuner, s_std, std); /* mute audio on tea6420s */ - mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_line[6][0]); - mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_line[6][1]); - mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_cd[6][0]); - mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_cd[6][1]); + tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[6][0]); + tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[6][1]); + tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[6][0]); + tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[6][1]); - /* switch to tuner-channel on tea6415c*/ - vm.out = 17; - vm.in = 3; - mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm); + /* switch to tuner-channel on tea6415c */ + route.input = 3; + route.output = 17; + tea6415c_call(mxb, video, s_routing, &route); - /* select tuner-output on multicable on tea6415c*/ - vm.in = 3; - vm.out = 13; - mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm); + /* select tuner-output on multicable on tea6415c */ + route.input = 3; + route.output = 13; + tea6415c_call(mxb, video, s_routing, &route); /* the rest for mxb */ mxb->cur_input = 0; @@ -462,14 +433,14 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc) mxb->cur_mute = vc->value; if (!vc->value) { /* switch the audio-source */ - mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, + tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[video_audio_connect[mxb->cur_input]][0]); - mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, + tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[video_audio_connect[mxb->cur_input]][1]); } else { - mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, + tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[6][0]); - mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, + tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[6][1]); } DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value)); @@ -500,7 +471,6 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input) { struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; struct mxb *mxb = (struct mxb *)dev->ext_priv; - struct tea6415c_multiplex vm; struct v4l2_routing route; int i = 0; @@ -519,16 +489,16 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input) switch (input) { case TUNER: i = SAA7115_COMPOSITE0; - vm.in = 3; - vm.out = 17; + route.input = 3; + route.output = 17; - if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) { + if (tea6415c_call(mxb, video, s_routing, &route)) { printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n"); return -EFAULT; } /* connect tuner-output always to multicable */ - vm.in = 3; - vm.out = 13; + route.input = 3; + route.output = 13; break; case AUX3_YC: /* nothing to be done here. aux3_yc is @@ -542,8 +512,8 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input) break; case AUX1: i = SAA7115_COMPOSITE0; - vm.in = 1; - vm.out = 17; + route.input = 1; + route.output = 17; break; } @@ -551,7 +521,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input) switch (input) { case TUNER: case AUX1: - if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) { + if (tea6415c_call(mxb, video, s_routing, &route)) { printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n"); return -EFAULT; } @@ -563,14 +533,14 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input) /* switch video in saa7111a */ route.input = i; route.output = 0; - if (mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route)) + if (saa7111a_call(mxb, video, s_routing, &route)) printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a #1.\n"); /* switch the audio-source only if necessary */ if (0 == mxb->cur_mute) { - mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, + tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[video_audio_connect[input]][0]); - mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, + tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[video_audio_connect[input]][1]); } @@ -590,14 +560,12 @@ static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t) DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index)); memset(t, 0, sizeof(*t)); - i2c_clients_command(&mxb->i2c_adapter, VIDIOC_G_TUNER, t); - strlcpy(t->name, "TV Tuner", sizeof(t->name)); t->type = V4L2_TUNER_ANALOG_TV; t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; t->audmode = mxb->cur_mode; - return 0; + return call_all(dev, tuner, g_tuner, t); } static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t) @@ -611,8 +579,7 @@ static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t) } mxb->cur_mode = t->audmode; - i2c_clients_command(&mxb->i2c_adapter, VIDIOC_S_TUNER, t); - return 0; + return call_all(dev, tuner, s_tuner, t); } static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f) @@ -653,7 +620,7 @@ static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency)); /* tune in desired frequency */ - mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq); + tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq); /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */ spin_lock(&dev->slock); @@ -688,19 +655,15 @@ static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a) static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) { struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct mxb *mxb = (struct mxb *)dev->ext_priv; - i2c_clients_command(&mxb->i2c_adapter, VIDIOC_DBG_G_REGISTER, reg); - return 0; + return call_all(dev, core, g_register, reg); } static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) { struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct mxb *mxb = (struct mxb *)dev->ext_priv; - i2c_clients_command(&mxb->i2c_adapter, VIDIOC_DBG_S_REGISTER, reg); - return 0; + return call_all(dev, core, s_register, reg); } #endif @@ -721,8 +684,8 @@ static long vidioc_default(struct file *file, void *fh, int cmd, void *arg) DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n", i)); - mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_cd[i][0]); - mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_cd[i][1]); + tea6420_1_call(mxb, audio, s_routing, &TEA6420_cd[i][0]); + tea6420_2_call(mxb, audio, s_routing, &TEA6420_cd[i][1]); return 0; } @@ -736,8 +699,8 @@ static long vidioc_default(struct file *file, void *fh, int cmd, void *arg) } DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n", i)); - mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_line[i][0]); - mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_line[i][1]); + tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[i][0]); + tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[i][1]); return 0; } @@ -792,13 +755,6 @@ static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data } } - i2c_use_client(mxb->tea6420_1); - i2c_use_client(mxb->tea6420_2); - i2c_use_client(mxb->tea6415c); - i2c_use_client(mxb->tda9840); - i2c_use_client(mxb->saa7111a); - i2c_use_client(mxb->tuner); - printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num); mxb_num++; @@ -812,13 +768,6 @@ static int mxb_detach(struct saa7146_dev *dev) DEB_EE(("dev:%p\n", dev)); - i2c_release_client(mxb->tea6420_1); - i2c_release_client(mxb->tea6420_2); - i2c_release_client(mxb->tea6415c); - i2c_release_client(mxb->tda9840); - i2c_release_client(mxb->saa7111a); - i2c_release_client(mxb->tuner); - saa7146_unregister_device(&mxb->video_dev,dev); if (MXB_BOARD_CAN_DO_VBI(dev)) saa7146_unregister_device(&mxb->vbi_dev, dev); @@ -835,8 +784,6 @@ static int mxb_detach(struct saa7146_dev *dev) static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard) { struct mxb *mxb = (struct mxb *)dev->ext_priv; - int zero = 0; - int one = 1; if (V4L2_STD_PAL_I == standard->id) { v4l2_std_id std = V4L2_STD_PAL_I; @@ -845,8 +792,8 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa /* set the 7146 gpio register -- I don't know what this does exactly */ saa7146_write(dev, GPIO_CTRL, 0x00404050); /* unset the 7111 gpio register -- I don't know what this does exactly */ - mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_GPIO, &zero); - mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); + saa7111a_call(mxb, core, s_gpio, 0); + tuner_call(mxb, tuner, s_std, std); } else { v4l2_std_id std = V4L2_STD_PAL_BG; @@ -854,8 +801,8 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa /* set the 7146 gpio register -- I don't know what this does exactly */ saa7146_write(dev, GPIO_CTRL, 0x00404050); /* set the 7111 gpio register -- I don't know what this does exactly */ - mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_GPIO, &one); - mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); + saa7111a_call(mxb, core, s_gpio, 1); + tuner_call(mxb, tuner, s_std, std); } return 0; } diff --git a/linux/drivers/media/video/saa5246a.c b/linux/drivers/media/video/saa5246a.c index be23b5bd5..d7faf20bc 100644 --- a/linux/drivers/media/video/saa5246a.c +++ b/linux/drivers/media/video/saa5246a.c @@ -46,10 +46,11 @@ #include #include #include -#include -#include +#include +#include +#include #include -#include +#include #include "compat.h" MODULE_AUTHOR("Michael Geng "); @@ -386,16 +387,27 @@ MODULE_LICENSE("GPL"); #define MINUTE_MAX 0x59 #define PAGE_MAX 0x8FF +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) +static unsigned short normal_i2c[] = { 0x11, I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD; +#endif struct saa5246a_device { + struct v4l2_subdev sd; + struct video_device *vdev; u8 pgbuf[NUM_DAUS][VTX_VIRTUALSIZE]; int is_searching[NUM_DAUS]; - struct i2c_client *client; unsigned long in_use; struct mutex lock; }; +static inline struct saa5246a_device *to_dev(struct v4l2_subdev *sd) +{ + return container_of(sd, struct saa5246a_device, sd); +} + static struct video_device saa_template; /* Declared near bottom */ /* @@ -404,12 +416,13 @@ static struct video_device saa_template; /* Declared near bottom */ static int i2c_sendbuf(struct saa5246a_device *t, int reg, int count, u8 *data) { + struct i2c_client *client = v4l2_get_subdevdata(&t->sd); char buf[64]; buf[0] = reg; memcpy(buf+1, data, count); - if(i2c_master_send(t->client, buf, count+1)==count+1) + if (i2c_master_send(client, buf, count + 1) == count + 1) return 0; return -1; } @@ -437,7 +450,9 @@ static int i2c_senddata(struct saa5246a_device *t, ...) */ static int i2c_getdata(struct saa5246a_device *t, int count, u8 *buf) { - if(i2c_master_recv(t->client, buf, count)!=count) + struct i2c_client *client = v4l2_get_subdevdata(&t->sd); + + if (i2c_master_recv(client, buf, count) != count) return -1; return 0; } @@ -962,9 +977,6 @@ static int saa5246a_open(struct file *file) { struct saa5246a_device *t = video_drvdata(file); - if (t->client == NULL) - return -ENODEV; - if (test_and_set_bit(0, &t->in_use)) return -EBUSY; @@ -1034,18 +1046,29 @@ static struct video_device saa_template = .minor = -1, }; -/* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END }; +static int saa5246a_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_SAA5246A, 0); +} + +static const struct v4l2_subdev_core_ops saa5246a_core_ops = { + .g_chip_ident = saa5246a_g_chip_ident, +}; + +static const struct v4l2_subdev_ops saa5246a_ops = { + .core = &saa5246a_core_ops, +}; -I2C_CLIENT_INSMOD; static int saa5246a_probe(struct i2c_client *client, const struct i2c_device_id *id) { int pgbuf; int err; - struct video_device *vd; struct saa5246a_device *t; + struct v4l2_subdev *sd; v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); @@ -1054,40 +1077,43 @@ static int saa5246a_probe(struct i2c_client *client, t = kzalloc(sizeof(*t), GFP_KERNEL); if (t == NULL) return -ENOMEM; + sd = &t->sd; + v4l2_i2c_subdev_init(sd, client, &saa5246a_ops); mutex_init(&t->lock); /* Now create a video4linux device */ - vd = video_device_alloc(); - if (vd == NULL) { + t->vdev = video_device_alloc(); + if (t->vdev == NULL) { kfree(t); return -ENOMEM; } - i2c_set_clientdata(client, vd); - memcpy(vd, &saa_template, sizeof(*vd)); + memcpy(t->vdev, &saa_template, sizeof(*t->vdev)); for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) { memset(t->pgbuf[pgbuf], ' ', sizeof(t->pgbuf[0])); t->is_searching[pgbuf] = false; } - video_set_drvdata(vd, t); + video_set_drvdata(t->vdev, t); /* Register it */ - err = video_register_device(vd, VFL_TYPE_VTX, -1); + err = video_register_device(t->vdev, VFL_TYPE_VTX, -1); if (err < 0) { kfree(t); - video_device_release(vd); + video_device_release(t->vdev); + t->vdev = NULL; return err; } - t->client = client; return 0; } static int saa5246a_remove(struct i2c_client *client) { - struct video_device *vd = i2c_get_clientdata(client); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct saa5246a_device *t = to_dev(sd); - video_unregister_device(vd); - kfree(video_get_drvdata(vd)); + video_unregister_device(t->vdev); + v4l2_device_unregister_subdev(sd); + kfree(t); return 0; } diff --git a/linux/drivers/media/video/saa5249.c b/linux/drivers/media/video/saa5249.c index eeb0edea4..12f48ebd3 100644 --- a/linux/drivers/media/video/saa5249.c +++ b/linux/drivers/media/video/saa5249.c @@ -50,16 +50,23 @@ #include #include #include -#include -#include +#include +#include +#include #include -#include +#include #include "compat.h" MODULE_AUTHOR("Michael Geng "); MODULE_DESCRIPTION("Philips SAA5249 Teletext decoder driver"); MODULE_LICENSE("GPL"); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) +static unsigned short normal_i2c[] = { 0x11, I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD; +#endif + #define VTX_VER_MAJ 1 #define VTX_VER_MIN 8 @@ -96,17 +103,23 @@ typedef struct { struct saa5249_device { + struct v4l2_subdev sd; + struct video_device *vdev; vdau_t vdau[NUM_DAUS]; /* Data for virtual DAUs (the 5249 only has one */ /* real DAU, so we have to simulate some more) */ int vtx_use_count; int is_searching[NUM_DAUS]; int disp_mode; int virtual_mode; - struct i2c_client *client; unsigned long in_use; struct mutex lock; }; +static inline struct saa5249_device *to_dev(struct v4l2_subdev *sd) +{ + return container_of(sd, struct saa5249_device, sd); +} + #define CCTWR 34 /* I²C write/read-address of vtx-chip */ #define CCTRD 35 @@ -148,12 +161,13 @@ static void jdelay(unsigned long delay) static int i2c_sendbuf(struct saa5249_device *t, int reg, int count, u8 *data) { + struct i2c_client *client = v4l2_get_subdevdata(&t->sd); char buf[64]; buf[0] = reg; memcpy(buf+1, data, count); - if (i2c_master_send(t->client, buf, count + 1) == count + 1) + if (i2c_master_send(client, buf, count + 1) == count + 1) return 0; return -1; } @@ -181,7 +195,9 @@ static int i2c_senddata(struct saa5249_device *t, ...) static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf) { - if(i2c_master_recv(t->client, buf, count)!=count) + struct i2c_client *client = v4l2_get_subdevdata(&t->sd); + + if (i2c_master_recv(client, buf, count) != count) return -1; return 0; } @@ -498,9 +514,6 @@ static int saa5249_open(struct file *file) struct saa5249_device *t = video_drvdata(file); int pgbuf; - if (t->client == NULL) - return -ENODEV; - if (test_and_set_bit(0, &t->in_use)) return -EBUSY; @@ -554,18 +567,28 @@ static struct video_device saa_template = .release = video_device_release, }; -/* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END }; +static int saa5249_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); -I2C_CLIENT_INSMOD; + return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA5249, 0); +} + +static const struct v4l2_subdev_core_ops saa5249_core_ops = { + .g_chip_ident = saa5249_g_chip_ident, +}; + +static const struct v4l2_subdev_ops saa5249_ops = { + .core = &saa5249_core_ops, +}; static int saa5249_probe(struct i2c_client *client, const struct i2c_device_id *id) { int pgbuf; int err; - struct video_device *vd; struct saa5249_device *t; + struct v4l2_subdev *sd; v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); @@ -574,16 +597,17 @@ static int saa5249_probe(struct i2c_client *client, t = kzalloc(sizeof(*t), GFP_KERNEL); if (t == NULL) return -ENOMEM; + sd = &t->sd; + v4l2_i2c_subdev_init(sd, client, &saa5249_ops); mutex_init(&t->lock); /* Now create a video4linux device */ - vd = kmalloc(sizeof(struct video_device), GFP_KERNEL); - if (vd == NULL) { + t->vdev = video_device_alloc(); + if (t->vdev == NULL) { kfree(client); return -ENOMEM; } - i2c_set_clientdata(client, vd); - memcpy(vd, &saa_template, sizeof(*vd)); + memcpy(t->vdev, &saa_template, sizeof(*t->vdev)); for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) { memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf)); @@ -594,26 +618,27 @@ static int saa5249_probe(struct i2c_client *client, t->vdau[pgbuf].stopped = true; t->is_searching[pgbuf] = false; } - video_set_drvdata(vd, t); + video_set_drvdata(t->vdev, t); /* Register it */ - err = video_register_device(vd, VFL_TYPE_VTX, -1); + err = video_register_device(t->vdev, VFL_TYPE_VTX, -1); if (err < 0) { kfree(t); - kfree(vd); + video_device_release(t->vdev); + t->vdev = NULL; return err; } - t->client = client; return 0; } static int saa5249_remove(struct i2c_client *client) { - struct video_device *vd = i2c_get_clientdata(client); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct saa5249_device *t = to_dev(sd); - video_unregister_device(vd); - kfree(video_get_drvdata(vd)); - kfree(vd); + video_unregister_device(t->vdev); + v4l2_device_unregister_subdev(sd); + kfree(t); return 0; } diff --git a/linux/drivers/media/video/tda9840.c b/linux/drivers/media/video/tda9840.c index d2178ad78..f6d27d581 100644 --- a/linux/drivers/media/video/tda9840.c +++ b/linux/drivers/media/video/tda9840.c @@ -30,8 +30,8 @@ #include #include #include -#include -#include "tda9840.h" +#include +#include #include "compat.h" MODULE_AUTHOR("Michael Hunold "); @@ -57,11 +57,11 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); #define TDA9840_SET_BOTH_R 0x16 #define TDA9840_SET_EXTERNAL 0x7a -/* addresses to scan, found only at 0x42 (7-Bit) */ -static unsigned short normal_i2c[] = { I2C_ADDR_TDA9840, I2C_CLIENT_END }; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) +static unsigned short normal_i2c[] = { 0x42, I2C_CLIENT_END }; -/* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; +#endif static void tda9840_write(struct v4l2_subdev *sd, u8 reg, u8 val) { @@ -138,60 +138,17 @@ static int tda9840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t) return 0; } -static long tda9840_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) +static int tda9840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { - int byte; - - switch (cmd) { - case TDA9840_LEVEL_ADJUST: - byte = *(int *)arg; - v4l2_dbg(1, debug, sd, "TDA9840_LEVEL_ADJUST: %d\n", byte); - - /* check for correct range */ - if (byte > 25 || byte < -20) - return -EINVAL; - - /* calculate actual value to set, see specs, page 18 */ - byte /= 5; - if (0 < byte) - byte += 0x8; - else - byte = -byte; - tda9840_write(sd, LEVEL_ADJUST, byte); - break; - - case TDA9840_STEREO_ADJUST: - byte = *(int *)arg; - v4l2_dbg(1, debug, sd, "TDA9840_STEREO_ADJUST: %d\n", byte); - - /* check for correct range */ - if (byte > 25 || byte < -24) - return -EINVAL; - - /* calculate actual value to set */ - byte /= 5; - if (0 < byte) - byte += 0x20; - else - byte = -byte; - - tda9840_write(sd, STEREO_ADJUST, byte); - break; - default: - return -ENOIOCTLCMD; - } - return 0; -} + struct i2c_client *client = v4l2_get_subdevdata(sd); -static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg) -{ - return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); + return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TDA9840, 0); } /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops tda9840_core_ops = { - .ioctl = tda9840_ioctl, + .g_chip_ident = tda9840_g_chip_ident, }; static const struct v4l2_subdev_tuner_ops tda9840_tuner_ops = { @@ -210,8 +167,6 @@ static int tda9840_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct v4l2_subdev *sd; - int result; - int byte; /* let's see whether this adapter can support what we need */ if (!i2c_check_functionality(client->adapter, @@ -228,15 +183,9 @@ static int tda9840_probe(struct i2c_client *client, v4l2_i2c_subdev_init(sd, client, &tda9840_ops); /* set initial values for level & stereo - adjustment, mode */ - byte = 0; - result = tda9840_ioctl(sd, TDA9840_LEVEL_ADJUST, &byte); - result |= tda9840_ioctl(sd, TDA9840_STEREO_ADJUST, &byte); + tda9840_write(sd, LEVEL_ADJUST, 0); + tda9840_write(sd, STEREO_ADJUST, 0); tda9840_write(sd, SWITCH, TDA9840_SET_STEREO); - if (result) { - v4l2_dbg(1, debug, sd, "could not initialize tda9840\n"); - kfree(sd); - return -ENODEV; - } return 0; } @@ -249,12 +198,15 @@ static int tda9840_remove(struct i2c_client *client) return 0; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) static int tda9840_legacy_probe(struct i2c_adapter *adapter) { /* Let's see whether this is a known adapter we can attach to. Prevents conflicts with tvaudio.c. */ return adapter->id == I2C_HW_SAA7146; } +#endif + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) static const struct i2c_device_id tda9840_id[] = { { "tda9840", 0 }, @@ -265,10 +217,11 @@ MODULE_DEVICE_TABLE(i2c, tda9840_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tda9840", - .command = tda9840_command, .probe = tda9840_probe, .remove = tda9840_remove, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) .legacy_probe = tda9840_legacy_probe, +#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) .id_table = tda9840_id, #endif diff --git a/linux/drivers/media/video/tda9840.h b/linux/drivers/media/video/tda9840.h deleted file mode 100644 index dc12ae7ca..000000000 --- a/linux/drivers/media/video/tda9840.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __INCLUDED_TDA9840__ -#define __INCLUDED_TDA9840__ - -#define I2C_ADDR_TDA9840 0x42 - -/* values may range between +2.5 and -2.0; - the value has to be multiplied with 10 */ -#define TDA9840_LEVEL_ADJUST _IOW('v',3,int) - -/* values may range between +2.5 and -2.4; - the value has to be multiplied with 10 */ -#define TDA9840_STEREO_ADJUST _IOW('v',4,int) - -#endif diff --git a/linux/drivers/media/video/tea6415c.c b/linux/drivers/media/video/tea6415c.c index 2e57dd281..eaf29bd90 100644 --- a/linux/drivers/media/video/tea6415c.c +++ b/linux/drivers/media/video/tea6415c.c @@ -32,7 +32,8 @@ #include #include #include -#include +#include +#include #include "tea6415c.h" #include "compat.h" @@ -45,25 +46,27 @@ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Debug level (0-1)"); -/* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */ -static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END }; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) +static unsigned short normal_i2c[] = { 0x03, 0x43, I2C_CLIENT_END }; -/* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; +#endif -/* makes a connection between the input-pin 'i' and the output-pin 'o' - for the tea6415c-client 'client' */ -static int switch_matrix(struct i2c_client *client, int i, int o) +/* makes a connection between the input-pin 'i' and the output-pin 'o' */ +static int tea6415c_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route) { + struct i2c_client *client = v4l2_get_subdevdata(sd); u8 byte = 0; + u32 i = route->input; + u32 o = route->output; int ret; - v4l_dbg(1, debug, client, "i=%d, o=%d\n", i, o); + v4l2_dbg(1, debug, sd, "i=%d, o=%d\n", i, o); /* check if the pins are valid */ if (0 == ((1 == i || 3 == i || 5 == i || 6 == i || 8 == i || 10 == i || 20 == i || 11 == i) && (18 == o || 17 == o || 16 == o || 15 == o || 14 == o || 13 == o))) - return -1; + return -EINVAL; /* to understand this, have a look at the tea6415c-specs (p.5) */ switch (o) { @@ -116,37 +119,33 @@ static int switch_matrix(struct i2c_client *client, int i, int o) ret = i2c_smbus_write_byte(client, byte); if (ret) { - v4l_dbg(1, debug, client, + v4l2_dbg(1, debug, sd, "i2c_smbus_write_byte() failed, ret:%d\n", ret); return -EIO; } return ret; } -static long tea6415c_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) +static int tea6415c_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { - if (cmd == TEA6415C_SWITCH) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct tea6415c_multiplex *v = (struct tea6415c_multiplex *)arg; + struct i2c_client *client = v4l2_get_subdevdata(sd); - return switch_matrix(client, v->in, v->out); - } - return -ENOIOCTLCMD; -} - -static int tea6415c_command(struct i2c_client *client, unsigned cmd, void *arg) -{ - return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); + return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6415C, 0); } /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops tea6415c_core_ops = { - .ioctl = tea6415c_ioctl, + .g_chip_ident = tea6415c_g_chip_ident, +}; + +static const struct v4l2_subdev_video_ops tea6415c_video_ops = { + .s_routing = tea6415c_s_routing, }; static const struct v4l2_subdev_ops tea6415c_ops = { .core = &tea6415c_core_ops, + .video = &tea6415c_video_ops, }; /* this function is called by i2c_probe */ @@ -177,12 +176,14 @@ static int tea6415c_remove(struct i2c_client *client) return 0; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) static int tea6415c_legacy_probe(struct i2c_adapter *adapter) { /* Let's see whether this is a known adapter we can attach to. Prevents conflicts with tvaudio.c. */ return adapter->id == I2C_HW_SAA7146; } +#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) static const struct i2c_device_id tea6415c_id[] = { @@ -194,10 +195,11 @@ MODULE_DEVICE_TABLE(i2c, tea6415c_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tea6415c", - .command = tea6415c_command, .probe = tea6415c_probe, .remove = tea6415c_remove, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) .legacy_probe = tea6415c_legacy_probe, +#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) .id_table = tea6415c_id, #endif diff --git a/linux/drivers/media/video/tea6415c.h b/linux/drivers/media/video/tea6415c.h index f84ed8005..3a47d6975 100644 --- a/linux/drivers/media/video/tea6415c.h +++ b/linux/drivers/media/video/tea6415c.h @@ -1,10 +1,6 @@ #ifndef __INCLUDED_TEA6415C__ #define __INCLUDED_TEA6415C__ -/* possible i2c-addresses */ -#define I2C_TEA6415C_1 0x03 -#define I2C_TEA6415C_2 0x43 - /* the tea6415c's design is quite brain-dead. although there are 8 inputs and 6 outputs, these aren't enumerated in any way. because I don't want to say "connect input pin 20 to output pin 17", I define @@ -28,12 +24,4 @@ #define TEA6415C_INPUT7 1 #define TEA6415C_INPUT8 11 -struct tea6415c_multiplex -{ - int in; /* input-pin */ - int out; /* output-pin */ -}; - -#define TEA6415C_SWITCH _IOW('v',1,struct tea6415c_multiplex) - #endif diff --git a/linux/drivers/media/video/tea6420.c b/linux/drivers/media/video/tea6420.c index 023952ae7..8bddef6d9 100644 --- a/linux/drivers/media/video/tea6420.c +++ b/linux/drivers/media/video/tea6420.c @@ -32,7 +32,8 @@ #include #include #include -#include +#include +#include #include "tea6420.h" #include "compat.h" @@ -45,24 +46,28 @@ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Debug level (0-1)"); -/* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */ -static unsigned short normal_i2c[] = { I2C_ADDR_TEA6420_1, I2C_ADDR_TEA6420_2, I2C_CLIENT_END }; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) +static unsigned short normal_i2c[] = { 0x4c, 0x4d, I2C_CLIENT_END }; -/* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; +#endif /* make a connection between the input 'i' and the output 'o' - with gain 'g' for the tea6420-client 'client' (note: i = 6 means 'mute') */ -static int tea6420_switch(struct i2c_client *client, int i, int o, int g) + with gain 'g' (note: i = 6 means 'mute') */ +static int tea6420_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route) { + struct i2c_client *client = v4l2_get_subdevdata(sd); + int i = route->input; + int o = route->output & 0xf; + int g = (route->output >> 4) & 0xf; u8 byte; int ret; - v4l_dbg(1, debug, client, "i=%d, o=%d, g=%d\n", i, o, g); + v4l2_dbg(1, debug, sd, "i=%d, o=%d, g=%d\n", i, o, g); /* check if the parameters are valid */ if (i < 1 || i > 6 || o < 1 || o > 4 || g < 0 || g > 6 || g % 2 != 0) - return -1; + return -EINVAL; byte = ((o - 1) << 5); byte |= (i - 1); @@ -84,37 +89,33 @@ static int tea6420_switch(struct i2c_client *client, int i, int o, int g) ret = i2c_smbus_write_byte(client, byte); if (ret) { - v4l_dbg(1, debug, client, + v4l2_dbg(1, debug, sd, "i2c_smbus_write_byte() failed, ret:%d\n", ret); return -EIO; } return 0; } -static long tea6420_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) +static int tea6420_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { - if (cmd == TEA6420_SWITCH) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct tea6420_multiplex *a = (struct tea6420_multiplex *)arg; + struct i2c_client *client = v4l2_get_subdevdata(sd); - return tea6420_switch(client, a->in, a->out, a->gain); - } - return -ENOIOCTLCMD; -} - -static int tea6420_command(struct i2c_client *client, unsigned cmd, void *arg) -{ - return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); + return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6420, 0); } /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops tea6420_core_ops = { - .ioctl = tea6420_ioctl, + .g_chip_ident = tea6420_g_chip_ident, +}; + +static const struct v4l2_subdev_audio_ops tea6420_audio_ops = { + .s_routing = tea6420_s_routing, }; static const struct v4l2_subdev_ops tea6420_ops = { .core = &tea6420_core_ops, + .audio = &tea6420_audio_ops, }; /* this function is called by i2c_probe */ @@ -131,20 +132,24 @@ static int tea6420_probe(struct i2c_client *client, v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); + sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); + if (sd == NULL) + return -ENOMEM; + v4l2_i2c_subdev_init(sd, client, &tea6420_ops); + /* set initial values: set "mute"-input to all outputs at gain 0 */ err = 0; for (i = 1; i < 5; i++) { - err += tea6420_switch(client, 6, i, 0); + struct v4l2_routing route; + + route.input = 6; + route.output = i; + err += tea6420_s_routing(sd, &route); } if (err) { v4l_dbg(1, debug, client, "could not initialize tea6420\n"); return -ENODEV; } - - sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); - if (sd == NULL) - return -ENOMEM; - v4l2_i2c_subdev_init(sd, client, &tea6420_ops); return 0; } @@ -157,12 +162,14 @@ static int tea6420_remove(struct i2c_client *client) return 0; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) static int tea6420_legacy_probe(struct i2c_adapter *adapter) { /* Let's see whether this is a known adapter we can attach to. Prevents conflicts with tvaudio.c. */ return adapter->id == I2C_HW_SAA7146; } +#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) static const struct i2c_device_id tea6420_id[] = { @@ -174,10 +181,11 @@ MODULE_DEVICE_TABLE(i2c, tea6420_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tea6420", - .command = tea6420_command, .probe = tea6420_probe, .remove = tea6420_remove, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) .legacy_probe = tea6420_legacy_probe, +#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) .id_table = tea6420_id, #endif diff --git a/linux/drivers/media/video/tea6420.h b/linux/drivers/media/video/tea6420.h index 5ef7c18e0..4aa3edb3e 100644 --- a/linux/drivers/media/video/tea6420.h +++ b/linux/drivers/media/video/tea6420.h @@ -1,17 +1,24 @@ #ifndef __INCLUDED_TEA6420__ #define __INCLUDED_TEA6420__ -/* possible addresses */ -#define I2C_ADDR_TEA6420_1 0x4c -#define I2C_ADDR_TEA6420_2 0x4d +/* input pins */ +#define TEA6420_OUTPUT1 1 +#define TEA6420_OUTPUT2 2 +#define TEA6420_OUTPUT3 3 +#define TEA6420_OUTPUT4 4 -struct tea6420_multiplex -{ - int in; /* input of audio switch */ - int out; /* output of audio switch */ - int gain; /* gain of connection */ -}; +/* output pins */ +#define TEA6420_INPUT1 1 +#define TEA6420_INPUT2 2 +#define TEA6420_INPUT3 3 +#define TEA6420_INPUT4 4 +#define TEA6420_INPUT5 5 +#define TEA6420_INPUT6 6 -#define TEA6420_SWITCH _IOW('v',1,struct tea6420_multiplex) +/* gain on the output pins, ORed with the output pin */ +#define TEA6420_GAIN0 0x00 +#define TEA6420_GAIN2 0x20 +#define TEA6420_GAIN4 0x40 +#define TEA6420_GAIN6 0x60 #endif diff --git a/linux/include/media/v4l2-chip-ident.h b/linux/include/media/v4l2-chip-ident.h index 9aaf652b2..4e2182e52 100644 --- a/linux/include/media/v4l2-chip-ident.h +++ b/linux/include/media/v4l2-chip-ident.h @@ -63,6 +63,9 @@ enum { V4L2_IDENT_OV7720 = 251, V4L2_IDENT_OV7725 = 252, + /* module saa7146: reserved range 300-309 */ + V4L2_IDENT_SAA7146 = 300, + /* Conexant MPEG encoder/decoders: reserved range 410-420 */ V4L2_IDENT_CX23415 = 415, V4L2_IDENT_CX23416 = 416, @@ -74,9 +77,21 @@ enum { /* module tvp5150 */ V4L2_IDENT_TVP5150 = 5150, + /* module saa5246a: just ident 5246 */ + V4L2_IDENT_SAA5246A = 5246, + + /* module saa5249: just ident 5249 */ + V4L2_IDENT_SAA5249 = 5249, + /* module cs5345: just ident 5345 */ V4L2_IDENT_CS5345 = 5345, + /* module tea6415c: just ident 6415 */ + V4L2_IDENT_TEA6415C = 6415, + + /* module tea6420: just ident 6420 */ + V4L2_IDENT_TEA6420 = 6420, + /* module saa6752hs: reserved range 6750-6759 */ V4L2_IDENT_SAA6752HS = 6752, V4L2_IDENT_SAA6752HS_AC3 = 6753, @@ -87,6 +102,9 @@ enum { /* module wm8775: just ident 8775 */ V4L2_IDENT_WM8775 = 8775, + /* module tda9840: just ident 9840 */ + V4L2_IDENT_TDA9840 = 9840, + /* module tw9910: just ident 9910 */ V4L2_IDENT_TW9910 = 9910, -- cgit v1.2.3 From 7a1cf2bbfb14fef2c4debf9f474cd0ed65a7c65e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 7 Feb 2009 15:25:05 +0100 Subject: saa7146: setting control while capturing should return EBUSY, not EINVAL. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/common/saa7146_video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/common/saa7146_video.c b/linux/drivers/media/common/saa7146_video.c index 6536853c1..240757afb 100644 --- a/linux/drivers/media/common/saa7146_video.c +++ b/linux/drivers/media/common/saa7146_video.c @@ -698,7 +698,7 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) if (IS_CAPTURE_ACTIVE(fh) != 0) { DEB_D(("V4L2_CID_HFLIP while active capture.\n")); mutex_unlock(&dev->lock); - return -EINVAL; + return -EBUSY; } vv->hflip = c->value; break; @@ -706,7 +706,7 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) if (IS_CAPTURE_ACTIVE(fh) != 0) { DEB_D(("V4L2_CID_VFLIP while active capture.\n")); mutex_unlock(&dev->lock); - return -EINVAL; + return -EBUSY; } vv->vflip = c->value; break; -- cgit v1.2.3 From 7c101a67fb72f74c1a2af5e2ab8e206a5fd9f5ff Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 8 Feb 2009 00:15:22 +0100 Subject: saa7146: prevent unnecessary loading of v4l2-common. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/common/saa7146_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/common/saa7146_video.c b/linux/drivers/media/common/saa7146_video.c index 240757afb..b7d73b7fd 100644 --- a/linux/drivers/media/common/saa7146_video.c +++ b/linux/drivers/media/common/saa7146_video.c @@ -1125,7 +1125,7 @@ static int vidioc_g_chip_ident(struct file *file, void *__fh, chip->ident = V4L2_IDENT_NONE; chip->revision = 0; - if (v4l2_chip_match_host(&chip->match)) { + if (chip->match.type == V4L2_CHIP_MATCH_HOST && !chip->match.addr) { chip->ident = V4L2_IDENT_SAA7146; return 0; } -- cgit v1.2.3 From b857ad615158d8e49953055fb34cd55050d5ebf2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 8 Feb 2009 00:42:33 +0100 Subject: saa7146: move v4l2 device registration to saa7146_vv. From: Hans Verkuil Doing the v4l2_device registration in the saa7146 core will make it dependent on v4l2, even for DVB-only boards. This registration and unregistration belongs in saa7146_vv instead. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/common/saa7146_core.c | 14 +++++++------- linux/drivers/media/common/saa7146_fops.c | 11 +++++++++-- 2 files changed, 16 insertions(+), 9 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/common/saa7146_core.c b/linux/drivers/media/common/saa7146_core.c index 067a1f282..dfb4915a8 100644 --- a/linux/drivers/media/common/saa7146_core.c +++ b/linux/drivers/media/common/saa7146_core.c @@ -367,16 +367,13 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent ERR(("out of memory.\n")); goto out; } - err = v4l2_device_register(&pci->dev, &dev->v4l2_dev); - if (err) - goto err_free; DEB_EE(("pci:%p\n",pci)); err = pci_enable_device(pci); if (err < 0) { ERR(("pci_enable_device() failed.\n")); - goto err_unreg; + goto err_free; } /* enable bus-mastering */ @@ -484,6 +481,10 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent DEB_D(("ext->attach() failed for %p. skipping device.\n",dev)); goto err_free_i2c; } + /* V4L extensions will set the pci drvdata to the v4l2_device in the + attach() above. So for those cards that do not use V4L we have to + set it explicitly. */ + pci_set_drvdata(pci, &dev->v4l2_dev); INIT_LIST_HEAD(&dev->item); list_add_tail(&dev->item,&saa7146_devices); @@ -510,8 +511,6 @@ err_release: pci_release_region(pci, 0); err_disable: pci_disable_device(pci); -err_unreg: - v4l2_device_unregister(&dev->v4l2_dev); err_free: kfree(dev); goto out; @@ -534,7 +533,8 @@ static void saa7146_remove_one(struct pci_dev *pdev) DEB_EE(("dev:%p\n",dev)); dev->ext->detach(dev); - v4l2_device_unregister(&dev->v4l2_dev); + /* Zero the PCI drvdata after use. */ + pci_set_drvdata(pdev, NULL); /* shut down all video dma transfers */ saa7146_write(dev, MC1, 0x00ff0000); diff --git a/linux/drivers/media/common/saa7146_fops.c b/linux/drivers/media/common/saa7146_fops.c index c6cc8574a..90e1d1ebb 100644 --- a/linux/drivers/media/common/saa7146_fops.c +++ b/linux/drivers/media/common/saa7146_fops.c @@ -447,11 +447,17 @@ static void vv_callback(struct saa7146_dev *dev, unsigned long status) int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) { - struct saa7146_vv *vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL); + struct saa7146_vv *vv; + int err; + + err = v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev); + if (err) + return err; + vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL); if (vv == NULL) { ERR(("out of memory. aborting.\n")); - return -1; + return -ENOMEM; } ext_vv->ops = saa7146_video_ioctl_ops; ext_vv->core_ops = &saa7146_video_ioctl_ops; @@ -497,6 +503,7 @@ int saa7146_vv_release(struct saa7146_dev* dev) DEB_EE(("dev:%p\n",dev)); + v4l2_device_unregister(&dev->v4l2_dev); pci_free_consistent(dev->pci, SAA7146_CLIPPING_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle); kfree(vv); dev->vv_data = NULL; -- cgit v1.2.3 From 2f8e6c790e74ada20db6965056476d944041fdfa Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 8 Feb 2009 11:45:34 -0200 Subject: em28xx: remove bad check (changeset a31c595188af) From: Douglas Schilling Landgraf Removed bad check. Thanks to Robert Krakora to report that. Priority: high Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/video/em28xx/em28xx-audio.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-audio.c b/linux/drivers/media/video/em28xx/em28xx-audio.c index fcf21a614..ebbc64b3a 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -62,7 +62,7 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev) int i; dprintk("Stopping isoc\n"); - for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { + for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { if (!irqs_disabled()) usb_kill_urb(dev->adev.urb[i]); else @@ -74,7 +74,6 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev) dev->adev.transfer_buffer[i] = NULL; } - dev->isoc_ctl.num_bufs = 0; return 0; } @@ -179,8 +178,6 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) dprintk("Starting isoc transfers\n"); - dev->isoc_ctl.num_bufs = 0; - for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { struct urb *urb; int j, k; @@ -222,19 +219,10 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC); if (errCode) { - if (dev->isoc_ctl.num_bufs == 0) { - usb_free_urb(dev->adev.urb[i]); - dev->adev.urb[i] = NULL; - kfree(dev->adev.transfer_buffer[i]); - dev->adev.transfer_buffer[i] = NULL; - } else - em28xx_isoc_audio_deinit(dev); + em28xx_isoc_audio_deinit(dev); return errCode; } - mutex_lock(&dev->lock); - dev->isoc_ctl.num_bufs++; - mutex_unlock(&dev->lock); } return 0; -- cgit v1.2.3 From 2bd11adc025f4c324d0eb2a9861bdf7589e3b74e Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 8 Feb 2009 14:09:11 -0200 Subject: em28xx: Fix for em28xx memory leak and function rename From: Robert Krakora Fix for em28xx memory leak and function rename Priority: high Signed-off-by: Robert Krakora Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/video/em28xx/em28xx-audio.c | 22 ++++++++++++++++++---- linux/drivers/media/video/em28xx/em28xx-core.c | 13 +++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-audio.c b/linux/drivers/media/video/em28xx/em28xx-audio.c index ebbc64b3a..8753398b0 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -57,7 +57,7 @@ MODULE_PARM_DESC(debug, "activates debug info"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; -static int em28xx_isoc_audio_deinit(struct em28xx *dev) +static int em28xx_deinit_isoc_audio(struct em28xx *dev) { int i; @@ -67,6 +67,7 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev) usb_kill_urb(dev->adev.urb[i]); else usb_unlink_urb(dev->adev.urb[i]); + usb_free_urb(dev->adev.urb[i]); dev->adev.urb[i] = NULL; @@ -100,6 +101,20 @@ static void em28xx_audio_isocirq(struct urb *urb) struct snd_pcm_substream *substream; struct snd_pcm_runtime *runtime; #endif + + switch (urb->status) { + case 0: /* success */ + case -ETIMEDOUT: /* NAK */ + break; + case -ECONNRESET: /* kill */ + case -ENOENT: + case -ESHUTDOWN: + return; + default: /* error */ + dprintk("urb completition error %d.\n", urb->status); + break; + } + if (dev->adev.capture_pcm_substream) { substream = dev->adev.capture_pcm_substream; runtime = substream->runtime; @@ -219,8 +234,7 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC); if (errCode) { - em28xx_isoc_audio_deinit(dev); - + em28xx_deinit_isoc_audio(dev); return errCode; } } @@ -240,7 +254,7 @@ static int em28xx_cmd(struct em28xx *dev, int cmd, int arg) em28xx_init_audio_isoc(dev); } else if (dev->adev.capture_stream == STREAM_ON && arg == 0) { dev->adev.capture_stream = STREAM_OFF; - em28xx_isoc_audio_deinit(dev); + em28xx_deinit_isoc_audio(dev); } else { printk(KERN_ERR "An underrun very likely occurred. " "Ignoring it.\n"); diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c index 15d86bc97..743215ca9 100644 --- a/linux/drivers/media/video/em28xx/em28xx-core.c +++ b/linux/drivers/media/video/em28xx/em28xx-core.c @@ -836,6 +836,19 @@ static void em28xx_irq_callback(struct urb *urb) struct em28xx *dev = container_of(dma_q, struct em28xx, vidq); int rc, i; + switch (urb->status) { + case 0: /* success */ + case -ETIMEDOUT: /* NAK */ + break; + case -ECONNRESET: /* kill */ + case -ENOENT: + case -ESHUTDOWN: + return; + default: /* error */ + em28xx_isocdbg("urb completition error %d.\n", urb->status); + break; + } + /* Copy data from URB */ spin_lock(&dev->slock); rc = dev->isoc_ctl.isoc_copy(dev, urb); -- cgit v1.2.3 From 96f4a3677c2e17fe91f9956779fad977ec6a8f8c Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 8 Feb 2009 14:10:39 -0200 Subject: em28xx: Fix for em28xx audio startup From: Robert Krakora Essentially if a snd_em28xx_capture_trigger() stop followed by a snd_em28xx_capture_trigger() start would not yield any data because there was some logic put in with an adev->shutdown variable which did not seem warranted in my humble opinion. It would cause snd_em28xx_capture_trigger start never to start up the audio stream until the device was closed and reopened again. Upon re-opening the device adev->shutdown is reset and audio data would again flow. Priority: high Signed-off-by: Robert Krakora Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/video/em28xx/em28xx-audio.c | 12 +----------- linux/drivers/media/video/em28xx/em28xx.h | 2 +- 2 files changed, 2 insertions(+), 12 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-audio.c b/linux/drivers/media/video/em28xx/em28xx-audio.c index 8753398b0..921ec190d 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -174,9 +174,6 @@ static void em28xx_audio_isocirq(struct urb *urb) } urb->status = 0; - if (dev->adev.shutdown) - return; - status = usb_submit_urb(urb, GFP_ATOMIC); if (status < 0) { em28xx_errdev("resubmit of audio urb failed (error=%i)\n", @@ -387,13 +384,6 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream) em28xx_audio_analog_set(dev); mutex_unlock(&dev->lock); - if (dev->adev.users == 0 && dev->adev.shutdown == 1) { - dprintk("audio users: %d\n", dev->adev.users); - dprintk("disabling audio stream!\n"); - dev->adev.shutdown = 0; - dprintk("released lock\n"); - em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0); - } return 0; } @@ -463,7 +453,7 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream, em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 1); return 0; case SNDRV_PCM_TRIGGER_STOP: - dev->adev.shutdown = 1; + em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0); return 0; default: return -EINVAL; diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index 1e2ffea54..f3d0d3184 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -430,7 +430,7 @@ struct em28xx_audio { struct snd_card *sndcard; #endif - int users, shutdown; + int users; enum em28xx_stream_state capture_stream; spinlock_t slock; }; -- cgit v1.2.3 From c06f528a6de5324f104965c8a90907211963e29e Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 8 Feb 2009 15:17:15 -0200 Subject: em28xx-audio: Add spinlock for trigger From: Douglas Schilling Landgraf Added spinlock for trigger session Priority: high Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/video/em28xx/em28xx-audio.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-audio.c b/linux/drivers/media/video/em28xx/em28xx-audio.c index 921ec190d..a5a28eb19 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -445,19 +445,27 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream, #endif { struct em28xx *dev = snd_pcm_substream_chip(substream); + int retval; dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START)? "start": "stop"); + + spin_lock(&dev->adev.slock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 1); - return 0; + retval = 0; + break; case SNDRV_PCM_TRIGGER_STOP: em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0); - return 0; + retval = 0; + break; default: - return -EINVAL; + retval = -EINVAL; } + + spin_unlock(&dev->adev.slock); + return retval; } #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 16) -- cgit v1.2.3 From 88f9e29eb77d77129e59b899af1ef9e462997409 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 8 Feb 2009 02:11:13 -0200 Subject: em28xx-audio: Add lock for users From: Douglas Schilling Landgraf Added lock for users count Priority: high Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/video/em28xx/em28xx-audio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-audio.c b/linux/drivers/media/video/em28xx/em28xx-audio.c index a5a28eb19..5102ff75f 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -356,7 +356,9 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) dprintk("changing alternate number to 7\n"); } + mutex_lock(&dev->lock); dev->adev.users++; + mutex_unlock(&dev->lock); snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); dev->adev.capture_pcm_substream = substream; @@ -375,12 +377,12 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream) #endif { struct em28xx *dev = snd_pcm_substream_chip(substream); - dev->adev.users--; dprintk("closing device\n"); dev->mute = 1; mutex_lock(&dev->lock); + dev->adev.users--; em28xx_audio_analog_set(dev); mutex_unlock(&dev->lock); -- cgit v1.2.3 From a24b83e8ea0f14b0f879c03a8d9547b6cb06e7e4 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 8 Feb 2009 02:16:32 -0200 Subject: em28xx-audio: replace printk with em28xx_errdev From: Alexey Klimov Patch removes printk and place em28xx_errdev macros to provide information about driver name to dmesg. Priority: normal Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/video/em28xx/em28xx-audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-audio.c b/linux/drivers/media/video/em28xx/em28xx-audio.c index 5102ff75f..1d665ba27 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -253,7 +253,7 @@ static int em28xx_cmd(struct em28xx *dev, int cmd, int arg) dev->adev.capture_stream = STREAM_OFF; em28xx_deinit_isoc_audio(dev); } else { - printk(KERN_ERR "An underrun very likely occurred. " + em28xx_errdev("An underrun very likely occurred. " "Ignoring it.\n"); } return 0; -- cgit v1.2.3 From 46b15827cbd9a9297b369049585c78e6e685aacd Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 8 Feb 2009 02:38:10 -0200 Subject: em28xx-audio: Add macros EM28XX_START_AUDIO / EM28XX_STOP_AUDIO From: Douglas Schilling Landgraf Added macros EM28XX_START_AUDIO and EM28XX_STOP_AUDIO for em28xx_cmd(). Priority: normal Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/video/em28xx/em28xx-audio.c | 10 +++++----- linux/drivers/media/video/em28xx/em28xx.h | 4 ++++ 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-audio.c b/linux/drivers/media/video/em28xx/em28xx-audio.c index 1d665ba27..e7dfebd7b 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -246,10 +246,10 @@ static int em28xx_cmd(struct em28xx *dev, int cmd, int arg) switch (cmd) { case EM28XX_CAPTURE_STREAM_EN: - if (dev->adev.capture_stream == STREAM_OFF && arg == 1) { + if (dev->adev.capture_stream == STREAM_OFF && arg == EM28XX_START_AUDIO) { dev->adev.capture_stream = STREAM_ON; em28xx_init_audio_isoc(dev); - } else if (dev->adev.capture_stream == STREAM_ON && arg == 0) { + } else if (dev->adev.capture_stream == STREAM_ON && arg == EM28XX_STOP_AUDIO) { dev->adev.capture_stream = STREAM_OFF; em28xx_deinit_isoc_audio(dev); } else { @@ -425,7 +425,7 @@ static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream) dprintk("Stop capture, if needed\n"); if (dev->adev.capture_stream == STREAM_ON) - em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0); + em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_STOP_AUDIO); return 0; } @@ -455,11 +455,11 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream, spin_lock(&dev->adev.slock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: - em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 1); + em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_START_AUDIO); retval = 0; break; case SNDRV_PCM_TRIGGER_STOP: - em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0); + em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_STOP_AUDIO); retval = 0; break; default: diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index f3d0d3184..81e7292ae 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -112,6 +112,10 @@ #define EM28XX_BOARD_NOT_VALIDATED 1 #define EM28XX_BOARD_VALIDATED 0 +/* Params for em28xx_cmd() audio */ +#define EM28XX_START_AUDIO 1 +#define EM28XX_STOP_AUDIO 0 + /* maximum number of em28xx boards */ #define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */ -- cgit v1.2.3 From ca4755f6e3b59333a7d5df3b7808d785bfb006b1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 8 Feb 2009 09:34:43 -0200 Subject: tda827x: Be sure that gate will be open/closed at the proper time From: Mauro Carvalho Chehab The gate control logic is broken: several routines just keep it open; other rotines close it properly; there are even other routines that assumes that it is open without really checking or opening it. Instead of having to manually handle the gate control and having such troubles, let a sub-routine take care of the gate, opening it before i2c_transfer and closing it after that. This avoids leaving the gate into a random state. Priority: normal CC: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/tuners/tda827x.c | 183 ++++++++++++++++------------ 1 file changed, 102 insertions(+), 81 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/common/tuners/tda827x.c b/linux/drivers/media/common/tuners/tda827x.c index a14fe817d..eb989c241 100644 --- a/linux/drivers/media/common/tuners/tda827x.c +++ b/linux/drivers/media/common/tuners/tda827x.c @@ -133,11 +133,31 @@ static const struct tda827x_data tda827x_table[] = { { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} }; +static int tuner_transfer(struct dvb_frontend *fe, + struct i2c_msg *msg, + const int size) +{ + int rc; + struct tda827x_priv *priv = fe->tuner_priv; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + rc = i2c_transfer(priv->i2c_adap, msg, size); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + if (rc >= 0 && rc != size) + return -EIO; + + return rc; +} + static int tda827xo_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { struct tda827x_priv *priv = fe->tuner_priv; u8 buf[14]; + int rc; struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, .buf = buf, .len = sizeof(buf) }; @@ -184,27 +204,29 @@ static int tda827xo_set_params(struct dvb_frontend *fe, buf[13] = 0x40; msg.len = 14; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) { - printk("%s: could not write to tuner at addr: 0x%02x\n", - __func__, priv->i2c_addr << 1); - return -EIO; - } + rc = tuner_transfer(fe, &msg, 1); + if (rc < 0) + goto err; + msleep(500); /* correct CP value */ buf[0] = 0x30; buf[1] = 0x50 + tda827x_table[i].cp; msg.len = 2; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - i2c_transfer(priv->i2c_adap, &msg, 1); + rc = tuner_transfer(fe, &msg, 1); + if (rc < 0) + goto err; priv->frequency = params->frequency; priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; return 0; + +err: + printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n", + __func__, priv->i2c_addr << 1); + return rc; } static int tda827xo_sleep(struct dvb_frontend *fe) @@ -215,9 +237,7 @@ static int tda827xo_sleep(struct dvb_frontend *fe) .buf = buf, .len = sizeof(buf) }; dprintk("%s:\n", __func__); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); if (priv->cfg && priv->cfg->sleep) priv->cfg->sleep(fe); @@ -267,44 +287,44 @@ static int tda827xo_set_analog_params(struct dvb_frontend *fe, msg.buf = tuner_reg; msg.len = 8; - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); msg.buf = reg2; msg.len = 2; reg2[0] = 0x80; reg2[1] = 0; - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); reg2[0] = 0x60; reg2[1] = 0xbf; - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); reg2[0] = 0x30; reg2[1] = tuner_reg[4] + 0x80; - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); msleep(1); reg2[0] = 0x30; reg2[1] = tuner_reg[4] + 4; - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); msleep(1); reg2[0] = 0x30; reg2[1] = tuner_reg[4]; - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); msleep(550); reg2[0] = 0x30; reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp; - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); reg2[0] = 0x60; reg2[1] = 0x3f; - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); reg2[0] = 0x80; reg2[1] = 0x08; /* Vsync en */ - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); priv->frequency = params->frequency; @@ -318,7 +338,7 @@ static void tda827xo_agcf(struct dvb_frontend *fe) struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, .buf = data, .len = 2}; - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); } /* ------------------------------------------------------------------ */ @@ -399,13 +419,8 @@ static int tda827xa_sleep(struct dvb_frontend *fe) .buf = buf, .len = sizeof(buf) }; dprintk("%s:\n", __func__); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - i2c_transfer(priv->i2c_adap, &msg, 1); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); + tuner_transfer(fe, &msg, 1); if (priv->cfg && priv->cfg->sleep) priv->cfg->sleep(fe); @@ -456,7 +471,7 @@ static void tda827xa_lna_gain(struct dvb_frontend *fe, int high, buf[1] = high ? 0 : 1; if (priv->cfg->config == 2) buf[1] = high ? 1 : 0; - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); break; case 3: /* switch with GPIO of saa713x */ if (fe->callback) @@ -475,7 +490,7 @@ static int tda827xa_set_params(struct dvb_frontend *fe, struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, .buf = buf, .len = sizeof(buf) }; - int i, tuner_freq, if_freq; + int i, tuner_freq, if_freq, rc; u32 N; dprintk("%s:\n", __func__); @@ -517,35 +532,32 @@ static int tda827xa_set_params(struct dvb_frontend *fe, buf[9] = 0x24; buf[10] = 0x00; msg.len = 11; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) { - printk("%s: could not write to tuner at addr: 0x%02x\n", - __func__, priv->i2c_addr << 1); - return -EIO; - } + rc = tuner_transfer(fe, &msg, 1); + if (rc < 0) + goto err; + buf[0] = 0x90; buf[1] = 0xff; buf[2] = 0x60; buf[3] = 0x00; buf[4] = 0x59; // lpsel, for 6MHz + 2 msg.len = 5; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - i2c_transfer(priv->i2c_adap, &msg, 1); + rc = tuner_transfer(fe, &msg, 1); + if (rc < 0) + goto err; buf[0] = 0xa0; buf[1] = 0x40; msg.len = 2; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - i2c_transfer(priv->i2c_adap, &msg, 1); + rc = tuner_transfer(fe, &msg, 1); + if (rc < 0) + goto err; msleep(11); msg.flags = I2C_M_RD; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - i2c_transfer(priv->i2c_adap, &msg, 1); + rc = tuner_transfer(fe, &msg, 1); + if (rc < 0) + goto err; msg.flags = 0; buf[1] >>= 4; @@ -554,49 +566,55 @@ static int tda827xa_set_params(struct dvb_frontend *fe, tda827xa_lna_gain(fe, 0, NULL); buf[0] = 0x60; buf[1] = 0x0c; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - i2c_transfer(priv->i2c_adap, &msg, 1); + rc = tuner_transfer(fe, &msg, 1); + if (rc < 0) + goto err; } buf[0] = 0xc0; buf[1] = 0x99; // lpsel, for 6MHz + 2 - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - i2c_transfer(priv->i2c_adap, &msg, 1); + rc = tuner_transfer(fe, &msg, 1); + if (rc < 0) + goto err; buf[0] = 0x60; buf[1] = 0x3c; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - i2c_transfer(priv->i2c_adap, &msg, 1); + rc = tuner_transfer(fe, &msg, 1); + if (rc < 0) + goto err; /* correct CP value */ buf[0] = 0x30; buf[1] = 0x10 + tda827xa_dvbt[i].scr; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - i2c_transfer(priv->i2c_adap, &msg, 1); + rc = tuner_transfer(fe, &msg, 1); + if (rc < 0) + goto err; msleep(163); buf[0] = 0xc0; buf[1] = 0x39; // lpsel, for 6MHz + 2 - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - i2c_transfer(priv->i2c_adap, &msg, 1); + rc = tuner_transfer(fe, &msg, 1); + if (rc < 0) + goto err; msleep(3); /* freeze AGC1 */ buf[0] = 0x50; buf[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - i2c_transfer(priv->i2c_adap, &msg, 1); + rc = tuner_transfer(fe, &msg, 1); + if (rc < 0) + goto err; priv->frequency = params->frequency; priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; + return 0; + +err: + printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n", + __func__, priv->i2c_addr << 1); + return rc; } @@ -644,7 +662,7 @@ static int tda827xa_set_analog_params(struct dvb_frontend *fe, tuner_reg[9] = 0x20; tuner_reg[10] = 0x00; msg.len = 11; - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); tuner_reg[0] = 0x90; tuner_reg[1] = 0xff; @@ -652,19 +670,19 @@ static int tda827xa_set_analog_params(struct dvb_frontend *fe, tuner_reg[3] = 0; tuner_reg[4] = 0x99 + (priv->lpsel << 1); msg.len = 5; - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); tuner_reg[0] = 0xa0; tuner_reg[1] = 0xc0; msg.len = 2; - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); tuner_reg[0] = 0x30; tuner_reg[1] = 0x10 + tda827xa_analog[i].scr; - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); msg.flags = I2C_M_RD; - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); msg.flags = 0; tuner_reg[1] >>= 4; dprintk("AGC2 gain is: %d\n", tuner_reg[1]); @@ -674,24 +692,24 @@ static int tda827xa_set_analog_params(struct dvb_frontend *fe, msleep(100); tuner_reg[0] = 0x60; tuner_reg[1] = 0x3c; - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); msleep(163); tuner_reg[0] = 0x50; tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4); - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); tuner_reg[0] = 0x80; tuner_reg[1] = 0x28; - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); tuner_reg[0] = 0xb0; tuner_reg[1] = 0x01; - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); tuner_reg[0] = 0xc0; tuner_reg[1] = 0x19 + (priv->lpsel << 1); - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); priv->frequency = params->frequency; @@ -704,7 +722,7 @@ static void tda827xa_agcf(struct dvb_frontend *fe) unsigned char data[] = {0x80, 0x2c}; struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0, .buf = data, .len = 2}; - i2c_transfer(priv->i2c_adap, &msg, 1); + tuner_transfer(fe, &msg, 1); } /* ------------------------------------------------------------------ */ @@ -793,16 +811,19 @@ static struct dvb_tuner_ops tda827xa_tuner_ops = { }; static int tda827x_probe_version(struct dvb_frontend *fe) -{ u8 data; +{ + u8 data; + int rc; struct tda827x_priv *priv = fe->tuner_priv; struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD, .buf = &data, .len = 1 }; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) { + + rc = tuner_transfer(fe, &msg, 1); + + if (rc < 0) { printk("%s: could not read from tuner at addr: 0x%02x\n", __func__, msg.addr << 1); - return -EIO; + return rc; } if ((data & 0x3c) == 0) { dprintk("tda827x tuner found\n"); -- cgit v1.2.3 From cde88dd58c4b1be925590b3b7f8d454cfd0d7441 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 8 Feb 2009 09:42:29 -0200 Subject: tda8290: Print an error if i2c_gate is not provided From: Mauro Carvalho Chehab While here, be sure that gate will be kept disabled if an error occurs. Priority: normal CC: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/tuners/tda8290.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/common/tuners/tda8290.c b/linux/drivers/media/common/tuners/tda8290.c index 67c0fd5f7..54423df4c 100644 --- a/linux/drivers/media/common/tuners/tda8290.c +++ b/linux/drivers/media/common/tuners/tda8290.c @@ -589,8 +589,11 @@ static int tda829x_find_tuner(struct dvb_frontend *fe) u8 data; struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 }; - if (NULL == analog_ops->i2c_gate_ctrl) + if (!analog_ops->i2c_gate_ctrl) { + printk(KERN_ERR "tda8290: no gate control were provided!\n"); + return -EINVAL; + } analog_ops->i2c_gate_ctrl(fe, 1); @@ -638,6 +641,7 @@ static int tda829x_find_tuner(struct dvb_frontend *fe) if (ret != 1) { tuner_warn("tuner access failed!\n"); + analog_ops->i2c_gate_ctrl(fe, 0); return -EREMOTEIO; } -- cgit v1.2.3 From 8e932048c503b5597b2bde42ef5f781d6dc9ae16 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 8 Feb 2009 09:50:50 -0200 Subject: saa7134: move tuner init code to saa7134-cards From: Mauro Carvalho Chehab On certain devices, before opening a tuner, we need to open the tuner gate via i2c. This patch just moves the tuner probing code to the same place where such i2c commands are handled, to make easier to fix this trouble on later patches. Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-cards.c | 24 +++++++++++++++++++++++ linux/drivers/media/video/saa7134/saa7134-core.c | 24 ----------------------- 2 files changed, 24 insertions(+), 24 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c index 9ad47eba4..be614fa88 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -6300,6 +6300,30 @@ int saa7134_board_init2(struct saa7134_dev *dev) unsigned char buf; int board; + /* initialize hardware #2 */ + if (TUNER_ABSENT != dev->tuner_type) { + int has_demod = (dev->tda9887_conf & TDA9887_PRESENT); + + /* Note: radio tuner address is always filled in, + so we do not need to probe for a radio tuner device. */ + if (dev->radio_type != UNSET) + v4l2_i2c_new_subdev(&dev->i2c_adap, + "tuner", "tuner", dev->radio_addr); + if (has_demod) + v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner", + "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); + if (dev->tuner_addr == ADDR_UNSET) { + enum v4l2_i2c_tuner_type type = + has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; + + v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner", + "tuner", v4l2_i2c_tuner_addrs(type)); + } else { + v4l2_i2c_new_subdev(&dev->i2c_adap, + "tuner", "tuner", dev->tuner_addr); + } + } + switch (dev->board) { case SAA7134_BOARD_BMK_MPEX_NOTUNER: case SAA7134_BOARD_BMK_MPEX_TUNER: diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c index 6e98c992c..78b5c8f3c 100644 --- a/linux/drivers/media/video/saa7134/saa7134-core.c +++ b/linux/drivers/media/video/saa7134/saa7134-core.c @@ -1034,30 +1034,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, /* wait a bit, register i2c bus */ msleep(100); saa7134_i2c_register(dev); - - /* initialize hardware #2 */ - if (TUNER_ABSENT != dev->tuner_type) { - int has_demod = (dev->tda9887_conf & TDA9887_PRESENT); - - /* Note: radio tuner address is always filled in, - so we do not need to probe for a radio tuner device. */ - if (dev->radio_type != UNSET) - v4l2_i2c_new_subdev(&dev->i2c_adap, - "tuner", "tuner", dev->radio_addr); - if (has_demod) - v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner", - "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); - if (dev->tuner_addr == ADDR_UNSET) { - enum v4l2_i2c_tuner_type type = - has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; - - v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner", - "tuner", v4l2_i2c_tuner_addrs(type)); - } else { - v4l2_i2c_new_subdev(&dev->i2c_adap, - "tuner", "tuner", dev->tuner_addr); - } - } saa7134_board_init2(dev); saa7134_hwinit2(dev); -- cgit v1.2.3 From 695dfe0ccd35ae13a124ba61bcedc089f536510a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 8 Feb 2009 10:33:15 -0200 Subject: saa7134: Fix analog mode on devices that need to open an i2c gate From: Mauro Carvalho Chehab Some saa7134 devices require to open an i2c gate before tuning. This patch fix the initialization for those devices. The nxt200x_gate_ctrl() logic were returned back to the old place, since we don't know how to close the gate. A future pacth could revert that change and provide the proper close gate control, to avoid keeping it open forever. Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-cards.c | 147 +++++++++++----------- 1 file changed, 77 insertions(+), 70 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c index be614fa88..01cc9543f 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -5995,32 +5995,6 @@ static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data) /* ----------------------------------------------------------- */ -static void nxt200x_gate_ctrl(struct saa7134_dev *dev, int open) -{ - /* enable tuner */ - int i; - static const u8 buffer [][2] = { - { 0x10, 0x12 }, - { 0x13, 0x04 }, - { 0x16, 0x00 }, - { 0x14, 0x04 }, - { 0x17, 0x00 }, - }; - - dev->i2c_client.addr = 0x0a; - - /* FIXME: don't know how to close the i2c gate on NXT200x */ - if (!open) - return; - - for (i = 0; i < ARRAY_SIZE(buffer); i++) - if (2 != i2c_master_send(&dev->i2c_client, - &buffer[i][0], ARRAY_SIZE(buffer[0]))) - printk(KERN_WARNING - "%s: Unable to enable tuner(%i).\n", - dev->name, i); -} - int saa7134_board_init1(struct saa7134_dev *dev) { /* Always print gpio, often manufacturers encode tuner type and other info. */ @@ -6218,10 +6192,6 @@ int saa7134_board_init1(struct saa7134_dev *dev) "are supported for now.\n", dev->name, card(dev).name, dev->name); break; - case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI: - case SAA7134_BOARD_KWORLD_ATSC110: - dev->gate_ctrl = nxt200x_gate_ctrl; - break; } return 0; } @@ -6300,33 +6270,20 @@ int saa7134_board_init2(struct saa7134_dev *dev) unsigned char buf; int board; - /* initialize hardware #2 */ - if (TUNER_ABSENT != dev->tuner_type) { - int has_demod = (dev->tda9887_conf & TDA9887_PRESENT); - - /* Note: radio tuner address is always filled in, - so we do not need to probe for a radio tuner device. */ - if (dev->radio_type != UNSET) - v4l2_i2c_new_subdev(&dev->i2c_adap, - "tuner", "tuner", dev->radio_addr); - if (has_demod) - v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner", - "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); - if (dev->tuner_addr == ADDR_UNSET) { - enum v4l2_i2c_tuner_type type = - has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; - - v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner", - "tuner", v4l2_i2c_tuner_addrs(type)); - } else { - v4l2_i2c_new_subdev(&dev->i2c_adap, - "tuner", "tuner", dev->tuner_addr); - } - } - + /* Put here the code that enables the chips that are needed + for analog mode and doesn't depend on the tuner attachment. + It is also a good idea to get tuner type from eeprom, etc before + initializing tuner, since we can avoid loading tuner driver + on devices that has TUNER_ABSENT + */ switch (dev->board) { case SAA7134_BOARD_BMK_MPEX_NOTUNER: case SAA7134_BOARD_BMK_MPEX_TUNER: + /* Checks if the device has a tuner at 0x60 addr + If the device doesn't have a tuner, TUNER_ABSENT + will be used at tuner_type, avoiding loading tuner + without needing it + */ dev->i2c_client.addr = 0x60; board = (i2c_master_recv(&dev->i2c_client, &buf, 0) < 0) ? SAA7134_BOARD_BMK_MPEX_NOTUNER @@ -6344,11 +6301,15 @@ int saa7134_board_init2(struct saa7134_dev *dev) u8 subaddr; u8 data[3]; int ret, tuner_t; - struct i2c_msg msg[] = {{.addr=0x50, .flags=0, .buf=&subaddr, .len = 1}, {.addr=0x50, .flags=I2C_M_RD, .buf=data, .len = 3}}; + subaddr= 0x14; tuner_t = 0; + + /* Retrieve device data from eeprom, checking for the + proper tuner_type. + */ ret = i2c_transfer(&dev->i2c_adap, msg, 2); if (ret != 2) { printk(KERN_ERR "EEPROM read failure\n"); @@ -6404,12 +6365,14 @@ int saa7134_board_init2(struct saa7134_dev *dev) dev->name, saa7134_boards[dev->board].name); break; } + /* break intentionally omitted */ case SAA7134_BOARD_VIDEOMATE_DVBT_300: case SAA7134_BOARD_ASUS_EUROPA2_HYBRID: { - /* The Philips EUROPA based hybrid boards have the tuner connected through - * the channel decoder. We have to make it transparent to find it + /* The Philips EUROPA based hybrid boards have the tuner + connected through the channel decoder. We have to make it + transparent to find it */ u8 data[] = { 0x07, 0x02}; struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; @@ -6430,21 +6393,15 @@ int saa7134_board_init2(struct saa7134_dev *dev) if (dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) { dev->tuner_type = TUNER_PHILIPS_TDA8290; - saa7134_tuner_setup(dev); - data[2] = 0x68; i2c_transfer(&dev->i2c_adap, &msg, 1); - - /* Tuner setup is handled before I2C transfer. - Due to that, there's no need to do it later - */ - return 0; + break; } i2c_transfer(&dev->i2c_adap, &msg, 1); break; } - case SAA7134_BOARD_ASUSTeK_TVFM7135: - /* The card below is detected as card=53, but is different */ + case SAA7134_BOARD_ASUSTeK_TVFM7135: + /* The card below is detected as card=53, but is different */ if (dev->autodetected && (dev->eedata[0x27] == 0x03)) { dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG; printk(KERN_INFO "%s: P7131 analog only, using " @@ -6515,9 +6472,9 @@ int saa7134_board_init2(struct saa7134_dev *dev) /* Don't do this if the board was specifically selected with an * insmod option or if we have the default configuration T200*/ - if(!dev->autodetected || (dev->eedata[0x41] == 0xd0)) + if (!dev->autodetected || (dev->eedata[0x41] == 0xd0)) break; - if(dev->eedata[0x41] == 0x02) { + if (dev->eedata[0x41] == 0x02) { /* Reconfigure board as T200A */ dev->board = SAA7134_BOARD_VIDEOMATE_DVBT_200A; dev->tuner_type = saa7134_boards[dev->board].tuner_type; @@ -6530,6 +6487,58 @@ int saa7134_board_init2(struct saa7134_dev *dev) break; } break; + case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI: + case SAA7134_BOARD_KWORLD_ATSC110: + { + struct i2c_msg msg = { .addr = 0x0a, .flags = 0 }; + int i; + static u8 buffer[][2] = { + { 0x10, 0x12 }, + { 0x13, 0x04 }, + { 0x16, 0x00 }, + { 0x14, 0x04 }, + { 0x17, 0x00 }, + }; + + for (i = 0; i < ARRAY_SIZE(buffer); i++) { + msg.buf = &buffer[i][0]; + msg.len = ARRAY_SIZE(buffer[0]); + if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) + printk(KERN_WARNING + "%s: Unable to enable tuner(%i).\n", + dev->name, i); + } + break; + } + } /* switch() */ + + /* initialize tuner */ + if (TUNER_ABSENT != dev->tuner_type) { + int has_demod = (dev->tda9887_conf & TDA9887_PRESENT); + + /* Note: radio tuner address is always filled in, + so we do not need to probe for a radio tuner device. */ + if (dev->radio_type != UNSET) + v4l2_i2c_new_subdev(&dev->i2c_adap, + "tuner", "tuner", dev->radio_addr); + if (has_demod) + v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner", + "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); + if (dev->tuner_addr == ADDR_UNSET) { + enum v4l2_i2c_tuner_type type = + has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; + + v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner", + "tuner", v4l2_i2c_tuner_addrs(type)); + } else { + v4l2_i2c_new_subdev(&dev->i2c_adap, + "tuner", "tuner", dev->tuner_addr); + } + } + + saa7134_tuner_setup(dev); + + switch (dev->board) { case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: { struct v4l2_priv_tun_config tea5767_cfg; @@ -6546,7 +6555,5 @@ int saa7134_board_init2(struct saa7134_dev *dev) } } /* switch() */ - saa7134_tuner_setup(dev); - return 0; } -- cgit v1.2.3 From 179db25fdf42f7df16cc1f2045211dcac5b08c2d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 9 Feb 2009 06:29:54 -0200 Subject: saa7134: Cleanup: remove unused waitqueue from struct From: Mauro Carvalho Chehab The waitqueue is never used. So, let's just remove it. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134.h | 1 - 1 file changed, 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h index 040f447c6..f681751ae 100644 --- a/linux/drivers/media/video/saa7134/saa7134.h +++ b/linux/drivers/media/video/saa7134/saa7134.h @@ -447,7 +447,6 @@ struct saa7134_dmasound { unsigned int bufsize; struct saa7134_pgtable pt; struct videobuf_dmabuf dma; - wait_queue_head_t wq; unsigned int dma_blk; unsigned int read_offset; unsigned int read_count; -- cgit v1.2.3 From 3b9a242cbd6a8f91f6a3f13baf4519353d48372a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 9 Feb 2009 06:33:54 -0200 Subject: saa7134-video: two int controls lack a step From: Mauro Carvalho Chehab Fix two broken controls where a step weren't specified. Without a step, userspace apps won't allow to adjust such controls. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-video.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7134/saa7134-video.c b/linux/drivers/media/video/saa7134/saa7134-video.c index 2180527b3..f3c170d23 100644 --- a/linux/drivers/media/video/saa7134/saa7134-video.c +++ b/linux/drivers/media/video/saa7134/saa7134-video.c @@ -452,6 +452,7 @@ static const struct v4l2_queryctrl video_ctrls[] = { .name = "y offset odd field", .minimum = 0, .maximum = 128, + .step = 1, .default_value = 0, .type = V4L2_CTRL_TYPE_INTEGER, },{ @@ -459,6 +460,7 @@ static const struct v4l2_queryctrl video_ctrls[] = { .name = "y offset even field", .minimum = 0, .maximum = 128, + .step = 1, .default_value = 0, .type = V4L2_CTRL_TYPE_INTEGER, },{ -- cgit v1.2.3 From 971e043fbd20b5614646918ed64a80c1fb0667f4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 9 Feb 2009 13:27:03 -0200 Subject: saa7134: get rid of KBL From: Mauro Carvalho Chehab KBL is not needed on saa7134, so, let's remove it. However, we should take some care to avoid opening the module while initializing it. This issue exists with newer udev's that opens a device as soon as the driver is registered. So, a proper lock is needed on open. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-core.c | 44 +++++++++++------------ linux/drivers/media/video/saa7134/saa7134-video.c | 14 ++++---- linux/drivers/media/video/saa7134/saa7134.h | 1 + 3 files changed, 30 insertions(+), 29 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c index 78b5c8f3c..d499064ee 100644 --- a/linux/drivers/media/video/saa7134/saa7134-core.c +++ b/linux/drivers/media/video/saa7134/saa7134-core.c @@ -86,8 +86,10 @@ MODULE_PARM_DESC(radio_nr, "radio device number"); MODULE_PARM_DESC(tuner, "tuner type"); MODULE_PARM_DESC(card, "card type"); -static DEFINE_MUTEX(devlist_lock); +DEFINE_MUTEX(saa7134_devlist_lock); +EXPORT_SYMBOL(saa7134_devlist_lock); LIST_HEAD(saa7134_devlist); +EXPORT_SYMBOL(saa7134_devlist); static LIST_HEAD(mops_list); static unsigned int saa7134_devcount; @@ -1052,6 +1054,18 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, v4l2_prio_init(&dev->prio); + mutex_lock(&saa7134_devlist_lock); + list_for_each_entry(mops, &mops_list, next) + mpeg_ops_attach(mops, dev); + list_add_tail(&dev->devlist, &saa7134_devlist); + mutex_unlock(&saa7134_devlist_lock); + + /* check for signal */ + saa7134_irq_video_signalchange(dev); + + if (TUNER_ABSENT != dev->tuner_type) + saa_call_all(dev, core, s_standby, 0); + /* register v4l devices */ if (saa7134_no_overlay > 0) printk(KERN_INFO "%s: Overlay support disabled.\n", dev->name); @@ -1089,21 +1103,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, /* everything worked */ saa7134_devcount++; - mutex_lock(&devlist_lock); - list_for_each_entry(mops, &mops_list, next) - mpeg_ops_attach(mops, dev); - list_add_tail(&dev->devlist,&saa7134_devlist); - mutex_unlock(&devlist_lock); - - /* check for signal */ - saa7134_irq_video_signalchange(dev); - - if (saa7134_dmasound_init && !dev->dmasound.priv_data) { + if (saa7134_dmasound_init && !dev->dmasound.priv_data) saa7134_dmasound_init(dev); - } - - if (TUNER_ABSENT != dev->tuner_type) - saa_call_all(dev, core, s_standby, 0); return 0; @@ -1154,11 +1155,11 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev) saa7134_hwfini(dev); /* unregister */ - mutex_lock(&devlist_lock); + mutex_lock(&saa7134_devlist_lock); list_del(&dev->devlist); list_for_each_entry(mops, &mops_list, next) mpeg_ops_detach(mops, dev); - mutex_unlock(&devlist_lock); + mutex_unlock(&saa7134_devlist_lock); saa7134_devcount--; saa7134_i2c_unregister(dev); @@ -1321,11 +1322,11 @@ int saa7134_ts_register(struct saa7134_mpeg_ops *ops) { struct saa7134_dev *dev; - mutex_lock(&devlist_lock); + mutex_lock(&saa7134_devlist_lock); list_for_each_entry(dev, &saa7134_devlist, devlist) mpeg_ops_attach(ops, dev); list_add_tail(&ops->next,&mops_list); - mutex_unlock(&devlist_lock); + mutex_unlock(&saa7134_devlist_lock); return 0; } @@ -1333,11 +1334,11 @@ void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops) { struct saa7134_dev *dev; - mutex_lock(&devlist_lock); + mutex_lock(&saa7134_devlist_lock); list_del(&ops->next); list_for_each_entry(dev, &saa7134_devlist, devlist) mpeg_ops_detach(ops, dev); - mutex_unlock(&devlist_lock); + mutex_unlock(&saa7134_devlist_lock); } EXPORT_SYMBOL(saa7134_ts_register); @@ -1381,7 +1382,6 @@ module_exit(saa7134_fini); /* ----------------------------------------------------------- */ EXPORT_SYMBOL(saa7134_set_gpio); -EXPORT_SYMBOL(saa7134_devlist); EXPORT_SYMBOL(saa7134_boards); /* ----------------- for the DMA sound modules --------------- */ diff --git a/linux/drivers/media/video/saa7134/saa7134-video.c b/linux/drivers/media/video/saa7134/saa7134-video.c index f3c170d23..be7f98bc0 100644 --- a/linux/drivers/media/video/saa7134/saa7134-video.c +++ b/linux/drivers/media/video/saa7134/saa7134-video.c @@ -1335,7 +1335,7 @@ static int video_open(struct file *file) enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; int radio = 0; - lock_kernel(); + mutex_lock(&saa7134_devlist_lock); list_for_each_entry(dev, &saa7134_devlist, devlist) { if (dev->video_dev && (dev->video_dev->minor == minor)) goto found; @@ -1348,19 +1348,20 @@ static int video_open(struct file *file) goto found; } } - unlock_kernel(); + mutex_unlock(&saa7134_devlist_lock); return -ENODEV; - found: + +found: + mutex_unlock(&saa7134_devlist_lock); dprintk("open minor=%d radio=%d type=%s\n",minor,radio, 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; - } + file->private_data = fh; fh->dev = dev; fh->radio = radio; @@ -1393,7 +1394,6 @@ static int video_open(struct file *file) /* switch to video/vbi mode */ video_mux(dev,dev->ctl_input); } - unlock_kernel(); return 0; } diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h index f681751ae..c9d4d4354 100644 --- a/linux/drivers/media/video/saa7134/saa7134.h +++ b/linux/drivers/media/video/saa7134/saa7134.h @@ -646,6 +646,7 @@ struct saa7134_dev { /* saa7134-core.c */ extern struct list_head saa7134_devlist; +extern struct mutex saa7134_devlist_lock; extern int saa7134_no_overlay; void saa7134_track_gpio(struct saa7134_dev *dev, char *msg); -- cgit v1.2.3 From ac487327990e64111a50dee1162658ea7b949645 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 9 Feb 2009 14:12:41 -0200 Subject: tda1004x: Fix eeprom firmware load on boards with 16MHz Xtal From: Mauro Carvalho Chehab For i2c normal work, we need to slow down the bus speed. However, the slow down breaks the eeprom firmware load. So, use normal speed for eeprom booting and then restore the i2c speed after that. It should also be noticed that no other I2C transfer should be in course while booting from eeprom, otherwise, tda10046 goes into an instable state. So, proper locking are needed at the i2c bus master. Tested with saa7134 MSI TV @nyware A/D board, that comes with an eeprom with firmware version 29. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/tda1004x.c | 30 ++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/tda1004x.c b/linux/drivers/media/dvb/frontends/tda1004x.c index 1465ff77b..4981cef8b 100644 --- a/linux/drivers/media/dvb/frontends/tda1004x.c +++ b/linux/drivers/media/dvb/frontends/tda1004x.c @@ -162,7 +162,7 @@ static int tda1004x_read_byte(struct tda1004x_state *state, int reg) if (ret != 2) { dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret); - return -1; + return -EINVAL; } dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__, @@ -481,16 +481,18 @@ static void tda10046_init_plls(struct dvb_frontend* fe) static int tda10046_fwupload(struct dvb_frontend* fe) { struct tda1004x_state* state = fe->demodulator_priv; - int ret; + int ret, confc4; const struct firmware *fw; /* reset + wake up chip */ if (state->config->xtal_freq == TDA10046_XTAL_4M) { - tda1004x_write_byteI(state, TDA1004X_CONFC4, 0); + confc4 = 0; } else { dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __func__); - tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80); + confc4 = 0x80; } + tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4); + tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0); /* set GPIO 1 and 3 */ if (state->config->gpio_config != TDA10046_GPTRI) { @@ -508,13 +510,29 @@ static int tda10046_fwupload(struct dvb_frontend* fe) if (tda1004x_check_upload_ok(state) == 0) return 0; + /* + For i2c normal work, we need to slow down the bus speed. + However, the slow down breaks the eeprom firmware load. + So, use normal speed for eeprom booting and then restore the + i2c speed after that. Tested with MSI TV @nyware A/D board, + that comes with firmware version 29 inside their eeprom. + + It should also be noticed that no other I2C transfer should + be in course while booting from eeprom, otherwise, tda10046 + goes into an instable state. So, proper locking are needed + at the i2c bus master. + */ printk(KERN_INFO "tda1004x: trying to boot from eeprom\n"); - tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4); + tda1004x_write_byteI(state, TDA1004X_CONFC4, 4); msleep(300); - /* don't re-upload unless necessary */ + tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4); + + /* Checks if eeprom firmware went without troubles */ if (tda1004x_check_upload_ok(state) == 0) return 0; + /* eeprom firmware didn't work. Load one manually. */ + if (state->config->request_firmware != NULL) { /* request the firmware, this will block until someone uploads it */ printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); -- cgit v1.2.3 From 5ebad183669c1c51f03b1a7273135d4a6135ce6a Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Tue, 10 Feb 2009 23:00:06 -0200 Subject: em28xx: Add DVC 101 model to Pinnacle Dazzle description From: Douglas Schilling Landgraf Added DVC 101 model to Pinnacle Dazzle description Priority: normal Signed-off-by: Douglas Schilling Landgraf --- linux/Documentation/video4linux/CARDLIST.em28xx | 2 +- linux/drivers/media/video/em28xx/em28xx-cards.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/Documentation/video4linux/CARDLIST.em28xx b/linux/Documentation/video4linux/CARDLIST.em28xx index f7a7f48f4..e67df4917 100644 --- a/linux/Documentation/video4linux/CARDLIST.em28xx +++ b/linux/Documentation/video4linux/CARDLIST.em28xx @@ -7,7 +7,7 @@ 6 -> Terratec Cinergy 200 USB (em2800) 7 -> Leadtek Winfast USB II (em2800) [0413:6023] 8 -> Kworld USB2800 (em2800) - 9 -> Pinnacle Dazzle DVC 90/DVC 100 (em2820/em2840) [2304:0207,2304:021a] + 9 -> Pinnacle Dazzle DVC 90/DVC 100/DVC 101 (em2820/em2840) [2304:0207,2304:021a] 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500] 11 -> Terratec Hybrid XS (em2880) [0ccd:0042] 12 -> Kworld PVR TV 2800 RF (em2820/em2840) diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index 608fa86e4..4db2ead66 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -957,7 +957,7 @@ struct em28xx_board em28xx_boards[] = { } }, }, [EM2820_BOARD_PINNACLE_DVC_90] = { - .name = "Pinnacle Dazzle DVC 90/DVC 100", + .name = "Pinnacle Dazzle DVC 90/DVC 100/DVC 101", .tuner_type = TUNER_ABSENT, /* capture only board */ .decoder = EM28XX_SAA711X, .input = { { -- cgit v1.2.3 From c6fd49ac8accb7a3252958a16ddf87fd216e694e Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Wed, 11 Feb 2009 00:28:24 -0200 Subject: em28xx: Coding style fixes and a typo correction From: Nicola Soranzo Lots of coding style fixes and a typo correction for em28xx. Priority: normal Signed-off-by: Nicola Soranzo [dougsland@redhat.com: fixed a reject due to a change on em28xx-audio.c] Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/video/em28xx/em28xx-audio.c | 8 ++--- linux/drivers/media/video/em28xx/em28xx-cards.c | 24 +++++++------- linux/drivers/media/video/em28xx/em28xx-core.c | 19 +++++------ linux/drivers/media/video/em28xx/em28xx-i2c.c | 6 ++-- linux/drivers/media/video/em28xx/em28xx-video.c | 43 ++++++++++++++----------- linux/drivers/media/video/em28xx/em28xx.h | 6 ++-- 6 files changed, 59 insertions(+), 47 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-audio.c b/linux/drivers/media/video/em28xx/em28xx-audio.c index e7dfebd7b..f37abcffa 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -263,8 +263,7 @@ static int em28xx_cmd(struct em28xx *dev, int cmd, int arg) } #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 16) -static int snd_pcm_alloc_vmalloc_buffer(snd_pcm_substream_t *subs, - size_t size) +static int snd_pcm_alloc_vmalloc_buffer(snd_pcm_substream_t *subs, size_t size) #else static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t size) @@ -276,7 +275,7 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, struct snd_pcm_runtime *runtime = subs->runtime; #endif - dprintk("Alocating vbuffer\n"); + dprintk("Allocating vbuffer\n"); if (runtime->dma_area) { if (runtime->dma_bytes > size) return 0; @@ -478,8 +477,7 @@ static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream *substream) #endif { - unsigned long flags; - + unsigned long flags; struct em28xx *dev; snd_pcm_uframes_t hwptr_done; diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index 4db2ead66..543fbb8e3 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -257,7 +257,7 @@ struct em28xx_board em28xx_boards[] = { .name = "Hauppauge WinTV USB 2", .tuner_type = TUNER_PHILIPS_FM1236_MK3, .tda9887_conf = TDA9887_PRESENT | - TDA9887_PORT1_ACTIVE| + TDA9887_PORT1_ACTIVE | TDA9887_PORT2_ACTIVE, .decoder = EM28XX_TVP5150, .has_msp34xx = 1, @@ -534,7 +534,7 @@ struct em28xx_board em28xx_boards[] = { }, [EM2861_BOARD_YAKUMO_MOVIE_MIXER] = { .name = "Yakumo MovieMixer", - .tuner_type = TUNER_ABSENT, /* Capture only device */ + .tuner_type = TUNER_ABSENT, /* Capture only device */ .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, @@ -902,11 +902,11 @@ struct em28xx_board em28xx_boards[] = { } }, }, [EM2800_BOARD_GRABBEEX_USB2800] = { - .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder", - .is_em2800 = 1, - .decoder = EM28XX_SAA711X, - .tuner_type = TUNER_ABSENT, /* capture only board */ - .input = { { + .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder", + .is_em2800 = 1, + .decoder = EM28XX_SAA711X, + .tuner_type = TUNER_ABSENT, /* capture only board */ + .input = { { .type = EM28XX_VMUX_COMPOSITE1, .vmux = SAA7115_COMPOSITE0, .amux = EM28XX_AMUX_LINE_IN, @@ -1282,7 +1282,9 @@ struct em28xx_board em28xx_boards[] = { .has_dvb = 1, .dvb_gpio = kworld_330u_digital, .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, - .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_EEPROM_ON_BOARD | EM28XX_I2C_EEPROM_KEY_VALID, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | + EM28XX_I2C_EEPROM_ON_BOARD | + EM28XX_I2C_EEPROM_KEY_VALID, .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = TVP5150_COMPOSITE0, @@ -1321,7 +1323,7 @@ struct em28xx_board em28xx_boards[] = { const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); /* table of devices that work with this driver */ -struct usb_device_id em28xx_id_table [] = { +struct usb_device_id em28xx_id_table[] = { { USB_DEVICE(0xeb1a, 0x2750), .driver_info = EM2750_BOARD_UNKNOWN }, { USB_DEVICE(0xeb1a, 0x2751), @@ -1425,7 +1427,7 @@ MODULE_DEVICE_TABLE(usb, em28xx_id_table); /* * EEPROM hash table for devices with generic USB IDs */ -static struct em28xx_hash_table em28xx_eeprom_hash [] = { +static struct em28xx_hash_table em28xx_eeprom_hash[] = { /* P/N: SA 60002070465 Tuner: TVF7533-MF */ {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF}, @@ -1457,7 +1459,7 @@ int em28xx_tuner_callback(void *ptr, int component, int command, int arg) } EXPORT_SYMBOL_GPL(em28xx_tuner_callback); -static void inline em28xx_set_model(struct em28xx *dev) +static inline void em28xx_set_model(struct em28xx *dev) { memcpy(&dev->board, &em28xx_boards[dev->model], sizeof(dev->board)); diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c index 743215ca9..f10abc5b4 100644 --- a/linux/drivers/media/video/em28xx/em28xx-core.c +++ b/linux/drivers/media/video/em28xx/em28xx-core.c @@ -33,8 +33,8 @@ /* #define ENABLE_DEBUG_ISOC_FRAMES */ static unsigned int core_debug; -module_param(core_debug,int,0644); -MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); +module_param(core_debug, int, 0644); +MODULE_PARM_DESC(core_debug, "enable debug messages [core]"); #define em28xx_coredbg(fmt, arg...) do {\ if (core_debug) \ @@ -42,8 +42,8 @@ MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); dev->name, __func__ , ##arg); } while (0) static unsigned int reg_debug; -module_param(reg_debug,int,0644); -MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]"); +module_param(reg_debug, int, 0644); +MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]"); #define em28xx_regdbg(fmt, arg...) do {\ if (reg_debug) \ @@ -77,7 +77,7 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, return -EINVAL; if (reg_debug) { - printk( KERN_DEBUG "(pipe 0x%08x): " + printk(KERN_DEBUG "(pipe 0x%08x): " "IN: %02x %02x %02x %02x %02x %02x %02x %02x ", pipe, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, @@ -154,7 +154,7 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, if (reg_debug) { int byte; - printk( KERN_DEBUG "(pipe 0x%08x): " + printk(KERN_DEBUG "(pipe 0x%08x): " "OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>", pipe, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, @@ -462,7 +462,8 @@ int em28xx_audio_analog_set(struct em28xx *dev) if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) { int sel = ac97_return_record_select(dev->ctl_aoutput); - /* Use the same input for both left and right channels */ + /* Use the same input for both left and right + channels */ sel |= (sel << 8); em28xx_write_ac97(dev, AC97_RECORD_SELECT, sel); @@ -698,7 +699,7 @@ static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2); /* it seems that both H and V scalers must be active to work correctly */ - mode = (h || v)? 0x30: 0x00; + mode = (h || v) ? 0x30 : 0x00; } return em28xx_write_reg_bits(dev, EM28XX_R26_COMPR, mode, 0x30); } @@ -967,7 +968,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets, em28xx_err("unable to allocate %i bytes for transfer" " buffer %i%s\n", sb_size, i, - in_interrupt()?" while in int":""); + in_interrupt() ? " while in int" : ""); em28xx_uninit_isoc(dev); return -ENOMEM; } diff --git a/linux/drivers/media/video/em28xx/em28xx-i2c.c b/linux/drivers/media/video/em28xx/em28xx-i2c.c index 7084728eb..1bdcf2500 100644 --- a/linux/drivers/media/video/em28xx/em28xx-i2c.c +++ b/linux/drivers/media/video/em28xx/em28xx-i2c.c @@ -402,10 +402,12 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) dev->name); break; case 2: - printk(KERN_INFO "%s:\tI2S audio, sample rate=32k\n", dev->name); + printk(KERN_INFO "%s:\tI2S audio, sample rate=32k\n", + dev->name); break; case 3: - printk(KERN_INFO "%s:\tI2S audio, 3 sample rates\n", dev->name); + printk(KERN_INFO "%s:\tI2S audio, 3 sample rates\n", + dev->name); break; } diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index 50c3af538..448a02b04 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -186,7 +186,8 @@ static void em28xx_copy_video(struct em28xx *dev, em28xx_isocdbg("Overflow of %zi bytes past buffer end (1)\n", ((char *)startwrite + lencopy) - ((char *)outp + buf->vb.size)); - lencopy = remain = (char *)outp + buf->vb.size - (char *)startwrite; + remain = (char *)outp + buf->vb.size - (char *)startwrite; + lencopy = remain; } if (lencopy <= 0) return; @@ -202,7 +203,8 @@ static void em28xx_copy_video(struct em28xx *dev, else lencopy = bytesperline; - if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) { + if ((char *)startwrite + lencopy > (char *)outp + + buf->vb.size) { em28xx_isocdbg("Overflow of %zi bytes past buffer end (2)\n", ((char *)startwrite + lencopy) - ((char *)outp + buf->vb.size)); @@ -351,7 +353,7 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb) } if (p[0] == 0x22 && p[1] == 0x5a) { em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2], - len, (p[2] & 1)? "odd" : "even"); + len, (p[2] & 1) ? "odd" : "even"); if (!(p[2] & 1)) { if (buf != NULL) @@ -480,7 +482,9 @@ fail: static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) { - struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); + struct em28xx_buffer *buf = container_of(vb, + struct em28xx_buffer, + vb); struct em28xx_fh *fh = vq->priv_data; struct em28xx *dev = fh->dev; struct em28xx_dmaqueue *vidq = &dev->vidq; @@ -493,7 +497,9 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb) { - struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); + struct em28xx_buffer *buf = container_of(vb, + struct em28xx_buffer, + vb); struct em28xx_fh *fh = vq->priv_data; struct em28xx *dev = (struct em28xx *)fh->dev; @@ -561,7 +567,7 @@ static int res_get(struct em28xx_fh *fh) static int res_check(struct em28xx_fh *fh) { - return (fh->stream_on); + return fh->stream_on; } static void res_free(struct em28xx_fh *fh) @@ -795,7 +801,7 @@ out: return rc; } -static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm) +static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; @@ -1483,7 +1489,7 @@ static int vidioc_reqbufs(struct file *file, void *priv, if (rc < 0) return rc; - return (videobuf_reqbufs(&fh->vb_vidq, rb)); + return videobuf_reqbufs(&fh->vb_vidq, rb); } static int vidioc_querybuf(struct file *file, void *priv, @@ -1497,7 +1503,7 @@ static int vidioc_querybuf(struct file *file, void *priv, if (rc < 0) return rc; - return (videobuf_querybuf(&fh->vb_vidq, b)); + return videobuf_querybuf(&fh->vb_vidq, b); } static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) @@ -1510,7 +1516,7 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) if (rc < 0) return rc; - return (videobuf_qbuf(&fh->vb_vidq, b)); + return videobuf_qbuf(&fh->vb_vidq, b); } static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) @@ -1523,8 +1529,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) if (rc < 0) return rc; - return (videobuf_dqbuf(&fh->vb_vidq, b, - file->f_flags & O_NONBLOCK)); + return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK); } #ifdef CONFIG_VIDEO_V4L1_COMPAT @@ -1848,7 +1853,7 @@ em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count, * em28xx_v4l2_poll() * will allocate buffers when called for the first time */ -static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait) +static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait) { struct em28xx_fh *fh = filp->private_data; struct em28xx *dev = fh->dev; @@ -2006,8 +2011,8 @@ static struct video_device em28xx_radio_template = { static struct video_device *em28xx_vdev_init(struct em28xx *dev, - const struct video_device *template, - const char *type_name) + const struct video_device *template, + const char *type_name) { struct video_device *vfd; @@ -2057,8 +2062,9 @@ int em28xx_register_analog_devices(struct em28xx *dev) /* enable vbi capturing */ /* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */ - val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK); - em28xx_write_reg(dev, EM28XX_R0F_XCLK, (EM28XX_XCLK_AUDIO_UNMUTE | val)); + val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK); + em28xx_write_reg(dev, EM28XX_R0F_XCLK, + (EM28XX_XCLK_AUDIO_UNMUTE | val)); em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51); #endif @@ -2094,7 +2100,8 @@ int em28xx_register_analog_devices(struct em28xx *dev) } if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) { - dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio"); + dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, + "radio"); if (!dev->radio_dev) { em28xx_errdev("cannot allocate video_device.\n"); return -ENODEV; diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index 81e7292ae..a83a36f49 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -160,7 +160,8 @@ */ /* time to wait when stopping the isoc transfer */ -#define EM28XX_URB_TIMEOUT msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS) +#define EM28XX_URB_TIMEOUT \ + msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS) /* time in msecs to wait for i2c writes to finish */ #define EM2800_I2C_WRITE_TIMEOUT 20 @@ -537,7 +538,8 @@ struct em28xx { int num_alt; /* Number of alternative settings */ unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */ - char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */ + char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc + transfer */ char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */ /* helper funcs that call usb_control_msg */ -- cgit v1.2.3 From c192ce009da1f0d6917e4d183859cf21b9c15896 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Wed, 11 Feb 2009 12:13:05 -0200 Subject: em28xx: support added for IO-DATA GV/MVP SZ - EMPIA-2820 chipset From: Indika Katugampala Priority: normal Signed-off-by: Indika Katugampala [dougsland@redhat.com: Fixed CodingStyle] Signed-off-by: Douglas Schilling Landgraf --- linux/Documentation/video4linux/CARDLIST.em28xx | 1 + linux/drivers/media/video/em28xx/em28xx-cards.c | 32 +++++++++++++++++++++++++ linux/drivers/media/video/em28xx/em28xx.h | 1 + 3 files changed, 34 insertions(+) (limited to 'linux') diff --git a/linux/Documentation/video4linux/CARDLIST.em28xx b/linux/Documentation/video4linux/CARDLIST.em28xx index 69601089f..f97c8533d 100644 --- a/linux/Documentation/video4linux/CARDLIST.em28xx +++ b/linux/Documentation/video4linux/CARDLIST.em28xx @@ -61,3 +61,4 @@ 62 -> Gadmei TVR200 (em2820/em2840) 63 -> Kaiomy TVnPC U2 (em2860) [eb1a:e303] 64 -> Easy Cap Capture DC-60 (em2860) + 65 -> IO-DATA GV-MVP/SZ (em2820/em2840) [04bb:0515] diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index 8e285fc84..d69000674 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -1362,6 +1362,26 @@ struct em28xx_board em28xx_boards[] = { .amux = EM28XX_AMUX_LINE_IN, } }, }, + [EM2820_BOARD_IODATA_GVMVP_SZ] = { + .name = "IO-DATA GV-MVP/SZ", + .tuner_type = TUNER_PHILIPS_FM1236_MK3, + .tuner_gpio = default_tuner_gpio, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = EM28XX_AMUX_VIDEO, + }, { /* Composite has not been tested yet */ + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = EM28XX_AMUX_VIDEO, + }, { /* S-video has not been tested yet */ + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = EM28XX_AMUX_VIDEO, + } }, + }, }; const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); @@ -1465,6 +1485,8 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII }, { USB_DEVICE(0x093b, 0xa005), .driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U }, + { USB_DEVICE(0x04bb, 0x0515), + .driver_info = EM2820_BOARD_IODATA_GVMVP_SZ }, { }, }; MODULE_DEVICE_TABLE(usb, em28xx_id_table); @@ -1658,6 +1680,16 @@ void em28xx_pre_card_setup(struct em28xx *dev) em28xx_write_regs(dev, 0x08, "\xf8", 1); break; + case EM2820_BOARD_IODATA_GVMVP_SZ: + em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff); + msleep(70); + em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7); + msleep(10); + em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); + msleep(70); + em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); + msleep(70); + break; } em28xx_gpio_set(dev, dev->board.tuner_gpio); diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index a0128819d..4aebda6c7 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -102,6 +102,7 @@ #define EM2820_BOARD_GADMEI_TVR200 62 #define EM2860_BOARD_KAIOMY_TVNPC_U2 63 #define EM2860_BOARD_EASYCAP 64 +#define EM2820_BOARD_IODATA_GVMVP_SZ 65 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v1.2.3 From ca22e13799e2e82ead5bed32cb6bf61bfd0a262a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 11 Feb 2009 15:13:20 -0200 Subject: em28xx: Add support for Kaiomy TVnPC U2 stick From: Mauro Carvalho Chehab Thanks to Peter Senna Tschudin for borrow me one of those devices. Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/Documentation/video4linux/CARDLIST.em28xx | 1 + linux/drivers/media/video/em28xx/em28xx-cards.c | 43 +++++++++++++++++++++++++ linux/drivers/media/video/em28xx/em28xx.h | 1 + 3 files changed, 45 insertions(+) (limited to 'linux') diff --git a/linux/Documentation/video4linux/CARDLIST.em28xx b/linux/Documentation/video4linux/CARDLIST.em28xx index f7a7f48f4..e914b1374 100644 --- a/linux/Documentation/video4linux/CARDLIST.em28xx +++ b/linux/Documentation/video4linux/CARDLIST.em28xx @@ -57,5 +57,6 @@ 57 -> Kworld PlusTV HD Hybrid 330 (em2883) [eb1a:a316] 58 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041] 60 -> Hauppauge WinTV HVR 850 (em2883) [2040:651f] + 61 -> Kaiomy TVnPC U2 (em2860) [eb1a:e303] 61 -> Pixelview PlayTV Box 4 USB 2.0 (em2820/em2840) 62 -> Gadmei TVR200 (em2820/em2840) diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index 608fa86e4..12f52803a 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -1317,6 +1317,33 @@ struct em28xx_board em28xx_boards[] = { .amux = EM28XX_AMUX_LINE_IN, } }, }, + [EM2860_BOARD_KAIOMY_TVNPC_U2] = { + .name = "Kaiomy TVnPC U2", + .vchannels = 3, + .tuner_type = TUNER_XC2028, + .tuner_addr = 0x61, + .mts_firmware = 1, + .decoder = EM28XX_TVP5150, + .tuner_gpio = default_tuner_gpio, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = EM28XX_AMUX_VIDEO, + + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = EM28XX_AMUX_LINE_IN, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = EM28XX_AMUX_LINE_IN, + } }, + .radio = { + .type = EM28XX_RADIO, + .amux = EM28XX_AMUX_LINE_IN, + } + } }; const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); @@ -1344,6 +1371,8 @@ struct usb_device_id em28xx_id_table [] = { .driver_info = EM2820_BOARD_UNKNOWN }, { USB_DEVICE(0xeb1a, 0xe300), .driver_info = EM2861_BOARD_KWORLD_PVRTV_300U }, + { USB_DEVICE(0xeb1a, 0xe303), + .driver_info = EM2860_BOARD_KAIOMY_TVNPC_U2 }, { USB_DEVICE(0xeb1a, 0xe305), .driver_info = EM2880_BOARD_KWORLD_DVB_305U }, { USB_DEVICE(0xeb1a, 0xe310), @@ -1593,6 +1622,20 @@ void em28xx_pre_card_setup(struct em28xx *dev) /* enables audio for that devices */ em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); break; + + case EM2860_BOARD_KAIOMY_TVNPC_U2: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + em28xx_write_regs(dev, 0x0d, "\x42", 1); + em28xx_write_regs(dev, 0x08, "\xfd", 1); + msleep(10); + em28xx_write_regs(dev, 0x08, "\xff", 1); + msleep(10); + em28xx_write_regs(dev, 0x08, "\x7f", 1); + msleep(10); + em28xx_write_regs(dev, 0x08, "\x6b", 1); + + break; } em28xx_gpio_set(dev, dev->board.tuner_gpio); diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index 1e2ffea54..3fb1c05fe 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -100,6 +100,7 @@ #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60 #define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2 61 #define EM2820_BOARD_GADMEI_TVR200 62 +#define EM2860_BOARD_KAIOMY_TVNPC_U2 61 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v1.2.3 From b3ce86f6a8cf81930b025976cade18b7b93c626c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 11 Feb 2009 15:15:14 -0200 Subject: Adds IR table for the IR provided with this board and includes it at From: Mauro Carvalho Chehab Kaiomy entry. Thanks to Peter Senna Tschudin for borrow me one of those devices. Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/ir-keymaps.c | 49 +++++++++++++++++++++++++ linux/drivers/media/video/em28xx/em28xx-cards.c | 1 + linux/include/media/ir-common.h | 1 + 3 files changed, 51 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/common/ir-keymaps.c b/linux/drivers/media/common/ir-keymaps.c index ee9931f56..03fabc86c 100644 --- a/linux/drivers/media/common/ir-keymaps.c +++ b/linux/drivers/media/common/ir-keymaps.c @@ -2502,6 +2502,55 @@ IR_KEYTAB_TYPE ir_codes_kworld_plus_tv_analog[IR_KEYTAB_SIZE] = { }; EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog); +/* Kaiomy TVnPC U2 + Mauro Carvalho Chehab + */ +IR_KEYTAB_TYPE ir_codes_kaiomy[IR_KEYTAB_SIZE] = { + [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, +}; +EXPORT_SYMBOL_GPL(ir_codes_kaiomy); + IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE] = { [0x20] = KEY_LIST, [0x00] = KEY_POWER, diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index 12f52803a..a772170f4 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -1325,6 +1325,7 @@ struct em28xx_board em28xx_boards[] = { .mts_firmware = 1, .decoder = EM28XX_TVP5150, .tuner_gpio = default_tuner_gpio, + .ir_codes = ir_codes_kaiomy, .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = TVP5150_COMPOSITE0, diff --git a/linux/include/media/ir-common.h b/linux/include/media/ir-common.h index 5bf2ea006..31e62abb5 100644 --- a/linux/include/media/ir-common.h +++ b/linux/include/media/ir-common.h @@ -159,6 +159,7 @@ extern IR_KEYTAB_TYPE ir_codes_real_audio_220_32_keys[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_msi_tvanywhere_plus[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_ati_tv_wonder_hd_600[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_kworld_plus_tv_analog[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_kaiomy[IR_KEYTAB_SIZE]; #endif /* -- cgit v1.2.3 From 6bb5aad0cf3ec4e211f6b3a3a09ece3488019548 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 11 Feb 2009 15:18:36 -0200 Subject: em28xx: Add support for Easy Cap Capture DC-60 From: Mauro Carvalho Chehab Thanks to Peter Senna Tschudin for borrow me one of those devices. Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/Documentation/video4linux/CARDLIST.em28xx | 3 ++- linux/drivers/media/video/em28xx/em28xx-cards.c | 21 ++++++++++++++++++++- linux/drivers/media/video/em28xx/em28xx.h | 3 ++- 3 files changed, 24 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/Documentation/video4linux/CARDLIST.em28xx b/linux/Documentation/video4linux/CARDLIST.em28xx index e914b1374..b336dcab1 100644 --- a/linux/Documentation/video4linux/CARDLIST.em28xx +++ b/linux/Documentation/video4linux/CARDLIST.em28xx @@ -57,6 +57,7 @@ 57 -> Kworld PlusTV HD Hybrid 330 (em2883) [eb1a:a316] 58 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041] 60 -> Hauppauge WinTV HVR 850 (em2883) [2040:651f] - 61 -> Kaiomy TVnPC U2 (em2860) [eb1a:e303] 61 -> Pixelview PlayTV Box 4 USB 2.0 (em2820/em2840) 62 -> Gadmei TVR200 (em2820/em2840) + 63 -> Kaiomy TVnPC U2 (em2860) [eb1a:e303] + 64 -> Easy Cap Capture DC-60 (em2860) diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index a772170f4..96e3b4e80 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -1344,7 +1344,22 @@ struct em28xx_board em28xx_boards[] = { .type = EM28XX_RADIO, .amux = EM28XX_AMUX_LINE_IN, } - } + }, + [EM2860_BOARD_EASYCAP] = { + .name = "Easy Cap Capture DC-60", + .vchannels = 2, + .tuner_type = TUNER_ABSENT, + .decoder = EM28XX_SAA711X, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = EM28XX_AMUX_LINE_IN, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = EM28XX_AMUX_LINE_IN, + } }, + }, }; const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); @@ -1637,6 +1652,10 @@ void em28xx_pre_card_setup(struct em28xx *dev) em28xx_write_regs(dev, 0x08, "\x6b", 1); break; + case EM2860_BOARD_EASYCAP: + em28xx_write_regs(dev, 0x08, "\xf8", 1); + break; + } em28xx_gpio_set(dev, dev->board.tuner_gpio); diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index 3fb1c05fe..46f738a8d 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -100,7 +100,8 @@ #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60 #define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2 61 #define EM2820_BOARD_GADMEI_TVR200 62 -#define EM2860_BOARD_KAIOMY_TVNPC_U2 61 +#define EM2860_BOARD_KAIOMY_TVNPC_U2 63 +#define EM2860_BOARD_EASYCAP 64 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v1.2.3 From efb7c378b6c916b25aaeaa1a38d6307eb8407282 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 11 Feb 2009 23:14:09 +0100 Subject: saa6588: convert to v4l2-i2c-drv-legacy.h From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa6588.c | 86 +++++++++++++------------------------ 1 file changed, 31 insertions(+), 55 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa6588.c b/linux/drivers/media/video/saa6588.c index ab41d9526..57a40e62f 100644 --- a/linux/drivers/media/video/saa6588.c +++ b/linux/drivers/media/video/saa6588.c @@ -32,6 +32,8 @@ #include #include +#include +#include #include "compat.h" /* Addresses to scan */ @@ -73,7 +75,7 @@ MODULE_LICENSE("GPL"); #define dprintk if (debug) printk struct saa6588 { - struct i2c_client client; + struct i2c_client *client; struct work_struct work; struct timer_list timer; spinlock_t lock; @@ -87,9 +89,6 @@ struct saa6588 { int data_available_for_read; }; -static struct i2c_driver driver; -static struct i2c_client client_template; - /* ---------------------------------------------------------------------- */ /* @@ -266,7 +265,7 @@ static void saa6588_i2c_poll(struct saa6588 *s) /* Although we only need 3 bytes, we have to read at least 6. SAA6588 returns garbage otherwise */ - if (6 != i2c_master_recv(&s->client, &tmpbuf[0], 6)) { + if (6 != i2c_master_recv(s->client, &tmpbuf[0], 6)) { if (debug > 1) dprintk(PREFIX "read error!\n"); return; @@ -389,7 +388,8 @@ static int saa6588_configure(struct saa6588 *s) dprintk(PREFIX "writing: 0w=0x%02x 1w=0x%02x 2w=0x%02x\n", buf[0], buf[1], buf[2]); - if (3 != (rc = i2c_master_send(&s->client, buf, 3))) + rc = i2c_master_send(s->client, buf, 3); + if (rc != 3) printk(PREFIX "i2c i/o error: rc == %d (should be 3)\n", rc); return 0; @@ -397,33 +397,34 @@ static int saa6588_configure(struct saa6588 *s) /* ---------------------------------------------------------------------- */ -static int saa6588_attach(struct i2c_adapter *adap, int addr, int kind) +static int saa6588_probe(struct i2c_client *client, + const struct i2c_device_id *id) { struct saa6588 *s; - client_template.adapter = adap; - client_template.addr = addr; - printk(PREFIX "chip found @ 0x%x\n", addr << 1); + v4l_info(client, "saa6588 found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); - if (NULL == (s = kmalloc(sizeof(*s), GFP_KERNEL))) + s = kzalloc(sizeof(*s), GFP_KERNEL); + if (s == NULL) return -ENOMEM; + s->client = client; s->buf_size = bufblocks * 3; - if (NULL == (s->buffer = kmalloc(s->buf_size, GFP_KERNEL))) { + s->buffer = kmalloc(s->buf_size, GFP_KERNEL); + if (s->buffer == NULL) { kfree(s); return -ENOMEM; } spin_lock_init(&s->lock); - s->client = client_template; s->block_count = 0; s->wr_index = 0; s->rd_index = 0; s->last_blocknum = 0xff; init_waitqueue_head(&s->read_queue); s->data_available_for_read = 0; - i2c_set_clientdata(&s->client, s); - i2c_attach_client(&s->client); + i2c_set_clientdata(client, s); saa6588_configure(s); @@ -440,21 +441,13 @@ static int saa6588_attach(struct i2c_adapter *adap, int addr, int kind) return 0; } -static int saa6588_probe(struct i2c_adapter *adap) -{ - if (adap->class & I2C_CLASS_TV_ANALOG) - return i2c_probe(adap, &addr_data, saa6588_attach); - return 0; -} - -static int saa6588_detach(struct i2c_client *client) +static int saa6588_remove(struct i2c_client *client) { struct saa6588 *s = i2c_get_clientdata(client); del_timer_sync(&s->timer); flush_scheduled_work(); - i2c_detach_client(client); kfree(s->buffer); kfree(s); return 0; @@ -499,38 +492,21 @@ static int saa6588_command(struct i2c_client *client, unsigned int cmd, /* ----------------------------------------------------------------------- */ -static struct i2c_driver driver = { - .driver = { - .name = "saa6588", - }, - .id = -1, /* FIXME */ - .attach_adapter = saa6588_probe, - .detach_client = saa6588_detach, - .command = saa6588_command, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +static const struct i2c_device_id saa6588_id[] = { + { "saa6588", 0 }, + { } }; +MODULE_DEVICE_TABLE(i2c, saa6588_id); -static struct i2c_client client_template = { +#endif +static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "saa6588", - .driver = &driver, + .command = saa6588_command, + .probe = saa6588_probe, + .remove = saa6588_remove, + .legacy_class = I2C_CLASS_TV_ANALOG, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + .id_table = saa6588_id, +#endif }; - -static int __init saa6588_init_module(void) -{ - return i2c_add_driver(&driver); -} - -static void __exit saa6588_cleanup_module(void) -{ - i2c_del_driver(&driver); -} - -module_init(saa6588_init_module); -module_exit(saa6588_cleanup_module); - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * --------------------------------------------------------------------------- - * Local variables: - * c-basic-offset: 8 - * End: - */ -- cgit v1.2.3 From ed3c315b6213d5787151999cac89a343634a4814 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 11 Feb 2009 23:23:57 +0100 Subject: saa6588: convert to v4l2_subdev. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa6588.c | 117 ++++++++++++++++++++++-------------- 1 file changed, 72 insertions(+), 45 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa6588.c b/linux/drivers/media/video/saa6588.c index 57a40e62f..53c74f2ba 100644 --- a/linux/drivers/media/video/saa6588.c +++ b/linux/drivers/media/video/saa6588.c @@ -32,7 +32,7 @@ #include #include -#include +#include #include #include "compat.h" @@ -75,7 +75,7 @@ MODULE_LICENSE("GPL"); #define dprintk if (debug) printk struct saa6588 { - struct i2c_client *client; + struct v4l2_subdev sd; struct work_struct work; struct timer_list timer; spinlock_t lock; @@ -89,6 +89,11 @@ struct saa6588 { int data_available_for_read; }; +static inline struct saa6588 *to_saa6588(struct v4l2_subdev *sd) +{ + return container_of(sd, struct saa6588, sd); +} + /* ---------------------------------------------------------------------- */ /* @@ -258,6 +263,7 @@ static void block_to_buf(struct saa6588 *s, unsigned char *blockbuf) static void saa6588_i2c_poll(struct saa6588 *s) { + struct i2c_client *client = v4l2_get_subdevdata(&s->sd); unsigned long flags; unsigned char tmpbuf[6]; unsigned char blocknum; @@ -265,7 +271,7 @@ static void saa6588_i2c_poll(struct saa6588 *s) /* Although we only need 3 bytes, we have to read at least 6. SAA6588 returns garbage otherwise */ - if (6 != i2c_master_recv(s->client, &tmpbuf[0], 6)) { + if (6 != i2c_master_recv(client, &tmpbuf[0], 6)) { if (debug > 1) dprintk(PREFIX "read error!\n"); return; @@ -341,6 +347,7 @@ static void saa6588_work(struct work_struct *work) static int saa6588_configure(struct saa6588 *s) { + struct i2c_client *client = v4l2_get_subdevdata(&s->sd); unsigned char buf[3]; int rc; @@ -388,7 +395,7 @@ static int saa6588_configure(struct saa6588 *s) dprintk(PREFIX "writing: 0w=0x%02x 1w=0x%02x 2w=0x%02x\n", buf[0], buf[1], buf[2]); - rc = i2c_master_send(s->client, buf, 3); + rc = i2c_master_send(client, buf, 3); if (rc != 3) printk(PREFIX "i2c i/o error: rc == %d (should be 3)\n", rc); @@ -397,10 +404,64 @@ static int saa6588_configure(struct saa6588 *s) /* ---------------------------------------------------------------------- */ +static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + struct saa6588 *s = to_saa6588(sd); + struct rds_command *a = arg; + + switch (cmd) { + /* --- open() for /dev/radio --- */ + case RDS_CMD_OPEN: + a->result = 0; /* return error if chip doesn't work ??? */ + break; + /* --- close() for /dev/radio --- */ + case RDS_CMD_CLOSE: + s->data_available_for_read = 1; + wake_up_interruptible(&s->read_queue); + a->result = 0; + break; + /* --- read() for /dev/radio --- */ + case RDS_CMD_READ: + read_from_buf(s, a); + break; + /* --- poll() for /dev/radio --- */ + case RDS_CMD_POLL: + a->result = 0; + if (s->data_available_for_read) { + a->result |= POLLIN | POLLRDNORM; + } + poll_wait(a->instance, &s->read_queue, a->event_list); + break; + + default: + /* nothing */ + return -ENOIOCTLCMD; + } + return 0; +} + +static int saa6588_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); +} + +/* ----------------------------------------------------------------------- */ + +static const struct v4l2_subdev_core_ops saa6588_core_ops = { + .ioctl = saa6588_ioctl, +}; + +static const struct v4l2_subdev_ops saa6588_ops = { + .core = &saa6588_core_ops, +}; + +/* ---------------------------------------------------------------------- */ + static int saa6588_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct saa6588 *s; + struct v4l2_subdev *sd; v4l_info(client, "saa6588 found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); @@ -409,7 +470,6 @@ static int saa6588_probe(struct i2c_client *client, if (s == NULL) return -ENOMEM; - s->client = client; s->buf_size = bufblocks * 3; s->buffer = kmalloc(s->buf_size, GFP_KERNEL); @@ -417,6 +477,8 @@ static int saa6588_probe(struct i2c_client *client, kfree(s); return -ENOMEM; } + sd = &s->sd; + v4l2_i2c_subdev_init(sd, client, &saa6588_ops); spin_lock_init(&s->lock); s->block_count = 0; s->wr_index = 0; @@ -424,12 +486,11 @@ static int saa6588_probe(struct i2c_client *client, s->last_blocknum = 0xff; init_waitqueue_head(&s->read_queue); s->data_available_for_read = 0; - i2c_set_clientdata(client, s); saa6588_configure(s); /* start polling via eventd */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) INIT_WORK(&s->work, saa6588_work, s); #else INIT_WORK(&s->work, saa6588_work); @@ -443,7 +504,10 @@ static int saa6588_probe(struct i2c_client *client, static int saa6588_remove(struct i2c_client *client) { - struct saa6588 *s = i2c_get_clientdata(client); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct saa6588 *s = to_saa6588(sd); + + v4l2_device_unregister_subdev(sd); del_timer_sync(&s->timer); flush_scheduled_work(); @@ -453,43 +517,6 @@ static int saa6588_remove(struct i2c_client *client) return 0; } -static int saa6588_command(struct i2c_client *client, unsigned int cmd, - void *arg) -{ - struct saa6588 *s = i2c_get_clientdata(client); - struct rds_command *a = (struct rds_command *)arg; - - switch (cmd) { - /* --- open() for /dev/radio --- */ - case RDS_CMD_OPEN: - a->result = 0; /* return error if chip doesn't work ??? */ - break; - /* --- close() for /dev/radio --- */ - case RDS_CMD_CLOSE: - s->data_available_for_read = 1; - wake_up_interruptible(&s->read_queue); - a->result = 0; - break; - /* --- read() for /dev/radio --- */ - case RDS_CMD_READ: - read_from_buf(s, a); - break; - /* --- poll() for /dev/radio --- */ - case RDS_CMD_POLL: - a->result = 0; - if (s->data_available_for_read) { - a->result |= POLLIN | POLLRDNORM; - } - poll_wait(a->instance, &s->read_queue, a->event_list); - break; - - default: - /* nothing */ - break; - } - return 0; -} - /* ----------------------------------------------------------------------- */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) -- cgit v1.2.3 From d096d77d6e81756f65115cc8c10a2df07c64d466 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 11 Feb 2009 23:28:30 +0100 Subject: saa6588: add g_chip_ident support. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa6588.c | 9 +++++++++ linux/include/media/v4l2-chip-ident.h | 3 +++ 2 files changed, 12 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/saa6588.c b/linux/drivers/media/video/saa6588.c index 53c74f2ba..4f60df943 100644 --- a/linux/drivers/media/video/saa6588.c +++ b/linux/drivers/media/video/saa6588.c @@ -33,6 +33,7 @@ #include #include +#include #include #include "compat.h" @@ -440,6 +441,13 @@ static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) return 0; } +static int saa6588_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_SAA6588, 0); +} + static int saa6588_command(struct i2c_client *client, unsigned cmd, void *arg) { return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); @@ -448,6 +456,7 @@ static int saa6588_command(struct i2c_client *client, unsigned cmd, void *arg) /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops saa6588_core_ops = { + .g_chip_ident = saa6588_g_chip_ident, .ioctl = saa6588_ioctl, }; diff --git a/linux/include/media/v4l2-chip-ident.h b/linux/include/media/v4l2-chip-ident.h index 4e2182e52..bbe2bb6a5 100644 --- a/linux/include/media/v4l2-chip-ident.h +++ b/linux/include/media/v4l2-chip-ident.h @@ -92,6 +92,9 @@ enum { /* module tea6420: just ident 6420 */ V4L2_IDENT_TEA6420 = 6420, + /* module saa6588: just ident 6588 */ + V4L2_IDENT_SAA6588 = 6588, + /* module saa6752hs: reserved range 6750-6759 */ V4L2_IDENT_SAA6752HS = 6752, V4L2_IDENT_SAA6752HS_AC3 = 6753, -- cgit v1.2.3 From 9ddff42d7f7354e47e024a3b71bb84cf04158ad9 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 12 Feb 2009 12:05:45 +0100 Subject: gspca - main: More checks of the device disconnection. From: Jean-Francois Moine - prevent application oops when the device is disconnected - wake up the application at disconnection time - check the disconnection in ioctl dqbuf and poll Priority: high Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/gspca.c | 105 ++++++++++++++++++++++---------- 1 file changed, 74 insertions(+), 31 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index 64842682e..8d78b9287 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -136,11 +136,13 @@ static void fill_frame(struct gspca_dev *gspca_dev, cam_pkt_op pkt_scan; if (urb->status != 0) { + if (urb->status == -ESHUTDOWN) + return; /* disconnection */ #ifdef CONFIG_PM if (!gspca_dev->frozen) #endif PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); - return; /* disconnection ? */ + return; } pkt_scan = gspca_dev->sd_desc->pkt_scan; for (i = 0; i < urb->number_of_packets; i++) { @@ -220,6 +222,8 @@ static void bulk_irq(struct urb *urb) switch (urb->status) { case 0: break; + case -ESHUTDOWN: + return; /* disconnection */ case -ECONNRESET: urb->status = 0; break; @@ -228,7 +232,7 @@ static void bulk_irq(struct urb *urb) if (!gspca_dev->frozen) #endif PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); - return; /* disconnection ? */ + return; } /* check the availability of the frame buffer */ @@ -434,10 +438,8 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) if (urb == NULL) break; - BUG_ON(!gspca_dev->dev); gspca_dev->urb[i] = NULL; - if (!gspca_dev->present) - usb_kill_urb(urb); + usb_kill_urb(urb); if (urb->transfer_buffer != NULL) usb_buffer_free(gspca_dev->dev, urb->transfer_buffer_length, @@ -605,6 +607,11 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; + if (!gspca_dev->present) { + ret = -ENODEV; + goto out; + } + /* set the higher alternate setting and * loop until urb submit succeeds */ gspca_dev->alt = gspca_dev->nbalt; @@ -674,12 +681,14 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev) static void gspca_stream_off(struct gspca_dev *gspca_dev) { gspca_dev->streaming = 0; - if (gspca_dev->present - && gspca_dev->sd_desc->stopN) - gspca_dev->sd_desc->stopN(gspca_dev); - destroy_urbs(gspca_dev); - if (gspca_dev->present) + if (gspca_dev->present) { + if (gspca_dev->sd_desc->stopN) + gspca_dev->sd_desc->stopN(gspca_dev); + destroy_urbs(gspca_dev); gspca_set_alt0(gspca_dev); + } + + /* always call stop0 to free the subdriver's resources */ if (gspca_dev->sd_desc->stop0) gspca_dev->sd_desc->stop0(gspca_dev); PDEBUG(D_STREAM, "stream off OK"); @@ -961,8 +970,17 @@ static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { struct gspca_dev *gspca_dev = priv; + int ret; memset(cap, 0, sizeof *cap); + + /* protect the access to the usb device */ + if (mutex_lock_interruptible(&gspca_dev->usb_lock)) + return -ERESTARTSYS; + if (!gspca_dev->present) { + ret = -ENODEV; + goto out; + } strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver); if (gspca_dev->dev->product != NULL) { strncpy(cap->card, gspca_dev->dev->product, @@ -978,7 +996,10 @@ static int vidioc_querycap(struct file *file, void *priv, cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; - return 0; + ret = 0; +out: + mutex_unlock(&gspca_dev->usb_lock); + return ret; } static int vidioc_queryctrl(struct file *file, void *priv, @@ -1041,7 +1062,10 @@ 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; - ret = ctrls->set(gspca_dev, ctrl->value); + if (gspca_dev->present) + ret = ctrls->set(gspca_dev, ctrl->value); + else + ret = -ENODEV; mutex_unlock(&gspca_dev->usb_lock); return ret; } @@ -1065,7 +1089,10 @@ static int vidioc_g_ctrl(struct file *file, void *priv, return -EINVAL; if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; - ret = ctrls->get(gspca_dev, &ctrl->value); + if (gspca_dev->present) + ret = ctrls->get(gspca_dev, &ctrl->value); + else + ret = -ENODEV; mutex_unlock(&gspca_dev->usb_lock); return ret; } @@ -1227,10 +1254,7 @@ static int vidioc_streamon(struct file *file, void *priv, return -EINVAL; if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; - if (!gspca_dev->present) { - ret = -ENODEV; - goto out; - } + if (gspca_dev->nframes == 0 || !(gspca_dev->frame[0].v4l2_buf.flags & V4L2_BUF_FLAG_QUEUED)) { ret = -EINVAL; @@ -1298,7 +1322,10 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv, return -EINVAL; if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; - ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp); + if (gspca_dev->present) + ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp); + else + ret = -ENODEV; mutex_unlock(&gspca_dev->usb_lock); return ret; } @@ -1313,7 +1340,10 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv, return -EINVAL; if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; - ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp); + if (gspca_dev->present) + ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp); + else + ret = -ENODEV; mutex_unlock(&gspca_dev->usb_lock); return ret; } @@ -1332,7 +1362,11 @@ static int vidioc_g_parm(struct file *filp, void *priv, if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; - ret = gspca_dev->sd_desc->get_streamparm(gspca_dev, parm); + if (gspca_dev->present) + ret = gspca_dev->sd_desc->get_streamparm(gspca_dev, + parm); + else + ret = -ENODEV; mutex_unlock(&gspca_dev->usb_lock); return ret; } @@ -1357,7 +1391,11 @@ static int vidioc_s_parm(struct file *filp, void *priv, if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; - ret = gspca_dev->sd_desc->set_streamparm(gspca_dev, parm); + if (gspca_dev->present) + ret = gspca_dev->sd_desc->set_streamparm(gspca_dev, + parm); + else + ret = -ENODEV; mutex_unlock(&gspca_dev->usb_lock); return ret; } @@ -1531,7 +1569,8 @@ static int frame_wait(struct gspca_dev *gspca_dev, if (gspca_dev->sd_desc->dq_callback) { mutex_lock(&gspca_dev->usb_lock); - gspca_dev->sd_desc->dq_callback(gspca_dev); + if (gspca_dev->present) + gspca_dev->sd_desc->dq_callback(gspca_dev); mutex_unlock(&gspca_dev->usb_lock); } return j; @@ -1553,6 +1592,9 @@ static int vidioc_dqbuf(struct file *file, void *priv, if (v4l2_buf->memory != gspca_dev->memory) return -EINVAL; + if (!gspca_dev->present) + return -ENODEV; + /* if not streaming, be sure the application will not loop forever */ if (!(file->f_flags & O_NONBLOCK) && !gspca_dev->streaming && gspca_dev->users == 1) @@ -1703,8 +1745,6 @@ static unsigned int dev_poll(struct file *file, poll_table *wait) PDEBUG(D_FRAM, "poll"); poll_wait(file, &gspca_dev->wq, wait); - if (!gspca_dev->present) - return POLLERR; /* if reqbufs is not done, the user would use read() */ if (gspca_dev->nframes == 0) { @@ -1717,10 +1757,6 @@ static unsigned int dev_poll(struct file *file, poll_table *wait) if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0) return POLLERR; - if (!gspca_dev->present) { - ret = POLLERR; - goto out; - } /* check the next incoming buffer */ i = gspca_dev->fr_o; @@ -1729,8 +1765,9 @@ static unsigned int dev_poll(struct file *file, poll_table *wait) ret = POLLIN | POLLRDNORM; /* something to read */ else ret = 0; -out: mutex_unlock(&gspca_dev->queue_lock); + if (!gspca_dev->present) + return POLLHUP; return ret; } @@ -1956,10 +1993,16 @@ void gspca_disconnect(struct usb_interface *intf) mutex_lock(&gspca_dev->usb_lock); gspca_dev->present = 0; - mutex_unlock(&gspca_dev->usb_lock); - destroy_urbs(gspca_dev); + if (gspca_dev->streaming) { + destroy_urbs(gspca_dev); + wake_up_interruptible(&gspca_dev->wq); + } + + /* the device is freed at exit of this function */ gspca_dev->dev = NULL; + mutex_unlock(&gspca_dev->usb_lock); + usb_set_intfdata(intf, NULL); /* release the device */ -- cgit v1.2.3 From 4b065a8018a42e1e0345298dc04c33e831695664 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 12 Feb 2009 14:32:50 +0100 Subject: vino: convert to video_ioctl2. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/vino.c | 490 ++++++++++++++------------------------- 1 file changed, 173 insertions(+), 317 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/vino.c b/linux/drivers/media/video/vino.c index 349ef053f..357f81f62 100644 --- a/linux/drivers/media/video/vino.c +++ b/linux/drivers/media/video/vino.c @@ -2888,35 +2888,7 @@ static int vino_find_data_format(__u32 pixelformat) return VINO_DATA_FMT_NONE; } -static int vino_enum_data_norm(struct vino_channel_settings *vcs, __u32 index) -{ - int data_norm = VINO_DATA_NORM_NONE; - unsigned long flags; - - spin_lock_irqsave(&vino_drvdata->input_lock, flags); - switch(vcs->input) { - case VINO_INPUT_COMPOSITE: - case VINO_INPUT_SVIDEO: - if (index == 0) { - data_norm = VINO_DATA_NORM_PAL; - } else if (index == 1) { - data_norm = VINO_DATA_NORM_NTSC; - } else if (index == 2) { - data_norm = VINO_DATA_NORM_SECAM; - } - break; - case VINO_INPUT_D1: - if (index == 0) { - data_norm = VINO_DATA_NORM_D1; - } - break; - } - spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); - - return data_norm; -} - -static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index) +static int vino_int_enum_input(struct vino_channel_settings *vcs, __u32 index) { int input = VINO_INPUT_NONE; unsigned long flags; @@ -2995,7 +2967,8 @@ static __u32 vino_find_input_index(struct vino_channel_settings *vcs) /* V4L2 ioctls */ -static void vino_v4l2_querycap(struct v4l2_capability *cap) +static int vino_querycap(struct file *file, void *__fh, + struct v4l2_capability *cap) { memset(cap, 0, sizeof(struct v4l2_capability)); @@ -3007,16 +2980,18 @@ static void vino_v4l2_querycap(struct v4l2_capability *cap) V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; // V4L2_CAP_OVERLAY, V4L2_CAP_READWRITE + return 0; } -static int vino_v4l2_enuminput(struct vino_channel_settings *vcs, +static int vino_enum_input(struct file *file, void *__fh, struct v4l2_input *i) { + struct vino_channel_settings *vcs = video_drvdata(file); __u32 index = i->index; int input; dprintk("requested index = %d\n", index); - input = vino_enum_input(vcs, index); + input = vino_int_enum_input(vcs, index); if (input == VINO_INPUT_NONE) return -EINVAL; @@ -3038,9 +3013,10 @@ static int vino_v4l2_enuminput(struct vino_channel_settings *vcs, return 0; } -static int vino_v4l2_g_input(struct vino_channel_settings *vcs, +static int vino_g_input(struct file *file, void *__fh, unsigned int *i) { + struct vino_channel_settings *vcs = video_drvdata(file); __u32 index; int input; unsigned long flags; @@ -3061,52 +3037,24 @@ static int vino_v4l2_g_input(struct vino_channel_settings *vcs, return 0; } -static int vino_v4l2_s_input(struct vino_channel_settings *vcs, - unsigned int *i) +static int vino_s_input(struct file *file, void *__fh, + unsigned int i) { + struct vino_channel_settings *vcs = video_drvdata(file); int input; - dprintk("requested input = %d\n", *i); + dprintk("requested input = %d\n", i); - input = vino_enum_input(vcs, *i); + input = vino_int_enum_input(vcs, i); if (input == VINO_INPUT_NONE) return -EINVAL; return vino_set_input(vcs, input); } -static int vino_v4l2_enumstd(struct vino_channel_settings *vcs, - struct v4l2_standard *s) -{ - int index = s->index; - int data_norm; - - data_norm = vino_enum_data_norm(vcs, index); - dprintk("standard index = %d\n", index); - - if (data_norm == VINO_DATA_NORM_NONE) - return -EINVAL; - - dprintk("standard name = %s\n", - vino_data_norms[data_norm].description); - - memset(s, 0, sizeof(struct v4l2_standard)); - s->index = index; - - s->id = vino_data_norms[data_norm].std; - s->frameperiod.numerator = 1; - s->frameperiod.denominator = - vino_data_norms[data_norm].fps_max; - s->framelines = - vino_data_norms[data_norm].framelines; - strcpy(s->name, - vino_data_norms[data_norm].description); - - return 0; -} - -static int vino_v4l2_querystd(struct vino_channel_settings *vcs, +static int vino_querystd(struct file *file, void *__fh, v4l2_std_id *std) { + struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; int err = 0; @@ -3142,9 +3090,10 @@ static int vino_v4l2_querystd(struct vino_channel_settings *vcs, return err; } -static int vino_v4l2_g_std(struct vino_channel_settings *vcs, +static int vino_g_std(struct file *file, void *__fh, v4l2_std_id *std) { + struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; spin_lock_irqsave(&vino_drvdata->input_lock, flags); @@ -3157,9 +3106,10 @@ static int vino_v4l2_g_std(struct vino_channel_settings *vcs, return 0; } -static int vino_v4l2_s_std(struct vino_channel_settings *vcs, +static int vino_s_std(struct file *file, void *__fh, v4l2_std_id *std) { + struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; int ret = 0; @@ -3211,185 +3161,152 @@ out: return ret; } -static int vino_v4l2_enum_fmt(struct vino_channel_settings *vcs, +static int vino_enum_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_fmtdesc *fd) { enum v4l2_buf_type type = fd->type; int index = fd->index; + dprintk("format index = %d\n", index); - switch (fd->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if ((fd->index < 0) || - (fd->index >= VINO_DATA_FMT_COUNT)) - return -EINVAL; - dprintk("format name = %s\n", - vino_data_formats[index].description); - - memset(fd, 0, sizeof(struct v4l2_fmtdesc)); - fd->index = index; - fd->type = type; - fd->pixelformat = vino_data_formats[index].pixelformat; - strcpy(fd->description, vino_data_formats[index].description); - break; - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - default: + if ((fd->index < 0) || + (fd->index >= VINO_DATA_FMT_COUNT)) return -EINVAL; - } - + dprintk("format name = %s\n", + vino_data_formats[index].description); + + memset(fd, 0, sizeof(struct v4l2_fmtdesc)); + fd->index = index; + fd->type = type; + fd->pixelformat = vino_data_formats[index].pixelformat; + strcpy(fd->description, vino_data_formats[index].description); return 0; } -static int vino_v4l2_try_fmt(struct vino_channel_settings *vcs, +static int vino_try_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_format *f) { + struct vino_channel_settings *vcs = video_drvdata(file); struct vino_channel_settings tempvcs; unsigned long flags; + struct v4l2_pix_format *pf = &f->fmt.pix; - switch (f->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: { - struct v4l2_pix_format *pf = &f->fmt.pix; + dprintk("requested: w = %d, h = %d\n", + pf->width, pf->height); - dprintk("requested: w = %d, h = %d\n", - pf->width, pf->height); - - spin_lock_irqsave(&vino_drvdata->input_lock, flags); - memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings)); - spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); + spin_lock_irqsave(&vino_drvdata->input_lock, flags); + memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings)); + spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); - tempvcs.data_format = vino_find_data_format(pf->pixelformat); - if (tempvcs.data_format == VINO_DATA_FMT_NONE) { - tempvcs.data_format = VINO_DATA_FMT_GREY; - pf->pixelformat = - vino_data_formats[tempvcs.data_format]. - pixelformat; - } + tempvcs.data_format = vino_find_data_format(pf->pixelformat); + if (tempvcs.data_format == VINO_DATA_FMT_NONE) { + tempvcs.data_format = VINO_DATA_FMT_GREY; + pf->pixelformat = + vino_data_formats[tempvcs.data_format]. + pixelformat; + } - /* data format must be set before clipping/scaling */ - vino_set_scaling(&tempvcs, pf->width, pf->height); + /* data format must be set before clipping/scaling */ + vino_set_scaling(&tempvcs, pf->width, pf->height); - dprintk("data format = %s\n", - vino_data_formats[tempvcs.data_format].description); + dprintk("data format = %s\n", + vino_data_formats[tempvcs.data_format].description); - pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) / - tempvcs.decimation; - pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) / - tempvcs.decimation; + pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) / + tempvcs.decimation; + pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) / + tempvcs.decimation; - pf->field = V4L2_FIELD_INTERLACED; - pf->bytesperline = tempvcs.line_size; - pf->sizeimage = tempvcs.line_size * - (tempvcs.clipping.bottom - tempvcs.clipping.top) / - tempvcs.decimation; - pf->colorspace = - vino_data_formats[tempvcs.data_format].colorspace; - - pf->priv = 0; - break; - } - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - default: - return -EINVAL; - } + pf->field = V4L2_FIELD_INTERLACED; + pf->bytesperline = tempvcs.line_size; + pf->sizeimage = tempvcs.line_size * + (tempvcs.clipping.bottom - tempvcs.clipping.top) / + tempvcs.decimation; + pf->colorspace = + vino_data_formats[tempvcs.data_format].colorspace; + pf->priv = 0; return 0; } -static int vino_v4l2_g_fmt(struct vino_channel_settings *vcs, +static int vino_g_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_format *f) { + struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; + struct v4l2_pix_format *pf = &f->fmt.pix; - switch (f->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: { - struct v4l2_pix_format *pf = &f->fmt.pix; - - spin_lock_irqsave(&vino_drvdata->input_lock, flags); + spin_lock_irqsave(&vino_drvdata->input_lock, flags); - pf->width = (vcs->clipping.right - vcs->clipping.left) / - vcs->decimation; - pf->height = (vcs->clipping.bottom - vcs->clipping.top) / - vcs->decimation; - pf->pixelformat = - vino_data_formats[vcs->data_format].pixelformat; + pf->width = (vcs->clipping.right - vcs->clipping.left) / + vcs->decimation; + pf->height = (vcs->clipping.bottom - vcs->clipping.top) / + vcs->decimation; + pf->pixelformat = + vino_data_formats[vcs->data_format].pixelformat; - pf->field = V4L2_FIELD_INTERLACED; - pf->bytesperline = vcs->line_size; - pf->sizeimage = vcs->line_size * - (vcs->clipping.bottom - vcs->clipping.top) / - vcs->decimation; - pf->colorspace = - vino_data_formats[vcs->data_format].colorspace; + pf->field = V4L2_FIELD_INTERLACED; + pf->bytesperline = vcs->line_size; + pf->sizeimage = vcs->line_size * + (vcs->clipping.bottom - vcs->clipping.top) / + vcs->decimation; + pf->colorspace = + vino_data_formats[vcs->data_format].colorspace; - pf->priv = 0; - - spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); - break; - } - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - default: - return -EINVAL; - } + pf->priv = 0; + spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); return 0; } -static int vino_v4l2_s_fmt(struct vino_channel_settings *vcs, +static int vino_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_format *f) { + struct vino_channel_settings *vcs = video_drvdata(file); int data_format; unsigned long flags; + struct v4l2_pix_format *pf = &f->fmt.pix; - switch (f->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: { - struct v4l2_pix_format *pf = &f->fmt.pix; - - spin_lock_irqsave(&vino_drvdata->input_lock, flags); - - data_format = vino_find_data_format(pf->pixelformat); + spin_lock_irqsave(&vino_drvdata->input_lock, flags); - if (data_format == VINO_DATA_FMT_NONE) { - vcs->data_format = VINO_DATA_FMT_GREY; - pf->pixelformat = - vino_data_formats[vcs->data_format]. - pixelformat; - } else { - vcs->data_format = data_format; - } + data_format = vino_find_data_format(pf->pixelformat); - /* data format must be set before clipping/scaling */ - vino_set_scaling(vcs, pf->width, pf->height); + if (data_format == VINO_DATA_FMT_NONE) { + vcs->data_format = VINO_DATA_FMT_GREY; + pf->pixelformat = + vino_data_formats[vcs->data_format]. + pixelformat; + } else { + vcs->data_format = data_format; + } - dprintk("data format = %s\n", - vino_data_formats[vcs->data_format].description); + /* data format must be set before clipping/scaling */ + vino_set_scaling(vcs, pf->width, pf->height); - pf->width = vcs->clipping.right - vcs->clipping.left; - pf->height = vcs->clipping.bottom - vcs->clipping.top; + dprintk("data format = %s\n", + vino_data_formats[vcs->data_format].description); - pf->field = V4L2_FIELD_INTERLACED; - pf->bytesperline = vcs->line_size; - pf->sizeimage = vcs->line_size * - (vcs->clipping.bottom - vcs->clipping.top) / - vcs->decimation; - pf->colorspace = - vino_data_formats[vcs->data_format].colorspace; + pf->width = vcs->clipping.right - vcs->clipping.left; + pf->height = vcs->clipping.bottom - vcs->clipping.top; - pf->priv = 0; + pf->field = V4L2_FIELD_INTERLACED; + pf->bytesperline = vcs->line_size; + pf->sizeimage = vcs->line_size * + (vcs->clipping.bottom - vcs->clipping.top) / + vcs->decimation; + pf->colorspace = + vino_data_formats[vcs->data_format].colorspace; - spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); - break; - } - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - default: - return -EINVAL; - } + pf->priv = 0; + spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); return 0; } -static int vino_v4l2_cropcap(struct vino_channel_settings *vcs, +static int vino_cropcap(struct file *file, void *__fh, struct v4l2_cropcap *ccap) { + struct vino_channel_settings *vcs = video_drvdata(file); const struct vino_data_norm *norm; unsigned long flags; @@ -3419,9 +3336,10 @@ static int vino_v4l2_cropcap(struct vino_channel_settings *vcs, return 0; } -static int vino_v4l2_g_crop(struct vino_channel_settings *vcs, +static int vino_g_crop(struct file *file, void *__fh, struct v4l2_crop *c) { + struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; switch (c->type) { @@ -3443,9 +3361,10 @@ static int vino_v4l2_g_crop(struct vino_channel_settings *vcs, return 0; } -static int vino_v4l2_s_crop(struct vino_channel_settings *vcs, +static int vino_s_crop(struct file *file, void *__fh, struct v4l2_crop *c) { + struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; switch (c->type) { @@ -3465,9 +3384,10 @@ static int vino_v4l2_s_crop(struct vino_channel_settings *vcs, return 0; } -static int vino_v4l2_g_parm(struct vino_channel_settings *vcs, +static int vino_g_parm(struct file *file, void *__fh, struct v4l2_streamparm *sp) { + struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; switch (sp->type) { @@ -3495,9 +3415,10 @@ static int vino_v4l2_g_parm(struct vino_channel_settings *vcs, return 0; } -static int vino_v4l2_s_parm(struct vino_channel_settings *vcs, +static int vino_s_parm(struct file *file, void *__fh, struct v4l2_streamparm *sp) { + struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; switch (sp->type) { @@ -3528,9 +3449,10 @@ static int vino_v4l2_s_parm(struct vino_channel_settings *vcs, return 0; } -static int vino_v4l2_reqbufs(struct vino_channel_settings *vcs, +static int vino_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *rb) { + struct vino_channel_settings *vcs = video_drvdata(file); if (vcs->reading) return -EBUSY; @@ -3610,9 +3532,10 @@ static void vino_v4l2_get_buffer_status(struct vino_channel_settings *vcs, fb->id, fb->size, fb->data_size, fb->offset); } -static int vino_v4l2_querybuf(struct vino_channel_settings *vcs, +static int vino_querybuf(struct file *file, void *__fh, struct v4l2_buffer *b) { + struct vino_channel_settings *vcs = video_drvdata(file); if (vcs->reading) return -EBUSY; @@ -3645,9 +3568,10 @@ static int vino_v4l2_querybuf(struct vino_channel_settings *vcs, return 0; } -static int vino_v4l2_qbuf(struct vino_channel_settings *vcs, +static int vino_qbuf(struct file *file, void *__fh, struct v4l2_buffer *b) { + struct vino_channel_settings *vcs = video_drvdata(file); if (vcs->reading) return -EBUSY; @@ -3683,10 +3607,11 @@ static int vino_v4l2_qbuf(struct vino_channel_settings *vcs, return 0; } -static int vino_v4l2_dqbuf(struct vino_channel_settings *vcs, - struct v4l2_buffer *b, - unsigned int nonblocking) +static int vino_dqbuf(struct file *file, void *__fh, + struct v4l2_buffer *b) { + struct vino_channel_settings *vcs = video_drvdata(file); + unsigned int nonblocking = file->f_flags & O_NONBLOCK; if (vcs->reading) return -EBUSY; @@ -3758,8 +3683,10 @@ static int vino_v4l2_dqbuf(struct vino_channel_settings *vcs, return 0; } -static int vino_v4l2_streamon(struct vino_channel_settings *vcs) +static int vino_streamon(struct file *file, void *__fh, + enum v4l2_buf_type i) { + struct vino_channel_settings *vcs = video_drvdata(file); unsigned int incoming; int ret; if (vcs->reading) @@ -3796,8 +3723,10 @@ static int vino_v4l2_streamon(struct vino_channel_settings *vcs) return 0; } -static int vino_v4l2_streamoff(struct vino_channel_settings *vcs) +static int vino_streamoff(struct file *file, void *__fh, + enum v4l2_buf_type i) { + struct vino_channel_settings *vcs = video_drvdata(file); if (vcs->reading) return -EBUSY; @@ -3810,9 +3739,10 @@ static int vino_v4l2_streamoff(struct vino_channel_settings *vcs) return 0; } -static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs, +static int vino_queryctrl(struct file *file, void *__fh, struct v4l2_queryctrl *queryctrl) { + struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; int i; int err = 0; @@ -3859,9 +3789,10 @@ static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs, return err; } -static int vino_v4l2_g_ctrl(struct vino_channel_settings *vcs, +static int vino_g_ctrl(struct file *file, void *__fh, struct v4l2_control *control) { + struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; int i; int err = 0; @@ -3932,9 +3863,10 @@ out: return err; } -static int vino_v4l2_s_ctrl(struct vino_channel_settings *vcs, +static int vino_s_ctrl(struct file *file, void *__fh, struct v4l2_control *control) { + struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; int i; int err = 0; @@ -4241,112 +4173,6 @@ error: return ret; } -static long vino_do_ioctl(struct file *file, unsigned int cmd, void *arg) -{ - struct vino_channel_settings *vcs = video_drvdata(file); - -#ifdef VINO_DEBUG - switch (_IOC_TYPE(cmd)) { - case 'v': - dprintk("ioctl(): V4L1 unsupported (0x%08x)\n", cmd); - break; - case 'V': - dprintk("ioctl(): V4L2 %s (0x%08x)\n", - v4l2_ioctl_names[_IOC_NR(cmd)], cmd); - break; - default: - dprintk("ioctl(): unsupported command 0x%08x\n", cmd); - } -#endif - - switch (cmd) { - /* V4L2 interface */ - case VIDIOC_QUERYCAP: { - vino_v4l2_querycap(arg); - break; - } - case VIDIOC_ENUMINPUT: { - return vino_v4l2_enuminput(vcs, arg); - } - case VIDIOC_G_INPUT: { - return vino_v4l2_g_input(vcs, arg); - } - case VIDIOC_S_INPUT: { - return vino_v4l2_s_input(vcs, arg); - } - case VIDIOC_ENUMSTD: { - return vino_v4l2_enumstd(vcs, arg); - } - case VIDIOC_QUERYSTD: { - return vino_v4l2_querystd(vcs, arg); - } - case VIDIOC_G_STD: { - return vino_v4l2_g_std(vcs, arg); - } - case VIDIOC_S_STD: { - return vino_v4l2_s_std(vcs, arg); - } - case VIDIOC_ENUM_FMT: { - return vino_v4l2_enum_fmt(vcs, arg); - } - case VIDIOC_TRY_FMT: { - return vino_v4l2_try_fmt(vcs, arg); - } - case VIDIOC_G_FMT: { - return vino_v4l2_g_fmt(vcs, arg); - } - case VIDIOC_S_FMT: { - return vino_v4l2_s_fmt(vcs, arg); - } - case VIDIOC_CROPCAP: { - return vino_v4l2_cropcap(vcs, arg); - } - case VIDIOC_G_CROP: { - return vino_v4l2_g_crop(vcs, arg); - } - case VIDIOC_S_CROP: { - return vino_v4l2_s_crop(vcs, arg); - } - case VIDIOC_G_PARM: { - return vino_v4l2_g_parm(vcs, arg); - } - case VIDIOC_S_PARM: { - return vino_v4l2_s_parm(vcs, arg); - } - case VIDIOC_REQBUFS: { - return vino_v4l2_reqbufs(vcs, arg); - } - case VIDIOC_QUERYBUF: { - return vino_v4l2_querybuf(vcs, arg); - } - case VIDIOC_QBUF: { - return vino_v4l2_qbuf(vcs, arg); - } - case VIDIOC_DQBUF: { - return vino_v4l2_dqbuf(vcs, arg, file->f_flags & O_NONBLOCK); - } - case VIDIOC_STREAMON: { - return vino_v4l2_streamon(vcs); - } - case VIDIOC_STREAMOFF: { - return vino_v4l2_streamoff(vcs); - } - case VIDIOC_QUERYCTRL: { - return vino_v4l2_queryctrl(vcs, arg); - } - case VIDIOC_G_CTRL: { - return vino_v4l2_g_ctrl(vcs, arg); - } - case VIDIOC_S_CTRL: { - return vino_v4l2_s_ctrl(vcs, arg); - } - default: - return -ENOIOCTLCMD; - } - - return 0; -} - static long vino_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -4356,7 +4182,7 @@ static long vino_ioctl(struct file *file, if (mutex_lock_interruptible(&vcs->mutex)) return -EINTR; - ret = video_usercopy(file, cmd, arg, vino_do_ioctl); + ret = video_ioctl2(file, cmd, arg); mutex_unlock(&vcs->mutex); @@ -4368,6 +4194,34 @@ static long vino_ioctl(struct file *file, /* __initdata */ static int vino_init_stage; +const struct v4l2_ioctl_ops vino_ioctl_ops = { + .vidioc_enum_fmt_vid_cap = vino_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = vino_g_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = vino_s_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = vino_try_fmt_vid_cap, + .vidioc_querycap = vino_querycap, + .vidioc_enum_input = vino_enum_input, + .vidioc_g_input = vino_g_input, + .vidioc_s_input = vino_s_input, + .vidioc_g_std = vino_g_std, + .vidioc_s_std = vino_s_std, + .vidioc_querystd = vino_querystd, + .vidioc_cropcap = vino_cropcap, + .vidioc_s_crop = vino_s_crop, + .vidioc_g_crop = vino_g_crop, + .vidioc_s_parm = vino_s_parm, + .vidioc_g_parm = vino_g_parm, + .vidioc_reqbufs = vino_reqbufs, + .vidioc_querybuf = vino_querybuf, + .vidioc_qbuf = vino_qbuf, + .vidioc_dqbuf = vino_dqbuf, + .vidioc_streamon = vino_streamon, + .vidioc_streamoff = vino_streamoff, + .vidioc_queryctrl = vino_queryctrl, + .vidioc_g_ctrl = vino_g_ctrl, + .vidioc_s_ctrl = vino_s_ctrl, +}; + static const struct v4l2_file_operations vino_fops = { .owner = THIS_MODULE, .open = vino_open, @@ -4380,6 +4234,8 @@ static const struct v4l2_file_operations vino_fops = { static struct video_device v4l_device_template = { .name = "NOT SET", .fops = &vino_fops, + .ioctl_ops = &vino_ioctl_ops, + .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, .minor = -1, }; -- cgit v1.2.3 From 6b667a7c08554109a944d6816a8f7a50b65492fe Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 12 Feb 2009 15:31:13 +0100 Subject: vino: minor renames From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/vino.c | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/vino.c b/linux/drivers/media/video/vino.c index 357f81f62..bdd035cf9 100644 --- a/linux/drivers/media/video/vino.c +++ b/linux/drivers/media/video/vino.c @@ -289,7 +289,7 @@ struct vino_channel_settings { struct vino_interrupt_data int_data; /* V4L support */ - struct video_device *v4l_device; + struct video_device *vdev; }; struct vino_client { @@ -347,8 +347,8 @@ static struct vino_settings *vino_drvdata; static const char *vino_driver_name = "vino"; static const char *vino_driver_description = "SGI VINO"; static const char *vino_bus_name = "GIO64 bus"; -static const char *vino_v4l_device_name_a = "SGI VINO Channel A"; -static const char *vino_v4l_device_name_b = "SGI VINO Channel B"; +static const char *vino_vdev_name_a = "SGI VINO Channel A"; +static const char *vino_vdev_name_b = "SGI VINO Channel B"; static void vino_capture_tasklet(unsigned long channel); @@ -4231,7 +4231,7 @@ static const struct v4l2_file_operations vino_fops = { .poll = vino_poll, }; -static struct video_device v4l_device_template = { +static struct video_device vdev_template = { .name = "NOT SET", .fops = &vino_fops, .ioctl_ops = &vino_ioctl_ops, @@ -4243,24 +4243,24 @@ static void vino_module_cleanup(int stage) { switch(stage) { case 10: - video_unregister_device(vino_drvdata->b.v4l_device); - vino_drvdata->b.v4l_device = NULL; + video_unregister_device(vino_drvdata->b.vdev); + vino_drvdata->b.vdev = NULL; case 9: - video_unregister_device(vino_drvdata->a.v4l_device); - vino_drvdata->a.v4l_device = NULL; + video_unregister_device(vino_drvdata->a.vdev); + vino_drvdata->a.vdev = NULL; case 8: vino_i2c_del_bus(); case 7: free_irq(SGI_VINO_IRQ, NULL); case 6: - if (vino_drvdata->b.v4l_device) { - video_device_release(vino_drvdata->b.v4l_device); - vino_drvdata->b.v4l_device = NULL; + if (vino_drvdata->b.vdev) { + video_device_release(vino_drvdata->b.vdev); + vino_drvdata->b.vdev = NULL; } case 5: - if (vino_drvdata->a.v4l_device) { - video_device_release(vino_drvdata->a.v4l_device); - vino_drvdata->a.v4l_device = NULL; + if (vino_drvdata->a.vdev) { + video_device_release(vino_drvdata->a.vdev); + vino_drvdata->a.vdev = NULL; } case 4: /* all entries in dma_cpu dummy table have the same address */ @@ -4402,19 +4402,19 @@ static int vino_init_channel_settings(struct vino_channel_settings *vcs, spin_lock_init(&vcs->fb_queue.queue_lock); init_waitqueue_head(&vcs->fb_queue.frame_wait_queue); - vcs->v4l_device = video_device_alloc(); - if (!vcs->v4l_device) { + vcs->vdev = video_device_alloc(); + if (!vcs->vdev) { vino_module_cleanup(vino_init_stage); return -ENOMEM; } vino_init_stage++; - memcpy(vcs->v4l_device, &v4l_device_template, + memcpy(vcs->vdev, &vdev_template, sizeof(struct video_device)); - strcpy(vcs->v4l_device->name, name); - vcs->v4l_device->release = video_device_release; + strcpy(vcs->vdev->name, name); + vcs->vdev->release = video_device_release; - video_set_drvdata(vcs->v4l_device, vcs); + video_set_drvdata(vcs->vdev, vcs); return 0; } @@ -4440,12 +4440,12 @@ static int __init vino_module_init(void) spin_lock_init(&vino_drvdata->input_lock); ret = vino_init_channel_settings(&vino_drvdata->a, VINO_CHANNEL_A, - vino_v4l_device_name_a); + vino_vdev_name_a); if (ret) return ret; ret = vino_init_channel_settings(&vino_drvdata->b, VINO_CHANNEL_B, - vino_v4l_device_name_b); + vino_vdev_name_b); if (ret) return ret; @@ -4469,7 +4469,7 @@ static int __init vino_module_init(void) } vino_init_stage++; - ret = video_register_device(vino_drvdata->a.v4l_device, + ret = video_register_device(vino_drvdata->a.vdev, VFL_TYPE_GRABBER, -1); if (ret < 0) { printk(KERN_ERR "VINO channel A Video4Linux-device " @@ -4479,7 +4479,7 @@ static int __init vino_module_init(void) } vino_init_stage++; - ret = video_register_device(vino_drvdata->b.v4l_device, + ret = video_register_device(vino_drvdata->b.vdev, VFL_TYPE_GRABBER, -1); if (ret < 0) { printk(KERN_ERR "VINO channel B Video4Linux-device " -- cgit v1.2.3 From 6cd9330d1dfb971343c26b47a5658bd108a38fe4 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Thu, 12 Feb 2009 15:21:52 -0200 Subject: em28xx: CodingStyle fixes From: Nicola Soranzo Coding style fixes for recent changesets in em28xx. Priority: normal Signed-off-by: Nicola Soranzo Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/video/em28xx/em28xx-audio.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-audio.c b/linux/drivers/media/video/em28xx/em28xx-audio.c index f37abcffa..bfa3986f5 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -246,10 +246,12 @@ static int em28xx_cmd(struct em28xx *dev, int cmd, int arg) switch (cmd) { case EM28XX_CAPTURE_STREAM_EN: - if (dev->adev.capture_stream == STREAM_OFF && arg == EM28XX_START_AUDIO) { + if (dev->adev.capture_stream == STREAM_OFF && + arg == EM28XX_START_AUDIO) { dev->adev.capture_stream = STREAM_ON; em28xx_init_audio_isoc(dev); - } else if (dev->adev.capture_stream == STREAM_ON && arg == EM28XX_STOP_AUDIO) { + } else if (dev->adev.capture_stream == STREAM_ON && + arg == EM28XX_STOP_AUDIO) { dev->adev.capture_stream = STREAM_OFF; em28xx_deinit_isoc_audio(dev); } else { @@ -448,8 +450,8 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream, struct em28xx *dev = snd_pcm_substream_chip(substream); int retval; - dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START)? - "start": "stop"); + dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START) ? + "start" : "stop"); spin_lock(&dev->adev.slock); switch (cmd) { -- cgit v1.2.3 From e5a5404bb87498cd9b8009d407e1de1b2bbea611 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Thu, 12 Feb 2009 15:22:42 -0200 Subject: em28xx-cards: Add Pinnacle Dazzle Video Creator Plus DVC107 description From: Douglas Schilling Landgraf Added board Pinnacle Dazzle Video Creator Plus DVC107 to name description field. Priority: normal Signed-off-by: Douglas Schilling Landgraf --- linux/Documentation/video4linux/CARDLIST.em28xx | 2 +- linux/drivers/media/video/em28xx/em28xx-cards.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/Documentation/video4linux/CARDLIST.em28xx b/linux/Documentation/video4linux/CARDLIST.em28xx index f97c8533d..77874bd20 100644 --- a/linux/Documentation/video4linux/CARDLIST.em28xx +++ b/linux/Documentation/video4linux/CARDLIST.em28xx @@ -7,7 +7,7 @@ 6 -> Terratec Cinergy 200 USB (em2800) 7 -> Leadtek Winfast USB II (em2800) [0413:6023] 8 -> Kworld USB2800 (em2800) - 9 -> Pinnacle Dazzle DVC 90/DVC 100/DVC 101 (em2820/em2840) [2304:0207,2304:021a] + 9 -> Pinnacle Dazzle DVC 90/DVC 100/DVC 101/DVC 107 (em2820/em2840) [2304:0207,2304:021a] 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500] 11 -> Terratec Hybrid XS (em2880) [0ccd:0042] 12 -> Kworld PVR TV 2800 RF (em2820/em2840) diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index d69000674..5af4c417a 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -957,7 +957,7 @@ struct em28xx_board em28xx_boards[] = { } }, }, [EM2820_BOARD_PINNACLE_DVC_90] = { - .name = "Pinnacle Dazzle DVC 90/DVC 100/DVC 101", + .name = "Pinnacle Dazzle DVC 90/DVC 100/DVC 101/DVC 107", .tuner_type = TUNER_ABSENT, /* capture only board */ .decoder = EM28XX_SAA711X, .input = { { -- cgit v1.2.3 From ae85ab3edf003a61636030b72791577b41818bb0 Mon Sep 17 00:00:00 2001 From: Tobias Lorenz Date: Thu, 12 Feb 2009 18:55:45 +0100 Subject: Documentation and code cleanups From: Tobias Lorenz - "DealExtreme" sells the "PCear" radio and that comes from "Sanei Electric". - MPlayer is also usable as radio application. - Consistent usage of tabulators and blanks in the code. Priority: normal Signed-off-by: Tobias Lorenz --- linux/Documentation/video4linux/si470x.txt | 11 ++++++++--- linux/drivers/media/radio/radio-si470x.c | 11 ++++++----- 2 files changed, 14 insertions(+), 8 deletions(-) (limited to 'linux') diff --git a/linux/Documentation/video4linux/si470x.txt b/linux/Documentation/video4linux/si470x.txt index 49679e6aa..3a7823e01 100644 --- a/linux/Documentation/video4linux/si470x.txt +++ b/linux/Documentation/video4linux/si470x.txt @@ -1,6 +1,6 @@ Driver for USB radios for the Silicon Labs Si470x FM Radio Receivers -Copyright (c) 2008 Tobias Lorenz +Copyright (c) 2009 Tobias Lorenz Information from Silicon Labs @@ -41,7 +41,7 @@ chips are known to work: - 10c4:818a: Silicon Labs USB FM Radio Reference Design - 06e1:a155: ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF) - 1b80:d700: KWorld USB FM Radio SnapMusic Mobile 700 (FM700) -- 10c5:819a: DealExtreme USB Radio +- 10c5:819a: Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear) Software @@ -52,6 +52,7 @@ Testing is usually done with most application under Debian/testing: - gradio - GTK FM radio tuner - kradio - Comfortable Radio Application for KDE - radio - ncurses-based radio application +- mplayer - The Ultimate Movie Player For Linux There is also a library libv4l, which can be used. It's going to have a function for frequency seeking, either by using hardware functionality as in radio-si470x @@ -69,7 +70,7 @@ Audio Listing USB Audio is provided by the ALSA snd_usb_audio module. It is recommended to also select SND_USB_AUDIO, as this is required to get sound from the radio. For listing you have to redirect the sound, for example using one of the following -commands. +commands. Please adjust the audio devices to your needs (/dev/dsp* and hw:x,x). If you just want to test audio (very poor quality): cat /dev/dsp1 > /dev/dsp @@ -80,6 +81,10 @@ sox -2 --endian little -r 96000 -t oss /dev/dsp1 -t oss /dev/dsp If you use arts try: arecord -D hw:1,0 -r96000 -c2 -f S16_LE | artsdsp aplay -B - +If you use mplayer try: +mplayer -radio adevice=hw=1.0:arate=96000 \ + -rawaudio rate=96000 \ + radio:///capture Module Parameters ================= diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index f77a65d2a..718481313 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -5,8 +5,9 @@ * - Silicon Labs USB FM Radio Reference Design * - ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF) * - KWorld USB FM Radio SnapMusic Mobile 700 (FM700) + * - Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear) * - * Copyright (c) 2008 Tobias Lorenz + * Copyright (c) 2009 Tobias Lorenz * * 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 @@ -29,7 +30,7 @@ * 2008-01-12 Tobias Lorenz * Version 1.0.0 * - First working version - * 2008-01-13 Tobias Lorenz + * 2008-01-13 Tobias Lorenz * Version 1.0.1 * - Improved error handling, every function now returns errno * - Improved multi user access (start/mute/stop) @@ -141,7 +142,7 @@ static struct usb_device_id si470x_usb_driver_id_table[] = { { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) }, /* KWorld USB FM Radio SnapMusic Mobile 700 (FM700) */ { USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) }, - /* DealExtreme USB Radio */ + /* Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear) */ { USB_DEVICE_AND_INTERFACE_INFO(0x10c5, 0x819a, USB_CLASS_HID, 0, 0) }, /* Terminating entry */ { } @@ -341,7 +342,7 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); /* Report 19: stream */ #define STREAM_REPORT_SIZE 3 -#define STREAM_REPORT 19 +#define STREAM_REPORT 19 /* Report 20: scratch */ #define SCRATCH_PAGE_SIZE 63 @@ -410,7 +411,7 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); /* bootloader commands */ #define GET_SW_VERSION_COMMAND 0x00 -#define SET_PAGE_COMMAND 0x01 +#define SET_PAGE_COMMAND 0x01 #define ERASE_PAGE_COMMAND 0x02 #define WRITE_PAGE_COMMAND 0x03 #define CRC_ON_PAGE_COMMAND 0x04 -- cgit v1.2.3 From d0578265f7ee9cfe91ebb445d025f67987b7aaed Mon Sep 17 00:00:00 2001 From: Tobias Lorenz Date: Thu, 12 Feb 2009 18:55:56 +0100 Subject: Code rearrangements in preparation for other report types From: Tobias Lorenz LED_REPORT and all flash REPORTs are on it's way. This code rearrangement cleans up the code for proper integration later on. Priority: normal Signed-off-by: Tobias Lorenz --- linux/drivers/media/radio/radio-si470x.c | 122 +++++++++++++++++-------------- 1 file changed, 67 insertions(+), 55 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index 718481313..49317f91f 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -481,7 +481,7 @@ struct si470x_device { /************************************************************************** - * General Driver Functions + * General Driver Functions - REGISTER_REPORTs **************************************************************************/ /* @@ -566,60 +566,6 @@ static int si470x_set_register(struct si470x_device *radio, int regnr) } -/* - * si470x_get_all_registers - read entire registers - */ -static int si470x_get_all_registers(struct si470x_device *radio) -{ - unsigned char buf[ENTIRE_REPORT_SIZE]; - int retval; - unsigned char regnr; - - buf[0] = ENTIRE_REPORT; - - retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); - - if (retval >= 0) - for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++) - radio->registers[regnr] = get_unaligned_be16( - &buf[regnr * RADIO_REGISTER_SIZE + 1]); - - return (retval < 0) ? -EINVAL : 0; -} - - -/* - * si470x_get_rds_registers - read rds registers - */ -static int si470x_get_rds_registers(struct si470x_device *radio) -{ - unsigned char buf[RDS_REPORT_SIZE]; - int retval; - int size; - unsigned char regnr; - - buf[0] = RDS_REPORT; - - retval = usb_interrupt_msg(radio->usbdev, - usb_rcvintpipe(radio->usbdev, 1), - (void *) &buf, sizeof(buf), &size, usb_timeout); - if (size != sizeof(buf)) - printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: " - "return size differs: %d != %zu\n", size, sizeof(buf)); - if (retval < 0) - printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: " - "usb_interrupt_msg returned %d\n", retval); - - if (retval >= 0) - for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) - radio->registers[STATUSRSSI + regnr] = - get_unaligned_be16( - &buf[regnr * RADIO_REGISTER_SIZE + 1]); - - return (retval < 0) ? -EINVAL : 0; -} - - /* * si470x_set_chan - set the channel */ @@ -887,6 +833,70 @@ static int si470x_rds_on(struct si470x_device *radio) +/************************************************************************** + * General Driver Functions - ENTIRE_REPORT + **************************************************************************/ + +/* + * si470x_get_all_registers - read entire registers + */ +static int si470x_get_all_registers(struct si470x_device *radio) +{ + unsigned char buf[ENTIRE_REPORT_SIZE]; + int retval; + unsigned char regnr; + + buf[0] = ENTIRE_REPORT; + + retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); + + if (retval >= 0) + for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++) + radio->registers[regnr] = get_unaligned_be16( + &buf[regnr * RADIO_REGISTER_SIZE + 1]); + + return (retval < 0) ? -EINVAL : 0; +} + + + +/************************************************************************** + * General Driver Functions - RDS_REPORT + **************************************************************************/ + +/* + * si470x_get_rds_registers - read rds registers + */ +static int si470x_get_rds_registers(struct si470x_device *radio) +{ + unsigned char buf[RDS_REPORT_SIZE]; + int retval; + int size; + unsigned char regnr; + + buf[0] = RDS_REPORT; + + retval = usb_interrupt_msg(radio->usbdev, + usb_rcvintpipe(radio->usbdev, 1), + (void *) &buf, sizeof(buf), &size, usb_timeout); + if (size != sizeof(buf)) + printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: " + "return size differs: %d != %zu\n", size, sizeof(buf)); + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: " + "usb_interrupt_msg returned %d\n", retval); + + if (retval >= 0) + for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) + radio->registers[STATUSRSSI + regnr] = + get_unaligned_be16( + &buf[regnr * RADIO_REGISTER_SIZE + 1]); + + return (retval < 0) ? -EINVAL : 0; +} + + + /************************************************************************** * RDS Driver Functions **************************************************************************/ @@ -1101,6 +1111,7 @@ static int si470x_fops_open(struct file *file) } if (radio->users == 1) { + /* start radio */ retval = si470x_start(radio); if (retval < 0) usb_autopm_put_interface(radio->intf); @@ -1142,6 +1153,7 @@ static int si470x_fops_release(struct file *file) /* cancel read processes */ wake_up_interruptible(&radio->read_queue); + /* stop radio */ retval = si470x_stop(radio); usb_autopm_put_interface(radio->intf); } -- cgit v1.2.3 From 30db0e876957f7d463bc717f76c73b9e34aa9e92 Mon Sep 17 00:00:00 2001 From: Tobias Lorenz Date: Thu, 12 Feb 2009 18:56:10 +0100 Subject: Correction of Stereo detection/setting and signal strength indication From: Tobias Lorenz Thanks to Bob Ross - correction of stereo detection/setting - correction of signal strength indicator scaling Priority: normal Signed-off-by: Tobias Lorenz --- linux/drivers/media/radio/radio-si470x.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index 49317f91f..d211d5176 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -99,6 +99,9 @@ * - blacklisted KWorld radio in hid-core.c and hid-ids.h * 2008-12-03 Mark Lord * - add support for DealExtreme USB Radio + * 2009-01-31 Bob Ross + * - correction of stereo detection/setting + * - correction of signal strength indicator scaling * * ToDo: * - add firmware download/update support @@ -1405,20 +1408,22 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, }; /* stereo indicator == stereo (instead of mono) */ - if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 1) - tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; - else + if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 0) tuner->rxsubchans = V4L2_TUNER_SUB_MONO; + else + tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; /* mono/stereo selector */ - if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 1) - tuner->audmode = V4L2_TUNER_MODE_MONO; - else + if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 0) tuner->audmode = V4L2_TUNER_MODE_STEREO; + else + tuner->audmode = V4L2_TUNER_MODE_MONO; /* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */ - tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI) - * 0x0101; + /* measured in units of dbµV in 1 db increments (max at ~75 dbµV) */ + tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI); + /* the ideal factor is 0xffff/75 = 873,8 */ + tuner->signal = (tuner->signal * 873) + (8 * tuner->signal / 10); /* automatic frequency control: -1: freq to low, 1 freq to high */ /* AFCRL does only indicate that freq. differs, not if too low/high */ -- cgit v1.2.3 From c29af88de22ef512cc331c823d9d334f1c4515fc Mon Sep 17 00:00:00 2001 From: Tobias Lorenz Date: Thu, 12 Feb 2009 18:56:19 +0100 Subject: LED status output From: Tobias Lorenz This patch closes one of my todos that was since long on my list. Some people reported clicks and glitches in the audio stream, correlated to the LED color changing cycle. Thanks to Rick Bronson . Priority: normal Signed-off-by: Tobias Lorenz --- linux/drivers/media/radio/radio-si470x.c | 34 +++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index d211d5176..71c3228d8 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -102,11 +102,13 @@ * 2009-01-31 Bob Ross * - correction of stereo detection/setting * - correction of signal strength indicator scaling + * 2009-01-31 Rick Bronson + * Tobias Lorenz + * - add LED status output * * ToDo: * - add firmware download/update support * - RDS support: interrupt mode, instead of polling - * - add LED status output (check if that's not already done in firmware) */ @@ -900,6 +902,30 @@ static int si470x_get_rds_registers(struct si470x_device *radio) +/************************************************************************** + * General Driver Functions - LED_REPORT + **************************************************************************/ + +/* + * si470x_set_led_state - sets the led state + */ +static int si470x_set_led_state(struct si470x_device *radio, + unsigned char led_state) +{ + unsigned char buf[LED_REPORT_SIZE]; + int retval; + + buf[0] = LED_REPORT; + buf[1] = LED_COMMAND; + buf[2] = led_state; + + retval = si470x_set_report(radio, (void *) &buf, sizeof(buf)); + + return (retval < 0) ? -EINVAL : 0; +} + + + /************************************************************************** * RDS Driver Functions **************************************************************************/ @@ -1657,6 +1683,9 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, /* set initial frequency */ si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */ + /* set led to connect state */ + si470x_set_led_state(radio, BLINK_GREEN_LED); + /* rds buffer allocation */ radio->buf_size = rds_buf * 3; radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); @@ -1740,6 +1769,9 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf) cancel_delayed_work_sync(&radio->work); usb_set_intfdata(intf, NULL); if (radio->users == 0) { + /* set led to disconnect state */ + si470x_set_led_state(radio, BLINK_ORANGE_LED); + video_unregister_device(radio->videodev); kfree(radio->buffer); kfree(radio); -- cgit v1.2.3 From a7fd6975aa1ecb967ed5c0ed1186a4cb17b59a1a Mon Sep 17 00:00:00 2001 From: Tobias Lorenz Date: Thu, 12 Feb 2009 18:56:30 +0100 Subject: Output HW/SW version from scratchpad From: Tobias Lorenz This patch adds functions to access the scratchpad. For it is this good for? In the first two bytes, the developers stored the HW/PCB version and the software release of the firmware. This is now written to syslog, so debugging get's easier. Also knowing the versions is the key for flash upgrades later on. There are also some cleanups of the flash report sizes. Altogether this should justify the new version number 1.0.9. Thanks to Rick Bronson Priority: normal Signed-off-by: Tobias Lorenz --- linux/drivers/media/radio/radio-si470x.c | 61 ++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 10 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index 71c3228d8..b0a1e5832 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -105,6 +105,7 @@ * 2009-01-31 Rick Bronson * Tobias Lorenz * - add LED status output + * - get HW/SW version from scratchpad * * ToDo: * - add firmware download/update support @@ -115,10 +116,10 @@ /* driver definitions */ #define DRIVER_AUTHOR "Tobias Lorenz " #define DRIVER_NAME "radio-si470x" -#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 8) +#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 9) #define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver" #define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers" -#define DRIVER_VERSION "1.0.8" +#define DRIVER_VERSION "1.0.9" /* kernel includes */ @@ -355,9 +356,13 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); #define SCRATCH_REPORT 20 /* Reports 19-22: flash upgrade of the C8051F321 */ +#define WRITE_REPORT_SIZE 4 #define WRITE_REPORT 19 +#define FLASH_REPORT_SIZE 64 #define FLASH_REPORT 20 +#define CRC_REPORT_SIZE 3 #define CRC_REPORT 21 +#define RESPONSE_REPORT_SIZE 2 #define RESPONSE_REPORT 22 /* Report 23: currently unused, but can accept 60 byte reports on the HID */ @@ -430,12 +435,6 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); #define COMMAND_FAILED 0x02 #define COMMAND_PENDING 0x03 -/* buffer sizes */ -#define COMMAND_BUFFER_SIZE 4 -#define RESPONSE_BUFFER_SIZE 2 -#define FLASH_BUFFER_SIZE 64 -#define CRC_BUFFER_SIZE 3 - /************************************************************************** @@ -471,6 +470,10 @@ struct si470x_device { unsigned int buf_size; unsigned int rd_index; unsigned int wr_index; + + /* scratch page */ + unsigned char software_version; + unsigned char hardware_version; }; @@ -926,6 +929,35 @@ static int si470x_set_led_state(struct si470x_device *radio, +/************************************************************************** + * General Driver Functions - SCRATCH_REPORT + **************************************************************************/ + +/* + * si470x_get_scratch_versions - gets the scratch page and version infos + */ +static int si470x_get_scratch_page_versions(struct si470x_device *radio) +{ + unsigned char buf[SCRATCH_REPORT_SIZE]; + int retval; + + buf[0] = SCRATCH_REPORT; + + retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); + + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME ": si470x_get_scratch: " + "si470x_get_report returned %d\n", retval); + else { + radio->software_version = buf[1]; + radio->hardware_version = buf[2]; + } + + return (retval < 0) ? -EINVAL : 0; +} + + + /************************************************************************** * RDS Driver Functions **************************************************************************/ @@ -1656,7 +1688,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, sizeof(si470x_viddev_template)); video_set_drvdata(radio->videodev, radio); - /* show some infos about the specific device */ + /* show some infos about the specific si470x device */ if (si470x_get_all_registers(radio) < 0) { retval = -EIO; goto err_all; @@ -1664,7 +1696,16 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", radio->registers[DEVICEID], radio->registers[CHIPID]); - /* check if firmware is current */ + /* get software and hardware versions */ + if (si470x_get_scratch_page_versions(radio) < 0) { + retval = -EIO; + goto err_all; + } + printk(KERN_INFO DRIVER_NAME + ": software version %d, hardware version %d\n", + radio->software_version, radio->hardware_version); + + /* check if device and firmware is current */ if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) < RADIO_SW_VERSION_CURRENT) { printk(KERN_WARNING DRIVER_NAME -- cgit v1.2.3 From 4162a001c7f1ef358a70ce97fa1867e3d102cb32 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 13 Feb 2009 09:08:27 +0100 Subject: saa6588: remove legacy_class, not needed for saa6588 From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa6588.c | 1 - 1 file changed, 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa6588.c b/linux/drivers/media/video/saa6588.c index 4f60df943..77c3b59e8 100644 --- a/linux/drivers/media/video/saa6588.c +++ b/linux/drivers/media/video/saa6588.c @@ -541,7 +541,6 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .command = saa6588_command, .probe = saa6588_probe, .remove = saa6588_remove, - .legacy_class = I2C_CLASS_TV_ANALOG, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) .id_table = saa6588_id, #endif -- cgit v1.2.3 From 52a672f1e1c02901afbfcc810f5ab962759a05e0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 13 Feb 2009 09:12:02 +0100 Subject: cx2341x: fixed bug causing several audio controls to be no longer listed From: Hans Verkuil The cx2341x_mpeg_ctrls array must be ordered by control ID. I know that this is bad design, but for now I will just fix this bug and revisit it when all drivers have moved to v4l2_device/v4l2_subdev, since that will allow me to do greatly improve control handling. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/cx2341x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx2341x.c b/linux/drivers/media/video/cx2341x.c index c92b98135..ebee97bc2 100644 --- a/linux/drivers/media/video/cx2341x.c +++ b/linux/drivers/media/video/cx2341x.c @@ -46,12 +46,12 @@ const u32 cx2341x_mpeg_ctrls[] = { V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ, V4L2_CID_MPEG_AUDIO_ENCODING, V4L2_CID_MPEG_AUDIO_L2_BITRATE, - V4L2_CID_MPEG_AUDIO_AC3_BITRATE, V4L2_CID_MPEG_AUDIO_MODE, V4L2_CID_MPEG_AUDIO_MODE_EXTENSION, V4L2_CID_MPEG_AUDIO_EMPHASIS, V4L2_CID_MPEG_AUDIO_CRC, V4L2_CID_MPEG_AUDIO_MUTE, + V4L2_CID_MPEG_AUDIO_AC3_BITRATE, V4L2_CID_MPEG_VIDEO_ENCODING, V4L2_CID_MPEG_VIDEO_ASPECT, V4L2_CID_MPEG_VIDEO_B_FRAMES, -- cgit v1.2.3 From 33161971ac895973f70bb79980c85248ebfb7699 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 13 Feb 2009 11:31:05 +0100 Subject: saa7191: convert to v4l2-i2c-drv-legacy.h From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa7191.c | 161 +++++++++++++++--------------------- 1 file changed, 67 insertions(+), 94 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7191.c b/linux/drivers/media/video/saa7191.c index c4f169c95..f8313aa44 100644 --- a/linux/drivers/media/video/saa7191.c +++ b/linux/drivers/media/video/saa7191.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include "compat.h" #include "saa7191.h" @@ -33,6 +35,10 @@ MODULE_VERSION(SAA7191_MODULE_VERSION); MODULE_AUTHOR("Mikael Nousiainen "); MODULE_LICENSE("GPL"); +static unsigned short normal_i2c[] = { 0x8a >> 1, 0x8e >> 1, I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD; + // #define SAA7191_DEBUG #ifdef SAA7191_DEBUG @@ -55,8 +61,6 @@ struct saa7191 { int norm; }; -static struct i2c_driver i2c_driver_saa7191; - static const u8 initseq[] = { 0, /* Subaddress */ @@ -562,83 +566,6 @@ static int saa7191_set_control(struct i2c_client *client, /* I2C-interface */ -static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind) -{ - int err = 0; - struct saa7191 *decoder; - struct i2c_client *client; - - printk(KERN_INFO "Philips SAA7191 driver version %s\n", - SAA7191_MODULE_VERSION); - - client = kzalloc(sizeof(*client), GFP_KERNEL); - if (!client) - return -ENOMEM; - decoder = kzalloc(sizeof(*decoder), GFP_KERNEL); - if (!decoder) { - err = -ENOMEM; - goto out_free_client; - } - - client->addr = addr; - client->adapter = adap; - client->driver = &i2c_driver_saa7191; - client->flags = 0; - strcpy(client->name, "saa7191 client"); - i2c_set_clientdata(client, decoder); - - decoder->client = client; - - err = i2c_attach_client(client); - if (err) - goto out_free_decoder; - - err = saa7191_write_block(client, sizeof(initseq), initseq); - if (err) { - printk(KERN_ERR "SAA7191 initialization failed\n"); - goto out_detach_client; - } - - printk(KERN_INFO "SAA7191 initialized\n"); - - decoder->input = SAA7191_INPUT_COMPOSITE; - decoder->norm = SAA7191_NORM_PAL; - - err = saa7191_autodetect_norm(client); - if (err && (err != -EBUSY)) { - printk(KERN_ERR "SAA7191: Signal auto-detection failed\n"); - } - - return 0; - -out_detach_client: - i2c_detach_client(client); -out_free_decoder: - kfree(decoder); -out_free_client: - kfree(client); - return err; -} - -static int saa7191_probe(struct i2c_adapter *adap) -{ - /* Always connected to VINO */ - if (adap->id == I2C_HW_SGI_VINO) - return saa7191_attach(adap, SAA7191_ADDR, 0); - /* Feel free to add probe here :-) */ - return -ENODEV; -} - -static int saa7191_detach(struct i2c_client *client) -{ - struct saa7191 *decoder = i2c_get_clientdata(client); - - i2c_detach_client(client); - kfree(decoder); - kfree(client); - return 0; -} - static int saa7191_command(struct i2c_client *client, unsigned int cmd, void *arg) { @@ -784,25 +711,71 @@ static int saa7191_command(struct i2c_client *client, unsigned int cmd, return 0; } -static struct i2c_driver i2c_driver_saa7191 = { - .driver = { - .name = "saa7191", - }, - .id = I2C_DRIVERID_SAA7191, - .attach_adapter = saa7191_probe, - .detach_client = saa7191_detach, - .command = saa7191_command -}; +static int saa7191_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int err = 0; + struct saa7191 *decoder; + + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); -static int saa7191_init(void) + decoder = kzalloc(sizeof(*decoder), GFP_KERNEL); + if (!decoder) + return -ENOMEM; + + i2c_set_clientdata(client, decoder); + + decoder->client = client; + + err = saa7191_write_block(client, sizeof(initseq), initseq); + if (err) { + printk(KERN_ERR "SAA7191 initialization failed\n"); + kfree(decoder); + return err; + } + + printk(KERN_INFO "SAA7191 initialized\n"); + + decoder->input = SAA7191_INPUT_COMPOSITE; + decoder->norm = SAA7191_NORM_PAL; + + err = saa7191_autodetect_norm(client); + if (err && (err != -EBUSY)) + printk(KERN_ERR "SAA7191: Signal auto-detection failed\n"); + + return 0; +} + +static int saa7191_remove(struct i2c_client *client) { - return i2c_add_driver(&i2c_driver_saa7191); + struct saa7191 *decoder = i2c_get_clientdata(client); + + kfree(decoder); + return 0; } -static void saa7191_exit(void) +static int saa7191_legacy_probe(struct i2c_adapter *adapter) { - i2c_del_driver(&i2c_driver_saa7191); + return adapter->id == I2C_HW_SGI_VINO; } -module_init(saa7191_init); -module_exit(saa7191_exit); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +static const struct i2c_device_id saa7191_id[] = { + { "saa7191", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, saa7191_id); + +#endif +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "saa7191", + .driverid = I2C_DRIVERID_SAA7191, + .command = saa7191_command, + .probe = saa7191_probe, + .remove = saa7191_remove, + .legacy_probe = saa7191_legacy_probe, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + .id_table = saa7191_id, +#endif +}; -- cgit v1.2.3 From 6a1975515ebe6c5782f5f5ccf0bfdbbe6a27bd8c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 13 Feb 2009 11:48:21 +0100 Subject: v4l2-subdev: add querystd and g_input_status From: Hans Verkuil In order to convert the v4l1 zoran and vino i2c drivers to v4l2 these extra ops are required. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/v4l2-subdev.c | 4 ++++ linux/include/media/v4l2-common.h | 3 +++ linux/include/media/v4l2-subdev.h | 2 ++ 3 files changed, 9 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/v4l2-subdev.c b/linux/drivers/media/video/v4l2-subdev.c index 158bc55de..923ec8d01 100644 --- a/linux/drivers/media/video/v4l2-subdev.c +++ b/linux/drivers/media/video/v4l2-subdev.c @@ -104,6 +104,10 @@ int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg) return v4l2_subdev_call(sd, video, g_fmt, arg); case VIDIOC_INT_S_STD_OUTPUT: return v4l2_subdev_call(sd, video, s_std_output, *(v4l2_std_id *)arg); + case VIDIOC_QUERYSTD: + return v4l2_subdev_call(sd, video, querystd, arg); + case VIDIOC_INT_G_INPUT_STATUS: + return v4l2_subdev_call(sd, video, g_input_status, arg); case VIDIOC_STREAMON: return v4l2_subdev_call(sd, video, s_stream, 1); case VIDIOC_STREAMOFF: diff --git a/linux/include/media/v4l2-common.h b/linux/include/media/v4l2-common.h index 0f864f8da..1637cc302 100644 --- a/linux/include/media/v4l2-common.h +++ b/linux/include/media/v4l2-common.h @@ -297,4 +297,7 @@ struct v4l2_crystal_freq { a v4l2_gpio struct if a direction is also needed. */ #define VIDIOC_INT_S_GPIO _IOW('d', 117, u32) +/* Get input status. Same as the status field in the v4l2_input struct. */ +#define VIDIOC_INT_G_INPUT_STATUS _IOR('d', 118, u32) + #endif /* V4L2_COMMON_H_ */ diff --git a/linux/include/media/v4l2-subdev.h b/linux/include/media/v4l2-subdev.h index 9c1663d91..cd640c6f0 100644 --- a/linux/include/media/v4l2-subdev.h +++ b/linux/include/media/v4l2-subdev.h @@ -115,6 +115,8 @@ struct v4l2_subdev_video_ops { int (*g_vbi_data)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_data *vbi_data); int (*g_sliced_vbi_cap)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_cap *cap); int (*s_std_output)(struct v4l2_subdev *sd, v4l2_std_id std); + int (*querystd)(struct v4l2_subdev *sd, v4l2_std_id *std); + int (*g_input_status)(struct v4l2_subdev *sd, u32 *status); int (*s_stream)(struct v4l2_subdev *sd, int enable); int (*s_fmt)(struct v4l2_subdev *sd, struct v4l2_format *fmt); int (*g_fmt)(struct v4l2_subdev *sd, struct v4l2_format *fmt); -- cgit v1.2.3 From 660dd279265a8004e38a9f2ec42c7b43d1fbf308 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 13 Feb 2009 09:24:34 -0200 Subject: tuner: fix TUV1236D analog/digital setup From: Mauro Carvalho Chehab As reported by David Engel , ATSC115 doesn't work fine with mythtv. This software opens both analog and dvb interfaces of saa7134. What happens is that some tuner commands are going to the wrong place, as shown at the logs: Feb 12 20:37:48 opus kernel: tuner-simple 1-0061: using tuner params #0 (ntsc) Feb 12 20:37:48 opus kernel: tuner-simple 1-0061: freq = 67.25 (1076), range = 0, config = 0xce, cb = 0x01 Feb 12 20:37:48 opus kernel: tuner-simple 1-0061: Freq= 67.25 MHz, V_IF=45.75 MHz, Offset=0.00 MHz, div=1808 Feb 12 20:37:48 opus kernel: tuner 1-0061: tv freq set to 67.25 Feb 12 20:37:48 opus kernel: tuner-simple 1-000a: using tuner params #0 (ntsc) Feb 12 20:37:48 opus kernel: tuner-simple 1-000a: freq = 67.25 (1076), range = 0, config = 0xce, cb = 0x01 Feb 12 20:37:48 opus kernel: tuner-simple 1-000a: Freq= 67.25 MHz, V_IF=45.75 MHz, Offset=0.00 MHz, div=1808 Feb 12 20:37:48 opus kernel: tuner-simple 1-000a: tv 0x07 0x10 0xce 0x01 Feb 12 20:37:48 opus kernel: tuner-simple 1-0061: tv 0x07 0x10 0xce 0x01 This happens due to a hack at TUV1236D analog setup, where it replaces tuner address, at 0x61 for 0x0a, in order to save a few memory bytes. The code assumes that nobody else would try to access the tuner during that setup, but the point is that there's no lock to protect such access. So, this opens the possibility of race conditions to happen. Instead of hacking tuner address, this patch uses a temporary var with the proper tuner value to be used during the setup. This should save the issue, although we should consider to write some analog/digital lock at saa7134 driver. Priority: high Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/tuners/tuner-simple.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/common/tuners/tuner-simple.c b/linux/drivers/media/common/tuners/tuner-simple.c index 36aaa7e75..233476df9 100644 --- a/linux/drivers/media/common/tuners/tuner-simple.c +++ b/linux/drivers/media/common/tuners/tuner-simple.c @@ -325,7 +325,6 @@ static int simple_std_setup(struct dvb_frontend *fe, u8 *config, u8 *cb) { struct tuner_simple_priv *priv = fe->tuner_priv; - u8 tuneraddr; int rc; /* tv norm specific stuff for multi-norm tuners */ @@ -394,6 +393,7 @@ static int simple_std_setup(struct dvb_frontend *fe, case TUNER_PHILIPS_TUV1236D: { + struct tuner_i2c_props i2c = priv->i2c_props; /* 0x40 -> ATSC antenna input 1 */ /* 0x48 -> ATSC antenna input 2 */ /* 0x00 -> NTSC antenna input 1 */ @@ -405,17 +405,15 @@ static int simple_std_setup(struct dvb_frontend *fe, buffer[1] = 0x04; } /* set to the correct mode (analog or digital) */ - tuneraddr = priv->i2c_props.addr; - priv->i2c_props.addr = 0x0a; - rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[0], 2); + i2c.addr = 0x0a; + rc = tuner_i2c_xfer_send(&i2c, &buffer[0], 2); if (2 != rc) tuner_warn("i2c i/o error: rc == %d " "(should be 2)\n", rc); - rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[2], 2); + rc = tuner_i2c_xfer_send(&i2c, &buffer[2], 2); if (2 != rc) tuner_warn("i2c i/o error: rc == %d " "(should be 2)\n", rc); - priv->i2c_props.addr = tuneraddr; break; } } -- cgit v1.2.3 From 12a53c2ca239e0fd7a2b858b577d624677982ab9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 13 Feb 2009 14:57:48 +0100 Subject: v4l2-common: add comments warning that about the sort order From: Hans Verkuil Control arrays as are used with v4l2_ctrl_next must be sorted from low to high. Add a comment at the top of all such arrays to warn about this. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/cx18/cx18-controls.c | 1 + linux/drivers/media/video/cx2341x.c | 1 + linux/drivers/media/video/cx23885/cx23885-video.c | 1 + linux/drivers/media/video/cx88/cx88-video.c | 1 + linux/drivers/media/video/ivtv/ivtv-controls.c | 1 + linux/drivers/media/video/saa7134/saa7134-empress.c | 2 ++ linux/drivers/media/video/v4l2-common.c | 2 +- linux/include/media/v4l2-common.h | 5 +++++ 8 files changed, 13 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-controls.c b/linux/drivers/media/video/cx18/cx18-controls.c index 6af4d5c19..10a4e07b7 100644 --- a/linux/drivers/media/video/cx18/cx18-controls.c +++ b/linux/drivers/media/video/cx18/cx18-controls.c @@ -30,6 +30,7 @@ #include "cx18-mailbox.h" #include "cx18-controls.h" +/* Must be sorted from low to high control ID! */ static const u32 user_ctrls[] = { V4L2_CID_USER_CLASS, V4L2_CID_BRIGHTNESS, diff --git a/linux/drivers/media/video/cx2341x.c b/linux/drivers/media/video/cx2341x.c index ebee97bc2..01c4d2d02 100644 --- a/linux/drivers/media/video/cx2341x.c +++ b/linux/drivers/media/video/cx2341x.c @@ -39,6 +39,7 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Debug level (0-1)"); +/* Must be sorted from low to high control ID! */ const u32 cx2341x_mpeg_ctrls[] = { V4L2_CID_MPEG_CLASS, V4L2_CID_MPEG_STREAM_TYPE, diff --git a/linux/drivers/media/video/cx23885/cx23885-video.c b/linux/drivers/media/video/cx23885/cx23885-video.c index 09291888d..131fc740a 100644 --- a/linux/drivers/media/video/cx23885/cx23885-video.c +++ b/linux/drivers/media/video/cx23885/cx23885-video.c @@ -276,6 +276,7 @@ static struct cx23885_ctrl cx23885_ctls[] = { }; static const int CX23885_CTLS = ARRAY_SIZE(cx23885_ctls); +/* Must be sorted from low to high control ID! */ static const u32 cx23885_user_ctrls[] = { V4L2_CID_USER_CLASS, V4L2_CID_BRIGHTNESS, diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c index a95bcb0ea..c8870cf06 100644 --- a/linux/drivers/media/video/cx88/cx88-video.c +++ b/linux/drivers/media/video/cx88/cx88-video.c @@ -299,6 +299,7 @@ static struct cx88_ctrl cx8800_ctls[] = { }; static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls); +/* Must be sorted from low to high control ID! */ const u32 cx88_user_ctrls[] = { V4L2_CID_USER_CLASS, V4L2_CID_BRIGHTNESS, diff --git a/linux/drivers/media/video/ivtv/ivtv-controls.c b/linux/drivers/media/video/ivtv/ivtv-controls.c index 62aa06f5d..84995bcf4 100644 --- a/linux/drivers/media/video/ivtv/ivtv-controls.c +++ b/linux/drivers/media/video/ivtv/ivtv-controls.c @@ -26,6 +26,7 @@ #include "ivtv-mailbox.h" #include "ivtv-controls.h" +/* Must be sorted from low to high control ID! */ static const u32 user_ctrls[] = { V4L2_CID_USER_CLASS, V4L2_CID_BRIGHTNESS, diff --git a/linux/drivers/media/video/saa7134/saa7134-empress.c b/linux/drivers/media/video/saa7134/saa7134-empress.c index 3b0b42545..813f5f88d 100644 --- a/linux/drivers/media/video/saa7134/saa7134-empress.c +++ b/linux/drivers/media/video/saa7134/saa7134-empress.c @@ -352,6 +352,7 @@ static int empress_s_ctrl(struct file *file, void *priv, static int empress_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *c) { + /* Must be sorted from low to high control ID! */ static const u32 user_ctrls[] = { V4L2_CID_USER_CLASS, V4L2_CID_BRIGHTNESS, @@ -364,6 +365,7 @@ static int empress_queryctrl(struct file *file, void *priv, 0 }; + /* Must be sorted from low to high control ID! */ static const u32 mpeg_ctrls[] = { V4L2_CID_MPEG_CLASS, V4L2_CID_MPEG_STREAM_TYPE, diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index 6cc7d4058..8ae8dd366 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -750,7 +750,7 @@ EXPORT_SYMBOL(v4l2_ctrl_query_menu_valid_items); /* ctrl_classes points to an array of u32 pointers, the last element is a NULL pointer. Each u32 array is a 0-terminated array of control IDs. Each array must be sorted low to high and belong to the same control - class. The array of u32 pointer must also be sorted, from low class IDs + class. The array of u32 pointers must also be sorted, from low class IDs to high class IDs. This function returns the first ID that follows after the given ID. diff --git a/linux/include/media/v4l2-common.h b/linux/include/media/v4l2-common.h index 0f864f8da..4d82f1619 100644 --- a/linux/include/media/v4l2-common.h +++ b/linux/include/media/v4l2-common.h @@ -107,6 +107,11 @@ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qctrl, const char **menu_items); #define V4L2_CTRL_MENU_IDS_END (0xffffffff) int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *ids); + +/* Note: ctrl_classes points to an array of u32 pointers. Each u32 array is a + 0-terminated array of control IDs. Each array must be sorted low to high + and belong to the same control class. The array of u32 pointers must also + be sorted, from low class IDs to high class IDs. */ u32 v4l2_ctrl_next(const u32 * const *ctrl_classes, u32 id); /* ------------------------------------------------------------------------- */ -- cgit v1.2.3 From 9c0e40e186e68445ec869433c25a88c2eb4a7229 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 27 Feb 2009 13:05:10 +0100 Subject: vino/indycam/saa7191: convert to i2c modules to V4L2. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/indycam.c | 236 +++++++-------------- linux/drivers/media/video/indycam.h | 19 +- linux/drivers/media/video/saa7191.c | 228 ++++++--------------- linux/drivers/media/video/saa7191.h | 26 +-- linux/drivers/media/video/vino.c | 396 ++++++++++-------------------------- 5 files changed, 259 insertions(+), 646 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/indycam.c b/linux/drivers/media/video/indycam.c index 84b9e4f2b..492f1e6cb 100644 --- a/linux/drivers/media/video/indycam.c +++ b/linux/drivers/media/video/indycam.c @@ -19,10 +19,11 @@ #include #include -#include /* IndyCam decodes stream of photons into digital image representation ;-) */ -#include +#include #include +#include +#include #include "indycam.h" @@ -33,6 +34,10 @@ MODULE_VERSION(INDYCAM_MODULE_VERSION); MODULE_AUTHOR("Mikael Nousiainen "); MODULE_LICENSE("GPL"); +static unsigned short normal_i2c[] = { 0x56 >> 1, I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD; + // #define INDYCAM_DEBUG #ifdef INDYCAM_DEBUG @@ -48,8 +53,6 @@ struct indycam { u8 version; }; -static struct i2c_driver i2c_driver_indycam; - static const u8 initseq[] = { INDYCAM_CONTROL_AGCENA, /* INDYCAM_CONTROL */ INDYCAM_SHUTTER_60, /* INDYCAM_SHUTTER */ @@ -138,44 +141,44 @@ static void indycam_regdump_debug(struct i2c_client *client) #endif static int indycam_get_control(struct i2c_client *client, - struct indycam_control *ctrl) + struct v4l2_control *ctrl) { struct indycam *camera = i2c_get_clientdata(client); u8 reg; int ret = 0; - switch (ctrl->type) { - case INDYCAM_CONTROL_AGC: - case INDYCAM_CONTROL_AWB: + switch (ctrl->id) { + case V4L2_CID_AUTOGAIN: + case V4L2_CID_AUTO_WHITE_BALANCE: ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, ®); if (ret) return -EIO; - if (ctrl->type == INDYCAM_CONTROL_AGC) + if (ctrl->id == V4L2_CID_AUTOGAIN) ctrl->value = (reg & INDYCAM_CONTROL_AGCENA) ? 1 : 0; else ctrl->value = (reg & INDYCAM_CONTROL_AWBCTL) ? 1 : 0; break; - case INDYCAM_CONTROL_SHUTTER: + case V4L2_CID_EXPOSURE: ret = indycam_read_reg(client, INDYCAM_REG_SHUTTER, ®); if (ret) return -EIO; ctrl->value = ((s32)reg == 0x00) ? 0xff : ((s32)reg - 1); break; - case INDYCAM_CONTROL_GAIN: + case V4L2_CID_GAIN: ret = indycam_read_reg(client, INDYCAM_REG_GAIN, ®); if (ret) return -EIO; ctrl->value = (s32)reg; break; - case INDYCAM_CONTROL_RED_BALANCE: + case V4L2_CID_RED_BALANCE: ret = indycam_read_reg(client, INDYCAM_REG_RED_BALANCE, ®); if (ret) return -EIO; ctrl->value = (s32)reg; break; - case INDYCAM_CONTROL_BLUE_BALANCE: + case V4L2_CID_BLUE_BALANCE: ret = indycam_read_reg(client, INDYCAM_REG_BLUE_BALANCE, ®); if (ret) return -EIO; @@ -195,7 +198,7 @@ static int indycam_get_control(struct i2c_client *client, return -EIO; ctrl->value = (s32)reg; break; - case INDYCAM_CONTROL_GAMMA: + case V4L2_CID_GAMMA: if (camera->version == CAMERA_VERSION_MOOSE) { ret = indycam_read_reg(client, INDYCAM_REG_GAMMA, ®); @@ -214,20 +217,20 @@ static int indycam_get_control(struct i2c_client *client, } static int indycam_set_control(struct i2c_client *client, - struct indycam_control *ctrl) + struct v4l2_control *ctrl) { struct indycam *camera = i2c_get_clientdata(client); u8 reg; int ret = 0; - switch (ctrl->type) { - case INDYCAM_CONTROL_AGC: - case INDYCAM_CONTROL_AWB: + switch (ctrl->id) { + case V4L2_CID_AUTOGAIN: + case V4L2_CID_AUTO_WHITE_BALANCE: ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, ®); if (ret) break; - if (ctrl->type == INDYCAM_CONTROL_AGC) { + if (ctrl->id == V4L2_CID_AUTOGAIN) { if (ctrl->value) reg |= INDYCAM_CONTROL_AGCENA; else @@ -241,18 +244,18 @@ static int indycam_set_control(struct i2c_client *client, ret = indycam_write_reg(client, INDYCAM_REG_CONTROL, reg); break; - case INDYCAM_CONTROL_SHUTTER: + case V4L2_CID_EXPOSURE: reg = (ctrl->value == 0xff) ? 0x00 : (ctrl->value + 1); ret = indycam_write_reg(client, INDYCAM_REG_SHUTTER, reg); break; - case INDYCAM_CONTROL_GAIN: + case V4L2_CID_GAIN: ret = indycam_write_reg(client, INDYCAM_REG_GAIN, ctrl->value); break; - case INDYCAM_CONTROL_RED_BALANCE: + case V4L2_CID_RED_BALANCE: ret = indycam_write_reg(client, INDYCAM_REG_RED_BALANCE, ctrl->value); break; - case INDYCAM_CONTROL_BLUE_BALANCE: + case V4L2_CID_BLUE_BALANCE: ret = indycam_write_reg(client, INDYCAM_REG_BLUE_BALANCE, ctrl->value); break; @@ -264,7 +267,7 @@ static int indycam_set_control(struct i2c_client *client, ret = indycam_write_reg(client, INDYCAM_REG_BLUE_SATURATION, ctrl->value); break; - case INDYCAM_CONTROL_GAMMA: + case V4L2_CID_GAMMA: if (camera->version == CAMERA_VERSION_MOOSE) { ret = indycam_write_reg(client, INDYCAM_REG_GAMMA, ctrl->value); @@ -279,44 +282,50 @@ static int indycam_set_control(struct i2c_client *client, /* I2C-interface */ -static int indycam_attach(struct i2c_adapter *adap, int addr, int kind) +static int indycam_command(struct i2c_client *client, unsigned int cmd, + void *arg) +{ + /* The old video_decoder interface just isn't enough, + * so we'll use some custom commands. */ + switch (cmd) { + case VIDIOC_G_CTRL: + return indycam_get_control(client, arg); + + case VIDIOC_S_CTRL: + return indycam_set_control(client, arg); + + default: + return -EINVAL; + } + + return 0; +} + +static int indycam_probe(struct i2c_client *client, + const struct i2c_device_id *id) { int err = 0; struct indycam *camera; - struct i2c_client *client; - printk(KERN_INFO "SGI IndyCam driver version %s\n", - INDYCAM_MODULE_VERSION); + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!client) - return -ENOMEM; camera = kzalloc(sizeof(struct indycam), GFP_KERNEL); - if (!camera) { - err = -ENOMEM; - goto out_free_client; - } + if (!camera) + return -ENOMEM; - client->addr = addr; - client->adapter = adap; - client->driver = &i2c_driver_indycam; - client->flags = 0; - strcpy(client->name, "IndyCam client"); i2c_set_clientdata(client, camera); camera->client = client; - err = i2c_attach_client(client); - if (err) - goto out_free_camera; - camera->version = i2c_smbus_read_byte_data(client, INDYCAM_REG_VERSION); if (camera->version != CAMERA_VERSION_INDY && camera->version != CAMERA_VERSION_MOOSE) { - err = -ENODEV; - goto out_detach_client; + kfree(camera); + return -ENODEV; } + printk(KERN_INFO "IndyCam v%d.%d detected\n", INDYCAM_VERSION_MAJOR(camera->version), INDYCAM_VERSION_MINOR(camera->version)); @@ -327,8 +336,8 @@ static int indycam_attach(struct i2c_adapter *adap, int addr, int kind) err = indycam_write_block(client, 0, sizeof(initseq), (u8 *)&initseq); if (err) { printk(KERN_ERR "IndyCam initialization failed\n"); - err = -EIO; - goto out_detach_client; + kfree(camera); + return -EIO; } indycam_regdump(client); @@ -338,8 +347,8 @@ static int indycam_attach(struct i2c_adapter *adap, int addr, int kind) INDYCAM_CONTROL_AGCENA | INDYCAM_CONTROL_AWBCTL); if (err) { printk(KERN_ERR "IndyCam: White balancing camera failed\n"); - err = -EIO; - goto out_detach_client; + kfree(camera); + return -EIO; } indycam_regdump(client); @@ -347,124 +356,37 @@ static int indycam_attach(struct i2c_adapter *adap, int addr, int kind) printk(KERN_INFO "IndyCam initialized\n"); return 0; - -out_detach_client: - i2c_detach_client(client); -out_free_camera: - kfree(camera); -out_free_client: - kfree(client); - return err; } -static int indycam_probe(struct i2c_adapter *adap) -{ - /* Indy specific crap */ - if (adap->id == I2C_HW_SGI_VINO) - return indycam_attach(adap, INDYCAM_ADDR, 0); - /* Feel free to add probe here :-) */ - return -ENODEV; -} - -static int indycam_detach(struct i2c_client *client) +static int indycam_remove(struct i2c_client *client) { struct indycam *camera = i2c_get_clientdata(client); - i2c_detach_client(client); kfree(camera); - kfree(client); return 0; } -static int indycam_command(struct i2c_client *client, unsigned int cmd, - void *arg) +static int indycam_legacy_probe(struct i2c_adapter *adapter) { - // struct indycam *camera = i2c_get_clientdata(client); - - /* The old video_decoder interface just isn't enough, - * so we'll use some custom commands. */ - switch (cmd) { - case DECODER_GET_CAPABILITIES: { - struct video_decoder_capability *cap = arg; - - cap->flags = VIDEO_DECODER_NTSC; - cap->inputs = 1; - cap->outputs = 1; - break; - } - case DECODER_GET_STATUS: { - int *iarg = arg; - - *iarg = DECODER_STATUS_GOOD | DECODER_STATUS_NTSC | - DECODER_STATUS_COLOR; - break; - } - case DECODER_SET_NORM: { - int *iarg = arg; - - switch (*iarg) { - case VIDEO_MODE_NTSC: - break; - default: - return -EINVAL; - } - break; - } - case DECODER_SET_INPUT: { - int *iarg = arg; - - if (*iarg != 0) - return -EINVAL; - break; - } - case DECODER_SET_OUTPUT: { - int *iarg = arg; - - if (*iarg != 0) - return -EINVAL; - break; - } - case DECODER_ENABLE_OUTPUT: { - /* Always enabled */ - break; - } - case DECODER_SET_PICTURE: { - // struct video_picture *pic = arg; - /* TODO: convert values for indycam_set_controls() */ - break; - } - case DECODER_INDYCAM_GET_CONTROL: { - return indycam_get_control(client, arg); - } - case DECODER_INDYCAM_SET_CONTROL: { - return indycam_set_control(client, arg); - } - default: - return -EINVAL; - } - - return 0; + return adapter->id == I2C_HW_SGI_VINO; } -static struct i2c_driver i2c_driver_indycam = { - .driver = { - .name = "indycam", - }, - .id = I2C_DRIVERID_INDYCAM, - .attach_adapter = indycam_probe, - .detach_client = indycam_detach, - .command = indycam_command, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +static const struct i2c_device_id indycam_id[] = { + { "indycam", 0 }, + { } }; +MODULE_DEVICE_TABLE(i2c, indycam_id); -static int __init indycam_init(void) -{ - return i2c_add_driver(&i2c_driver_indycam); -} - -static void __exit indycam_exit(void) -{ - i2c_del_driver(&i2c_driver_indycam); -} - -module_init(indycam_init); -module_exit(indycam_exit); +#endif +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "indycam", + .driverid = I2C_DRIVERID_INDYCAM, + .command = indycam_command, + .probe = indycam_probe, + .remove = indycam_remove, + .legacy_probe = indycam_legacy_probe, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + .id_table = indycam_id, +#endif +}; diff --git a/linux/drivers/media/video/indycam.h b/linux/drivers/media/video/indycam.h index e6ee82063..881f21c47 100644 --- a/linux/drivers/media/video/indycam.h +++ b/linux/drivers/media/video/indycam.h @@ -87,22 +87,7 @@ /* Driver interface definitions */ -#define INDYCAM_CONTROL_AGC 0 /* boolean */ -#define INDYCAM_CONTROL_AWB 1 /* boolean */ -#define INDYCAM_CONTROL_SHUTTER 2 -#define INDYCAM_CONTROL_GAIN 3 -#define INDYCAM_CONTROL_RED_BALANCE 4 -#define INDYCAM_CONTROL_BLUE_BALANCE 5 -#define INDYCAM_CONTROL_RED_SATURATION 6 -#define INDYCAM_CONTROL_BLUE_SATURATION 7 -#define INDYCAM_CONTROL_GAMMA 8 - -struct indycam_control { - u8 type; - s32 value; -}; - -#define DECODER_INDYCAM_GET_CONTROL _IOR('d', 193, struct indycam_control) -#define DECODER_INDYCAM_SET_CONTROL _IOW('d', 194, struct indycam_control) +#define INDYCAM_CONTROL_RED_SATURATION (V4L2_CID_PRIVATE_BASE + 0) +#define INDYCAM_CONTROL_BLUE_SATURATION (V4L2_CID_PRIVATE_BASE + 1) #endif diff --git a/linux/drivers/media/video/saa7191.c b/linux/drivers/media/video/saa7191.c index f8313aa44..2c4c8ac5c 100644 --- a/linux/drivers/media/video/saa7191.c +++ b/linux/drivers/media/video/saa7191.c @@ -19,8 +19,7 @@ #include #include -#include -#include +#include #include #include #include @@ -58,7 +57,7 @@ struct saa7191 { u8 reg[25]; int input; - int norm; + v4l2_std_id norm; }; static const u8 initseq[] = { @@ -192,7 +191,7 @@ static int saa7191_set_input(struct i2c_client *client, int input) return 0; } -static int saa7191_set_norm(struct i2c_client *client, int norm) +static int saa7191_set_norm(struct i2c_client *client, v4l2_std_id norm) { struct saa7191 *decoder = i2c_get_clientdata(client); u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC); @@ -200,24 +199,20 @@ static int saa7191_set_norm(struct i2c_client *client, int norm) u8 chcv = saa7191_read_reg(client, SAA7191_REG_CHCV); int err; - switch(norm) { - case SAA7191_NORM_PAL: + if (norm & V4L2_STD_PAL) { stdc &= ~SAA7191_STDC_SECS; ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL); chcv = SAA7191_CHCV_PAL; - break; - case SAA7191_NORM_NTSC: + } else if (norm & V4L2_STD_NTSC) { stdc &= ~SAA7191_STDC_SECS; ctl3 &= ~SAA7191_CTL3_AUFD; ctl3 |= SAA7191_CTL3_FSEL; chcv = SAA7191_CHCV_NTSC; - break; - case SAA7191_NORM_SECAM: + } else if (norm & V4L2_STD_SECAM) { stdc |= SAA7191_STDC_SECS; ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL); chcv = SAA7191_CHCV_PAL; - break; - default: + } else { return -EINVAL; } @@ -235,7 +230,7 @@ static int saa7191_set_norm(struct i2c_client *client, int norm) dprintk("ctl3: %02x stdc: %02x chcv: %02x\n", ctl3, stdc, chcv); - dprintk("norm: %d\n", norm); + dprintk("norm: %llx\n", norm); return 0; } @@ -263,15 +258,19 @@ static int saa7191_wait_for_signal(struct i2c_client *client, u8 *status) return -EBUSY; } -static int saa7191_autodetect_norm_extended(struct i2c_client *client) +static int saa7191_autodetect_norm_extended(struct i2c_client *client, + v4l2_std_id *norm) { + struct saa7191 *decoder = i2c_get_clientdata(client); u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC); u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3); u8 status; + v4l2_std_id old_norm = decoder->norm; int err = 0; dprintk("SAA7191 extended signal auto-detection...\n"); + *norm = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM; stdc &= ~SAA7191_STDC_SECS; ctl3 &= ~(SAA7191_CTL3_FSEL); @@ -302,14 +301,15 @@ static int saa7191_autodetect_norm_extended(struct i2c_client *client) if (status & SAA7191_STATUS_FIDT) { /* 60Hz signal -> NTSC */ dprintk("60Hz signal: NTSC\n"); - return saa7191_set_norm(client, SAA7191_NORM_NTSC); + *norm = V4L2_STD_NTSC; + return 0; } /* 50Hz signal */ dprintk("50Hz signal: Trying PAL...\n"); /* try PAL first */ - err = saa7191_set_norm(client, SAA7191_NORM_PAL); + err = saa7191_set_norm(client, V4L2_STD_PAL); if (err) goto out; @@ -322,20 +322,20 @@ static int saa7191_autodetect_norm_extended(struct i2c_client *client) /* not 50Hz ? */ if (status & SAA7191_STATUS_FIDT) { dprintk("No 50Hz signal\n"); - err = -EAGAIN; - goto out; + saa7191_set_norm(client, old_norm); + return -EAGAIN; } if (status & SAA7191_STATUS_CODE) { dprintk("PAL\n"); - return 0; + *norm = V4L2_STD_PAL; + return saa7191_set_norm(client, old_norm); } dprintk("No color detected with PAL - Trying SECAM...\n"); /* no color detected ? -> try SECAM */ - err = saa7191_set_norm(client, - SAA7191_NORM_SECAM); + err = saa7191_set_norm(client, V4L2_STD_SECAM); if (err) goto out; @@ -355,29 +355,14 @@ static int saa7191_autodetect_norm_extended(struct i2c_client *client) if (status & SAA7191_STATUS_CODE) { /* Color detected -> SECAM */ dprintk("SECAM\n"); - return 0; + *norm = V4L2_STD_SECAM; + return saa7191_set_norm(client, old_norm); } dprintk("No color detected with SECAM - Going back to PAL.\n"); - /* still no color detected ? - * -> set norm back to PAL */ - err = saa7191_set_norm(client, - SAA7191_NORM_PAL); - if (err) - goto out; - out: - ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3); - if (ctl3 & SAA7191_CTL3_AUFD) { - ctl3 &= ~(SAA7191_CTL3_AUFD); - err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3); - if (err) { - err = -EIO; - } - } - - return err; + return saa7191_set_norm(client, old_norm); } static int saa7191_autodetect_norm(struct i2c_client *client) @@ -404,26 +389,26 @@ static int saa7191_autodetect_norm(struct i2c_client *client) if (status & SAA7191_STATUS_FIDT) { /* 60hz signal -> NTSC */ dprintk("NTSC\n"); - return saa7191_set_norm(client, SAA7191_NORM_NTSC); + return saa7191_set_norm(client, V4L2_STD_NTSC); } else { /* 50hz signal -> PAL */ dprintk("PAL\n"); - return saa7191_set_norm(client, SAA7191_NORM_PAL); + return saa7191_set_norm(client, V4L2_STD_PAL); } } static int saa7191_get_control(struct i2c_client *client, - struct saa7191_control *ctrl) + struct v4l2_control *ctrl) { u8 reg; int ret = 0; - switch (ctrl->type) { + switch (ctrl->id) { case SAA7191_CONTROL_BANDPASS: case SAA7191_CONTROL_BANDPASS_WEIGHT: case SAA7191_CONTROL_CORING: reg = saa7191_read_reg(client, SAA7191_REG_LUMA); - switch (ctrl->type) { + switch (ctrl->id) { case SAA7191_CONTROL_BANDPASS: ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK) >> SAA7191_LUMA_BPSS_SHIFT; @@ -441,13 +426,13 @@ static int saa7191_get_control(struct i2c_client *client, case SAA7191_CONTROL_FORCE_COLOUR: case SAA7191_CONTROL_CHROMA_GAIN: reg = saa7191_read_reg(client, SAA7191_REG_GAIN); - if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR) + if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR) ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0; else ctrl->value = ((s32)reg & SAA7191_GAIN_LFIS_MASK) >> SAA7191_GAIN_LFIS_SHIFT; break; - case SAA7191_CONTROL_HUE: + case V4L2_CID_HUE: reg = saa7191_read_reg(client, SAA7191_REG_HUEC); if (reg < 0x80) reg += 0x80; @@ -479,17 +464,17 @@ static int saa7191_get_control(struct i2c_client *client, } static int saa7191_set_control(struct i2c_client *client, - struct saa7191_control *ctrl) + struct v4l2_control *ctrl) { u8 reg; int ret = 0; - switch (ctrl->type) { + switch (ctrl->id) { case SAA7191_CONTROL_BANDPASS: case SAA7191_CONTROL_BANDPASS_WEIGHT: case SAA7191_CONTROL_CORING: reg = saa7191_read_reg(client, SAA7191_REG_LUMA); - switch (ctrl->type) { + switch (ctrl->id) { case SAA7191_CONTROL_BANDPASS: reg &= ~SAA7191_LUMA_BPSS_MASK; reg |= (ctrl->value << SAA7191_LUMA_BPSS_SHIFT) @@ -511,7 +496,7 @@ static int saa7191_set_control(struct i2c_client *client, case SAA7191_CONTROL_FORCE_COLOUR: case SAA7191_CONTROL_CHROMA_GAIN: reg = saa7191_read_reg(client, SAA7191_REG_GAIN); - if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR) { + if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR) { if (ctrl->value) reg |= SAA7191_GAIN_COLO; else @@ -523,7 +508,7 @@ static int saa7191_set_control(struct i2c_client *client, } ret = saa7191_write_reg(client, SAA7191_REG_GAIN, reg); break; - case SAA7191_CONTROL_HUE: + case V4L2_CID_HUE: reg = ctrl->value & 0xff; if (reg < 0x80) reg += 0x80; @@ -569,141 +554,42 @@ static int saa7191_set_control(struct i2c_client *client, static int saa7191_command(struct i2c_client *client, unsigned int cmd, void *arg) { - struct saa7191 *decoder = i2c_get_clientdata(client); - switch (cmd) { - case DECODER_GET_CAPABILITIES: { - struct video_decoder_capability *cap = arg; - - cap->flags = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC | - VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO; - cap->inputs = (client->adapter->id == I2C_HW_SGI_VINO) ? 2 : 1; - cap->outputs = 1; - break; - } - case DECODER_GET_STATUS: { - int *iarg = arg; + case VIDIOC_INT_G_INPUT_STATUS: { + u32 *iarg = arg; u8 status; - int res = 0; + int res = V4L2_IN_ST_NO_SIGNAL; - if (saa7191_read_status(client, &status)) { + if (saa7191_read_status(client, &status)) return -EIO; - } if ((status & SAA7191_STATUS_HLCK) == 0) - res |= DECODER_STATUS_GOOD; - if (status & SAA7191_STATUS_CODE) - res |= DECODER_STATUS_COLOR; - switch (decoder->norm) { - case SAA7191_NORM_NTSC: - res |= DECODER_STATUS_NTSC; - break; - case SAA7191_NORM_PAL: - res |= DECODER_STATUS_PAL; - break; - case SAA7191_NORM_SECAM: - res |= DECODER_STATUS_SECAM; - break; - case SAA7191_NORM_AUTO: - default: - if (status & SAA7191_STATUS_FIDT) - res |= DECODER_STATUS_NTSC; - else - res |= DECODER_STATUS_PAL; - break; - } + res = 0; + if (!(status & SAA7191_STATUS_CODE)) + res |= V4L2_IN_ST_NO_COLOR; *iarg = res; break; } - case DECODER_SET_NORM: { - int *iarg = arg; - - switch (*iarg) { - case VIDEO_MODE_AUTO: - return saa7191_autodetect_norm(client); - case VIDEO_MODE_PAL: - return saa7191_set_norm(client, SAA7191_NORM_PAL); - case VIDEO_MODE_NTSC: - return saa7191_set_norm(client, SAA7191_NORM_NTSC); - case VIDEO_MODE_SECAM: - return saa7191_set_norm(client, SAA7191_NORM_SECAM); - default: - return -EINVAL; - } - break; - } - case DECODER_SET_INPUT: { - int *iarg = arg; - - switch (client->adapter->id) { - case I2C_HW_SGI_VINO: - return saa7191_set_input(client, *iarg); - default: - if (*iarg != 0) - return -EINVAL; - } - break; - } - case DECODER_SET_OUTPUT: { - int *iarg = arg; - /* not much choice of outputs */ - if (*iarg != 0) - return -EINVAL; - break; - } - case DECODER_ENABLE_OUTPUT: { - /* Always enabled */ - break; - } - case DECODER_SET_PICTURE: { - struct video_picture *pic = arg; - unsigned val; - int err; - - val = (pic->hue >> 8) - 0x80; + case VIDIOC_QUERYSTD: + return saa7191_autodetect_norm_extended(client, arg); - err = saa7191_write_reg(client, SAA7191_REG_HUEC, val); - if (err) - return -EIO; + case VIDIOC_S_STD: { + v4l2_std_id *istd = arg; - break; + return saa7191_set_norm(client, *istd); } - case DECODER_SAA7191_GET_STATUS: { - struct saa7191_status *status = arg; - u8 status_reg; - - if (saa7191_read_status(client, &status_reg)) - return -EIO; - - status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0) - ? 1 : 0; - status->signal_60hz = (status_reg & SAA7191_STATUS_FIDT) - ? 1 : 0; - status->color = (status_reg & SAA7191_STATUS_CODE) ? 1 : 0; + case VIDIOC_INT_S_VIDEO_ROUTING: { + struct v4l2_routing *route = arg; - status->input = decoder->input; - status->norm = decoder->norm; - - break; + return saa7191_set_input(client, route->input); } - case DECODER_SAA7191_SET_NORM: { - int *norm = arg; - - switch (*norm) { - case SAA7191_NORM_AUTO: - return saa7191_autodetect_norm(client); - case SAA7191_NORM_AUTO_EXT: - return saa7191_autodetect_norm_extended(client); - default: - return saa7191_set_norm(client, *norm); - } - } - case DECODER_SAA7191_GET_CONTROL: { + + case VIDIOC_G_CTRL: return saa7191_get_control(client, arg); - } - case DECODER_SAA7191_SET_CONTROL: { + + case VIDIOC_S_CTRL: return saa7191_set_control(client, arg); - } + default: return -EINVAL; } @@ -738,7 +624,7 @@ static int saa7191_probe(struct i2c_client *client, printk(KERN_INFO "SAA7191 initialized\n"); decoder->input = SAA7191_INPUT_COMPOSITE; - decoder->norm = SAA7191_NORM_PAL; + decoder->norm = V4L2_STD_PAL; err = saa7191_autodetect_norm(client); if (err && (err != -EBUSY)) diff --git a/linux/drivers/media/video/saa7191.h b/linux/drivers/media/video/saa7191.h index a2310da19..803c74d60 100644 --- a/linux/drivers/media/video/saa7191.h +++ b/linux/drivers/media/video/saa7191.h @@ -176,11 +176,9 @@ #define SAA7191_INPUT_COMPOSITE 0 #define SAA7191_INPUT_SVIDEO 1 -#define SAA7191_NORM_AUTO 0 #define SAA7191_NORM_PAL 1 #define SAA7191_NORM_NTSC 2 #define SAA7191_NORM_SECAM 3 -#define SAA7191_NORM_AUTO_EXT 4 /* extended auto-detection */ struct saa7191_status { /* 0=no signal, 1=signal detected */ @@ -232,24 +230,16 @@ struct saa7191_status { #define SAA7191_VNR_MAX 0x03 #define SAA7191_VNR_DEFAULT 0x00 -#define SAA7191_CONTROL_BANDPASS 0 -#define SAA7191_CONTROL_BANDPASS_WEIGHT 1 -#define SAA7191_CONTROL_CORING 2 -#define SAA7191_CONTROL_FORCE_COLOUR 3 /* boolean */ -#define SAA7191_CONTROL_CHROMA_GAIN 4 -#define SAA7191_CONTROL_HUE 5 -#define SAA7191_CONTROL_VTRC 6 /* boolean */ -#define SAA7191_CONTROL_LUMA_DELAY 7 -#define SAA7191_CONTROL_VNR 8 - -struct saa7191_control { - u8 type; - s32 value; -}; +#define SAA7191_CONTROL_BANDPASS (V4L2_CID_PRIVATE_BASE + 0) +#define SAA7191_CONTROL_BANDPASS_WEIGHT (V4L2_CID_PRIVATE_BASE + 1) +#define SAA7191_CONTROL_CORING (V4L2_CID_PRIVATE_BASE + 2) +#define SAA7191_CONTROL_FORCE_COLOUR (V4L2_CID_PRIVATE_BASE + 3) +#define SAA7191_CONTROL_CHROMA_GAIN (V4L2_CID_PRIVATE_BASE + 4) +#define SAA7191_CONTROL_VTRC (V4L2_CID_PRIVATE_BASE + 5) +#define SAA7191_CONTROL_LUMA_DELAY (V4L2_CID_PRIVATE_BASE + 6) +#define SAA7191_CONTROL_VNR (V4L2_CID_PRIVATE_BASE + 7) #define DECODER_SAA7191_GET_STATUS _IOR('d', 195, struct saa7191_status) #define DECODER_SAA7191_SET_NORM _IOW('d', 196, int) -#define DECODER_SAA7191_GET_CONTROL _IOR('d', 197, struct saa7191_control) -#define DECODER_SAA7191_SET_CONTROL _IOW('d', 198, struct saa7191_control) #endif diff --git a/linux/drivers/media/video/vino.c b/linux/drivers/media/video/vino.c index bdd035cf9..6b87a55a9 100644 --- a/linux/drivers/media/video/vino.c +++ b/linux/drivers/media/video/vino.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include @@ -139,10 +138,6 @@ MODULE_LICENSE("GPL"); #define VINO_DATA_NORM_PAL 1 #define VINO_DATA_NORM_SECAM 2 #define VINO_DATA_NORM_D1 3 -/* The following are special entries that can be used to - * autodetect the norm. */ -#define VINO_DATA_NORM_AUTO 0xfe -#define VINO_DATA_NORM_AUTO_EXT 0xff #define VINO_DATA_NORM_COUNT 4 @@ -360,11 +355,11 @@ static const struct vino_input vino_inputs[] = { .name = "Composite", .std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, - },{ + }, { .name = "S-Video", .std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, - },{ + }, { .name = "D1/IndyCam", .std = V4L2_STD_NTSC, } @@ -376,17 +371,17 @@ static const struct vino_data_format vino_data_formats[] = { .bpp = 1, .pixelformat = V4L2_PIX_FMT_GREY, .colorspace = V4L2_COLORSPACE_SMPTE170M, - },{ + }, { .description = "8-bit dithered RGB 3-3-2", .bpp = 1, .pixelformat = V4L2_PIX_FMT_RGB332, .colorspace = V4L2_COLORSPACE_SRGB, - },{ + }, { .description = "32-bit RGB", .bpp = 4, .pixelformat = V4L2_PIX_FMT_RGB32, .colorspace = V4L2_COLORSPACE_SRGB, - },{ + }, { .description = "YUV 4:2:2", .bpp = 2, .pixelformat = V4L2_PIX_FMT_YUYV, // XXX: swapped? @@ -417,7 +412,7 @@ static const struct vino_data_norm vino_data_norms[] = { + VINO_NTSC_HEIGHT / 2 - 1, .right = VINO_NTSC_WIDTH, }, - },{ + }, { .description = "PAL", .std = V4L2_STD_PAL, .fps_min = 5, @@ -439,7 +434,7 @@ static const struct vino_data_norm vino_data_norms[] = { + VINO_PAL_HEIGHT / 2 - 1, .right = VINO_PAL_WIDTH, }, - },{ + }, { .description = "SECAM", .std = V4L2_STD_SECAM, .fps_min = 5, @@ -461,7 +456,7 @@ static const struct vino_data_norm vino_data_norms[] = { + VINO_PAL_HEIGHT / 2 - 1, .right = VINO_PAL_WIDTH, }, - },{ + }, { .description = "NTSC/D1", .std = V4L2_STD_NTSC, .fps_min = 6, @@ -497,9 +492,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = { .maximum = 1, .step = 1, .default_value = INDYCAM_AGC_DEFAULT, - .flags = 0, - .reserved = { INDYCAM_CONTROL_AGC, 0 }, - },{ + }, { .id = V4L2_CID_AUTO_WHITE_BALANCE, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Automatic White Balance", @@ -507,9 +500,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = { .maximum = 1, .step = 1, .default_value = INDYCAM_AWB_DEFAULT, - .flags = 0, - .reserved = { INDYCAM_CONTROL_AWB, 0 }, - },{ + }, { .id = V4L2_CID_GAIN, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Gain", @@ -517,29 +508,23 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = { .maximum = INDYCAM_GAIN_MAX, .step = 1, .default_value = INDYCAM_GAIN_DEFAULT, - .flags = 0, - .reserved = { INDYCAM_CONTROL_GAIN, 0 }, - },{ - .id = V4L2_CID_PRIVATE_BASE, + }, { + .id = INDYCAM_CONTROL_RED_SATURATION, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Red Saturation", .minimum = INDYCAM_RED_SATURATION_MIN, .maximum = INDYCAM_RED_SATURATION_MAX, .step = 1, .default_value = INDYCAM_RED_SATURATION_DEFAULT, - .flags = 0, - .reserved = { INDYCAM_CONTROL_RED_SATURATION, 0 }, - },{ - .id = V4L2_CID_PRIVATE_BASE + 1, + }, { + .id = INDYCAM_CONTROL_BLUE_SATURATION, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Blue Saturation", .minimum = INDYCAM_BLUE_SATURATION_MIN, .maximum = INDYCAM_BLUE_SATURATION_MAX, .step = 1, .default_value = INDYCAM_BLUE_SATURATION_DEFAULT, - .flags = 0, - .reserved = { INDYCAM_CONTROL_BLUE_SATURATION, 0 }, - },{ + }, { .id = V4L2_CID_RED_BALANCE, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Red Balance", @@ -547,9 +532,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = { .maximum = INDYCAM_RED_BALANCE_MAX, .step = 1, .default_value = INDYCAM_RED_BALANCE_DEFAULT, - .flags = 0, - .reserved = { INDYCAM_CONTROL_RED_BALANCE, 0 }, - },{ + }, { .id = V4L2_CID_BLUE_BALANCE, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Blue Balance", @@ -557,9 +540,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = { .maximum = INDYCAM_BLUE_BALANCE_MAX, .step = 1, .default_value = INDYCAM_BLUE_BALANCE_DEFAULT, - .flags = 0, - .reserved = { INDYCAM_CONTROL_BLUE_BALANCE, 0 }, - },{ + }, { .id = V4L2_CID_EXPOSURE, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Shutter Control", @@ -567,9 +548,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = { .maximum = INDYCAM_SHUTTER_MAX, .step = 1, .default_value = INDYCAM_SHUTTER_DEFAULT, - .flags = 0, - .reserved = { INDYCAM_CONTROL_SHUTTER, 0 }, - },{ + }, { .id = V4L2_CID_GAMMA, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Gamma", @@ -577,8 +556,6 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = { .maximum = INDYCAM_GAMMA_MAX, .step = 1, .default_value = INDYCAM_GAMMA_DEFAULT, - .flags = 0, - .reserved = { INDYCAM_CONTROL_GAMMA, 0 }, } }; @@ -593,88 +570,70 @@ struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = { .maximum = SAA7191_HUE_MAX, .step = 1, .default_value = SAA7191_HUE_DEFAULT, - .flags = 0, - .reserved = { SAA7191_CONTROL_HUE, 0 }, - },{ - .id = V4L2_CID_PRIVATE_BASE, + }, { + .id = SAA7191_CONTROL_BANDPASS, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Luminance Bandpass", .minimum = SAA7191_BANDPASS_MIN, .maximum = SAA7191_BANDPASS_MAX, .step = 1, .default_value = SAA7191_BANDPASS_DEFAULT, - .flags = 0, - .reserved = { SAA7191_CONTROL_BANDPASS, 0 }, - },{ - .id = V4L2_CID_PRIVATE_BASE + 1, + }, { + .id = SAA7191_CONTROL_BANDPASS_WEIGHT, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Luminance Bandpass Weight", .minimum = SAA7191_BANDPASS_WEIGHT_MIN, .maximum = SAA7191_BANDPASS_WEIGHT_MAX, .step = 1, .default_value = SAA7191_BANDPASS_WEIGHT_DEFAULT, - .flags = 0, - .reserved = { SAA7191_CONTROL_BANDPASS_WEIGHT, 0 }, - },{ - .id = V4L2_CID_PRIVATE_BASE + 2, + }, { + .id = SAA7191_CONTROL_CORING, .type = V4L2_CTRL_TYPE_INTEGER, .name = "HF Luminance Coring", .minimum = SAA7191_CORING_MIN, .maximum = SAA7191_CORING_MAX, .step = 1, .default_value = SAA7191_CORING_DEFAULT, - .flags = 0, - .reserved = { SAA7191_CONTROL_CORING, 0 }, - },{ - .id = V4L2_CID_PRIVATE_BASE + 3, + }, { + .id = SAA7191_CONTROL_FORCE_COLOUR, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Force Colour", .minimum = SAA7191_FORCE_COLOUR_MIN, .maximum = SAA7191_FORCE_COLOUR_MAX, .step = 1, .default_value = SAA7191_FORCE_COLOUR_DEFAULT, - .flags = 0, - .reserved = { SAA7191_CONTROL_FORCE_COLOUR, 0 }, - },{ - .id = V4L2_CID_PRIVATE_BASE + 4, + }, { + .id = SAA7191_CONTROL_CHROMA_GAIN, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Chrominance Gain Control", .minimum = SAA7191_CHROMA_GAIN_MIN, .maximum = SAA7191_CHROMA_GAIN_MAX, .step = 1, .default_value = SAA7191_CHROMA_GAIN_DEFAULT, - .flags = 0, - .reserved = { SAA7191_CONTROL_CHROMA_GAIN, 0 }, - },{ - .id = V4L2_CID_PRIVATE_BASE + 5, + }, { + .id = SAA7191_CONTROL_VTRC, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "VTR Time Constant", .minimum = SAA7191_VTRC_MIN, .maximum = SAA7191_VTRC_MAX, .step = 1, .default_value = SAA7191_VTRC_DEFAULT, - .flags = 0, - .reserved = { SAA7191_CONTROL_VTRC, 0 }, - },{ - .id = V4L2_CID_PRIVATE_BASE + 6, + }, { + .id = SAA7191_CONTROL_LUMA_DELAY, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Luminance Delay Compensation", .minimum = SAA7191_LUMA_DELAY_MIN, .maximum = SAA7191_LUMA_DELAY_MAX, .step = 1, .default_value = SAA7191_LUMA_DELAY_DEFAULT, - .flags = 0, - .reserved = { SAA7191_CONTROL_LUMA_DELAY, 0 }, - },{ - .id = V4L2_CID_PRIVATE_BASE + 7, + }, { + .id = SAA7191_CONTROL_VNR, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Vertical Noise Reduction", .minimum = SAA7191_VNR_MIN, .maximum = SAA7191_VNR_MAX, .step = 1, .default_value = SAA7191_VNR_DEFAULT, - .flags = 0, - .reserved = { SAA7191_CONTROL_VNR, 0 }, } }; @@ -2494,77 +2453,6 @@ static int vino_get_saa7191_input(int input) } } -static int vino_get_saa7191_norm(unsigned int data_norm) -{ - switch (data_norm) { - case VINO_DATA_NORM_AUTO: - return SAA7191_NORM_AUTO; - case VINO_DATA_NORM_AUTO_EXT: - return SAA7191_NORM_AUTO_EXT; - case VINO_DATA_NORM_PAL: - return SAA7191_NORM_PAL; - case VINO_DATA_NORM_NTSC: - return SAA7191_NORM_NTSC; - case VINO_DATA_NORM_SECAM: - return SAA7191_NORM_SECAM; - default: - printk(KERN_ERR "VINO: vino_get_saa7191_norm(): " - "invalid norm!\n"); - return -1; - } -} - -static int vino_get_from_saa7191_norm(int saa7191_norm) -{ - switch (saa7191_norm) { - case SAA7191_NORM_PAL: - return VINO_DATA_NORM_PAL; - case SAA7191_NORM_NTSC: - return VINO_DATA_NORM_NTSC; - case SAA7191_NORM_SECAM: - return VINO_DATA_NORM_SECAM; - default: - printk(KERN_ERR "VINO: vino_get_from_saa7191_norm(): " - "invalid norm!\n"); - return VINO_DATA_NORM_NONE; - } -} - -static int vino_saa7191_set_norm(unsigned int *data_norm) -{ - int saa7191_norm, new_data_norm; - int err = 0; - - saa7191_norm = vino_get_saa7191_norm(*data_norm); - - err = i2c_decoder_command(DECODER_SAA7191_SET_NORM, - &saa7191_norm); - if (err) - goto out; - - if ((*data_norm == VINO_DATA_NORM_AUTO) - || (*data_norm == VINO_DATA_NORM_AUTO_EXT)) { - struct saa7191_status status; - - err = i2c_decoder_command(DECODER_SAA7191_GET_STATUS, - &status); - if (err) - goto out; - - new_data_norm = - vino_get_from_saa7191_norm(status.norm); - if (new_data_norm == VINO_DATA_NORM_NONE) { - err = -EINVAL; - goto out; - } - - *data_norm = (unsigned int)new_data_norm; - } - -out: - return err; -} - /* execute with input_lock locked */ static int vino_is_input_owner(struct vino_channel_settings *vcs) { @@ -2597,15 +2485,16 @@ static int vino_acquire_input(struct vino_channel_settings *vcs) vcs->data_norm = VINO_DATA_NORM_D1; } else if (vino_drvdata->decoder.driver && (vino_drvdata->decoder.owner == VINO_NO_CHANNEL)) { - int input, data_norm; - int saa7191_input; + int input; + int data_norm; + v4l2_std_id norm; + struct v4l2_routing route = { 0, 0 }; i2c_use_client(vino_drvdata->decoder.driver); input = VINO_INPUT_COMPOSITE; - saa7191_input = vino_get_saa7191_input(input); - ret = i2c_decoder_command(DECODER_SET_INPUT, - &saa7191_input); + route.input = vino_get_saa7191_input(input); + ret = i2c_decoder_command(VIDIOC_INT_S_VIDEO_ROUTING, &route); if (ret) { ret = -EINVAL; goto out; @@ -2616,12 +2505,15 @@ static int vino_acquire_input(struct vino_channel_settings *vcs) /* Don't hold spinlocks while auto-detecting norm * as it may take a while... */ - data_norm = VINO_DATA_NORM_AUTO_EXT; - - ret = vino_saa7191_set_norm(&data_norm); - if ((ret == -EBUSY) || (ret == -EAGAIN)) { - data_norm = VINO_DATA_NORM_PAL; - ret = vino_saa7191_set_norm(&data_norm); + ret = i2c_decoder_command(VIDIOC_QUERYSTD, &norm); + if (!ret) { + for (data_norm = 0; data_norm < 3; data_norm++) { + if (vino_data_norms[data_norm].std & norm) + break; + } + if (data_norm == 3) + data_norm = VINO_DATA_NORM_PAL; + ret = i2c_decoder_command(VIDIOC_S_STD, &norm); } spin_lock_irqsave(&vino_drvdata->input_lock, flags); @@ -2688,11 +2580,11 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input) if (vino_drvdata->decoder.owner == vcs->channel) { int data_norm; - int saa7191_input; + v4l2_std_id norm; + struct v4l2_routing route = { 0, 0 }; - saa7191_input = vino_get_saa7191_input(input); - ret = i2c_decoder_command(DECODER_SET_INPUT, - &saa7191_input); + route.input = vino_get_saa7191_input(input); + ret = i2c_decoder_command(VIDIOC_INT_S_VIDEO_ROUTING, &route); if (ret) { vino_drvdata->decoder.owner = VINO_NO_CHANNEL; ret = -EINVAL; @@ -2704,12 +2596,15 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input) /* Don't hold spinlocks while auto-detecting norm * as it may take a while... */ - data_norm = VINO_DATA_NORM_AUTO_EXT; - - ret = vino_saa7191_set_norm(&data_norm); - if ((ret == -EBUSY) || (ret == -EAGAIN)) { - data_norm = VINO_DATA_NORM_PAL; - ret = vino_saa7191_set_norm(&data_norm); + ret = i2c_decoder_command(VIDIOC_QUERYSTD, &norm); + if (!ret) { + for (data_norm = 0; data_norm < 3; data_norm++) { + if (vino_data_norms[data_norm].std & norm) + break; + } + if (data_norm == 3) + data_norm = VINO_DATA_NORM_PAL; + ret = i2c_decoder_command(VIDIOC_S_STD, &norm); } spin_lock_irqsave(&vino_drvdata->input_lock, flags); @@ -2737,8 +2632,7 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input) if (vcs2->input == VINO_INPUT_D1) { vino_drvdata->camera.owner = vcs2->channel; } else { - i2c_release_client(vino_drvdata-> - camera.driver); + i2c_release_client(vino_drvdata->camera.driver); vino_drvdata->camera.owner = VINO_NO_CHANNEL; } } @@ -2833,18 +2727,16 @@ static int vino_set_data_norm(struct vino_channel_settings *vcs, switch (vcs->input) { case VINO_INPUT_D1: /* only one "norm" supported */ - if ((data_norm != VINO_DATA_NORM_D1) - && (data_norm != VINO_DATA_NORM_AUTO) - && (data_norm != VINO_DATA_NORM_AUTO_EXT)) + if (data_norm != VINO_DATA_NORM_D1) return -EINVAL; break; case VINO_INPUT_COMPOSITE: case VINO_INPUT_SVIDEO: { + v4l2_std_id norm; + if ((data_norm != VINO_DATA_NORM_PAL) && (data_norm != VINO_DATA_NORM_NTSC) - && (data_norm != VINO_DATA_NORM_SECAM) - && (data_norm != VINO_DATA_NORM_AUTO) - && (data_norm != VINO_DATA_NORM_AUTO_EXT)) + && (data_norm != VINO_DATA_NORM_SECAM)) return -EINVAL; spin_unlock_irqrestore(&vino_drvdata->input_lock, *flags); @@ -2852,7 +2744,8 @@ static int vino_set_data_norm(struct vino_channel_settings *vcs, /* Don't hold spinlocks while setting norm * as it may take a while... */ - err = vino_saa7191_set_norm(&data_norm); + norm = vino_data_norms[data_norm].std; + err = i2c_decoder_command(VIDIOC_S_STD, &norm); spin_lock_irqsave(&vino_drvdata->input_lock, *flags); @@ -3002,14 +2895,8 @@ static int vino_enum_input(struct file *file, void *__fh, i->std = vino_inputs[input].std; strcpy(i->name, vino_inputs[input].name); - if ((input == VINO_INPUT_COMPOSITE) - || (input == VINO_INPUT_SVIDEO)) { - struct saa7191_status status; - i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status); - i->status |= status.signal ? 0 : V4L2_IN_ST_NO_SIGNAL; - i->status |= status.color ? 0 : V4L2_IN_ST_NO_COLOR; - } - + if (input == VINO_INPUT_COMPOSITE || input == VINO_INPUT_SVIDEO) + i2c_decoder_command(VIDIOC_INT_G_INPUT_STATUS, &i->status); return 0; } @@ -3066,19 +2953,7 @@ static int vino_querystd(struct file *file, void *__fh, break; case VINO_INPUT_COMPOSITE: case VINO_INPUT_SVIDEO: { - struct saa7191_status status; - - i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status); - - if (status.signal) { - if (status.signal_60hz) { - *std = V4L2_STD_NTSC; - } else { - *std = V4L2_STD_PAL | V4L2_STD_SECAM; - } - } else { - *std = vino_inputs[vcs->input].std; - } + i2c_decoder_command(VIDIOC_QUERYSTD, std); break; } default: @@ -3130,12 +3005,7 @@ static int vino_s_std(struct file *file, void *__fh, if (vcs->input == VINO_INPUT_D1) goto out; - if (((*std) & V4L2_STD_PAL) - && ((*std) & V4L2_STD_NTSC) - && ((*std) & V4L2_STD_SECAM)) { - ret = vino_set_data_norm(vcs, VINO_DATA_NORM_AUTO_EXT, - &flags); - } else if ((*std) & V4L2_STD_PAL) { + if ((*std) & V4L2_STD_PAL) { ret = vino_set_data_norm(vcs, VINO_DATA_NORM_PAL, &flags); } else if ((*std) & V4L2_STD_NTSC) { @@ -3801,56 +3671,38 @@ static int vino_g_ctrl(struct file *file, void *__fh, switch (vcs->input) { case VINO_INPUT_D1: { - struct indycam_control indycam_ctrl; - + err = -EINVAL; for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) { - if (vino_indycam_v4l2_controls[i].id == - control->id) { - goto found1; + if (vino_indycam_v4l2_controls[i].id == control->id) { + err = 0; + break; } } - err = -EINVAL; - goto out; - -found1: - indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0]; - - err = i2c_camera_command(DECODER_INDYCAM_GET_CONTROL, - &indycam_ctrl); - if (err) { - err = -EINVAL; + if (err) goto out; - } - control->value = indycam_ctrl.value; + err = i2c_camera_command(VIDIOC_G_CTRL, &control); + if (err) + err = -EINVAL; break; } case VINO_INPUT_COMPOSITE: case VINO_INPUT_SVIDEO: { - struct saa7191_control saa7191_ctrl; - + err = -EINVAL; for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) { - if (vino_saa7191_v4l2_controls[i].id == - control->id) { - goto found2; + if (vino_saa7191_v4l2_controls[i].id == control->id) { + err = 0; + break; } } - err = -EINVAL; - goto out; - -found2: - saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0]; - - err = i2c_decoder_command(DECODER_SAA7191_GET_CONTROL, - &saa7191_ctrl); - if (err) { - err = -EINVAL; + if (err) goto out; - } - control->value = saa7191_ctrl.value; + err = i2c_decoder_command(VIDIOC_G_CTRL, &control); + if (err) + err = -EINVAL; break; } default: @@ -3880,65 +3732,43 @@ static int vino_s_ctrl(struct file *file, void *__fh, switch (vcs->input) { case VINO_INPUT_D1: { - struct indycam_control indycam_ctrl; - + err = -EINVAL; for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) { - if (vino_indycam_v4l2_controls[i].id == - control->id) { - if ((control->value >= - vino_indycam_v4l2_controls[i].minimum) - && (control->value <= - vino_indycam_v4l2_controls[i]. - maximum)) { - goto found1; - } else { - err = -ERANGE; - goto out; - } + if (vino_indycam_v4l2_controls[i].id == control->id) { + err = 0; + break; } } - - err = -EINVAL; - goto out; - -found1: - indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0]; - indycam_ctrl.value = control->value; - - err = i2c_camera_command(DECODER_INDYCAM_SET_CONTROL, - &indycam_ctrl); + if (err) + goto out; + if (control->value < vino_indycam_v4l2_controls[i].minimum || + control->value > vino_indycam_v4l2_controls[i].maximum) { + err = -ERANGE; + goto out; + } + err = i2c_camera_command(VIDIOC_S_CTRL, &control); if (err) err = -EINVAL; break; } case VINO_INPUT_COMPOSITE: case VINO_INPUT_SVIDEO: { - struct saa7191_control saa7191_ctrl; - + err = -EINVAL; for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) { - if (vino_saa7191_v4l2_controls[i].id == - control->id) { - if ((control->value >= - vino_saa7191_v4l2_controls[i].minimum) - && (control->value <= - vino_saa7191_v4l2_controls[i]. - maximum)) { - goto found2; - } else { - err = -ERANGE; - goto out; - } + if (vino_saa7191_v4l2_controls[i].id == control->id) { + err = 0; + break; } } - err = -EINVAL; - goto out; - -found2: - saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0]; - saa7191_ctrl.value = control->value; + if (err) + goto out; + if (control->value < vino_saa7191_v4l2_controls[i].minimum || + control->value > vino_saa7191_v4l2_controls[i].maximum) { + err = -ERANGE; + goto out; + } - err = i2c_decoder_command(DECODER_SAA7191_SET_CONTROL, - &saa7191_ctrl); + err = i2c_decoder_command(VIDIOC_S_CTRL, &control); if (err) err = -EINVAL; break; -- cgit v1.2.3 From 86772b4bbf98d80df9084f91a47c6290f2d4a25b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 13 Feb 2009 23:38:10 +0100 Subject: indycam: convert to v4l2_subdev From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/indycam.c | 128 +++++++++++++++++++--------------- linux/include/media/v4l2-chip-ident.h | 3 + 2 files changed, 74 insertions(+), 57 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/indycam.c b/linux/drivers/media/video/indycam.c index 492f1e6cb..9c09fe1b8 100644 --- a/linux/drivers/media/video/indycam.c +++ b/linux/drivers/media/video/indycam.c @@ -22,7 +22,8 @@ /* IndyCam decodes stream of photons into digital image representation ;-) */ #include #include -#include +#include +#include #include #include "indycam.h" @@ -49,10 +50,15 @@ I2C_CLIENT_INSMOD; #endif struct indycam { - struct i2c_client *client; + struct v4l2_subdev sd; u8 version; }; +static inline struct indycam *to_indycam(struct v4l2_subdev *sd) +{ + return container_of(sd, struct indycam, sd); +} + static const u8 initseq[] = { INDYCAM_CONTROL_AGCENA, /* INDYCAM_CONTROL */ INDYCAM_SHUTTER_60, /* INDYCAM_SHUTTER */ @@ -66,8 +72,9 @@ static const u8 initseq[] = { /* IndyCam register handling */ -static int indycam_read_reg(struct i2c_client *client, u8 reg, u8 *value) +static int indycam_read_reg(struct v4l2_subdev *sd, u8 reg, u8 *value) { + struct i2c_client *client = v4l2_get_subdevdata(sd); int ret; if (reg == INDYCAM_REG_RESET) { @@ -90,12 +97,12 @@ static int indycam_read_reg(struct i2c_client *client, u8 reg, u8 *value) return 0; } -static int indycam_write_reg(struct i2c_client *client, u8 reg, u8 value) +static int indycam_write_reg(struct v4l2_subdev *sd, u8 reg, u8 value) { + struct i2c_client *client = v4l2_get_subdevdata(sd); int err; - if ((reg == INDYCAM_REG_BRIGHTNESS) - || (reg == INDYCAM_REG_VERSION)) { + if (reg == INDYCAM_REG_BRIGHTNESS || reg == INDYCAM_REG_VERSION) { dprintk("indycam_write_reg(): " "skipping read-only register %d\n", reg); return 0; @@ -111,13 +118,13 @@ static int indycam_write_reg(struct i2c_client *client, u8 reg, u8 value) return err; } -static int indycam_write_block(struct i2c_client *client, u8 reg, +static int indycam_write_block(struct v4l2_subdev *sd, u8 reg, u8 length, u8 *data) { int i, err; for (i = 0; i < length; i++) { - err = indycam_write_reg(client, reg + i, data[i]); + err = indycam_write_reg(sd, reg + i, data[i]); if (err) return err; } @@ -128,29 +135,28 @@ static int indycam_write_block(struct i2c_client *client, u8 reg, /* Helper functions */ #ifdef INDYCAM_DEBUG -static void indycam_regdump_debug(struct i2c_client *client) +static void indycam_regdump_debug(struct v4l2_subdev *sd) { int i; u8 val; for (i = 0; i < 9; i++) { - indycam_read_reg(client, i, &val); + indycam_read_reg(sd, i, &val); dprintk("Reg %d = 0x%02x\n", i, val); } } #endif -static int indycam_get_control(struct i2c_client *client, - struct v4l2_control *ctrl) +static int indycam_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { - struct indycam *camera = i2c_get_clientdata(client); + struct indycam *camera = to_indycam(sd); u8 reg; int ret = 0; switch (ctrl->id) { case V4L2_CID_AUTOGAIN: case V4L2_CID_AUTO_WHITE_BALANCE: - ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, ®); + ret = indycam_read_reg(sd, INDYCAM_REG_CONTROL, ®); if (ret) return -EIO; if (ctrl->id == V4L2_CID_AUTOGAIN) @@ -161,38 +167,38 @@ static int indycam_get_control(struct i2c_client *client, ? 1 : 0; break; case V4L2_CID_EXPOSURE: - ret = indycam_read_reg(client, INDYCAM_REG_SHUTTER, ®); + ret = indycam_read_reg(sd, INDYCAM_REG_SHUTTER, ®); if (ret) return -EIO; ctrl->value = ((s32)reg == 0x00) ? 0xff : ((s32)reg - 1); break; case V4L2_CID_GAIN: - ret = indycam_read_reg(client, INDYCAM_REG_GAIN, ®); + ret = indycam_read_reg(sd, INDYCAM_REG_GAIN, ®); if (ret) return -EIO; ctrl->value = (s32)reg; break; case V4L2_CID_RED_BALANCE: - ret = indycam_read_reg(client, INDYCAM_REG_RED_BALANCE, ®); + ret = indycam_read_reg(sd, INDYCAM_REG_RED_BALANCE, ®); if (ret) return -EIO; ctrl->value = (s32)reg; break; case V4L2_CID_BLUE_BALANCE: - ret = indycam_read_reg(client, INDYCAM_REG_BLUE_BALANCE, ®); + ret = indycam_read_reg(sd, INDYCAM_REG_BLUE_BALANCE, ®); if (ret) return -EIO; ctrl->value = (s32)reg; break; case INDYCAM_CONTROL_RED_SATURATION: - ret = indycam_read_reg(client, + ret = indycam_read_reg(sd, INDYCAM_REG_RED_SATURATION, ®); if (ret) return -EIO; ctrl->value = (s32)reg; break; case INDYCAM_CONTROL_BLUE_SATURATION: - ret = indycam_read_reg(client, + ret = indycam_read_reg(sd, INDYCAM_REG_BLUE_SATURATION, ®); if (ret) return -EIO; @@ -200,7 +206,7 @@ static int indycam_get_control(struct i2c_client *client, break; case V4L2_CID_GAMMA: if (camera->version == CAMERA_VERSION_MOOSE) { - ret = indycam_read_reg(client, + ret = indycam_read_reg(sd, INDYCAM_REG_GAMMA, ®); if (ret) return -EIO; @@ -216,17 +222,16 @@ static int indycam_get_control(struct i2c_client *client, return ret; } -static int indycam_set_control(struct i2c_client *client, - struct v4l2_control *ctrl) +static int indycam_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { - struct indycam *camera = i2c_get_clientdata(client); + struct indycam *camera = to_indycam(sd); u8 reg; int ret = 0; switch (ctrl->id) { case V4L2_CID_AUTOGAIN: case V4L2_CID_AUTO_WHITE_BALANCE: - ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, ®); + ret = indycam_read_reg(sd, INDYCAM_REG_CONTROL, ®); if (ret) break; @@ -242,34 +247,34 @@ static int indycam_set_control(struct i2c_client *client, reg &= ~INDYCAM_CONTROL_AWBCTL; } - ret = indycam_write_reg(client, INDYCAM_REG_CONTROL, reg); + ret = indycam_write_reg(sd, INDYCAM_REG_CONTROL, reg); break; case V4L2_CID_EXPOSURE: reg = (ctrl->value == 0xff) ? 0x00 : (ctrl->value + 1); - ret = indycam_write_reg(client, INDYCAM_REG_SHUTTER, reg); + ret = indycam_write_reg(sd, INDYCAM_REG_SHUTTER, reg); break; case V4L2_CID_GAIN: - ret = indycam_write_reg(client, INDYCAM_REG_GAIN, ctrl->value); + ret = indycam_write_reg(sd, INDYCAM_REG_GAIN, ctrl->value); break; case V4L2_CID_RED_BALANCE: - ret = indycam_write_reg(client, INDYCAM_REG_RED_BALANCE, + ret = indycam_write_reg(sd, INDYCAM_REG_RED_BALANCE, ctrl->value); break; case V4L2_CID_BLUE_BALANCE: - ret = indycam_write_reg(client, INDYCAM_REG_BLUE_BALANCE, + ret = indycam_write_reg(sd, INDYCAM_REG_BLUE_BALANCE, ctrl->value); break; case INDYCAM_CONTROL_RED_SATURATION: - ret = indycam_write_reg(client, INDYCAM_REG_RED_SATURATION, + ret = indycam_write_reg(sd, INDYCAM_REG_RED_SATURATION, ctrl->value); break; case INDYCAM_CONTROL_BLUE_SATURATION: - ret = indycam_write_reg(client, INDYCAM_REG_BLUE_SATURATION, + ret = indycam_write_reg(sd, INDYCAM_REG_BLUE_SATURATION, ctrl->value); break; case V4L2_CID_GAMMA: if (camera->version == CAMERA_VERSION_MOOSE) { - ret = indycam_write_reg(client, INDYCAM_REG_GAMMA, + ret = indycam_write_reg(sd, INDYCAM_REG_GAMMA, ctrl->value); } break; @@ -282,30 +287,39 @@ static int indycam_set_control(struct i2c_client *client, /* I2C-interface */ -static int indycam_command(struct i2c_client *client, unsigned int cmd, - void *arg) +static int indycam_g_chip_ident(struct v4l2_subdev *sd, + struct v4l2_dbg_chip_ident *chip) { - /* The old video_decoder interface just isn't enough, - * so we'll use some custom commands. */ - switch (cmd) { - case VIDIOC_G_CTRL: - return indycam_get_control(client, arg); - - case VIDIOC_S_CTRL: - return indycam_set_control(client, arg); + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct indycam *camera = to_indycam(sd); - default: - return -EINVAL; - } + return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_INDYCAM, + camera->version); +} - return 0; +static int indycam_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); } +/* ----------------------------------------------------------------------- */ + +static const struct v4l2_subdev_core_ops indycam_core_ops = { + .g_chip_ident = indycam_g_chip_ident, + .g_ctrl = indycam_g_ctrl, + .s_ctrl = indycam_s_ctrl, +}; + +static const struct v4l2_subdev_ops indycam_ops = { + .core = &indycam_core_ops, +}; + static int indycam_probe(struct i2c_client *client, const struct i2c_device_id *id) { int err = 0; struct indycam *camera; + struct v4l2_subdev *sd; v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); @@ -314,9 +328,8 @@ static int indycam_probe(struct i2c_client *client, if (!camera) return -ENOMEM; - i2c_set_clientdata(client, camera); - - camera->client = client; + sd = &camera->sd; + v4l2_i2c_subdev_init(sd, client, &indycam_ops); camera->version = i2c_smbus_read_byte_data(client, INDYCAM_REG_VERSION); @@ -330,20 +343,20 @@ static int indycam_probe(struct i2c_client *client, INDYCAM_VERSION_MAJOR(camera->version), INDYCAM_VERSION_MINOR(camera->version)); - indycam_regdump(client); + indycam_regdump(sd); // initialize - err = indycam_write_block(client, 0, sizeof(initseq), (u8 *)&initseq); + err = indycam_write_block(sd, 0, sizeof(initseq), (u8 *)&initseq); if (err) { printk(KERN_ERR "IndyCam initialization failed\n"); kfree(camera); return -EIO; } - indycam_regdump(client); + indycam_regdump(sd); // white balance - err = indycam_write_reg(client, INDYCAM_REG_CONTROL, + err = indycam_write_reg(sd, INDYCAM_REG_CONTROL, INDYCAM_CONTROL_AGCENA | INDYCAM_CONTROL_AWBCTL); if (err) { printk(KERN_ERR "IndyCam: White balancing camera failed\n"); @@ -351,7 +364,7 @@ static int indycam_probe(struct i2c_client *client, return -EIO; } - indycam_regdump(client); + indycam_regdump(sd); printk(KERN_INFO "IndyCam initialized\n"); @@ -360,9 +373,10 @@ static int indycam_probe(struct i2c_client *client, static int indycam_remove(struct i2c_client *client) { - struct indycam *camera = i2c_get_clientdata(client); + struct v4l2_subdev *sd = i2c_get_clientdata(client); - kfree(camera); + v4l2_device_unregister_subdev(sd); + kfree(to_indycam(sd)); return 0; } diff --git a/linux/include/media/v4l2-chip-ident.h b/linux/include/media/v4l2-chip-ident.h index 70117e748..f02517bdf 100644 --- a/linux/include/media/v4l2-chip-ident.h +++ b/linux/include/media/v4l2-chip-ident.h @@ -70,6 +70,9 @@ enum { V4L2_IDENT_CX23416 = 416, V4L2_IDENT_CX23418 = 418, + /* module indycam: just ident 2000 */ + V4L2_IDENT_INDYCAM = 2000, + /* module bt819: reserved range 810-819 */ V4L2_IDENT_BT815A = 815, V4L2_IDENT_BT817A = 817, -- cgit v1.2.3 From 6e3bf4e0c794fd26a3532ea033dbbf6e28e0b44d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 13 Feb 2009 23:58:12 +0100 Subject: saa7191: convert to v4l2_subdev. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa7191.c | 240 ++++++++++++++++++---------------- linux/include/media/v4l2-chip-ident.h | 3 + 2 files changed, 129 insertions(+), 114 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7191.c b/linux/drivers/media/video/saa7191.c index 2c4c8ac5c..970b99924 100644 --- a/linux/drivers/media/video/saa7191.c +++ b/linux/drivers/media/video/saa7191.c @@ -21,7 +21,8 @@ #include #include -#include +#include +#include #include #include "compat.h" @@ -50,7 +51,7 @@ I2C_CLIENT_INSMOD; #define SAA7191_SYNC_DELAY 100 /* milliseconds */ struct saa7191 { - struct i2c_client *client; + struct v4l2_subdev sd; /* the register values are stored here as the actual * I2C-registers are write-only */ @@ -60,6 +61,11 @@ struct saa7191 { v4l2_std_id norm; }; +static inline struct saa7191 *to_saa7191(struct v4l2_subdev *sd) +{ + return container_of(sd, struct saa7191, sd); +} + static const u8 initseq[] = { 0, /* Subaddress */ @@ -104,15 +110,14 @@ static const u8 initseq[] = { /* SAA7191 register handling */ -static u8 saa7191_read_reg(struct i2c_client *client, - u8 reg) +static u8 saa7191_read_reg(struct v4l2_subdev *sd, u8 reg) { - return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg]; + return to_saa7191(sd)->reg[reg]; } -static int saa7191_read_status(struct i2c_client *client, - u8 *value) +static int saa7191_read_status(struct v4l2_subdev *sd, u8 *value) { + struct i2c_client *client = v4l2_get_subdevdata(sd); int ret; ret = i2c_master_recv(client, value, 1); @@ -125,21 +130,23 @@ static int saa7191_read_status(struct i2c_client *client, } -static int saa7191_write_reg(struct i2c_client *client, u8 reg, - u8 value) +static int saa7191_write_reg(struct v4l2_subdev *sd, u8 reg, u8 value) { - ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value; + struct i2c_client *client = v4l2_get_subdevdata(sd); + + to_saa7191(sd)->reg[reg] = value; return i2c_smbus_write_byte_data(client, reg, value); } /* the first byte of data must be the first subaddress number (register) */ -static int saa7191_write_block(struct i2c_client *client, +static int saa7191_write_block(struct v4l2_subdev *sd, u8 length, const u8 *data) { + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct saa7191 *decoder = to_saa7191(sd); int i; int ret; - struct saa7191 *decoder = (struct saa7191 *)i2c_get_clientdata(client); for (i = 0; i < (length - 1); i++) { decoder->reg[data[0] + i] = data[i + 1]; } @@ -156,14 +163,15 @@ static int saa7191_write_block(struct i2c_client *client, /* Helper functions */ -static int saa7191_set_input(struct i2c_client *client, int input) +static int saa7191_s_routing(struct v4l2_subdev *sd, + const struct v4l2_routing *route) { - struct saa7191 *decoder = i2c_get_clientdata(client); - u8 luma = saa7191_read_reg(client, SAA7191_REG_LUMA); - u8 iock = saa7191_read_reg(client, SAA7191_REG_IOCK); + struct saa7191 *decoder = to_saa7191(sd); + u8 luma = saa7191_read_reg(sd, SAA7191_REG_LUMA); + u8 iock = saa7191_read_reg(sd, SAA7191_REG_IOCK); int err; - switch (input) { + switch (route->input) { case SAA7191_INPUT_COMPOSITE: /* Set Composite input */ iock &= ~(SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW1 | SAA7191_IOCK_GPSW2); @@ -179,24 +187,24 @@ static int saa7191_set_input(struct i2c_client *client, int input) return -EINVAL; } - err = saa7191_write_reg(client, SAA7191_REG_LUMA, luma); + err = saa7191_write_reg(sd, SAA7191_REG_LUMA, luma); if (err) return -EIO; - err = saa7191_write_reg(client, SAA7191_REG_IOCK, iock); + err = saa7191_write_reg(sd, SAA7191_REG_IOCK, iock); if (err) return -EIO; - decoder->input = input; + decoder->input = route->input; return 0; } -static int saa7191_set_norm(struct i2c_client *client, v4l2_std_id norm) +static int saa7191_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) { - struct saa7191 *decoder = i2c_get_clientdata(client); - u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC); - u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3); - u8 chcv = saa7191_read_reg(client, SAA7191_REG_CHCV); + struct saa7191 *decoder = to_saa7191(sd); + u8 stdc = saa7191_read_reg(sd, SAA7191_REG_STDC); + u8 ctl3 = saa7191_read_reg(sd, SAA7191_REG_CTL3); + u8 chcv = saa7191_read_reg(sd, SAA7191_REG_CHCV); int err; if (norm & V4L2_STD_PAL) { @@ -216,13 +224,13 @@ static int saa7191_set_norm(struct i2c_client *client, v4l2_std_id norm) return -EINVAL; } - err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3); + err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3); if (err) return -EIO; - err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc); + err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc); if (err) return -EIO; - err = saa7191_write_reg(client, SAA7191_REG_CHCV, chcv); + err = saa7191_write_reg(sd, SAA7191_REG_CHCV, chcv); if (err) return -EIO; @@ -235,14 +243,14 @@ static int saa7191_set_norm(struct i2c_client *client, v4l2_std_id norm) return 0; } -static int saa7191_wait_for_signal(struct i2c_client *client, u8 *status) +static int saa7191_wait_for_signal(struct v4l2_subdev *sd, u8 *status) { int i = 0; dprintk("Checking for signal...\n"); for (i = 0; i < SAA7191_SYNC_COUNT; i++) { - if (saa7191_read_status(client, status)) + if (saa7191_read_status(sd, status)) return -EIO; if (((*status) & SAA7191_STATUS_HLCK) == 0) { @@ -258,12 +266,11 @@ static int saa7191_wait_for_signal(struct i2c_client *client, u8 *status) return -EBUSY; } -static int saa7191_autodetect_norm_extended(struct i2c_client *client, - v4l2_std_id *norm) +static int saa7191_querystd(struct v4l2_subdev *sd, v4l2_std_id *norm) { - struct saa7191 *decoder = i2c_get_clientdata(client); - u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC); - u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3); + struct saa7191 *decoder = to_saa7191(sd); + u8 stdc = saa7191_read_reg(sd, SAA7191_REG_STDC); + u8 ctl3 = saa7191_read_reg(sd, SAA7191_REG_CTL3); u8 status; v4l2_std_id old_norm = decoder->norm; int err = 0; @@ -274,19 +281,19 @@ static int saa7191_autodetect_norm_extended(struct i2c_client *client, stdc &= ~SAA7191_STDC_SECS; ctl3 &= ~(SAA7191_CTL3_FSEL); - err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc); + err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc); if (err) { err = -EIO; goto out; } - err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3); + err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3); if (err) { err = -EIO; goto out; } ctl3 |= SAA7191_CTL3_AUFD; - err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3); + err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3); if (err) { err = -EIO; goto out; @@ -294,7 +301,7 @@ static int saa7191_autodetect_norm_extended(struct i2c_client *client, msleep(SAA7191_SYNC_DELAY); - err = saa7191_wait_for_signal(client, &status); + err = saa7191_wait_for_signal(sd, &status); if (err) goto out; @@ -309,39 +316,39 @@ static int saa7191_autodetect_norm_extended(struct i2c_client *client, dprintk("50Hz signal: Trying PAL...\n"); /* try PAL first */ - err = saa7191_set_norm(client, V4L2_STD_PAL); + err = saa7191_s_std(sd, V4L2_STD_PAL); if (err) goto out; msleep(SAA7191_SYNC_DELAY); - err = saa7191_wait_for_signal(client, &status); + err = saa7191_wait_for_signal(sd, &status); if (err) goto out; /* not 50Hz ? */ if (status & SAA7191_STATUS_FIDT) { dprintk("No 50Hz signal\n"); - saa7191_set_norm(client, old_norm); + saa7191_s_std(sd, old_norm); return -EAGAIN; } if (status & SAA7191_STATUS_CODE) { dprintk("PAL\n"); *norm = V4L2_STD_PAL; - return saa7191_set_norm(client, old_norm); + return saa7191_s_std(sd, old_norm); } dprintk("No color detected with PAL - Trying SECAM...\n"); /* no color detected ? -> try SECAM */ - err = saa7191_set_norm(client, V4L2_STD_SECAM); + err = saa7191_s_std(sd, V4L2_STD_SECAM); if (err) goto out; msleep(SAA7191_SYNC_DELAY); - err = saa7191_wait_for_signal(client, &status); + err = saa7191_wait_for_signal(sd, &status); if (err) goto out; @@ -356,16 +363,16 @@ static int saa7191_autodetect_norm_extended(struct i2c_client *client, /* Color detected -> SECAM */ dprintk("SECAM\n"); *norm = V4L2_STD_SECAM; - return saa7191_set_norm(client, old_norm); + return saa7191_s_std(sd, old_norm); } dprintk("No color detected with SECAM - Going back to PAL.\n"); out: - return saa7191_set_norm(client, old_norm); + return saa7191_s_std(sd, old_norm); } -static int saa7191_autodetect_norm(struct i2c_client *client) +static int saa7191_autodetect_norm(struct v4l2_subdev *sd) { u8 status; @@ -373,7 +380,7 @@ static int saa7191_autodetect_norm(struct i2c_client *client) dprintk("Reading status...\n"); - if (saa7191_read_status(client, &status)) + if (saa7191_read_status(sd, &status)) return -EIO; dprintk("Checking for signal...\n"); @@ -389,16 +396,15 @@ static int saa7191_autodetect_norm(struct i2c_client *client) if (status & SAA7191_STATUS_FIDT) { /* 60hz signal -> NTSC */ dprintk("NTSC\n"); - return saa7191_set_norm(client, V4L2_STD_NTSC); + return saa7191_s_std(sd, V4L2_STD_NTSC); } else { /* 50hz signal -> PAL */ dprintk("PAL\n"); - return saa7191_set_norm(client, V4L2_STD_PAL); + return saa7191_s_std(sd, V4L2_STD_PAL); } } -static int saa7191_get_control(struct i2c_client *client, - struct v4l2_control *ctrl) +static int saa7191_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { u8 reg; int ret = 0; @@ -407,7 +413,7 @@ static int saa7191_get_control(struct i2c_client *client, case SAA7191_CONTROL_BANDPASS: case SAA7191_CONTROL_BANDPASS_WEIGHT: case SAA7191_CONTROL_CORING: - reg = saa7191_read_reg(client, SAA7191_REG_LUMA); + reg = saa7191_read_reg(sd, SAA7191_REG_LUMA); switch (ctrl->id) { case SAA7191_CONTROL_BANDPASS: ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK) @@ -425,7 +431,7 @@ static int saa7191_get_control(struct i2c_client *client, break; case SAA7191_CONTROL_FORCE_COLOUR: case SAA7191_CONTROL_CHROMA_GAIN: - reg = saa7191_read_reg(client, SAA7191_REG_GAIN); + reg = saa7191_read_reg(sd, SAA7191_REG_GAIN); if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR) ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0; else @@ -433,7 +439,7 @@ static int saa7191_get_control(struct i2c_client *client, >> SAA7191_GAIN_LFIS_SHIFT; break; case V4L2_CID_HUE: - reg = saa7191_read_reg(client, SAA7191_REG_HUEC); + reg = saa7191_read_reg(sd, SAA7191_REG_HUEC); if (reg < 0x80) reg += 0x80; else @@ -441,18 +447,18 @@ static int saa7191_get_control(struct i2c_client *client, ctrl->value = (s32)reg; break; case SAA7191_CONTROL_VTRC: - reg = saa7191_read_reg(client, SAA7191_REG_STDC); + reg = saa7191_read_reg(sd, SAA7191_REG_STDC); ctrl->value = ((s32)reg & SAA7191_STDC_VTRC) ? 1 : 0; break; case SAA7191_CONTROL_LUMA_DELAY: - reg = saa7191_read_reg(client, SAA7191_REG_CTL3); + reg = saa7191_read_reg(sd, SAA7191_REG_CTL3); ctrl->value = ((s32)reg & SAA7191_CTL3_YDEL_MASK) >> SAA7191_CTL3_YDEL_SHIFT; if (ctrl->value >= 4) ctrl->value -= 8; break; case SAA7191_CONTROL_VNR: - reg = saa7191_read_reg(client, SAA7191_REG_CTL4); + reg = saa7191_read_reg(sd, SAA7191_REG_CTL4); ctrl->value = ((s32)reg & SAA7191_CTL4_VNOI_MASK) >> SAA7191_CTL4_VNOI_SHIFT; break; @@ -463,8 +469,7 @@ static int saa7191_get_control(struct i2c_client *client, return ret; } -static int saa7191_set_control(struct i2c_client *client, - struct v4l2_control *ctrl) +static int saa7191_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { u8 reg; int ret = 0; @@ -473,7 +478,7 @@ static int saa7191_set_control(struct i2c_client *client, case SAA7191_CONTROL_BANDPASS: case SAA7191_CONTROL_BANDPASS_WEIGHT: case SAA7191_CONTROL_CORING: - reg = saa7191_read_reg(client, SAA7191_REG_LUMA); + reg = saa7191_read_reg(sd, SAA7191_REG_LUMA); switch (ctrl->id) { case SAA7191_CONTROL_BANDPASS: reg &= ~SAA7191_LUMA_BPSS_MASK; @@ -491,11 +496,11 @@ static int saa7191_set_control(struct i2c_client *client, & SAA7191_LUMA_CORI_MASK; break; } - ret = saa7191_write_reg(client, SAA7191_REG_LUMA, reg); + ret = saa7191_write_reg(sd, SAA7191_REG_LUMA, reg); break; case SAA7191_CONTROL_FORCE_COLOUR: case SAA7191_CONTROL_CHROMA_GAIN: - reg = saa7191_read_reg(client, SAA7191_REG_GAIN); + reg = saa7191_read_reg(sd, SAA7191_REG_GAIN); if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR) { if (ctrl->value) reg |= SAA7191_GAIN_COLO; @@ -506,7 +511,7 @@ static int saa7191_set_control(struct i2c_client *client, reg |= (ctrl->value << SAA7191_GAIN_LFIS_SHIFT) & SAA7191_GAIN_LFIS_MASK; } - ret = saa7191_write_reg(client, SAA7191_REG_GAIN, reg); + ret = saa7191_write_reg(sd, SAA7191_REG_GAIN, reg); break; case V4L2_CID_HUE: reg = ctrl->value & 0xff; @@ -514,33 +519,33 @@ static int saa7191_set_control(struct i2c_client *client, reg += 0x80; else reg -= 0x80; - ret = saa7191_write_reg(client, SAA7191_REG_HUEC, reg); + ret = saa7191_write_reg(sd, SAA7191_REG_HUEC, reg); break; case SAA7191_CONTROL_VTRC: - reg = saa7191_read_reg(client, SAA7191_REG_STDC); + reg = saa7191_read_reg(sd, SAA7191_REG_STDC); if (ctrl->value) reg |= SAA7191_STDC_VTRC; else reg &= ~SAA7191_STDC_VTRC; - ret = saa7191_write_reg(client, SAA7191_REG_STDC, reg); + ret = saa7191_write_reg(sd, SAA7191_REG_STDC, reg); break; case SAA7191_CONTROL_LUMA_DELAY: { s32 value = ctrl->value; if (value < 0) value += 8; - reg = saa7191_read_reg(client, SAA7191_REG_CTL3); + reg = saa7191_read_reg(sd, SAA7191_REG_CTL3); reg &= ~SAA7191_CTL3_YDEL_MASK; reg |= (value << SAA7191_CTL3_YDEL_SHIFT) & SAA7191_CTL3_YDEL_MASK; - ret = saa7191_write_reg(client, SAA7191_REG_CTL3, reg); + ret = saa7191_write_reg(sd, SAA7191_REG_CTL3, reg); break; } case SAA7191_CONTROL_VNR: - reg = saa7191_read_reg(client, SAA7191_REG_CTL4); + reg = saa7191_read_reg(sd, SAA7191_REG_CTL4); reg &= ~SAA7191_CTL4_VNOI_MASK; reg |= (ctrl->value << SAA7191_CTL4_VNOI_SHIFT) & SAA7191_CTL4_VNOI_MASK; - ret = saa7191_write_reg(client, SAA7191_REG_CTL4, reg); + ret = saa7191_write_reg(sd, SAA7191_REG_CTL4, reg); break; default: ret = -EINVAL; @@ -551,57 +556,64 @@ static int saa7191_set_control(struct i2c_client *client, /* I2C-interface */ -static int saa7191_command(struct i2c_client *client, unsigned int cmd, - void *arg) +static int saa7191_g_input_status(struct v4l2_subdev *sd, u32 *status) { - switch (cmd) { - case VIDIOC_INT_G_INPUT_STATUS: { - u32 *iarg = arg; - u8 status; - int res = V4L2_IN_ST_NO_SIGNAL; + u8 status_reg; + int res = V4L2_IN_ST_NO_SIGNAL; - if (saa7191_read_status(client, &status)) - return -EIO; - if ((status & SAA7191_STATUS_HLCK) == 0) - res = 0; - if (!(status & SAA7191_STATUS_CODE)) - res |= V4L2_IN_ST_NO_COLOR; - *iarg = res; - break; - } + if (saa7191_read_status(sd, &status_reg)) + return -EIO; + if ((status_reg & SAA7191_STATUS_HLCK) == 0) + res = 0; + if (!(status_reg & SAA7191_STATUS_CODE)) + res |= V4L2_IN_ST_NO_COLOR; + *status = res; + return 0; +} - case VIDIOC_QUERYSTD: - return saa7191_autodetect_norm_extended(client, arg); - case VIDIOC_S_STD: { - v4l2_std_id *istd = arg; +static int saa7191_g_chip_ident(struct v4l2_subdev *sd, + struct v4l2_dbg_chip_ident *chip) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); - return saa7191_set_norm(client, *istd); - } - case VIDIOC_INT_S_VIDEO_ROUTING: { - struct v4l2_routing *route = arg; + return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7191, 0); +} - return saa7191_set_input(client, route->input); - } +static int saa7191_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); +} - case VIDIOC_G_CTRL: - return saa7191_get_control(client, arg); +/* ----------------------------------------------------------------------- */ - case VIDIOC_S_CTRL: - return saa7191_set_control(client, arg); +static const struct v4l2_subdev_core_ops saa7191_core_ops = { + .g_chip_ident = saa7191_g_chip_ident, + .g_ctrl = saa7191_g_ctrl, + .s_ctrl = saa7191_s_ctrl, +}; - default: - return -EINVAL; - } +static const struct v4l2_subdev_tuner_ops saa7191_tuner_ops = { + .s_std = saa7191_s_std, +}; - return 0; -} +static const struct v4l2_subdev_video_ops saa7191_video_ops = { + .s_routing = saa7191_s_routing, + .querystd = saa7191_querystd, + .g_input_status = saa7191_g_input_status, +}; + +static const struct v4l2_subdev_ops saa7191_ops = { + .core = &saa7191_core_ops, + .video = &saa7191_video_ops, +}; static int saa7191_probe(struct i2c_client *client, const struct i2c_device_id *id) { int err = 0; struct saa7191 *decoder; + struct v4l2_subdev *sd; v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); @@ -610,11 +622,10 @@ static int saa7191_probe(struct i2c_client *client, if (!decoder) return -ENOMEM; - i2c_set_clientdata(client, decoder); - - decoder->client = client; + sd = &decoder->sd; + v4l2_i2c_subdev_init(sd, client, &saa7191_ops); - err = saa7191_write_block(client, sizeof(initseq), initseq); + err = saa7191_write_block(sd, sizeof(initseq), initseq); if (err) { printk(KERN_ERR "SAA7191 initialization failed\n"); kfree(decoder); @@ -626,7 +637,7 @@ static int saa7191_probe(struct i2c_client *client, decoder->input = SAA7191_INPUT_COMPOSITE; decoder->norm = V4L2_STD_PAL; - err = saa7191_autodetect_norm(client); + err = saa7191_autodetect_norm(sd); if (err && (err != -EBUSY)) printk(KERN_ERR "SAA7191: Signal auto-detection failed\n"); @@ -635,9 +646,10 @@ static int saa7191_probe(struct i2c_client *client, static int saa7191_remove(struct i2c_client *client) { - struct saa7191 *decoder = i2c_get_clientdata(client); + struct v4l2_subdev *sd = i2c_get_clientdata(client); - kfree(decoder); + v4l2_device_unregister_subdev(sd); + kfree(to_saa7191(sd)); return 0; } diff --git a/linux/include/media/v4l2-chip-ident.h b/linux/include/media/v4l2-chip-ident.h index f02517bdf..43684f105 100644 --- a/linux/include/media/v4l2-chip-ident.h +++ b/linux/include/media/v4l2-chip-ident.h @@ -131,6 +131,9 @@ enum { /* module saa7185: just ident 7185 */ V4L2_IDENT_SAA7185 = 7185, + /* module saa7191: just ident 7191 */ + V4L2_IDENT_SAA7191 = 7191, + /* module wm8739: just ident 8739 */ V4L2_IDENT_WM8739 = 8739, -- cgit v1.2.3 From 44b989fe4b33534a20c8b32f0b14177b1814e489 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 14 Feb 2009 00:32:39 -0500 Subject: cx18: Convert the integrated A/V decoder core interface to a v4l2_subdev From: Andy Walls This is the next step in converting the cx18 driver to use the v4l2_device/ v4l2_subdevice framework. This is a straightforward conversion of the cx18_av_*[ch] files. It compiles, but leaves the driver in an unlinkable state at the moment. Note, the cx18 integrated A/V digitizer will now make a host match at address 1, as far as v4l2-dbg is concerned. That means it identifies itself as a separate "chip", and acts as an alias to the integrated A/V decoder registers that are also available with the host match at address 0. Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-av-core.c | 577 ++++++++++++++------------ linux/drivers/media/video/cx18/cx18-av-core.h | 13 +- 2 files changed, 333 insertions(+), 257 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-av-core.c b/linux/drivers/media/video/cx18/cx18-av-core.c index a3bd2c95f..8f79cc3f4 100644 --- a/linux/drivers/media/video/cx18/cx18-av-core.c +++ b/linux/drivers/media/video/cx18/cx18-av-core.c @@ -22,8 +22,10 @@ * 02110-1301, USA. */ +#include #include "cx18-driver.h" #include "cx18-io.h" +#include "cx18-cards.h" int cx18_av_write(struct cx18 *cx, u16 addr, u8 value) { @@ -97,15 +99,6 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask, or_value); } -/* ----------------------------------------------------------------------- */ - -static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, - enum cx18_av_audio_input aud_input); -static void log_audio_status(struct cx18 *cx); -static void log_video_status(struct cx18 *cx); - -/* ----------------------------------------------------------------------- */ - static void cx18_av_initialize(struct cx18 *cx) { struct cx18_av_state *state = &cx->av_state; @@ -200,7 +193,26 @@ static void cx18_av_initialize(struct cx18 *cx) state->default_volume = ((state->default_volume / 2) + 23) << 9; } -/* ----------------------------------------------------------------------- */ +static int cx18_av_reset(struct v4l2_subdev *sd, u32 val) +{ + struct cx18 *cx = v4l2_get_subdevdata(sd); + + cx18_av_initialize(cx); + return 0; +} + +static int cx18_av_init_hardware(struct v4l2_subdev *sd, u32 val) +{ + struct cx18_av_state *state = to_cx18_av_state(sd); + struct cx18 *cx = v4l2_get_subdevdata(sd); + + if (!state->is_initialized) { + /* initialize on first use */ + state->is_initialized = 1; + cx18_av_initialize(cx); + } + return 0; +} void cx18_av_std_setup(struct cx18 *cx) { @@ -362,7 +374,18 @@ void cx18_av_std_setup(struct cx18 *cx) cx18_av_write(cx, 0x47f, state->slicer_line_delay); } -/* ----------------------------------------------------------------------- */ +static int cx18_av_decode_vbi_line(struct v4l2_subdev *sd, + struct v4l2_decode_vbi_line *vbi_line) +{ + struct cx18 *cx = v4l2_get_subdevdata(sd); + return cx18_av_vbi(cx, VIDIOC_INT_DECODE_VBI_LINE, vbi_line); +} + +static int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq) +{ + struct cx18 *cx = v4l2_get_subdevdata(sd); + return cx18_av_audio(cx, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freq); +} static void input_change(struct cx18 *cx) { @@ -409,6 +432,14 @@ static void input_change(struct cx18 *cx) } } +static int cx18_av_s_frequency(struct v4l2_subdev *sd, + struct v4l2_frequency *freq) +{ + struct cx18 *cx = v4l2_get_subdevdata(sd); + input_change(cx); + return 0; +} + static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, enum cx18_av_audio_input aud_input) { @@ -488,14 +519,118 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, return 0; } -/* ----------------------------------------------------------------------- */ +static int cx18_av_s_video_routing(struct v4l2_subdev *sd, + const struct v4l2_routing *route) +{ + struct cx18_av_state *state = to_cx18_av_state(sd); + struct cx18 *cx = v4l2_get_subdevdata(sd); + return set_input(cx, route->input, state->aud_input); +} -static int set_v4lstd(struct cx18 *cx) +static int cx18_av_s_audio_routing(struct v4l2_subdev *sd, + const struct v4l2_routing *route) { - struct cx18_av_state *state = &cx->av_state; + struct cx18_av_state *state = to_cx18_av_state(sd); + struct cx18 *cx = v4l2_get_subdevdata(sd); + return set_input(cx, state->vid_input, route->input); +} + +static int cx18_av_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) +{ + struct cx18_av_state *state = to_cx18_av_state(sd); + struct cx18 *cx = v4l2_get_subdevdata(sd); + u8 vpres; + u8 mode; + int val = 0; + + if (state->radio) + return 0; + + vpres = cx18_av_read(cx, 0x40e) & 0x20; + vt->signal = vpres ? 0xffff : 0x0; + + vt->capability |= + V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | + V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; + + mode = cx18_av_read(cx, 0x804); + + /* get rxsubchans and audmode */ + if ((mode & 0xf) == 1) + val |= V4L2_TUNER_SUB_STEREO; + else + val |= V4L2_TUNER_SUB_MONO; + + if (mode == 2 || mode == 4) + val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; + + if (mode & 0x10) + val |= V4L2_TUNER_SUB_SAP; + + vt->rxsubchans = val; + vt->audmode = state->audmode; + return 0; +} + +static int cx18_av_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) +{ + struct cx18_av_state *state = to_cx18_av_state(sd); + struct cx18 *cx = v4l2_get_subdevdata(sd); + u8 v; + + if (state->radio) + return 0; + + v = cx18_av_read(cx, 0x809); + v &= ~0xf; + + switch (vt->audmode) { + case V4L2_TUNER_MODE_MONO: + /* mono -> mono + stereo -> mono + bilingual -> lang1 */ + break; + case V4L2_TUNER_MODE_STEREO: + case V4L2_TUNER_MODE_LANG1: + /* mono -> mono + stereo -> stereo + bilingual -> lang1 */ + v |= 0x4; + break; + case V4L2_TUNER_MODE_LANG1_LANG2: + /* mono -> mono + stereo -> stereo + bilingual -> lang1/lang2 */ + v |= 0x7; + break; + case V4L2_TUNER_MODE_LANG2: + /* mono -> mono + stereo -> stereo + bilingual -> lang2 */ + v |= 0x1; + break; + default: + return -EINVAL; + } + cx18_av_write_expect(cx, 0x809, v, v, 0xff); + state->audmode = vt->audmode; + return 0; +} + +static int cx18_av_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) +{ + struct cx18_av_state *state = to_cx18_av_state(sd); + struct cx18 *cx = v4l2_get_subdevdata(sd); + u8 fmt = 0; /* zero is autodetect */ u8 pal_m = 0; + if (state->radio == 0 && state->std == norm) + return 0; + + state->radio = 0; + state->std = norm; + /* First tests should be against specific std */ if (state->std == V4L2_STD_NTSC_M_JP) { fmt = 0x2; @@ -538,10 +673,17 @@ static int set_v4lstd(struct cx18 *cx) return 0; } -/* ----------------------------------------------------------------------- */ +static int cx18_av_s_radio(struct v4l2_subdev *sd) +{ + struct cx18_av_state *state = to_cx18_av_state(sd); + state->radio = 1; + return 0; +} -static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl) +static int cx18_av_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { + struct cx18 *cx = v4l2_get_subdevdata(sd); + switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: if (ctrl->value < 0 || ctrl->value > 255) { @@ -593,12 +735,13 @@ static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl) default: return -EINVAL; } - return 0; } -static int get_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl) +static int cx18_av_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { + struct cx18 *cx = v4l2_get_subdevdata(sd); + switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: ctrl->value = (s8)cx18_av_read(cx, 0x414) + 128; @@ -621,27 +764,56 @@ static int get_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl) default: return -EINVAL; } - return 0; } -/* ----------------------------------------------------------------------- */ +static int cx18_av_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) +{ + struct cx18_av_state *state = to_cx18_av_state(sd); + + switch (qc->id) { + case V4L2_CID_BRIGHTNESS: + case V4L2_CID_CONTRAST: + case V4L2_CID_SATURATION: + case V4L2_CID_HUE: + return v4l2_ctrl_query_fill_std(qc); + default: + break; + } + + switch (qc->id) { + case V4L2_CID_AUDIO_VOLUME: + return v4l2_ctrl_query_fill(qc, 0, 65535, + 65535 / 100, state->default_volume); + case V4L2_CID_AUDIO_MUTE: + case V4L2_CID_AUDIO_BALANCE: + case V4L2_CID_AUDIO_BASS: + case V4L2_CID_AUDIO_TREBLE: + return v4l2_ctrl_query_fill_std(qc); + default: + return -EINVAL; + } + return -EINVAL; +} -static int get_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt) +static int cx18_av_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) { + struct cx18 *cx = v4l2_get_subdevdata(sd); + switch (fmt->type) { case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: return cx18_av_vbi(cx, VIDIOC_G_FMT, fmt); default: return -EINVAL; } - return 0; } -static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt) +static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) { - struct cx18_av_state *state = &cx->av_state; + struct cx18_av_state *state = to_cx18_av_state(sd); + struct cx18 *cx = v4l2_get_subdevdata(sd); + struct v4l2_pix_format *pix; int HSC, VSC, Vsrc, Hsrc, filter, Vlines; int is_50Hz = !(state->std & V4L2_STD_525_60); @@ -701,249 +873,24 @@ static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt) default: return -EINVAL; } - - return 0; -} - -/* ----------------------------------------------------------------------- */ - -static int valid_av_cmd(unsigned int cmd) -{ - switch (cmd) { - /* All commands supported by cx18_av_cmd() */ - case VIDIOC_INT_DECODE_VBI_LINE: - case VIDIOC_INT_AUDIO_CLOCK_FREQ: - case VIDIOC_STREAMON: - case VIDIOC_STREAMOFF: - case VIDIOC_LOG_STATUS: - case VIDIOC_G_CTRL: - case VIDIOC_S_CTRL: - case VIDIOC_QUERYCTRL: - case VIDIOC_G_STD: - case VIDIOC_S_STD: - case AUDC_SET_RADIO: - case VIDIOC_INT_G_VIDEO_ROUTING: - case VIDIOC_INT_S_VIDEO_ROUTING: - case VIDIOC_INT_G_AUDIO_ROUTING: - case VIDIOC_INT_S_AUDIO_ROUTING: - case VIDIOC_S_FREQUENCY: - case VIDIOC_G_TUNER: - case VIDIOC_S_TUNER: - case VIDIOC_G_FMT: - case VIDIOC_S_FMT: - case VIDIOC_INT_RESET: - return 1; - default: - return 0; - } return 0; } -int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg) +static int cx18_av_s_stream(struct v4l2_subdev *sd, int enable) { - struct cx18_av_state *state = &cx->av_state; - struct v4l2_tuner *vt = arg; - struct v4l2_routing *route = arg; - - if (!state->is_initialized && valid_av_cmd(cmd)) { - CX18_DEBUG_INFO("cmd %08x triggered fw load\n", cmd); - /* initialize on first use */ - state->is_initialized = 1; - cx18_av_initialize(cx); - } - - switch (cmd) { - case VIDIOC_INT_DECODE_VBI_LINE: - return cx18_av_vbi(cx, cmd, arg); + struct cx18 *cx = v4l2_get_subdevdata(sd); - case VIDIOC_INT_AUDIO_CLOCK_FREQ: - return cx18_av_audio(cx, cmd, arg); - - case VIDIOC_STREAMON: - CX18_DEBUG_INFO("enable output\n"); + CX18_DEBUG_INFO("%s output\n", enable ? "enable" : "disable"); + if (enable) { cx18_av_write(cx, 0x115, 0x8c); cx18_av_write(cx, 0x116, 0x07); - break; - - case VIDIOC_STREAMOFF: - CX18_DEBUG_INFO("disable output\n"); + } else { cx18_av_write(cx, 0x115, 0x00); cx18_av_write(cx, 0x116, 0x00); - break; - - case VIDIOC_LOG_STATUS: - log_video_status(cx); - log_audio_status(cx); - break; - - case VIDIOC_G_CTRL: - return get_v4lctrl(cx, (struct v4l2_control *)arg); - - case VIDIOC_S_CTRL: - return set_v4lctrl(cx, (struct v4l2_control *)arg); - - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *qc = arg; - - switch (qc->id) { - case V4L2_CID_BRIGHTNESS: - case V4L2_CID_CONTRAST: - case V4L2_CID_SATURATION: - case V4L2_CID_HUE: - return v4l2_ctrl_query_fill_std(qc); - default: - break; - } - - switch (qc->id) { - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(qc, 0, 65535, - 65535 / 100, state->default_volume); - case V4L2_CID_AUDIO_MUTE: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - return v4l2_ctrl_query_fill_std(qc); - default: - return -EINVAL; - } - return -EINVAL; } - - case VIDIOC_G_STD: - *(v4l2_std_id *)arg = state->std; - break; - - case VIDIOC_S_STD: - if (state->radio == 0 && state->std == *(v4l2_std_id *)arg) - return 0; - state->radio = 0; - state->std = *(v4l2_std_id *)arg; - return set_v4lstd(cx); - - case AUDC_SET_RADIO: - state->radio = 1; - break; - - case VIDIOC_INT_G_VIDEO_ROUTING: - route->input = state->vid_input; - route->output = 0; - break; - - case VIDIOC_INT_S_VIDEO_ROUTING: - return set_input(cx, route->input, state->aud_input); - - case VIDIOC_INT_G_AUDIO_ROUTING: - route->input = state->aud_input; - route->output = 0; - break; - - case VIDIOC_INT_S_AUDIO_ROUTING: - return set_input(cx, state->vid_input, route->input); - - case VIDIOC_S_FREQUENCY: - input_change(cx); - break; - - case VIDIOC_G_TUNER: - { - u8 vpres = cx18_av_read(cx, 0x40e) & 0x20; - u8 mode; - int val = 0; - - if (state->radio) - break; - - vt->signal = vpres ? 0xffff : 0x0; - - vt->capability |= - V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | - V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; - - mode = cx18_av_read(cx, 0x804); - - /* get rxsubchans and audmode */ - if ((mode & 0xf) == 1) - val |= V4L2_TUNER_SUB_STEREO; - else - val |= V4L2_TUNER_SUB_MONO; - - if (mode == 2 || mode == 4) - val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; - - if (mode & 0x10) - val |= V4L2_TUNER_SUB_SAP; - - vt->rxsubchans = val; - vt->audmode = state->audmode; - break; - } - - case VIDIOC_S_TUNER: - { - u8 v; - - if (state->radio) - break; - - v = cx18_av_read(cx, 0x809); - v &= ~0xf; - - switch (vt->audmode) { - case V4L2_TUNER_MODE_MONO: - /* mono -> mono - stereo -> mono - bilingual -> lang1 */ - break; - case V4L2_TUNER_MODE_STEREO: - case V4L2_TUNER_MODE_LANG1: - /* mono -> mono - stereo -> stereo - bilingual -> lang1 */ - v |= 0x4; - break; - case V4L2_TUNER_MODE_LANG1_LANG2: - /* mono -> mono - stereo -> stereo - bilingual -> lang1/lang2 */ - v |= 0x7; - break; - case V4L2_TUNER_MODE_LANG2: - /* mono -> mono - stereo -> stereo - bilingual -> lang2 */ - v |= 0x1; - break; - default: - return -EINVAL; - } - cx18_av_write_expect(cx, 0x809, v, v, 0xff); - state->audmode = vt->audmode; - break; - } - - case VIDIOC_G_FMT: - return get_v4lfmt(cx, (struct v4l2_format *)arg); - - case VIDIOC_S_FMT: - return set_v4lfmt(cx, (struct v4l2_format *)arg); - - case VIDIOC_INT_RESET: - cx18_av_initialize(cx); - break; - - default: - return -EINVAL; - } - return 0; } -/* ----------------------------------------------------------------------- */ - -/* ----------------------------------------------------------------------- */ - static void log_video_status(struct cx18 *cx) { static const char *const fmt_strs[] = { @@ -981,8 +928,6 @@ static void log_video_status(struct cx18 *cx) CX18_INFO("Specified audioclock freq: %d Hz\n", state->audclk_freq); } -/* ----------------------------------------------------------------------- */ - static void log_audio_status(struct cx18 *cx) { struct cx18_av_state *state = &cx->av_state; @@ -1130,3 +1075,123 @@ static void log_audio_status(struct cx18 *cx) CX18_INFO("Selected 45 MHz format: %s\n", p); } } + +static int cx18_av_log_status(struct v4l2_subdev *sd) +{ + struct cx18 *cx = v4l2_get_subdevdata(sd); + log_video_status(cx); + log_audio_status(cx); + return 0; +} + +static inline int cx18_av_dbg_match(const struct v4l2_dbg_match *match) +{ + return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 1; +} + +static int cx18_av_g_chip_ident(struct v4l2_subdev *sd, + struct v4l2_dbg_chip_ident *chip) +{ + if (cx18_av_dbg_match(&chip->match)) { + /* + * Nothing else is going to claim to be this combination, + * and the real host chip revision will be returned by a host + * match on address 0. + */ + chip->ident = V4L2_IDENT_CX25843; + chip->revision = V4L2_IDENT_CX23418; /* Why not */ + } + return 0; +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int cx18_av_g_register(struct v4l2_subdev *sd, + struct v4l2_dbg_register *reg) +{ + struct cx18 *cx = v4l2_get_subdevdata(sd); + + if (!cx18_av_dbg_match(®->match)) + return -EINVAL; + if ((reg->reg & 0x3) != 0) + return -EINVAL; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + reg->size = 4; + reg->val = cx18_av_read4(cx, reg->reg & 0x00000ffc); + return 0; +} + +static int cx18_av_s_register(struct v4l2_subdev *sd, + struct v4l2_dbg_register *reg) +{ + struct cx18 *cx = v4l2_get_subdevdata(sd); + + if (!cx18_av_dbg_match(®->match)) + return -EINVAL; + if ((reg->reg & 0x3) != 0) + return -EINVAL; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + cx18_av_write4(cx, reg->reg & 0x00000ffc, reg->val); + return 0; +} +#endif + +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_hardware, + .reset = cx18_av_reset, + .queryctrl = cx18_av_queryctrl, + .g_ctrl = cx18_av_g_ctrl, + .s_ctrl = cx18_av_s_ctrl, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .g_register = cx18_av_g_register, + .s_register = cx18_av_s_register, +#endif +}; + +static const struct v4l2_subdev_tuner_ops cx18_av_tuner_ops = { + .s_radio = cx18_av_s_radio, + .s_frequency = cx18_av_s_frequency, + .g_tuner = cx18_av_g_tuner, + .s_tuner = cx18_av_s_tuner, + .s_std = cx18_av_s_std, +}; + +static const struct v4l2_subdev_audio_ops cx18_av_audio_ops = { + .s_clock_freq = cx18_av_s_clock_freq, + .s_routing = cx18_av_s_audio_routing, +}; + +static const struct v4l2_subdev_video_ops cx18_av_video_ops = { + .s_routing = cx18_av_s_video_routing, + .decode_vbi_line = cx18_av_decode_vbi_line, + .s_stream = cx18_av_s_stream, + .g_fmt = cx18_av_g_fmt, + .s_fmt = cx18_av_s_fmt, +}; + +static const struct v4l2_subdev_ops cx18_av_ops = { + .core = &cx18_av_general_ops, + .tuner = &cx18_av_tuner_ops, + .audio = &cx18_av_audio_ops, + .video = &cx18_av_video_ops, +}; + +int cx18_av_init(struct cx18 *cx) +{ + struct v4l2_subdev *sd = &cx->av_state.sd; + + v4l2_subdev_init(sd, &cx18_av_ops); + v4l2_set_subdevdata(sd, cx); + snprintf(sd->name, sizeof(sd->name), + "%s-internal A/V decoder", cx->v4l2_dev.name); + sd->grp_id = CX18_HW_CX23418; + return v4l2_device_register_subdev(&cx->v4l2_dev, sd); +} + +void cx18_av_fini(struct cx18 *cx) +{ + v4l2_device_unregister_subdev(&cx->av_state.sd); +} diff --git a/linux/drivers/media/video/cx18/cx18-av-core.h b/linux/drivers/media/video/cx18/cx18-av-core.h index d83760cae..025100aee 100644 --- a/linux/drivers/media/video/cx18/cx18-av-core.h +++ b/linux/drivers/media/video/cx18/cx18-av-core.h @@ -25,6 +25,8 @@ #ifndef _CX18_AV_CORE_H_ #define _CX18_AV_CORE_H_ +#include + struct cx18; enum cx18_av_video_input { @@ -73,6 +75,7 @@ enum cx18_av_audio_input { }; struct cx18_av_state { + struct v4l2_subdev sd; int radio; v4l2_std_id std; enum cx18_av_video_input vid_input; @@ -315,6 +318,11 @@ struct cx18_av_state { #define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */ #define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */ +static inline struct cx18_av_state *to_cx18_av_state(struct v4l2_subdev *sd) +{ + return container_of(sd, struct cx18_av_state, sd); +} + /* ----------------------------------------------------------------------- */ /* cx18_av-core.c */ int cx18_av_write(struct cx18 *cx, u16 addr, u8 value); @@ -327,9 +335,12 @@ u8 cx18_av_read(struct cx18 *cx, u16 addr); u32 cx18_av_read4(struct cx18 *cx, u16 addr); int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value); int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value); -int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg); void cx18_av_std_setup(struct cx18 *cx); +int cx18_av_cmd(struct cx18 *cx, int cmd, void *arg); /* FIXME - Remove */ +int cx18_av_init(struct cx18 *cx); +void cx18_av_fini(struct cx18 *cx); + /* ----------------------------------------------------------------------- */ /* cx18_av-firmware.c */ int cx18_av_loadfw(struct cx18 *cx); -- cgit v1.2.3 From 8f6e212e7f25dca1323cc8b7d4a5112c3b2225e3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 14 Feb 2009 08:29:07 -0200 Subject: v4l2-framework: documments videobuf usage on drivers From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/Documentation/video4linux/v4l2-framework.txt | 92 +++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/Documentation/video4linux/v4l2-framework.txt b/linux/Documentation/video4linux/v4l2-framework.txt index 73f9b6423..21f83089a 100644 --- a/linux/Documentation/video4linux/v4l2-framework.txt +++ b/linux/Documentation/video4linux/v4l2-framework.txt @@ -47,7 +47,9 @@ All drivers have the following structure: 3) Creating V4L2 device nodes (/dev/videoX, /dev/vbiX, /dev/radioX and /dev/vtxX) and keeping track of device-node specific data. -4) Filehandle-specific structs containing per-filehandle data. +4) Filehandle-specific structs containing per-filehandle data; + +5) video buffer handling. This is a rough schematic of how it all relates: @@ -525,3 +527,91 @@ void *video_drvdata(struct file *file); You can go from a video_device struct to the v4l2_device struct using: struct v4l2_device *v4l2_dev = vdev->v4l2_dev; + +video buffer helper functions +----------------------------- + +The v4l2 core API provides a standard method for dealing with video +buffers. Those methods allow a driver to implement read(), mmap() and +overlay() on a consistent way. + +There are currently methods for using video buffers on devices that +supports DMA with scatter/gather method (videobuf-dma-sg), DMA with +linear access (videobuf-dma-contig), and vmalloced buffers, mostly +used on USB drivers (videobuf-vmalloc). + +Any driver using videobuf should provide operations (callbacks) for +four handlers: + +ops->buf_setup - calculates the size of the video buffers and avoid they + to waste more than some maximum limit of RAM; +ops->buf_prepare - fills the video buffer structs and calls + videobuf_iolock() to alloc and prepare mmaped memory; +ops->buf_queue - advices the driver that another buffer were + requested (by read() or by QBUF); +ops->buf_release - frees any buffer that were allocated. + +In order to use it, the driver need to have a code (generally called at +interrupt context) that will properly handle the buffer request lists, +announcing that a new buffer were filled. + +The irq handling code should handle the videobuf task lists, in order +to advice videobuf that a new frame were filled, in order to honor to a +request. The code is generally like this one: + if (list_empty(&dma_q->active)) + return; + + buf = list_entry(dma_q->active.next, struct vbuffer, vb.queue); + + if (!waitqueue_active(&buf->vb.done)) + return; + + /* Some logic to handle the buf may be needed here */ + + list_del(&buf->vb.queue); + do_gettimeofday(&buf->vb.ts); + wake_up(&buf->vb.done); + +Those are the videobuffer functions used on drivers, implemented on +videobuf-core: + +- videobuf_queue_core_init() + Initializes the videobuf infrastructure. This function should be + called before any other videobuf function. + +- videobuf_iolock() + Prepares the videobuf memory for the proper method (read, mmap, overlay). + +- videobuf_queue_is_busy() + Checks if a videobuf is streaming. + +- videobuf_queue_cancel() + Stops video handling. + +- videobuf_mmap_free() + frees mmap buffers. + +- videobuf_stop() + Stops video handling, ends mmap and frees mmap and other buffers. + +- V4L2 api functions. Those functions correspond to VIDIOC_foo ioctls: + videobuf_reqbufs(), videobuf_querybuf(), videobuf_qbuf(), + videobuf_dqbuf(), videobuf_streamon(), videobuf_streamoff(). + +- V4L1 api function (corresponds to VIDIOCMBUF ioctl): + videobuf_cgmbuf() + This function is used to provide backward compatibility with V4L1 + API. + +- Some help functions for read()/poll() operations: + videobuf_read_stream() + For continuous stream read() + videobuf_read_one() + For snapshot read() + videobuf_poll_stream() + polling help function + +The better way to understand it is to take a look at vivi driver. One +of the main reasons for vivi is to be a videobuf usage example. the +vivi_thread_tick() does the task that the IRQ callback would do on PCI +drivers (or the irq callback on USB). -- cgit v1.2.3 From c02991ae9384f6940ac34f853f5191b7bcf1f453 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 14 Feb 2009 08:51:28 -0200 Subject: v4l2-framework.txt: Fixes the videobuf init functions From: Mauro Carvalho Chehab Documents the driver usage functions, instead of the generic one used by the videobuf specific handlers. Signed-off-by: Mauro Carvalho Chehab --- linux/Documentation/video4linux/v4l2-framework.txt | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/Documentation/video4linux/v4l2-framework.txt b/linux/Documentation/video4linux/v4l2-framework.txt index 21f83089a..a6005257a 100644 --- a/linux/Documentation/video4linux/v4l2-framework.txt +++ b/linux/Documentation/video4linux/v4l2-framework.txt @@ -575,9 +575,21 @@ request. The code is generally like this one: Those are the videobuffer functions used on drivers, implemented on videobuf-core: -- videobuf_queue_core_init() - Initializes the videobuf infrastructure. This function should be - called before any other videobuf function. +- Videobuf init functions + videobuf_queue_sg_init() + Initializes the videobuf infrastructure. This function should be + called before any other videobuf function on drivers that uses DMA + Scatter/Gather buffers. + + videobuf_queue_dma_contig_init + Initializes the videobuf infrastructure. This function should be + called before any other videobuf function on drivers that need DMA + contiguous buffers. + + videobuf_queue_vmalloc_init() + Initializes the videobuf infrastructure. This function should be + called before any other videobuf function on USB (and other drivers) + that need a vmalloced type of videobuf. - videobuf_iolock() Prepares the videobuf memory for the proper method (read, mmap, overlay). -- cgit v1.2.3 From add4cca4f1bb659d08d75b45f57b226325a34a6b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 14 Feb 2009 15:31:01 +0100 Subject: v4l2-dev: remove limit of 32 devices per driver in get_index() From: Hans Verkuil get_index() had a limitation of 32 devices per driver. This was unnecessarily strict and has been replaced with the maximum number of devices. That should really satisfy anyone! Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/v4l2-dev.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/v4l2-dev.c b/linux/drivers/media/video/v4l2-dev.c index 9e34e9ec2..e6dc1279a 100644 --- a/linux/drivers/media/video/v4l2-dev.c +++ b/linux/drivers/media/video/v4l2-dev.c @@ -326,37 +326,38 @@ static const struct file_operations v4l2_fops = { */ static int get_index(struct video_device *vdev, int num) { - u32 used = 0; - const int max_index = sizeof(used) * 8 - 1; + /* This can be static since this function is called with the global + videodev_lock held. */ + static DECLARE_BITMAP(used, VIDEO_NUM_DEVICES); int i; - /* Currently a single v4l driver instance cannot create more than - 32 devices. - Increase to u64 or an array of u32 if more are needed. */ - if (num > max_index) { + if (num >= VIDEO_NUM_DEVICES) { printk(KERN_ERR "videodev: %s num is too large\n", __func__); return -EINVAL; } - /* Some drivers do not set the parent. In that case always return 0. */ + /* Some drivers do not set the parent. In that case always return + num or 0. */ if (vdev->parent == NULL) - return 0; + return num >= 0 ? num : 0; + + bitmap_zero(used, VIDEO_NUM_DEVICES); for (i = 0; i < VIDEO_NUM_DEVICES; i++) { if (video_device[i] != NULL && video_device[i]->parent == vdev->parent) { - used |= 1 << video_device[i]->index; + set_bit(video_device[i]->index, used); } } if (num >= 0) { - if (used & (1 << num)) + if (test_bit(num, used)) return -ENFILE; return num; } - i = ffz(used); - return i > max_index ? -ENFILE : i; + i = find_first_zero_bit(used, VIDEO_NUM_DEVICES); + return i == VIDEO_NUM_DEVICES ? -ENFILE : i; } int video_register_device(struct video_device *vdev, int type, int nr) -- cgit v1.2.3 From 398608cab6406080ef01e4cbfbd88a4c401f4fc0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 14 Feb 2009 15:37:17 +0100 Subject: vivi: update comment to reflect that vivi can now create more than 32 devs. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/vivi.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index 603274874..e089cbd27 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -1348,10 +1348,7 @@ static struct video_device vivi_template = { The real maximum number of virtual drivers will depend on how many drivers will succeed. This is limited to the maximum number of devices that - videodev supports. Since there are 64 minors for video grabbers, this is - currently the theoretical maximum limit. However, a further limit does - exist at videodev that forbids any driver to register more than 32 video - grabbers. + videodev supports, which is equal to VIDEO_NUM_DEVICES. */ static int __init vivi_init(void) { -- cgit v1.2.3 From 9511f472cfb47c53ad0f210dd137dedfb753cea7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 14 Feb 2009 15:54:23 +0100 Subject: v4l2-device: allow a NULL parent device when registering. From: Hans Verkuil Some drivers (e.g. for ISA devices) have no parent device because there is no associated bus driver. Allow the parent device to be NULL in those cases when registering v4l2_device. Priority: normal Signed-off-by: Hans Verkuil --- linux/Documentation/video4linux/v4l2-framework.txt | 58 +++++++++++----------- linux/drivers/media/video/v4l2-device.c | 37 +++++++++----- linux/include/media/v4l2-device.h | 31 +++++++----- 3 files changed, 72 insertions(+), 54 deletions(-) (limited to 'linux') diff --git a/linux/Documentation/video4linux/v4l2-framework.txt b/linux/Documentation/video4linux/v4l2-framework.txt index a6005257a..e1620e2a3 100644 --- a/linux/Documentation/video4linux/v4l2-framework.txt +++ b/linux/Documentation/video4linux/v4l2-framework.txt @@ -84,12 +84,14 @@ You must register the device instance: v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev); Registration will initialize the v4l2_device struct and link dev->driver_data -to v4l2_dev. Registration will also set v4l2_dev->name to a value derived from -dev (driver name followed by the bus_id, to be precise). You may change the -name after registration if you want. +to v4l2_dev. If v4l2_dev->name is empty then it will be set to a value derived +from dev (driver name followed by the bus_id, to be precise). If you set it +up before calling v4l2_device_register then it will be untouched. If dev is +NULL, then you *must* setup v4l2_dev->name before calling v4l2_device_register. The first 'dev' argument is normally the struct device pointer of a pci_dev, -usb_device or platform_device. +usb_device or platform_device. It is rare for dev to be NULL, but it happens +with ISA devices, for example. You unregister with: @@ -531,11 +533,11 @@ struct v4l2_device *v4l2_dev = vdev->v4l2_dev; video buffer helper functions ----------------------------- -The v4l2 core API provides a standard method for dealing with video -buffers. Those methods allow a driver to implement read(), mmap() and +The v4l2 core API provides a standard method for dealing with video +buffers. Those methods allow a driver to implement read(), mmap() and overlay() on a consistent way. -There are currently methods for using video buffers on devices that +There are currently methods for using video buffers on devices that supports DMA with scatter/gather method (videobuf-dma-sg), DMA with linear access (videobuf-dma-contig), and vmalloced buffers, mostly used on USB drivers (videobuf-vmalloc). @@ -544,50 +546,50 @@ Any driver using videobuf should provide operations (callbacks) for four handlers: ops->buf_setup - calculates the size of the video buffers and avoid they - to waste more than some maximum limit of RAM; + to waste more than some maximum limit of RAM; ops->buf_prepare - fills the video buffer structs and calls videobuf_iolock() to alloc and prepare mmaped memory; ops->buf_queue - advices the driver that another buffer were - requested (by read() or by QBUF); + requested (by read() or by QBUF); ops->buf_release - frees any buffer that were allocated. In order to use it, the driver need to have a code (generally called at interrupt context) that will properly handle the buffer request lists, announcing that a new buffer were filled. -The irq handling code should handle the videobuf task lists, in order -to advice videobuf that a new frame were filled, in order to honor to a +The irq handling code should handle the videobuf task lists, in order +to advice videobuf that a new frame were filled, in order to honor to a request. The code is generally like this one: - if (list_empty(&dma_q->active)) + if (list_empty(&dma_q->active)) return; - buf = list_entry(dma_q->active.next, struct vbuffer, vb.queue); + buf = list_entry(dma_q->active.next, struct vbuffer, vb.queue); - if (!waitqueue_active(&buf->vb.done)) + if (!waitqueue_active(&buf->vb.done)) return; /* Some logic to handle the buf may be needed here */ - list_del(&buf->vb.queue); - do_gettimeofday(&buf->vb.ts); - wake_up(&buf->vb.done); + list_del(&buf->vb.queue); + do_gettimeofday(&buf->vb.ts); + wake_up(&buf->vb.done); -Those are the videobuffer functions used on drivers, implemented on +Those are the videobuffer functions used on drivers, implemented on videobuf-core: - Videobuf init functions videobuf_queue_sg_init() - Initializes the videobuf infrastructure. This function should be - called before any other videobuf function on drivers that uses DMA + Initializes the videobuf infrastructure. This function should be + called before any other videobuf function on drivers that uses DMA Scatter/Gather buffers. videobuf_queue_dma_contig_init - Initializes the videobuf infrastructure. This function should be - called before any other videobuf function on drivers that need DMA + Initializes the videobuf infrastructure. This function should be + called before any other videobuf function on drivers that need DMA contiguous buffers. videobuf_queue_vmalloc_init() - Initializes the videobuf infrastructure. This function should be + Initializes the videobuf infrastructure. This function should be called before any other videobuf function on USB (and other drivers) that need a vmalloced type of videobuf. @@ -607,12 +609,12 @@ videobuf-core: Stops video handling, ends mmap and frees mmap and other buffers. - V4L2 api functions. Those functions correspond to VIDIOC_foo ioctls: - videobuf_reqbufs(), videobuf_querybuf(), videobuf_qbuf(), + videobuf_reqbufs(), videobuf_querybuf(), videobuf_qbuf(), videobuf_dqbuf(), videobuf_streamon(), videobuf_streamoff(). - V4L1 api function (corresponds to VIDIOCMBUF ioctl): videobuf_cgmbuf() - This function is used to provide backward compatibility with V4L1 + This function is used to provide backward compatibility with V4L1 API. - Some help functions for read()/poll() operations: @@ -623,7 +625,7 @@ videobuf-core: videobuf_poll_stream() polling help function -The better way to understand it is to take a look at vivi driver. One -of the main reasons for vivi is to be a videobuf usage example. the -vivi_thread_tick() does the task that the IRQ callback would do on PCI +The better way to understand it is to take a look at vivi driver. One +of the main reasons for vivi is to be a videobuf usage example. the +vivi_thread_tick() does the task that the IRQ callback would do on PCI drivers (or the irq callback on USB). diff --git a/linux/drivers/media/video/v4l2-device.c b/linux/drivers/media/video/v4l2-device.c index e84925976..cb8234437 100644 --- a/linux/drivers/media/video/v4l2-device.c +++ b/linux/drivers/media/video/v4l2-device.c @@ -27,15 +27,24 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev) { - if (dev == NULL || v4l2_dev == NULL) + if (v4l2_dev == NULL) return -EINVAL; - /* Warn if we apparently re-register a device */ - WARN_ON(dev_get_drvdata(dev) != NULL); + INIT_LIST_HEAD(&v4l2_dev->subdevs); spin_lock_init(&v4l2_dev->lock); v4l2_dev->dev = dev; - snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s", + if (dev == NULL) { + /* If dev == NULL, then name must be filled in by the caller */ + WARN_ON(!v4l2_dev->name[0]); + return 0; + } + + /* Set name to driver name + device name if it is empty. */ + if (!v4l2_dev->name[0]) + snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s", dev->driver->name, dev_name(dev)); + if (dev_get_drvdata(dev)) + v4l2_warn(v4l2_dev, "Non-NULL drvdata on register\n"); dev_set_drvdata(dev, v4l2_dev); return 0; } @@ -45,10 +54,11 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev) { struct v4l2_subdev *sd, *next; - if (v4l2_dev == NULL || v4l2_dev->dev == NULL) + if (v4l2_dev == NULL) return; - dev_set_drvdata(v4l2_dev->dev, NULL); - /* unregister subdevs */ + if (v4l2_dev->dev) + dev_set_drvdata(v4l2_dev->dev, NULL); + /* Unregister subdevs */ list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list) v4l2_device_unregister_subdev(sd); @@ -56,19 +66,20 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev) } EXPORT_SYMBOL_GPL(v4l2_device_unregister); -int v4l2_device_register_subdev(struct v4l2_device *dev, struct v4l2_subdev *sd) +int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, + struct v4l2_subdev *sd) { /* Check for valid input */ - if (dev == NULL || sd == NULL || !sd->name[0]) + if (v4l2_dev == NULL || sd == NULL || !sd->name[0]) return -EINVAL; /* Warn if we apparently re-register a subdev */ WARN_ON(sd->dev != NULL); if (!try_module_get(sd->owner)) return -ENODEV; - sd->dev = dev; - spin_lock(&dev->lock); - list_add_tail(&sd->list, &dev->subdevs); - spin_unlock(&dev->lock); + sd->dev = v4l2_dev; + spin_lock(&v4l2_dev->lock); + list_add_tail(&sd->list, &v4l2_dev->subdevs); + spin_unlock(&v4l2_dev->lock); return 0; } EXPORT_SYMBOL_GPL(v4l2_device_register_subdev); diff --git a/linux/include/media/v4l2-device.h b/linux/include/media/v4l2-device.h index 55e41afd9..5d7146dc2 100644 --- a/linux/include/media/v4l2-device.h +++ b/linux/include/media/v4l2-device.h @@ -33,7 +33,9 @@ #define V4L2_DEVICE_NAME_SIZE (BUS_ID_SIZE + 16) struct v4l2_device { - /* dev->driver_data points to this struct */ + /* dev->driver_data points to this struct. + Note: dev might be NULL if there is no parent device + as is the case with e.g. ISA devices. */ struct device *dev; /* used to keep track of the registered subdevs */ struct list_head subdevs; @@ -44,7 +46,9 @@ struct v4l2_device { char name[V4L2_DEVICE_NAME_SIZE]; }; -/* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev */ +/* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev. + dev may be NULL in rare cases (ISA devices). In that case you + must fill in the v4l2_dev->name field before calling this function. */ int __must_check v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev); /* Set v4l2_dev->dev->driver_data to NULL and unregister all sub-devices */ void v4l2_device_unregister(struct v4l2_device *v4l2_dev); @@ -52,23 +56,24 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev); /* Register a subdev with a v4l2 device. While registered the subdev module is marked as in-use. An error is returned if the module is no longer loaded when you attempt to register it. */ -int __must_check v4l2_device_register_subdev(struct v4l2_device *dev, struct v4l2_subdev *sd); +int __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, + struct v4l2_subdev *sd); /* Unregister a subdev with a v4l2 device. Can also be called if the subdev wasn't registered. In that case it will do nothing. */ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd); /* Iterate over all subdevs. */ -#define v4l2_device_for_each_subdev(sd, dev) \ - list_for_each_entry(sd, &(dev)->subdevs, list) +#define v4l2_device_for_each_subdev(sd, v4l2_dev) \ + list_for_each_entry(sd, &(v4l2_dev)->subdevs, list) /* Call the specified callback for all subdevs matching the condition. Ignore any errors. Note that you cannot add or delete a subdev while walking the subdevs list. */ -#define __v4l2_device_call_subdevs(dev, cond, o, f, args...) \ +#define __v4l2_device_call_subdevs(v4l2_dev, cond, o, f, args...) \ do { \ struct v4l2_subdev *sd; \ \ - list_for_each_entry(sd, &(dev)->subdevs, list) \ + list_for_each_entry(sd, &(v4l2_dev)->subdevs, list) \ if ((cond) && sd->ops->o && sd->ops->o->f) \ sd->ops->o->f(sd , ##args); \ } while (0) @@ -77,12 +82,12 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd); If the callback returns an error other than 0 or -ENOIOCTLCMD, then return with that error code. Note that you cannot add or delete a subdev while walking the subdevs list. */ -#define __v4l2_device_call_subdevs_until_err(dev, cond, o, f, args...) \ +#define __v4l2_device_call_subdevs_until_err(v4l2_dev, cond, o, f, args...) \ ({ \ struct v4l2_subdev *sd; \ long err = 0; \ \ - list_for_each_entry(sd, &(dev)->subdevs, list) { \ + list_for_each_entry(sd, &(v4l2_dev)->subdevs, list) { \ if ((cond) && sd->ops->o && sd->ops->o->f) \ err = sd->ops->o->f(sd , ##args); \ if (err && err != -ENOIOCTLCMD) \ @@ -94,16 +99,16 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd); /* Call the specified callback for all subdevs matching grp_id (if 0, then match them all). Ignore any errors. Note that you cannot add or delete a subdev while walking the subdevs list. */ -#define v4l2_device_call_all(dev, grpid, o, f, args...) \ - __v4l2_device_call_subdevs(dev, \ +#define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...) \ + __v4l2_device_call_subdevs(v4l2_dev, \ !(grpid) || sd->grp_id == (grpid), o, f , ##args) /* Call the specified callback for all subdevs matching grp_id (if 0, then match them all). If the callback returns an error other than 0 or -ENOIOCTLCMD, then return with that error code. Note that you cannot add or delete a subdev while walking the subdevs list. */ -#define v4l2_device_call_until_err(dev, grpid, o, f, args...) \ - __v4l2_device_call_subdevs_until_err(dev, \ +#define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...) \ + __v4l2_device_call_subdevs_until_err(v4l2_dev, \ !(grpid) || sd->grp_id == (grpid), o, f , ##args) #endif -- cgit v1.2.3 From 951bf44feee86f832f1b68efe05395dfee73a15c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 14 Feb 2009 16:00:53 +0100 Subject: v4l2-subdev: rename dev field to v4l2_dev From: Hans Verkuil Remain consistent in the naming: fields pointing to v4l2_device should be called v4l2_dev. There are too many device-like entities without adding to the confusion by mixing naming conventions. Priority: normal Signed-off-by: Hans Verkuil --- linux/Documentation/video4linux/v4l2-framework.txt | 2 +- linux/drivers/media/video/v4l2-device.c | 12 ++++++------ linux/include/media/v4l2-subdev.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'linux') diff --git a/linux/Documentation/video4linux/v4l2-framework.txt b/linux/Documentation/video4linux/v4l2-framework.txt index e1620e2a3..accc376e9 100644 --- a/linux/Documentation/video4linux/v4l2-framework.txt +++ b/linux/Documentation/video4linux/v4l2-framework.txt @@ -268,7 +268,7 @@ errors (except -ENOIOCTLCMD) occured, then 0 is returned. The second argument to both calls is a group ID. If 0, then all subdevs are called. If non-zero, then only those whose group ID match that value will -be called. Before a bridge driver registers a subdev it can set subdev->grp_id +be called. Before a bridge driver registers a subdev it can set sd->grp_id to whatever value it wants (it's 0 by default). This value is owned by the bridge driver and the sub-device driver will never modify or use it. diff --git a/linux/drivers/media/video/v4l2-device.c b/linux/drivers/media/video/v4l2-device.c index cb8234437..35e42e947 100644 --- a/linux/drivers/media/video/v4l2-device.c +++ b/linux/drivers/media/video/v4l2-device.c @@ -73,10 +73,10 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, if (v4l2_dev == NULL || sd == NULL || !sd->name[0]) return -EINVAL; /* Warn if we apparently re-register a subdev */ - WARN_ON(sd->dev != NULL); + WARN_ON(sd->v4l2_dev != NULL); if (!try_module_get(sd->owner)) return -ENODEV; - sd->dev = v4l2_dev; + sd->v4l2_dev = v4l2_dev; spin_lock(&v4l2_dev->lock); list_add_tail(&sd->list, &v4l2_dev->subdevs); spin_unlock(&v4l2_dev->lock); @@ -87,12 +87,12 @@ EXPORT_SYMBOL_GPL(v4l2_device_register_subdev); void v4l2_device_unregister_subdev(struct v4l2_subdev *sd) { /* return if it isn't registered */ - if (sd == NULL || sd->dev == NULL) + if (sd == NULL || sd->v4l2_dev == NULL) return; - spin_lock(&sd->dev->lock); + spin_lock(&sd->v4l2_dev->lock); list_del(&sd->list); - spin_unlock(&sd->dev->lock); - sd->dev = NULL; + spin_unlock(&sd->v4l2_dev->lock); + sd->v4l2_dev = NULL; module_put(sd->owner); } EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev); diff --git a/linux/include/media/v4l2-subdev.h b/linux/include/media/v4l2-subdev.h index cd640c6f0..05b69652e 100644 --- a/linux/include/media/v4l2-subdev.h +++ b/linux/include/media/v4l2-subdev.h @@ -137,7 +137,7 @@ struct v4l2_subdev_ops { struct v4l2_subdev { struct list_head list; struct module *owner; - struct v4l2_device *dev; + struct v4l2_device *v4l2_dev; const struct v4l2_subdev_ops *ops; /* name must be unique */ char name[V4L2_SUBDEV_NAME_SIZE]; @@ -176,7 +176,7 @@ static inline void v4l2_subdev_init(struct v4l2_subdev *sd, /* ops->core MUST be set */ BUG_ON(!ops || !ops->core); sd->ops = ops; - sd->dev = NULL; + sd->v4l2_dev = NULL; sd->name[0] = '\0'; sd->grp_id = 0; sd->priv = NULL; -- cgit v1.2.3 From f9bd48b87f02902de6b355af1489669baaad39b5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 14 Feb 2009 17:23:12 +0100 Subject: vivi: introduce v4l2_device and do several cleanups From: Hans Verkuil - add v4l2_device - remove BKL - make the debug parameter settable on the fly - set bus_info in querycap Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/vivi.c | 258 ++++++++++++++++++++------------------- 1 file changed, 130 insertions(+), 128 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index e089cbd27..e4cb33ca0 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -34,14 +34,15 @@ #include #endif #include -#include -#include -#include #include #include #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) #include #endif +#include +#include +#include +#include "font.h" #define VIVI_MODULE_NAME "vivi" @@ -50,18 +51,32 @@ #define WAKE_DENOMINATOR 1001 #define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ -#include "font.h" - #define VIVI_MAJOR_VERSION 0 -#define VIVI_MINOR_VERSION 5 +#define VIVI_MINOR_VERSION 6 #define VIVI_RELEASE 0 #define VIVI_VERSION \ KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) -/* Declare static vars that will be used as parameters */ -static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ -static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ -static int n_devs = 1; /* Number of virtual devices */ +MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board"); +MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol"); +MODULE_LICENSE("Dual BSD/GPL"); + +static unsigned video_nr = -1; +module_param(video_nr, uint, 0644); +MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect"); + +static unsigned n_devs = 1; +module_param(n_devs, uint, 0644); +MODULE_PARM_DESC(n_devs, "number of video devices to create"); + +static unsigned debug; +module_param(debug, uint, 0644); +MODULE_PARM_DESC(debug, "activates debug info"); + +static unsigned int vid_limit = 16; +module_param(vid_limit, uint, 0644); +MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); + /* supported controls */ static struct v4l2_queryctrl vivi_qctrl[] = { @@ -115,11 +130,8 @@ static struct v4l2_queryctrl vivi_qctrl[] = { static int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; -#define dprintk(dev, level, fmt, arg...) \ - do { \ - if (dev->vfd->debug >= (level)) \ - printk(KERN_DEBUG "vivi: " fmt , ## arg); \ - } while (0) +#define dprintk(dev, level, fmt, arg...) \ + v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg) /* ------------------------------------------------------------------ Basic structures @@ -209,6 +221,7 @@ static LIST_HEAD(vivi_devlist); struct vivi_dev { struct list_head vivi_devlist; + struct v4l2_device v4l2_dev; spinlock_t slock; struct mutex mutex; @@ -659,7 +672,7 @@ static int vivi_start_thread(struct vivi_fh *fh) dma_q->kthread = kthread_run(vivi_thread, fh, "vivi"); if (IS_ERR(dma_q->kthread)) { - printk(KERN_ERR "vivi: kernel_thread() failed\n"); + v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n"); return PTR_ERR(dma_q->kthread); } /* Wakes thread */ @@ -802,8 +815,12 @@ static struct videobuf_queue_ops vivi_video_qops = { static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { + struct vivi_fh *fh = priv; + struct vivi_dev *dev = fh->dev; + strcpy(cap->driver, "vivi"); strcpy(cap->card, "vivi"); + strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info)); cap->version = VIVI_VERSION; cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | @@ -1127,32 +1144,21 @@ static int vidioc_s_ctrl(struct file *file, void *priv, static int vivi_open(struct file *file) { - int minor = video_devdata(file)->minor; - struct vivi_dev *dev; + struct vivi_dev *dev = video_drvdata(file); struct vivi_fh *fh = NULL; int i; int retval = 0; - printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor); - - lock_kernel(); - list_for_each_entry(dev, &vivi_devlist, vivi_devlist) - if (dev->vfd->minor == minor) - goto found; - unlock_kernel(); - return -ENODEV; - -found: mutex_lock(&dev->mutex); dev->users++; if (dev->users > 1) { dev->users--; - retval = -EBUSY; - goto unlock; + mutex_unlock(&dev->mutex); + return -EBUSY; } - dprintk(dev, 1, "open minor=%d type=%s users=%d\n", minor, + dprintk(dev, 1, "open /dev/video%d type=%s users=%d\n", dev->vfd->num, v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users); /* allocate + initialize per filehandle data */ @@ -1160,14 +1166,11 @@ found: if (NULL == fh) { dev->users--; retval = -ENOMEM; - goto unlock; } -unlock: mutex_unlock(&dev->mutex); - if (retval) { - unlock_kernel(); + + if (retval) return retval; - } file->private_data = fh; fh->dev = dev; @@ -1196,7 +1199,6 @@ unlock: sizeof(struct vivi_buffer), fh); vivi_start_thread(fh); - unlock_kernel(); return 0; } @@ -1252,32 +1254,6 @@ static int vivi_close(struct file *file) return 0; } -static int vivi_release(void) -{ - struct vivi_dev *dev; - struct list_head *list; - - while (!list_empty(&vivi_devlist)) { - list = vivi_devlist.next; - list_del(list); - dev = list_entry(list, struct vivi_dev, vivi_devlist); - - if (-1 != dev->vfd->minor) { - printk(KERN_INFO "%s: unregistering /dev/video%d\n", - VIVI_MODULE_NAME, dev->vfd->num); - video_unregister_device(dev->vfd); - } else { - printk(KERN_INFO "%s: releasing /dev/video%d\n", - VIVI_MODULE_NAME, dev->vfd->num); - video_device_release(dev->vfd); - } - - kfree(dev); - } - - return 0; -} - static int vivi_mmap(struct file *file, struct vm_area_struct *vma) { struct vivi_fh *fh = file->private_data; @@ -1340,84 +1316,126 @@ static struct video_device vivi_template = { .tvnorms = V4L2_STD_525_60, .current_norm = V4L2_STD_NTSC_M, }; + /* ----------------------------------------------------------------- Initialization and module stuff ------------------------------------------------------------------*/ -/* This routine allocates from 1 to n_devs virtual drivers. +static int vivi_release(void) +{ + struct vivi_dev *dev; + struct list_head *list; - The real maximum number of virtual drivers will depend on how many drivers - will succeed. This is limited to the maximum number of devices that - videodev supports, which is equal to VIDEO_NUM_DEVICES. - */ -static int __init vivi_init(void) + while (!list_empty(&vivi_devlist)) { + list = vivi_devlist.next; + 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); + video_unregister_device(dev->vfd); + v4l2_device_unregister(&dev->v4l2_dev); + kfree(dev); + } + + return 0; +} + +static int __init vivi_create_instance(int i) { - int ret = -ENOMEM, i; struct vivi_dev *dev; struct video_device *vfd; + int ret; - if (n_devs <= 0) - n_devs = 1; + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; - for (i = 0; i < n_devs; i++) { - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - break; + snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), + "%s-%03d", VIVI_MODULE_NAME, i); + ret = v4l2_device_register(NULL, &dev->v4l2_dev); + if (ret) + goto free_dev; - /* init video dma queues */ - INIT_LIST_HEAD(&dev->vidq.active); - init_waitqueue_head(&dev->vidq.wq); + /* init video dma queues */ + INIT_LIST_HEAD(&dev->vidq.active); + init_waitqueue_head(&dev->vidq.wq); - /* initialize locks */ - spin_lock_init(&dev->slock); - mutex_init(&dev->mutex); + /* initialize locks */ + spin_lock_init(&dev->slock); + mutex_init(&dev->mutex); - vfd = video_device_alloc(); - if (!vfd) { - kfree(dev); - break; - } + ret = -ENOMEM; + vfd = video_device_alloc(); + if (!vfd) + goto unreg_dev; - *vfd = vivi_template; + *vfd = vivi_template; - ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); - if (ret < 0) { - video_device_release(vfd); - kfree(dev); + ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); + if (ret < 0) + goto rel_vdev; - /* If some registers succeeded, keep driver */ - if (i) - ret = 0; + video_set_drvdata(vfd, dev); - break; - } + /* Now that everything is fine, let's add it to device list */ + list_add_tail(&dev->vivi_devlist, &vivi_devlist); - /* 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); - snprintf(vfd->name, sizeof(vfd->name), "%s (%i)", - vivi_template.name, vfd->minor); + if (video_nr >= 0) + video_nr++; - if (video_nr >= 0) - video_nr++; + dev->vfd = vfd; + v4l2_info(&dev->v4l2_dev, "V4L2 device registered as /dev/video%d\n", + vfd->num); + return 0; + +rel_vdev: + video_device_release(vfd); +unreg_dev: + v4l2_device_unregister(&dev->v4l2_dev); +free_dev: + kfree(dev); + return ret; +} - dev->vfd = vfd; - printk(KERN_INFO "%s: V4L2 device registered as /dev/video%d\n", - VIVI_MODULE_NAME, vfd->num); +/* This routine allocates from 1 to n_devs virtual drivers. + + The real maximum number of virtual drivers will depend on how many drivers + will succeed. This is limited to the maximum number of devices that + videodev supports, which is equal to VIDEO_NUM_DEVICES. + */ +static int __init vivi_init(void) +{ + int ret, i; + + if (n_devs <= 0) + n_devs = 1; + + for (i = 0; i < n_devs; i++) { + ret = vivi_create_instance(i); + if (ret) { + /* If some instantiations succeeded, keep driver */ + if (i) + ret = 0; + break; + } } if (ret < 0) { - vivi_release(); printk(KERN_INFO "Error %d while loading vivi driver\n", ret); - } else { - printk(KERN_INFO "Video Technology Magazine Virtual Video " + return ret; + } + + printk(KERN_INFO "Video Technology Magazine Virtual Video " "Capture Board ver %u.%u.%u successfully loaded.\n", (VIVI_VERSION >> 16) & 0xFF, (VIVI_VERSION >> 8) & 0xFF, VIVI_VERSION & 0xFF); - /* n_devs will reflect the actual number of allocated devices */ - n_devs = i; - } + /* n_devs will reflect the actual number of allocated devices */ + n_devs = i; return ret; } @@ -1429,19 +1447,3 @@ static void __exit vivi_exit(void) module_init(vivi_init); module_exit(vivi_exit); - -MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board"); -MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol"); -MODULE_LICENSE("Dual BSD/GPL"); - -module_param(video_nr, uint, 0444); -MODULE_PARM_DESC(video_nr, "video iminor start number"); - -module_param(n_devs, uint, 0444); -MODULE_PARM_DESC(n_devs, "number of video devices to create"); - -module_param_named(debug, vivi_template.debug, int, 0444); -MODULE_PARM_DESC(debug, "activates debug info"); - -module_param(vid_limit, int, 0644); -MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); -- cgit v1.2.3 From c70e5dd6b23d260a1294ff4b23f49ccd78999c86 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 14 Feb 2009 17:43:44 +0100 Subject: vivi: controls are per-device, not global. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/vivi.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index e4cb33ca0..207dfa58f 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -128,8 +128,6 @@ static struct v4l2_queryctrl vivi_qctrl[] = { } }; -static int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; - #define dprintk(dev, level, fmt, arg...) \ v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg) @@ -242,6 +240,9 @@ struct vivi_dev { /* Input Number */ int input; + + /* Control 'registers' */ + int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; }; struct vivi_fh { @@ -1111,12 +1112,14 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { + struct vivi_fh *fh = priv; + struct vivi_dev *dev = fh->dev; int i; for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) if (ctrl->id == vivi_qctrl[i].id) { - ctrl->value = qctl_regs[i]; - return (0); + ctrl->value = dev->qctl_regs[i]; + return 0; } return -EINVAL; @@ -1124,16 +1127,18 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { + struct vivi_fh *fh = priv; + struct vivi_dev *dev = fh->dev; int i; for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) if (ctrl->id == vivi_qctrl[i].id) { - if (ctrl->value < vivi_qctrl[i].minimum - || ctrl->value > vivi_qctrl[i].maximum) { - return (-ERANGE); - } - qctl_regs[i] = ctrl->value; - return (0); + if (ctrl->value < vivi_qctrl[i].minimum || + ctrl->value > vivi_qctrl[i].maximum) { + return -ERANGE; + } + dev->qctl_regs[i] = ctrl->value; + return 0; } return -EINVAL; } @@ -1146,7 +1151,6 @@ static int vivi_open(struct file *file) { struct vivi_dev *dev = video_drvdata(file); struct vivi_fh *fh = NULL; - int i; int retval = 0; mutex_lock(&dev->mutex); @@ -1180,10 +1184,6 @@ static int vivi_open(struct file *file) fh->width = 640; fh->height = 480; - /* Put all controls at a sane state */ - for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) - qctl_regs[i] = vivi_qctrl[i].default_value; - /* Resets frame counters */ dev->h = 0; dev->m = 0; @@ -1341,18 +1341,18 @@ static int vivi_release(void) return 0; } -static int __init vivi_create_instance(int i) +static int __init vivi_create_instance(int inst) { struct vivi_dev *dev; struct video_device *vfd; - int ret; + int ret, i; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), - "%s-%03d", VIVI_MODULE_NAME, i); + "%s-%03d", VIVI_MODULE_NAME, inst); ret = v4l2_device_register(NULL, &dev->v4l2_dev); if (ret) goto free_dev; @@ -1378,6 +1378,10 @@ static int __init vivi_create_instance(int i) video_set_drvdata(vfd, dev); + /* Set all controls to their default value. */ + for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) + dev->qctl_regs[i] = vivi_qctrl[i].default_value; + /* Now that everything is fine, let's add it to device list */ list_add_tail(&dev->vivi_devlist, &vivi_devlist); -- cgit v1.2.3 From 9446aad394fc912dc47f17e7638357edfd470ded Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 14 Feb 2009 17:50:19 +0100 Subject: vivi: add slider flag to controls. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/vivi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index 207dfa58f..76f7dfc32 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -87,7 +87,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = { .maximum = 65535, .step = 65535/100, .default_value = 65535, - .flags = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, .type = V4L2_CTRL_TYPE_INTEGER, }, { .id = V4L2_CID_BRIGHTNESS, @@ -97,7 +97,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = { .maximum = 255, .step = 1, .default_value = 127, - .flags = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, }, { .id = V4L2_CID_CONTRAST, .type = V4L2_CTRL_TYPE_INTEGER, @@ -106,7 +106,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = { .maximum = 255, .step = 0x1, .default_value = 0x10, - .flags = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, }, { .id = V4L2_CID_SATURATION, .type = V4L2_CTRL_TYPE_INTEGER, @@ -115,7 +115,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = { .maximum = 255, .step = 0x1, .default_value = 127, - .flags = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, }, { .id = V4L2_CID_HUE, .type = V4L2_CTRL_TYPE_INTEGER, @@ -124,7 +124,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = { .maximum = 127, .step = 0x1, .default_value = 0, - .flags = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, } }; -- cgit v1.2.3 From 2aa8e5c7af6768440a674eceede51b867f915445 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 14 Feb 2009 15:08:37 -0500 Subject: cx18: Slim down instance handling, build names from v4l2_device.name From: Andy Walls Convert card instance handling to a lighter weight mechanism like ivtv. Also convert name strings and debug messages to use v4l2_device.name. Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-driver.c | 107 ++++++++++---------------- linux/drivers/media/video/cx18/cx18-driver.h | 27 +++---- linux/drivers/media/video/cx18/cx18-fileops.c | 35 ++------- linux/drivers/media/video/cx18/cx18-i2c.c | 2 +- linux/drivers/media/video/cx18/cx18-ioctl.c | 10 +-- linux/drivers/media/video/cx18/cx18-streams.c | 9 ++- 6 files changed, 71 insertions(+), 119 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-driver.c b/linux/drivers/media/video/cx18/cx18-driver.c index f78566bcd..9daf3c90a 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.c +++ b/linux/drivers/media/video/cx18/cx18-driver.c @@ -39,10 +39,6 @@ #include - -/* var to keep track of the number of array elements in use */ -int cx18_cards_active; - /* If you have already X v4l cards, then set this to X. This way the device numbers stay matched. Example: you have a WinTV card without radio and a Compro H900 with. Normally this would give a @@ -50,12 +46,6 @@ int cx18_cards_active; setting this to 1 you ensure that radio0 is now also radio1. */ int cx18_first_minor; -/* Master variable for all cx18 info */ -struct cx18 *cx18_cards[CX18_MAX_CARDS]; - -/* Protects cx18_cards_active */ -DEFINE_SPINLOCK(cx18_cards_lock); - /* add your revision and whatnot here */ static struct pci_device_id cx18_pci_tbl[] __devinitdata = { {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418, @@ -65,6 +55,8 @@ static struct pci_device_id cx18_pci_tbl[] __devinitdata = { MODULE_DEVICE_TABLE(pci, cx18_pci_tbl); +static atomic_t cx18_instance = ATOMIC_INIT(0); + /* Parameter declarations */ static int cardtype[CX18_MAX_CARDS]; static int tuner[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, @@ -491,9 +483,9 @@ static void cx18_process_options(struct cx18 *cx) cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */ } - cx->options.cardtype = cardtype[cx->num]; - cx->options.tuner = tuner[cx->num]; - cx->options.radio = radio[cx->num]; + cx->options.cardtype = cardtype[cx->instance]; + cx->options.tuner = tuner[cx->instance]; + cx->options.radio = radio[cx->instance]; cx->std = cx18_parse_std(cx); if (cx->options.cardtype == -1) { @@ -550,7 +542,7 @@ done: } /* Precondition: the cx18 structure has been memset to 0. Only - the dev and num fields have been filled in. + the dev and instance fields have been filled in. No assumptions on the card type may be made here (see cx18_init_struct2 for that). */ @@ -567,7 +559,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) mutex_init(&cx->epu2apu_mb_lock); mutex_init(&cx->epu2cpu_mb_lock); - cx->work_queue = create_singlethread_workqueue(cx->name); + cx->work_queue = create_singlethread_workqueue(cx->v4l2_dev.name); if (cx->work_queue == NULL) { CX18_ERR("Unable to create work hander thread\n"); return -ENOMEM; @@ -652,15 +644,16 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev, CX18_DEBUG_INFO("Enabling pci device\n"); if (pci_enable_device(pci_dev)) { - CX18_ERR("Can't enable device %d!\n", cx->num); + CX18_ERR("Can't enable device %d!\n", cx->instance); return -EIO; } if (pci_set_dma_mask(pci_dev, 0xffffffff)) { - CX18_ERR("No suitable DMA available on card %d.\n", cx->num); + CX18_ERR("No suitable DMA available, card %d\n", cx->instance); return -EIO; } if (!request_mem_region(cx->base_addr, CX18_MEM_SIZE, "cx18 encoder")) { - CX18_ERR("Cannot request encoder memory region on card %d.\n", cx->num); + CX18_ERR("Cannot request encoder memory region, card %d\n", + cx->instance); return -EIO; } @@ -746,44 +739,42 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, u32 devtype; struct cx18 *cx; - spin_lock(&cx18_cards_lock); - - /* Make sure we've got a place for this card */ - if (cx18_cards_active == CX18_MAX_CARDS) { - printk(KERN_ERR "cx18: Maximum number of cards detected (%d).\n", - cx18_cards_active); - spin_unlock(&cx18_cards_lock); + /* FIXME - module parameter arrays constrain max instances */ + i = atomic_inc_return(&cx18_instance) - 1; + if (i >= CX18_MAX_CARDS) { + printk(KERN_ERR "cx18: cannot manage card %d, driver has a " + "limit of 0 - %d\n", i, CX18_MAX_CARDS - 1); return -ENOMEM; } cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC); - if (!cx) { - spin_unlock(&cx18_cards_lock); + if (cx == NULL) { + printk(KERN_ERR "cx18: cannot manage card %d, out of memory\n", + i); return -ENOMEM; } - cx18_cards[cx18_cards_active] = cx; - cx->num = cx18_cards_active++; - snprintf(cx->name, sizeof(cx->name), "cx18-%d", cx->num); - CX18_INFO("Initializing card #%d\n", cx->num); - - spin_unlock(&cx18_cards_lock); - cx->pci_dev = pci_dev; + cx->instance = i; + retval = v4l2_device_register(&pci_dev->dev, &cx->v4l2_dev); if (retval) { - CX18_ERR("Call to v4l2_device_register() failed\n"); - goto err; + printk(KERN_ERR "cx18: v4l2_device_register of card %d failed" + "\n", cx->instance); + kfree(cx); + return retval; } - CX18_DEBUG_INFO("registered v4l2_device name: %s\n", cx->v4l2_dev.name); + snprintf(cx->v4l2_dev.name, sizeof(cx->v4l2_dev.name), "cx18-%d", + cx->instance); + CX18_INFO("Initializing card %d\n", cx->instance); cx18_process_options(cx); if (cx->options.cardtype == -1) { retval = -ENODEV; - goto unregister_v4l2; + goto err; } if (cx18_init_struct1(cx)) { retval = -ENOMEM; - goto unregister_v4l2; + goto err; } CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr); @@ -834,8 +825,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, goto free_map; } - CX18_DEBUG_INFO("Active card count: %d.\n", cx18_cards_active); - if (cx->card->hw_all & CX18_HW_TVEEPROM) { /* Based on the model number the cardtype may be changed. The PCI IDs are not always reliable. */ @@ -852,7 +841,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, /* Register IRQ */ retval = request_irq(cx->pci_dev->irq, cx18_irq_handler, - IRQF_SHARED | IRQF_DISABLED, cx->name, (void *)cx); + IRQF_SHARED | IRQF_DISABLED, + cx->v4l2_dev.name, (void *)cx); if (retval) { CX18_ERR("Failed to register irq %d\n", retval); goto free_i2c; @@ -938,8 +928,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, goto free_streams; } - CX18_INFO("Initialized card #%d: %s\n", cx->num, cx->card_name); - + CX18_INFO("Initialized card: %s\n", cx->card_name); return 0; free_streams: @@ -954,18 +943,13 @@ free_mem: release_mem_region(cx->base_addr, CX18_MEM_SIZE); free_workqueue: destroy_workqueue(cx->work_queue); -unregister_v4l2: - v4l2_device_unregister(&cx->v4l2_dev); err: if (retval == 0) retval = -ENODEV; CX18_ERR("Error %d on initialization\n", retval); - i = cx->num; - spin_lock(&cx18_cards_lock); - kfree(cx18_cards[i]); - cx18_cards[i] = NULL; - spin_unlock(&cx18_cards_lock); + v4l2_device_unregister(&cx->v4l2_dev); + kfree(cx); return retval; } @@ -1076,9 +1060,9 @@ static void cx18_cancel_epu_work_orders(struct cx18 *cx) static void cx18_remove(struct pci_dev *pci_dev) { struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); - struct cx18 *cx = container_of(v4l2_dev, struct cx18, v4l2_dev); + struct cx18 *cx = to_cx18(v4l2_dev); - CX18_DEBUG_INFO("Removing Card #%d\n", cx->num); + CX18_DEBUG_INFO("Removing Card\n"); /* Stop all captures */ CX18_DEBUG_INFO("Stopping all streams\n"); @@ -1115,10 +1099,12 @@ static void cx18_remove(struct pci_dev *pci_dev) release_mem_region(cx->base_addr, CX18_MEM_SIZE); pci_disable_device(cx->pci_dev); + /* FIXME - we leak cx->vbi.sliced_mpeg_data[i] allocations */ - v4l2_device_unregister(v4l2_dev); + CX18_INFO("Removed %s\n", cx->card_name); - CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num); + v4l2_device_unregister(v4l2_dev); + kfree(cx); } /* define a pci_driver for card detection */ @@ -1133,8 +1119,6 @@ static int module_start(void) { printk(KERN_INFO "cx18: Start initialization, version %s\n", CX18_VERSION); - memset(cx18_cards, 0, sizeof(cx18_cards)); - /* Validate parameters */ if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) { printk(KERN_ERR "cx18: Exiting, cx18_first_minor must be between 0 and %d\n", @@ -1157,16 +1141,7 @@ static int module_start(void) static void module_cleanup(void) { - int i; - pci_unregister_driver(&cx18_pci_driver); - - for (i = 0; i < cx18_cards_active; i++) { - if (cx18_cards[i] == NULL) - continue; - kfree(cx18_cards[i]); - } - } module_init(module_start); diff --git a/linux/drivers/media/video/cx18/cx18-driver.h b/linux/drivers/media/video/cx18/cx18-driver.h index 7fc914c52..def82bd10 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.h +++ b/linux/drivers/media/video/cx18/cx18-driver.h @@ -144,12 +144,12 @@ /* Flag to turn on high volume debugging */ #define CX18_DBGFLG_HIGHVOL (1 << 8) -/* NOTE: extra space before comma in 'cx->num , ## args' is required for +/* NOTE: extra space before comma in 'fmt , ## args' is required for gcc-2.95, otherwise it won't compile. */ #define CX18_DEBUG(x, type, fmt, args...) \ do { \ if ((x) & cx18_debug) \ - printk(KERN_INFO "cx18-%d " type ": " fmt, cx->num , ## args); \ + v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \ } while (0) #define CX18_DEBUG_WARN(fmt, args...) CX18_DEBUG(CX18_DBGFLG_WARN, "warning", fmt , ## args) #define CX18_DEBUG_INFO(fmt, args...) CX18_DEBUG(CX18_DBGFLG_INFO, "info", fmt , ## args) @@ -163,7 +163,7 @@ #define CX18_DEBUG_HIGH_VOL(x, type, fmt, args...) \ do { \ if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \ - printk(KERN_INFO "cx18%d " type ": " fmt, cx->num , ## args); \ + v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \ } while (0) #define CX18_DEBUG_HI_WARN(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_WARN, "warning", fmt , ## args) #define CX18_DEBUG_HI_INFO(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_INFO, "info", fmt , ## args) @@ -175,9 +175,9 @@ #define CX18_DEBUG_HI_IRQ(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IRQ, "irq", fmt , ## args) /* Standard kernel messages */ -#define CX18_ERR(fmt, args...) printk(KERN_ERR "cx18-%d: " fmt, cx->num , ## args) -#define CX18_WARN(fmt, args...) printk(KERN_WARNING "cx18-%d: " fmt, cx->num , ## args) -#define CX18_INFO(fmt, args...) printk(KERN_INFO "cx18-%d: " fmt, cx->num , ## args) +#define CX18_ERR(fmt, args...) v4l2_err(&cx->v4l2_dev, fmt , ## args) +#define CX18_WARN(fmt, args...) v4l2_warn(&cx->v4l2_dev, fmt , ## args) +#define CX18_INFO(fmt, args...) v4l2_info(&cx->v4l2_dev, fmt , ## args) /* Values for CX18_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */ #define MPEG_FRAME_TYPE_IFRAME 1 @@ -445,8 +445,7 @@ struct cx18_i2c_algo_callback_data { /* Struct to hold info about cx18 cards */ struct cx18 { - int num; /* board number, -1 during init! */ - char name[8]; /* board name for printk and interrupts (e.g. 'cx180') */ + int instance; struct pci_dev *pci_dev; struct v4l2_device v4l2_dev; @@ -455,8 +454,8 @@ struct cx18 { const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */ u8 is_50hz; u8 is_60hz; - u8 is_out_50hz; - u8 is_out_60hz; + u8 is_out_50hz; /* FIXME - remove, we don't have an output decoder */ + u8 is_out_60hz; /* FIXME - remove, we don't have an output decoder */ u8 nof_inputs; /* number of video inputs */ u8 nof_audio_inputs; /* number of audio inputs */ u16 buffer_id; /* buffer ID counter */ @@ -547,11 +546,13 @@ struct cx18 { v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */ }; +static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev) +{ + return container_of(v4l2_dev, struct cx18, v4l2_dev); +} + /* Globals */ -extern struct cx18 *cx18_cards[]; -extern int cx18_cards_active; extern int cx18_first_minor; -extern spinlock_t cx18_cards_lock; /*==============Prototypes==================*/ diff --git a/linux/drivers/media/video/cx18/cx18-fileops.c b/linux/drivers/media/video/cx18/cx18-fileops.c index c73fbe65b..c2acb16a9 100644 --- a/linux/drivers/media/video/cx18/cx18-fileops.c +++ b/linux/drivers/media/video/cx18/cx18-fileops.c @@ -718,38 +718,15 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp) int cx18_v4l2_open(struct file *filp) { - int res, x, y = 0; - struct cx18 *cx = NULL; - struct cx18_stream *s = NULL; - int minor = video_devdata(filp)->minor; - - /* Find which card this open was on */ - spin_lock(&cx18_cards_lock); - for (x = 0; cx == NULL && x < cx18_cards_active; x++) { - /* find out which stream this open was on */ - for (y = 0; y < CX18_MAX_STREAMS; y++) { - if (cx18_cards[x] == NULL) - continue; - s = &cx18_cards[x]->streams[y]; - if (s->video_dev && s->video_dev->minor == minor) { - cx = cx18_cards[x]; - break; - } - } - } - spin_unlock(&cx18_cards_lock); - - if (cx == NULL) { - /* Couldn't find a device registered - on that minor, shouldn't happen! */ - printk(KERN_WARNING "No cx18 device found on minor %d\n", - minor); - return -ENXIO; - } + int res; + struct video_device *video_dev = video_devdata(filp); + struct cx18_stream *s = video_get_drvdata(video_dev); + struct cx18 *cx = s->cx;; mutex_lock(&cx->serialize_lock); if (cx18_init_on_first_open(cx)) { - CX18_ERR("Failed to initialize on minor %d\n", minor); + CX18_ERR("Failed to initialize on minor %d\n", + video_dev->minor); mutex_unlock(&cx->serialize_lock); return -ENXIO; } diff --git a/linux/drivers/media/video/cx18/cx18-i2c.c b/linux/drivers/media/video/cx18/cx18-i2c.c index fe6fa60a7..1fd6c04ec 100644 --- a/linux/drivers/media/video/cx18/cx18-i2c.c +++ b/linux/drivers/media/video/cx18/cx18-i2c.c @@ -384,7 +384,7 @@ int init_cx18_i2c(struct cx18 *cx) cx->i2c_adap[i].algo_data = &cx->i2c_algo[i]; sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name), - " #%d-%d", cx->num, i); + " #%d-%d", cx->instance, i); i2c_set_adapdata(&cx->i2c_adap[i], cx); memcpy(&cx->i2c_client[i], &cx18_i2c_client_template, diff --git a/linux/drivers/media/video/cx18/cx18-ioctl.c b/linux/drivers/media/video/cx18/cx18-ioctl.c index 995e19c23..a4a0ed6fe 100644 --- a/linux/drivers/media/video/cx18/cx18-ioctl.c +++ b/linux/drivers/media/video/cx18/cx18-ioctl.c @@ -387,20 +387,17 @@ static int cx18_g_chip_ident(struct file *file, void *fh, static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) { struct v4l2_dbg_register *regs = arg; - unsigned long flags; if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE) return -EINVAL; - spin_lock_irqsave(&cx18_cards_lock, flags); regs->size = 4; if (cmd == VIDIOC_DBG_G_REGISTER) regs->val = cx18_read_enc(cx, regs->reg); else cx18_write_enc(cx, regs->val, regs->reg); - spin_unlock_irqrestore(&cx18_cards_lock, flags); return 0; } @@ -864,7 +861,7 @@ static int cx18_log_status(struct file *file, void *fh) int i; CX18_INFO("================= START STATUS CARD #%d " - "=================\n", cx->num); + "=================\n", cx->instance); CX18_INFO("Version: %s Card: %s\n", CX18_VERSION, cx->card_name); if (cx->hw_flags & CX18_HW_TVEEPROM) { struct tveeprom tv; @@ -882,7 +879,7 @@ static int cx18_log_status(struct file *file, void *fh) mutex_unlock(&cx->gpio_lock); CX18_INFO("Tuner: %s\n", test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV"); - cx2341x_log_status(&cx->params, cx->name); + cx2341x_log_status(&cx->params, cx->v4l2_dev.name); CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags); for (i = 0; i < CX18_MAX_STREAMS; i++) { struct cx18_stream *s = &cx->streams[i]; @@ -897,7 +894,8 @@ static int cx18_log_status(struct file *file, void *fh) CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n", (long long)cx->mpg_data_received, (long long)cx->vbi_data_inserted); - CX18_INFO("================== END STATUS CARD #%d ==================\n", cx->num); + CX18_INFO("================== END STATUS CARD #%d " + "==================\n", cx->instance); return 0; } diff --git a/linux/drivers/media/video/cx18/cx18-streams.c b/linux/drivers/media/video/cx18/cx18-streams.c index e4a70cefc..fb6767086 100644 --- a/linux/drivers/media/video/cx18/cx18-streams.c +++ b/linux/drivers/media/video/cx18/cx18-streams.c @@ -130,7 +130,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type) struct cx18_stream *s = &cx->streams[type]; u32 cap = cx->v4l2_cap; int num_offset = cx18_stream_info[type].num_offset; - int num = cx->num + cx18_first_minor + num_offset; + int num = cx->instance + cx18_first_minor + num_offset; /* These four fields are always initialized. If video_dev == NULL, then this stream is not in use. In that case no other fields but these @@ -170,11 +170,11 @@ static int cx18_prep_dev(struct cx18 *cx, int type) return -ENOMEM; } - snprintf(s->video_dev->name, sizeof(s->video_dev->name), "cx18-%d", - cx->num); + snprintf(s->video_dev->name, sizeof(s->video_dev->name), "%s %s", + cx->v4l2_dev.name, s->name); s->video_dev->num = num; - s->video_dev->parent = &cx->pci_dev->dev; + s->video_dev->v4l2_dev = &cx->v4l2_dev; s->video_dev->fops = &cx18_v4l2_enc_fops; s->video_dev->release = video_device_release; s->video_dev->tvnorms = V4L2_STD_ALL; @@ -239,6 +239,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type) num = s_mpg->video_dev->num + cx18_stream_info[type].num_offset; } + video_set_drvdata(s->video_dev, s); /* Register device. First try the desired minor, then any free one. */ ret = video_register_device(s->video_dev, vfl_type, num); -- cgit v1.2.3 From bdff40c8e0a3b0971c67f28db1b0f9b2fe581313 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 14 Feb 2009 23:26:56 +0100 Subject: uvcvideo: Initialize streaming parameters with the probe control value From: Laurent Pinchart The UVC specification requires SET_CUR requests on the streaming commit control to use values retrieved from a successful GET_CUR request on the probe control. Initialize streaming parameters with the probe control current value to make sure the driver always complies. Priority: normal Signed-off-by: Laurent Pinchart --- linux/drivers/media/video/uvc/uvc_video.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/uvc/uvc_video.c b/linux/drivers/media/video/uvc/uvc_video.c index 04c791213..a4034ccb2 100644 --- a/linux/drivers/media/video/uvc/uvc_video.c +++ b/linux/drivers/media/video/uvc/uvc_video.c @@ -1030,11 +1030,20 @@ int uvc_video_init(struct uvc_video_device *video) */ usb_set_interface(video->dev->udev, video->streaming->intfnum, 0); - /* Some webcams don't suport GET_DEF requests on the probe control. We - * fall back to GET_CUR if GET_DEF fails. + /* Set the streaming probe control with default streaming parameters + * retrieved from the device. Webcams that don't suport GET_DEF + * requests on the probe control will just keep their current streaming + * parameters. */ - if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_DEF)) < 0 && - (ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0) + if (uvc_get_video_ctrl(video, probe, 1, GET_DEF) == 0) + uvc_set_video_ctrl(video, probe, 1); + + /* Initialize the streaming parameters with the probe control current + * value. This makes sure SET_CUR requests on the streaming commit + * control will always use values retrieved from a successful GET_CUR + * request on the probe control, as required by the UVC specification. + */ + if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0) return ret; /* Check if the default format descriptor exists. Use the first -- cgit v1.2.3 From e2a760f26ff7124de2bc6bed4647962dd7078d1b Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 14 Feb 2009 23:39:08 +0100 Subject: uvcvideo: Ignore empty bulk URBs From: Laurent Pinchart Devices may send a zero-length packet to signal the end of a bulk payload. If the payload size is a multiple of the URB size the zero-length packet will be received by the URB completion handler. Handle this by ignoring all empty URBs. Priority: normal Signed-off-by: Laurent Pinchart --- linux/drivers/media/video/uvc/uvc_video.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/uvc/uvc_video.c b/linux/drivers/media/video/uvc/uvc_video.c index a4034ccb2..328910855 100644 --- a/linux/drivers/media/video/uvc/uvc_video.c +++ b/linux/drivers/media/video/uvc/uvc_video.c @@ -540,6 +540,9 @@ static void uvc_video_decode_bulk(struct urb *urb, u8 *mem; int len, ret; + if (urb->actual_length == 0) + return; + mem = urb->transfer_buffer; len = urb->actual_length; video->bulk.payload_size += len; -- cgit v1.2.3 From 2fc2bbdf325e45fee8f2e62a8594fc62f18b5f3e Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Mon, 16 Feb 2009 00:23:25 -0500 Subject: cx18, v4l2-chip-ident: Finish conversion of AV decoder core to v4l2_subdev From: Andy Walls Added a new chip identifer to v4l2-chip-ident for the integrated A/V broadcast decoder core internal to the CX23418. Completed separation and encapsulation of the A/V decoder core interface as a v4l2_subdevice. The cx18 driver now compiles and links again. Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-av-core.c | 85 +++++++++++++++++++------- linux/drivers/media/video/cx18/cx18-av-core.h | 10 ++- linux/drivers/media/video/cx18/cx18-controls.c | 8 +-- linux/drivers/media/video/cx18/cx18-driver.c | 18 +++--- linux/drivers/media/video/cx18/cx18-driver.h | 1 + linux/drivers/media/video/cx18/cx18-firmware.c | 18 ------ linux/drivers/media/video/cx18/cx18-i2c.c | 4 +- linux/drivers/media/video/cx18/cx18-ioctl.c | 22 +++++-- linux/drivers/media/video/cx18/cx18-streams.c | 2 +- linux/drivers/media/video/cx18/cx18-vbi.c | 2 +- linux/drivers/media/video/cx18/cx18-video.c | 2 +- linux/include/media/v4l2-chip-ident.h | 3 +- 12 files changed, 108 insertions(+), 67 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-av-core.c b/linux/drivers/media/video/cx18/cx18-av-core.c index 8f79cc3f4..71f051c33 100644 --- a/linux/drivers/media/video/cx18/cx18-av-core.c +++ b/linux/drivers/media/video/cx18/cx18-av-core.c @@ -201,15 +201,45 @@ static int cx18_av_reset(struct v4l2_subdev *sd, u32 val) return 0; } -static int cx18_av_init_hardware(struct v4l2_subdev *sd, u32 val) +static int cx18_av_init(struct v4l2_subdev *sd, u32 val) { struct cx18_av_state *state = to_cx18_av_state(sd); struct cx18 *cx = v4l2_get_subdevdata(sd); - if (!state->is_initialized) { - /* initialize on first use */ - state->is_initialized = 1; - cx18_av_initialize(cx); + switch (val) { + case CX18_AV_INIT_PLLS: + /* + * The crystal freq used in calculations in this driver will be + * 28.636360 MHz. + * Aim to run the PLLs' VCOs near 400 MHz to minimze errors. + */ + + /* + * VDCLK Integer = 0x0f, Post Divider = 0x04 + * AIMCLK Integer = 0x0e, Post Divider = 0x16 + */ + cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f); + + /* VDCLK Fraction = 0x2be2fe */ + /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */ + cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe); + + /* AIMCLK Fraction = 0x05227ad */ + /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/ + cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad); + + /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */ + cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56); + break; + + case CX18_AV_INIT_NORMAL: + default: + if (!state->is_initialized) { + /* initialize on first use */ + state->is_initialized = 1; + cx18_av_initialize(cx); + } + break; } return 0; } @@ -1092,14 +1122,11 @@ static inline int cx18_av_dbg_match(const struct v4l2_dbg_match *match) static int cx18_av_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { + struct cx18_av_state *state = to_cx18_av_state(sd); + if (cx18_av_dbg_match(&chip->match)) { - /* - * Nothing else is going to claim to be this combination, - * and the real host chip revision will be returned by a host - * match on address 0. - */ - chip->ident = V4L2_IDENT_CX25843; - chip->revision = V4L2_IDENT_CX23418; /* Why not */ + chip->ident = state->id; + chip->revision = state->rev; } return 0; } @@ -1140,7 +1167,7 @@ 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_hardware, + .init = cx18_av_init, .reset = cx18_av_reset, .queryctrl = cx18_av_queryctrl, .g_ctrl = cx18_av_g_ctrl, @@ -1179,19 +1206,31 @@ static const struct v4l2_subdev_ops cx18_av_ops = { .video = &cx18_av_video_ops, }; -int cx18_av_init(struct cx18 *cx) +int cx18_av_probe(struct cx18 *cx, struct v4l2_subdev **sd) { - struct v4l2_subdev *sd = &cx->av_state.sd; - - v4l2_subdev_init(sd, &cx18_av_ops); - v4l2_set_subdevdata(sd, cx); - snprintf(sd->name, sizeof(sd->name), - "%s-internal A/V decoder", cx->v4l2_dev.name); - sd->grp_id = CX18_HW_CX23418; - return v4l2_device_register_subdev(&cx->v4l2_dev, sd); + struct cx18_av_state *state = &cx->av_state; + + state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff; + state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO) + ? V4L2_IDENT_CX23418_843 : V4L2_IDENT_UNKNOWN; + + state->vid_input = CX18_AV_COMPOSITE7; + state->aud_input = CX18_AV_AUDIO8; + state->audclk_freq = 48000; + state->audmode = V4L2_TUNER_MODE_LANG1; + state->slicer_line_delay = 0; + state->slicer_line_offset = (10 + state->slicer_line_delay - 2); + + *sd = &state->sd; + v4l2_subdev_init(*sd, &cx18_av_ops); + v4l2_set_subdevdata(*sd, cx); + snprintf((*sd)->name, sizeof((*sd)->name), + "%s internal A/V decoder", cx->v4l2_dev.name); + (*sd)->grp_id = CX18_HW_CX23418; + return v4l2_device_register_subdev(&cx->v4l2_dev, *sd); } -void cx18_av_fini(struct cx18 *cx) +void cx18_av_exit(struct cx18 *cx, struct v4l2_subdev *sd) { v4l2_device_unregister_subdev(&cx->av_state.sd); } diff --git a/linux/drivers/media/video/cx18/cx18-av-core.h b/linux/drivers/media/video/cx18/cx18-av-core.h index 025100aee..90bdca960 100644 --- a/linux/drivers/media/video/cx18/cx18-av-core.h +++ b/linux/drivers/media/video/cx18/cx18-av-core.h @@ -323,6 +323,11 @@ static inline struct cx18_av_state *to_cx18_av_state(struct v4l2_subdev *sd) return container_of(sd, struct cx18_av_state, sd); } +enum cx18_av_subdev_init_arg { + CX18_AV_INIT_NORMAL = 0, + CX18_AV_INIT_PLLS = 1, +}; + /* ----------------------------------------------------------------------- */ /* cx18_av-core.c */ int cx18_av_write(struct cx18 *cx, u16 addr, u8 value); @@ -337,9 +342,8 @@ int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value); int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value); void cx18_av_std_setup(struct cx18 *cx); -int cx18_av_cmd(struct cx18 *cx, int cmd, void *arg); /* FIXME - Remove */ -int cx18_av_init(struct cx18 *cx); -void cx18_av_fini(struct cx18 *cx); +int cx18_av_probe(struct cx18 *cx, struct v4l2_subdev **sd); +void cx18_av_exit(struct cx18 *cx, struct v4l2_subdev *sd); /* ----------------------------------------------------------------------- */ /* cx18_av-firmware.c */ diff --git a/linux/drivers/media/video/cx18/cx18-controls.c b/linux/drivers/media/video/cx18/cx18-controls.c index 10a4e07b7..9505c4173 100644 --- a/linux/drivers/media/video/cx18/cx18-controls.c +++ b/linux/drivers/media/video/cx18/cx18-controls.c @@ -67,7 +67,7 @@ int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl) case V4L2_CID_HUE: case V4L2_CID_SATURATION: case V4L2_CID_CONTRAST: - if (cx18_av_cmd(cx, VIDIOC_QUERYCTRL, qctrl)) + if (v4l2_subdev_call(cx->sd_av, core, queryctrl, qctrl)) qctrl->flags |= V4L2_CTRL_FLAG_DISABLED; return 0; @@ -126,7 +126,7 @@ static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl) case V4L2_CID_HUE: case V4L2_CID_SATURATION: case V4L2_CID_CONTRAST: - return cx18_av_cmd(cx, VIDIOC_S_CTRL, vctrl); + return v4l2_subdev_call(cx->sd_av, core, s_ctrl, vctrl); case V4L2_CID_AUDIO_VOLUME: case V4L2_CID_AUDIO_MUTE: @@ -151,7 +151,7 @@ static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl) case V4L2_CID_HUE: case V4L2_CID_SATURATION: case V4L2_CID_CONTRAST: - return cx18_av_cmd(cx, VIDIOC_G_CTRL, vctrl); + return v4l2_subdev_call(cx->sd_av, core, g_ctrl, vctrl); case V4L2_CID_AUDIO_VOLUME: case V4L2_CID_AUDIO_MUTE: @@ -278,7 +278,7 @@ int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) fmt.fmt.pix.width = cx->params.width / (is_mpeg1 ? 2 : 1); fmt.fmt.pix.height = cx->params.height; - cx18_av_cmd(cx, VIDIOC_S_FMT, &fmt); + v4l2_subdev_call(cx->sd_av, video, s_fmt, &fmt); } priv.cx = cx; priv.s = &cx->streams[id->type]; diff --git a/linux/drivers/media/video/cx18/cx18-driver.c b/linux/drivers/media/video/cx18/cx18-driver.c index 9daf3c90a..eca2901c9 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.c +++ b/linux/drivers/media/video/cx18/cx18-driver.c @@ -626,13 +626,6 @@ static void __devinit cx18_init_struct2(struct cx18 *cx) i = 0; cx->active_input = i; cx->audio_input = cx->card->video_inputs[i].audio_index; - cx->av_state.vid_input = CX18_AV_COMPOSITE7; - cx->av_state.aud_input = CX18_AV_AUDIO8; - cx->av_state.audclk_freq = 48000; - cx->av_state.audmode = V4L2_TUNER_MODE_LANG1; - cx->av_state.slicer_line_delay = 0; - cx->av_state.slicer_line_offset = - (10 + cx->av_state.slicer_line_delay - 2); } static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev, @@ -817,6 +810,14 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, cx18_gpio_init(cx); + retval = cx18_av_probe(cx, &cx->sd_av); + if (retval) { + CX18_ERR("Could not register A/V decoder subdevice\n"); + goto free_map; + } + /* Initialize the A/V decoder PLLs to sane defaults */ + v4l2_subdev_call(cx->sd_av, core, init, (u32) CX18_AV_INIT_PLLS); + /* active i2c */ CX18_DEBUG_INFO("activating i2c...\n"); retval = init_cx18_i2c(cx); @@ -1025,6 +1026,9 @@ int cx18_init_on_first_open(struct cx18 *cx) cx18_vapi(cx, CX18_APU_RESETAI, 0); cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG); + /* Init the A/V decoder, if it hasn't been already */ + v4l2_subdev_call(cx->sd_av, core, init, (u32) CX18_AV_INIT_NORMAL); + vf.tuner = 0; vf.type = V4L2_TUNER_ANALOG_TV; vf.frequency = 6400; /* the tuner 'baseline' frequency */ diff --git a/linux/drivers/media/video/cx18/cx18-driver.h b/linux/drivers/media/video/cx18/cx18-driver.h index def82bd10..4b50878fc 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.h +++ b/linux/drivers/media/video/cx18/cx18-driver.h @@ -448,6 +448,7 @@ struct cx18 { int instance; struct pci_dev *pci_dev; struct v4l2_device v4l2_dev; + struct v4l2_subdev *sd_av; const struct cx18_card *card; /* card information */ const char *card_name; /* full name of the card */ diff --git a/linux/drivers/media/video/cx18/cx18-firmware.c b/linux/drivers/media/video/cx18/cx18-firmware.c index aa89bee65..83cd559cc 100644 --- a/linux/drivers/media/video/cx18/cx18-firmware.c +++ b/linux/drivers/media/video/cx18/cx18-firmware.c @@ -26,7 +26,6 @@ #include "cx18-irq.h" #include "cx18-firmware.h" #include "cx18-cards.h" -#include "cx18-av-core.h" #include #define CX18_PROC_SOFT_RESET 0xc70010 @@ -286,23 +285,6 @@ void cx18_init_power(struct cx18 *cx, int lowpwr) cx18_write_reg(cx, 0x2BE2FE, CX18_MPEG_CLOCK_PLL_FRAC); cx18_write_reg(cx, 8, CX18_MPEG_CLOCK_PLL_POST); - /* - * VDCLK Integer = 0x0f, Post Divider = 0x04 - * AIMCLK Integer = 0x0e, Post Divider = 0x16 - */ - cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f); - - /* VDCLK Fraction = 0x2be2fe */ - /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */ - cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe); - - /* AIMCLK Fraction = 0x05227ad */ - /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz before post-divide */ - cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad); - - /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */ - cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56); - /* Defaults */ /* APU = SC or SC/2 = 125/62.5 */ /* EPU = SC = 125 */ diff --git a/linux/drivers/media/video/cx18/cx18-i2c.c b/linux/drivers/media/video/cx18/cx18-i2c.c index 1fd6c04ec..d6f4d9d27 100644 --- a/linux/drivers/media/video/cx18/cx18-i2c.c +++ b/linux/drivers/media/video/cx18/cx18-i2c.c @@ -330,7 +330,7 @@ int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg) return cx18_gpio(cx, cmd, arg); if (hw == CX18_HW_CX23418) - return cx18_av_cmd(cx, cmd, arg); + return v4l2_subdev_command(cx->sd_av, cmd, arg); addr = cx18_i2c_hw_addr(cx, hw); if (addr < 0) { @@ -348,7 +348,7 @@ void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg) CX18_ERR("adapter is not set\n"); return; } - cx18_av_cmd(cx, cmd, arg); + v4l2_subdev_command(cx->sd_av, cmd, arg); i2c_clients_command(&cx->i2c_adap[0], cmd, arg); i2c_clients_command(&cx->i2c_adap[1], cmd, arg); if (cx->hw_flags & CX18_HW_GPIO) diff --git a/linux/drivers/media/video/cx18/cx18-ioctl.c b/linux/drivers/media/video/cx18/cx18-ioctl.c index a4a0ed6fe..4345fd733 100644 --- a/linux/drivers/media/video/cx18/cx18-ioctl.c +++ b/linux/drivers/media/video/cx18/cx18-ioctl.c @@ -208,7 +208,7 @@ static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh, * digitizer/slicer. Note, cx18_av_vbi() wipes the passed in * fmt->fmt.sliced under valid calling conditions */ - if (cx18_av_cmd(cx, VIDIOC_G_FMT, fmt)) + if (v4l2_subdev_call(cx->sd_av, video, g_fmt, fmt)) return -EINVAL; /* Ensure V4L2 spec compliant output */ @@ -295,7 +295,7 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh, cx->params.width = w; cx->params.height = h; - cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); + v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt); return cx18_g_fmt_vid_cap(file, fh, fmt); } @@ -322,7 +322,7 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh, * Note cx18_av_vbi_wipes out alot of the passed in fmt under valid * calling conditions */ - ret = cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); + ret = v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt); if (ret) return ret; @@ -359,7 +359,7 @@ static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh, * Note, cx18_av_vbi() wipes some "impossible" service lines in the * passed in fmt->fmt.sliced under valid calling conditions */ - ret = cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); + ret = v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt); if (ret) return ret; /* Store our current v4l2 sliced VBI settings */ @@ -516,7 +516,12 @@ static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop) if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - return cx18_av_cmd(cx, VIDIOC_S_CROP, crop); +#if 0 + return v4l2_subdev_call(cx->sd_av, video, s_crop, crop); +#else + CX18_DEBUG_WARN("VIDIOC_S_CROP not implemented\n"); + return -EINVAL; +#endif } static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) @@ -525,7 +530,12 @@ static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - return cx18_av_cmd(cx, VIDIOC_G_CROP, crop); +#if 0 + return v4l2_subdev_call(cx->sd_av, video, g_crop, crop); +#else + CX18_DEBUG_WARN("VIDIOC_G_CROP not implemented\n"); + return -EINVAL; +#endif } static int cx18_enum_fmt_vid_cap(struct file *file, void *fh, diff --git a/linux/drivers/media/video/cx18/cx18-streams.c b/linux/drivers/media/video/cx18/cx18-streams.c index fb6767086..b022ed161 100644 --- a/linux/drivers/media/video/cx18/cx18-streams.c +++ b/linux/drivers/media/video/cx18/cx18-streams.c @@ -348,7 +348,7 @@ static void cx18_vbi_setup(struct cx18_stream *s) } /* setup VBI registers */ - cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in); + v4l2_subdev_call(cx->sd_av, video, s_fmt, &cx->vbi.in); /* * Send the CX18_CPU_SET_RAW_VBI_PARAM API command to setup Encoder Raw diff --git a/linux/drivers/media/video/cx18/cx18-vbi.c b/linux/drivers/media/video/cx18/cx18-vbi.c index 8e6f4d4af..91c21dce6 100644 --- a/linux/drivers/media/video/cx18/cx18-vbi.c +++ b/linux/drivers/media/video/cx18/cx18-vbi.c @@ -154,7 +154,7 @@ static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf, if (p[0] != 0xff || p[1] || p[2] || p[3] != eav) continue; vbi.p = p + 4; - cx18_av_cmd(cx, VIDIOC_INT_DECODE_VBI_LINE, &vbi); + v4l2_subdev_call(cx->sd_av, video, decode_vbi_line, &vbi); if (vbi.type) { cx->vbi.sliced_data[line].id = vbi.type; cx->vbi.sliced_data[line].field = vbi.is_second_field; diff --git a/linux/drivers/media/video/cx18/cx18-video.c b/linux/drivers/media/video/cx18/cx18-video.c index 2e5c41939..fabacb0f8 100644 --- a/linux/drivers/media/video/cx18/cx18-video.c +++ b/linux/drivers/media/video/cx18/cx18-video.c @@ -32,7 +32,7 @@ void cx18_video_set_io(struct cx18 *cx) route.input = cx->card->video_inputs[inp].video_input; route.output = 0; - cx18_av_cmd(cx, VIDIOC_INT_S_VIDEO_ROUTING, &route); + v4l2_subdev_call(cx->sd_av, video, s_routing, &route); type = cx->card->video_inputs[inp].video_type; diff --git a/linux/include/media/v4l2-chip-ident.h b/linux/include/media/v4l2-chip-ident.h index bbe2bb6a5..ef58d7b13 100644 --- a/linux/include/media/v4l2-chip-ident.h +++ b/linux/include/media/v4l2-chip-ident.h @@ -66,7 +66,8 @@ enum { /* module saa7146: reserved range 300-309 */ V4L2_IDENT_SAA7146 = 300, - /* Conexant MPEG encoder/decoders: reserved range 410-420 */ + /* Conexant MPEG encoder/decoders: reserved range 400-420 */ + V4L2_IDENT_CX23418_843 = 403, /* Integrated A/V Decoder on the '418 */ V4L2_IDENT_CX23415 = 415, V4L2_IDENT_CX23416 = 416, V4L2_IDENT_CX23418 = 418, -- cgit v1.2.3 From b25818a3a4e324f54c59786922c73867af099253 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 16 Feb 2009 21:41:52 +0100 Subject: uvcvideo: Add quirk to override wrong bandwidth value for Vimicro devices From: Laurent Pinchart At least 3 Vimicro cameras (0x332d, 0x3410 and 0x3420) fail to return correct bandwidth information. The first model rounds the value provided by the host to the nearest supported packet size, while the other two always request the maximum bandwidth. Introduce a device quirk to override the value returned by the device with an estimated bandwidth computed by the driver from the frame size and frame rate, and enable it for all Vimicro cameras. Priority: normal Signed-off-by: Laurent Pinchart --- linux/drivers/media/video/uvc/uvc_driver.c | 9 ++++++++ linux/drivers/media/video/uvc/uvc_video.c | 34 ++++++++++++++++++++++++++---- linux/drivers/media/video/uvc/uvcvideo.h | 1 + 3 files changed, 40 insertions(+), 4 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/uvc/uvc_driver.c b/linux/drivers/media/video/uvc/uvc_driver.c index 2a41eb418..0d2d87198 100644 --- a/linux/drivers/media/video/uvc/uvc_driver.c +++ b/linux/drivers/media/video/uvc/uvc_driver.c @@ -1863,6 +1863,15 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_STREAM_NO_FID }, + /* ViMicro */ + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x0ac8, + .idProduct = 0x0000, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_FIX_BANDWIDTH }, /* MT6227 */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, diff --git a/linux/drivers/media/video/uvc/uvc_video.c b/linux/drivers/media/video/uvc/uvc_video.c index 328910855..82a9999b6 100644 --- a/linux/drivers/media/video/uvc/uvc_video.c +++ b/linux/drivers/media/video/uvc/uvc_video.c @@ -61,7 +61,7 @@ int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, return 0; } -static void uvc_fixup_buffer_size(struct uvc_video_device *video, +static void uvc_fixup_video_ctrl(struct uvc_video_device *video, struct uvc_streaming_control *ctrl) { struct uvc_format *format; @@ -84,6 +84,31 @@ static void uvc_fixup_buffer_size(struct uvc_video_device *video, video->dev->uvc_version < 0x0110)) ctrl->dwMaxVideoFrameSize = frame->dwMaxVideoFrameBufferSize; + + if (video->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH && + video->streaming->intf->num_altsetting > 1) { + u32 interval; + u32 bandwidth; + + interval = (ctrl->dwFrameInterval > 100000) + ? ctrl->dwFrameInterval + : frame->dwFrameInterval[0]; + + /* Compute a bandwidth estimation by multiplying the frame + * size by the number of video frames per second, divide the + * result by the number of USB frames (or micro-frames for + * high-speed devices) per second and add the UVC header size + * (assumed to be 12 bytes long). + */ + bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp; + bandwidth *= 10000000 / interval + 1; + bandwidth /= 1000; + if (video->dev->udev->speed == USB_SPEED_HIGH) + bandwidth /= 8; + bandwidth += 12; + + ctrl->dwMaxPayloadTransferSize = bandwidth; + } } static int uvc_get_video_ctrl(struct uvc_video_device *video, @@ -158,10 +183,11 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video, ctrl->bMaxVersion = 0; } - /* Some broken devices return a null or wrong dwMaxVideoFrameSize. - * Try to get the value from the format and frame descriptors. + /* Some broken devices return null or wrong dwMaxVideoFrameSize and + * dwMaxPayloadTransferSize fields. Try to get the value from the + * format and frame descriptors. */ - uvc_fixup_buffer_size(video, ctrl); + uvc_fixup_video_ctrl(video, ctrl); ret = 0; out: diff --git a/linux/drivers/media/video/uvc/uvcvideo.h b/linux/drivers/media/video/uvc/uvcvideo.h index 408b8b846..53d5c9e0c 100644 --- a/linux/drivers/media/video/uvc/uvcvideo.h +++ b/linux/drivers/media/video/uvc/uvcvideo.h @@ -315,6 +315,7 @@ struct uvc_xu_control { #define UVC_QUIRK_STREAM_NO_FID 0x00000010 #define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 #define UVC_QUIRK_PRUNE_CONTROLS 0x00000040 +#define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 /* Format flags */ #define UVC_FMT_FLAG_COMPRESSED 0x00000001 -- cgit v1.2.3 From b598952580418f91c7bd0dc9d42802a052e84a6e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 17 Feb 2009 10:11:12 -0300 Subject: backport include changes on some .h files From: Mauro Carvalho Chehab kernel-sync: Signed-off-by: Mauro Carvalho Chehab --- linux/include/linux/dvb/audio.h | 5 ----- linux/include/linux/dvb/dmx.h | 2 +- linux/include/linux/dvb/frontend.h | 3 +-- linux/include/linux/dvb/net.h | 3 +-- linux/include/linux/dvb/video.h | 7 ++----- linux/include/linux/video_decoder.h | 2 ++ linux/include/linux/videodev.h | 1 + linux/include/media/videobuf-dma-sg.h | 2 +- 8 files changed, 9 insertions(+), 16 deletions(-) (limited to 'linux') diff --git a/linux/include/linux/dvb/audio.h b/linux/include/linux/dvb/audio.h index 89412e18f..bb0df2aae 100644 --- a/linux/include/linux/dvb/audio.h +++ b/linux/include/linux/dvb/audio.h @@ -24,12 +24,7 @@ #ifndef _DVBAUDIO_H_ #define _DVBAUDIO_H_ -#ifdef __KERNEL__ #include -#else -#include -#endif - typedef enum { AUDIO_SOURCE_DEMUX, /* Select the demux as the main source */ diff --git a/linux/include/linux/dvb/dmx.h b/linux/include/linux/dvb/dmx.h index 402fb7a8d..fef943738 100644 --- a/linux/include/linux/dvb/dmx.h +++ b/linux/include/linux/dvb/dmx.h @@ -24,7 +24,7 @@ #ifndef _DVBDMX_H_ #define _DVBDMX_H_ -#include +#include #ifdef __KERNEL__ #include #else diff --git a/linux/include/linux/dvb/frontend.h b/linux/include/linux/dvb/frontend.h index 61a86e720..6a0405f65 100644 --- a/linux/include/linux/dvb/frontend.h +++ b/linux/include/linux/dvb/frontend.h @@ -26,8 +26,7 @@ #ifndef _DVBFRONTEND_H_ #define _DVBFRONTEND_H_ -#include - +#include typedef enum fe_type { FE_QPSK, diff --git a/linux/include/linux/dvb/net.h b/linux/include/linux/dvb/net.h index 5be474bf0..f451e7eb0 100644 --- a/linux/include/linux/dvb/net.h +++ b/linux/include/linux/dvb/net.h @@ -24,8 +24,7 @@ #ifndef _DVBNET_H_ #define _DVBNET_H_ -#include - +#include struct dvb_net_if { __u16 pid; diff --git a/linux/include/linux/dvb/video.h b/linux/include/linux/dvb/video.h index 50839fe9e..bd49c3ebf 100644 --- a/linux/include/linux/dvb/video.h +++ b/linux/include/linux/dvb/video.h @@ -24,17 +24,14 @@ #ifndef _DVBVIDEO_H_ #define _DVBVIDEO_H_ -#include - -#ifdef __KERNEL__ #include +#ifdef __KERNEL__ +#include #else -#include #include #include #endif - typedef enum { VIDEO_FORMAT_4_3, /* Select 4:3 format */ VIDEO_FORMAT_16_9, /* Select 16:9 format. */ diff --git a/linux/include/linux/video_decoder.h b/linux/include/linux/video_decoder.h index 121e26da2..e26c0c86a 100644 --- a/linux/include/linux/video_decoder.h +++ b/linux/include/linux/video_decoder.h @@ -1,6 +1,8 @@ #ifndef _LINUX_VIDEO_DECODER_H #define _LINUX_VIDEO_DECODER_H +#include + #define HAVE_VIDEO_DECODER 1 struct video_decoder_capability { /* this name is too long */ diff --git a/linux/include/linux/videodev.h b/linux/include/linux/videodev.h index 15a653d41..837f392fb 100644 --- a/linux/include/linux/videodev.h +++ b/linux/include/linux/videodev.h @@ -12,6 +12,7 @@ #ifndef __LINUX_VIDEODEV_H #define __LINUX_VIDEODEV_H +#include #include #include diff --git a/linux/include/media/videobuf-dma-sg.h b/linux/include/media/videobuf-dma-sg.h index 90edd22d3..dda47f008 100644 --- a/linux/include/media/videobuf-dma-sg.h +++ b/linux/include/media/videobuf-dma-sg.h @@ -49,7 +49,7 @@ struct scatterlist* videobuf_pages_to_sg(struct page **pages, int nr_pages, * does memory allocation too using vmalloc_32(). * * videobuf_dma_*() - * see Documentation/DMA-mapping.txt, these functions to + * see Documentation/PCI/PCI-DMA-mapping.txt, these functions to * basically the same. The map function does also build a * scatterlist for the buffer (and unmap frees it ...) * -- cgit v1.2.3 From 538850e6819a36200323bf1469eb8544e4f4e0c6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 17 Feb 2009 13:46:22 +0000 Subject: Drop test for kernel version 2.6.15 From: Jean Delvare The v4l-dvb repository supports kernel versions 2.6.16 and later only, so no need to test for kernel version 2.6.15. Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-usb/af9015.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.c b/linux/drivers/media/dvb/dvb-usb/af9015.c index 88a365ad9..ca7609583 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.c +++ b/linux/drivers/media/dvb/dvb-usb/af9015.c @@ -1507,9 +1507,6 @@ static void af9015_usb_device_exit(struct usb_interface *intf) /* usb specific object needed to register this driver with the usb subsystem */ static struct usb_driver af9015_usb_driver = { -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 15) - .owner = THIS_MODULE, -#endif .name = "dvb_usb_af9015", .probe = af9015_usb_probe, .disconnect = af9015_usb_device_exit, -- cgit v1.2.3 From ea5c2ae318fda3731d4fe711b704122a62a7dce9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 18 Feb 2009 10:11:10 +0100 Subject: [PATCH] V4L: missing parentheses? From: Roel Kluin Add missing parentheses Signed-off-by: Roel Kluin Acked-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/tuners/tda18271-common.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/common/tuners/tda18271-common.c b/linux/drivers/media/common/tuners/tda18271-common.c index a8fb96698..a49facb7b 100644 --- a/linux/drivers/media/common/tuners/tda18271-common.c +++ b/linux/drivers/media/common/tuners/tda18271-common.c @@ -558,9 +558,9 @@ int tda18271_set_standby_mode(struct dvb_frontend *fe, tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt); regs[R_EP3] &= ~0xe0; /* clear sm, sm_lt, sm_xt */ - regs[R_EP3] |= sm ? (1 << 7) : 0 | - sm_lt ? (1 << 6) : 0 | - sm_xt ? (1 << 5) : 0; + regs[R_EP3] |= (sm ? (1 << 7) : 0) | + (sm_lt ? (1 << 6) : 0) | + (sm_xt ? (1 << 5) : 0); return tda18271_write_regs(fe, R_EP3, 1); } -- cgit v1.2.3 From 0e80661eedb37a2d8810e6de027c2530db814c27 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 16:22:16 +0100 Subject: saa7115: don't access reg 0x87 if it is not present. From: Hans Verkuil Devices like the saa7111 do not have this register, so check for this before using it. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa7115.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7115.c b/linux/drivers/media/video/saa7115.c index 9fbb93775..2e868fade 100644 --- a/linux/drivers/media/video/saa7115.c +++ b/linux/drivers/media/video/saa7115.c @@ -1309,11 +1309,12 @@ static int saa711x_s_stream(struct v4l2_subdev *sd, int enable) v4l2_dbg(1, debug, sd, "%s output\n", enable ? "enable" : "disable"); - if (state->enable != enable) { - state->enable = enable; - saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, - state->enable); - } + if (state->enable == enable) + return 0; + state->enable = enable; + if (!saa711x_has_reg(state->ident, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED)) + return 0; + saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, state->enable); return 0; } -- cgit v1.2.3 From 6fdf67ebdaa0672d9f580433d4331b451ada01bd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 16:23:38 +0100 Subject: saa7185: add colorbar support. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa7185.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7185.c b/linux/drivers/media/video/saa7185.c index 195e2f415..68bec4d5d 100644 --- a/linux/drivers/media/video/saa7185.c +++ b/linux/drivers/media/video/saa7185.c @@ -282,6 +282,8 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) switch (*iarg) { case 0: + /* turn off colorbar */ + saa7185_write(client, 0x3a, 0x0f); /* Switch RTCE to 1 */ saa7185_write(client, 0x61, (encoder->reg[0x61] & 0xf7) | 0x08); @@ -289,6 +291,8 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) break; case 1: + /* turn off colorbar */ + saa7185_write(client, 0x3a, 0x0f); /* Switch RTCE to 0 */ saa7185_write(client, 0x61, (encoder->reg[0x61] & 0xf7) | 0x00); @@ -296,6 +300,16 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) saa7185_write(client, 0x6e, 0x00); break; + case 2: + /* turn on colorbar */ + saa7185_write(client, 0x3a, 0x8f); + /* Switch RTCE to 0 */ + saa7185_write(client, 0x61, + (encoder->reg[0x61] & 0xf7) | 0x08); + /* SW: a slight sync problem... */ + saa7185_write(client, 0x6e, 0x01); + break; + default: return -EINVAL; } -- cgit v1.2.3 From d508d21a881363ed8a29131a5d766a17562d9596 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 16:35:33 +0100 Subject: saa7115: add querystd and g_input_status support for zoran. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa7115.c | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7115.c b/linux/drivers/media/video/saa7115.c index 2e868fade..169b01f6d 100644 --- a/linux/drivers/media/video/saa7115.c +++ b/linux/drivers/media/video/saa7115.c @@ -1372,6 +1372,47 @@ static int saa711x_g_vbi_data(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_dat } } +static int saa711x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) +{ + struct saa711x_state *state = to_state(sd); + int reg1e; + + *std = V4L2_STD_ALL; + if (state->ident != V4L2_IDENT_SAA7115) + return 0; + reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC); + + switch (reg1e & 0x03) { + case 1: + *std = V4L2_STD_NTSC; + break; + case 2: + *std = V4L2_STD_PAL; + break; + case 3: + *std = V4L2_STD_SECAM; + break; + default: + break; + } + return 0; +} + +static int saa711x_g_input_status(struct v4l2_subdev *sd, u32 *status) +{ + struct saa711x_state *state = to_state(sd); + int reg1e = 0x80; + int reg1f; + + *status = V4L2_IN_ST_NO_SIGNAL; + if (state->ident == V4L2_IDENT_SAA7115) + reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC); + reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC); + if ((reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80) + *status = 0; + return 0; +} + #ifdef CONFIG_VIDEO_ADV_DEBUG static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { @@ -1495,6 +1536,8 @@ static const struct v4l2_subdev_video_ops saa711x_video_ops = { .g_vbi_data = saa711x_g_vbi_data, .decode_vbi_line = saa711x_decode_vbi_line, .s_stream = saa711x_s_stream, + .querystd = saa711x_querystd, + .g_input_status = saa711x_g_input_status, }; static const struct v4l2_subdev_ops saa711x_ops = { -- cgit v1.2.3 From 01293c4d013ac24226a4b52660d28c2fe85fe3fa Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 17:13:31 +0100 Subject: zoran: convert to video_ioctl2 and remove 'ready_to_be_freed' hack. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran.h | 2 - linux/drivers/media/video/zoran/zoran_driver.c | 2557 +++++++++++------------- 2 files changed, 1114 insertions(+), 1445 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/zoran/zoran.h b/linux/drivers/media/video/zoran/zoran.h index e873a9162..1bf540cb5 100644 --- a/linux/drivers/media/video/zoran/zoran.h +++ b/linux/drivers/media/video/zoran/zoran.h @@ -312,7 +312,6 @@ struct zoran_jpg_struct { struct zoran_jpg_buffer buffer[BUZ_MAX_FRAME]; /* buffers */ int num_buffers, buffer_size; u8 allocated; /* Flag if buffers are allocated */ - u8 ready_to_be_freed; /* hack - see zoran_driver.c */ u8 need_contiguous; /* Flag if contiguous buffers are needed */ }; @@ -321,7 +320,6 @@ struct zoran_v4l_struct { struct zoran_v4l_buffer buffer[VIDEO_MAX_FRAME]; /* buffers */ int num_buffers, buffer_size; u8 allocated; /* Flag if buffers are allocated */ - u8 ready_to_be_freed; /* hack - see zoran_driver.c */ }; struct zoran; diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index 798745c0a..afbb18b89 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -321,11 +321,6 @@ v4l_fbuffer_alloc (struct file *file) unsigned long pmem = 0; #endif - /* we might have old buffers lying around... */ - if (fh->v4l_buffers.ready_to_be_freed) { - v4l_fbuffer_free(file); - } - for (i = 0; i < fh->v4l_buffers.num_buffers; i++) { if (fh->v4l_buffers.buffer[i].fbuffer) dprintk(2, @@ -486,7 +481,6 @@ v4l_fbuffer_free (struct file *file) } fh->v4l_buffers.allocated = 0; - fh->v4l_buffers.ready_to_be_freed = 0; } /* @@ -531,11 +525,6 @@ jpg_fbuffer_alloc (struct file *file) int i, j, off; unsigned long mem; - /* we might have old buffers lying around */ - if (fh->jpg_buffers.ready_to_be_freed) { - jpg_fbuffer_free(file); - } - for (i = 0; i < fh->jpg_buffers.num_buffers; i++) { if (fh->jpg_buffers.buffer[i].frag_tab) dprintk(2, @@ -678,7 +667,6 @@ jpg_fbuffer_free (struct file *file) } fh->jpg_buffers.allocated = 0; - fh->jpg_buffers.ready_to_be_freed = 0; } /* @@ -722,7 +710,7 @@ zoran_v4l_set_format (struct file *file, if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) { dprintk(1, KERN_ERR - "%s: v4l_set_format() - wrong frame alingment\n", + "%s: v4l_set_format() - wrong frame alignment\n", ZR_DEVNAME(zr)); return -EINVAL; } @@ -1187,7 +1175,6 @@ zoran_open_init_session (struct file *file) fh->v4l_buffers.buffer[i].bs.frame = i; } fh->v4l_buffers.allocated = 0; - fh->v4l_buffers.ready_to_be_freed = 0; fh->v4l_buffers.active = ZORAN_FREE; fh->v4l_buffers.buffer_size = v4l_bufsize; fh->v4l_buffers.num_buffers = v4l_nbufs; @@ -1203,7 +1190,6 @@ zoran_open_init_session (struct file *file) } fh->jpg_buffers.need_contiguous = zr->jpg_buffers.need_contiguous; fh->jpg_buffers.allocated = 0; - fh->jpg_buffers.ready_to_be_freed = 0; fh->jpg_buffers.active = ZORAN_FREE; fh->jpg_buffers.buffer_size = jpg_bufsize; fh->jpg_buffers.num_buffers = jpg_nbufs; @@ -1237,10 +1223,8 @@ zoran_close_end_session (struct file *file) } /* v4l buffers */ - if (fh->v4l_buffers.allocated || - fh->v4l_buffers.ready_to_be_freed) { + if (fh->v4l_buffers.allocated) v4l_fbuffer_free(file); - } /* jpg capture */ if (fh->jpg_buffers.active != ZORAN_FREE) { @@ -1251,10 +1235,8 @@ zoran_close_end_session (struct file *file) } /* jpg buffers */ - if (fh->jpg_buffers.allocated || - fh->jpg_buffers.ready_to_be_freed) { + if (fh->jpg_buffers.allocated) jpg_fbuffer_free(file); - } } /* @@ -1968,38 +1950,13 @@ zoran_set_input (struct zoran *zr, * ioctl routine */ -static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) { - struct zoran_fh *fh = file->private_data; + struct zoran_fh *fh = __fh; struct zoran *zr = fh->zr; - /* CAREFUL: used in multiple places here */ struct zoran_jpg_settings settings; - /* we might have older buffers lying around... We don't want - * to wait, but we do want to try cleaning them up ASAP. So - * we try to obtain the lock and free them. If that fails, we - * don't do anything and wait for the next turn. In the end, - * zoran_close() or a new allocation will still free them... - * This is just a 'the sooner the better' extra 'feature' - * - * We don't free the buffers right on munmap() because that - * causes oopses (kfree() inside munmap() oopses for no - * apparent reason - it's also not reproduceable in any way, - * but moving the free code outside the munmap() handler fixes - * all this... If someone knows why, please explain me (Ronald) - */ - if (mutex_trylock(&zr->resource_lock)) { - /* we obtained it! Let's try to free some things */ - if (fh->jpg_buffers.ready_to_be_freed) - jpg_fbuffer_free(file); - if (fh->v4l_buffers.ready_to_be_freed) - v4l_fbuffer_free(file); - - mutex_unlock(&zr->resource_lock); - } - switch (cmd) { - case VIDIOCGCAP: { struct video_capability *vcap = arg; @@ -2021,7 +1978,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } - break; case VIDIOCGCHAN: { @@ -2052,7 +2008,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } - break; /* RJ: the documentation at http://roadrunner.swansea.linux.org.uk/v4lapi.shtml says: * @@ -2082,11 +2037,10 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) /* Make sure the changes come into effect */ res = wait_grab_pending(zr); - schan_unlock_and_return: +schan_unlock_and_return: mutex_unlock(&zr->resource_lock); return res; } - break; case VIDIOCGPICT: { @@ -2110,7 +2064,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } - break; case VIDIOCSPICT: { @@ -2156,7 +2109,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } - break; case VIDIOCCAPTURE: { @@ -2171,7 +2123,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return res; } - break; case VIDIOCGWIN: { @@ -2189,7 +2140,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) vwin->clipcount = 0; return 0; } - break; case VIDIOCSWIN: { @@ -2211,7 +2161,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return res; } - break; case VIDIOCGFBUF: { @@ -2224,7 +2173,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) mutex_unlock(&zr->resource_lock); return 0; } - break; case VIDIOCSFBUF: { @@ -2257,7 +2205,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return res; } - break; case VIDIOCSYNC: { @@ -2273,7 +2220,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) zr->v4l_sync_tail++; return res; } - break; case VIDIOCMCAPTURE: { @@ -2291,7 +2237,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) mutex_unlock(&zr->resource_lock); return res; } - break; case VIDIOCGMBUF: { @@ -2327,12 +2272,11 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) /* The next mmap will map the V4L buffers */ fh->map_mode = ZORAN_MAP_MODE_RAW; - v4l1reqbuf_unlock_and_return: +v4l1reqbuf_unlock_and_return: mutex_unlock(&zr->resource_lock); return res; } - break; case VIDIOCGUNIT: { @@ -2348,7 +2292,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } - break; /* * RJ: In principal we could support subcaptures for V4L grabbing. @@ -2362,7 +2305,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) ZR_DEVNAME(zr)); return -EINVAL; } - break; case VIDIOCSCAPTURE: { @@ -2370,7 +2312,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) ZR_DEVNAME(zr)); return -EINVAL; } - break; case BUZIOC_G_PARAMS: { @@ -2417,7 +2358,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } - break; case BUZIOC_S_PARAMS: { @@ -2466,12 +2406,11 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) } fh->jpg_settings = settings; - sparams_unlock_and_return: +sparams_unlock_and_return: mutex_unlock(&zr->resource_lock); return res; } - break; case BUZIOC_REQBUFS: { @@ -2521,12 +2460,11 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) /* The next mmap will map the MJPEG buffers - could * also be *_PLAY, but it doesn't matter here */ fh->map_mode = ZORAN_MAP_MODE_JPG_REC; - jpgreqbuf_unlock_and_return: +jpgreqbuf_unlock_and_return: mutex_unlock(&zr->resource_lock); return res; } - break; case BUZIOC_QBUF_CAPT: { @@ -2541,7 +2479,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return res; } - break; case BUZIOC_QBUF_PLAY: { @@ -2556,7 +2493,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return res; } - break; case BUZIOC_SYNC: { @@ -2571,7 +2507,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return res; } - break; case BUZIOC_G_STATUS: { @@ -2615,7 +2550,7 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) input = zr->card.input[zr->input].muxsel; decoder_command(zr, DECODER_SET_INPUT, &input); decoder_command(zr, DECODER_SET_NORM, &zr->norm); - gstat_unlock_and_return: +gstat_unlock_and_return: mutex_unlock(&zr->resource_lock); if (!res) { @@ -2634,1599 +2569,1297 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return res; } - break; - - /* The new video4linux2 capture interface - much nicer than video4linux1, since - * it allows for integrating the JPEG capturing calls inside standard v4l2 - */ - - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCAP\n", ZR_DEVNAME(zr)); - memset(cap, 0, sizeof(*cap)); - strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1); - strncpy(cap->driver, "zoran", sizeof(cap->driver)-1); - snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", - pci_name(zr->pci_dev)); - cap->version = - KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION, - RELEASE_VERSION); - cap->capabilities = ZORAN_V4L2_VID_FLAGS; - - return 0; + default: + return -EINVAL; } - break; - - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *fmt = arg; - int index = fmt->index, num = -1, i, flag = 0, type = - fmt->type; +} - dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUM_FMT - index=%d\n", - ZR_DEVNAME(zr), fmt->index); +static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - flag = ZORAN_FORMAT_CAPTURE; - break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - flag = ZORAN_FORMAT_PLAYBACK; - break; - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - flag = ZORAN_FORMAT_OVERLAY; - break; - default: - dprintk(1, - KERN_ERR - "%s: VIDIOC_ENUM_FMT - unknown type %d\n", - ZR_DEVNAME(zr), fmt->type); - return -EINVAL; - } + memset(cap, 0, sizeof(*cap)); + strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1); + strncpy(cap->driver, "zoran", sizeof(cap->driver)-1); + snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", + pci_name(zr->pci_dev)); + cap->version = + KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION, + RELEASE_VERSION); + cap->capabilities = ZORAN_V4L2_VID_FLAGS; - for (i = 0; i < NUM_FORMATS; i++) { - if (zoran_formats[i].flags & flag) - num++; - if (num == fmt->index) - break; - } - if (fmt->index < 0 /* late, but not too late */ || - i == NUM_FORMATS) - return -EINVAL; + return 0; +} - memset(fmt, 0, sizeof(*fmt)); - fmt->index = index; - fmt->type = type; - strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1); - fmt->pixelformat = zoran_formats[i].fourcc; - if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED) - fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; +static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag) +{ + int num = -1, i; - return 0; + for (i = 0; i < NUM_FORMATS; i++) { + if (zoran_formats[i].flags & flag) + num++; + if (num == fmt->index) + break; } - break; - - case VIDIOC_G_FMT: - { - struct v4l2_format *fmt = arg; - int type = fmt->type; + if (fmt->index < 0 /* late, but not too late */ || i == NUM_FORMATS) + return -EINVAL; - dprintk(5, KERN_DEBUG "%s: VIDIOC_G_FMT\n", ZR_DEVNAME(zr)); + strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1); + fmt->pixelformat = zoran_formats[i].fourcc; + if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED) + fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; + return 0; +} - memset(fmt, 0, sizeof(*fmt)); - fmt->type = type; +static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh, + struct v4l2_fmtdesc *f) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_OVERLAY: + return zoran_enum_fmt(zr, f, ZORAN_FORMAT_CAPTURE); +} - mutex_lock(&zr->resource_lock); +static int zoran_enum_fmt_vid_out(struct file *file, void *__fh, + struct v4l2_fmtdesc *f) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - fmt->fmt.win.w.left = fh->overlay_settings.x; - fmt->fmt.win.w.top = fh->overlay_settings.y; - fmt->fmt.win.w.width = fh->overlay_settings.width; - fmt->fmt.win.w.height = - fh->overlay_settings.height; - if (fh->overlay_settings.width * 2 > - BUZ_MAX_HEIGHT) - fmt->fmt.win.field = V4L2_FIELD_INTERLACED; - else - fmt->fmt.win.field = V4L2_FIELD_TOP; + return zoran_enum_fmt(zr, f, ZORAN_FORMAT_PLAYBACK); +} - mutex_unlock(&zr->resource_lock); +static int zoran_enum_fmt_vid_overlay(struct file *file, void *__fh, + struct v4l2_fmtdesc *f) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - break; + return zoran_enum_fmt(zr, f, ZORAN_FORMAT_OVERLAY); +} - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - - mutex_lock(&zr->resource_lock); - - if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && - fh->map_mode == ZORAN_MAP_MODE_RAW) { - - fmt->fmt.pix.width = - fh->v4l_settings.width; - fmt->fmt.pix.height = - fh->v4l_settings.height; - fmt->fmt.pix.sizeimage = - fh->v4l_settings.bytesperline * - fh->v4l_settings.height; - fmt->fmt.pix.pixelformat = - fh->v4l_settings.format->fourcc; - fmt->fmt.pix.colorspace = - fh->v4l_settings.format->colorspace; - fmt->fmt.pix.bytesperline = - fh->v4l_settings.bytesperline; - if (BUZ_MAX_HEIGHT < - (fh->v4l_settings.height * 2)) - fmt->fmt.pix.field = - V4L2_FIELD_INTERLACED; - else - fmt->fmt.pix.field = - V4L2_FIELD_TOP; +static int zoran_g_fmt_vid_out(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - } else { + mutex_lock(&zr->resource_lock); - fmt->fmt.pix.width = - fh->jpg_settings.img_width / - fh->jpg_settings.HorDcm; - fmt->fmt.pix.height = - fh->jpg_settings.img_height / - (fh->jpg_settings.VerDcm * - fh->jpg_settings.TmpDcm); - fmt->fmt.pix.sizeimage = - zoran_v4l2_calc_bufsize(&fh-> - jpg_settings); - fmt->fmt.pix.pixelformat = - V4L2_PIX_FMT_MJPEG; - if (fh->jpg_settings.TmpDcm == 1) - fmt->fmt.pix.field = - (fh->jpg_settings. - odd_even ? V4L2_FIELD_SEQ_BT : - V4L2_FIELD_SEQ_BT); - else - fmt->fmt.pix.field = - (fh->jpg_settings. - odd_even ? V4L2_FIELD_TOP : - V4L2_FIELD_BOTTOM); - - fmt->fmt.pix.bytesperline = 0; - fmt->fmt.pix.colorspace = - V4L2_COLORSPACE_SMPTE170M; - } + fmt->fmt.pix.width = fh->jpg_settings.img_width / fh->jpg_settings.HorDcm; + fmt->fmt.pix.height = fh->jpg_settings.img_height / + (fh->jpg_settings.VerDcm * fh->jpg_settings.TmpDcm); + fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&fh->jpg_settings); + fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; + if (fh->jpg_settings.TmpDcm == 1) + fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? + V4L2_FIELD_SEQ_BT : V4L2_FIELD_SEQ_BT); + else + fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? + V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); + fmt->fmt.pix.bytesperline = 0; + fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - mutex_unlock(&zr->resource_lock); + mutex_unlock(&zr->resource_lock); + return 0; +} - break; +static int zoran_g_fmt_vid_cap(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - default: - dprintk(1, - KERN_ERR - "%s: VIDIOC_G_FMT - unsupported type %d\n", - ZR_DEVNAME(zr), fmt->type); - return -EINVAL; - } - return 0; - } - break; + if (fh->map_mode != ZORAN_MAP_MODE_RAW) + return zoran_g_fmt_vid_out(file, fh, fmt); - case VIDIOC_S_FMT: - { - struct v4l2_format *fmt = arg; - int i, res = 0; - __le32 printformat; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_S_FMT - type=%d, ", - ZR_DEVNAME(zr), fmt->type); - - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - - dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n", - fmt->fmt.win.w.left, fmt->fmt.win.w.top, - fmt->fmt.win.w.width, - fmt->fmt.win.w.height, - fmt->fmt.win.clipcount, - fmt->fmt.win.bitmap); - mutex_lock(&zr->resource_lock); - res = - setup_window(file, fmt->fmt.win.w.left, - fmt->fmt.win.w.top, - fmt->fmt.win.w.width, - fmt->fmt.win.w.height, - (struct video_clip __user *) - fmt->fmt.win.clips, - fmt->fmt.win.clipcount, - fmt->fmt.win.bitmap); - mutex_unlock(&zr->resource_lock); - return res; - break; + mutex_lock(&zr->resource_lock); + fmt->fmt.pix.width = fh->v4l_settings.width; + fmt->fmt.pix.height = fh->v4l_settings.height; + fmt->fmt.pix.sizeimage = fh->v4l_settings.bytesperline * + fh->v4l_settings.height; + fmt->fmt.pix.pixelformat = fh->v4l_settings.format->fourcc; + fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace; + fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline; + if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2)) + fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; + else + fmt->fmt.pix.field = V4L2_FIELD_TOP; + mutex_unlock(&zr->resource_lock); + return 0; +} - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - - printformat = - __cpu_to_le32(fmt->fmt.pix.pixelformat); - dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n", - fmt->fmt.pix.width, fmt->fmt.pix.height, - fmt->fmt.pix.pixelformat, - (char *) &printformat); - - /* we can be requested to do JPEG/raw playback/capture */ - if (! - (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || - (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && - fmt->fmt.pix.pixelformat == - V4L2_PIX_FMT_MJPEG))) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_FMT - unknown type %d/0x%x(%4.4s) combination\n", - ZR_DEVNAME(zr), fmt->type, - fmt->fmt.pix.pixelformat, - (char *) &printformat); - return -EINVAL; - } +static int zoran_g_fmt_vid_overlay(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) { - mutex_lock(&zr->resource_lock); + mutex_lock(&zr->resource_lock); - settings = fh->jpg_settings; + fmt->fmt.win.w.left = fh->overlay_settings.x; + fmt->fmt.win.w.top = fh->overlay_settings.y; + fmt->fmt.win.w.width = fh->overlay_settings.width; + fmt->fmt.win.w.height = fh->overlay_settings.height; + if (fh->overlay_settings.width * 2 > BUZ_MAX_HEIGHT) + fmt->fmt.win.field = V4L2_FIELD_INTERLACED; + else + fmt->fmt.win.field = V4L2_FIELD_TOP; - if (fh->v4l_buffers.allocated || - fh->jpg_buffers.allocated) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_FMT - cannot change capture mode\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto sfmtjpg_unlock_and_return; - } + mutex_unlock(&zr->resource_lock); + return 0; +} - /* we actually need to set 'real' parameters now */ - if ((fmt->fmt.pix.height * 2) > - BUZ_MAX_HEIGHT) - settings.TmpDcm = 1; - else - settings.TmpDcm = 2; - settings.decimation = 0; - if (fmt->fmt.pix.height <= - fh->jpg_settings.img_height / 2) - settings.VerDcm = 2; - else - settings.VerDcm = 1; - if (fmt->fmt.pix.width <= - fh->jpg_settings.img_width / 4) - settings.HorDcm = 4; - else if (fmt->fmt.pix.width <= - fh->jpg_settings.img_width / 2) - settings.HorDcm = 2; - else - settings.HorDcm = 1; - if (settings.TmpDcm == 1) - settings.field_per_buff = 2; - else - settings.field_per_buff = 1; - - /* check */ - if ((res = - zoran_check_jpg_settings(zr, - &settings))) - goto sfmtjpg_unlock_and_return; - - /* it's ok, so set them */ - fh->jpg_settings = settings; - - /* tell the user what we actually did */ - fmt->fmt.pix.width = - settings.img_width / settings.HorDcm; - fmt->fmt.pix.height = - settings.img_height * 2 / - (settings.TmpDcm * settings.VerDcm); - if (settings.TmpDcm == 1) - fmt->fmt.pix.field = - (fh->jpg_settings. - odd_even ? V4L2_FIELD_SEQ_TB : - V4L2_FIELD_SEQ_BT); - else - fmt->fmt.pix.field = - (fh->jpg_settings. - odd_even ? V4L2_FIELD_TOP : - V4L2_FIELD_BOTTOM); - fh->jpg_buffers.buffer_size = - zoran_v4l2_calc_bufsize(&fh-> - jpg_settings); - fmt->fmt.pix.bytesperline = 0; - fmt->fmt.pix.sizeimage = - fh->jpg_buffers.buffer_size; - fmt->fmt.pix.colorspace = - V4L2_COLORSPACE_SMPTE170M; - - /* we hereby abuse this variable to show that - * we're gonna do mjpeg capture */ - fh->map_mode = - (fmt->type == - V4L2_BUF_TYPE_VIDEO_CAPTURE) ? - ZORAN_MAP_MODE_JPG_REC : - ZORAN_MAP_MODE_JPG_PLAY; - sfmtjpg_unlock_and_return: - mutex_unlock(&zr->resource_lock); - } else { - for (i = 0; i < NUM_FORMATS; i++) - if (fmt->fmt.pix.pixelformat == - zoran_formats[i].fourcc) - break; - if (i == NUM_FORMATS) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x (%4.4s)\n", - ZR_DEVNAME(zr), - fmt->fmt.pix.pixelformat, - (char *) &printformat); - return -EINVAL; - } - mutex_lock(&zr->resource_lock); - if (fh->jpg_buffers.allocated || - (fh->v4l_buffers.allocated && - fh->v4l_buffers.active != - ZORAN_FREE)) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_FMT - cannot change capture mode\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto sfmtv4l_unlock_and_return; - } - if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) - fmt->fmt.pix.height = - BUZ_MAX_HEIGHT; - if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) - fmt->fmt.pix.width = BUZ_MAX_WIDTH; - - if ((res = - zoran_v4l_set_format(file, - fmt->fmt.pix. - width, - fmt->fmt.pix. - height, - &zoran_formats - [i]))) - goto sfmtv4l_unlock_and_return; - - /* tell the user the - * results/missing stuff */ - fmt->fmt.pix.bytesperline = - fh->v4l_settings.bytesperline; - fmt->fmt.pix.sizeimage = - fh->v4l_settings.height * - fh->v4l_settings.bytesperline; - fmt->fmt.pix.colorspace = - fh->v4l_settings.format->colorspace; - if (BUZ_MAX_HEIGHT < - (fh->v4l_settings.height * 2)) - fmt->fmt.pix.field = - V4L2_FIELD_INTERLACED; - else - fmt->fmt.pix.field = - V4L2_FIELD_TOP; - - fh->map_mode = ZORAN_MAP_MODE_RAW; - sfmtv4l_unlock_and_return: - mutex_unlock(&zr->resource_lock); - } +static int zoran_try_fmt_vid_overlay(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - break; + mutex_lock(&zr->resource_lock); - default: - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_FMT - unsupported type %d\n", - ZR_DEVNAME(zr), fmt->type); - return -EINVAL; - } + if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH) + fmt->fmt.win.w.width = BUZ_MAX_WIDTH; + if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH) + fmt->fmt.win.w.width = BUZ_MIN_WIDTH; + if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT) + fmt->fmt.win.w.height = BUZ_MAX_HEIGHT; + if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT) + fmt->fmt.win.w.height = BUZ_MIN_HEIGHT; - return res; - } - break; + mutex_unlock(&zr->resource_lock); + return 0; +} - case VIDIOC_G_FBUF: - { - struct v4l2_framebuffer *fb = arg; +static int zoran_try_fmt_vid_out(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + struct zoran_jpg_settings settings; + int res = 0; - dprintk(3, KERN_DEBUG "%s: VIDIOC_G_FBUF\n", ZR_DEVNAME(zr)); + if (fmt->fmt.pix.bytesperline > 0) + return -EINVAL; - memset(fb, 0, sizeof(*fb)); - mutex_lock(&zr->resource_lock); - fb->base = zr->buffer.base; - fb->fmt.width = zr->buffer.width; - fb->fmt.height = zr->buffer.height; - if (zr->overlay_settings.format) { - fb->fmt.pixelformat = - fh->overlay_settings.format->fourcc; - } - fb->fmt.bytesperline = zr->buffer.bytesperline; - mutex_unlock(&zr->resource_lock); - fb->fmt.colorspace = V4L2_COLORSPACE_SRGB; - fb->fmt.field = V4L2_FIELD_INTERLACED; - fb->flags = V4L2_FBUF_FLAG_OVERLAY; - fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; + if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) + return -EINVAL; - return 0; - } - break; + mutex_lock(&zr->resource_lock); + settings = fh->jpg_settings; - case VIDIOC_S_FBUF: - { - int i, res = 0; - struct v4l2_framebuffer *fb = arg; - __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat); + /* we actually need to set 'real' parameters now */ + if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT) + settings.TmpDcm = 1; + else + settings.TmpDcm = 2; + settings.decimation = 0; + if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2) + settings.VerDcm = 2; + else + settings.VerDcm = 1; + if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4) + settings.HorDcm = 4; + else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2) + settings.HorDcm = 2; + else + settings.HorDcm = 1; + if (settings.TmpDcm == 1) + settings.field_per_buff = 2; + else + settings.field_per_buff = 1; + + /* check */ + res = zoran_check_jpg_settings(zr, &settings); + if (res) + goto tryfmt_unlock_and_return; + + /* tell the user what we actually did */ + fmt->fmt.pix.width = settings.img_width / settings.HorDcm; + fmt->fmt.pix.height = settings.img_height * 2 / + (settings.TmpDcm * settings.VerDcm); + if (settings.TmpDcm == 1) + fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? + V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); + else + fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? + V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); - dprintk(3, - KERN_DEBUG - "%s: VIDIOC_S_FBUF - base=0x%p, size=%dx%d, bpl=%d, fmt=0x%x (%4.4s)\n", - ZR_DEVNAME(zr), fb->base, fb->fmt.width, fb->fmt.height, - fb->fmt.bytesperline, fb->fmt.pixelformat, - (char *) &printformat); + fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&settings); +tryfmt_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - for (i = 0; i < NUM_FORMATS; i++) - if (zoran_formats[i].fourcc == fb->fmt.pixelformat) - break; - if (i == NUM_FORMATS) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n", - ZR_DEVNAME(zr), fb->fmt.pixelformat, - (char *) &printformat); - return -EINVAL; - } +static int zoran_try_fmt_vid_cap(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int i; - mutex_lock(&zr->resource_lock); - res = - setup_fbuffer(file, fb->base, &zoran_formats[i], - fb->fmt.width, fb->fmt.height, - fb->fmt.bytesperline); - mutex_unlock(&zr->resource_lock); + if (fmt->fmt.pix.bytesperline > 0) + return -EINVAL; - return res; - } - break; + if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) + return zoran_try_fmt_vid_out(file, fh, fmt); - case VIDIOC_OVERLAY: - { - int *on = arg, res; + mutex_lock(&zr->resource_lock); - dprintk(3, KERN_DEBUG "%s: VIDIOC_PREVIEW - on=%d\n", - ZR_DEVNAME(zr), *on); + for (i = 0; i < NUM_FORMATS; i++) + if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat) + break; - mutex_lock(&zr->resource_lock); - res = setup_overlay(file, *on); + if (i == NUM_FORMATS) { mutex_unlock(&zr->resource_lock); - - return res; + return -EINVAL; } - break; - - case VIDIOC_REQBUFS: - { - struct v4l2_requestbuffers *req = arg; - int res = 0; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_REQBUFS - type=%d\n", - ZR_DEVNAME(zr), req->type); - if (req->memory != V4L2_MEMORY_MMAP) { - dprintk(1, - KERN_ERR - "%s: only MEMORY_MMAP capture is supported, not %d\n", - ZR_DEVNAME(zr), req->memory); - return -EINVAL; - } + if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) + fmt->fmt.pix.width = BUZ_MAX_WIDTH; + if (fmt->fmt.pix.width < BUZ_MIN_WIDTH) + fmt->fmt.pix.width = BUZ_MIN_WIDTH; + if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) + fmt->fmt.pix.height = BUZ_MAX_HEIGHT; + if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT) + fmt->fmt.pix.height = BUZ_MIN_HEIGHT; + mutex_unlock(&zr->resource_lock); - mutex_lock(&zr->resource_lock); + return 0; +} - if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_REQBUFS - buffers allready allocated\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto v4l2reqbuf_unlock_and_return; - } +static int zoran_s_fmt_vid_overlay(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res; + + dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n", + fmt->fmt.win.w.left, fmt->fmt.win.w.top, + fmt->fmt.win.w.width, + fmt->fmt.win.w.height, + fmt->fmt.win.clipcount, + fmt->fmt.win.bitmap); + mutex_lock(&zr->resource_lock); + res = setup_window(file, fmt->fmt.win.w.left, + fmt->fmt.win.w.top, + fmt->fmt.win.w.width, + fmt->fmt.win.w.height, + (struct video_clip __user *) + fmt->fmt.win.clips, + fmt->fmt.win.clipcount, + fmt->fmt.win.bitmap); + mutex_unlock(&zr->resource_lock); + return res; +} - if (fh->map_mode == ZORAN_MAP_MODE_RAW && - req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { +static int zoran_s_fmt_vid_out(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + __le32 printformat = __cpu_to_le32(fmt->fmt.pix.pixelformat); + struct zoran_jpg_settings settings; + int res = 0; - /* control user input */ - if (req->count < 2) - req->count = 2; - if (req->count > v4l_nbufs) - req->count = v4l_nbufs; - fh->v4l_buffers.num_buffers = req->count; + dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n", + fmt->fmt.pix.width, fmt->fmt.pix.height, + fmt->fmt.pix.pixelformat, + (char *) &printformat); + if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) + return -EINVAL; - if (v4l_fbuffer_alloc(file)) { - res = -ENOMEM; - goto v4l2reqbuf_unlock_and_return; - } + mutex_lock(&zr->resource_lock); - /* The next mmap will map the V4L buffers */ - fh->map_mode = ZORAN_MAP_MODE_RAW; + settings = fh->jpg_settings; - } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC || - fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { + if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) { + dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto sfmtjpg_unlock_and_return; + } - /* we need to calculate size ourselves now */ - if (req->count < 4) - req->count = 4; - if (req->count > jpg_nbufs) - req->count = jpg_nbufs; - fh->jpg_buffers.num_buffers = req->count; - fh->jpg_buffers.buffer_size = - zoran_v4l2_calc_bufsize(&fh->jpg_settings); - - if (jpg_fbuffer_alloc(file)) { - res = -ENOMEM; - goto v4l2reqbuf_unlock_and_return; - } - - /* The next mmap will map the MJPEG buffers */ - if (req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - fh->map_mode = ZORAN_MAP_MODE_JPG_REC; - else - fh->map_mode = ZORAN_MAP_MODE_JPG_PLAY; - - } else { - dprintk(1, - KERN_ERR - "%s: VIDIOC_REQBUFS - unknown type %d\n", - ZR_DEVNAME(zr), req->type); - res = -EINVAL; - goto v4l2reqbuf_unlock_and_return; - } - v4l2reqbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); - - return 0; - } - break; - - case VIDIOC_QUERYBUF: - { - struct v4l2_buffer *buf = arg; - __u32 type = buf->type; - int index = buf->index, res; - - dprintk(3, - KERN_DEBUG - "%s: VIDIOC_QUERYBUF - index=%d, type=%d\n", - ZR_DEVNAME(zr), buf->index, buf->type); + /* we actually need to set 'real' parameters now */ + if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT) + settings.TmpDcm = 1; + else + settings.TmpDcm = 2; + settings.decimation = 0; + if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2) + settings.VerDcm = 2; + else + settings.VerDcm = 1; + if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4) + settings.HorDcm = 4; + else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2) + settings.HorDcm = 2; + else + settings.HorDcm = 1; + if (settings.TmpDcm == 1) + settings.field_per_buff = 2; + else + settings.field_per_buff = 1; + + /* check */ + res = zoran_check_jpg_settings(zr, &settings); + if (res) + goto sfmtjpg_unlock_and_return; + + /* it's ok, so set them */ + fh->jpg_settings = settings; + + /* tell the user what we actually did */ + fmt->fmt.pix.width = settings.img_width / settings.HorDcm; + fmt->fmt.pix.height = settings.img_height * 2 / + (settings.TmpDcm * settings.VerDcm); + if (settings.TmpDcm == 1) + fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? + V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); + else + fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? + V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); + fh->jpg_buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings); + fmt->fmt.pix.bytesperline = 0; + fmt->fmt.pix.sizeimage = fh->jpg_buffers.buffer_size; + fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + + /* we hereby abuse this variable to show that + * we're gonna do mjpeg capture */ + fh->map_mode = (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ? + ZORAN_MAP_MODE_JPG_REC : ZORAN_MAP_MODE_JPG_PLAY; +sfmtjpg_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - memset(buf, 0, sizeof(*buf)); - buf->type = type; - buf->index = index; +static int zoran_s_fmt_vid_cap(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int i; + int res = 0; - mutex_lock(&zr->resource_lock); - res = zoran_v4l2_buffer_status(file, buf, buf->index); - mutex_unlock(&zr->resource_lock); + if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) + return zoran_s_fmt_vid_out(file, fh, fmt); - return res; + for (i = 0; i < NUM_FORMATS; i++) + if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc) + break; + if (i == NUM_FORMATS) { + dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x\n", + ZR_DEVNAME(zr), fmt->fmt.pix.pixelformat); + return -EINVAL; } - break; - - case VIDIOC_QBUF: - { - struct v4l2_buffer *buf = arg; - int res = 0, codec_mode, buf_type; - - dprintk(3, - KERN_DEBUG "%s: VIDIOC_QBUF - type=%d, index=%d\n", - ZR_DEVNAME(zr), buf->type, buf->index); + mutex_lock(&zr->resource_lock); + if (fh->jpg_buffers.allocated || + (fh->v4l_buffers.allocated && fh->v4l_buffers.active != ZORAN_FREE)) { + dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto sfmtv4l_unlock_and_return; + } + if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) + fmt->fmt.pix.height = BUZ_MAX_HEIGHT; + if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) + fmt->fmt.pix.width = BUZ_MAX_WIDTH; + + res = zoran_v4l_set_format(file, fmt->fmt.pix.width, + fmt->fmt.pix.height, &zoran_formats[i]); + if (res) + goto sfmtv4l_unlock_and_return; + + /* tell the user the + * results/missing stuff */ + fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline; + fmt->fmt.pix.sizeimage = fh->v4l_settings.height * fh->v4l_settings.bytesperline; + fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace; + if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2)) + fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; + else + fmt->fmt.pix.field = V4L2_FIELD_TOP; - mutex_lock(&zr->resource_lock); + fh->map_mode = ZORAN_MAP_MODE_RAW; +sfmtv4l_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - switch (fh->map_mode) { - case ZORAN_MAP_MODE_RAW: - if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", - ZR_DEVNAME(zr), buf->type, fh->map_mode); - res = -EINVAL; - goto qbuf_unlock_and_return; - } +static int zoran_g_fbuf(struct file *file, void *__fh, + struct v4l2_framebuffer *fb) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - res = zoran_v4l_queue_frame(file, buf->index); - if (res) - goto qbuf_unlock_and_return; - if (!zr->v4l_memgrab_active && - fh->v4l_buffers.active == ZORAN_LOCKED) - zr36057_set_memgrab(zr, 1); - break; + memset(fb, 0, sizeof(*fb)); + mutex_lock(&zr->resource_lock); + fb->base = zr->buffer.base; + fb->fmt.width = zr->buffer.width; + fb->fmt.height = zr->buffer.height; + if (zr->overlay_settings.format) + fb->fmt.pixelformat = fh->overlay_settings.format->fourcc; + fb->fmt.bytesperline = zr->buffer.bytesperline; + mutex_unlock(&zr->resource_lock); + fb->fmt.colorspace = V4L2_COLORSPACE_SRGB; + fb->fmt.field = V4L2_FIELD_INTERLACED; + fb->flags = V4L2_FBUF_FLAG_OVERLAY; + fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; - case ZORAN_MAP_MODE_JPG_REC: - case ZORAN_MAP_MODE_JPG_PLAY: - if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { - buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - codec_mode = BUZ_MODE_MOTION_DECOMPRESS; - } else { - buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - codec_mode = BUZ_MODE_MOTION_COMPRESS; - } + return 0; +} - if (buf->type != buf_type) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", - ZR_DEVNAME(zr), buf->type, fh->map_mode); - res = -EINVAL; - goto qbuf_unlock_and_return; - } +static int zoran_s_fbuf(struct file *file, void *__fh, + struct v4l2_framebuffer *fb) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int i, res = 0; + __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat); - res = - zoran_jpg_queue_frame(file, buf->index, - codec_mode); - if (res != 0) - goto qbuf_unlock_and_return; - if (zr->codec_mode == BUZ_MODE_IDLE && - fh->jpg_buffers.active == ZORAN_LOCKED) { - zr36057_enable_jpg(zr, codec_mode); - } + for (i = 0; i < NUM_FORMATS; i++) + if (zoran_formats[i].fourcc == fb->fmt.pixelformat) break; - - default: - dprintk(1, - KERN_ERR - "%s: VIDIOC_QBUF - unsupported type %d\n", - ZR_DEVNAME(zr), buf->type); - res = -EINVAL; - goto qbuf_unlock_and_return; - } - qbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); - - return res; + if (i == NUM_FORMATS) { + dprintk(1, KERN_ERR "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n", + ZR_DEVNAME(zr), fb->fmt.pixelformat, + (char *)&printformat); + return -EINVAL; } - break; - - case VIDIOC_DQBUF: - { - struct v4l2_buffer *buf = arg; - int res = 0, buf_type, num = -1; /* compiler borks here (?) */ - dprintk(3, KERN_DEBUG "%s: VIDIOC_DQBUF - type=%d\n", - ZR_DEVNAME(zr), buf->type); - - mutex_lock(&zr->resource_lock); + mutex_lock(&zr->resource_lock); + res = setup_fbuffer(file, fb->base, &zoran_formats[i], + fb->fmt.width, fb->fmt.height, + fb->fmt.bytesperline); + mutex_unlock(&zr->resource_lock); - switch (fh->map_mode) { - case ZORAN_MAP_MODE_RAW: - if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", - ZR_DEVNAME(zr), buf->type, fh->map_mode); - res = -EINVAL; - goto dqbuf_unlock_and_return; - } + return res; +} - num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME]; - if (file->f_flags & O_NONBLOCK && - zr->v4l_buffers.buffer[num].state != - BUZ_STATE_DONE) { - res = -EAGAIN; - goto dqbuf_unlock_and_return; - } - res = v4l_sync(file, num); - if (res) - goto dqbuf_unlock_and_return; - else - zr->v4l_sync_tail++; - res = zoran_v4l2_buffer_status(file, buf, num); - break; +static int zoran_overlay(struct file *file, void *__fh, unsigned int on) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res; - case ZORAN_MAP_MODE_JPG_REC: - case ZORAN_MAP_MODE_JPG_PLAY: - { - struct zoran_sync bs; + mutex_lock(&zr->resource_lock); + res = setup_overlay(file, on); + mutex_unlock(&zr->resource_lock); - if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) - buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - else - buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + return res; +} - if (buf->type != buf_type) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", - ZR_DEVNAME(zr), buf->type, fh->map_mode); - res = -EINVAL; - goto dqbuf_unlock_and_return; - } +static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *req) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res = 0; - num = - zr->jpg_pend[zr-> - jpg_que_tail & BUZ_MASK_FRAME]; + if (req->memory != V4L2_MEMORY_MMAP) { + dprintk(1, + KERN_ERR + "%s: only MEMORY_MMAP capture is supported, not %d\n", + ZR_DEVNAME(zr), req->memory); + return -EINVAL; + } - if (file->f_flags & O_NONBLOCK && - zr->jpg_buffers.buffer[num].state != - BUZ_STATE_DONE) { - res = -EAGAIN; - goto dqbuf_unlock_and_return; - } - res = jpg_sync(file, &bs); - if (res) - goto dqbuf_unlock_and_return; - res = - zoran_v4l2_buffer_status(file, buf, bs.frame); - break; - } + mutex_lock(&zr->resource_lock); - default: - dprintk(1, + if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) { + dprintk(1, KERN_ERR - "%s: VIDIOC_DQBUF - unsupported type %d\n", - ZR_DEVNAME(zr), buf->type); - res = -EINVAL; - goto dqbuf_unlock_and_return; - } - dqbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); - - return res; + "%s: VIDIOC_REQBUFS - buffers allready allocated\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto v4l2reqbuf_unlock_and_return; } - break; - - case VIDIOC_STREAMON: - { - int res = 0; - dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMON\n", ZR_DEVNAME(zr)); + if (fh->map_mode == ZORAN_MAP_MODE_RAW && + req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - mutex_lock(&zr->resource_lock); + /* control user input */ + if (req->count < 2) + req->count = 2; + if (req->count > v4l_nbufs) + req->count = v4l_nbufs; + fh->v4l_buffers.num_buffers = req->count; - switch (fh->map_mode) { - case ZORAN_MAP_MODE_RAW: /* raw capture */ - if (zr->v4l_buffers.active != ZORAN_ACTIVE || - fh->v4l_buffers.active != ZORAN_ACTIVE) { - res = -EBUSY; - goto strmon_unlock_and_return; - } + if (v4l_fbuffer_alloc(file)) { + res = -ENOMEM; + goto v4l2reqbuf_unlock_and_return; + } - zr->v4l_buffers.active = fh->v4l_buffers.active = - ZORAN_LOCKED; - zr->v4l_settings = fh->v4l_settings; + /* The next mmap will map the V4L buffers */ + fh->map_mode = ZORAN_MAP_MODE_RAW; - zr->v4l_sync_tail = zr->v4l_pend_tail; - if (!zr->v4l_memgrab_active && - zr->v4l_pend_head != zr->v4l_pend_tail) { - zr36057_set_memgrab(zr, 1); - } - break; + } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC || + fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { - case ZORAN_MAP_MODE_JPG_REC: - case ZORAN_MAP_MODE_JPG_PLAY: - /* what is the codec mode right now? */ - if (zr->jpg_buffers.active != ZORAN_ACTIVE || - fh->jpg_buffers.active != ZORAN_ACTIVE) { - res = -EBUSY; - goto strmon_unlock_and_return; - } + /* we need to calculate size ourselves now */ + if (req->count < 4) + req->count = 4; + if (req->count > jpg_nbufs) + req->count = jpg_nbufs; + fh->jpg_buffers.num_buffers = req->count; + fh->jpg_buffers.buffer_size = + zoran_v4l2_calc_bufsize(&fh->jpg_settings); - zr->jpg_buffers.active = fh->jpg_buffers.active = - ZORAN_LOCKED; + if (jpg_fbuffer_alloc(file)) { + res = -ENOMEM; + goto v4l2reqbuf_unlock_and_return; + } - if (zr->jpg_que_head != zr->jpg_que_tail) { - /* Start the jpeg codec when the first frame is queued */ - jpeg_start(zr); - } + /* The next mmap will map the MJPEG buffers */ + if (req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + fh->map_mode = ZORAN_MAP_MODE_JPG_REC; + else + fh->map_mode = ZORAN_MAP_MODE_JPG_PLAY; - break; - default: - dprintk(1, + } else { + dprintk(1, KERN_ERR - "%s: VIDIOC_STREAMON - invalid map mode %d\n", - ZR_DEVNAME(zr), fh->map_mode); - res = -EINVAL; - goto strmon_unlock_and_return; - } - strmon_unlock_and_return: - mutex_unlock(&zr->resource_lock); - - return res; + "%s: VIDIOC_REQBUFS - unknown type %d\n", + ZR_DEVNAME(zr), req->type); + res = -EINVAL; + goto v4l2reqbuf_unlock_and_return; } - break; - - case VIDIOC_STREAMOFF: - { - int i, res = 0; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMOFF\n", ZR_DEVNAME(zr)); - - mutex_lock(&zr->resource_lock); +v4l2reqbuf_unlock_and_return: + mutex_unlock(&zr->resource_lock); - switch (fh->map_mode) { - case ZORAN_MAP_MODE_RAW: /* raw capture */ - if (fh->v4l_buffers.active == ZORAN_FREE && - zr->v4l_buffers.active != ZORAN_FREE) { - res = -EPERM; /* stay off other's settings! */ - goto strmoff_unlock_and_return; - } - if (zr->v4l_buffers.active == ZORAN_FREE) - goto strmoff_unlock_and_return; + return res; +} - /* unload capture */ - if (zr->v4l_memgrab_active) { - unsigned long flags; +static int zoran_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + __u32 type = buf->type; + int index = buf->index, res; - spin_lock_irqsave(&zr->spinlock, flags); - zr36057_set_memgrab(zr, 0); - spin_unlock_irqrestore(&zr->spinlock, flags); - } + memset(buf, 0, sizeof(*buf)); + buf->type = type; + buf->index = index; - for (i = 0; i < fh->v4l_buffers.num_buffers; i++) - zr->v4l_buffers.buffer[i].state = - BUZ_STATE_USER; - fh->v4l_buffers = zr->v4l_buffers; + mutex_lock(&zr->resource_lock); + res = zoran_v4l2_buffer_status(file, buf, buf->index); + mutex_unlock(&zr->resource_lock); - zr->v4l_buffers.active = fh->v4l_buffers.active = - ZORAN_FREE; + return res; +} - zr->v4l_grab_seq = 0; - zr->v4l_pend_head = zr->v4l_pend_tail = 0; - zr->v4l_sync_tail = 0; +static int zoran_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res = 0, codec_mode, buf_type; - break; + mutex_lock(&zr->resource_lock); - case ZORAN_MAP_MODE_JPG_REC: - case ZORAN_MAP_MODE_JPG_PLAY: - if (fh->jpg_buffers.active == ZORAN_FREE && - zr->jpg_buffers.active != ZORAN_FREE) { - res = -EPERM; /* stay off other's settings! */ - goto strmoff_unlock_and_return; - } - if (zr->jpg_buffers.active == ZORAN_FREE) - goto strmoff_unlock_and_return; - - res = - jpg_qbuf(file, -1, - (fh->map_mode == - ZORAN_MAP_MODE_JPG_REC) ? - BUZ_MODE_MOTION_COMPRESS : - BUZ_MODE_MOTION_DECOMPRESS); - if (res) - goto strmoff_unlock_and_return; - break; - default: - dprintk(1, - KERN_ERR - "%s: VIDIOC_STREAMOFF - invalid map mode %d\n", - ZR_DEVNAME(zr), fh->map_mode); + switch (fh->map_mode) { + case ZORAN_MAP_MODE_RAW: + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + dprintk(1, KERN_ERR + "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", + ZR_DEVNAME(zr), buf->type, fh->map_mode); res = -EINVAL; - goto strmoff_unlock_and_return; + goto qbuf_unlock_and_return; } - strmoff_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; - } + res = zoran_v4l_queue_frame(file, buf->index); + if (res) + goto qbuf_unlock_and_return; + if (!zr->v4l_memgrab_active && + fh->v4l_buffers.active == ZORAN_LOCKED) + zr36057_set_memgrab(zr, 1); break; - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *ctrl = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCTRL - id=%d\n", - ZR_DEVNAME(zr), ctrl->id); - - /* we only support hue/saturation/contrast/brightness */ - if (ctrl->id < V4L2_CID_BRIGHTNESS || - ctrl->id > V4L2_CID_HUE) - return -EINVAL; - else { - int id = ctrl->id; - memset(ctrl, 0, sizeof(*ctrl)); - ctrl->id = id; + case ZORAN_MAP_MODE_JPG_REC: + case ZORAN_MAP_MODE_JPG_PLAY: + if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { + buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + codec_mode = BUZ_MODE_MOTION_DECOMPRESS; + } else { + buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + codec_mode = BUZ_MODE_MOTION_COMPRESS; } - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - strncpy(ctrl->name, "Brightness", sizeof(ctrl->name)-1); - break; - case V4L2_CID_CONTRAST: - strncpy(ctrl->name, "Contrast", sizeof(ctrl->name)-1); - break; - case V4L2_CID_SATURATION: - strncpy(ctrl->name, "Saturation", sizeof(ctrl->name)-1); - break; - case V4L2_CID_HUE: - strncpy(ctrl->name, "Hue", sizeof(ctrl->name)-1); - break; + if (buf->type != buf_type) { + dprintk(1, KERN_ERR + "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", + ZR_DEVNAME(zr), buf->type, fh->map_mode); + res = -EINVAL; + goto qbuf_unlock_and_return; } - ctrl->minimum = 0; - ctrl->maximum = 65535; - ctrl->step = 1; - ctrl->default_value = 32768; - ctrl->type = V4L2_CTRL_TYPE_INTEGER; - - return 0; - } - break; - - case VIDIOC_G_CTRL: - { - struct v4l2_control *ctrl = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_G_CTRL - id=%d\n", - ZR_DEVNAME(zr), ctrl->id); - - /* we only support hue/saturation/contrast/brightness */ - if (ctrl->id < V4L2_CID_BRIGHTNESS || - ctrl->id > V4L2_CID_HUE) - return -EINVAL; - - mutex_lock(&zr->resource_lock); - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - ctrl->value = zr->brightness; - break; - case V4L2_CID_CONTRAST: - ctrl->value = zr->contrast; - break; - case V4L2_CID_SATURATION: - ctrl->value = zr->saturation; - break; - case V4L2_CID_HUE: - ctrl->value = zr->hue; - break; + res = zoran_jpg_queue_frame(file, buf->index, + codec_mode); + if (res != 0) + goto qbuf_unlock_and_return; + if (zr->codec_mode == BUZ_MODE_IDLE && + fh->jpg_buffers.active == ZORAN_LOCKED) { + zr36057_enable_jpg(zr, codec_mode); } - mutex_unlock(&zr->resource_lock); + break; - return 0; - } + default: + dprintk(1, KERN_ERR + "%s: VIDIOC_QBUF - unsupported type %d\n", + ZR_DEVNAME(zr), buf->type); + res = -EINVAL; break; + } +qbuf_unlock_and_return: + mutex_unlock(&zr->resource_lock); - case VIDIOC_S_CTRL: - { - struct v4l2_control *ctrl = arg; - struct video_picture pict; + return res; +} - dprintk(3, KERN_DEBUG "%s: VIDIOC_S_CTRL - id=%d\n", - ZR_DEVNAME(zr), ctrl->id); +static int zoran_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res = 0, buf_type, num = -1; /* compiler borks here (?) */ - /* we only support hue/saturation/contrast/brightness */ - if (ctrl->id < V4L2_CID_BRIGHTNESS || - ctrl->id > V4L2_CID_HUE) - return -EINVAL; + mutex_lock(&zr->resource_lock); - if (ctrl->value < 0 || ctrl->value > 65535) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_CTRL - invalid value %d for id=%d\n", - ZR_DEVNAME(zr), ctrl->value, ctrl->id); - return -EINVAL; + switch (fh->map_mode) { + case ZORAN_MAP_MODE_RAW: + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + dprintk(1, KERN_ERR + "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", + ZR_DEVNAME(zr), buf->type, fh->map_mode); + res = -EINVAL; + goto dqbuf_unlock_and_return; } - mutex_lock(&zr->resource_lock); - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - zr->brightness = ctrl->value; - break; - case V4L2_CID_CONTRAST: - zr->contrast = ctrl->value; - break; - case V4L2_CID_SATURATION: - zr->saturation = ctrl->value; - break; - case V4L2_CID_HUE: - zr->hue = ctrl->value; - break; + num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME]; + if (file->f_flags & O_NONBLOCK && + zr->v4l_buffers.buffer[num].state != BUZ_STATE_DONE) { + res = -EAGAIN; + goto dqbuf_unlock_and_return; } - pict.brightness = zr->brightness; - pict.contrast = zr->contrast; - pict.colour = zr->saturation; - pict.hue = zr->hue; - - decoder_command(zr, DECODER_SET_PICTURE, &pict); - - mutex_unlock(&zr->resource_lock); - - return 0; - } + res = v4l_sync(file, num); + if (res) + goto dqbuf_unlock_and_return; + zr->v4l_sync_tail++; + res = zoran_v4l2_buffer_status(file, buf, num); break; - case VIDIOC_ENUMSTD: + case ZORAN_MAP_MODE_JPG_REC: + case ZORAN_MAP_MODE_JPG_PLAY: { - struct v4l2_standard *std = arg; + struct zoran_sync bs; - dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMSTD - index=%d\n", - ZR_DEVNAME(zr), std->index); + if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) + buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + else + buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (std->index < 0 || std->index >= (zr->card.norms + 1)) - return -EINVAL; - else { - int id = std->index; - memset(std, 0, sizeof(*std)); - std->index = id; + if (buf->type != buf_type) { + dprintk(1, KERN_ERR + "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", + ZR_DEVNAME(zr), buf->type, fh->map_mode); + res = -EINVAL; + goto dqbuf_unlock_and_return; } - if (std->index == zr->card.norms) { - /* if we have autodetect, ... */ - struct video_decoder_capability caps; - decoder_command(zr, DECODER_GET_CAPABILITIES, - &caps); - if (caps.flags & VIDEO_DECODER_AUTO) { - std->id = V4L2_STD_ALL; - strncpy(std->name, "Autodetect", sizeof(std->name)-1); - return 0; - } else - return -EINVAL; - } - switch (std->index) { - case 0: - std->id = V4L2_STD_PAL; - strncpy(std->name, "PAL", sizeof(std->name)-1); - std->frameperiod.numerator = 1; - std->frameperiod.denominator = 25; - std->framelines = zr->card.tvn[0]->Ht; - break; - case 1: - std->id = V4L2_STD_NTSC; - strncpy(std->name, "NTSC", sizeof(std->name)-1); - std->frameperiod.numerator = 1001; - std->frameperiod.denominator = 30000; - std->framelines = zr->card.tvn[1]->Ht; - break; - case 2: - std->id = V4L2_STD_SECAM; - strncpy(std->name, "SECAM", sizeof(std->name)-1); - std->frameperiod.numerator = 1; - std->frameperiod.denominator = 25; - std->framelines = zr->card.tvn[2]->Ht; - break; - } + num = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME]; - return 0; + if (file->f_flags & O_NONBLOCK && + zr->jpg_buffers.buffer[num].state != BUZ_STATE_DONE) { + res = -EAGAIN; + goto dqbuf_unlock_and_return; + } + res = jpg_sync(file, &bs); + if (res) + goto dqbuf_unlock_and_return; + res = zoran_v4l2_buffer_status(file, buf, bs.frame); + break; } + + default: + dprintk(1, KERN_ERR + "%s: VIDIOC_DQBUF - unsupported type %d\n", + ZR_DEVNAME(zr), buf->type); + res = -EINVAL; break; + } +dqbuf_unlock_and_return: + mutex_unlock(&zr->resource_lock); - case VIDIOC_G_STD: - { - v4l2_std_id *std = arg; - int norm; + return res; +} - dprintk(3, KERN_DEBUG "%s: VIDIOC_G_STD\n", ZR_DEVNAME(zr)); +static int zoran_streamon(struct file *file, void *__fh, enum v4l2_buf_type type) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res = 0; - mutex_lock(&zr->resource_lock); - norm = zr->norm; - mutex_unlock(&zr->resource_lock); + mutex_lock(&zr->resource_lock); - switch (norm) { - case VIDEO_MODE_PAL: - *std = V4L2_STD_PAL; - break; - case VIDEO_MODE_NTSC: - *std = V4L2_STD_NTSC; - break; - case VIDEO_MODE_SECAM: - *std = V4L2_STD_SECAM; - break; + switch (fh->map_mode) { + case ZORAN_MAP_MODE_RAW: /* raw capture */ + if (zr->v4l_buffers.active != ZORAN_ACTIVE || + fh->v4l_buffers.active != ZORAN_ACTIVE) { + res = -EBUSY; + goto strmon_unlock_and_return; } - return 0; - } + zr->v4l_buffers.active = fh->v4l_buffers.active = ZORAN_LOCKED; + zr->v4l_settings = fh->v4l_settings; + + zr->v4l_sync_tail = zr->v4l_pend_tail; + if (!zr->v4l_memgrab_active && + zr->v4l_pend_head != zr->v4l_pend_tail) { + zr36057_set_memgrab(zr, 1); + } break; - case VIDIOC_S_STD: - { - int norm = -1, res = 0; - v4l2_std_id *std = arg; + case ZORAN_MAP_MODE_JPG_REC: + case ZORAN_MAP_MODE_JPG_PLAY: + /* what is the codec mode right now? */ + if (zr->jpg_buffers.active != ZORAN_ACTIVE || + fh->jpg_buffers.active != ZORAN_ACTIVE) { + res = -EBUSY; + goto strmon_unlock_and_return; + } - dprintk(3, KERN_DEBUG "%s: VIDIOC_S_STD - norm=0x%llx\n", - ZR_DEVNAME(zr), (unsigned long long)*std); + zr->jpg_buffers.active = fh->jpg_buffers.active = ZORAN_LOCKED; - if ((*std & V4L2_STD_PAL) && !(*std & ~V4L2_STD_PAL)) - norm = VIDEO_MODE_PAL; - else if ((*std & V4L2_STD_NTSC) && !(*std & ~V4L2_STD_NTSC)) - norm = VIDEO_MODE_NTSC; - else if ((*std & V4L2_STD_SECAM) && !(*std & ~V4L2_STD_SECAM)) - norm = VIDEO_MODE_SECAM; - else if (*std == V4L2_STD_ALL) - norm = VIDEO_MODE_AUTO; - else { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_STD - invalid norm 0x%llx\n", - ZR_DEVNAME(zr), (unsigned long long)*std); - return -EINVAL; + if (zr->jpg_que_head != zr->jpg_que_tail) { + /* Start the jpeg codec when the first frame is queued */ + jpeg_start(zr); } + break; - mutex_lock(&zr->resource_lock); - if ((res = zoran_set_norm(zr, norm))) - goto sstd_unlock_and_return; - - res = wait_grab_pending(zr); - sstd_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; - } + default: + dprintk(1, + KERN_ERR + "%s: VIDIOC_STREAMON - invalid map mode %d\n", + ZR_DEVNAME(zr), fh->map_mode); + res = -EINVAL; break; + } +strmon_unlock_and_return: + mutex_unlock(&zr->resource_lock); - case VIDIOC_ENUMINPUT: - { - struct v4l2_input *inp = arg; - int status; + return res; +} + +static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int i, res = 0; - dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMINPUT - index=%d\n", - ZR_DEVNAME(zr), inp->index); + mutex_lock(&zr->resource_lock); - if (inp->index < 0 || inp->index >= zr->card.inputs) - return -EINVAL; - else { - int id = inp->index; - memset(inp, 0, sizeof(*inp)); - inp->index = id; + switch (fh->map_mode) { + case ZORAN_MAP_MODE_RAW: /* raw capture */ + if (fh->v4l_buffers.active == ZORAN_FREE && + zr->v4l_buffers.active != ZORAN_FREE) { + res = -EPERM; /* stay off other's settings! */ + goto strmoff_unlock_and_return; } + if (zr->v4l_buffers.active == ZORAN_FREE) + goto strmoff_unlock_and_return; - strncpy(inp->name, zr->card.input[inp->index].name, - sizeof(inp->name) - 1); - inp->type = V4L2_INPUT_TYPE_CAMERA; - inp->std = V4L2_STD_ALL; - - /* Get status of video decoder */ - mutex_lock(&zr->resource_lock); - decoder_command(zr, DECODER_GET_STATUS, &status); - mutex_unlock(&zr->resource_lock); + /* unload capture */ + if (zr->v4l_memgrab_active) { + unsigned long flags; - if (!(status & DECODER_STATUS_GOOD)) { - inp->status |= V4L2_IN_ST_NO_POWER; - inp->status |= V4L2_IN_ST_NO_SIGNAL; + spin_lock_irqsave(&zr->spinlock, flags); + zr36057_set_memgrab(zr, 0); + spin_unlock_irqrestore(&zr->spinlock, flags); } - if (!(status & DECODER_STATUS_COLOR)) - inp->status |= V4L2_IN_ST_NO_COLOR; - return 0; - } - break; + for (i = 0; i < fh->v4l_buffers.num_buffers; i++) + zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER; + fh->v4l_buffers = zr->v4l_buffers; - case VIDIOC_G_INPUT: - { - int *input = arg; + zr->v4l_buffers.active = fh->v4l_buffers.active = ZORAN_FREE; - dprintk(3, KERN_DEBUG "%s: VIDIOC_G_INPUT\n", ZR_DEVNAME(zr)); + zr->v4l_grab_seq = 0; + zr->v4l_pend_head = zr->v4l_pend_tail = 0; + zr->v4l_sync_tail = 0; - mutex_lock(&zr->resource_lock); - *input = zr->input; - mutex_unlock(&zr->resource_lock); + break; - return 0; - } + case ZORAN_MAP_MODE_JPG_REC: + case ZORAN_MAP_MODE_JPG_PLAY: + if (fh->jpg_buffers.active == ZORAN_FREE && + zr->jpg_buffers.active != ZORAN_FREE) { + res = -EPERM; /* stay off other's settings! */ + goto strmoff_unlock_and_return; + } + if (zr->jpg_buffers.active == ZORAN_FREE) + goto strmoff_unlock_and_return; + + res = jpg_qbuf(file, -1, + (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ? + BUZ_MODE_MOTION_COMPRESS : + BUZ_MODE_MOTION_DECOMPRESS); + if (res) + goto strmoff_unlock_and_return; + break; + default: + dprintk(1, KERN_ERR + "%s: VIDIOC_STREAMOFF - invalid map mode %d\n", + ZR_DEVNAME(zr), fh->map_mode); + res = -EINVAL; break; + } +strmoff_unlock_and_return: + mutex_unlock(&zr->resource_lock); - case VIDIOC_S_INPUT: - { - int *input = arg, res = 0; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_S_INPUT - input=%d\n", - ZR_DEVNAME(zr), *input); - - mutex_lock(&zr->resource_lock); - if ((res = zoran_set_input(zr, *input))) - goto sinput_unlock_and_return; + return res; +} - /* Make sure the changes come into effect */ - res = wait_grab_pending(zr); - sinput_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; +static int zoran_queryctrl(struct file *file, void *__fh, + struct v4l2_queryctrl *ctrl) +{ + /* we only support hue/saturation/contrast/brightness */ + if (ctrl->id < V4L2_CID_BRIGHTNESS || + ctrl->id > V4L2_CID_HUE) + return -EINVAL; + else { + int id = ctrl->id; + memset(ctrl, 0, sizeof(*ctrl)); + ctrl->id = id; } + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + strncpy(ctrl->name, "Brightness", sizeof(ctrl->name)-1); + break; + case V4L2_CID_CONTRAST: + strncpy(ctrl->name, "Contrast", sizeof(ctrl->name)-1); + break; + case V4L2_CID_SATURATION: + strncpy(ctrl->name, "Saturation", sizeof(ctrl->name)-1); break; + case V4L2_CID_HUE: + strncpy(ctrl->name, "Hue", sizeof(ctrl->name)-1); + break; + } - case VIDIOC_ENUMOUTPUT: - { - struct v4l2_output *outp = arg; + ctrl->minimum = 0; + ctrl->maximum = 65535; + ctrl->step = 1; + ctrl->default_value = 32768; + ctrl->type = V4L2_CTRL_TYPE_INTEGER; - dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMOUTPUT - index=%d\n", - ZR_DEVNAME(zr), outp->index); + return 0; +} - if (outp->index != 0) - return -EINVAL; +static int zoran_g_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - memset(outp, 0, sizeof(*outp)); - outp->index = 0; - outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; - strncpy(outp->name, "Autodetect", sizeof(outp->name)-1); + /* we only support hue/saturation/contrast/brightness */ + if (ctrl->id < V4L2_CID_BRIGHTNESS || + ctrl->id > V4L2_CID_HUE) + return -EINVAL; - return 0; - } + mutex_lock(&zr->resource_lock); + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + ctrl->value = zr->brightness; break; + case V4L2_CID_CONTRAST: + ctrl->value = zr->contrast; + break; + case V4L2_CID_SATURATION: + ctrl->value = zr->saturation; + break; + case V4L2_CID_HUE: + ctrl->value = zr->hue; + break; + } + mutex_unlock(&zr->resource_lock); - case VIDIOC_G_OUTPUT: - { - int *output = arg; + return 0; +} - dprintk(3, KERN_DEBUG "%s: VIDIOC_G_OUTPUT\n", ZR_DEVNAME(zr)); +static int zoran_s_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + struct video_picture pict; - *output = 0; + /* we only support hue/saturation/contrast/brightness */ + if (ctrl->id < V4L2_CID_BRIGHTNESS || + ctrl->id > V4L2_CID_HUE) + return -EINVAL; - return 0; + if (ctrl->value < 0 || ctrl->value > 65535) { + dprintk(1, KERN_ERR + "%s: VIDIOC_S_CTRL - invalid value %d for id=%d\n", + ZR_DEVNAME(zr), ctrl->value, ctrl->id); + return -EINVAL; } + + mutex_lock(&zr->resource_lock); + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + zr->brightness = ctrl->value; + break; + case V4L2_CID_CONTRAST: + zr->contrast = ctrl->value; break; + case V4L2_CID_SATURATION: + zr->saturation = ctrl->value; + break; + case V4L2_CID_HUE: + zr->hue = ctrl->value; + break; + } + pict.brightness = zr->brightness; + pict.contrast = zr->contrast; + pict.colour = zr->saturation; + pict.hue = zr->hue; - case VIDIOC_S_OUTPUT: - { - int *output = arg; + decoder_command(zr, DECODER_SET_PICTURE, &pict); - dprintk(3, KERN_DEBUG "%s: VIDIOC_S_OUTPUT - output=%d\n", - ZR_DEVNAME(zr), *output); + mutex_unlock(&zr->resource_lock); - if (*output != 0) - return -EINVAL; + return 0; +} - return 0; - } +static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int norm; + + mutex_lock(&zr->resource_lock); + norm = zr->norm; + mutex_unlock(&zr->resource_lock); + + switch (norm) { + case VIDEO_MODE_PAL: + *std = V4L2_STD_PAL; break; + case VIDEO_MODE_NTSC: + *std = V4L2_STD_NTSC; + break; + case VIDEO_MODE_SECAM: + *std = V4L2_STD_SECAM; + break; + } - /* cropping (sub-frame capture) */ - case VIDIOC_CROPCAP: - { - struct v4l2_cropcap *cropcap = arg; - int type = cropcap->type, res = 0; + return 0; +} - dprintk(3, KERN_ERR "%s: VIDIOC_CROPCAP - type=%d\n", - ZR_DEVNAME(zr), cropcap->type); +static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id *std) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int norm = -1, res = 0; + + if ((*std & V4L2_STD_PAL) && !(*std & ~V4L2_STD_PAL)) + norm = VIDEO_MODE_PAL; + else if ((*std & V4L2_STD_NTSC) && !(*std & ~V4L2_STD_NTSC)) + norm = VIDEO_MODE_NTSC; + else if ((*std & V4L2_STD_SECAM) && !(*std & ~V4L2_STD_SECAM)) + norm = VIDEO_MODE_SECAM; + else if (*std == V4L2_STD_ALL) + norm = VIDEO_MODE_AUTO; + else { + dprintk(1, KERN_ERR + "%s: VIDIOC_S_STD - invalid norm 0x%llx\n", + ZR_DEVNAME(zr), (unsigned long long)*std); + return -EINVAL; + } - memset(cropcap, 0, sizeof(*cropcap)); - cropcap->type = type; + mutex_lock(&zr->resource_lock); + res = zoran_set_norm(zr, norm); + if (res) + goto sstd_unlock_and_return; - mutex_lock(&zr->resource_lock); + res = wait_grab_pending(zr); +sstd_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && - (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - fh->map_mode == ZORAN_MAP_MODE_RAW)) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n", - ZR_DEVNAME(zr)); - res = -EINVAL; - goto cropcap_unlock_and_return; - } +static int zoran_enum_input(struct file *file, void *__fh, + struct v4l2_input *inp) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int status; - cropcap->bounds.top = cropcap->bounds.left = 0; - cropcap->bounds.width = BUZ_MAX_WIDTH; - cropcap->bounds.height = BUZ_MAX_HEIGHT; - cropcap->defrect.top = cropcap->defrect.left = 0; - cropcap->defrect.width = BUZ_MIN_WIDTH; - cropcap->defrect.height = BUZ_MIN_HEIGHT; - cropcap_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; + if (inp->index < 0 || inp->index >= zr->card.inputs) + return -EINVAL; + else { + int id = inp->index; + memset(inp, 0, sizeof(*inp)); + inp->index = id; } - break; - case VIDIOC_G_CROP: - { - struct v4l2_crop *crop = arg; - int type = crop->type, res = 0; + strncpy(inp->name, zr->card.input[inp->index].name, + sizeof(inp->name) - 1); + inp->type = V4L2_INPUT_TYPE_CAMERA; + inp->std = V4L2_STD_ALL; - dprintk(3, KERN_ERR "%s: VIDIOC_G_CROP - type=%d\n", - ZR_DEVNAME(zr), crop->type); + /* Get status of video decoder */ + mutex_lock(&zr->resource_lock); + decoder_command(zr, DECODER_GET_STATUS, &status); + mutex_unlock(&zr->resource_lock); - memset(crop, 0, sizeof(*crop)); - crop->type = type; + if (!(status & DECODER_STATUS_GOOD)) { + inp->status |= V4L2_IN_ST_NO_POWER; + inp->status |= V4L2_IN_ST_NO_SIGNAL; + } + if (!(status & DECODER_STATUS_COLOR)) + inp->status |= V4L2_IN_ST_NO_COLOR; - mutex_lock(&zr->resource_lock); + return 0; +} - if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && - (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - fh->map_mode == ZORAN_MAP_MODE_RAW)) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n", - ZR_DEVNAME(zr)); - res = -EINVAL; - goto gcrop_unlock_and_return; - } +static int zoran_g_input(struct file *file, void *__fh, unsigned int *input) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - crop->c.top = fh->jpg_settings.img_y; - crop->c.left = fh->jpg_settings.img_x; - crop->c.width = fh->jpg_settings.img_width; - crop->c.height = fh->jpg_settings.img_height; + mutex_lock(&zr->resource_lock); + *input = zr->input; + mutex_unlock(&zr->resource_lock); - gcrop_unlock_and_return: - mutex_unlock(&zr->resource_lock); + return 0; +} - return res; - } - break; +static int zoran_s_input(struct file *file, void *__fh, unsigned int input) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res; - case VIDIOC_S_CROP: - { - struct v4l2_crop *crop = arg; - int res = 0; + mutex_lock(&zr->resource_lock); + res = zoran_set_input(zr, input); + if (res) + goto sinput_unlock_and_return; - settings = fh->jpg_settings; + /* Make sure the changes come into effect */ + res = wait_grab_pending(zr); +sinput_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - dprintk(3, - KERN_ERR - "%s: VIDIOC_S_CROP - type=%d, x=%d,y=%d,w=%d,h=%d\n", - ZR_DEVNAME(zr), crop->type, crop->c.left, crop->c.top, - crop->c.width, crop->c.height); +static int zoran_enum_output(struct file *file, void *__fh, + struct v4l2_output *outp) +{ + if (outp->index != 0) + return -EINVAL; - mutex_lock(&zr->resource_lock); + memset(outp, 0, sizeof(*outp)); + outp->index = 0; + outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; + strncpy(outp->name, "Autodetect", sizeof(outp->name)-1); - if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_CROP - cannot change settings while active\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto scrop_unlock_and_return; - } + return 0; +} - if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && - (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - fh->map_mode == ZORAN_MAP_MODE_RAW)) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n", - ZR_DEVNAME(zr)); - res = -EINVAL; - goto scrop_unlock_and_return; - } +static int zoran_g_output(struct file *file, void *__fh, unsigned int *output) +{ + *output = 0; + + return 0; +} - /* move into a form that we understand */ - settings.img_x = crop->c.left; - settings.img_y = crop->c.top; - settings.img_width = crop->c.width; - settings.img_height = crop->c.height; +static int zoran_s_output(struct file *file, void *__fh, unsigned int output) +{ + if (output != 0) + return -EINVAL; - /* check validity */ - if ((res = zoran_check_jpg_settings(zr, &settings))) - goto scrop_unlock_and_return; + return 0; +} - /* accept */ - fh->jpg_settings = settings; +/* cropping (sub-frame capture) */ +static int zoran_cropcap(struct file *file, void *__fh, + struct v4l2_cropcap *cropcap) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int type = cropcap->type, res = 0; - scrop_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; - } - break; + memset(cropcap, 0, sizeof(*cropcap)); + cropcap->type = type; - case VIDIOC_G_JPEGCOMP: - { - struct v4l2_jpegcompression *params = arg; + mutex_lock(&zr->resource_lock); - dprintk(3, KERN_DEBUG "%s: VIDIOC_G_JPEGCOMP\n", + if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && + (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + fh->map_mode == ZORAN_MAP_MODE_RAW)) { + dprintk(1, KERN_ERR + "%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n", ZR_DEVNAME(zr)); + res = -EINVAL; + goto cropcap_unlock_and_return; + } - memset(params, 0, sizeof(*params)); + cropcap->bounds.top = cropcap->bounds.left = 0; + cropcap->bounds.width = BUZ_MAX_WIDTH; + cropcap->bounds.height = BUZ_MAX_HEIGHT; + cropcap->defrect.top = cropcap->defrect.left = 0; + cropcap->defrect.width = BUZ_MIN_WIDTH; + cropcap->defrect.height = BUZ_MIN_HEIGHT; +cropcap_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - mutex_lock(&zr->resource_lock); +static int zoran_g_crop(struct file *file, void *__fh, struct v4l2_crop *crop) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int type = crop->type, res = 0; - params->quality = fh->jpg_settings.jpg_comp.quality; - params->APPn = fh->jpg_settings.jpg_comp.APPn; - memcpy(params->APP_data, - fh->jpg_settings.jpg_comp.APP_data, - fh->jpg_settings.jpg_comp.APP_len); - params->APP_len = fh->jpg_settings.jpg_comp.APP_len; - memcpy(params->COM_data, - fh->jpg_settings.jpg_comp.COM_data, - fh->jpg_settings.jpg_comp.COM_len); - params->COM_len = fh->jpg_settings.jpg_comp.COM_len; - params->jpeg_markers = - fh->jpg_settings.jpg_comp.jpeg_markers; + memset(crop, 0, sizeof(*crop)); + crop->type = type; - mutex_unlock(&zr->resource_lock); + mutex_lock(&zr->resource_lock); - return 0; + if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && + (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + fh->map_mode == ZORAN_MAP_MODE_RAW)) { + dprintk(1, + KERN_ERR + "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n", + ZR_DEVNAME(zr)); + res = -EINVAL; + goto gcrop_unlock_and_return; } - break; - - case VIDIOC_S_JPEGCOMP: - { - struct v4l2_jpegcompression *params = arg; - int res = 0; - settings = fh->jpg_settings; + crop->c.top = fh->jpg_settings.img_y; + crop->c.left = fh->jpg_settings.img_x; + crop->c.width = fh->jpg_settings.img_width; + crop->c.height = fh->jpg_settings.img_height; - dprintk(3, - KERN_DEBUG - "%s: VIDIOC_S_JPEGCOMP - quality=%d, APPN=%d, APP_len=%d, COM_len=%d\n", - ZR_DEVNAME(zr), params->quality, params->APPn, - params->APP_len, params->COM_len); +gcrop_unlock_and_return: + mutex_unlock(&zr->resource_lock); - settings.jpg_comp = *params; + return res; +} - mutex_lock(&zr->resource_lock); +static int zoran_s_crop(struct file *file, void *__fh, struct v4l2_crop *crop) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res = 0; + struct zoran_jpg_settings settings; - if (fh->v4l_buffers.active != ZORAN_FREE || - fh->jpg_buffers.active != ZORAN_FREE) { - dprintk(1, - KERN_WARNING - "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto sjpegc_unlock_and_return; - } + settings = fh->jpg_settings; - if ((res = zoran_check_jpg_settings(zr, &settings))) - goto sjpegc_unlock_and_return; - if (!fh->jpg_buffers.allocated) - fh->jpg_buffers.buffer_size = - zoran_v4l2_calc_bufsize(&fh->jpg_settings); - fh->jpg_settings.jpg_comp = *params = settings.jpg_comp; - sjpegc_unlock_and_return: - mutex_unlock(&zr->resource_lock); + mutex_lock(&zr->resource_lock); - return 0; + if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { + dprintk(1, KERN_ERR + "%s: VIDIOC_S_CROP - cannot change settings while active\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto scrop_unlock_and_return; } - break; - case VIDIOC_QUERYSTD: /* why is this useful? */ - { - v4l2_std_id *std = arg; + if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && + (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + fh->map_mode == ZORAN_MAP_MODE_RAW)) { + dprintk(1, KERN_ERR + "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n", + ZR_DEVNAME(zr)); + res = -EINVAL; + goto scrop_unlock_and_return; + } - dprintk(3, - KERN_DEBUG "%s: VIDIOC_QUERY_STD - std=0x%llx\n", - ZR_DEVNAME(zr), (unsigned long long)*std); + /* move into a form that we understand */ + settings.img_x = crop->c.left; + settings.img_y = crop->c.top; + settings.img_width = crop->c.width; + settings.img_height = crop->c.height; - if (*std == V4L2_STD_ALL || *std == V4L2_STD_NTSC || - *std == V4L2_STD_PAL || (*std == V4L2_STD_SECAM && - zr->card.norms == 3)) { - return 0; - } + /* check validity */ + res = zoran_check_jpg_settings(zr, &settings); + if (res) + goto scrop_unlock_and_return; - return -EINVAL; - } - break; + /* accept */ + fh->jpg_settings = settings; - case VIDIOC_TRY_FMT: - { - struct v4l2_format *fmt = arg; - int res = 0; +scrop_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - dprintk(3, KERN_DEBUG "%s: VIDIOC_TRY_FMT - type=%d\n", - ZR_DEVNAME(zr), fmt->type); +static int zoran_g_jpegcomp(struct file *file, void *__fh, + struct v4l2_jpegcompression *params) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + memset(params, 0, sizeof(*params)); - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - mutex_lock(&zr->resource_lock); + mutex_lock(&zr->resource_lock); - if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH) - fmt->fmt.win.w.width = BUZ_MAX_WIDTH; - if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH) - fmt->fmt.win.w.width = BUZ_MIN_WIDTH; - if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT) - fmt->fmt.win.w.height = BUZ_MAX_HEIGHT; - if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT) - fmt->fmt.win.w.height = BUZ_MIN_HEIGHT; + params->quality = fh->jpg_settings.jpg_comp.quality; + params->APPn = fh->jpg_settings.jpg_comp.APPn; + memcpy(params->APP_data, + fh->jpg_settings.jpg_comp.APP_data, + fh->jpg_settings.jpg_comp.APP_len); + params->APP_len = fh->jpg_settings.jpg_comp.APP_len; + memcpy(params->COM_data, + fh->jpg_settings.jpg_comp.COM_data, + fh->jpg_settings.jpg_comp.COM_len); + params->COM_len = fh->jpg_settings.jpg_comp.COM_len; + params->jpeg_markers = + fh->jpg_settings.jpg_comp.jpeg_markers; - mutex_unlock(&zr->resource_lock); - break; + mutex_unlock(&zr->resource_lock); - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (fmt->fmt.pix.bytesperline > 0) - return -EINVAL; + return 0; +} - mutex_lock(&zr->resource_lock); - - if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) { - settings = fh->jpg_settings; - - /* we actually need to set 'real' parameters now */ - if ((fmt->fmt.pix.height * 2) > - BUZ_MAX_HEIGHT) - settings.TmpDcm = 1; - else - settings.TmpDcm = 2; - settings.decimation = 0; - if (fmt->fmt.pix.height <= - fh->jpg_settings.img_height / 2) - settings.VerDcm = 2; - else - settings.VerDcm = 1; - if (fmt->fmt.pix.width <= - fh->jpg_settings.img_width / 4) - settings.HorDcm = 4; - else if (fmt->fmt.pix.width <= - fh->jpg_settings.img_width / 2) - settings.HorDcm = 2; - else - settings.HorDcm = 1; - if (settings.TmpDcm == 1) - settings.field_per_buff = 2; - else - settings.field_per_buff = 1; - - /* check */ - if ((res = - zoran_check_jpg_settings(zr, - &settings))) - goto tryfmt_unlock_and_return; - - /* tell the user what we actually did */ - fmt->fmt.pix.width = - settings.img_width / settings.HorDcm; - fmt->fmt.pix.height = - settings.img_height * 2 / - (settings.TmpDcm * settings.VerDcm); - if (settings.TmpDcm == 1) - fmt->fmt.pix.field = - (fh->jpg_settings. - odd_even ? V4L2_FIELD_SEQ_TB : - V4L2_FIELD_SEQ_BT); - else - fmt->fmt.pix.field = - (fh->jpg_settings. - odd_even ? V4L2_FIELD_TOP : - V4L2_FIELD_BOTTOM); - - fmt->fmt.pix.sizeimage = - zoran_v4l2_calc_bufsize(&settings); - } else if (fmt->type == - V4L2_BUF_TYPE_VIDEO_CAPTURE) { - int i; - - for (i = 0; i < NUM_FORMATS; i++) - if (zoran_formats[i].fourcc == - fmt->fmt.pix.pixelformat) - break; - if (i == NUM_FORMATS) { - res = -EINVAL; - goto tryfmt_unlock_and_return; - } +static int zoran_s_jpegcomp(struct file *file, void *__fh, + struct v4l2_jpegcompression *params) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res = 0; + struct zoran_jpg_settings settings; - if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) - fmt->fmt.pix.width = BUZ_MAX_WIDTH; - if (fmt->fmt.pix.width < BUZ_MIN_WIDTH) - fmt->fmt.pix.width = BUZ_MIN_WIDTH; - if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) - fmt->fmt.pix.height = - BUZ_MAX_HEIGHT; - if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT) - fmt->fmt.pix.height = - BUZ_MIN_HEIGHT; - } else { - res = -EINVAL; - goto tryfmt_unlock_and_return; - } - tryfmt_unlock_and_return: - mutex_unlock(&zr->resource_lock); + settings = fh->jpg_settings; - return res; - break; + settings.jpg_comp = *params; - default: - return -EINVAL; - } + mutex_lock(&zr->resource_lock); - return 0; + if (fh->v4l_buffers.active != ZORAN_FREE || + fh->jpg_buffers.active != ZORAN_FREE) { + dprintk(1, KERN_WARNING + "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto sjpegc_unlock_and_return; } - break; - default: - dprintk(1, KERN_DEBUG "%s: UNKNOWN ioctl cmd: 0x%x\n", - ZR_DEVNAME(zr), cmd); - return -ENOIOCTLCMD; - break; + res = zoran_check_jpg_settings(zr, &settings); + if (res) + goto sjpegc_unlock_and_return; + if (!fh->jpg_buffers.allocated) + fh->jpg_buffers.buffer_size = + zoran_v4l2_calc_bufsize(&fh->jpg_settings); + fh->jpg_settings.jpg_comp = *params = settings.jpg_comp; +sjpegc_unlock_and_return: + mutex_unlock(&zr->resource_lock); - } return 0; } - -static long -zoran_ioctl(struct file *file, - unsigned int cmd, - unsigned long arg) -{ - return video_usercopy(file, cmd, arg, zoran_do_ioctl); -} - static unsigned int zoran_poll (struct file *file, poll_table *wait) @@ -4365,10 +3998,7 @@ zoran_vm_close (struct vm_area_struct *vma) fh->jpg_buffers.active = ZORAN_FREE; } - //jpg_fbuffer_free(file); - fh->jpg_buffers.allocated = 0; - fh->jpg_buffers.ready_to_be_freed = 1; - + jpg_fbuffer_free(file); mutex_unlock(&zr->resource_lock); } @@ -4405,10 +4035,7 @@ zoran_vm_close (struct vm_area_struct *vma) ZORAN_FREE; spin_unlock_irqrestore(&zr->spinlock, flags); } - //v4l_fbuffer_free(file); - fh->v4l_buffers.allocated = 0; - fh->v4l_buffers.ready_to_be_freed = 1; - + v4l_fbuffer_free(file); mutex_unlock(&zr->resource_lock); } @@ -4647,11 +4274,53 @@ zoran_mmap (struct file *file, return 0; } +static const struct v4l2_ioctl_ops zoran_ioctl_ops = { + .vidioc_querycap = zoran_querycap, + .vidioc_cropcap = zoran_cropcap, + .vidioc_s_crop = zoran_s_crop, + .vidioc_g_crop = zoran_g_crop, + .vidioc_enum_input = zoran_enum_input, + .vidioc_g_input = zoran_g_input, + .vidioc_s_input = zoran_s_input, + .vidioc_enum_output = zoran_enum_output, + .vidioc_g_output = zoran_g_output, + .vidioc_s_output = zoran_s_output, + .vidioc_g_fbuf = zoran_g_fbuf, + .vidioc_s_fbuf = zoran_s_fbuf, + .vidioc_g_std = zoran_g_std, + .vidioc_s_std = zoran_s_std, + .vidioc_g_jpegcomp = zoran_g_jpegcomp, + .vidioc_s_jpegcomp = zoran_s_jpegcomp, + .vidioc_overlay = zoran_overlay, + .vidioc_reqbufs = zoran_reqbufs, + .vidioc_querybuf = zoran_querybuf, + .vidioc_qbuf = zoran_qbuf, + .vidioc_dqbuf = zoran_dqbuf, + .vidioc_streamon = zoran_streamon, + .vidioc_streamoff = zoran_streamoff, + .vidioc_enum_fmt_vid_cap = zoran_enum_fmt_vid_cap, + .vidioc_enum_fmt_vid_out = zoran_enum_fmt_vid_out, + .vidioc_enum_fmt_vid_overlay = zoran_enum_fmt_vid_overlay, + .vidioc_g_fmt_vid_cap = zoran_g_fmt_vid_cap, + .vidioc_g_fmt_vid_out = zoran_g_fmt_vid_out, + .vidioc_g_fmt_vid_overlay = zoran_g_fmt_vid_overlay, + .vidioc_s_fmt_vid_cap = zoran_s_fmt_vid_cap, + .vidioc_s_fmt_vid_out = zoran_s_fmt_vid_out, + .vidioc_s_fmt_vid_overlay = zoran_s_fmt_vid_overlay, + .vidioc_try_fmt_vid_cap = zoran_try_fmt_vid_cap, + .vidioc_try_fmt_vid_out = zoran_try_fmt_vid_out, + .vidioc_try_fmt_vid_overlay = zoran_try_fmt_vid_overlay, + .vidioc_queryctrl = zoran_queryctrl, + .vidioc_s_ctrl = zoran_s_ctrl, + .vidioc_g_ctrl = zoran_g_ctrl, + .vidioc_default = zoran_default, +}; + static const struct v4l2_file_operations zoran_fops = { .owner = THIS_MODULE, .open = zoran_open, .release = zoran_close, - .ioctl = zoran_ioctl, + .ioctl = video_ioctl2, .read = zoran_read, .write = zoran_write, .mmap = zoran_mmap, @@ -4661,7 +4330,9 @@ static const struct v4l2_file_operations zoran_fops = { struct video_device zoran_template __devinitdata = { .name = ZORAN_NAME, .fops = &zoran_fops, + .ioctl_ops = &zoran_ioctl_ops, .release = &zoran_vdev_release, + .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, .minor = -1 }; -- cgit v1.2.3 From d69e4a1d433220958c117d5e9a51638eaeb3e361 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 17:20:05 +0100 Subject: zoran: remove broken BIGPHYS_AREA and BUZ_HIMEM code, and allow for kmallocs > 128 kB From: Hans Verkuil Remove memory allocation madness. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran.h | 2 - linux/drivers/media/video/zoran/zoran_driver.c | 247 +++---------------------- 2 files changed, 28 insertions(+), 221 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/zoran/zoran.h b/linux/drivers/media/video/zoran/zoran.h index 1bf540cb5..76668bda0 100644 --- a/linux/drivers/media/video/zoran/zoran.h +++ b/linux/drivers/media/video/zoran/zoran.h @@ -170,8 +170,6 @@ Private IOCTL to set up for displaying MJPEG #endif #define V4L_MASK_FRAME (V4L_MAX_FRAME - 1) -#define MAX_KMALLOC_MEM (128*1024) - #include "zr36057.h" enum card_type { diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index afbb18b89..5c8630647 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -192,16 +192,6 @@ const struct zoran_format zoran_formats[] = { }; #define NUM_FORMATS ARRAY_SIZE(zoran_formats) -// RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined -#if !defined(CONFIG_BIGPHYS_AREA) && !defined(BUZ_USE_HIMEM) -//#undef CONFIG_BIGPHYS_AREA -#define BUZ_USE_HIMEM -#endif - -#if defined(CONFIG_BIGPHYS_AREA) -# include -#endif - static int lock_norm; /* 0 = default 1 = Don't change TV standard (norm) */ module_param(lock_norm, int, 0644); MODULE_PARM_DESC(lock_norm, "Prevent norm changes (1 = ignore, >1 = fail)"); @@ -237,79 +227,8 @@ static void jpg_fbuffer_free(struct file *file); * Allocate the V4L grab buffers * * These have to be pysically contiguous. - * If v4l_bufsize <= MAX_KMALLOC_MEM we use kmalloc - * else we try to allocate them with bigphysarea_alloc_pages - * if the bigphysarea patch is present in the kernel, - * else we try to use high memory (if the user has bootet - * Linux with the necessary memory left over). - */ - -#if defined(BUZ_USE_HIMEM) && !defined(CONFIG_BIGPHYS_AREA) -static unsigned long -get_high_mem (unsigned long size) -{ -/* - * Check if there is usable memory at the end of Linux memory - * of at least size. Return the physical address of this memory, - * return 0 on failure. - * - * The idea is from Alexandro Rubini's book "Linux device drivers". - * The driver from him which is downloadable from O'Reilly's - * web site misses the "virt_to_phys(high_memory)" part - * (and therefore doesn't work at all - at least with 2.2.x kernels). - * - * It should be unnecessary to mention that THIS IS DANGEROUS, - * if more than one driver at a time has the idea to use this memory!!!! */ - volatile unsigned char __iomem *mem; - unsigned char c; - unsigned long hi_mem_ph; - unsigned long i; - - /* Map the high memory to user space */ - - hi_mem_ph = virt_to_phys(high_memory); - - mem = ioremap(hi_mem_ph, size); - if (!mem) { - dprintk(1, - KERN_ERR "%s: get_high_mem() - ioremap failed\n", - ZORAN_NAME); - return 0; - } - - for (i = 0; i < size; i++) { - /* Check if it is memory */ - c = i & 0xff; - writeb(c, mem + i); - if (readb(mem + i) != c) - break; - c = 255 - c; - writeb(c, mem + i); - if (readb(mem + i) != c) - break; - writeb(0, mem + i); /* zero out memory */ - - /* give the kernel air to breath */ - if ((i & 0x3ffff) == 0x3ffff) - schedule(); - } - - iounmap(mem); - - if (i != size) { - dprintk(1, - KERN_ERR - "%s: get_high_mem() - requested %lu, avail %lu\n", - ZORAN_NAME, size, i); - return 0; - } - - return hi_mem_ph; -} -#endif - static int v4l_fbuffer_alloc (struct file *file) { @@ -317,132 +236,37 @@ v4l_fbuffer_alloc (struct file *file) struct zoran *zr = fh->zr; int i, off; unsigned char *mem; -#if defined(BUZ_USE_HIMEM) && !defined(CONFIG_BIGPHYS_AREA) - unsigned long pmem = 0; -#endif for (i = 0; i < fh->v4l_buffers.num_buffers; i++) { if (fh->v4l_buffers.buffer[i].fbuffer) dprintk(2, KERN_WARNING - "%s: v4l_fbuffer_alloc() - buffer %d allready allocated!?\n", + "%s: v4l_fbuffer_alloc() - buffer %d already allocated!?\n", ZR_DEVNAME(zr), i); //udelay(20); - if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) { - /* Use kmalloc */ - - mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL); - if (!mem) { - dprintk(1, - KERN_ERR - "%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n", - ZR_DEVNAME(zr), i); - v4l_fbuffer_free(file); - return -ENOBUFS; - } - fh->v4l_buffers.buffer[i].fbuffer = mem; - fh->v4l_buffers.buffer[i].fbuffer_phys = - virt_to_phys(mem); - fh->v4l_buffers.buffer[i].fbuffer_bus = - virt_to_bus(mem); - for (off = 0; off < fh->v4l_buffers.buffer_size; - off += PAGE_SIZE) - SetPageReserved(MAP_NR(mem + off)); - dprintk(4, - KERN_INFO - "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%llx)\n", - ZR_DEVNAME(zr), i, (unsigned long) mem, - (unsigned long long)virt_to_bus(mem)); - } else { -#if defined(CONFIG_BIGPHYS_AREA) - /* Use bigphysarea_alloc_pages */ - - int n = - (fh->v4l_buffers.buffer_size + PAGE_SIZE - - 1) / PAGE_SIZE; - - mem = - (unsigned char *) bigphysarea_alloc_pages(n, 0, - GFP_KERNEL); - if (mem == 0) { - dprintk(1, - KERN_ERR - "%s: v4l_fbuffer_alloc() - bigphysarea_alloc_pages for V4L buf %d failed\n", - ZR_DEVNAME(zr), i); - v4l_fbuffer_free(file); - return -ENOBUFS; - } - fh->v4l_buffers.buffer[i].fbuffer = mem; - fh->v4l_buffers.buffer[i].fbuffer_phys = - virt_to_phys(mem); - fh->v4l_buffers.buffer[i].fbuffer_bus = - virt_to_bus(mem); - dprintk(4, - KERN_INFO - "%s: Bigphysarea frame %d mem %p (bus: 0x%lx)\n", - ZR_DEVNAME(zr), i, mem, virt_to_bus(mem)); - - /* Zero out the allocated memory */ - memset(fh->v4l_buffers.buffer[i].fbuffer, 0, - fh->v4l_buffers.buffer_size); -#else -#if defined(BUZ_USE_HIMEM) - - /* Use high memory which has been left at boot time */ - - /* Ok., Ok. this is an evil hack - we make - * the assumption that physical addresses are - * the same as bus addresses (true at least - * for Intel processors). The whole method of - * obtaining and using this memory is not very - * nice - but I hope it saves some poor users - * from kernel hacking, which might have even - * more evil results */ - - if (i == 0) { - int size = - fh->v4l_buffers.num_buffers * - fh->v4l_buffers.buffer_size; - - pmem = get_high_mem(size); - if (pmem == 0) { - dprintk(1, - KERN_ERR - "%s: v4l_fbuffer_alloc() - get_high_mem (size = %d KB) for V4L bufs failed\n", - ZR_DEVNAME(zr), size >> 10); - return -ENOBUFS; - } - fh->v4l_buffers.buffer[0].fbuffer = NULL; - fh->v4l_buffers.buffer[0].fbuffer_phys = pmem; - fh->v4l_buffers.buffer[0].fbuffer_bus = pmem; - dprintk(4, - KERN_INFO - "%s: v4l_fbuffer_alloc() - using %d KB high memory\n", - ZR_DEVNAME(zr), size >> 10); - } else { - fh->v4l_buffers.buffer[i].fbuffer = NULL; - fh->v4l_buffers.buffer[i].fbuffer_phys = - pmem + i * fh->v4l_buffers.buffer_size; - fh->v4l_buffers.buffer[i].fbuffer_bus = - pmem + i * fh->v4l_buffers.buffer_size; - } -#else - /* No bigphysarea present, usage of high memory disabled, - * but user wants buffers of more than MAX_KMALLOC_MEM */ + mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL); + if (!mem) { dprintk(1, KERN_ERR - "%s: v4l_fbuffer_alloc() - no bigphysarea_patch present, usage of high memory disabled,\n", - ZR_DEVNAME(zr)); - dprintk(1, - KERN_ERR - "%s: v4l_fbuffer_alloc() - sorry, could not allocate %d V4L buffers of size %d KB.\n", - ZR_DEVNAME(zr), fh->v4l_buffers.num_buffers, - fh->v4l_buffers.buffer_size >> 10); + "%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n", + ZR_DEVNAME(zr), i); + v4l_fbuffer_free(file); return -ENOBUFS; -#endif -#endif } + fh->v4l_buffers.buffer[i].fbuffer = mem; + fh->v4l_buffers.buffer[i].fbuffer_phys = + virt_to_phys(mem); + fh->v4l_buffers.buffer[i].fbuffer_bus = + virt_to_bus(mem); + for (off = 0; off < fh->v4l_buffers.buffer_size; + off += PAGE_SIZE) + SetPageReserved(MAP_NR(mem + off)); + dprintk(4, + KERN_INFO + "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%lx)\n", + ZR_DEVNAME(zr), i, (unsigned long) mem, + virt_to_bus(mem)); } fh->v4l_buffers.allocated = 1; @@ -465,18 +289,11 @@ v4l_fbuffer_free (struct file *file) if (!fh->v4l_buffers.buffer[i].fbuffer) continue; - if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) { - mem = fh->v4l_buffers.buffer[i].fbuffer; - for (off = 0; off < fh->v4l_buffers.buffer_size; - off += PAGE_SIZE) - ClearPageReserved(MAP_NR(mem + off)); - kfree((void *) fh->v4l_buffers.buffer[i].fbuffer); - } -#if defined(CONFIG_BIGPHYS_AREA) - else - bigphysarea_free_pages((void *) fh->v4l_buffers. - buffer[i].fbuffer); -#endif + mem = fh->v4l_buffers.buffer[i].fbuffer; + for (off = 0; off < fh->v4l_buffers.buffer_size; + off += PAGE_SIZE) + ClearPageReserved(MAP_NR(mem + off)); + kfree((void *) fh->v4l_buffers.buffer[i].fbuffer); fh->v4l_buffers.buffer[i].fbuffer = NULL; } @@ -486,16 +303,10 @@ v4l_fbuffer_free (struct file *file) /* * Allocate the MJPEG grab buffers. * - * If the requested buffer size is smaller than MAX_KMALLOC_MEM, - * kmalloc is used to request a physically contiguous area, - * else we allocate the memory in framgents with get_zeroed_page. - * * If a Natoma chipset is present and this is a revision 1 zr36057, * each MJPEG buffer needs to be physically contiguous. * (RJ: This statement is from Dave Perks' original driver, * I could never check it because I have a zr36067) - * The driver cares about this because it reduces the buffer - * size to MAX_KMALLOC_MEM in that case (which forces contiguous allocation). * * RJ: The contents grab buffers needs never be accessed in the driver. * Therefore there is no need to allocate them with vmalloc in order @@ -529,7 +340,7 @@ jpg_fbuffer_alloc (struct file *file) if (fh->jpg_buffers.buffer[i].frag_tab) dprintk(2, KERN_WARNING - "%s: jpg_fbuffer_alloc() - buffer %d allready allocated!?\n", + "%s: jpg_fbuffer_alloc() - buffer %d already allocated!?\n", ZR_DEVNAME(zr), i); /* Allocate fragment table for this buffer */ @@ -569,7 +380,7 @@ jpg_fbuffer_alloc (struct file *file) off += PAGE_SIZE) SetPageReserved(MAP_NR(mem + off)); } else { - /* jpg_bufsize is allreay page aligned */ + /* jpg_bufsize is already page aligned */ for (j = 0; j < fh->jpg_buffers.buffer_size / PAGE_SIZE; j++) { @@ -2238,6 +2049,7 @@ schan_unlock_and_return: return res; } + case VIDIOCGMBUF: { struct video_mbuf *vmbuf = arg; @@ -2434,16 +2246,13 @@ sparams_unlock_and_return: * tables to a Maximum of 2 MB */ if (breq->size > jpg_bufsize) breq->size = jpg_bufsize; - if (fh->jpg_buffers.need_contiguous && - breq->size > MAX_KMALLOC_MEM) - breq->size = MAX_KMALLOC_MEM; mutex_lock(&zr->resource_lock); if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { dprintk(1, KERN_ERR - "%s: BUZIOC_REQBUFS - buffers allready allocated\n", + "%s: BUZIOC_REQBUFS - buffers already allocated\n", ZR_DEVNAME(zr)); res = -EBUSY; goto jpgreqbuf_unlock_and_return; -- cgit v1.2.3 From c263f2e699cb58f1ac5e12e170d0879329845c0a Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 17:23:24 +0100 Subject: zoran: use slider flag with volume etc. controls. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_driver.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux') diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index 5c8630647..ebae49f91 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -3261,6 +3261,7 @@ static int zoran_queryctrl(struct file *file, void *__fh, ctrl->step = 1; ctrl->default_value = 32768; ctrl->type = V4L2_CTRL_TYPE_INTEGER; + ctrl->flags = V4L2_CTRL_FLAG_SLIDER; return 0; } -- cgit v1.2.3 From a393861c10e72edfaf97362739be70ebe940c246 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 17:24:56 +0100 Subject: zoran: fix field typo. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index ebae49f91..eeb541f26 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -2464,7 +2464,7 @@ static int zoran_g_fmt_vid_out(struct file *file, void *__fh, fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; if (fh->jpg_settings.TmpDcm == 1) fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? - V4L2_FIELD_SEQ_BT : V4L2_FIELD_SEQ_BT); + V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); else fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); -- cgit v1.2.3 From 0dd0437a3727766237df82bdfa89bc02a18cc901 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 17:28:28 +0100 Subject: zoran: set bytesperline to 0 when using MJPEG. From: Hans Verkuil Remove bogus check on bytesperline in the try_fmt_vid_out call. Just set it to 0. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_driver.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index eeb541f26..b4a1b1c7b 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -2550,12 +2550,11 @@ static int zoran_try_fmt_vid_out(struct file *file, void *__fh, struct zoran_jpg_settings settings; int res = 0; - if (fmt->fmt.pix.bytesperline > 0) - return -EINVAL; - if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) return -EINVAL; + fmt->fmt.pix.bytesperline = 0; + mutex_lock(&zr->resource_lock); settings = fh->jpg_settings; @@ -2609,9 +2608,6 @@ static int zoran_try_fmt_vid_cap(struct file *file, void *__fh, struct zoran *zr = fh->zr; int i; - if (fmt->fmt.pix.bytesperline > 0) - return -EINVAL; - if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) return zoran_try_fmt_vid_out(file, fh, fmt); -- cgit v1.2.3 From 4f77e897cb187126ad10aad97b2edc6a89395d79 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 17:51:13 +0100 Subject: zoran: remove old V4L1 ioctls, use v4l1-compat instead. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/Kconfig | 4 +- linux/drivers/media/video/zoran/zoran_driver.c | 459 +++---------------------- 2 files changed, 46 insertions(+), 417 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/zoran/Kconfig b/linux/drivers/media/video/zoran/Kconfig index 4ea5fa71d..a0fe52260 100644 --- a/linux/drivers/media/video/zoran/Kconfig +++ b/linux/drivers/media/video/zoran/Kconfig @@ -1,6 +1,6 @@ config VIDEO_ZORAN tristate "Zoran ZR36057/36067 Video For Linux" - depends on PCI && I2C_ALGOBIT && VIDEO_V4L1 && VIRT_TO_BUS + depends on PCI && I2C_ALGOBIT && VIDEO_V4L2 && VIRT_TO_BUS help Say Y for support for MJPEG capture cards based on the Zoran 36057/36067 PCI controller chipset. This includes the Iomega @@ -66,7 +66,7 @@ config VIDEO_ZORAN_LML33R10 config VIDEO_ZORAN_AVS6EYES tristate "AverMedia 6 Eyes support (EXPERIMENTAL)" - depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL && VIDEO_V4L1 + depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_KS0127 if VIDEO_HELPER_CHIPS_AUTO help diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index b4a1b1c7b..6a2607998 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -614,64 +614,6 @@ zoran_v4l_queue_frame (struct file *file, return res; } -static int -v4l_grab (struct file *file, - struct video_mmap *mp) -{ - struct zoran_fh *fh = file->private_data; - struct zoran *zr = fh->zr; - int res = 0, i; - - for (i = 0; i < NUM_FORMATS; i++) { - if (zoran_formats[i].palette == mp->format && - zoran_formats[i].flags & ZORAN_FORMAT_CAPTURE && - !(zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)) - break; - } - if (i == NUM_FORMATS || zoran_formats[i].depth == 0) { - dprintk(1, - KERN_ERR - "%s: v4l_grab() - wrong bytes-per-pixel format\n", - ZR_DEVNAME(zr)); - return -EINVAL; - } - - /* - * To minimize the time spent in the IRQ routine, we avoid setting up - * the video front end there. - * If this grab has different parameters from a running streaming capture - * we stop the streaming capture and start it over again. - */ - if (zr->v4l_memgrab_active && - (zr->v4l_settings.width != mp->width || - zr->v4l_settings.height != mp->height || - zr->v4l_settings.format->palette != mp->format)) { - res = wait_grab_pending(zr); - if (res) - return res; - } - if ((res = zoran_v4l_set_format(file, - mp->width, - mp->height, - &zoran_formats[i]))) - return res; - zr->v4l_settings = fh->v4l_settings; - - /* queue the frame in the pending queue */ - if ((res = zoran_v4l_queue_frame(file, mp->frame))) { - fh->v4l_buffers.active = ZORAN_FREE; - return res; - } - - /* put the 36057 into frame grabbing mode */ - if (!res && !zr->v4l_memgrab_active) - zr36057_set_memgrab(zr, 1); - - //dprintk(4, KERN_INFO "%s: Frame grab 3...\n", ZR_DEVNAME(zr)); - - return res; -} - /* * Sync on a V4L buffer */ @@ -1761,6 +1703,7 @@ zoran_set_input (struct zoran *zr, * ioctl routine */ +#ifdef CONFIG_VIDEO_V4L1_COMPAT static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) { struct zoran_fh *fh = __fh; @@ -1768,363 +1711,6 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) struct zoran_jpg_settings settings; switch (cmd) { - case VIDIOCGCAP: - { - struct video_capability *vcap = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGCAP\n", ZR_DEVNAME(zr)); - - memset(vcap, 0, sizeof(struct video_capability)); - strncpy(vcap->name, ZR_DEVNAME(zr), sizeof(vcap->name)-1); - vcap->type = ZORAN_VID_TYPE; - - vcap->channels = zr->card.inputs; - vcap->audios = 0; - mutex_lock(&zr->resource_lock); - vcap->maxwidth = BUZ_MAX_WIDTH; - vcap->maxheight = BUZ_MAX_HEIGHT; - vcap->minwidth = BUZ_MIN_WIDTH; - vcap->minheight = BUZ_MIN_HEIGHT; - mutex_unlock(&zr->resource_lock); - - return 0; - } - - case VIDIOCGCHAN: - { - struct video_channel *vchan = arg; - int channel = vchan->channel; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGCHAN - channel=%d\n", - ZR_DEVNAME(zr), vchan->channel); - - memset(vchan, 0, sizeof(struct video_channel)); - if (channel > zr->card.inputs || channel < 0) { - dprintk(1, - KERN_ERR - "%s: VIDIOCGCHAN on not existing channel %d\n", - ZR_DEVNAME(zr), channel); - return -EINVAL; - } - - strcpy(vchan->name, zr->card.input[channel].name); - - vchan->tuners = 0; - vchan->flags = 0; - vchan->type = VIDEO_TYPE_CAMERA; - mutex_lock(&zr->resource_lock); - vchan->norm = zr->norm; - mutex_unlock(&zr->resource_lock); - vchan->channel = channel; - - return 0; - } - - /* RJ: the documentation at http://roadrunner.swansea.linux.org.uk/v4lapi.shtml says: - * - * * "The VIDIOCSCHAN ioctl takes an integer argument and switches the capture to this input." - * * ^^^^^^^ - * * The famos BTTV driver has it implemented with a struct video_channel argument - * * and we follow it for compatibility reasons - * * - * * BTW: this is the only way the user can set the norm! - */ - - case VIDIOCSCHAN: - { - struct video_channel *vchan = arg; - int res; - - dprintk(3, - KERN_DEBUG - "%s: VIDIOCSCHAN - channel=%d, norm=%d\n", - ZR_DEVNAME(zr), vchan->channel, vchan->norm); - - mutex_lock(&zr->resource_lock); - if ((res = zoran_set_input(zr, vchan->channel))) - goto schan_unlock_and_return; - if ((res = zoran_set_norm(zr, vchan->norm))) - goto schan_unlock_and_return; - - /* Make sure the changes come into effect */ - res = wait_grab_pending(zr); -schan_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; - } - - case VIDIOCGPICT: - { - struct video_picture *vpict = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGPICT\n", ZR_DEVNAME(zr)); - - memset(vpict, 0, sizeof(struct video_picture)); - mutex_lock(&zr->resource_lock); - vpict->hue = zr->hue; - vpict->brightness = zr->brightness; - vpict->contrast = zr->contrast; - vpict->colour = zr->saturation; - if (fh->overlay_settings.format) { - vpict->depth = fh->overlay_settings.format->depth; - vpict->palette = fh->overlay_settings.format->palette; - } else { - vpict->depth = 0; - } - mutex_unlock(&zr->resource_lock); - - return 0; - } - - case VIDIOCSPICT: - { - struct video_picture *vpict = arg; - int i; - - dprintk(3, - KERN_DEBUG - "%s: VIDIOCSPICT - bri=%d, hue=%d, col=%d, con=%d, dep=%d, pal=%d\n", - ZR_DEVNAME(zr), vpict->brightness, vpict->hue, - vpict->colour, vpict->contrast, vpict->depth, - vpict->palette); - - for (i = 0; i < NUM_FORMATS; i++) { - const struct zoran_format *fmt = &zoran_formats[i]; - - if (fmt->palette != -1 && - fmt->flags & ZORAN_FORMAT_OVERLAY && - fmt->palette == vpict->palette && - fmt->depth == vpict->depth) - break; - } - if (i == NUM_FORMATS) { - dprintk(1, - KERN_ERR - "%s: VIDIOCSPICT - Invalid palette %d\n", - ZR_DEVNAME(zr), vpict->palette); - return -EINVAL; - } - - mutex_lock(&zr->resource_lock); - - decoder_command(zr, DECODER_SET_PICTURE, vpict); - - zr->hue = vpict->hue; - zr->contrast = vpict->contrast; - zr->saturation = vpict->colour; - zr->brightness = vpict->brightness; - - fh->overlay_settings.format = &zoran_formats[i]; - - mutex_unlock(&zr->resource_lock); - - return 0; - } - - case VIDIOCCAPTURE: - { - int *on = arg, res; - - dprintk(3, KERN_DEBUG "%s: VIDIOCCAPTURE - on=%d\n", - ZR_DEVNAME(zr), *on); - - mutex_lock(&zr->resource_lock); - res = setup_overlay(file, *on); - mutex_unlock(&zr->resource_lock); - - return res; - } - - case VIDIOCGWIN: - { - struct video_window *vwin = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGWIN\n", ZR_DEVNAME(zr)); - - memset(vwin, 0, sizeof(struct video_window)); - mutex_lock(&zr->resource_lock); - vwin->x = fh->overlay_settings.x; - vwin->y = fh->overlay_settings.y; - vwin->width = fh->overlay_settings.width; - vwin->height = fh->overlay_settings.height; - mutex_unlock(&zr->resource_lock); - vwin->clipcount = 0; - return 0; - } - - case VIDIOCSWIN: - { - struct video_window *vwin = arg; - int res; - - dprintk(3, - KERN_DEBUG - "%s: VIDIOCSWIN - x=%d, y=%d, w=%d, h=%d, clipcount=%d\n", - ZR_DEVNAME(zr), vwin->x, vwin->y, vwin->width, - vwin->height, vwin->clipcount); - - mutex_lock(&zr->resource_lock); - res = - setup_window(file, vwin->x, vwin->y, vwin->width, - vwin->height, vwin->clips, - vwin->clipcount, NULL); - mutex_unlock(&zr->resource_lock); - - return res; - } - - case VIDIOCGFBUF: - { - struct video_buffer *vbuf = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGFBUF\n", ZR_DEVNAME(zr)); - - mutex_lock(&zr->resource_lock); - *vbuf = zr->buffer; - mutex_unlock(&zr->resource_lock); - return 0; - } - - case VIDIOCSFBUF: - { - struct video_buffer *vbuf = arg; - int i, res = 0; - - dprintk(3, - KERN_DEBUG - "%s: VIDIOCSFBUF - base=%p, w=%d, h=%d, depth=%d, bpl=%d\n", - ZR_DEVNAME(zr), vbuf->base, vbuf->width, - vbuf->height, vbuf->depth, vbuf->bytesperline); - - for (i = 0; i < NUM_FORMATS; i++) - if (zoran_formats[i].depth == vbuf->depth) - break; - if (i == NUM_FORMATS) { - dprintk(1, - KERN_ERR - "%s: VIDIOCSFBUF - invalid fbuf depth %d\n", - ZR_DEVNAME(zr), vbuf->depth); - return -EINVAL; - } - - mutex_lock(&zr->resource_lock); - res = - setup_fbuffer(file, vbuf->base, &zoran_formats[i], - vbuf->width, vbuf->height, - vbuf->bytesperline); - mutex_unlock(&zr->resource_lock); - - return res; - } - - case VIDIOCSYNC: - { - int *frame = arg, res; - - dprintk(3, KERN_DEBUG "%s: VIDIOCSYNC - frame=%d\n", - ZR_DEVNAME(zr), *frame); - - mutex_lock(&zr->resource_lock); - res = v4l_sync(file, *frame); - mutex_unlock(&zr->resource_lock); - if (!res) - zr->v4l_sync_tail++; - return res; - } - - case VIDIOCMCAPTURE: - { - struct video_mmap *vmap = arg; - int res; - - dprintk(3, - KERN_DEBUG - "%s: VIDIOCMCAPTURE - frame=%d, geom=%dx%d, fmt=%d\n", - ZR_DEVNAME(zr), vmap->frame, vmap->width, vmap->height, - vmap->format); - - mutex_lock(&zr->resource_lock); - res = v4l_grab(file, vmap); - mutex_unlock(&zr->resource_lock); - return res; - } - - - case VIDIOCGMBUF: - { - struct video_mbuf *vmbuf = arg; - int i, res = 0; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGMBUF\n", ZR_DEVNAME(zr)); - - vmbuf->size = - fh->v4l_buffers.num_buffers * - fh->v4l_buffers.buffer_size; - vmbuf->frames = fh->v4l_buffers.num_buffers; - for (i = 0; i < vmbuf->frames; i++) { - vmbuf->offsets[i] = - i * fh->v4l_buffers.buffer_size; - } - - mutex_lock(&zr->resource_lock); - - if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { - dprintk(1, - KERN_ERR - "%s: VIDIOCGMBUF - buffers already allocated\n", - ZR_DEVNAME(zr)); - res = -EINVAL; - goto v4l1reqbuf_unlock_and_return; - } - - if (v4l_fbuffer_alloc(file)) { - res = -ENOMEM; - goto v4l1reqbuf_unlock_and_return; - } - - /* The next mmap will map the V4L buffers */ - fh->map_mode = ZORAN_MAP_MODE_RAW; -v4l1reqbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); - - return res; - } - - case VIDIOCGUNIT: - { - struct video_unit *vunit = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGUNIT\n", ZR_DEVNAME(zr)); - - vunit->video = zr->video_dev->minor; - vunit->vbi = VIDEO_NO_UNIT; - vunit->radio = VIDEO_NO_UNIT; - vunit->audio = VIDEO_NO_UNIT; - vunit->teletext = VIDEO_NO_UNIT; - - return 0; - } - - /* - * RJ: In principal we could support subcaptures for V4L grabbing. - * Not even the famous BTTV driver has them, however. - * If there should be a strong demand, one could consider - * to implement them. - */ - case VIDIOCGCAPTURE: - { - dprintk(3, KERN_ERR "%s: VIDIOCGCAPTURE not supported\n", - ZR_DEVNAME(zr)); - return -EINVAL; - } - - case VIDIOCSCAPTURE: - { - dprintk(3, KERN_ERR "%s: VIDIOCSCAPTURE not supported\n", - ZR_DEVNAME(zr)); - return -EINVAL; - } - case BUZIOC_G_PARAMS: { struct zoran_params *bparams = arg; @@ -2384,6 +1970,46 @@ gstat_unlock_and_return: } } +static int zoran_vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *vmbuf) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int i, res = 0; + + vmbuf->size = + fh->v4l_buffers.num_buffers * + fh->v4l_buffers.buffer_size; + vmbuf->frames = fh->v4l_buffers.num_buffers; + for (i = 0; i < vmbuf->frames; i++) { + vmbuf->offsets[i] = + i * fh->v4l_buffers.buffer_size; + } + + mutex_lock(&zr->resource_lock); + + if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { + dprintk(1, + KERN_ERR + "%s: VIDIOCGMBUF - buffers already allocated\n", + ZR_DEVNAME(zr)); + res = -EINVAL; + goto v4l1reqbuf_unlock_and_return; + } + + if (v4l_fbuffer_alloc(file)) { + res = -ENOMEM; + goto v4l1reqbuf_unlock_and_return; + } + + /* The next mmap will map the V4L buffers */ + fh->map_mode = ZORAN_MAP_MODE_RAW; +v4l1reqbuf_unlock_and_return: + mutex_unlock(&zr->resource_lock); + + return res; +} +#endif + static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap) { struct zoran_fh *fh = __fh; @@ -4119,7 +3745,10 @@ static const struct v4l2_ioctl_ops zoran_ioctl_ops = { .vidioc_queryctrl = zoran_queryctrl, .vidioc_s_ctrl = zoran_s_ctrl, .vidioc_g_ctrl = zoran_g_ctrl, +#ifdef CONFIG_VIDEO_V4L1_COMPAT .vidioc_default = zoran_default, + .vidiocgmbuf = zoran_vidiocgmbuf, +#endif }; static const struct v4l2_file_operations zoran_fops = { -- cgit v1.2.3 From 7b62aa559970adaf22b84c7e776fbefc96d14dd1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 17:52:24 +0100 Subject: zoran: set correct parent of the video device. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_card.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux') diff --git a/linux/drivers/media/video/zoran/zoran_card.c b/linux/drivers/media/video/zoran/zoran_card.c index 5d0fa99f2..99a25218b 100644 --- a/linux/drivers/media/video/zoran/zoran_card.c +++ b/linux/drivers/media/video/zoran/zoran_card.c @@ -1138,6 +1138,7 @@ zr36057_init (struct zoran *zr) * Now add the template and register the device unit. */ memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template)); + zr->video_dev->parent = &zr->pci_dev->dev; strcpy(zr->video_dev->name, ZR_DEVNAME(zr)); err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]); if (err < 0) -- cgit v1.2.3 From f29dd75cad2ab933c187296919168a2a2a34ae1b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 21:00:37 +0100 Subject: zoran: cleanups in an attempt to make the source a bit more readable. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_card.c | 9 +- linux/drivers/media/video/zoran/zoran_device.c | 404 +++++++++++-------------- linux/drivers/media/video/zoran/zoran_driver.c | 4 +- 3 files changed, 184 insertions(+), 233 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/zoran/zoran_card.c b/linux/drivers/media/video/zoran/zoran_card.c index 99a25218b..ef0533086 100644 --- a/linux/drivers/media/video/zoran/zoran_card.c +++ b/linux/drivers/media/video/zoran/zoran_card.c @@ -920,15 +920,12 @@ zoran_check_jpg_settings (struct zoran *zr, err0++; if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) err0++; - if (settings->img_y + settings->img_height > - BUZ_MAX_HEIGHT / 2) + if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) err0++; if (settings->HorDcm && settings->VerDcm) { - if (settings->img_width % - (16 * settings->HorDcm) != 0) + if (settings->img_width % (16 * settings->HorDcm) != 0) err0++; - if (settings->img_height % - (8 * settings->VerDcm) != 0) + if (settings->img_height % (8 * settings->VerDcm) != 0) err0++; } diff --git a/linux/drivers/media/video/zoran/zoran_device.c b/linux/drivers/media/video/zoran/zoran_device.c index 87f894fa2..592300e2f 100644 --- a/linux/drivers/media/video/zoran/zoran_device.c +++ b/linux/drivers/media/video/zoran/zoran_device.c @@ -1209,22 +1209,52 @@ zoran_reap_stat_com (struct zoran *zr) } } +static void zoran_restart(struct zoran *zr) +{ + /* Now the stat_comm buffer is ready for restart */ + int status, mode; + + if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { + decoder_command(zr, DECODER_GET_STATUS, &status); + mode = CODEC_DO_COMPRESSION; + } else { + status = 0; + mode = CODEC_DO_EXPANSION; + } + if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || + (status & DECODER_STATUS_GOOD)) { + /********** RESTART code *************/ + jpeg_codec_reset(zr); + zr->codec->set_mode(zr->codec, mode); + zr36057_set_jpg(zr, zr->codec_mode); + jpeg_start(zr); + + if (zr->num_errors <= 8) + dprintk(2, KERN_INFO "%s: Restart\n", + ZR_DEVNAME(zr)); + + zr->JPEG_missed = 0; + zr->JPEG_error = 2; + /********** End RESTART code ***********/ + } +} + static void error_handler (struct zoran *zr, u32 astat, u32 stat) { + int i, j; + /* This is JPEG error handling part */ - if ((zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) && - (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS)) { - //dprintk(1, KERN_ERR "%s: Internal error: error handling request in mode %d\n", ZR_DEVNAME(zr), zr->codec_mode); + if (zr->codec_mode != BUZ_MODE_MOTION_COMPRESS && + zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS) { return; } if ((stat & 1) == 0 && zr->codec_mode == BUZ_MODE_MOTION_COMPRESS && - zr->jpg_dma_tail - zr->jpg_que_tail >= - zr->jpg_buffers.num_buffers) { + zr->jpg_dma_tail - zr->jpg_que_tail >= zr->jpg_buffers.num_buffers) { /* No free buffers... */ zoran_reap_stat_com(zr); zoran_feed_stat_com(zr); @@ -1233,142 +1263,95 @@ error_handler (struct zoran *zr, return; } - if (zr->JPEG_error != 1) { - /* - * First entry: error just happened during normal operation - * - * In BUZ_MODE_MOTION_COMPRESS: - * - * Possible glitch in TV signal. In this case we should - * stop the codec and wait for good quality signal before - * restarting it to avoid further problems - * - * In BUZ_MODE_MOTION_DECOMPRESS: - * - * Bad JPEG frame: we have to mark it as processed (codec crashed - * and was not able to do it itself), and to remove it from queue. - */ - btand(~ZR36057_JMC_Go_en, ZR36057_JMC); - udelay(1); - stat = stat | (post_office_read(zr, 7, 0) & 3) << 8; - btwrite(0, ZR36057_JPC); - btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); - jpeg_codec_reset(zr); - jpeg_codec_sleep(zr, 1); - zr->JPEG_error = 1; - zr->num_errors++; - - /* Report error */ - if (zr36067_debug > 1 && zr->num_errors <= 8) { - long frame; - frame = - zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; - printk(KERN_ERR - "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ", - ZR_DEVNAME(zr), stat, zr->last_isr, - zr->jpg_que_tail, zr->jpg_dma_tail, - zr->jpg_dma_head, zr->jpg_que_head, - zr->jpg_seq_num, frame); - printk("stat_com frames:"); - { - int i, j; - for (j = 0; j < BUZ_NUM_STAT_COM; j++) { - for (i = 0; - i < zr->jpg_buffers.num_buffers; - i++) { - if (le32_to_cpu(zr->stat_com[j]) == - zr->jpg_buffers. - buffer[i]. - frag_tab_bus) { - printk("% d->%d", - j, i); - } - } - } - printk("\n"); - } - } - /* Find an entry in stat_com and rotate contents */ - { - int i; - - if (zr->jpg_settings.TmpDcm == 1) - i = (zr->jpg_dma_tail - - zr->jpg_err_shift) & BUZ_MASK_STAT_COM; - else - i = ((zr->jpg_dma_tail - - zr->jpg_err_shift) & 1) * 2; - if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) { - /* Mimic zr36067 operation */ - zr->stat_com[i] |= cpu_to_le32(1); - if (zr->jpg_settings.TmpDcm != 1) - zr->stat_com[i + 1] |= cpu_to_le32(1); - /* Refill */ - zoran_reap_stat_com(zr); - zoran_feed_stat_com(zr); - wake_up_interruptible(&zr->jpg_capq); - /* Find an entry in stat_com again after refill */ - if (zr->jpg_settings.TmpDcm == 1) - i = (zr->jpg_dma_tail - - zr->jpg_err_shift) & - BUZ_MASK_STAT_COM; - else - i = ((zr->jpg_dma_tail - - zr->jpg_err_shift) & 1) * 2; - } - if (i) { - /* Rotate stat_comm entries to make current entry first */ - int j; - __le32 bus_addr[BUZ_NUM_STAT_COM]; - - /* Here we are copying the stat_com array, which - * is already in little endian format, so - * no endian conversions here - */ - memcpy(bus_addr, zr->stat_com, - sizeof(bus_addr)); - for (j = 0; j < BUZ_NUM_STAT_COM; j++) { - zr->stat_com[j] = - bus_addr[(i + j) & - BUZ_MASK_STAT_COM]; + if (zr->JPEG_error == 1) { + zoran_restart(zr); + return; + } - } - zr->jpg_err_shift += i; - zr->jpg_err_shift &= BUZ_MASK_STAT_COM; + /* + * First entry: error just happened during normal operation + * + * In BUZ_MODE_MOTION_COMPRESS: + * + * Possible glitch in TV signal. In this case we should + * stop the codec and wait for good quality signal before + * restarting it to avoid further problems + * + * In BUZ_MODE_MOTION_DECOMPRESS: + * + * Bad JPEG frame: we have to mark it as processed (codec crashed + * and was not able to do it itself), and to remove it from queue. + */ + btand(~ZR36057_JMC_Go_en, ZR36057_JMC); + udelay(1); + stat = stat | (post_office_read(zr, 7, 0) & 3) << 8; + btwrite(0, ZR36057_JPC); + btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); + jpeg_codec_reset(zr); + jpeg_codec_sleep(zr, 1); + zr->JPEG_error = 1; + zr->num_errors++; + + /* Report error */ + if (zr36067_debug > 1 && zr->num_errors <= 8) { + long frame; + + frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; + printk(KERN_ERR + "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ", + ZR_DEVNAME(zr), stat, zr->last_isr, + zr->jpg_que_tail, zr->jpg_dma_tail, + zr->jpg_dma_head, zr->jpg_que_head, + zr->jpg_seq_num, frame); + printk(KERN_INFO "stat_com frames:"); + for (j = 0; j < BUZ_NUM_STAT_COM; j++) { + for (i = 0; i < zr->jpg_buffers.num_buffers; i++) { + if (le32_to_cpu(zr->stat_com[j]) == zr->jpg_buffers.buffer[i].frag_tab_bus) + printk(KERN_CONT "% d->%d", j, i); } - if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) - zr->jpg_err_seq = zr->jpg_seq_num; /* + 1; */ } + printk(KERN_CONT "\n"); } + /* Find an entry in stat_com and rotate contents */ + if (zr->jpg_settings.TmpDcm == 1) + i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM; + else + i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2; + if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) { + /* Mimic zr36067 operation */ + zr->stat_com[i] |= cpu_to_le32(1); + if (zr->jpg_settings.TmpDcm != 1) + zr->stat_com[i + 1] |= cpu_to_le32(1); + /* Refill */ + zoran_reap_stat_com(zr); + zoran_feed_stat_com(zr); + wake_up_interruptible(&zr->jpg_capq); + /* Find an entry in stat_com again after refill */ + if (zr->jpg_settings.TmpDcm == 1) + i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM; + else + i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2; + } + if (i) { + /* Rotate stat_comm entries to make current entry first */ + int j; + __le32 bus_addr[BUZ_NUM_STAT_COM]; + + /* Here we are copying the stat_com array, which + * is already in little endian format, so + * no endian conversions here + */ + memcpy(bus_addr, zr->stat_com, sizeof(bus_addr)); - /* Now the stat_comm buffer is ready for restart */ - do { - int status, mode; - - if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { - decoder_command(zr, DECODER_GET_STATUS, &status); - mode = CODEC_DO_COMPRESSION; - } else { - status = 0; - mode = CODEC_DO_EXPANSION; - } - if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || - (status & DECODER_STATUS_GOOD)) { - /********** RESTART code *************/ - jpeg_codec_reset(zr); - zr->codec->set_mode(zr->codec, mode); - zr36057_set_jpg(zr, zr->codec_mode); - jpeg_start(zr); - - if (zr->num_errors <= 8) - dprintk(2, KERN_INFO "%s: Restart\n", - ZR_DEVNAME(zr)); + for (j = 0; j < BUZ_NUM_STAT_COM; j++) + zr->stat_com[j] = bus_addr[(i + j) & BUZ_MASK_STAT_COM]; - zr->JPEG_missed = 0; - zr->JPEG_error = 2; - /********** End RESTART code ***********/ - } - } while (0); + zr->jpg_err_shift += i; + zr->jpg_err_shift &= BUZ_MASK_STAT_COM; + } + if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) + zr->jpg_err_seq = zr->jpg_seq_num; /* + 1; */ + zoran_restart(zr); } irqreturn_t @@ -1431,10 +1414,8 @@ zoran_irq (int irq, * We simply ignore them */ if (zr->v4l_memgrab_active) { - /* A lot more checks should be here ... */ - if ((btread(ZR36057_VSSFGR) & - ZR36057_VSSFGR_SnapShot) == 0) + if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SnapShot) == 0) dprintk(1, KERN_WARNING "%s: BuzIRQ with SnapShot off ???\n", @@ -1442,10 +1423,7 @@ zoran_irq (int irq, if (zr->v4l_grab_frame != NO_GRAB_ACTIVE) { /* There is a grab on a frame going on, check if it has finished */ - - if ((btread(ZR36057_VSSFGR) & - ZR36057_VSSFGR_FrameGrab) == - 0) { + if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_FrameGrab) == 0) { /* it is finished, notify the user */ zr->v4l_buffers.buffer[zr->v4l_grab_frame].state = BUZ_STATE_DONE; @@ -1463,9 +1441,7 @@ zoran_irq (int irq, if (zr->v4l_grab_frame == NO_GRAB_ACTIVE && zr->v4l_pend_tail != zr->v4l_pend_head) { - - int frame = zr->v4l_pend[zr->v4l_pend_tail & - V4L_MASK_FRAME]; + int frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME]; u32 reg; zr->v4l_grab_frame = frame; @@ -1474,27 +1450,17 @@ zoran_irq (int irq, /* Buffer address */ - reg = - zr->v4l_buffers.buffer[frame]. - fbuffer_bus; + reg = zr->v4l_buffers.buffer[frame].fbuffer_bus; btwrite(reg, ZR36057_VDTR); - if (zr->v4l_settings.height > - BUZ_MAX_HEIGHT / 2) - reg += - zr->v4l_settings. - bytesperline; + if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2) + reg += zr->v4l_settings.bytesperline; btwrite(reg, ZR36057_VDBR); /* video stride, status, and frame grab register */ reg = 0; - if (zr->v4l_settings.height > - BUZ_MAX_HEIGHT / 2) - reg += - zr->v4l_settings. - bytesperline; - reg = - (reg << - ZR36057_VSSFGR_DispStride); + if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2) + reg += zr->v4l_settings.bytesperline; + reg = (reg << ZR36057_VSSFGR_DispStride); reg |= ZR36057_VSSFGR_VidOvf; reg |= ZR36057_VSSFGR_SnapShot; reg |= ZR36057_VSSFGR_FrameGrab; @@ -1512,77 +1478,66 @@ zoran_irq (int irq, #if (IRQ_MASK & ZR36057_ISR_CodRepIRQ) if (astat & ZR36057_ISR_CodRepIRQ) { zr->intr_counter_CodRepIRQ++; - IDEBUG(printk - (KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n", + IDEBUG(printk(KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n", ZR_DEVNAME(zr))); btand(~ZR36057_ICR_CodRepIRQ, ZR36057_ICR); } #endif /* (IRQ_MASK & ZR36057_ISR_CodRepIRQ) */ #if (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) - if (astat & ZR36057_ISR_JPEGRepIRQ) { - - if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || - zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { - if (zr36067_debug > 1 && - (!zr->frame_num || zr->JPEG_error)) { - printk(KERN_INFO - "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n", - ZR_DEVNAME(zr), stat, - zr->jpg_settings.odd_even, - zr->jpg_settings. - field_per_buff, - zr->JPEG_missed); - { - char sc[] = "0000"; - char sv[5]; - int i; - strcpy(sv, sc); - for (i = 0; i < 4; i++) { - if (le32_to_cpu(zr->stat_com[i]) & 1) - sv[i] = '1'; - } - sv[4] = 0; - printk(KERN_INFO - "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n", - ZR_DEVNAME(zr), sv, - zr->jpg_que_tail, - zr->jpg_dma_tail, - zr->jpg_dma_head, - zr->jpg_que_head); - } - } else { - if (zr->JPEG_missed > zr->JPEG_max_missed) // Get statistics - zr->JPEG_max_missed = - zr->JPEG_missed; - if (zr->JPEG_missed < - zr->JPEG_min_missed) - zr->JPEG_min_missed = - zr->JPEG_missed; + if ((astat & ZR36057_ISR_JPEGRepIRQ) && + (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || + zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)) { + if (zr36067_debug > 1 && (!zr->frame_num || zr->JPEG_error)) { + char sc[] = "0000"; + char sv[5]; + int i; + + printk(KERN_INFO + "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n", + ZR_DEVNAME(zr), stat, + zr->jpg_settings.odd_even, + zr->jpg_settings.field_per_buff, + zr->JPEG_missed); + + strcpy(sv, sc); + for (i = 0; i < 4; i++) { + if (le32_to_cpu(zr->stat_com[i]) & 1) + sv[i] = '1'; } + sv[4] = 0; + printk(KERN_INFO + "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n", + ZR_DEVNAME(zr), sv, + zr->jpg_que_tail, + zr->jpg_dma_tail, + zr->jpg_dma_head, + zr->jpg_que_head); + } else { + /* Get statistics */ + if (zr->JPEG_missed > zr->JPEG_max_missed) + zr->JPEG_max_missed = zr->JPEG_missed; + if (zr->JPEG_missed < zr->JPEG_min_missed) + zr->JPEG_min_missed = zr->JPEG_missed; + } - if (zr36067_debug > 2 && zr->frame_num < 6) { - int i; - printk("%s: seq=%ld stat_com:", - ZR_DEVNAME(zr), zr->jpg_seq_num); - for (i = 0; i < 4; i++) { - printk(" %08x", - le32_to_cpu(zr->stat_com[i])); - } - printk("\n"); + if (zr36067_debug > 2 && zr->frame_num < 6) { + int i; + + printk(KERN_INFO "%s: seq=%ld stat_com:", + ZR_DEVNAME(zr), zr->jpg_seq_num); + for (i = 0; i < 4; i++) { + printk(KERN_CONT " %08x", + le32_to_cpu(zr->stat_com[i])); } - zr->frame_num++; - zr->JPEG_missed = 0; - zr->JPEG_error = 0; - zoran_reap_stat_com(zr); - zoran_feed_stat_com(zr); - wake_up_interruptible(&zr->jpg_capq); - } /*else { - dprintk(1, - KERN_ERR - "%s: JPEG interrupt while not in motion (de)compress mode!\n", - ZR_DEVNAME(zr)); - }*/ + printk(KERN_CONT "\n"); + } + zr->frame_num++; + zr->JPEG_missed = 0; + zr->JPEG_error = 0; + zoran_reap_stat_com(zr); + zoran_feed_stat_com(zr); + wake_up_interruptible(&zr->jpg_capq); } #endif /* (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) */ @@ -1591,8 +1546,7 @@ zoran_irq (int irq, zr->JPEG_missed > 25 || zr->JPEG_error == 1 || ((zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) && - (zr->frame_num & (zr->JPEG_missed > - zr->jpg_settings.field_per_buff)))) { + (zr->frame_num & (zr->JPEG_missed > zr->jpg_settings.field_per_buff)))) { error_handler(zr, astat, stat); } diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index 6a2607998..18c3516f8 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -2315,7 +2315,7 @@ static int zoran_s_fmt_vid_out(struct file *file, void *__fh, } /* we actually need to set 'real' parameters now */ - if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT) + if (fmt->fmt.pix.height * 2 > BUZ_MAX_HEIGHT) settings.TmpDcm = 1; else settings.TmpDcm = 2; @@ -2502,7 +2502,7 @@ static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffe if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) { dprintk(1, KERN_ERR - "%s: VIDIOC_REQBUFS - buffers allready allocated\n", + "%s: VIDIOC_REQBUFS - buffers already allocated\n", ZR_DEVNAME(zr)); res = -EBUSY; goto v4l2reqbuf_unlock_and_return; -- cgit v1.2.3 From 796fbda0aa38a68a6ba7451fb0cb1974f36cf956 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 21:11:17 +0100 Subject: zoran: fix TRY_FMT support From: Hans Verkuil Actually try to turn the format into something usable rather than just rejecting it if it isn't perfect. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_card.c | 63 ++++++++++++++++++-------- linux/drivers/media/video/zoran/zoran_card.h | 3 +- linux/drivers/media/video/zoran/zoran_driver.c | 21 +++++++-- 3 files changed, 63 insertions(+), 24 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/zoran/zoran_card.c b/linux/drivers/media/video/zoran/zoran_card.c index ef0533086..552204bab 100644 --- a/linux/drivers/media/video/zoran/zoran_card.c +++ b/linux/drivers/media/video/zoran/zoran_card.c @@ -836,7 +836,8 @@ zoran_unregister_i2c (struct zoran *zr) int zoran_check_jpg_settings (struct zoran *zr, - struct zoran_jpg_settings *settings) + struct zoran_jpg_settings *settings, + int try) { int err = 0, err0 = 0; @@ -901,35 +902,61 @@ zoran_check_jpg_settings (struct zoran *zr, /* We have to check the data the user has set */ if (settings->HorDcm != 1 && settings->HorDcm != 2 && - (zr->card.type == DC10_new || settings->HorDcm != 4)) + (zr->card.type == DC10_new || settings->HorDcm != 4)) { + settings->HorDcm = clamp(settings->HorDcm, 1, 2); err0++; - if (settings->VerDcm != 1 && settings->VerDcm != 2) + } + if (settings->VerDcm != 1 && settings->VerDcm != 2) { + settings->VerDcm = clamp(settings->VerDcm, 1, 2); err0++; - if (settings->TmpDcm != 1 && settings->TmpDcm != 2) + } + if (settings->TmpDcm != 1 && settings->TmpDcm != 2) { + settings->TmpDcm = clamp(settings->TmpDcm, 1, 2); err0++; + } if (settings->field_per_buff != 1 && - settings->field_per_buff != 2) + settings->field_per_buff != 2) { + settings->field_per_buff = clamp(settings->field_per_buff, 1, 2); err0++; - if (settings->img_x < 0) + } + if (settings->img_x < 0) { + settings->img_x = 0; err0++; - if (settings->img_y < 0) + } + if (settings->img_y < 0) { + settings->img_y = 0; err0++; - if (settings->img_width < 0) + } + if (settings->img_width < 0 || settings->img_width > BUZ_MAX_WIDTH) { + settings->img_width = clamp(settings->img_width, 0, (int)BUZ_MAX_WIDTH); err0++; - if (settings->img_height < 0) + } + if (settings->img_height < 0 || settings->img_height > BUZ_MAX_HEIGHT / 2) { + settings->img_height = clamp(settings->img_height, 0, BUZ_MAX_HEIGHT / 2); err0++; - if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) + } + if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) { + settings->img_x = BUZ_MAX_WIDTH - settings->img_width; + err0++; + } + if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) { + settings->img_y = BUZ_MAX_HEIGHT / 2 - settings->img_height; err0++; - if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) + } + if (settings->img_width % (16 * settings->HorDcm) != 0) { + settings->img_width -= settings->img_width % (16 * settings->HorDcm); + if (settings->img_width == 0) + settings->img_width = 16 * settings->HorDcm; + err0++; + } + if (settings->img_height % (8 * settings->VerDcm) != 0) { + settings->img_height -= settings->img_height % (8 * settings->VerDcm); + if (settings->img_height == 0) + settings->img_height = 8 * settings->VerDcm; err0++; - if (settings->HorDcm && settings->VerDcm) { - if (settings->img_width % (16 * settings->HorDcm) != 0) - err0++; - if (settings->img_height % (8 * settings->VerDcm) != 0) - err0++; } - if (err0) { + if (!try && err0) { dprintk(1, KERN_ERR "%s: check_jpg_settings() - error in params for decimation = 0\n", @@ -1019,7 +1046,7 @@ zoran_open_init_params (struct zoran *zr) sizeof(zr->jpg_settings.jpg_comp.COM_data)); zr->jpg_settings.jpg_comp.jpeg_markers = JPEG_MARKER_DHT | JPEG_MARKER_DQT; - i = zoran_check_jpg_settings(zr, &zr->jpg_settings); + i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0); if (i) dprintk(1, KERN_ERR diff --git a/linux/drivers/media/video/zoran/zoran_card.h b/linux/drivers/media/video/zoran/zoran_card.h index 4507bdc5e..4936fead7 100644 --- a/linux/drivers/media/video/zoran/zoran_card.h +++ b/linux/drivers/media/video/zoran/zoran_card.h @@ -44,7 +44,8 @@ extern int zr36067_debug; extern struct video_device zoran_template; extern int zoran_check_jpg_settings(struct zoran *zr, - struct zoran_jpg_settings *settings); + struct zoran_jpg_settings *settings, + int try); extern void zoran_open_init_params(struct zoran *zr); extern void zoran_vdev_release(struct video_device *vdev); diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index 18c3516f8..748df1fcf 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -1798,7 +1798,7 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) /* Check the params first before overwriting our * nternal values */ - if (zoran_check_jpg_settings(zr, &settings)) { + if (zoran_check_jpg_settings(zr, &settings, 0)) { res = -EINVAL; goto sparams_unlock_and_return; } @@ -2206,7 +2206,7 @@ static int zoran_try_fmt_vid_out(struct file *file, void *__fh, settings.field_per_buff = 1; /* check */ - res = zoran_check_jpg_settings(zr, &settings); + res = zoran_check_jpg_settings(zr, &settings, 1); if (res) goto tryfmt_unlock_and_return; @@ -2232,6 +2232,7 @@ static int zoran_try_fmt_vid_cap(struct file *file, void *__fh, { struct zoran_fh *fh = __fh; struct zoran *zr = fh->zr; + int bpp; int i; if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) @@ -2248,6 +2249,8 @@ static int zoran_try_fmt_vid_cap(struct file *file, void *__fh, return -EINVAL; } + bpp = (zoran_formats[i].depth + 7) / 8; + fmt->fmt.pix.width &= ~((bpp == 2) ? 1 : 3); if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) fmt->fmt.pix.width = BUZ_MAX_WIDTH; if (fmt->fmt.pix.width < BUZ_MIN_WIDTH) @@ -2335,8 +2338,16 @@ static int zoran_s_fmt_vid_out(struct file *file, void *__fh, else settings.field_per_buff = 1; + if (settings.HorDcm > 1) { + settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0; + settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH; + } else { + settings.img_x = 0; + settings.img_width = BUZ_MAX_WIDTH; + } + /* check */ - res = zoran_check_jpg_settings(zr, &settings); + res = zoran_check_jpg_settings(zr, &settings, 0); if (res) goto sfmtjpg_unlock_and_return; @@ -3217,7 +3228,7 @@ static int zoran_s_crop(struct file *file, void *__fh, struct v4l2_crop *crop) settings.img_height = crop->c.height; /* check validity */ - res = zoran_check_jpg_settings(zr, &settings); + res = zoran_check_jpg_settings(zr, &settings, 0); if (res) goto scrop_unlock_and_return; @@ -3279,7 +3290,7 @@ static int zoran_s_jpegcomp(struct file *file, void *__fh, goto sjpegc_unlock_and_return; } - res = zoran_check_jpg_settings(zr, &settings); + res = zoran_check_jpg_settings(zr, &settings, 0); if (res) goto sjpegc_unlock_and_return; if (!fh->jpg_buffers.allocated) -- cgit v1.2.3 From 3c0d4e5fb734b1afe1cd961a4c61b90c8c6d5d9d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 21:12:34 +0100 Subject: zoran: fix G_FMT From: Hans Verkuil Returned height was really height / 2. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index 748df1fcf..98741c992 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -2084,7 +2084,7 @@ static int zoran_g_fmt_vid_out(struct file *file, void *__fh, mutex_lock(&zr->resource_lock); fmt->fmt.pix.width = fh->jpg_settings.img_width / fh->jpg_settings.HorDcm; - fmt->fmt.pix.height = fh->jpg_settings.img_height / + fmt->fmt.pix.height = fh->jpg_settings.img_height * 2 / (fh->jpg_settings.VerDcm * fh->jpg_settings.TmpDcm); fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&fh->jpg_settings); fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; -- cgit v1.2.3 From 42175ea795fa141cd724faf722cdbbd59358ad3c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 21:15:46 +0100 Subject: zoran: if reqbufs is called with count == 0, do a streamoff. From: Hans Verkuil count == 0 has a special meaning, implement this. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_driver.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index 98741c992..e67c6caac 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -2494,6 +2494,8 @@ static int zoran_overlay(struct file *file, void *__fh, unsigned int on) return res; } +static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type); + static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *req) { struct zoran_fh *fh = __fh; @@ -2501,17 +2503,19 @@ static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffe int res = 0; if (req->memory != V4L2_MEMORY_MMAP) { - dprintk(1, + dprintk(2, KERN_ERR "%s: only MEMORY_MMAP capture is supported, not %d\n", ZR_DEVNAME(zr), req->memory); return -EINVAL; } - mutex_lock(&zr->resource_lock); + if (req->count == 0) + return zoran_streamoff(file, fh, req->type); + mutex_lock(&zr->resource_lock); if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) { - dprintk(1, + dprintk(2, KERN_ERR "%s: VIDIOC_REQBUFS - buffers already allocated\n", ZR_DEVNAME(zr)); -- cgit v1.2.3 From 441ce16cab1f8d7a546eeb785da0f9caf28ef7cc Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 21:26:06 +0100 Subject: zoran et al: convert zoran i2c modules to V4L2. From: Hans Verkuil The zoran i2c modules were still using V4L1 internally. Replace this with V4L2. Also deleted saa7111.c and saa7114.c, we use saa7115.c instead. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/Kconfig | 28 +- linux/drivers/media/video/Makefile | 2 - linux/drivers/media/video/adv7170.c | 74 +- linux/drivers/media/video/adv7175.c | 81 +- linux/drivers/media/video/bt819.c | 271 +++--- linux/drivers/media/video/bt856.c | 92 +- linux/drivers/media/video/bt866.c | 67 +- linux/drivers/media/video/ks0127.c | 140 ++-- linux/drivers/media/video/saa7110.c | 208 ++--- linux/drivers/media/video/saa7111.c | 497 ----------- linux/drivers/media/video/saa7114.c | 1073 ------------------------ linux/drivers/media/video/saa7185.c | 78 +- linux/drivers/media/video/vpx3220.c | 220 ++--- linux/drivers/media/video/zoran/Kconfig | 4 +- linux/drivers/media/video/zoran/zoran.h | 6 +- linux/drivers/media/video/zoran/zoran_card.c | 60 +- linux/drivers/media/video/zoran/zoran_device.c | 61 +- linux/drivers/media/video/zoran/zoran_driver.c | 220 ++--- 18 files changed, 642 insertions(+), 2540 deletions(-) delete mode 100644 linux/drivers/media/video/saa7111.c delete mode 100644 linux/drivers/media/video/saa7114.c (limited to 'linux') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 19cf3b8f6..e671beb59 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -307,38 +307,18 @@ config VIDEO_TCM825X config VIDEO_SAA7110 tristate "Philips SAA7110 video decoder" - depends on VIDEO_V4L1 && I2C + depends on VIDEO_V4L2 && I2C ---help--- Support for the Philips SAA7110 video decoders. To compile this driver as a module, choose M here: the module will be called saa7110. -config VIDEO_SAA7111 - tristate "Philips SAA7111 video decoder" - depends on VIDEO_V4L1 && I2C - ---help--- - Support for the Philips SAA711 video decoder. - - To compile this driver as a module, choose M here: the - module will be called saa7111. - -config VIDEO_SAA7114 - tristate "Philips SAA7114 video decoder" - depends on VIDEO_V4L1 && I2C - ---help--- - Support for the Philips SAA7114 video decoder. This driver - is used only on Zoran driver and should be moved soon to - SAA711x module. - - To compile this driver as a module, choose M here: the - module will be called saa7114. - config VIDEO_SAA711X - tristate "Philips SAA7113/4/5 video decoders" + tristate "Philips SAA7111/3/4/5 video decoders" depends on VIDEO_V4L2 && I2C ---help--- - Support for the Philips SAA7113/4/5 video decoders. + Support for the Philips SAA7111/3/4/5 video decoders. To compile this driver as a module, choose M here: the module will be called saa7115. @@ -639,7 +619,7 @@ config VIDEO_MXB depends on PCI && VIDEO_V4L1 && I2C select VIDEO_SAA7146_VV select VIDEO_TUNER - select VIDEO_SAA7115 if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO select VIDEO_TEA6420 if VIDEO_HELPER_CHIPS_AUTO diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index 72f6d03d2..263c2264d 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -43,8 +43,6 @@ obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o obj-$(CONFIG_VIDEO_SAA7110) += saa7110.o -obj-$(CONFIG_VIDEO_SAA7111) += saa7111.o -obj-$(CONFIG_VIDEO_SAA7114) += saa7114.o obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o obj-$(CONFIG_VIDEO_SAA717X) += saa717x.o obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o diff --git a/linux/drivers/media/video/adv7170.c b/linux/drivers/media/video/adv7170.c index 0a319ad8e..323cea3a9 100644 --- a/linux/drivers/media/video/adv7170.c +++ b/linux/drivers/media/video/adv7170.c @@ -53,9 +53,8 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); struct adv7170 { unsigned char reg[128]; - int norm; + v4l2_std_id norm; int input; - int enable; int bright; int contrast; int hue; @@ -63,7 +62,6 @@ struct adv7170 { }; static char *inputs[] = { "pass_through", "play_back" }; -static char *norms[] = { "PAL", "NTSC" }; /* ----------------------------------------------------------------------- */ @@ -192,7 +190,7 @@ static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg) struct adv7170 *encoder = i2c_get_clientdata(client); switch (cmd) { - case 0: + case VIDIOC_INT_INIT: #if 0 /* keep */ /* This is just for testing!!! */ adv7170_write_block(client, init_common, @@ -202,63 +200,47 @@ static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg) #endif break; - case ENCODER_GET_CAPABILITIES: + case VIDIOC_INT_S_STD_OUTPUT: { - struct video_encoder_capability *cap = arg; + v4l2_std_id iarg = *(v4l2_std_id *) arg; - cap->flags = VIDEO_ENCODER_PAL | - VIDEO_ENCODER_NTSC; - cap->inputs = 2; - cap->outputs = 1; - break; - } - - case ENCODER_SET_NORM: - { - int iarg = *(int *) arg; - - v4l_dbg(1, debug, client, "set norm %d\n", iarg); + v4l_dbg(1, debug, client, "set norm %llx\n", iarg); - switch (iarg) { - case VIDEO_MODE_NTSC: + if (iarg & V4L2_STD_NTSC) { adv7170_write_block(client, init_NTSC, sizeof(init_NTSC)); if (encoder->input == 0) adv7170_write(client, 0x02, 0x0e); // Enable genlock adv7170_write(client, 0x07, TR0MODE | TR0RST); adv7170_write(client, 0x07, TR0MODE); - break; - - case VIDEO_MODE_PAL: + } else if (iarg & V4L2_STD_PAL) { adv7170_write_block(client, init_PAL, sizeof(init_PAL)); if (encoder->input == 0) adv7170_write(client, 0x02, 0x0e); // Enable genlock adv7170_write(client, 0x07, TR0MODE | TR0RST); adv7170_write(client, 0x07, TR0MODE); - break; - - default: - v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg); + } else { + v4l_dbg(1, debug, client, "illegal norm: %llx\n", iarg); return -EINVAL; } - v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]); + v4l_dbg(1, debug, client, "switched to %llx\n", iarg); encoder->norm = iarg; break; } - case ENCODER_SET_INPUT: + case VIDIOC_INT_S_VIDEO_ROUTING: { - int iarg = *(int *) arg; + struct v4l2_routing *route = arg; /* RJ: *iarg = 0: input is from decoder *iarg = 1: input is from ZR36060 *iarg = 2: color bar */ v4l_dbg(1, debug, client, "set input from %s\n", - iarg == 0 ? "decoder" : "ZR36060"); + route->input == 0 ? "decoder" : "ZR36060"); - switch (iarg) { + switch (route->input) { case 0: adv7170_write(client, 0x01, 0x20); adv7170_write(client, 0x08, TR1CAPT); /* TR1 */ @@ -278,30 +260,11 @@ static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg) break; default: - v4l_dbg(1, debug, client, "illegal input: %d\n", iarg); - return -EINVAL; - } - v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]); - encoder->input = iarg; - break; - } - - case ENCODER_SET_OUTPUT: - { - int *iarg = arg; - - /* not much choice of outputs */ - if (*iarg != 0) { + v4l_dbg(1, debug, client, "illegal input: %d\n", route->input); return -EINVAL; } - break; - } - - case ENCODER_ENABLE_OUTPUT: - { - int *iarg = arg; - - encoder->enable = !!*iarg; + v4l_dbg(1, debug, client, "switched to %s\n", inputs[route->input]); + encoder->input = route->input; break; } @@ -338,9 +301,8 @@ static int adv7170_probe(struct i2c_client *client, encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL); if (encoder == NULL) return -ENOMEM; - encoder->norm = VIDEO_MODE_NTSC; + encoder->norm = V4L2_STD_NTSC; encoder->input = 0; - encoder->enable = 1; i2c_set_clientdata(client, encoder); i = adv7170_write_block(client, init_NTSC, sizeof(init_NTSC)); diff --git a/linux/drivers/media/video/adv7175.c b/linux/drivers/media/video/adv7175.c index 281a3f53c..11c92440e 100644 --- a/linux/drivers/media/video/adv7175.c +++ b/linux/drivers/media/video/adv7175.c @@ -47,9 +47,8 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); /* ----------------------------------------------------------------------- */ struct adv7175 { - int norm; + v4l2_std_id norm; int input; - int enable; int bright; int contrast; int hue; @@ -60,7 +59,6 @@ struct adv7175 { #define I2C_ADV7176 0x54 static char *inputs[] = { "pass_through", "play_back", "color_bar" }; -static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" }; /* ----------------------------------------------------------------------- */ @@ -190,7 +188,7 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) struct adv7175 *encoder = i2c_get_clientdata(client); switch (cmd) { - case 0: + case VIDIOC_INT_INIT: /* This is just for testing!!! */ adv7175_write_block(client, init_common, sizeof(init_common)); @@ -198,42 +196,25 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) adv7175_write(client, 0x07, TR0MODE); break; - case ENCODER_GET_CAPABILITIES: + case VIDIOC_INT_S_STD_OUTPUT: { - struct video_encoder_capability *cap = arg; + v4l2_std_id iarg = *(v4l2_std_id *) arg; - cap->flags = VIDEO_ENCODER_PAL | - VIDEO_ENCODER_NTSC | - VIDEO_ENCODER_SECAM; /* well, hacky */ - cap->inputs = 2; - cap->outputs = 1; - break; - } - - case ENCODER_SET_NORM: - { - int iarg = *(int *) arg; - - switch (iarg) { - case VIDEO_MODE_NTSC: + if (iarg & V4L2_STD_NTSC) { adv7175_write_block(client, init_ntsc, sizeof(init_ntsc)); if (encoder->input == 0) adv7175_write(client, 0x0d, 0x4f); // Enable genlock adv7175_write(client, 0x07, TR0MODE | TR0RST); adv7175_write(client, 0x07, TR0MODE); - break; - - case VIDEO_MODE_PAL: + } else if (iarg & V4L2_STD_PAL) { adv7175_write_block(client, init_pal, sizeof(init_pal)); if (encoder->input == 0) adv7175_write(client, 0x0d, 0x4f); // Enable genlock adv7175_write(client, 0x07, TR0MODE | TR0RST); adv7175_write(client, 0x07, TR0MODE); - break; - - case VIDEO_MODE_SECAM: // WARNING! ADV7176 does not support SECAM. + } else if (iarg & V4L2_STD_SECAM) { /* This is an attempt to convert * SECAM->PAL (typically it does not work * due to genlock: when decoder is in SECAM @@ -246,33 +227,32 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) adv7175_write(client, 0x0d, 0x49); // Disable genlock adv7175_write(client, 0x07, TR0MODE | TR0RST); adv7175_write(client, 0x07, TR0MODE); - break; - default: - v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg); + } else { + v4l_dbg(1, debug, client, "illegal norm: %llx\n", iarg); return -EINVAL; } - v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]); + v4l_dbg(1, debug, client, "switched to %llx\n", iarg); encoder->norm = iarg; break; } - case ENCODER_SET_INPUT: + case VIDIOC_INT_S_VIDEO_ROUTING: { - int iarg = *(int *) arg; + struct v4l2_routing *route = arg; /* RJ: *iarg = 0: input is from SAA7110 *iarg = 1: input is from ZR36060 *iarg = 2: color bar */ - switch (iarg) { + switch (route->input) { case 0: adv7175_write(client, 0x01, 0x00); - if (encoder->norm == VIDEO_MODE_NTSC) + if (encoder->norm & V4L2_STD_NTSC) set_subcarrier_freq(client, 1); adv7175_write(client, 0x0c, TR1CAPT); /* TR1 */ - if (encoder->norm == VIDEO_MODE_SECAM) + if (encoder->norm & V4L2_STD_SECAM) adv7175_write(client, 0x0d, 0x49); // Disable genlock else adv7175_write(client, 0x0d, 0x4f); // Enable genlock @@ -284,7 +264,7 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) case 1: adv7175_write(client, 0x01, 0x00); - if (encoder->norm == VIDEO_MODE_NTSC) + if (encoder->norm & V4L2_STD_NTSC) set_subcarrier_freq(client, 0); adv7175_write(client, 0x0c, TR1PLAY); /* TR1 */ @@ -297,7 +277,7 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) case 2: adv7175_write(client, 0x01, 0x80); - if (encoder->norm == VIDEO_MODE_NTSC) + if (encoder->norm & V4L2_STD_NTSC) set_subcarrier_freq(client, 0); adv7175_write(client, 0x0d, 0x49); @@ -307,29 +287,11 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) break; default: - v4l_dbg(1, debug, client, "illegal input: %d\n", iarg); + v4l_dbg(1, debug, client, "illegal input: %d\n", route->input); return -EINVAL; } - v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]); - encoder->input = iarg; - break; - } - - case ENCODER_SET_OUTPUT: - { - int *iarg = arg; - - /* not much choice of outputs */ - if (*iarg != 0) - return -EINVAL; - break; - } - - case ENCODER_ENABLE_OUTPUT: - { - int *iarg = arg; - - encoder->enable = !!*iarg; + v4l_dbg(1, debug, client, "switched to %s\n", inputs[route->input]); + encoder->input = route->input; break; } @@ -370,9 +332,8 @@ static int adv7175_probe(struct i2c_client *client, encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL); if (encoder == NULL) return -ENOMEM; - encoder->norm = VIDEO_MODE_PAL; + encoder->norm = V4L2_STD_NTSC; encoder->input = 0; - encoder->enable = 1; i2c_set_clientdata(client, encoder); i = adv7175_write_block(client, init_common, sizeof(init_common)); diff --git a/linux/drivers/media/video/bt819.c b/linux/drivers/media/video/bt819.c index 201dd9277..cd85ea462 100644 --- a/linux/drivers/media/video/bt819.c +++ b/linux/drivers/media/video/bt819.c @@ -55,7 +55,7 @@ struct bt819 { unsigned char reg[32]; int initialized; - int norm; + v4l2_std_id norm; int input; int enable; int bright; @@ -179,7 +179,7 @@ static int bt819_init(struct i2c_client *client) 0x1a, 0x80, /* 0x1a ADC Interface */ }; - struct timing *timing = &timing_data[decoder->norm]; + struct timing *timing = &timing_data[(decoder->norm & V4L2_STD_525_60) ? 1 : 0]; init[0x03 * 2 - 1] = (((timing->vdelay >> 8) & 0x03) << 6) | @@ -193,7 +193,7 @@ static int bt819_init(struct i2c_client *client) init[0x08 * 2 - 1] = timing->hscale >> 8; init[0x09 * 2 - 1] = timing->hscale & 0xff; /* 0x15 in array is address 0x19 */ - init[0x15 * 2 - 1] = (decoder->norm == 0) ? 115 : 93; /* Chroma burst delay */ + init[0x15 * 2 - 1] = (decoder->norm & V4L2_STD_625_50) ? 115 : 93; /* Chroma burst delay */ /* reset */ bt819_write(client, 0x1f, 0x00); mdelay(1); @@ -216,121 +216,93 @@ static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg) } switch (cmd) { - case 0: + case VIDIOC_INT_INIT: /* This is just for testing!!! */ bt819_init(client); break; - case DECODER_GET_CAPABILITIES: - { - struct video_decoder_capability *cap = arg; - - cap->flags = VIDEO_DECODER_PAL | - VIDEO_DECODER_NTSC | - VIDEO_DECODER_AUTO | - VIDEO_DECODER_CCIR; - cap->inputs = 8; - cap->outputs = 1; - break; - } - - case DECODER_GET_STATUS: - { + case VIDIOC_QUERYSTD: + case VIDIOC_INT_G_INPUT_STATUS: { int *iarg = arg; + v4l2_std_id *istd = arg; int status; - int res; + int res = V4L2_IN_ST_NO_SIGNAL; + v4l2_std_id std; status = bt819_read(client, 0x00); - res = 0; if ((status & 0x80)) - res |= DECODER_STATUS_GOOD; + res = 0; - switch (decoder->norm) { - case VIDEO_MODE_NTSC: - res |= DECODER_STATUS_NTSC; - break; - case VIDEO_MODE_PAL: - res |= DECODER_STATUS_PAL; - break; - default: - case VIDEO_MODE_AUTO: - if ((status & 0x10)) - res |= DECODER_STATUS_PAL; - else - res |= DECODER_STATUS_NTSC; - break; - } - res |= DECODER_STATUS_COLOR; - *iarg = res; + if ((status & 0x10)) + std = V4L2_STD_PAL; + else + std = V4L2_STD_NTSC; + if (cmd == VIDIOC_QUERYSTD) + *istd = std; + else + *iarg = res; v4l_dbg(1, debug, client, "get status %x\n", *iarg); break; } - case DECODER_SET_NORM: + case VIDIOC_S_STD: { - int *iarg = arg; + v4l2_std_id *iarg = arg; struct timing *timing = NULL; - v4l_dbg(1, debug, client, "set norm %x\n", *iarg); + v4l_dbg(1, debug, client, "set norm %llx\n", *iarg); - switch (*iarg) { - case VIDEO_MODE_NTSC: + if (*iarg & V4L2_STD_NTSC) { bt819_setbit(client, 0x01, 0, 1); bt819_setbit(client, 0x01, 1, 0); bt819_setbit(client, 0x01, 5, 0); bt819_write(client, 0x18, 0x68); bt819_write(client, 0x19, 0x5d); /* bt819_setbit(client, 0x1a, 5, 1); */ - timing = &timing_data[VIDEO_MODE_NTSC]; - break; - case VIDEO_MODE_PAL: + timing = &timing_data[1]; + } else if (*iarg & V4L2_STD_PAL) { bt819_setbit(client, 0x01, 0, 1); bt819_setbit(client, 0x01, 1, 1); bt819_setbit(client, 0x01, 5, 1); bt819_write(client, 0x18, 0x7f); bt819_write(client, 0x19, 0x72); /* bt819_setbit(client, 0x1a, 5, 0); */ - timing = &timing_data[VIDEO_MODE_PAL]; - break; - case VIDEO_MODE_AUTO: - bt819_setbit(client, 0x01, 0, 0); - bt819_setbit(client, 0x01, 1, 0); - break; - default: - v4l_dbg(1, debug, client, "unsupported norm %x\n", *iarg); + timing = &timing_data[0]; + } else { + v4l_dbg(1, debug, client, "unsupported norm %llx\n", *iarg); return -EINVAL; } - - if (timing) { - bt819_write(client, 0x03, - (((timing->vdelay >> 8) & 0x03) << 6) | - (((timing->vactive >> 8) & 0x03) << 4) | - (((timing->hdelay >> 8) & 0x03) << 2) | - ((timing->hactive >> 8) & 0x03) ); - bt819_write(client, 0x04, timing->vdelay & 0xff); - bt819_write(client, 0x05, timing->vactive & 0xff); - bt819_write(client, 0x06, timing->hdelay & 0xff); - bt819_write(client, 0x07, timing->hactive & 0xff); - bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff); - bt819_write(client, 0x09, timing->hscale & 0xff); - } - +/* case VIDEO_MODE_AUTO: + bt819_setbit(client, 0x01, 0, 0); + bt819_setbit(client, 0x01, 1, 0);*/ + + bt819_write(client, 0x03, + (((timing->vdelay >> 8) & 0x03) << 6) | + (((timing->vactive >> 8) & 0x03) << 4) | + (((timing->hdelay >> 8) & 0x03) << 2) | + ((timing->hactive >> 8) & 0x03)); + bt819_write(client, 0x04, timing->vdelay & 0xff); + bt819_write(client, 0x05, timing->vactive & 0xff); + bt819_write(client, 0x06, timing->hdelay & 0xff); + bt819_write(client, 0x07, timing->hactive & 0xff); + bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff); + bt819_write(client, 0x09, timing->hscale & 0xff); decoder->norm = *iarg; break; } - case DECODER_SET_INPUT: + case VIDIOC_INT_S_VIDEO_ROUTING: { - int *iarg = arg; + struct v4l2_routing *route = arg; - v4l_dbg(1, debug, client, "set input %x\n", *iarg); + v4l_dbg(1, debug, client, "set input %x\n", route->input); - if (*iarg < 0 || *iarg > 7) + if (route->input < 0 || route->input > 7) return -EINVAL; - if (decoder->input != *iarg) { - decoder->input = *iarg; + if (decoder->input != route->input) { + decoder->input = route->input; /* select mode */ if (decoder->input == 0) { bt819_setbit(client, 0x0b, 6, 0); @@ -343,75 +315,116 @@ static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg) break; } - case DECODER_SET_OUTPUT: + case VIDIOC_STREAMON: + case VIDIOC_STREAMOFF: { - int *iarg = arg; + int enable = cmd == VIDIOC_STREAMON; - v4l_dbg(1, debug, client, "set output %x\n", *iarg); + v4l_dbg(1, debug, client, "enable output %x\n", enable); - /* not much choice of outputs */ - if (*iarg != 0) - return -EINVAL; + if (decoder->enable != enable) { + decoder->enable = enable; + bt819_setbit(client, 0x16, 7, !enable); + } break; } - case DECODER_ENABLE_OUTPUT: + case VIDIOC_QUERYCTRL: { - int *iarg = arg; - int enable = (*iarg != 0); + struct v4l2_queryctrl *qc = arg; - v4l_dbg(1, debug, client, "enable output %x\n", *iarg); + switch (qc->id) { + case V4L2_CID_BRIGHTNESS: + v4l2_ctrl_query_fill(qc, -128, 127, 1, 0); + break; - if (decoder->enable != enable) { - decoder->enable = enable; - bt819_setbit(client, 0x16, 7, !enable); + case V4L2_CID_CONTRAST: + v4l2_ctrl_query_fill(qc, 0, 511, 1, 256); + break; + + case V4L2_CID_SATURATION: + v4l2_ctrl_query_fill(qc, 0, 511, 1, 256); + break; + + case V4L2_CID_HUE: + v4l2_ctrl_query_fill(qc, -128, 127, 1, 0); + break; + + default: + return -EINVAL; } break; } - case DECODER_SET_PICTURE: + case VIDIOC_S_CTRL: { - struct video_picture *pic = arg; + struct v4l2_control *ctrl = arg; - v4l_dbg(1, debug, client, - "set picture brightness %d contrast %d colour %d\n", - pic->brightness, pic->contrast, pic->colour); + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + if (decoder->bright != ctrl->value) { + decoder->bright = ctrl->value; + bt819_write(client, 0x0a, decoder->bright); + } + break; + case V4L2_CID_CONTRAST: + if (decoder->contrast != ctrl->value) { + decoder->contrast = ctrl->value; + bt819_write(client, 0x0c, + decoder->contrast & 0xff); + bt819_setbit(client, 0x0b, 2, + ((decoder->contrast >> 8) & 0x01)); + } + break; - if (decoder->bright != pic->brightness) { - /* We want -128 to 127 we get 0-65535 */ - decoder->bright = pic->brightness; - bt819_write(client, 0x0a, - (decoder->bright >> 8) - 128); - } + case V4L2_CID_SATURATION: + if (decoder->sat != ctrl->value) { + decoder->sat = ctrl->value; + bt819_write(client, 0x0d, + (decoder->sat >> 7) & 0xff); + bt819_setbit(client, 0x0b, 1, + ((decoder->sat >> 15) & 0x01)); + + /* Ratio between U gain and V gain must stay the same as + the ratio between the default U and V gain values. */ + temp = (decoder->sat * 180) / 254; + bt819_write(client, 0x0e, (temp >> 7) & 0xff); + bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01); + } + break; - if (decoder->contrast != pic->contrast) { - /* We want 0 to 511 we get 0-65535 */ - decoder->contrast = pic->contrast; - bt819_write(client, 0x0c, - (decoder->contrast >> 7) & 0xff); - bt819_setbit(client, 0x0b, 2, - ((decoder->contrast >> 15) & 0x01)); + case V4L2_CID_HUE: + if (decoder->hue != ctrl->value) { + decoder->hue = ctrl->value; + bt819_write(client, 0x0f, decoder->hue); + } + break; + default: + return -EINVAL; } + break; + } - if (decoder->sat != pic->colour) { - /* We want 0 to 511 we get 0-65535 */ - decoder->sat = pic->colour; - bt819_write(client, 0x0d, - (decoder->sat >> 7) & 0xff); - bt819_setbit(client, 0x0b, 1, - ((decoder->sat >> 15) & 0x01)); - - temp = (decoder->sat * 201) / 237; - bt819_write(client, 0x0e, (temp >> 7) & 0xff); - bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01); - } + case VIDIOC_G_CTRL: + { + struct v4l2_control *ctrl = arg; - if (decoder->hue != pic->hue) { - /* We want -128 to 127 we get 0-65535 */ - decoder->hue = pic->hue; - bt819_write(client, 0x0f, - 128 - (decoder->hue >> 8)); + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + ctrl->value = decoder->bright; + break; + case V4L2_CID_CONTRAST: + ctrl->value = decoder->contrast; + break; + case V4L2_CID_SATURATION: + ctrl->value = decoder->sat; + break; + case V4L2_CID_HUE: + ctrl->value = decoder->hue; + break; + default: + return -EINVAL; } break; } @@ -463,13 +476,13 @@ static int bt819_probe(struct i2c_client *client, decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL); if (decoder == NULL) return -ENOMEM; - decoder->norm = VIDEO_MODE_NTSC; + decoder->norm = V4L2_STD_NTSC; decoder->input = 0; decoder->enable = 1; - decoder->bright = 32768; - decoder->contrast = 32768; - decoder->hue = 32768; - decoder->sat = 32768; + decoder->bright = 0; + decoder->contrast = 0xd8; /* 100% of original signal */ + decoder->hue = 0; + decoder->sat = 0xfe; /* 100% of original signal */ decoder->initialized = 0; i2c_set_clientdata(client, decoder); diff --git a/linux/drivers/media/video/bt856.c b/linux/drivers/media/video/bt856.c index 89c4061c7..626019e49 100644 --- a/linux/drivers/media/video/bt856.c +++ b/linux/drivers/media/video/bt856.c @@ -56,8 +56,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); struct bt856 { unsigned char reg[BT856_NR_REG]; - int norm; - int enable; + v4l2_std_id norm; }; /* ----------------------------------------------------------------------- */ @@ -97,7 +96,7 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) struct bt856 *encoder = i2c_get_clientdata(client); switch (cmd) { - case 0: + case VIDIOC_INT_INIT: /* This is just for testing!!! */ v4l_dbg(1, debug, client, "init\n"); bt856_write(client, 0xdc, 0x18); @@ -108,15 +107,10 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) //bt856_setbit(client, 0xdc, 6, 0); bt856_setbit(client, 0xdc, 4, 1); - switch (encoder->norm) { - case VIDEO_MODE_NTSC: + if (encoder->norm & V4L2_STD_NTSC) bt856_setbit(client, 0xdc, 2, 0); - break; - - case VIDEO_MODE_PAL: + else bt856_setbit(client, 0xdc, 2, 1); - break; - } bt856_setbit(client, 0xdc, 1, 1); bt856_setbit(client, 0xde, 4, 0); @@ -125,38 +119,19 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) bt856_dump(client); break; - case ENCODER_GET_CAPABILITIES: + case VIDIOC_INT_S_STD_OUTPUT: { - struct video_encoder_capability *cap = arg; - - v4l_dbg(1, debug, client, "get capabilities\n"); + v4l2_std_id *iarg = arg; - cap->flags = VIDEO_ENCODER_PAL | - VIDEO_ENCODER_NTSC | - VIDEO_ENCODER_CCIR; - cap->inputs = 2; - cap->outputs = 1; - break; - } - - case ENCODER_SET_NORM: - { - int *iarg = arg; + v4l_dbg(1, debug, client, "set norm %llx\n", *iarg); - v4l_dbg(1, debug, client, "set norm %d\n", *iarg); - - switch (*iarg) { - case VIDEO_MODE_NTSC: + if (*iarg & V4L2_STD_NTSC) { bt856_setbit(client, 0xdc, 2, 0); - break; - - case VIDEO_MODE_PAL: + } else if (*iarg & V4L2_STD_PAL) { bt856_setbit(client, 0xdc, 2, 1); bt856_setbit(client, 0xda, 0, 0); //bt856_setbit(client, 0xda, 0, 1); - break; - - default: + } else { return -EINVAL; } encoder->norm = *iarg; @@ -165,16 +140,16 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) break; } - case ENCODER_SET_INPUT: + case VIDIOC_INT_S_VIDEO_ROUTING: { - int *iarg = arg; + struct v4l2_routing *route = arg; - v4l_dbg(1, debug, client, "set input %d\n", *iarg); + v4l_dbg(1, debug, client, "set input %d\n", route->input); /* We only have video bus. - * iarg = 0: input is from bt819 - * iarg = 1: input is from ZR36060 */ - switch (*iarg) { + * route->input= 0: input is from bt819 + * route->input= 1: input is from ZR36060 */ + switch (route->input) { case 0: bt856_setbit(client, 0xde, 4, 0); bt856_setbit(client, 0xde, 3, 1); @@ -200,28 +175,6 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) break; } - case ENCODER_SET_OUTPUT: - { - int *iarg = arg; - - v4l_dbg(1, debug, client, "set output %d\n", *iarg); - - /* not much choice of outputs */ - if (*iarg != 0) - return -EINVAL; - break; - } - - case ENCODER_ENABLE_OUTPUT: - { - int *iarg = arg; - - encoder->enable = !!*iarg; - - v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable); - break; - } - default: return -EINVAL; } @@ -250,8 +203,7 @@ static int bt856_probe(struct i2c_client *client, encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL); if (encoder == NULL) return -ENOMEM; - encoder->norm = VIDEO_MODE_NTSC; - encoder->enable = 1; + encoder->norm = V4L2_STD_NTSC; i2c_set_clientdata(client, encoder); bt856_write(client, 0xdc, 0x18); @@ -262,16 +214,10 @@ static int bt856_probe(struct i2c_client *client, //bt856_setbit(client, 0xdc, 6, 0); bt856_setbit(client, 0xdc, 4, 1); - switch (encoder->norm) { - - case VIDEO_MODE_NTSC: + if (encoder->norm & V4L2_STD_NTSC) bt856_setbit(client, 0xdc, 2, 0); - break; - - case VIDEO_MODE_PAL: + else bt856_setbit(client, 0xdc, 2, 1); - break; - } bt856_setbit(client, 0xdc, 1, 1); bt856_setbit(client, 0xde, 4, 0); diff --git a/linux/drivers/media/video/bt866.c b/linux/drivers/media/video/bt866.c index aaa985c8e..5aed3c7f1 100644 --- a/linux/drivers/media/video/bt866.c +++ b/linux/drivers/media/video/bt866.c @@ -53,8 +53,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); struct bt866 { u8 reg[256]; - int norm; - int enable; + v4l2_std_id norm; int bright; int contrast; int hue; @@ -95,44 +94,21 @@ static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) struct bt866 *encoder = i2c_get_clientdata(client); switch (cmd) { - case ENCODER_GET_CAPABILITIES: + case VIDIOC_INT_S_STD_OUTPUT: { - struct video_encoder_capability *cap = arg; + v4l2_std_id *iarg = arg; - v4l_dbg(1, debug, client, "get capabilities\n"); + v4l_dbg(1, debug, client, "set norm %llx\n", *iarg); - cap->flags - = VIDEO_ENCODER_PAL - | VIDEO_ENCODER_NTSC - | VIDEO_ENCODER_CCIR; - cap->inputs = 2; - cap->outputs = 1; - break; - } - - case ENCODER_SET_NORM: - { - int *iarg = arg; - - v4l_dbg(1, debug, client, "set norm %d\n", *iarg); - - switch (*iarg) { - case VIDEO_MODE_NTSC: - break; - - case VIDEO_MODE_PAL: - break; - - default: + if (!(*iarg & (V4L2_STD_NTSC | V4L2_STD_PAL))) return -EINVAL; - } encoder->norm = *iarg; break; } - case ENCODER_SET_INPUT: + case VIDIOC_INT_S_VIDEO_ROUTING: { - int *iarg = arg; + struct v4l2_routing *route = arg; static const __u8 init[] = { 0xc8, 0xcc, /* CRSCALE */ 0xca, 0x91, /* CBSCALE */ @@ -168,7 +144,7 @@ static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) val = encoder->reg[0xdc]; - if (*iarg == 0) + if (route->input == 0) val |= 0x40; /* CBSWAP */ else val &= ~0x40; /* !CBSWAP */ @@ -176,15 +152,15 @@ static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) bt866_write(client, 0xdc, val); val = encoder->reg[0xcc]; - if (*iarg == 2) + if (route->input == 2) val |= 0x01; /* OSDBAR */ else val &= ~0x01; /* !OSDBAR */ bt866_write(client, 0xcc, val); - v4l_dbg(1, debug, client, "set input %d\n", *iarg); + v4l_dbg(1, debug, client, "set input %d\n", route->input); - switch (*iarg) { + switch (route->input) { case 0: break; case 1: @@ -195,27 +171,6 @@ static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) break; } - case ENCODER_SET_OUTPUT: - { - int *iarg = arg; - - v4l_dbg(1, debug, client, "set output %d\n", *iarg); - - /* not much choice of outputs */ - if (*iarg != 0) - return -EINVAL; - break; - } - - case ENCODER_ENABLE_OUTPUT: - { - int *iarg = arg; - encoder->enable = !!*iarg; - - v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable); - break; - } - case 4711: { int *iarg = arg; diff --git a/linux/drivers/media/video/ks0127.c b/linux/drivers/media/video/ks0127.c index 16526165b..3b565c039 100644 --- a/linux/drivers/media/video/ks0127.c +++ b/linux/drivers/media/video/ks0127.c @@ -202,7 +202,7 @@ struct ks0127 { int format_height; int cap_width; int cap_height; - int norm; + v4l2_std_id norm; int ks_type; u8 regs[256]; }; @@ -409,20 +409,22 @@ static void ks0127_reset(struct i2c_client *c) static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) { struct ks0127 *ks = i2c_get_clientdata(c); + struct v4l2_routing *route = arg; int *iarg = (int *)arg; + v4l2_std_id *istd = arg; int status; if (!ks) return -ENODEV; switch (cmd) { - case DECODER_INIT: - v4l_dbg(1, debug, c, "DECODER_INIT\n"); + case VIDIOC_INT_INIT: + v4l_dbg(1, debug, c, "VIDIOC_INT_INIT\n"); ks0127_reset(c); break; - case DECODER_SET_INPUT: - switch(*iarg) { + case VIDIOC_INT_S_VIDEO_ROUTING: + switch (route->input) { case KS_INPUT_COMPOSITE_1: case KS_INPUT_COMPOSITE_2: case KS_INPUT_COMPOSITE_3: @@ -430,7 +432,7 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) case KS_INPUT_COMPOSITE_5: case KS_INPUT_COMPOSITE_6: v4l_dbg(1, debug, c, - "DECODER_SET_INPUT %d: Composite\n", *iarg); + "VIDIOC_S_INPUT %d: Composite\n", *iarg); /* autodetect 50/60 Hz */ ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); /* VSE=0 */ @@ -464,7 +466,7 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) case KS_INPUT_SVIDEO_2: case KS_INPUT_SVIDEO_3: v4l_dbg(1, debug, c, - "DECODER_SET_INPUT %d: S-Video\n", *iarg); + "VIDIOC_S_INPUT %d: S-Video\n", *iarg); /* autodetect 50/60 Hz */ ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); /* VSE=0 */ @@ -496,9 +498,8 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) case KS_INPUT_YUV656: v4l_dbg(1, debug, c, - "DECODER_SET_INPUT 15: YUV656\n"); - if (ks->norm == VIDEO_MODE_NTSC || - ks->norm == KS_STD_PAL_M) + "VIDIOC_S_INPUT 15: YUV656\n"); + if (ks->norm & V4L2_STD_525_60) /* force 60 Hz */ ks0127_and_or(c, KS_CMDA, 0xfc, 0x03); else @@ -542,7 +543,7 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) default: v4l_dbg(1, debug, c, - "DECODER_SET_INPUT: Unknown input %d\n", *iarg); + "VIDIOC_INT_S_VIDEO_ROUTING: Unknown input %d\n", route->input); break; } @@ -551,33 +552,18 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) ks0127_write(c, KS_DEMOD, reg_defaults[KS_DEMOD]); break; - case DECODER_SET_OUTPUT: - switch(*iarg) { - case KS_OUTPUT_YUV656E: - v4l_dbg(1, debug, c, - "DECODER_SET_OUTPUT: OUTPUT_YUV656E (Missing)\n"); - return -EINVAL; - - case KS_OUTPUT_EXV: - v4l_dbg(1, debug, c, - "DECODER_SET_OUTPUT: OUTPUT_EXV\n"); - ks0127_and_or(c, KS_OFMTA, 0xf0, 0x09); - break; - } - break; - - case DECODER_SET_NORM: /* sam This block mixes old and new norm names... */ + case VIDIOC_S_STD: /* sam This block mixes old and new norm names... */ /* Set to automatic SECAM/Fsc mode */ ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00); - ks->norm = *iarg; - switch (*iarg) { + ks->norm = *istd; +#if 0 /* this is untested !! */ /* It just detects PAL_N/NTSC_M (no special frequencies) */ /* And you have to set the standard a second time afterwards */ case VIDEO_MODE_AUTO: v4l_dbg(1, debug, c, - "DECODER_SET_NORM: AUTO\n"); + "VIDIOC_S_STD: AUTO\n"); /* The chip determines the format */ /* based on the current field rate */ @@ -588,40 +574,33 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) ks->format_height = 240; ks->format_width = 704; break; +#endif - case VIDEO_MODE_NTSC: + if (*istd & V4L2_STD_NTSC) { v4l_dbg(1, debug, c, - "DECODER_SET_NORM: NTSC_M\n"); + "VIDIOC_S_STD: NTSC_M\n"); ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); ks->format_height = 240; ks->format_width = 704; - break; - - case KS_STD_NTSC_N: + } else if (*istd & V4L2_STD_PAL_N) { v4l_dbg(1, debug, c, "KS0127_SET_NORM: NTSC_N (fixme)\n"); ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40); ks->format_height = 240; ks->format_width = 704; - break; - - case VIDEO_MODE_PAL: + } else if (*istd & V4L2_STD_PAL) { v4l_dbg(1, debug, c, - "DECODER_SET_NORM: PAL_N\n"); + "VIDIOC_S_STD: PAL_N\n"); ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); ks->format_height = 290; ks->format_width = 704; - break; - - case KS_STD_PAL_M: + } else if (*istd & V4L2_STD_PAL_M) { v4l_dbg(1, debug, c, "KS0127_SET_NORM: PAL_M (fixme)\n"); ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40); ks->format_height = 290; ks->format_width = 704; - break; - - case VIDEO_MODE_SECAM: + } else if (*istd & V4L2_STD_SECAM) { v4l_dbg(1, debug, c, "KS0127_SET_NORM: SECAM\n"); ks->format_height = 290; @@ -633,29 +612,34 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) schedule_timeout_interruptible(HZ/10+1); /* did it autodetect? */ - if (ks0127_read(c, KS_DEMOD) & 0x40) - break; - - /* force to secam mode */ - ks0127_and_or(c, KS_DEMOD, 0xf0, 0x0f); - break; - - default: + if (!(ks0127_read(c, KS_DEMOD) & 0x40)) + /* force to secam mode */ + ks0127_and_or(c, KS_DEMOD, 0xf0, 0x0f); + } else { v4l_dbg(1, debug, c, - "DECODER_SET_NORM: Unknown norm %d\n", *iarg); - break; + "VIDIOC_S_STD: Unknown norm %llx\n", *istd); } break; - case DECODER_SET_PICTURE: + case VIDIOC_QUERYCTRL: + { + return -EINVAL; + } + + case VIDIOC_S_CTRL: v4l_dbg(1, debug, c, - "DECODER_SET_PICTURE: not yet supported\n"); + "VIDIOC_S_CTRL: not yet supported\n"); return -EINVAL; - /* sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE */ - /* sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE */ - /* sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? */ - /* sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE */ + case VIDIOC_G_CTRL: + v4l_dbg(1, debug, c, + "VIDIOC_G_CTRL: not yet supported\n"); + return -EINVAL; + + /* sam todo: KS0127_SET_BRIGHTNESS: Merge into VIDIOC_S_CTRL */ + /* sam todo: KS0127_SET_CONTRAST: Merge into VIDIOC_S_CTRL */ + /* sam todo: KS0127_SET_HUE: Merge into VIDIOC_S_CTRL? */ + /* sam todo: KS0127_SET_SATURATION: Merge into VIDIOC_S_CTRL */ /* sam todo: KS0127_SET_AGC_MODE: */ /* sam todo: KS0127_SET_AGC: */ /* sam todo: KS0127_SET_CHROMA_MODE: */ @@ -671,22 +655,21 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) /* sam todo: KS0127_SET_UNUSEV: */ /* sam todo: KS0127_SET_VSALIGN_MODE: */ - case DECODER_ENABLE_OUTPUT: + case VIDIOC_STREAMON: + case VIDIOC_STREAMOFF: { - int enable; + int enable = cmd == VIDIOC_STREAMON; - iarg = arg; - enable = (*iarg != 0); if (enable) { v4l_dbg(1, debug, c, - "DECODER_ENABLE_OUTPUT on\n"); + "VIDIOC_STREAMON\n"); /* All output pins on */ ks0127_and_or(c, KS_OFMTA, 0xcf, 0x30); /* Obey the OEN pin */ ks0127_and_or(c, KS_CDEM, 0x7f, 0x00); } else { v4l_dbg(1, debug, c, - "DECODER_ENABLE_OUTPUT off\n"); + "VIDIOC_STREAMOFF\n"); /* Video output pins off */ ks0127_and_or(c, KS_OFMTA, 0xcf, 0x00); /* Ignore the OEN pin */ @@ -700,19 +683,26 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) /* sam todo: KS0127_SET_HEIGHT: */ /* sam todo: KS0127_SET_HSCALE: */ - case DECODER_GET_STATUS: - v4l_dbg(1, debug, c, "DECODER_GET_STATUS\n"); - *iarg = 0; + case VIDIOC_QUERYSTD: + case VIDIOC_INT_G_INPUT_STATUS: { + int stat = V4L2_IN_ST_NO_SIGNAL; + v4l2_std_id std = V4L2_STD_ALL; + v4l_dbg(1, debug, c, "VIDIOC_QUERYSTD/VIDIOC_INT_G_INPUT_STATUS\n"); status = ks0127_read(c, KS_STAT); if (!(status & 0x20)) /* NOVID not set */ - *iarg = (*iarg | DECODER_STATUS_GOOD); - if ((status & 0x01)) /* CLOCK set */ - *iarg = (*iarg | DECODER_STATUS_COLOR); + stat = 0; + if (!(status & 0x01)) /* CLOCK set */ + stat |= V4L2_IN_ST_NO_COLOR; if ((status & 0x08)) /* PALDET set */ - *iarg = (*iarg | DECODER_STATUS_PAL); + std = V4L2_STD_PAL; + else + std = V4L2_STD_NTSC; + if (cmd == VIDIOC_QUERYSTD) + *istd = std; else - *iarg = (*iarg | DECODER_STATUS_NTSC); + *iarg = stat; break; + } /* Catch any unknown command */ default: diff --git a/linux/drivers/media/video/saa7110.c b/linux/drivers/media/video/saa7110.c index b7afe3124..147c36a71 100644 --- a/linux/drivers/media/video/saa7110.c +++ b/linux/drivers/media/video/saa7110.c @@ -55,7 +55,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); struct saa7110 { u8 reg[SAA7110_NR_REG]; - int norm; + v4l2_std_id norm; int input; int enable; int bright; @@ -177,7 +177,7 @@ static const unsigned char initseq[1 + SAA7110_NR_REG] = { /* 0x30 */ 0x44, 0x71, 0x02, 0x8C, 0x02 }; -static int determine_norm(struct i2c_client *client) +static v4l2_std_id determine_norm(struct i2c_client *client) { DEFINE_WAIT(wait); struct saa7110 *decoder = i2c_get_clientdata(client); @@ -199,11 +199,11 @@ static int determine_norm(struct i2c_client *client) if (status & 0x20) { v4l_dbg(1, debug, client, "status=0x%02x (NTSC/no color)\n", status); //saa7110_write(client,0x2E,0x81); - return VIDEO_MODE_NTSC; + return V4L2_STD_NTSC; } v4l_dbg(1, debug, client, "status=0x%02x (PAL/no color)\n", status); //saa7110_write(client,0x2E,0x9A); - return VIDEO_MODE_PAL; + return V4L2_STD_PAL; } //saa7110_write(client,0x06,0x03); if (status & 0x20) { /* 60Hz */ @@ -212,7 +212,7 @@ static int determine_norm(struct i2c_client *client) saa7110_write(client, 0x0F, 0x50); saa7110_write(client, 0x11, 0x2C); //saa7110_write(client,0x2E,0x81); - return VIDEO_MODE_NTSC; + return V4L2_STD_NTSC; } /* 50Hz -> PAL/SECAM */ @@ -229,10 +229,10 @@ static int determine_norm(struct i2c_client *client) if ((status & 0x03) == 0x01) { v4l_dbg(1, debug, client, "status=0x%02x (SECAM)\n", status); saa7110_write(client, 0x0D, 0x87); - return VIDEO_MODE_SECAM; + return V4L2_STD_SECAM; } v4l_dbg(1, debug, client, "status=0x%02x (PAL)\n", status); - return VIDEO_MODE_PAL; + return V4L2_STD_PAL; } static int @@ -241,112 +241,81 @@ saa7110_command (struct i2c_client *client, void *arg) { struct saa7110 *decoder = i2c_get_clientdata(client); + struct v4l2_routing *route = arg; + v4l2_std_id std; int v; switch (cmd) { - case 0: + case VIDIOC_INT_INIT: //saa7110_write_block(client, initseq, sizeof(initseq)); break; - case DECODER_GET_CAPABILITIES: - { - struct video_decoder_capability *dc = arg; - - dc->flags = - VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC | - VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO; - dc->inputs = SAA7110_MAX_INPUT; - dc->outputs = SAA7110_MAX_OUTPUT; - break; - } - - case DECODER_GET_STATUS: + case VIDIOC_INT_G_INPUT_STATUS: { + int res = V4L2_IN_ST_NO_SIGNAL; int status; - int res = 0; status = saa7110_read(client); - v4l_dbg(1, debug, client, "status=0x%02x norm=%d\n", + v4l_dbg(1, debug, client, "status=0x%02x norm=%llx\n", status, decoder->norm); if (!(status & 0x40)) - res |= DECODER_STATUS_GOOD; - if (status & 0x03) - res |= DECODER_STATUS_COLOR; + res = 0; + if (!(status & 0x03)) + res |= V4L2_IN_ST_NO_COLOR; - switch (decoder->norm) { - case VIDEO_MODE_NTSC: - res |= DECODER_STATUS_NTSC; - break; - case VIDEO_MODE_PAL: - res |= DECODER_STATUS_PAL; - break; - case VIDEO_MODE_SECAM: - res |= DECODER_STATUS_SECAM; - break; - } *(int *) arg = res; break; } - case DECODER_SET_NORM: - v = *(int *) arg; - if (decoder->norm != v) { - decoder->norm = v; + case VIDIOC_QUERYSTD: + { + *(v4l2_std_id *)arg = determine_norm(client); + break; + } + + case VIDIOC_S_STD: + std = *(v4l2_std_id *) arg; + if (decoder->norm != std) { + decoder->norm = std; //saa7110_write(client, 0x06, 0x03); - switch (v) { - case VIDEO_MODE_NTSC: + if (std & V4L2_STD_NTSC) { saa7110_write(client, 0x0D, 0x86); saa7110_write(client, 0x0F, 0x50); saa7110_write(client, 0x11, 0x2C); //saa7110_write(client, 0x2E, 0x81); v4l_dbg(1, debug, client, "switched to NTSC\n"); - break; - case VIDEO_MODE_PAL: + } else if (std & V4L2_STD_PAL) { saa7110_write(client, 0x0D, 0x86); saa7110_write(client, 0x0F, 0x10); saa7110_write(client, 0x11, 0x59); //saa7110_write(client, 0x2E, 0x9A); v4l_dbg(1, debug, client, "switched to PAL\n"); - break; - case VIDEO_MODE_SECAM: + } else if (std & V4L2_STD_SECAM) { saa7110_write(client, 0x0D, 0x87); saa7110_write(client, 0x0F, 0x10); saa7110_write(client, 0x11, 0x59); //saa7110_write(client, 0x2E, 0x9A); v4l_dbg(1, debug, client, "switched to SECAM\n"); - break; - case VIDEO_MODE_AUTO: - v4l_dbg(1, debug, client, "switched to AUTO\n"); - decoder->norm = determine_norm(client); - *(int *) arg = decoder->norm; - break; - default: - return -EPERM; + } else { + return -EINVAL; } } break; - case DECODER_SET_INPUT: - v = *(int *) arg; - if (v < 0 || v >= SAA7110_MAX_INPUT) { - v4l_dbg(1, debug, client, "input=%d not available\n", v); + case VIDIOC_INT_S_VIDEO_ROUTING: + if (route->input < 0 || route->input >= SAA7110_MAX_INPUT) { + v4l_dbg(1, debug, client, "input=%d not available\n", route->input); return -EINVAL; } - if (decoder->input != v) { - saa7110_selmux(client, v); - v4l_dbg(1, debug, client, "switched to input=%d\n", v); + if (decoder->input != route->input) { + saa7110_selmux(client, route->input); + v4l_dbg(1, debug, client, "switched to input=%d\n", route->input); } break; - case DECODER_SET_OUTPUT: - v = *(int *) arg; - /* not much choice of outputs */ - if (v != 0) - return -EINVAL; - break; - - case DECODER_ENABLE_OUTPUT: - v = *(int *) arg; + case VIDIOC_STREAMON: + case VIDIOC_STREAMOFF: + v = cmd == VIDIOC_STREAMON; if (decoder->enable != v) { decoder->enable = v; saa7110_write(client, 0x0E, v ? 0x18 : 0x80); @@ -354,46 +323,79 @@ saa7110_command (struct i2c_client *client, } break; - case DECODER_SET_PICTURE: + case VIDIOC_QUERYCTRL: { - struct video_picture *pic = arg; - - if (decoder->bright != pic->brightness) { - /* We want 0 to 255 we get 0-65535 */ - decoder->bright = pic->brightness; - saa7110_write(client, 0x19, decoder->bright >> 8); - } - if (decoder->contrast != pic->contrast) { - /* We want 0 to 127 we get 0-65535 */ - decoder->contrast = pic->contrast; - saa7110_write(client, 0x13, - decoder->contrast >> 9); - } - if (decoder->sat != pic->colour) { - /* We want 0 to 127 we get 0-65535 */ - decoder->sat = pic->colour; - saa7110_write(client, 0x12, decoder->sat >> 9); + struct v4l2_queryctrl *qc = arg; + + switch (qc->id) { + case V4L2_CID_BRIGHTNESS: + case V4L2_CID_CONTRAST: + case V4L2_CID_SATURATION: + case V4L2_CID_HUE: + return v4l2_ctrl_query_fill_std(qc); + default: + return -EINVAL; } - if (decoder->hue != pic->hue) { - /* We want -128 to 127 we get 0-65535 */ - decoder->hue = pic->hue; - saa7110_write(client, 0x07, - (decoder->hue >> 8) - 128); + break; + } + + case VIDIOC_G_CTRL: + { + struct v4l2_control *ctrl = arg; + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + ctrl->value = decoder->bright; + break; + case V4L2_CID_CONTRAST: + ctrl->value = decoder->contrast; + break; + case V4L2_CID_SATURATION: + ctrl->value = decoder->sat; + break; + case V4L2_CID_HUE: + ctrl->value = decoder->hue; + break; + default: + return -EINVAL; } break; } - case DECODER_DUMP: - if (!debug) + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl = arg; + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + if (decoder->bright != ctrl->value) { + decoder->bright = ctrl->value; + saa7110_write(client, 0x19, decoder->bright); + } break; - for (v = 0; v < SAA7110_NR_REG; v += 16) { - int j; - v4l_dbg(1, debug, client, "%02x:", v); - for (j = 0; j < 16 && v + j < SAA7110_NR_REG; j++) - printk(KERN_CONT " %02x", decoder->reg[v + j]); - printk(KERN_CONT "\n"); + case V4L2_CID_CONTRAST: + if (decoder->contrast != ctrl->value) { + decoder->contrast = ctrl->value; + saa7110_write(client, 0x13, decoder->contrast); + } + break; + case V4L2_CID_SATURATION: + if (decoder->sat != ctrl->value) { + decoder->sat = ctrl->value; + saa7110_write(client, 0x12, decoder->sat); + } + break; + case V4L2_CID_HUE: + if (decoder->hue != ctrl->value) { + decoder->hue = ctrl->value; + saa7110_write(client, 0x07, decoder->hue); + } + break; + default: + return -EINVAL; } break; + } default: v4l_dbg(1, debug, client, "unknown command %08x\n", cmd); @@ -430,7 +432,7 @@ static int saa7110_probe(struct i2c_client *client, decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL); if (!decoder) return -ENOMEM; - decoder->norm = VIDEO_MODE_PAL; + decoder->norm = V4L2_STD_PAL; decoder->input = 0; decoder->enable = 1; decoder->bright = 32768; diff --git a/linux/drivers/media/video/saa7111.c b/linux/drivers/media/video/saa7111.c deleted file mode 100644 index 94e5d0b4e..000000000 --- a/linux/drivers/media/video/saa7111.c +++ /dev/null @@ -1,497 +0,0 @@ -/* - * saa7111 - Philips SAA7111A video decoder driver version 0.0.3 - * - * Copyright (C) 1998 Dave Perks - * - * Slight changes for video timing and attachment output by - * Wolfgang Scherr - * - * Changes by Ronald Bultje - * - moved over to linux>=2.4.x i2c protocol (1/1/2003) - * - * Changes by Michael Hunold - * - implemented DECODER_SET_GPIO, DECODER_INIT, DECODER_SET_VBI_BYPASS - * - * 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 -#include -#include -#include -#include "compat.h" - -MODULE_DESCRIPTION("Philips SAA7111 video decoder driver"); -MODULE_AUTHOR("Dave Perks"); -MODULE_LICENSE("GPL"); - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Debug level (0-1)"); - -/* ----------------------------------------------------------------------- */ - -#define SAA7111_NR_REG 0x18 - -struct saa7111 { - unsigned char reg[SAA7111_NR_REG]; - - int norm; - int input; - int enable; -}; - -/* ----------------------------------------------------------------------- */ - -static inline int saa7111_write(struct i2c_client *client, u8 reg, u8 value) -{ - struct saa7111 *decoder = i2c_get_clientdata(client); - - decoder->reg[reg] = value; - return i2c_smbus_write_byte_data(client, reg, value); -} - -static inline void saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value) -{ - struct saa7111 *decoder = i2c_get_clientdata(client); - - if (decoder->reg[reg] != value) { - decoder->reg[reg] = value; - i2c_smbus_write_byte_data(client, reg, value); - } -} - -static int saa7111_write_block(struct i2c_client *client, const u8 *data, unsigned int len) -{ - int ret = -1; - u8 reg; - - /* the saa7111 has an autoincrement function, use it if - * the adapter understands raw I2C */ - if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - /* do raw I2C, not smbus compatible */ - struct saa7111 *decoder = i2c_get_clientdata(client); - u8 block_data[32]; - int block_len; - - while (len >= 2) { - block_len = 0; - block_data[block_len++] = reg = data[0]; - do { - block_data[block_len++] = - decoder->reg[reg++] = data[1]; - len -= 2; - data += 2; - } while (len >= 2 && data[0] == reg && block_len < 32); - ret = i2c_master_send(client, block_data, block_len); - if (ret < 0) - break; - } - } else { - /* do some slow I2C emulation kind of thing */ - while (len >= 2) { - reg = *data++; - ret = saa7111_write(client, reg, *data++); - if (ret < 0) - break; - len -= 2; - } - } - - return ret; -} - -static int saa7111_init_decoder(struct i2c_client *client, - struct video_decoder_init *init) -{ - return saa7111_write_block(client, init->data, init->len); -} - -static inline int saa7111_read(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_byte_data(client, reg); -} - -/* ----------------------------------------------------------------------- */ - -static const unsigned char saa7111_i2c_init[] = { - 0x00, 0x00, /* 00 - ID byte */ - 0x01, 0x00, /* 01 - reserved */ - - /*front end */ - 0x02, 0xd0, /* 02 - FUSE=3, GUDL=2, MODE=0 */ - 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, - * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */ - 0x04, 0x00, /* 04 - GAI1=256 */ - 0x05, 0x00, /* 05 - GAI2=256 */ - - /* decoder */ - 0x06, 0xf3, /* 06 - HSB at 13(50Hz) / 17(60Hz) - * pixels after end of last line */ - /*0x07, 0x13, * 07 - HSS at 113(50Hz) / 117(60Hz) pixels - * after end of last line */ - 0x07, 0xe8, /* 07 - HSS seems to be needed to - * work with NTSC, too */ - 0x08, 0xc8, /* 08 - AUFD=1, FSEL=1, EXFIL=0, - * VTRC=1, HPLL=0, VNOI=0 */ - 0x09, 0x01, /* 09 - BYPS=0, PREF=0, BPSS=0, - * VBLB=0, UPTCV=0, APER=1 */ - 0x0a, 0x80, /* 0a - BRIG=128 */ - 0x0b, 0x47, /* 0b - CONT=1.109 */ - 0x0c, 0x40, /* 0c - SATN=1.0 */ - 0x0d, 0x00, /* 0d - HUE=0 */ - 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0, - * FCTC=0, CHBW=1 */ - 0x0f, 0x00, /* 0f - reserved */ - 0x10, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */ - 0x11, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1, - * OEYC=1, OEHV=1, VIPB=0, COLO=0 */ - 0x12, 0x00, /* 12 - output control 2 */ - 0x13, 0x00, /* 13 - output control 3 */ - 0x14, 0x00, /* 14 - reserved */ - 0x15, 0x00, /* 15 - VBI */ - 0x16, 0x00, /* 16 - VBI */ - 0x17, 0x00, /* 17 - VBI */ -}; - -static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg) -{ - struct saa7111 *decoder = i2c_get_clientdata(client); - - switch (cmd) { - case 0: - break; - case DECODER_INIT: - { - struct video_decoder_init *init = arg; - struct video_decoder_init vdi; - - if (NULL != init) - return saa7111_init_decoder(client, init); - vdi.data = saa7111_i2c_init; - vdi.len = sizeof(saa7111_i2c_init); - return saa7111_init_decoder(client, &vdi); - } - - case DECODER_DUMP: - { - int i; - - for (i = 0; i < SAA7111_NR_REG; i += 16) { - int j; - - v4l_info(client, "%03x", i); - for (j = 0; j < 16 && i + j < SAA7111_NR_REG; ++j) { - printk(KERN_CONT " %02x", - saa7111_read(client, i + j)); - } - printk(KERN_CONT "\n"); - } - break; - } - - case DECODER_GET_CAPABILITIES: - { - struct video_decoder_capability *cap = arg; - - cap->flags = VIDEO_DECODER_PAL | - VIDEO_DECODER_NTSC | - VIDEO_DECODER_SECAM | - VIDEO_DECODER_AUTO | - VIDEO_DECODER_CCIR; - cap->inputs = 8; - cap->outputs = 1; - break; - } - - case DECODER_GET_STATUS: - { - int *iarg = arg; - int status; - int res; - - status = saa7111_read(client, 0x1f); - v4l_dbg(1, debug, client, "status: 0x%02x\n", status); - res = 0; - if ((status & (1 << 6)) == 0) { - res |= DECODER_STATUS_GOOD; - } - switch (decoder->norm) { - case VIDEO_MODE_NTSC: - res |= DECODER_STATUS_NTSC; - break; - case VIDEO_MODE_PAL: - res |= DECODER_STATUS_PAL; - break; - case VIDEO_MODE_SECAM: - res |= DECODER_STATUS_SECAM; - break; - default: - case VIDEO_MODE_AUTO: - if ((status & (1 << 5)) != 0) { - res |= DECODER_STATUS_NTSC; - } else { - res |= DECODER_STATUS_PAL; - } - break; - } - if ((status & (1 << 0)) != 0) { - res |= DECODER_STATUS_COLOR; - } - *iarg = res; - break; - } - - case DECODER_SET_GPIO: - { - int *iarg = arg; - if (0 != *iarg) { - saa7111_write(client, 0x11, - (decoder->reg[0x11] | 0x80)); - } else { - saa7111_write(client, 0x11, - (decoder->reg[0x11] & 0x7f)); - } - break; - } - - case DECODER_SET_VBI_BYPASS: - { - int *iarg = arg; - if (0 != *iarg) { - saa7111_write(client, 0x13, - (decoder->reg[0x13] & 0xf0) | 0x0a); - } else { - saa7111_write(client, 0x13, - (decoder->reg[0x13] & 0xf0)); - } - break; - } - - case DECODER_SET_NORM: - { - int *iarg = arg; - - switch (*iarg) { - - case VIDEO_MODE_NTSC: - saa7111_write(client, 0x08, - (decoder->reg[0x08] & 0x3f) | 0x40); - saa7111_write(client, 0x0e, - (decoder->reg[0x0e] & 0x8f)); - break; - - case VIDEO_MODE_PAL: - saa7111_write(client, 0x08, - (decoder->reg[0x08] & 0x3f) | 0x00); - saa7111_write(client, 0x0e, - (decoder->reg[0x0e] & 0x8f)); - break; - - case VIDEO_MODE_SECAM: - saa7111_write(client, 0x08, - (decoder->reg[0x08] & 0x3f) | 0x00); - saa7111_write(client, 0x0e, - (decoder->reg[0x0e] & 0x8f) | 0x50); - break; - - case VIDEO_MODE_AUTO: - saa7111_write(client, 0x08, - (decoder->reg[0x08] & 0x3f) | 0x80); - saa7111_write(client, 0x0e, - (decoder->reg[0x0e] & 0x8f)); - break; - - default: - return -EINVAL; - - } - decoder->norm = *iarg; - break; - } - - case DECODER_SET_INPUT: - { - int *iarg = arg; - - if (*iarg < 0 || *iarg > 7) { - return -EINVAL; - } - - if (decoder->input != *iarg) { - decoder->input = *iarg; - /* select mode */ - saa7111_write(client, 0x02, - (decoder-> - reg[0x02] & 0xf8) | decoder->input); - /* bypass chrominance trap for modes 4..7 */ - saa7111_write(client, 0x09, - (decoder-> - reg[0x09] & 0x7f) | ((decoder-> - input > - 3) ? 0x80 : - 0)); - } - break; - } - - case DECODER_SET_OUTPUT: - { - int *iarg = arg; - - /* not much choice of outputs */ - if (*iarg != 0) { - return -EINVAL; - } - break; - } - - case DECODER_ENABLE_OUTPUT: - { - int *iarg = arg; - int enable = (*iarg != 0); - - if (decoder->enable != enable) { - decoder->enable = enable; - - /* RJ: If output should be disabled (for - * playing videos), we also need a open PLL. - * The input is set to 0 (where no input - * source is connected), although this - * is not necessary. - * - * If output should be enabled, we have to - * reverse the above. - */ - - if (decoder->enable) { - saa7111_write(client, 0x02, - (decoder-> - reg[0x02] & 0xf8) | - decoder->input); - saa7111_write(client, 0x08, - (decoder->reg[0x08] & 0xfb)); - saa7111_write(client, 0x11, - (decoder-> - reg[0x11] & 0xf3) | 0x0c); - } else { - saa7111_write(client, 0x02, - (decoder->reg[0x02] & 0xf8)); - saa7111_write(client, 0x08, - (decoder-> - reg[0x08] & 0xfb) | 0x04); - saa7111_write(client, 0x11, - (decoder->reg[0x11] & 0xf3)); - } - } - break; - } - - case DECODER_SET_PICTURE: - { - struct video_picture *pic = arg; - - /* We want 0 to 255 we get 0-65535 */ - saa7111_write_if_changed(client, 0x0a, pic->brightness >> 8); - /* We want 0 to 127 we get 0-65535 */ - saa7111_write(client, 0x0b, pic->contrast >> 9); - /* We want 0 to 127 we get 0-65535 */ - saa7111_write(client, 0x0c, pic->colour >> 9); - /* We want -128 to 127 we get 0-65535 */ - saa7111_write(client, 0x0d, (pic->hue - 32768) >> 8); - break; - } - - default: - return -EINVAL; - } - - return 0; -} - -/* ----------------------------------------------------------------------- */ - -static unsigned short normal_i2c[] = { 0x48 >> 1, I2C_CLIENT_END }; - -I2C_CLIENT_INSMOD; - -static int saa7111_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int i; - struct saa7111 *decoder; - struct video_decoder_init vdi; - - /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return -ENODEV; - - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); - - decoder = kzalloc(sizeof(struct saa7111), GFP_KERNEL); - if (decoder == NULL) { - kfree(client); - return -ENOMEM; - } - decoder->norm = VIDEO_MODE_NTSC; - decoder->input = 0; - decoder->enable = 1; - i2c_set_clientdata(client, decoder); - - vdi.data = saa7111_i2c_init; - vdi.len = sizeof(saa7111_i2c_init); - i = saa7111_init_decoder(client, &vdi); - if (i < 0) { - v4l_dbg(1, debug, client, "init status %d\n", i); - } else { - v4l_dbg(1, debug, client, "revision %x\n", - saa7111_read(client, 0x00) >> 4); - } - return 0; -} - -static int saa7111_remove(struct i2c_client *client) -{ - kfree(i2c_get_clientdata(client)); - return 0; -} - -/* ----------------------------------------------------------------------- */ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) -static const struct i2c_device_id saa7111_id[] = { - { "saa7111_old", 0 }, /* "saa7111" maps to the saa7115 driver */ - { } -}; -MODULE_DEVICE_TABLE(i2c, saa7111_id); - -#endif -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "saa7111", - .driverid = I2C_DRIVERID_SAA7111A, - .command = saa7111_command, - .probe = saa7111_probe, - .remove = saa7111_remove, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) - .id_table = saa7111_id, -#endif -}; diff --git a/linux/drivers/media/video/saa7114.c b/linux/drivers/media/video/saa7114.c deleted file mode 100644 index 6d380e255..000000000 --- a/linux/drivers/media/video/saa7114.c +++ /dev/null @@ -1,1073 +0,0 @@ -/* - * saa7114 - Philips SAA7114H video decoder driver version 0.0.1 - * - * Copyright (C) 2002 Maxim Yevtyushkin - * - * Based on saa7111 driver by Dave Perks - * - * Copyright (C) 1998 Dave Perks - * - * Slight changes for video timing and attachment output by - * Wolfgang Scherr - * - * Changes by Ronald Bultje - * - moved over to linux>=2.4.x i2c protocol (1/1/2003) - * - * 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 -#include -#include -#include -#include "compat.h" - -MODULE_DESCRIPTION("Philips SAA7114H video decoder driver"); -MODULE_AUTHOR("Maxim Yevtyushkin"); -MODULE_LICENSE("GPL"); - -static int debug; -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "Debug level (0-1)"); - -/* ----------------------------------------------------------------------- */ - -struct saa7114 { - unsigned char reg[0xf0 * 2]; - - int norm; - int input; - int enable; - int bright; - int contrast; - int hue; - int sat; - int playback; -}; - -#define I2C_DELAY 10 - - -//#define SAA_7114_NTSC_HSYNC_START (-3) -//#define SAA_7114_NTSC_HSYNC_STOP (-18) - -#define SAA_7114_NTSC_HSYNC_START (-17) -#define SAA_7114_NTSC_HSYNC_STOP (-32) - -//#define SAA_7114_NTSC_HOFFSET (5) -#define SAA_7114_NTSC_HOFFSET (6) -#define SAA_7114_NTSC_VOFFSET (10) -#define SAA_7114_NTSC_WIDTH (720) -#define SAA_7114_NTSC_HEIGHT (250) - -#define SAA_7114_SECAM_HSYNC_START (-17) -#define SAA_7114_SECAM_HSYNC_STOP (-32) - -#define SAA_7114_SECAM_HOFFSET (2) -#define SAA_7114_SECAM_VOFFSET (10) -#define SAA_7114_SECAM_WIDTH (720) -#define SAA_7114_SECAM_HEIGHT (300) - -#define SAA_7114_PAL_HSYNC_START (-17) -#define SAA_7114_PAL_HSYNC_STOP (-32) - -#define SAA_7114_PAL_HOFFSET (2) -#define SAA_7114_PAL_VOFFSET (10) -#define SAA_7114_PAL_WIDTH (720) -#define SAA_7114_PAL_HEIGHT (300) - - - -#define SAA_7114_VERTICAL_CHROMA_OFFSET 0 //0x50504040 -#define SAA_7114_VERTICAL_LUMA_OFFSET 0 - -#define REG_ADDR(x) (((x) << 1) + 1) -#define LOBYTE(x) ((unsigned char)((x) & 0xff)) -#define HIBYTE(x) ((unsigned char)(((x) >> 8) & 0xff)) -#define LOWORD(x) ((unsigned short int)((x) & 0xffff)) -#define HIWORD(x) ((unsigned short int)(((x) >> 16) & 0xffff)) - - -/* ----------------------------------------------------------------------- */ - -static inline int saa7114_write(struct i2c_client *client, u8 reg, u8 value) -{ - return i2c_smbus_write_byte_data(client, reg, value); -} - -static int saa7114_write_block(struct i2c_client *client, const u8 *data, unsigned int len) -{ - int ret = -1; - u8 reg; - - /* the saa7114 has an autoincrement function, use it if - * the adapter understands raw I2C */ - if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - /* do raw I2C, not smbus compatible */ - u8 block_data[32]; - int block_len; - - while (len >= 2) { - block_len = 0; - block_data[block_len++] = reg = data[0]; - do { - block_data[block_len++] = data[1]; - reg++; - len -= 2; - data += 2; - } while (len >= 2 && data[0] == reg && block_len < 32); - ret = i2c_master_send(client, block_data, block_len); - if (ret < 0) - break; - } - } else { - /* do some slow I2C emulation kind of thing */ - while (len >= 2) { - reg = *data++; - ret = saa7114_write(client, reg, *data++); - if (ret < 0) - break; - len -= 2; - } - } - - return ret; -} - -static inline int saa7114_read(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_byte_data(client, reg); -} - -/* ----------------------------------------------------------------------- */ - -// initially set NTSC, composite - - -static const unsigned char init[] = { - 0x00, 0x00, /* 00 - ID byte , chip version, - * read only */ - 0x01, 0x08, /* 01 - X,X,X,X, IDEL3 to IDEL0 - - * horizontal increment delay, - * recommended position */ - 0x02, 0x00, /* 02 - FUSE=3, GUDL=2, MODE=0 ; - * input control */ - 0x03, 0x10, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, - * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */ - 0x04, 0x90, /* 04 - GAI1=256 */ - 0x05, 0x90, /* 05 - GAI2=256 */ - 0x06, SAA_7114_NTSC_HSYNC_START, /* 06 - HSB: hsync start, - * depends on the video standard */ - 0x07, SAA_7114_NTSC_HSYNC_STOP, /* 07 - HSS: hsync stop, depends - *on the video standard */ - 0x08, 0xb8, /* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1, - * HPLL: free running in playback, locked - * in capture, VNOI=0 */ - 0x09, 0x80, /* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0, - * UPTCV=0, APER=1; depends from input */ - 0x0a, 0x80, /* 0a - BRIG=128 */ - 0x0b, 0x44, /* 0b - CONT=1.109 */ - 0x0c, 0x40, /* 0c - SATN=1.0 */ - 0x0d, 0x00, /* 0d - HUE=0 */ - 0x0e, 0x84, /* 0e - CDTO, CSTD2 to 0, DCVF, FCTC, - * CCOMB; depends from video standard */ - 0x0f, 0x24, /* 0f - ACGC,CGAIN6 to CGAIN0; depends - * from video standard */ - 0x10, 0x03, /* 10 - OFFU1 to 0, OFFV1 to 0, CHBW, - * LCBW2 to 0 */ - 0x11, 0x59, /* 11 - COLO, RTP1, HEDL1 to 0, RTP0, - * YDEL2 to 0 */ - 0x12, 0xc9, /* 12 - RT signal control RTSE13 to 10 - * and 03 to 00 */ - 0x13, 0x80, /* 13 - RT/X port output control */ - 0x14, 0x00, /* 14 - analog, ADC, compatibility control */ - 0x15, 0x00, /* 15 - VGATE start FID change */ - 0x16, 0xfe, /* 16 - VGATE stop */ - 0x17, 0x00, /* 17 - Misc., VGATE MSBs */ - 0x18, 0x40, /* RAWG */ - 0x19, 0x80, /* RAWO */ - 0x1a, 0x00, - 0x1b, 0x00, - 0x1c, 0x00, - 0x1d, 0x00, - 0x1e, 0x00, - 0x1f, 0x00, /* status byte, read only */ - 0x20, 0x00, /* video decoder reserved part */ - 0x21, 0x00, - 0x22, 0x00, - 0x23, 0x00, - 0x24, 0x00, - 0x25, 0x00, - 0x26, 0x00, - 0x27, 0x00, - 0x28, 0x00, - 0x29, 0x00, - 0x2a, 0x00, - 0x2b, 0x00, - 0x2c, 0x00, - 0x2d, 0x00, - 0x2e, 0x00, - 0x2f, 0x00, - 0x30, 0xbc, /* audio clock generator */ - 0x31, 0xdf, - 0x32, 0x02, - 0x33, 0x00, - 0x34, 0xcd, - 0x35, 0xcc, - 0x36, 0x3a, - 0x37, 0x00, - 0x38, 0x03, - 0x39, 0x10, - 0x3a, 0x00, - 0x3b, 0x00, - 0x3c, 0x00, - 0x3d, 0x00, - 0x3e, 0x00, - 0x3f, 0x00, - 0x40, 0x00, /* VBI data slicer */ - 0x41, 0xff, - 0x42, 0xff, - 0x43, 0xff, - 0x44, 0xff, - 0x45, 0xff, - 0x46, 0xff, - 0x47, 0xff, - 0x48, 0xff, - 0x49, 0xff, - 0x4a, 0xff, - 0x4b, 0xff, - 0x4c, 0xff, - 0x4d, 0xff, - 0x4e, 0xff, - 0x4f, 0xff, - 0x50, 0xff, - 0x51, 0xff, - 0x52, 0xff, - 0x53, 0xff, - 0x54, 0xff, - 0x55, 0xff, - 0x56, 0xff, - 0x57, 0xff, - 0x58, 0x40, // framing code - 0x59, 0x47, // horizontal offset - 0x5a, 0x06, // vertical offset - 0x5b, 0x83, // field offset - 0x5c, 0x00, // reserved - 0x5d, 0x3e, // header and data - 0x5e, 0x00, // sliced data - 0x5f, 0x00, // reserved - 0x60, 0x00, /* video decoder reserved part */ - 0x61, 0x00, - 0x62, 0x00, - 0x63, 0x00, - 0x64, 0x00, - 0x65, 0x00, - 0x66, 0x00, - 0x67, 0x00, - 0x68, 0x00, - 0x69, 0x00, - 0x6a, 0x00, - 0x6b, 0x00, - 0x6c, 0x00, - 0x6d, 0x00, - 0x6e, 0x00, - 0x6f, 0x00, - 0x70, 0x00, /* video decoder reserved part */ - 0x71, 0x00, - 0x72, 0x00, - 0x73, 0x00, - 0x74, 0x00, - 0x75, 0x00, - 0x76, 0x00, - 0x77, 0x00, - 0x78, 0x00, - 0x79, 0x00, - 0x7a, 0x00, - 0x7b, 0x00, - 0x7c, 0x00, - 0x7d, 0x00, - 0x7e, 0x00, - 0x7f, 0x00, - 0x80, 0x00, /* X-port, I-port and scaler */ - 0x81, 0x00, - 0x82, 0x00, - 0x83, 0x00, - 0x84, 0xc5, - 0x85, 0x0d, // hsync and vsync ? - 0x86, 0x40, - 0x87, 0x01, - 0x88, 0x00, - 0x89, 0x00, - 0x8a, 0x00, - 0x8b, 0x00, - 0x8c, 0x00, - 0x8d, 0x00, - 0x8e, 0x00, - 0x8f, 0x00, - 0x90, 0x03, /* Task A definition */ - 0x91, 0x08, - 0x92, 0x00, - 0x93, 0x40, - 0x94, 0x00, // window settings - 0x95, 0x00, - 0x96, 0x00, - 0x97, 0x00, - 0x98, 0x00, - 0x99, 0x00, - 0x9a, 0x00, - 0x9b, 0x00, - 0x9c, 0x00, - 0x9d, 0x00, - 0x9e, 0x00, - 0x9f, 0x00, - 0xa0, 0x01, /* horizontal integer prescaling ratio */ - 0xa1, 0x00, /* horizontal prescaler accumulation - * sequence length */ - 0xa2, 0x00, /* UV FIR filter, Y FIR filter, prescaler - * DC gain */ - 0xa3, 0x00, - 0xa4, 0x80, // luminance brightness - 0xa5, 0x40, // luminance gain - 0xa6, 0x40, // chrominance saturation - 0xa7, 0x00, - 0xa8, 0x00, // horizontal luminance scaling increment - 0xa9, 0x04, - 0xaa, 0x00, // horizontal luminance phase offset - 0xab, 0x00, - 0xac, 0x00, // horizontal chrominance scaling increment - 0xad, 0x02, - 0xae, 0x00, // horizontal chrominance phase offset - 0xaf, 0x00, - 0xb0, 0x00, // vertical luminance scaling increment - 0xb1, 0x04, - 0xb2, 0x00, // vertical chrominance scaling increment - 0xb3, 0x04, - 0xb4, 0x00, - 0xb5, 0x00, - 0xb6, 0x00, - 0xb7, 0x00, - 0xb8, 0x00, - 0xb9, 0x00, - 0xba, 0x00, - 0xbb, 0x00, - 0xbc, 0x00, - 0xbd, 0x00, - 0xbe, 0x00, - 0xbf, 0x00, - 0xc0, 0x02, // Task B definition - 0xc1, 0x08, - 0xc2, 0x00, - 0xc3, 0x40, - 0xc4, 0x00, // window settings - 0xc5, 0x00, - 0xc6, 0x00, - 0xc7, 0x00, - 0xc8, 0x00, - 0xc9, 0x00, - 0xca, 0x00, - 0xcb, 0x00, - 0xcc, 0x00, - 0xcd, 0x00, - 0xce, 0x00, - 0xcf, 0x00, - 0xd0, 0x01, // horizontal integer prescaling ratio - 0xd1, 0x00, // horizontal prescaler accumulation sequence length - 0xd2, 0x00, // UV FIR filter, Y FIR filter, prescaler DC gain - 0xd3, 0x00, - 0xd4, 0x80, // luminance brightness - 0xd5, 0x40, // luminance gain - 0xd6, 0x40, // chrominance saturation - 0xd7, 0x00, - 0xd8, 0x00, // horizontal luminance scaling increment - 0xd9, 0x04, - 0xda, 0x00, // horizontal luminance phase offset - 0xdb, 0x00, - 0xdc, 0x00, // horizontal chrominance scaling increment - 0xdd, 0x02, - 0xde, 0x00, // horizontal chrominance phase offset - 0xdf, 0x00, - 0xe0, 0x00, // vertical luminance scaling increment - 0xe1, 0x04, - 0xe2, 0x00, // vertical chrominance scaling increment - 0xe3, 0x04, - 0xe4, 0x00, - 0xe5, 0x00, - 0xe6, 0x00, - 0xe7, 0x00, - 0xe8, 0x00, - 0xe9, 0x00, - 0xea, 0x00, - 0xeb, 0x00, - 0xec, 0x00, - 0xed, 0x00, - 0xee, 0x00, - 0xef, 0x00 -}; - -static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg) -{ - struct saa7114 *decoder = i2c_get_clientdata(client); - - switch (cmd) { - case 0: - //dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client)); - //saa7114_write_block(client, init, sizeof(init)); - break; - - case DECODER_DUMP: - { - int i; - - if (!debug) - break; - v4l_info(client, "decoder dump\n"); - - for (i = 0; i < 32; i += 16) { - int j; - - v4l_info(client, "%03x", i); - for (j = 0; j < 16; ++j) { - printk(KERN_CONT " %02x", - saa7114_read(client, i + j)); - } - printk(KERN_CONT "\n"); - } - break; - } - - case DECODER_GET_CAPABILITIES: - { - struct video_decoder_capability *cap = arg; - - v4l_dbg(1, debug, client, "get capabilities\n"); - - cap->flags = VIDEO_DECODER_PAL | - VIDEO_DECODER_NTSC | - VIDEO_DECODER_AUTO | - VIDEO_DECODER_CCIR; - cap->inputs = 8; - cap->outputs = 1; - break; - } - - case DECODER_GET_STATUS: - { - int *iarg = arg; - int status; - int res; - - status = saa7114_read(client, 0x1f); - - v4l_dbg(1, debug, client, "status: 0x%02x\n", status); - res = 0; - if ((status & (1 << 6)) == 0) { - res |= DECODER_STATUS_GOOD; - } - switch (decoder->norm) { - case VIDEO_MODE_NTSC: - res |= DECODER_STATUS_NTSC; - break; - case VIDEO_MODE_PAL: - res |= DECODER_STATUS_PAL; - break; - case VIDEO_MODE_SECAM: - res |= DECODER_STATUS_SECAM; - break; - default: - case VIDEO_MODE_AUTO: - if ((status & (1 << 5)) != 0) { - res |= DECODER_STATUS_NTSC; - } else { - res |= DECODER_STATUS_PAL; - } - break; - } - if ((status & (1 << 0)) != 0) { - res |= DECODER_STATUS_COLOR; - } - *iarg = res; - break; - } - - case DECODER_SET_NORM: - { - int *iarg = arg; - - short int hoff = 0, voff = 0, w = 0, h = 0; - - v4l_dbg(1, debug, client, "set norm\n"); - - switch (*iarg) { - case VIDEO_MODE_NTSC: - v4l_dbg(1, debug, client, "NTSC\n"); - decoder->reg[REG_ADDR(0x06)] = - SAA_7114_NTSC_HSYNC_START; - decoder->reg[REG_ADDR(0x07)] = - SAA_7114_NTSC_HSYNC_STOP; - - decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture - - decoder->reg[REG_ADDR(0x0e)] = 0x85; - decoder->reg[REG_ADDR(0x0f)] = 0x24; - - hoff = SAA_7114_NTSC_HOFFSET; - voff = SAA_7114_NTSC_VOFFSET; - w = SAA_7114_NTSC_WIDTH; - h = SAA_7114_NTSC_HEIGHT; - - break; - - case VIDEO_MODE_PAL: - v4l_dbg(1, debug, client, "PAL\n"); - decoder->reg[REG_ADDR(0x06)] = - SAA_7114_PAL_HSYNC_START; - decoder->reg[REG_ADDR(0x07)] = - SAA_7114_PAL_HSYNC_STOP; - - decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture - - decoder->reg[REG_ADDR(0x0e)] = 0x81; - decoder->reg[REG_ADDR(0x0f)] = 0x24; - - hoff = SAA_7114_PAL_HOFFSET; - voff = SAA_7114_PAL_VOFFSET; - w = SAA_7114_PAL_WIDTH; - h = SAA_7114_PAL_HEIGHT; - - break; - - default: - v4l_dbg(1, debug, client, "Unknown video mode\n"); - return -EINVAL; - } - - - decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low - decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high - decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low - decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high - decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low - decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high - decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low - decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high - decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low - decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high - decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low - decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high - - decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low - decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high - decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low - decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high - decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low - decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high - decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low - decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high - decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low - decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high - decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low - decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high - - - saa7114_write(client, 0x80, 0x06); // i-port and scaler back end clock selection, task A&B off - saa7114_write(client, 0x88, 0xd8); // sw reset scaler - saa7114_write(client, 0x88, 0xf8); // sw reset scaler release - - saa7114_write_block(client, decoder->reg + (0x06 << 1), - 3 << 1); - saa7114_write_block(client, decoder->reg + (0x0e << 1), - 2 << 1); - saa7114_write_block(client, decoder->reg + (0x5a << 1), - 2 << 1); - - saa7114_write_block(client, decoder->reg + (0x94 << 1), - (0x9f + 1 - 0x94) << 1); - saa7114_write_block(client, decoder->reg + (0xc4 << 1), - (0xcf + 1 - 0xc4) << 1); - - saa7114_write(client, 0x88, 0xd8); // sw reset scaler - saa7114_write(client, 0x88, 0xf8); // sw reset scaler release - saa7114_write(client, 0x80, 0x36); // i-port and scaler back end clock selection - - decoder->norm = *iarg; - break; - } - - case DECODER_SET_INPUT: - { - int *iarg = arg; - - v4l_dbg(1, debug, client, "set input (%d)\n", *iarg); - if (*iarg < 0 || *iarg > 7) { - return -EINVAL; - } - - if (decoder->input != *iarg) { - v4l_dbg(1, debug, client, "now setting %s input\n", - *iarg >= 6 ? "S-Video" : "Composite"); - decoder->input = *iarg; - - /* select mode */ - decoder->reg[REG_ADDR(0x02)] = - (decoder-> - reg[REG_ADDR(0x02)] & 0xf0) | (decoder-> - input < - 6 ? 0x0 : 0x9); - saa7114_write(client, 0x02, - decoder->reg[REG_ADDR(0x02)]); - - /* bypass chrominance trap for modes 6..9 */ - decoder->reg[REG_ADDR(0x09)] = - (decoder-> - reg[REG_ADDR(0x09)] & 0x7f) | (decoder-> - input < - 6 ? 0x0 : - 0x80); - saa7114_write(client, 0x09, - decoder->reg[REG_ADDR(0x09)]); - - decoder->reg[REG_ADDR(0x0e)] = - decoder->input < - 6 ? decoder-> - reg[REG_ADDR(0x0e)] | 1 : decoder-> - reg[REG_ADDR(0x0e)] & ~1; - saa7114_write(client, 0x0e, - decoder->reg[REG_ADDR(0x0e)]); - } - break; - } - - case DECODER_SET_OUTPUT: - { - int *iarg = arg; - - v4l_dbg(1, debug, client, "set output\n"); - - /* not much choice of outputs */ - if (*iarg != 0) { - return -EINVAL; - } - break; - } - - case DECODER_ENABLE_OUTPUT: - { - int *iarg = arg; - int enable = (*iarg != 0); - - v4l_dbg(1, debug, client, "%s output\n", - enable ? "enable" : "disable"); - - decoder->playback = !enable; - - if (decoder->enable != enable) { - decoder->enable = enable; - - /* RJ: If output should be disabled (for - * playing videos), we also need a open PLL. - * The input is set to 0 (where no input - * source is connected), although this - * is not necessary. - * - * If output should be enabled, we have to - * reverse the above. - */ - - if (decoder->enable) { - decoder->reg[REG_ADDR(0x08)] = 0xb8; - decoder->reg[REG_ADDR(0x12)] = 0xc9; - decoder->reg[REG_ADDR(0x13)] = 0x80; - decoder->reg[REG_ADDR(0x87)] = 0x01; - } else { - decoder->reg[REG_ADDR(0x08)] = 0x7c; - decoder->reg[REG_ADDR(0x12)] = 0x00; - decoder->reg[REG_ADDR(0x13)] = 0x00; - decoder->reg[REG_ADDR(0x87)] = 0x00; - } - - saa7114_write_block(client, - decoder->reg + (0x12 << 1), - 2 << 1); - saa7114_write(client, 0x08, - decoder->reg[REG_ADDR(0x08)]); - saa7114_write(client, 0x87, - decoder->reg[REG_ADDR(0x87)]); - saa7114_write(client, 0x88, 0xd8); // sw reset scaler - saa7114_write(client, 0x88, 0xf8); // sw reset scaler release - saa7114_write(client, 0x80, 0x36); - - } - break; - } - - case DECODER_SET_PICTURE: - { - struct video_picture *pic = arg; - - v4l_dbg(1, debug, client, - "decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n", - pic->brightness, pic->contrast, pic->colour, pic->hue); - - if (decoder->bright != pic->brightness) { - /* We want 0 to 255 we get 0-65535 */ - decoder->bright = pic->brightness; - saa7114_write(client, 0x0a, decoder->bright >> 8); - } - if (decoder->contrast != pic->contrast) { - /* We want 0 to 127 we get 0-65535 */ - decoder->contrast = pic->contrast; - saa7114_write(client, 0x0b, - decoder->contrast >> 9); - } - if (decoder->sat != pic->colour) { - /* We want 0 to 127 we get 0-65535 */ - decoder->sat = pic->colour; - saa7114_write(client, 0x0c, decoder->sat >> 9); - } - if (decoder->hue != pic->hue) { - /* We want -128 to 127 we get 0-65535 */ - decoder->hue = pic->hue; - saa7114_write(client, 0x0d, - (decoder->hue - 32768) >> 8); - } - break; - } - - default: - return -EINVAL; - } - - return 0; -} - -/* ----------------------------------------------------------------------- */ - -static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END }; - -I2C_CLIENT_INSMOD; - -static int saa7114_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int i, err[30]; - short int hoff = SAA_7114_NTSC_HOFFSET; - short int voff = SAA_7114_NTSC_VOFFSET; - short int w = SAA_7114_NTSC_WIDTH; - short int h = SAA_7114_NTSC_HEIGHT; - struct saa7114 *decoder; - - /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return -ENODEV; - - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); - - decoder = kzalloc(sizeof(struct saa7114), GFP_KERNEL); - if (decoder == NULL) - return -ENOMEM; - decoder->norm = VIDEO_MODE_NTSC; - decoder->input = -1; - decoder->enable = 1; - decoder->bright = 32768; - decoder->contrast = 32768; - decoder->hue = 32768; - decoder->sat = 32768; - decoder->playback = 0; // initially capture mode useda - i2c_set_clientdata(client, decoder); - - memcpy(decoder->reg, init, sizeof(init)); - - decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low - decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high - decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low - decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high - decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low - decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high - decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low - decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high - decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low - decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high - decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low - decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high - - decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low - decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high - decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low - decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high - decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low - decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high - decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low - decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high - decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low - decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high - decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low - decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high - - decoder->reg[REG_ADDR(0xb8)] = - LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); - decoder->reg[REG_ADDR(0xb9)] = - HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); - decoder->reg[REG_ADDR(0xba)] = - LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); - decoder->reg[REG_ADDR(0xbb)] = - HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); - - decoder->reg[REG_ADDR(0xbc)] = - LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); - decoder->reg[REG_ADDR(0xbd)] = - HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); - decoder->reg[REG_ADDR(0xbe)] = - LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); - decoder->reg[REG_ADDR(0xbf)] = - HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); - - decoder->reg[REG_ADDR(0xe8)] = - LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); - decoder->reg[REG_ADDR(0xe9)] = - HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); - decoder->reg[REG_ADDR(0xea)] = - LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); - decoder->reg[REG_ADDR(0xeb)] = - HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); - - decoder->reg[REG_ADDR(0xec)] = - LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); - decoder->reg[REG_ADDR(0xed)] = - HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); - decoder->reg[REG_ADDR(0xee)] = - LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); - decoder->reg[REG_ADDR(0xef)] = - HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); - - - decoder->reg[REG_ADDR(0x13)] = 0x80; // RTC0 on - decoder->reg[REG_ADDR(0x87)] = 0x01; // I-Port - decoder->reg[REG_ADDR(0x12)] = 0xc9; // RTS0 - - decoder->reg[REG_ADDR(0x02)] = 0xc0; // set composite1 input, aveasy - decoder->reg[REG_ADDR(0x09)] = 0x00; // chrominance trap - decoder->reg[REG_ADDR(0x0e)] |= 1; // combfilter on - - - v4l_dbg(1, debug, client, "starting init\n"); - - err[0] = - saa7114_write_block(client, decoder->reg + (0x20 << 1), - 0x10 << 1); - err[1] = - saa7114_write_block(client, decoder->reg + (0x30 << 1), - 0x10 << 1); - err[2] = - saa7114_write_block(client, decoder->reg + (0x63 << 1), - (0x7f + 1 - 0x63) << 1); - err[3] = - saa7114_write_block(client, decoder->reg + (0x89 << 1), - 6 << 1); - err[4] = - saa7114_write_block(client, decoder->reg + (0xb8 << 1), - 8 << 1); - err[5] = - saa7114_write_block(client, decoder->reg + (0xe8 << 1), - 8 << 1); - - - for (i = 0; i <= 5; i++) { - if (err[i] < 0) { - v4l_dbg(1, debug, client, - "init error %d at stage %d, leaving attach.\n", - i, err[i]); - kfree(decoder); - return -EIO; - } - } - - for (i = 6; i < 8; i++) { - v4l_dbg(1, debug, client, - "reg[0x%02x] = 0x%02x (0x%02x)\n", - i, saa7114_read(client, i), - decoder->reg[REG_ADDR(i)]); - } - - v4l_dbg(1, debug, client, - "performing decoder reset sequence\n"); - - err[6] = saa7114_write(client, 0x80, 0x06); // i-port and scaler backend clock selection, task A&B off - err[7] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler - err[8] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release - - for (i = 6; i <= 8; i++) { - if (err[i] < 0) { - v4l_dbg(1, debug, client, - "init error %d at stage %d, leaving attach.\n", - i, err[i]); - kfree(decoder); - return -EIO; - } - } - - v4l_dbg(1, debug, client, "performing the rest of init\n"); - - err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]); - err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1); // big seq - err[11] = saa7114_write_block(client, decoder->reg + (0x40 << 1), (0x5f + 1 - 0x40) << 1); // slicer - err[12] = saa7114_write_block(client, decoder->reg + (0x81 << 1), 2 << 1); // ? - err[13] = saa7114_write_block(client, decoder->reg + (0x83 << 1), 5 << 1); // ? - err[14] = saa7114_write_block(client, decoder->reg + (0x90 << 1), 4 << 1); // Task A - err[15] = - saa7114_write_block(client, decoder->reg + (0x94 << 1), - 12 << 1); - err[16] = - saa7114_write_block(client, decoder->reg + (0xa0 << 1), - 8 << 1); - err[17] = - saa7114_write_block(client, decoder->reg + (0xa8 << 1), - 8 << 1); - err[18] = - saa7114_write_block(client, decoder->reg + (0xb0 << 1), - 8 << 1); - err[19] = saa7114_write_block(client, decoder->reg + (0xc0 << 1), 4 << 1); // Task B - err[15] = - saa7114_write_block(client, decoder->reg + (0xc4 << 1), - 12 << 1); - err[16] = - saa7114_write_block(client, decoder->reg + (0xd0 << 1), - 8 << 1); - err[17] = - saa7114_write_block(client, decoder->reg + (0xd8 << 1), - 8 << 1); - err[18] = - saa7114_write_block(client, decoder->reg + (0xe0 << 1), - 8 << 1); - - for (i = 9; i <= 18; i++) { - if (err[i] < 0) { - v4l_dbg(1, debug, client, - "init error %d at stage %d, leaving attach.\n", - i, err[i]); - kfree(decoder); - return -EIO; - } - } - - - for (i = 6; i < 8; i++) { - v4l_dbg(1, debug, client, - "reg[0x%02x] = 0x%02x (0x%02x)\n", - i, saa7114_read(client, i), - decoder->reg[REG_ADDR(i)]); - } - - - for (i = 0x11; i <= 0x13; i++) { - v4l_dbg(1, debug, client, - "reg[0x%02x] = 0x%02x (0x%02x)\n", - i, saa7114_read(client, i), - decoder->reg[REG_ADDR(i)]); - } - - - v4l_dbg(1, debug, client, "setting video input\n"); - - err[19] = - saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]); - err[20] = - saa7114_write(client, 0x09, decoder->reg[REG_ADDR(0x09)]); - err[21] = - saa7114_write(client, 0x0e, decoder->reg[REG_ADDR(0x0e)]); - - for (i = 19; i <= 21; i++) { - if (err[i] < 0) { - v4l_dbg(1, debug, client, - "init error %d at stage %d, leaving attach.\n", - i, err[i]); - kfree(decoder); - return -EIO; - } - } - - v4l_dbg(1, debug, client, "performing decoder reset sequence\n"); - - err[22] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler - err[23] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release - err[24] = saa7114_write(client, 0x80, 0x36); // i-port and scaler backend clock selection, task A&B off - - - for (i = 22; i <= 24; i++) { - if (err[i] < 0) { - v4l_dbg(1, debug, client, - "init error %d at stage %d, leaving attach.\n", - i, err[i]); - kfree(decoder); - return -EIO; - } - } - - err[25] = saa7114_write(client, 0x06, init[REG_ADDR(0x06)]); - err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]); - err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]); - - v4l_dbg(1, debug, client, "chip version %x, decoder status 0x%02x\n", - saa7114_read(client, 0x00) >> 4, - saa7114_read(client, 0x1f)); - v4l_dbg(1, debug, client, - "power save control: 0x%02x, scaler status: 0x%02x\n", - saa7114_read(client, 0x88), - saa7114_read(client, 0x8f)); - - - for (i = 0x94; i < 0x96; i++) { - v4l_dbg(1, debug, client, - "reg[0x%02x] = 0x%02x (0x%02x)\n", - i, saa7114_read(client, i), - decoder->reg[REG_ADDR(i)]); - } - - //i = saa7114_write_block(client, init, sizeof(init)); - return 0; -} - -static int saa7114_remove(struct i2c_client *client) -{ - kfree(i2c_get_clientdata(client)); - return 0; -} - -/* ----------------------------------------------------------------------- */ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) -static const struct i2c_device_id saa7114_id[] = { - { "saa7114_old", 0 }, /* "saa7114" maps to the saa7115 driver */ - { } -}; -MODULE_DEVICE_TABLE(i2c, saa7114_id); - -#endif -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "saa7114", - .driverid = I2C_DRIVERID_SAA7114, - .command = saa7114_command, - .probe = saa7114_probe, - .remove = saa7114_remove, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) - .id_table = saa7114_id, -#endif -}; diff --git a/linux/drivers/media/video/saa7185.c b/linux/drivers/media/video/saa7185.c index 68bec4d5d..08cc04138 100644 --- a/linux/drivers/media/video/saa7185.c +++ b/linux/drivers/media/video/saa7185.c @@ -50,8 +50,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); struct saa7185 { unsigned char reg[128]; - int norm; - int enable; + v4l2_std_id norm; int bright; int contrast; int hue; @@ -219,68 +218,43 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) struct saa7185 *encoder = i2c_get_clientdata(client); switch (cmd) { - case 0: + case VIDIOC_INT_INIT: saa7185_write_block(client, init_common, sizeof(init_common)); - switch (encoder->norm) { - - case VIDEO_MODE_NTSC: + if (encoder->norm & V4L2_STD_NTSC) saa7185_write_block(client, init_ntsc, sizeof(init_ntsc)); - break; - - case VIDEO_MODE_PAL: + else saa7185_write_block(client, init_pal, sizeof(init_pal)); - break; - } - break; - - case ENCODER_GET_CAPABILITIES: - { - struct video_encoder_capability *cap = arg; - - cap->flags = - VIDEO_ENCODER_PAL | VIDEO_ENCODER_NTSC | - VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR; - cap->inputs = 1; - cap->outputs = 1; break; - } - case ENCODER_SET_NORM: + case VIDIOC_INT_S_STD_OUTPUT: { - int *iarg = arg; + v4l2_std_id *iarg = arg; //saa7185_write_block(client, init_common, sizeof(init_common)); - switch (*iarg) { - case VIDEO_MODE_NTSC: + if (*iarg & V4L2_STD_NTSC) saa7185_write_block(client, init_ntsc, sizeof(init_ntsc)); - break; - - case VIDEO_MODE_PAL: + else if (*iarg & V4L2_STD_PAL) saa7185_write_block(client, init_pal, sizeof(init_pal)); - break; - - case VIDEO_MODE_SECAM: - default: + else return -EINVAL; - } encoder->norm = *iarg; break; } - case ENCODER_SET_INPUT: + case VIDIOC_INT_S_VIDEO_ROUTING: { - int *iarg = arg; + struct v4l2_routing *route = arg; - /* RJ: *iarg = 0: input is from SA7111 - *iarg = 1: input is from ZR36060 */ + /* RJ: route->input = 0: input is from SA7111 + route->input = 1: input is from ZR36060 */ - switch (*iarg) { + switch (route->input) { case 0: /* turn off colorbar */ saa7185_write(client, 0x3a, 0x0f); @@ -316,27 +290,6 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) break; } - case ENCODER_SET_OUTPUT: - { - int *iarg = arg; - - /* not much choice of outputs */ - if (*iarg != 0) - return -EINVAL; - break; - } - - case ENCODER_ENABLE_OUTPUT: - { - int *iarg = arg; - - encoder->enable = !!*iarg; - saa7185_write(client, 0x61, - (encoder->reg[0x61] & 0xbf) | - (encoder->enable ? 0x00 : 0x40)); - break; - } - default: return -EINVAL; } @@ -366,8 +319,7 @@ static int saa7185_probe(struct i2c_client *client, encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL); if (encoder == NULL) return -ENOMEM; - encoder->norm = VIDEO_MODE_NTSC; - encoder->enable = 1; + encoder->norm = V4L2_STD_NTSC; i2c_set_clientdata(client, encoder); i = saa7185_write_block(client, init_common, sizeof(init_common)); diff --git a/linux/drivers/media/video/vpx3220.c b/linux/drivers/media/video/vpx3220.c index 5f368a1be..2487f8fe2 100644 --- a/linux/drivers/media/video/vpx3220.c +++ b/linux/drivers/media/video/vpx3220.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "compat.h" @@ -45,7 +46,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); struct vpx3220 { unsigned char reg[255]; - int norm; + v4l2_std_id norm; int input; int enable; int bright; @@ -260,6 +261,7 @@ static const unsigned short init_fp[] = { 0x4b, 0x298, /* PLL gain */ }; +#if 0 static void vpx3220_dump_i2c(struct i2c_client *client) { int len = sizeof(init_common); @@ -272,67 +274,42 @@ static void vpx3220_dump_i2c(struct i2c_client *client) len -= 2; } } +#endif static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) { struct vpx3220 *decoder = i2c_get_clientdata(client); switch (cmd) { - case 0: + case VIDIOC_INT_INIT: { vpx3220_write_block(client, init_common, sizeof(init_common)); vpx3220_write_fp_block(client, init_fp, sizeof(init_fp) >> 1); - switch (decoder->norm) { - case VIDEO_MODE_NTSC: + if (decoder->norm & V4L2_STD_NTSC) { vpx3220_write_fp_block(client, init_ntsc, sizeof(init_ntsc) >> 1); - break; - - case VIDEO_MODE_PAL: + } else if (decoder->norm & V4L2_STD_PAL) { vpx3220_write_fp_block(client, init_pal, sizeof(init_pal) >> 1); - break; - case VIDEO_MODE_SECAM: + } else if (decoder->norm & V4L2_STD_SECAM) { vpx3220_write_fp_block(client, init_secam, sizeof(init_secam) >> 1); - break; - default: + } else { vpx3220_write_fp_block(client, init_pal, sizeof(init_pal) >> 1); - break; } break; } - case DECODER_DUMP: - { - vpx3220_dump_i2c(client); - break; - } - - case DECODER_GET_CAPABILITIES: - { - struct video_decoder_capability *cap = arg; - - v4l_dbg(1, debug, client, "DECODER_GET_CAPABILITIES\n"); - - cap->flags = VIDEO_DECODER_PAL | - VIDEO_DECODER_NTSC | - VIDEO_DECODER_SECAM | - VIDEO_DECODER_AUTO | - VIDEO_DECODER_CCIR; - cap->inputs = 3; - cap->outputs = 1; - break; - } - - case DECODER_GET_STATUS: + case VIDIOC_QUERYSTD: + case VIDIOC_INT_G_INPUT_STATUS: { - int res = 0, status; + int res = V4L2_IN_ST_NO_SIGNAL, status; + v4l2_std_id std = 0; - v4l_dbg(1, debug, client, "DECODER_GET_STATUS\n"); + v4l_dbg(1, debug, client, "VIDIOC_QUERYSTD/VIDIOC_INT_G_INPUT_STATUS\n"); status = vpx3220_fp_read(client, 0x0f3); @@ -342,35 +319,38 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) return status; if ((status & 0x20) == 0) { - res |= DECODER_STATUS_GOOD | DECODER_STATUS_COLOR; + res = 0; switch (status & 0x18) { case 0x00: case 0x10: case 0x14: case 0x18: - res |= DECODER_STATUS_PAL; + std = V4L2_STD_PAL; break; case 0x08: - res |= DECODER_STATUS_SECAM; + std = V4L2_STD_SECAM; break; case 0x04: case 0x0c: case 0x1c: - res |= DECODER_STATUS_NTSC; + std = V4L2_STD_NTSC; break; } } - *(int *) arg = res; + if (cmd == VIDIOC_QUERYSTD) + *(v4l2_std_id *)arg = std; + else + *(int *)arg = res; break; } - case DECODER_SET_NORM: + case VIDIOC_S_STD: { - int *iarg = arg, data; + v4l2_std_id *iarg = arg; int temp_input; /* Here we back up the input selection because it gets @@ -378,36 +358,31 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) choosen video norm */ temp_input = vpx3220_fp_read(client, 0xf2); - v4l_dbg(1, debug, client, "DECODER_SET_NORM %d\n", *iarg); - switch (*iarg) { - case VIDEO_MODE_NTSC: + v4l_dbg(1, debug, client, "VIDIOC_S_STD %llx\n", *iarg); + if (*iarg & V4L2_STD_NTSC) { vpx3220_write_fp_block(client, init_ntsc, sizeof(init_ntsc) >> 1); v4l_dbg(1, debug, client, "norm switched to NTSC\n"); - break; - - case VIDEO_MODE_PAL: + } else if (*iarg & V4L2_STD_PAL) { vpx3220_write_fp_block(client, init_pal, sizeof(init_pal) >> 1); v4l_dbg(1, debug, client, "norm switched to PAL\n"); - break; - - case VIDEO_MODE_SECAM: + } else if (*iarg & V4L2_STD_SECAM) { vpx3220_write_fp_block(client, init_secam, sizeof(init_secam) >> 1); v4l_dbg(1, debug, client, "norm switched to SECAM\n"); - break; + } else { + return -EINVAL; + } +#if 0 case VIDEO_MODE_AUTO: /* FIXME This is only preliminary support */ data = vpx3220_fp_read(client, 0xf2) & 0x20; vpx3220_fp_write(client, 0xf2, 0x00c0 | data); v4l_dbg(1, debug, client, "norm switched to AUTO\n"); break; - - default: - return -EINVAL; - } +#endif decoder->norm = *iarg; /* And here we set the backed up video input again */ @@ -416,9 +391,10 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) break; } - case DECODER_SET_INPUT: + case VIDIOC_INT_S_VIDEO_ROUTING: { - int *iarg = arg, data; + struct v4l2_routing *route = arg; + int data; /* RJ: *iarg = 0: ST8 (PCTV) input *iarg = 1: COMPOSITE input @@ -430,73 +406,117 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) {0x0e, 1} }; - if (*iarg < 0 || *iarg > 2) + if (route->input < 0 || route->input > 2) return -EINVAL; - v4l_dbg(1, debug, client, "input switched to %s\n", inputs[*iarg]); + v4l_dbg(1, debug, client, "input switched to %s\n", inputs[route->input]); - vpx3220_write(client, 0x33, input[*iarg][0]); + vpx3220_write(client, 0x33, input[route->input][0]); data = vpx3220_fp_read(client, 0xf2) & ~(0x0020); if (data < 0) return data; /* 0x0010 is required to latch the setting */ vpx3220_fp_write(client, 0xf2, - data | (input[*iarg][1] << 5) | 0x0010); + data | (input[route->input][1] << 5) | 0x0010); udelay(10); break; } - case DECODER_SET_OUTPUT: + case VIDIOC_STREAMON: + case VIDIOC_STREAMOFF: { - int *iarg = arg; + int on = cmd == VIDIOC_STREAMON; + v4l_dbg(1, debug, client, "VIDIOC_STREAM%s\n", on ? "ON" : "OFF"); - /* not much choice of outputs */ - if (*iarg != 0) { - return -EINVAL; - } + vpx3220_write(client, 0xf2, (on ? 0x1b : 0x00)); break; } - case DECODER_ENABLE_OUTPUT: + case VIDIOC_QUERYCTRL: { - int *iarg = arg; + struct v4l2_queryctrl *qc = arg; + + switch (qc->id) { + case V4L2_CID_BRIGHTNESS: + v4l2_ctrl_query_fill(qc, -128, 127, 1, 0); + break; + + case V4L2_CID_CONTRAST: + v4l2_ctrl_query_fill(qc, 0, 63, 1, 32); + break; + + case V4L2_CID_SATURATION: + v4l2_ctrl_query_fill(qc, 0, 4095, 1, 2048); + break; - v4l_dbg(1, debug, client, "DECODER_ENABLE_OUTPUT %d\n", *iarg); + case V4L2_CID_HUE: + v4l2_ctrl_query_fill(qc, -512, 511, 1, 0); + break; - vpx3220_write(client, 0xf2, (*iarg ? 0x1b : 0x00)); + default: + return -EINVAL; + } break; } - case DECODER_SET_PICTURE: + case VIDIOC_G_CTRL: { - struct video_picture *pic = arg; + struct v4l2_control *ctrl = arg; - if (decoder->bright != pic->brightness) { - /* We want -128 to 128 we get 0-65535 */ - decoder->bright = pic->brightness; - vpx3220_write(client, 0xe6, - (decoder->bright - 32768) >> 8); - } - if (decoder->contrast != pic->contrast) { - /* We want 0 to 64 we get 0-65535 */ - /* Bit 7 and 8 is for noise shaping */ - decoder->contrast = pic->contrast; - vpx3220_write(client, 0xe7, - (decoder->contrast >> 10) + 192); - } - if (decoder->sat != pic->colour) { - /* We want 0 to 4096 we get 0-65535 */ - decoder->sat = pic->colour; - vpx3220_fp_write(client, 0xa0, - decoder->sat >> 4); + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + ctrl->value = decoder->bright; + break; + case V4L2_CID_CONTRAST: + ctrl->value = decoder->contrast; + break; + case V4L2_CID_SATURATION: + ctrl->value = decoder->sat; + break; + case V4L2_CID_HUE: + ctrl->value = decoder->hue; + break; + default: + return -EINVAL; } - if (decoder->hue != pic->hue) { - /* We want -512 to 512 we get 0-65535 */ - decoder->hue = pic->hue; - vpx3220_fp_write(client, 0x1c, - ((decoder->hue - 32768) >> 6) & 0xFFF); + break; + } + + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl = arg; + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + if (decoder->bright != ctrl->value) { + decoder->bright = ctrl->value; + vpx3220_write(client, 0xe6, decoder->bright); + } + break; + case V4L2_CID_CONTRAST: + if (decoder->contrast != ctrl->value) { + /* Bit 7 and 8 is for noise shaping */ + decoder->contrast = ctrl->value; + vpx3220_write(client, 0xe7, + decoder->contrast + 192); + } + break; + case V4L2_CID_SATURATION: + if (decoder->sat != ctrl->value) { + decoder->sat = ctrl->value; + vpx3220_fp_write(client, 0xa0, decoder->sat); + } + break; + case V4L2_CID_HUE: + if (decoder->hue != ctrl->value) { + decoder->hue = ctrl->value; + vpx3220_fp_write(client, 0x1c, decoder->hue); + } + break; + default: + return -EINVAL; } break; } @@ -542,7 +562,7 @@ static int vpx3220_probe(struct i2c_client *client, decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL); if (decoder == NULL) return -ENOMEM; - decoder->norm = VIDEO_MODE_PAL; + decoder->norm = V4L2_STD_PAL; decoder->input = 0; decoder->enable = 1; decoder->bright = 32768; diff --git a/linux/drivers/media/video/zoran/Kconfig b/linux/drivers/media/video/zoran/Kconfig index a0fe52260..925fb5159 100644 --- a/linux/drivers/media/video/zoran/Kconfig +++ b/linux/drivers/media/video/zoran/Kconfig @@ -32,7 +32,7 @@ config VIDEO_ZORAN_ZR36060 config VIDEO_ZORAN_BUZ tristate "Iomega Buz support" depends on VIDEO_ZORAN_ZR36060 - select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO select VIDEO_SAA7185 if VIDEO_HELPER_CHIPS_AUTO help Support for the Iomega Buz MJPEG capture/playback card. @@ -58,7 +58,7 @@ config VIDEO_ZORAN_LML33 config VIDEO_ZORAN_LML33R10 tristate "Linux Media Labs LML33R10 support" depends on VIDEO_ZORAN_ZR36060 - select VIDEO_SAA7114 if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO select VIDEO_ADV7170 if VIDEO_HELPER_CHIPS_AUTO help support for the Linux Media Labs LML33R10 MJPEG capture/playback diff --git a/linux/drivers/media/video/zoran/zoran.h b/linux/drivers/media/video/zoran/zoran.h index 76668bda0..ee31bfc34 100644 --- a/linux/drivers/media/video/zoran/zoran.h +++ b/linux/drivers/media/video/zoran/zoran.h @@ -352,7 +352,7 @@ struct card_info { char name[32]; } input[BUZ_MAX_INPUT]; - int norms; + v4l2_std_id norms; struct tvnorm *tvn[3]; /* supported TV norms */ u32 jpeg_int; /* JPEG interrupt */ @@ -401,8 +401,8 @@ struct zoran { spinlock_t spinlock; /* Spinlock */ /* Video for Linux parameters */ - int input, norm; /* card's norm and input - norm=VIDEO_MODE_* */ - int hue, saturation, contrast, brightness; /* Current picture params */ + int input; /* card's norm and input - norm=VIDEO_MODE_* */ + v4l2_std_id norm; struct video_buffer buffer; /* Current buffer params */ struct zoran_overlay_settings overlay_settings; u32 *overlay_mask; /* overlay mask */ diff --git a/linux/drivers/media/video/zoran/zoran_card.c b/linux/drivers/media/video/zoran/zoran_card.c index 552204bab..17c3aaffd 100644 --- a/linux/drivers/media/video/zoran/zoran_card.c +++ b/linux/drivers/media/video/zoran/zoran_card.c @@ -341,11 +341,8 @@ i2cid_to_modulename (u16 i2c_id) case I2C_DRIVERID_SAA7110: name = "saa7110"; break; - case I2C_DRIVERID_SAA7111A: - name = "saa7111"; - break; - case I2C_DRIVERID_SAA7114: - name = "saa7114"; + case I2C_DRIVERID_SAA711X: + name = "saa7115"; break; case I2C_DRIVERID_SAA7185B: name = "saa7185"; @@ -440,7 +437,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 2, "S-Video" }, { 0, "Internal/comp" } }, - .norms = 3, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, .tvn = { &f50sqpixel_dc10, &f60sqpixel_dc10, @@ -468,7 +465,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 7, "S-Video" }, { 5, "Internal/comp" } }, - .norms = 3, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, .tvn = { &f50sqpixel, &f60sqpixel, @@ -495,7 +492,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 7, "S-Video" }, { 5, "Internal/comp" } }, - .norms = 3, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, .tvn = { &f50sqpixel, &f60sqpixel, @@ -524,7 +521,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 2, "S-Video" }, { 0, "Internal/comp" } }, - .norms = 3, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, .tvn = { &f50sqpixel_dc10, &f60sqpixel_dc10, @@ -553,7 +550,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 2, "S-Video" }, { 0, "Internal/comp" } }, - .norms = 3, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, .tvn = { &f50sqpixel_dc10, &f60sqpixel_dc10, @@ -580,7 +577,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 0, "Composite" }, { 7, "S-Video" } }, - .norms = 2, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL, .tvn = { &f50ccir601_lml33, &f60ccir601_lml33, @@ -598,7 +595,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = LML33R10, .name = "LML33R10", - .i2c_decoder = I2C_DRIVERID_SAA7114, + .i2c_decoder = I2C_DRIVERID_SAA711X, .i2c_encoder = I2C_DRIVERID_ADV7170, .video_codec = CODEC_TYPE_ZR36060, @@ -607,7 +604,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 0, "Composite" }, { 7, "S-Video" } }, - .norms = 2, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL, .tvn = { &f50ccir601_lm33r10, &f60ccir601_lm33r10, @@ -625,7 +622,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = BUZ, .name = "Buz", - .i2c_decoder = I2C_DRIVERID_SAA7111A, + .i2c_decoder = I2C_DRIVERID_SAA711X, .i2c_encoder = I2C_DRIVERID_SAA7185B, .video_codec = CODEC_TYPE_ZR36060, @@ -634,7 +631,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 3, "Composite" }, { 7, "S-Video" } }, - .norms = 3, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, .tvn = { &f50ccir601, &f60ccir601, @@ -671,7 +668,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { {10, "S-Video 3" }, {15, "YCbCr" } }, - .norms = 2, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL, .tvn = { &f50ccir601_avs6eyes, &f60ccir601_avs6eyes, @@ -1087,8 +1084,6 @@ static int __devinit zr36057_init (struct zoran *zr) { int j, err; - int two = 2; - int zero = 0; dprintk(1, KERN_INFO @@ -1114,14 +1109,23 @@ zr36057_init (struct zoran *zr) if (default_norm < VIDEO_MODE_PAL && default_norm > VIDEO_MODE_SECAM) default_norm = VIDEO_MODE_PAL; - zr->norm = default_norm; - if (!(zr->timing = zr->card.tvn[zr->norm])) { + if (default_norm == VIDEO_MODE_PAL) { + zr->norm = V4L2_STD_PAL; + zr->timing = zr->card.tvn[0]; + } else if (default_norm == VIDEO_MODE_NTSC) { + zr->norm = V4L2_STD_NTSC; + zr->timing = zr->card.tvn[1]; + } else { + zr->norm = V4L2_STD_SECAM; + zr->timing = zr->card.tvn[2]; + } + if (zr->timing == NULL) { dprintk(1, KERN_WARNING "%s: zr36057_init() - default TV standard not supported by hardware. PAL will be used.\n", ZR_DEVNAME(zr)); - zr->norm = VIDEO_MODE_PAL; - zr->timing = zr->card.tvn[zr->norm]; + zr->norm = V4L2_STD_PAL; + zr->timing = zr->card.tvn[0]; } if (default_input > zr->card.inputs-1) { @@ -1133,12 +1137,6 @@ zr36057_init (struct zoran *zr) } zr->input = default_input; - /* Should the following be reset at every open ? */ - zr->hue = 32768; - zr->contrast = 32768; - zr->saturation = 32768; - zr->brightness = 32768; - /* default setup (will be repeated at every open) */ zoran_open_init_params(zr); @@ -1174,8 +1172,10 @@ zr36057_init (struct zoran *zr) detect_guest_activity(zr); test_interrupts(zr); if (!pass_through) { - decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero); - encoder_command(zr, ENCODER_SET_INPUT, &two); + struct v4l2_routing route = { 2, 0 }; + + decoder_command(zr, VIDIOC_STREAMOFF, 0); + encoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); } zr->zoran_proc = NULL; diff --git a/linux/drivers/media/video/zoran/zoran_device.c b/linux/drivers/media/video/zoran/zoran_device.c index 592300e2f..8544c9b99 100644 --- a/linux/drivers/media/video/zoran/zoran_device.c +++ b/linux/drivers/media/video/zoran/zoran_device.c @@ -38,6 +38,8 @@ #include #include "compat.h" #include +#include +#include #include #include @@ -313,9 +315,9 @@ zr36057_adjust_vfe (struct zoran *zr, case BUZ_MODE_MOTION_COMPRESS: case BUZ_MODE_IDLE: default: - if (zr->norm == VIDEO_MODE_NTSC || + if ((zr->norm & V4L2_STD_NTSC) || (zr->card.type == LML33R10 && - zr->norm == VIDEO_MODE_PAL)) + (zr->norm & V4L2_STD_PAL))) btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); else btor(ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); @@ -356,14 +358,6 @@ zr36057_set_vfe (struct zoran *zr, dprintk(2, KERN_INFO "%s: set_vfe() - width = %d, height = %d\n", ZR_DEVNAME(zr), video_width, video_height); - if (zr->norm != VIDEO_MODE_PAL && - zr->norm != VIDEO_MODE_NTSC && - zr->norm != VIDEO_MODE_SECAM) { - dprintk(1, - KERN_ERR "%s: set_vfe() - norm = %d not valid\n", - ZR_DEVNAME(zr), zr->norm); - return; - } if (video_width < BUZ_MIN_WIDTH || video_height < BUZ_MIN_HEIGHT || video_width > Wa || video_height > Ha) { @@ -427,7 +421,7 @@ zr36057_set_vfe (struct zoran *zr, * we get the correct colors when uncompressing to the screen */ //reg |= ZR36057_VFESPFR_VCLKPol; /**/ /* RJ: Don't know if that is needed for NTSC also */ - if (zr->norm != VIDEO_MODE_NTSC) + if (!(zr->norm & V4L2_STD_NTSC)) reg |= ZR36057_VFESPFR_ExtFl; // NEEDED!!!!!!! Wolfgang reg |= ZR36057_VFESPFR_TopField; if (HorDcm >= 48) { @@ -982,11 +976,10 @@ void zr36057_enable_jpg (struct zoran *zr, enum zoran_codec_mode mode) { - static int zero; - static int one = 1; struct vfe_settings cap; int field_size = zr->jpg_buffers.buffer_size / zr->jpg_settings.field_per_buff; + struct v4l2_routing route = { 0, 0 }; zr->codec_mode = mode; @@ -1008,8 +1001,9 @@ zr36057_enable_jpg (struct zoran *zr, * the video bus direction set to input. */ set_videobus_dir(zr, 0); - decoder_command(zr, DECODER_ENABLE_OUTPUT, &one); - encoder_command(zr, ENCODER_SET_INPUT, &zero); + decoder_command(zr, VIDIOC_STREAMON, 0); + route.input = 0; + encoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); /* Take the JPEG codec and the VFE out of sleep */ jpeg_codec_sleep(zr, 0); @@ -1055,9 +1049,10 @@ zr36057_enable_jpg (struct zoran *zr, /* In motion decompression mode, the decoder output must be disabled, and * the video bus direction set to output. */ - decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero); + decoder_command(zr, VIDIOC_STREAMOFF, 0); set_videobus_dir(zr, 1); - encoder_command(zr, ENCODER_SET_INPUT, &one); + route.input = 1; + encoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); /* Take the JPEG codec and the VFE out of sleep */ jpeg_codec_sleep(zr, 0); @@ -1101,8 +1096,9 @@ zr36057_enable_jpg (struct zoran *zr, jpeg_codec_sleep(zr, 1); zr36057_adjust_vfe(zr, mode); - decoder_command(zr, DECODER_ENABLE_OUTPUT, &one); - encoder_command(zr, ENCODER_SET_INPUT, &zero); + decoder_command(zr, VIDIOC_STREAMON, 0); + route.input = 0; + encoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); dprintk(2, KERN_INFO "%s: enable_jpg(IDLE)\n", ZR_DEVNAME(zr)); break; @@ -1212,17 +1208,17 @@ zoran_reap_stat_com (struct zoran *zr) static void zoran_restart(struct zoran *zr) { /* Now the stat_comm buffer is ready for restart */ - int status, mode; + int status = 0, mode; if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { - decoder_command(zr, DECODER_GET_STATUS, &status); + decoder_command(zr, VIDIOC_INT_G_INPUT_STATUS, &status); mode = CODEC_DO_COMPRESSION; } else { - status = 0; + status = V4L2_IN_ST_NO_SIGNAL; mode = CODEC_DO_EXPANSION; } if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || - (status & DECODER_STATUS_GOOD)) { + !(status & V4L2_IN_ST_NO_SIGNAL)) { /********** RESTART code *************/ jpeg_codec_reset(zr); zr->codec->set_mode(zr->codec, mode); @@ -1588,7 +1584,7 @@ zoran_set_pci_master (struct zoran *zr, void zoran_init_hardware (struct zoran *zr) { - int j, zero = 0; + struct v4l2_routing route = { 0, 0 }; /* Enable bus-mastering */ zoran_set_pci_master(zr, 1); @@ -1598,15 +1594,16 @@ zoran_init_hardware (struct zoran *zr) zr->card.init(zr); } - j = zr->card.input[zr->input].muxsel; + route.input = zr->card.input[zr->input].muxsel; - decoder_command(zr, 0, NULL); - decoder_command(zr, DECODER_SET_NORM, &zr->norm); - decoder_command(zr, DECODER_SET_INPUT, &j); + decoder_command(zr, VIDIOC_INT_INIT, NULL); + decoder_command(zr, VIDIOC_S_STD, &zr->norm); + decoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); - encoder_command(zr, 0, NULL); - encoder_command(zr, ENCODER_SET_NORM, &zr->norm); - encoder_command(zr, ENCODER_SET_INPUT, &zero); + encoder_command(zr, VIDIOC_INT_INIT, NULL); + encoder_command(zr, VIDIOC_INT_S_STD_OUTPUT, &zr->norm); + route.input = 0; + encoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); /* toggle JPEG codec sleep to sync PLL */ jpeg_codec_sleep(zr, 1); @@ -1680,7 +1677,7 @@ decoder_command (struct zoran *zr, return -EIO; if (zr->card.type == LML33 && - (cmd == DECODER_SET_NORM || cmd == DECODER_SET_INPUT)) { + (cmd == VIDIOC_S_STD || cmd == VIDIOC_INT_S_VIDEO_ROUTING)) { int res; // Bt819 needs to reset its FIFO buffer using #FRST pin and diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index e67c6caac..5145d2921 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -1146,9 +1146,10 @@ zoran_close(struct file *file) zoran_set_pci_master(zr, 0); if (!pass_through) { /* Switch to color bar */ - int zero = 0, two = 2; - decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero); - encoder_command(zr, ENCODER_SET_INPUT, &two); + struct v4l2_routing route = { 2, 0 }; + + decoder_command(zr, VIDIOC_STREAMOFF, 0); + encoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); } } @@ -1570,9 +1571,9 @@ zoran_v4l2_buffer_status (struct file *file, static int zoran_set_norm (struct zoran *zr, - int norm) /* VIDEO_MODE_* */ + v4l2_std_id norm) { - int norm_encoder, on; + int on; if (zr->v4l_buffers.active != ZORAN_FREE || zr->jpg_buffers.active != ZORAN_FREE) { @@ -1599,52 +1600,42 @@ zoran_set_norm (struct zoran *zr, } } - if (norm != VIDEO_MODE_AUTO && - (norm < 0 || norm >= zr->card.norms || - !zr->card.tvn[norm])) { + if (!(norm & zr->card.norms)) { dprintk(1, - KERN_ERR "%s: set_norm() - unsupported norm %d\n", + KERN_ERR "%s: set_norm() - unsupported norm %llx\n", ZR_DEVNAME(zr), norm); return -EINVAL; } - if (norm == VIDEO_MODE_AUTO) { - int status; + if (norm == V4L2_STD_ALL) { + int status = 0; + v4l2_std_id std = 0; - /* if we have autodetect, ... */ - struct video_decoder_capability caps; - decoder_command(zr, DECODER_GET_CAPABILITIES, &caps); - if (!(caps.flags & VIDEO_DECODER_AUTO)) { - dprintk(1, KERN_ERR "%s: norm=auto unsupported\n", - ZR_DEVNAME(zr)); - return -EINVAL; - } - - decoder_command(zr, DECODER_SET_NORM, &norm); + decoder_command(zr, VIDIOC_QUERYSTD, &std); + decoder_command(zr, VIDIOC_S_STD, &std); /* let changes come into effect */ ssleep(2); - decoder_command(zr, DECODER_GET_STATUS, &status); - if (!(status & DECODER_STATUS_GOOD)) { + decoder_command(zr, VIDIOC_INT_G_INPUT_STATUS, &status); + if (status & V4L2_IN_ST_NO_SIGNAL) { dprintk(1, KERN_ERR "%s: set_norm() - no norm detected\n", ZR_DEVNAME(zr)); /* reset norm */ - decoder_command(zr, DECODER_SET_NORM, &zr->norm); + decoder_command(zr, VIDIOC_S_STD, &zr->norm); return -EIO; } - if (status & DECODER_STATUS_NTSC) - norm = VIDEO_MODE_NTSC; - else if (status & DECODER_STATUS_SECAM) - norm = VIDEO_MODE_SECAM; - else - norm = VIDEO_MODE_PAL; + norm = std; } - zr->timing = zr->card.tvn[norm]; - norm_encoder = norm; + if (norm & V4L2_STD_SECAM) + zr->timing = zr->card.tvn[2]; + else if (norm & V4L2_STD_NTSC) + zr->timing = zr->card.tvn[1]; + else + zr->timing = zr->card.tvn[0]; /* We switch overlay off and on since a change in the * norm needs different VFE settings */ @@ -1652,8 +1643,8 @@ zoran_set_norm (struct zoran *zr, if (on) zr36057_overlay(zr, 0); - decoder_command(zr, DECODER_SET_NORM, &norm); - encoder_command(zr, ENCODER_SET_NORM, &norm_encoder); + decoder_command(zr, VIDIOC_S_STD, &norm); + encoder_command(zr, VIDIOC_INT_S_STD_OUTPUT, &norm); if (on) zr36057_overlay(zr, 1); @@ -1668,7 +1659,7 @@ static int zoran_set_input (struct zoran *zr, int input) { - int realinput; + struct v4l2_routing route = { 0, 0 }; if (input == zr->input) { return 0; @@ -1691,10 +1682,10 @@ zoran_set_input (struct zoran *zr, return -EINVAL; } - realinput = zr->card.input[input].muxsel; + route.input = zr->card.input[input].muxsel; zr->input = input; - decoder_command(zr, DECODER_SET_INPUT, &realinput); + decoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); return 0; } @@ -1723,7 +1714,13 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) mutex_lock(&zr->resource_lock); - bparams->norm = zr->norm; + if (zr->norm & V4L2_STD_NTSC) + bparams->norm = VIDEO_MODE_NTSC; + else if (zr->norm & V4L2_STD_PAL) + bparams->norm = VIDEO_MODE_PAL; + else + bparams->norm = VIDEO_MODE_SECAM; + bparams->input = zr->input; bparams->decimation = fh->jpg_settings.decimation; @@ -1906,7 +1903,9 @@ jpgreqbuf_unlock_and_return: case BUZIOC_G_STATUS: { struct zoran_status *bstat = arg; - int norm, input, status, res = 0; + struct v4l2_routing route = { 0, 0 }; + int status = 0, res = 0; + v4l2_std_id norm; dprintk(3, KERN_DEBUG "%s: BUZIOC_G_STATUS\n", ZR_DEVNAME(zr)); @@ -1918,8 +1917,7 @@ jpgreqbuf_unlock_and_return: return -EINVAL; } - input = zr->card.input[bstat->input].muxsel; - norm = VIDEO_MODE_AUTO; + route.input = zr->card.input[bstat->input].muxsel; mutex_lock(&zr->resource_lock); @@ -1932,34 +1930,33 @@ jpgreqbuf_unlock_and_return: goto gstat_unlock_and_return; } - decoder_command(zr, DECODER_SET_INPUT, &input); - decoder_command(zr, DECODER_SET_NORM, &norm); + decoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); /* sleep 1 second */ ssleep(1); /* Get status of video decoder */ - decoder_command(zr, DECODER_GET_STATUS, &status); + decoder_command(zr, VIDIOC_QUERYSTD, &norm); + decoder_command(zr, VIDIOC_INT_G_INPUT_STATUS, &status); /* restore previous input and norm */ - input = zr->card.input[zr->input].muxsel; - decoder_command(zr, DECODER_SET_INPUT, &input); - decoder_command(zr, DECODER_SET_NORM, &zr->norm); + route.input = zr->card.input[zr->input].muxsel; + decoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); gstat_unlock_and_return: mutex_unlock(&zr->resource_lock); if (!res) { bstat->signal = - (status & DECODER_STATUS_GOOD) ? 1 : 0; - if (status & DECODER_STATUS_NTSC) + (status & V4L2_IN_ST_NO_SIGNAL) ? 0 : 1; + if (norm & V4L2_STD_NTSC) bstat->norm = VIDEO_MODE_NTSC; - else if (status & DECODER_STATUS_SECAM) + else if (norm & V4L2_STD_SECAM) bstat->norm = VIDEO_MODE_SECAM; else bstat->norm = VIDEO_MODE_PAL; bstat->color = - (status & DECODER_STATUS_COLOR) ? 1 : 0; + (status & V4L2_IN_ST_NO_COLOR) ? 0 : 1; } return res; @@ -2868,37 +2865,15 @@ strmoff_unlock_and_return: static int zoran_queryctrl(struct file *file, void *__fh, struct v4l2_queryctrl *ctrl) { + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + /* we only support hue/saturation/contrast/brightness */ if (ctrl->id < V4L2_CID_BRIGHTNESS || ctrl->id > V4L2_CID_HUE) return -EINVAL; - else { - int id = ctrl->id; - memset(ctrl, 0, sizeof(*ctrl)); - ctrl->id = id; - } - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - strncpy(ctrl->name, "Brightness", sizeof(ctrl->name)-1); - break; - case V4L2_CID_CONTRAST: - strncpy(ctrl->name, "Contrast", sizeof(ctrl->name)-1); - break; - case V4L2_CID_SATURATION: - strncpy(ctrl->name, "Saturation", sizeof(ctrl->name)-1); - break; - case V4L2_CID_HUE: - strncpy(ctrl->name, "Hue", sizeof(ctrl->name)-1); - break; - } - ctrl->minimum = 0; - ctrl->maximum = 65535; - ctrl->step = 1; - ctrl->default_value = 32768; - ctrl->type = V4L2_CTRL_TYPE_INTEGER; - ctrl->flags = V4L2_CTRL_FLAG_SLIDER; + decoder_command(zr, VIDIOC_QUERYCTRL, ctrl); return 0; } @@ -2914,20 +2889,7 @@ static int zoran_g_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl return -EINVAL; mutex_lock(&zr->resource_lock); - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - ctrl->value = zr->brightness; - break; - case V4L2_CID_CONTRAST: - ctrl->value = zr->contrast; - break; - case V4L2_CID_SATURATION: - ctrl->value = zr->saturation; - break; - case V4L2_CID_HUE: - ctrl->value = zr->hue; - break; - } + decoder_command(zr, VIDIOC_G_CTRL, ctrl); mutex_unlock(&zr->resource_lock); return 0; @@ -2937,42 +2899,14 @@ static int zoran_s_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl { struct zoran_fh *fh = __fh; struct zoran *zr = fh->zr; - struct video_picture pict; /* we only support hue/saturation/contrast/brightness */ if (ctrl->id < V4L2_CID_BRIGHTNESS || ctrl->id > V4L2_CID_HUE) return -EINVAL; - if (ctrl->value < 0 || ctrl->value > 65535) { - dprintk(1, KERN_ERR - "%s: VIDIOC_S_CTRL - invalid value %d for id=%d\n", - ZR_DEVNAME(zr), ctrl->value, ctrl->id); - return -EINVAL; - } - mutex_lock(&zr->resource_lock); - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - zr->brightness = ctrl->value; - break; - case V4L2_CID_CONTRAST: - zr->contrast = ctrl->value; - break; - case V4L2_CID_SATURATION: - zr->saturation = ctrl->value; - break; - case V4L2_CID_HUE: - zr->hue = ctrl->value; - break; - } - pict.brightness = zr->brightness; - pict.contrast = zr->contrast; - pict.colour = zr->saturation; - pict.hue = zr->hue; - - decoder_command(zr, DECODER_SET_PICTURE, &pict); - + decoder_command(zr, VIDIOC_S_CTRL, ctrl); mutex_unlock(&zr->resource_lock); return 0; @@ -2982,24 +2916,10 @@ static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std) { struct zoran_fh *fh = __fh; struct zoran *zr = fh->zr; - int norm; mutex_lock(&zr->resource_lock); - norm = zr->norm; + *std = zr->norm; mutex_unlock(&zr->resource_lock); - - switch (norm) { - case VIDEO_MODE_PAL: - *std = V4L2_STD_PAL; - break; - case VIDEO_MODE_NTSC: - *std = V4L2_STD_NTSC; - break; - case VIDEO_MODE_SECAM: - *std = V4L2_STD_SECAM; - break; - } - return 0; } @@ -3007,25 +2927,10 @@ static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id *std) { struct zoran_fh *fh = __fh; struct zoran *zr = fh->zr; - int norm = -1, res = 0; - - if ((*std & V4L2_STD_PAL) && !(*std & ~V4L2_STD_PAL)) - norm = VIDEO_MODE_PAL; - else if ((*std & V4L2_STD_NTSC) && !(*std & ~V4L2_STD_NTSC)) - norm = VIDEO_MODE_NTSC; - else if ((*std & V4L2_STD_SECAM) && !(*std & ~V4L2_STD_SECAM)) - norm = VIDEO_MODE_SECAM; - else if (*std == V4L2_STD_ALL) - norm = VIDEO_MODE_AUTO; - else { - dprintk(1, KERN_ERR - "%s: VIDIOC_S_STD - invalid norm 0x%llx\n", - ZR_DEVNAME(zr), (unsigned long long)*std); - return -EINVAL; - } + int res = 0; mutex_lock(&zr->resource_lock); - res = zoran_set_norm(zr, norm); + res = zoran_set_norm(zr, *std); if (res) goto sstd_unlock_and_return; @@ -3040,7 +2945,6 @@ static int zoran_enum_input(struct file *file, void *__fh, { struct zoran_fh *fh = __fh; struct zoran *zr = fh->zr; - int status; if (inp->index < 0 || inp->index >= zr->card.inputs) return -EINVAL; @@ -3057,16 +2961,8 @@ static int zoran_enum_input(struct file *file, void *__fh, /* Get status of video decoder */ mutex_lock(&zr->resource_lock); - decoder_command(zr, DECODER_GET_STATUS, &status); + decoder_command(zr, VIDIOC_INT_G_INPUT_STATUS, &inp->status); mutex_unlock(&zr->resource_lock); - - if (!(status & DECODER_STATUS_GOOD)) { - inp->status |= V4L2_IN_ST_NO_POWER; - inp->status |= V4L2_IN_ST_NO_SIGNAL; - } - if (!(status & DECODER_STATUS_COLOR)) - inp->status |= V4L2_IN_ST_NO_COLOR; - return 0; } -- cgit v1.2.3 From 5ac82a7507d0e50ce9a90a524c6d2d410c1de604 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 21:39:45 +0100 Subject: zoran: clean up some old V4L1 left-overs and remove the MAP_NR macro. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran.h | 3 - linux/drivers/media/video/zoran/zoran_driver.c | 130 ++++++++----------------- 2 files changed, 43 insertions(+), 90 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/zoran/zoran.h b/linux/drivers/media/video/zoran/zoran.h index ee31bfc34..a323eb66e 100644 --- a/linux/drivers/media/video/zoran/zoran.h +++ b/linux/drivers/media/video/zoran/zoran.h @@ -238,9 +238,6 @@ enum gpcs_type { struct zoran_format { char *name; -#ifdef CONFIG_VIDEO_V4L1_COMPAT - int palette; -#endif __u32 fourcc; int colorspace; int depth; diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index 5145d2921..96085b123 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -58,16 +58,6 @@ #include #include -#define MAP_NR(x) virt_to_page(x) -#define ZORAN_VID_TYPE ( \ - VID_TYPE_CAPTURE | \ - VID_TYPE_OVERLAY | \ - VID_TYPE_CLIPPING | \ - VID_TYPE_FRAMERAM | \ - VID_TYPE_SCALES | \ - VID_TYPE_MJPEG_DECODER | \ - VID_TYPE_MJPEG_ENCODER \ - ) #include #include @@ -87,29 +77,12 @@ #include "zoran_device.h" #include "zoran_card.h" - /* we declare some card type definitions here, they mean - * the same as the v4l1 ZORAN_VID_TYPE above, except it's v4l2 */ -#define ZORAN_V4L2_VID_FLAGS ( \ - V4L2_CAP_STREAMING |\ - V4L2_CAP_VIDEO_CAPTURE |\ - V4L2_CAP_VIDEO_OUTPUT |\ - V4L2_CAP_VIDEO_OVERLAY \ - ) - - -#if defined(CONFIG_VIDEO_V4L1_COMPAT) -#define ZFMT(pal, fcc, cs) \ - .palette = (pal), .fourcc = (fcc), .colorspace = (cs) -#else -#define ZFMT(pal, fcc, cs) \ - .fourcc = (fcc), .colorspace = (cs) -#endif const struct zoran_format zoran_formats[] = { { .name = "15-bit RGB LE", - ZFMT(VIDEO_PALETTE_RGB555, - V4L2_PIX_FMT_RGB555, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_RGB555, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 15, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, @@ -117,16 +90,16 @@ const struct zoran_format zoran_formats[] = { ZR36057_VFESPFR_LittleEndian, }, { .name = "15-bit RGB BE", - ZFMT(-1, - V4L2_PIX_FMT_RGB555X, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_RGB555X, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 15, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif, }, { .name = "16-bit RGB LE", - ZFMT(VIDEO_PALETTE_RGB565, - V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_RGB565, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, @@ -134,56 +107,56 @@ const struct zoran_format zoran_formats[] = { ZR36057_VFESPFR_LittleEndian, }, { .name = "16-bit RGB BE", - ZFMT(-1, - V4L2_PIX_FMT_RGB565X, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_RGB565X, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif, }, { .name = "24-bit RGB", - ZFMT(VIDEO_PALETTE_RGB24, - V4L2_PIX_FMT_BGR24, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_BGR24, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 24, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_Pack24, }, { .name = "32-bit RGB LE", - ZFMT(VIDEO_PALETTE_RGB32, - V4L2_PIX_FMT_BGR32, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_BGR32, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 32, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_LittleEndian, }, { .name = "32-bit RGB BE", - ZFMT(-1, - V4L2_PIX_FMT_RGB32, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_RGB32, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 32, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB888, }, { .name = "4:2:2, packed, YUYV", - ZFMT(VIDEO_PALETTE_YUV422, - V4L2_PIX_FMT_YUYV, V4L2_COLORSPACE_SMPTE170M), + .fourcc = V4L2_PIX_FMT_YUYV, + .colorspace = V4L2_COLORSPACE_SMPTE170M, .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_YUV422, }, { .name = "4:2:2, packed, UYVY", - ZFMT(VIDEO_PALETTE_UYVY, - V4L2_PIX_FMT_UYVY, V4L2_COLORSPACE_SMPTE170M), + .fourcc = V4L2_PIX_FMT_UYVY, + .colorspace = V4L2_COLORSPACE_SMPTE170M, .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_YUV422|ZR36057_VFESPFR_LittleEndian, }, { .name = "Hardware-encoded Motion-JPEG", - ZFMT(-1, - V4L2_PIX_FMT_MJPEG, V4L2_COLORSPACE_SMPTE170M), + .fourcc = V4L2_PIX_FMT_MJPEG, + .colorspace = V4L2_COLORSPACE_SMPTE170M, .depth = 0, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_PLAYBACK | @@ -261,7 +234,7 @@ v4l_fbuffer_alloc (struct file *file) virt_to_bus(mem); for (off = 0; off < fh->v4l_buffers.buffer_size; off += PAGE_SIZE) - SetPageReserved(MAP_NR(mem + off)); + SetPageReserved(virt_to_page(mem + off)); dprintk(4, KERN_INFO "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%lx)\n", @@ -292,7 +265,7 @@ v4l_fbuffer_free (struct file *file) mem = fh->v4l_buffers.buffer[i].fbuffer; for (off = 0; off < fh->v4l_buffers.buffer_size; off += PAGE_SIZE) - ClearPageReserved(MAP_NR(mem + off)); + ClearPageReserved(virt_to_page(mem + off)); kfree((void *) fh->v4l_buffers.buffer[i].fbuffer); fh->v4l_buffers.buffer[i].fbuffer = NULL; } @@ -378,7 +351,7 @@ jpg_fbuffer_alloc (struct file *file) cpu_to_le32(((fh->jpg_buffers.buffer_size / 4) << 1) | 1); for (off = 0; off < fh->jpg_buffers.buffer_size; off += PAGE_SIZE) - SetPageReserved(MAP_NR(mem + off)); + SetPageReserved(virt_to_page(mem + off)); } else { /* jpg_bufsize is already page aligned */ for (j = 0; @@ -399,7 +372,7 @@ jpg_fbuffer_alloc (struct file *file) fh->jpg_buffers.buffer[i].frag_tab[2 * j + 1] = cpu_to_le32((PAGE_SIZE / 4) << 1); - SetPageReserved(MAP_NR(mem)); + SetPageReserved(virt_to_page(mem)); } fh->jpg_buffers.buffer[i].frag_tab[2 * j - 1] |= cpu_to_le32(1); @@ -425,6 +398,7 @@ jpg_fbuffer_free (struct file *file) struct zoran *zr = fh->zr; int i, j, off; unsigned char *mem; + __le32 frag_tab; dprintk(4, KERN_DEBUG "%s: jpg_fbuffer_free()\n", ZR_DEVNAME(zr)); @@ -432,48 +406,31 @@ jpg_fbuffer_free (struct file *file) if (!fh->jpg_buffers.buffer[i].frag_tab) continue; - //if (alloc_contig) { if (fh->jpg_buffers.need_contiguous) { - if (fh->jpg_buffers.buffer[i].frag_tab[0]) { - mem = (unsigned char *) bus_to_virt(le32_to_cpu( - fh->jpg_buffers.buffer[i].frag_tab[0])); - for (off = 0; - off < fh->jpg_buffers.buffer_size; - off += PAGE_SIZE) - ClearPageReserved(MAP_NR - (mem + off)); + frag_tab = fh->jpg_buffers.buffer[i].frag_tab[0]; + + if (frag_tab) { + mem = (unsigned char *)bus_to_virt(le32_to_cpu(frag_tab)); + for (off = 0; off < fh->jpg_buffers.buffer_size; off += PAGE_SIZE) + ClearPageReserved(virt_to_page(mem + off)); kfree(mem); fh->jpg_buffers.buffer[i].frag_tab[0] = 0; fh->jpg_buffers.buffer[i].frag_tab[1] = 0; } } else { - for (j = 0; - j < fh->jpg_buffers.buffer_size / PAGE_SIZE; - j++) { - if (!fh->jpg_buffers.buffer[i]. - frag_tab[2 * j]) + for (j = 0; j < fh->jpg_buffers.buffer_size / PAGE_SIZE; j++) { + frag_tab = fh->jpg_buffers.buffer[i].frag_tab[2 * j]; + + if (!frag_tab) break; - ClearPageReserved(MAP_NR - (bus_to_virt - (le32_to_cpu - (fh->jpg_buffers. - buffer[i].frag_tab[2 * - j])))); - free_page((unsigned long) - bus_to_virt - (le32_to_cpu - (fh->jpg_buffers. - buffer[i]. - frag_tab[2 * j]))); - fh->jpg_buffers.buffer[i].frag_tab[2 * j] = - 0; - fh->jpg_buffers.buffer[i].frag_tab[2 * j + - 1] = 0; + ClearPageReserved(virt_to_page(bus_to_virt(le32_to_cpu(frag_tab)))); + free_page((unsigned long)bus_to_virt(le32_to_cpu(frag_tab))); + fh->jpg_buffers.buffer[i].frag_tab[2 * j] = 0; + fh->jpg_buffers.buffer[i].frag_tab[2 * j + 1] = 0; } } - free_page((unsigned long) fh->jpg_buffers.buffer[i]. - frag_tab); + free_page((unsigned long)fh->jpg_buffers.buffer[i].frag_tab); fh->jpg_buffers.buffer[i].frag_tab = NULL; } @@ -2017,11 +1974,10 @@ static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability strncpy(cap->driver, "zoran", sizeof(cap->driver)-1); snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", pci_name(zr->pci_dev)); - cap->version = - KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION, + cap->version = KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION, RELEASE_VERSION); - cap->capabilities = ZORAN_V4L2_VID_FLAGS; - + cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OVERLAY; return 0; } -- cgit v1.2.3 From a9e2b393853fab732f68350caf74d3f8057ed8f1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 22:33:35 +0100 Subject: zoran: change buffer defaults to something that works with tvtime From: Hans Verkuil By popular request increased the default number and size of the buffers to something that tvtime likes. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_card.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/zoran/zoran_card.c b/linux/drivers/media/video/zoran/zoran_card.c index 17c3aaffd..37f75045f 100644 --- a/linux/drivers/media/video/zoran/zoran_card.c +++ b/linux/drivers/media/video/zoran/zoran_card.c @@ -126,8 +126,8 @@ MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)"); */ -int v4l_nbufs = 2; -int v4l_bufsize = 128; /* Everybody should be able to work with this setting */ +int v4l_nbufs = 4; +int v4l_bufsize = 810; /* Everybody should be able to work with this setting */ module_param(v4l_nbufs, int, 0644); MODULE_PARM_DESC(v4l_nbufs, "Maximum number of V4L buffers to use"); module_param(v4l_bufsize, int, 0644); -- cgit v1.2.3 From bb9189ca522bccdf0c7d76b92a5860b074bc0c02 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 22:34:55 +0100 Subject: zoran: TRY_FMT and S_FMT now do the same parameter checks. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_driver.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index 96085b123..66659d479 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -2132,8 +2132,6 @@ static int zoran_try_fmt_vid_out(struct file *file, void *__fh, if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) return -EINVAL; - fmt->fmt.pix.bytesperline = 0; - mutex_lock(&zr->resource_lock); settings = fh->jpg_settings; @@ -2158,6 +2156,14 @@ static int zoran_try_fmt_vid_out(struct file *file, void *__fh, else settings.field_per_buff = 1; + if (settings.HorDcm > 1) { + settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0; + settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH; + } else { + settings.img_x = 0; + settings.img_width = BUZ_MAX_WIDTH; + } + /* check */ res = zoran_check_jpg_settings(zr, &settings, 1); if (res) @@ -2175,6 +2181,8 @@ static int zoran_try_fmt_vid_out(struct file *file, void *__fh, V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&settings); + fmt->fmt.pix.bytesperline = 0; + fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; tryfmt_unlock_and_return: mutex_unlock(&zr->resource_lock); return res; -- cgit v1.2.3 From 7120d49dac791b2c3097ae0522c50bb3ca45be66 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 22:53:47 +0100 Subject: vino: introduce v4l2_device. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/vino.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/vino.c b/linux/drivers/media/video/vino.c index 6b87a55a9..d5c42049b 100644 --- a/linux/drivers/media/video/vino.c +++ b/linux/drivers/media/video/vino.c @@ -36,7 +36,7 @@ #include #include -#include +#include #include #include @@ -295,6 +295,7 @@ struct vino_client { }; struct vino_settings { + struct v4l2_device v4l2_dev; struct vino_channel_settings a; struct vino_channel_settings b; @@ -3999,7 +4000,6 @@ over: ret = POLLIN | POLLRDNORM; error: - return ret; } @@ -4056,7 +4056,7 @@ static const struct v4l2_file_operations vino_fops = { .owner = THIS_MODULE, .open = vino_open, .release = vino_close, - .ioctl = vino_ioctl, + .unlocked_ioctl = vino_ioctl, .mmap = vino_mmap, .poll = vino_poll, }; @@ -4072,27 +4072,27 @@ static struct video_device vdev_template = { static void vino_module_cleanup(int stage) { switch(stage) { - case 10: + case 11: video_unregister_device(vino_drvdata->b.vdev); vino_drvdata->b.vdev = NULL; - case 9: + case 10: video_unregister_device(vino_drvdata->a.vdev); vino_drvdata->a.vdev = NULL; - case 8: + case 9: vino_i2c_del_bus(); - case 7: + case 8: free_irq(SGI_VINO_IRQ, NULL); - case 6: + case 7: if (vino_drvdata->b.vdev) { video_device_release(vino_drvdata->b.vdev); vino_drvdata->b.vdev = NULL; } - case 5: + case 6: if (vino_drvdata->a.vdev) { video_device_release(vino_drvdata->a.vdev); vino_drvdata->a.vdev = NULL; } - case 4: + case 5: /* all entries in dma_cpu dummy table have the same address */ dma_unmap_single(NULL, vino_drvdata->dummy_desc_table.dma_cpu[0], @@ -4102,8 +4102,10 @@ static void vino_module_cleanup(int stage) (void *)vino_drvdata-> dummy_desc_table.dma_cpu, vino_drvdata->dummy_desc_table.dma); - case 3: + case 4: free_page(vino_drvdata->dummy_page); + case 3: + v4l2_device_unregister(&vino_drvdata->v4l2_dev); case 2: kfree(vino_drvdata); case 1: @@ -4158,6 +4160,7 @@ static int vino_probe(void) static int vino_init(void) { dma_addr_t dma_dummy_address; + int err; int i; vino_drvdata = kzalloc(sizeof(struct vino_settings), GFP_KERNEL); @@ -4166,6 +4169,12 @@ static int vino_init(void) return -ENOMEM; } vino_init_stage++; + strlcpy(vino_drvdata->v4l2_dev.name, "vino", + sizeof(vino_drvdata->v4l2_dev.name)); + err = v4l2_device_register(NULL, &vino_drvdata->v4l2_dev); + if (err) + return err; + vino_init_stage++; /* create a dummy dma descriptor */ vino_drvdata->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA); @@ -4243,6 +4252,7 @@ static int vino_init_channel_settings(struct vino_channel_settings *vcs, sizeof(struct video_device)); strcpy(vcs->vdev->name, name); vcs->vdev->release = video_device_release; + vcs->vdev->v4l2_dev = &vino_drvdata->v4l2_dev; video_set_drvdata(vcs->vdev, vcs); @@ -4297,6 +4307,7 @@ static int __init vino_module_init(void) vino_module_cleanup(vino_init_stage); return ret; } + i2c_set_adapdata(&vino_i2c_adapter, &vino_drvdata->v4l2_dev); vino_init_stage++; ret = video_register_device(vino_drvdata->a.vdev, -- cgit v1.2.3 From e8550a40016b1ca262d0fc9502d8d7d868420849 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 23:18:26 +0100 Subject: vino: convert to v4l2_subdev. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/vino.c | 207 +++++++++++++-------------------------- 1 file changed, 67 insertions(+), 140 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/vino.c b/linux/drivers/media/video/vino.c index d5c42049b..8a96ee7db 100644 --- a/linux/drivers/media/video/vino.c +++ b/linux/drivers/media/video/vino.c @@ -287,20 +287,17 @@ struct vino_channel_settings { struct video_device *vdev; }; -struct vino_client { - /* the channel which owns this client: - * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */ - unsigned int owner; - struct i2c_client *driver; -}; - struct vino_settings { struct v4l2_device v4l2_dev; struct vino_channel_settings a; struct vino_channel_settings b; - struct vino_client decoder; - struct vino_client camera; + /* the channel which owns this client: + * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */ + unsigned int decoder_owner; + struct v4l2_subdev *decoder; + unsigned int camera_owner; + struct v4l2_subdev *camera; /* a lock for vino register access */ spinlock_t vino_lock; @@ -340,6 +337,11 @@ static struct sgi_vino *vino; static struct vino_settings *vino_drvdata; +#define camera_call(o, f, args...) \ + v4l2_subdev_call(vino_drvdata->camera, o, f, ##args) +#define decoder_call(o, f, args...) \ + v4l2_subdev_call(vino_drvdata->decoder, o, f, ##args) + static const char *vino_driver_name = "vino"; static const char *vino_driver_description = "SGI VINO"; static const char *vino_bus_name = "GIO64 bus"; @@ -670,66 +672,12 @@ static struct i2c_algo_sgi_data i2c_sgi_vino_data = .ack_timeout = 1000, }; -/* - * There are two possible clients on VINO I2C bus, so we limit usage only - * to them. - */ -static int i2c_vino_client_reg(struct i2c_client *client) -{ - unsigned long flags; - int ret = 0; - - spin_lock_irqsave(&vino_drvdata->input_lock, flags); - switch (client->driver->id) { - case I2C_DRIVERID_SAA7191: - if (vino_drvdata->decoder.driver) - ret = -EBUSY; - else - vino_drvdata->decoder.driver = client; - break; - case I2C_DRIVERID_INDYCAM: - if (vino_drvdata->camera.driver) - ret = -EBUSY; - else - vino_drvdata->camera.driver = client; - break; - default: - ret = -ENODEV; - } - spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); - - return ret; -} - -static int i2c_vino_client_unreg(struct i2c_client *client) -{ - unsigned long flags; - int ret = 0; - - spin_lock_irqsave(&vino_drvdata->input_lock, flags); - if (client == vino_drvdata->decoder.driver) { - if (vino_drvdata->decoder.owner != VINO_NO_CHANNEL) - ret = -EBUSY; - else - vino_drvdata->decoder.driver = NULL; - } else if (client == vino_drvdata->camera.driver) { - if (vino_drvdata->camera.owner != VINO_NO_CHANNEL) - ret = -EBUSY; - else - vino_drvdata->camera.driver = NULL; - } - spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); - - return ret; -} - static struct i2c_adapter vino_i2c_adapter = { .name = "VINO I2C bus", .id = I2C_HW_SGI_VINO, .algo_data = &i2c_sgi_vino_data, - .client_register = &i2c_vino_client_reg, - .client_unregister = &i2c_vino_client_unreg, + .owner = THIS_MODULE, }; static int vino_i2c_add_bus(void) @@ -742,20 +690,6 @@ static int vino_i2c_del_bus(void) return i2c_del_adapter(&vino_i2c_adapter); } -static int i2c_camera_command(unsigned int cmd, void *arg) -{ - return vino_drvdata->camera.driver-> - driver->command(vino_drvdata->camera.driver, - cmd, arg); -} - -static int i2c_decoder_command(unsigned int cmd, void *arg) -{ - return vino_drvdata->decoder.driver-> - driver->command(vino_drvdata->decoder.driver, - cmd, arg); -} - /* VINO framebuffer/DMA descriptor management */ static void vino_free_buffer_with_count(struct vino_framebuffer *fb, @@ -2460,9 +2394,9 @@ static int vino_is_input_owner(struct vino_channel_settings *vcs) switch(vcs->input) { case VINO_INPUT_COMPOSITE: case VINO_INPUT_SVIDEO: - return (vino_drvdata->decoder.owner == vcs->channel); + return vino_drvdata->decoder_owner == vcs->channel; case VINO_INPUT_D1: - return (vino_drvdata->camera.owner == vcs->channel); + return vino_drvdata->camera_owner == vcs->channel; default: return 0; } @@ -2478,24 +2412,22 @@ static int vino_acquire_input(struct vino_channel_settings *vcs) spin_lock_irqsave(&vino_drvdata->input_lock, flags); /* First try D1 and then SAA7191 */ - if (vino_drvdata->camera.driver - && (vino_drvdata->camera.owner == VINO_NO_CHANNEL)) { - i2c_use_client(vino_drvdata->camera.driver); - vino_drvdata->camera.owner = vcs->channel; + if (vino_drvdata->camera + && (vino_drvdata->camera_owner == VINO_NO_CHANNEL)) { + vino_drvdata->camera_owner = vcs->channel; vcs->input = VINO_INPUT_D1; vcs->data_norm = VINO_DATA_NORM_D1; - } else if (vino_drvdata->decoder.driver - && (vino_drvdata->decoder.owner == VINO_NO_CHANNEL)) { + } else if (vino_drvdata->decoder + && (vino_drvdata->decoder_owner == VINO_NO_CHANNEL)) { int input; int data_norm; v4l2_std_id norm; struct v4l2_routing route = { 0, 0 }; - i2c_use_client(vino_drvdata->decoder.driver); input = VINO_INPUT_COMPOSITE; route.input = vino_get_saa7191_input(input); - ret = i2c_decoder_command(VIDIOC_INT_S_VIDEO_ROUTING, &route); + ret = decoder_call(video, s_routing, &route); if (ret) { ret = -EINVAL; goto out; @@ -2506,7 +2438,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs) /* Don't hold spinlocks while auto-detecting norm * as it may take a while... */ - ret = i2c_decoder_command(VIDIOC_QUERYSTD, &norm); + ret = decoder_call(video, querystd, &norm); if (!ret) { for (data_norm = 0; data_norm < 3; data_norm++) { if (vino_data_norms[data_norm].std & norm) @@ -2514,7 +2446,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs) } if (data_norm == 3) data_norm = VINO_DATA_NORM_PAL; - ret = i2c_decoder_command(VIDIOC_S_STD, &norm); + ret = decoder_call(tuner, s_std, norm); } spin_lock_irqsave(&vino_drvdata->input_lock, flags); @@ -2524,7 +2456,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs) goto out; } - vino_drvdata->decoder.owner = vcs->channel; + vino_drvdata->decoder_owner = vcs->channel; vcs->input = input; vcs->data_norm = data_norm; @@ -2569,25 +2501,24 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input) switch (input) { case VINO_INPUT_COMPOSITE: case VINO_INPUT_SVIDEO: - if (!vino_drvdata->decoder.driver) { + if (!vino_drvdata->decoder) { ret = -EINVAL; goto out; } - if (vino_drvdata->decoder.owner == VINO_NO_CHANNEL) { - i2c_use_client(vino_drvdata->decoder.driver); - vino_drvdata->decoder.owner = vcs->channel; + if (vino_drvdata->decoder_owner == VINO_NO_CHANNEL) { + vino_drvdata->decoder_owner = vcs->channel; } - if (vino_drvdata->decoder.owner == vcs->channel) { + if (vino_drvdata->decoder_owner == vcs->channel) { int data_norm; v4l2_std_id norm; struct v4l2_routing route = { 0, 0 }; route.input = vino_get_saa7191_input(input); - ret = i2c_decoder_command(VIDIOC_INT_S_VIDEO_ROUTING, &route); + ret = decoder_call(video, s_routing, &route); if (ret) { - vino_drvdata->decoder.owner = VINO_NO_CHANNEL; + vino_drvdata->decoder_owner = VINO_NO_CHANNEL; ret = -EINVAL; goto out; } @@ -2597,7 +2528,7 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input) /* Don't hold spinlocks while auto-detecting norm * as it may take a while... */ - ret = i2c_decoder_command(VIDIOC_QUERYSTD, &norm); + ret = decoder_call(video, querystd, &norm); if (!ret) { for (data_norm = 0; data_norm < 3; data_norm++) { if (vino_data_norms[data_norm].std & norm) @@ -2605,13 +2536,13 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input) } if (data_norm == 3) data_norm = VINO_DATA_NORM_PAL; - ret = i2c_decoder_command(VIDIOC_S_STD, &norm); + ret = decoder_call(tuner, s_std, norm); } spin_lock_irqsave(&vino_drvdata->input_lock, flags); if (ret) { - vino_drvdata->decoder.owner = VINO_NO_CHANNEL; + vino_drvdata->decoder_owner = VINO_NO_CHANNEL; ret = -EINVAL; goto out; } @@ -2628,36 +2559,31 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input) vcs->data_norm = vcs2->data_norm; } - if (vino_drvdata->camera.owner == vcs->channel) { + if (vino_drvdata->camera_owner == vcs->channel) { /* Transfer the ownership or release the input */ if (vcs2->input == VINO_INPUT_D1) { - vino_drvdata->camera.owner = vcs2->channel; + vino_drvdata->camera_owner = vcs2->channel; } else { - i2c_release_client(vino_drvdata->camera.driver); - vino_drvdata->camera.owner = VINO_NO_CHANNEL; + vino_drvdata->camera_owner = VINO_NO_CHANNEL; } } break; case VINO_INPUT_D1: - if (!vino_drvdata->camera.driver) { + if (!vino_drvdata->camera) { ret = -EINVAL; goto out; } - if (vino_drvdata->camera.owner == VINO_NO_CHANNEL) { - i2c_use_client(vino_drvdata->camera.driver); - vino_drvdata->camera.owner = vcs->channel; - } + if (vino_drvdata->camera_owner == VINO_NO_CHANNEL) + vino_drvdata->camera_owner = vcs->channel; - if (vino_drvdata->decoder.owner == vcs->channel) { + if (vino_drvdata->decoder_owner == vcs->channel) { /* Transfer the ownership or release the input */ if ((vcs2->input == VINO_INPUT_COMPOSITE) || (vcs2->input == VINO_INPUT_SVIDEO)) { - vino_drvdata->decoder.owner = vcs2->channel; + vino_drvdata->decoder_owner = vcs2->channel; } else { - i2c_release_client(vino_drvdata-> - decoder.driver); - vino_drvdata->decoder.owner = VINO_NO_CHANNEL; + vino_drvdata->decoder_owner = VINO_NO_CHANNEL; } } @@ -2694,20 +2620,18 @@ static void vino_release_input(struct vino_channel_settings *vcs) /* Release ownership of the channel * and if the other channel takes input from * the same source, transfer the ownership */ - if (vino_drvdata->camera.owner == vcs->channel) { + if (vino_drvdata->camera_owner == vcs->channel) { if (vcs2->input == VINO_INPUT_D1) { - vino_drvdata->camera.owner = vcs2->channel; + vino_drvdata->camera_owner = vcs2->channel; } else { - i2c_release_client(vino_drvdata->camera.driver); - vino_drvdata->camera.owner = VINO_NO_CHANNEL; + vino_drvdata->camera_owner = VINO_NO_CHANNEL; } - } else if (vino_drvdata->decoder.owner == vcs->channel) { + } else if (vino_drvdata->decoder_owner == vcs->channel) { if ((vcs2->input == VINO_INPUT_COMPOSITE) || (vcs2->input == VINO_INPUT_SVIDEO)) { - vino_drvdata->decoder.owner = vcs2->channel; + vino_drvdata->decoder_owner = vcs2->channel; } else { - i2c_release_client(vino_drvdata->decoder.driver); - vino_drvdata->decoder.owner = VINO_NO_CHANNEL; + vino_drvdata->decoder_owner = VINO_NO_CHANNEL; } } vcs->input = VINO_INPUT_NONE; @@ -2746,7 +2670,7 @@ static int vino_set_data_norm(struct vino_channel_settings *vcs, * as it may take a while... */ norm = vino_data_norms[data_norm].std; - err = i2c_decoder_command(VIDIOC_S_STD, &norm); + err = decoder_call(tuner, s_std, norm); spin_lock_irqsave(&vino_drvdata->input_lock, *flags); @@ -2788,7 +2712,7 @@ static int vino_int_enum_input(struct vino_channel_settings *vcs, __u32 index) unsigned long flags; spin_lock_irqsave(&vino_drvdata->input_lock, flags); - if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) { + if (vino_drvdata->decoder && vino_drvdata->camera) { switch (index) { case 0: input = VINO_INPUT_COMPOSITE; @@ -2800,7 +2724,7 @@ static int vino_int_enum_input(struct vino_channel_settings *vcs, __u32 index) input = VINO_INPUT_D1; break; } - } else if (vino_drvdata->decoder.driver) { + } else if (vino_drvdata->decoder) { switch (index) { case 0: input = VINO_INPUT_COMPOSITE; @@ -2809,7 +2733,7 @@ static int vino_int_enum_input(struct vino_channel_settings *vcs, __u32 index) input = VINO_INPUT_SVIDEO; break; } - } else if (vino_drvdata->camera.driver) { + } else if (vino_drvdata->camera) { switch (index) { case 0: input = VINO_INPUT_D1; @@ -2827,7 +2751,7 @@ static __u32 vino_find_input_index(struct vino_channel_settings *vcs) __u32 index = 0; // FIXME: detect when no inputs available - if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) { + if (vino_drvdata->decoder && vino_drvdata->camera) { switch (vcs->input) { case VINO_INPUT_COMPOSITE: index = 0; @@ -2839,7 +2763,7 @@ static __u32 vino_find_input_index(struct vino_channel_settings *vcs) index = 2; break; } - } else if (vino_drvdata->decoder.driver) { + } else if (vino_drvdata->decoder) { switch (vcs->input) { case VINO_INPUT_COMPOSITE: index = 0; @@ -2848,7 +2772,7 @@ static __u32 vino_find_input_index(struct vino_channel_settings *vcs) index = 1; break; } - } else if (vino_drvdata->camera.driver) { + } else if (vino_drvdata->camera) { switch (vcs->input) { case VINO_INPUT_D1: index = 0; @@ -2897,7 +2821,7 @@ static int vino_enum_input(struct file *file, void *__fh, strcpy(i->name, vino_inputs[input].name); if (input == VINO_INPUT_COMPOSITE || input == VINO_INPUT_SVIDEO) - i2c_decoder_command(VIDIOC_INT_G_INPUT_STATUS, &i->status); + decoder_call(video, g_input_status, &i->status); return 0; } @@ -2954,7 +2878,7 @@ static int vino_querystd(struct file *file, void *__fh, break; case VINO_INPUT_COMPOSITE: case VINO_INPUT_SVIDEO: { - i2c_decoder_command(VIDIOC_QUERYSTD, std); + decoder_call(video, querystd, std); break; } default: @@ -3683,7 +3607,7 @@ static int vino_g_ctrl(struct file *file, void *__fh, if (err) goto out; - err = i2c_camera_command(VIDIOC_G_CTRL, &control); + err = camera_call(core, g_ctrl, control); if (err) err = -EINVAL; break; @@ -3701,7 +3625,7 @@ static int vino_g_ctrl(struct file *file, void *__fh, if (err) goto out; - err = i2c_decoder_command(VIDIOC_G_CTRL, &control); + err = decoder_call(core, g_ctrl, control); if (err) err = -EINVAL; break; @@ -3747,7 +3671,7 @@ static int vino_s_ctrl(struct file *file, void *__fh, err = -ERANGE; goto out; } - err = i2c_camera_command(VIDIOC_S_CTRL, &control); + err = camera_call(core, s_ctrl, control); if (err) err = -EINVAL; break; @@ -3769,7 +3693,7 @@ static int vino_s_ctrl(struct file *file, void *__fh, goto out; } - err = i2c_decoder_command(VIDIOC_S_CTRL, &control); + err = decoder_call(core, s_ctrl, control); if (err) err = -EINVAL; break; @@ -4261,6 +4185,7 @@ static int vino_init_channel_settings(struct vino_channel_settings *vcs, static int __init vino_module_init(void) { + unsigned short addr[] = { 0, I2C_CLIENT_END }; int ret; printk(KERN_INFO "SGI VINO driver version %s\n", @@ -4330,10 +4255,12 @@ static int __init vino_module_init(void) } vino_init_stage++; -#ifdef MODULE - request_module("saa7191"); - request_module("indycam"); -#endif + addr[0] = 0x45; + vino_drvdata->decoder = v4l2_i2c_new_probed_subdev(&vino_i2c_adapter, + "saa7191", "saa7191", addr); + addr[0] = 0x2b; + vino_drvdata->camera = v4l2_i2c_new_probed_subdev(&vino_i2c_adapter, + "indycam", "indycam", addr); dprintk("init complete!\n"); -- cgit v1.2.3 From 662eeaff4dbeccc9958ac8d31e8b50b9fb058b4c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 23:23:43 +0100 Subject: saa7191, indycam: remove compat code. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/indycam.c | 17 +++-------------- linux/drivers/media/video/saa7191.c | 17 +++-------------- 2 files changed, 6 insertions(+), 28 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/indycam.c b/linux/drivers/media/video/indycam.c index 9c09fe1b8..f2da0550b 100644 --- a/linux/drivers/media/video/indycam.c +++ b/linux/drivers/media/video/indycam.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include "indycam.h" @@ -35,9 +35,11 @@ MODULE_VERSION(INDYCAM_MODULE_VERSION); MODULE_AUTHOR("Mikael Nousiainen "); MODULE_LICENSE("GPL"); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) static unsigned short normal_i2c[] = { 0x56 >> 1, I2C_CLIENT_END }; I2C_CLIENT_INSMOD; +#endif // #define INDYCAM_DEBUG @@ -297,11 +299,6 @@ static int indycam_g_chip_ident(struct v4l2_subdev *sd, camera->version); } -static int indycam_command(struct i2c_client *client, unsigned cmd, void *arg) -{ - return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); -} - /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops indycam_core_ops = { @@ -380,11 +377,6 @@ static int indycam_remove(struct i2c_client *client) return 0; } -static int indycam_legacy_probe(struct i2c_adapter *adapter) -{ - return adapter->id == I2C_HW_SGI_VINO; -} - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) static const struct i2c_device_id indycam_id[] = { { "indycam", 0 }, @@ -395,11 +387,8 @@ MODULE_DEVICE_TABLE(i2c, indycam_id); #endif static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "indycam", - .driverid = I2C_DRIVERID_INDYCAM, - .command = indycam_command, .probe = indycam_probe, .remove = indycam_remove, - .legacy_probe = indycam_legacy_probe, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) .id_table = indycam_id, #endif diff --git a/linux/drivers/media/video/saa7191.c b/linux/drivers/media/video/saa7191.c index 970b99924..9df505e0f 100644 --- a/linux/drivers/media/video/saa7191.c +++ b/linux/drivers/media/video/saa7191.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include "compat.h" #include "saa7191.h" @@ -35,9 +35,11 @@ MODULE_VERSION(SAA7191_MODULE_VERSION); MODULE_AUTHOR("Mikael Nousiainen "); MODULE_LICENSE("GPL"); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) static unsigned short normal_i2c[] = { 0x8a >> 1, 0x8e >> 1, I2C_CLIENT_END }; I2C_CLIENT_INSMOD; +#endif // #define SAA7191_DEBUG @@ -580,11 +582,6 @@ static int saa7191_g_chip_ident(struct v4l2_subdev *sd, return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7191, 0); } -static int saa7191_command(struct i2c_client *client, unsigned cmd, void *arg) -{ - return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); -} - /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops saa7191_core_ops = { @@ -653,11 +650,6 @@ static int saa7191_remove(struct i2c_client *client) return 0; } -static int saa7191_legacy_probe(struct i2c_adapter *adapter) -{ - return adapter->id == I2C_HW_SGI_VINO; -} - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) static const struct i2c_device_id saa7191_id[] = { { "saa7191", 0 }, @@ -668,11 +660,8 @@ MODULE_DEVICE_TABLE(i2c, saa7191_id); #endif static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "saa7191", - .driverid = I2C_DRIVERID_SAA7191, - .command = saa7191_command, .probe = saa7191_probe, .remove = saa7191_remove, - .legacy_probe = saa7191_legacy_probe, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) .id_table = saa7191_id, #endif -- cgit v1.2.3 From 353efa42bb001bd99872fdedd37a76d4fc085b23 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 19 Feb 2009 08:49:29 +0100 Subject: bt866: convert to v4l2_subdev. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/bt866.c | 231 ++++++++++++++++++---------------- linux/include/media/v4l2-chip-ident.h | 3 + 2 files changed, 125 insertions(+), 109 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt866.c b/linux/drivers/media/video/bt866.c index 5aed3c7f1..9f53b8176 100644 --- a/linux/drivers/media/video/bt866.c +++ b/linux/drivers/media/video/bt866.c @@ -34,9 +34,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include "compat.h" @@ -48,21 +48,25 @@ static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); +static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD; + /* ----------------------------------------------------------------------- */ struct bt866 { + struct v4l2_subdev sd; u8 reg[256]; - - v4l2_std_id norm; - int bright; - int contrast; - int hue; - int sat; }; -static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data) +static inline struct bt866 *to_bt866(struct v4l2_subdev *sd) { - struct bt866 *encoder = i2c_get_clientdata(client); + return container_of(sd, struct bt866, sd); +} + +static int bt866_write(struct bt866 *encoder, u8 subaddr, u8 data) +{ + struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd); u8 buffer[2]; int err; @@ -89,119 +93,125 @@ static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data) return 0; } -static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) +static int bt866_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std) { - struct bt866 *encoder = i2c_get_clientdata(client); + v4l2_dbg(1, debug, sd, "set norm %llx\n", std); - switch (cmd) { - case VIDIOC_INT_S_STD_OUTPUT: - { - v4l2_std_id *iarg = arg; - - v4l_dbg(1, debug, client, "set norm %llx\n", *iarg); + /* Only PAL supported by this driver at the moment! */ + if (!(std & V4L2_STD_NTSC)) + return -EINVAL; + return 0; +} - if (!(*iarg & (V4L2_STD_NTSC | V4L2_STD_PAL))) - return -EINVAL; - encoder->norm = *iarg; +static int bt866_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route) +{ + static const __u8 init[] = { + 0xc8, 0xcc, /* CRSCALE */ + 0xca, 0x91, /* CBSCALE */ + 0xcc, 0x24, /* YC16 | OSDNUM */ + 0xda, 0x00, /* */ + 0xdc, 0x24, /* SETMODE | PAL */ + 0xde, 0x02, /* EACTIVE */ + + /* overlay colors */ + 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */ + 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */ + 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */ + 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */ + 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */ + 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */ + 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */ + 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */ + + 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */ + 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */ + 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */ + 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */ + 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */ + 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */ + 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */ + 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */ + }; + struct bt866 *encoder = to_bt866(sd); + u8 val; + int i; + + for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2) + bt866_write(encoder, init[i], init[i+1]); + + val = encoder->reg[0xdc]; + + if (route->input == 0) + val |= 0x40; /* CBSWAP */ + else + val &= ~0x40; /* !CBSWAP */ + + bt866_write(encoder, 0xdc, val); + + val = encoder->reg[0xcc]; + if (route->input == 2) + val |= 0x01; /* OSDBAR */ + else + val &= ~0x01; /* !OSDBAR */ + bt866_write(encoder, 0xcc, val); + + v4l2_dbg(1, debug, sd, "set input %d\n", route->input); + + switch (route->input) { + case 0: + case 1: + case 2: break; + default: + return -EINVAL; } + return 0; +} - case VIDIOC_INT_S_VIDEO_ROUTING: - { - struct v4l2_routing *route = arg; - static const __u8 init[] = { - 0xc8, 0xcc, /* CRSCALE */ - 0xca, 0x91, /* CBSCALE */ - 0xcc, 0x24, /* YC16 | OSDNUM */ - 0xda, 0x00, /* */ - 0xdc, 0x24, /* SETMODE | PAL */ - 0xde, 0x02, /* EACTIVE */ - - /* overlay colors */ - 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */ - 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */ - 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */ - 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */ - 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */ - 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */ - 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */ - 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */ - - 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */ - 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */ - 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */ - 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */ - 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */ - 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */ - 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */ - 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */ - }; - int i; - u8 val; - - for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2) - bt866_write(client, init[i], init[i+1]); - - val = encoder->reg[0xdc]; - - if (route->input == 0) - val |= 0x40; /* CBSWAP */ - else - val &= ~0x40; /* !CBSWAP */ - - bt866_write(client, 0xdc, val); - - val = encoder->reg[0xcc]; - if (route->input == 2) - val |= 0x01; /* OSDBAR */ - else - val &= ~0x01; /* !OSDBAR */ - bt866_write(client, 0xcc, val); - - v4l_dbg(1, debug, client, "set input %d\n", route->input); - - switch (route->input) { - case 0: - break; - case 1: - break; - default: - return -EINVAL; - } - break; - } +#if 0 /* keep */ +/* Code to setup square pixels, might be of some use in the future, + but is currently unused. */ + val = encoder->reg[0xdc]; + if (*iarg) + val |= 1; /* SQUARE */ + else + val &= ~1; /* !SQUARE */ + bt866_write(client, 0xdc, val); +#endif - case 4711: - { - int *iarg = arg; - __u8 val; +static int bt866_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); - v4l_dbg(1, debug, client, "square %d\n", *iarg); + return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT866, 0); +} - val = encoder->reg[0xdc]; - if (*iarg) - val |= 1; /* SQUARE */ - else - val &= ~1; /* !SQUARE */ - bt866_write(client, 0xdc, val); - break; - } +static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); +} - default: - return -EINVAL; - } +/* ----------------------------------------------------------------------- */ - return 0; -} +static const struct v4l2_subdev_core_ops bt866_core_ops = { + .g_chip_ident = bt866_g_chip_ident, +}; -static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; +static const struct v4l2_subdev_video_ops bt866_video_ops = { + .s_std_output = bt866_s_std_output, + .s_routing = bt866_s_routing, +}; -I2C_CLIENT_INSMOD; +static const struct v4l2_subdev_ops bt866_ops = { + .core = &bt866_core_ops, + .video = &bt866_video_ops, +}; static int bt866_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct bt866 *encoder; + struct v4l2_subdev *sd; v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); @@ -209,14 +219,17 @@ static int bt866_probe(struct i2c_client *client, encoder = kzalloc(sizeof(*encoder), GFP_KERNEL); if (encoder == NULL) return -ENOMEM; - - i2c_set_clientdata(client, encoder); + sd = &encoder->sd; + v4l2_i2c_subdev_init(sd, client, &bt866_ops); return 0; } static int bt866_remove(struct i2c_client *client) { - kfree(i2c_get_clientdata(client)); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + + v4l2_device_unregister_subdev(sd); + kfree(to_bt866(sd)); return 0; } diff --git a/linux/include/media/v4l2-chip-ident.h b/linux/include/media/v4l2-chip-ident.h index bbe2bb6a5..cfb236e5a 100644 --- a/linux/include/media/v4l2-chip-ident.h +++ b/linux/include/media/v4l2-chip-ident.h @@ -71,6 +71,9 @@ enum { V4L2_IDENT_CX23416 = 416, V4L2_IDENT_CX23418 = 418, + /* module bt866: just ident 866 */ + V4L2_IDENT_BT866 = 866, + /* module vp27smpx: just ident 2700 */ V4L2_IDENT_VP27SMPX = 2700, -- cgit v1.2.3 From fbef599baf91dd9e8d3926f440a4087b8eaaaeb1 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 23 Feb 2009 16:11:25 +0100 Subject: soc-camera: fix S_CROP breakage on PXA and SuperH From: Guennadi Liakhovetski Recent format-negotiation patches caused S_CROP breakage in pxa_camera.c and sh_mobile_ceu_camera.c drivers, fix it. Signed-off-by: Guennadi Liakhovetski --- drivers/media/video/pxa_camera.c | 26 +++++++++++++------------- drivers/media/video/sh_mobile_ceu_camera.c | 13 +++++-------- 2 files changed, 18 insertions(+), 21 deletions(-) --- linux/drivers/media/video/pxa_camera.c | 26 ++++++++++++------------ linux/drivers/media/video/sh_mobile_ceu_camera.c | 13 +++++------- 2 files changed, 18 insertions(+), 21 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pxa_camera.c b/linux/drivers/media/video/pxa_camera.c index 2c283b82a..b6a34ba18 100644 --- a/linux/drivers/media/video/pxa_camera.c +++ b/linux/drivers/media/video/pxa_camera.c @@ -1164,23 +1164,23 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, { struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct pxa_camera_dev *pcdev = ici->priv; - const struct soc_camera_data_format *host_fmt, *cam_fmt = NULL; - const struct soc_camera_format_xlate *xlate; + 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, }; - int ret, buswidth; + int ret; - xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); - if (!xlate) { - dev_warn(&ici->dev, "Format %x not found\n", pixfmt); - return -EINVAL; - } + if (pixfmt) { + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); + if (!xlate) { + dev_warn(&ici->dev, "Format %x not found\n", pixfmt); + return -EINVAL; + } - buswidth = xlate->buswidth; - host_fmt = xlate->host_fmt; - cam_fmt = xlate->cam_fmt; + 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) @@ -1210,8 +1210,8 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, } if (pixfmt && !ret) { - icd->buswidth = buswidth; - icd->current_fmt = host_fmt; + icd->buswidth = xlate->buswidth; + icd->current_fmt = xlate->host_fmt; } return ret; diff --git a/linux/drivers/media/video/sh_mobile_ceu_camera.c b/linux/drivers/media/video/sh_mobile_ceu_camera.c index ae98eaf5f..ee113de47 100644 --- a/linux/drivers/media/video/sh_mobile_ceu_camera.c +++ b/linux/drivers/media/video/sh_mobile_ceu_camera.c @@ -604,21 +604,18 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, const struct soc_camera_format_xlate *xlate; int ret; + if (!pixfmt) + return icd->ops->set_fmt(icd, pixfmt, rect); + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); if (!xlate) { dev_warn(&ici->dev, "Format %x not found\n", pixfmt); return -EINVAL; } - switch (pixfmt) { - case 0: /* Only geometry change */ - ret = icd->ops->set_fmt(icd, pixfmt, rect); - break; - default: - ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect); - } + ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect); - if (pixfmt && !ret) { + if (!ret) { icd->buswidth = xlate->buswidth; icd->current_fmt = xlate->host_fmt; pcdev->camera_fmt = xlate->cam_fmt; -- cgit v1.2.3 From bc4a98a515e5988ced76cd09ff64046835528fde Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 19 Feb 2009 10:25:22 +0100 Subject: add SuperH files we need for video patches Signed-off-by: Guennadi Liakhovetski kernel-sync: --- --- linux/arch/sh/boards/board-ap325rxa.c | 525 +++++++++++++++++++++++++++++ linux/arch/sh/boards/mach-migor/setup.c | 578 ++++++++++++++++++++++++++++++++ 2 files changed, 1103 insertions(+) create mode 100644 linux/arch/sh/boards/board-ap325rxa.c create mode 100644 linux/arch/sh/boards/mach-migor/setup.c (limited to 'linux') diff --git a/linux/arch/sh/boards/board-ap325rxa.c b/linux/arch/sh/boards/board-ap325rxa.c new file mode 100644 index 000000000..7c35787d2 --- /dev/null +++ b/linux/arch/sh/boards/board-ap325rxa.c @@ -0,0 +1,525 @@ +/* + * Renesas - AP-325RXA + * (Compatible with Algo System ., LTD. - AP-320A) + * + * Copyright (C) 2008 Renesas Solutions Corp. + * Author : Yusuke Goda + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include