From e49df2de9c7938517f8047293228eb4b8f17e763 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 18 Jan 2008 06:53:26 -0200 Subject: Remove sound/driver.h From: Mauro Carvalho Chehab sound/driver.h is already included by sound/core. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-audio.c | 1 - 1 file changed, 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 901eeeb5c..be48bcdb6 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From 55d0724f5699252e25c050bd9c30cec1c1e53202 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 18 Jan 2008 08:08:21 -0200 Subject: include sound/driver.h should be before sound/core.h From: Mauro Carvalho Chehab Add compat.h at the proper place Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-audio.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-audio.c b/linux/drivers/media/video/em28xx/em28xx-audio.c index be48bcdb6..e97446778 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -35,6 +35,7 @@ #include #include #include +#include "compat.h" #include #include #include -- cgit v1.2.3 From e07e5abc1bfe38913c72ca97cce4d7b7b034cd1d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 7 Jan 2008 13:45:47 +0000 Subject: Cleans up error handling on or51xxx_attach From: Mauro Carvalho Chehab state is already NULL. Reviewed-by: Trent Piepho Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/or51132.c | 6 +----- linux/drivers/media/dvb/frontends/or51211.c | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/or51132.c b/linux/drivers/media/dvb/frontends/or51132.c index b314a1f2d..1d2d28ce8 100644 --- a/linux/drivers/media/dvb/frontends/or51132.c +++ b/linux/drivers/media/dvb/frontends/or51132.c @@ -564,7 +564,7 @@ struct dvb_frontend* or51132_attach(const struct or51132_config* config, /* Allocate memory for the internal state */ state = kmalloc(sizeof(struct or51132_state), GFP_KERNEL); if (state == NULL) - goto error; + return NULL; /* Setup the state */ state->config = config; @@ -576,10 +576,6 @@ struct dvb_frontend* or51132_attach(const struct or51132_config* config, memcpy(&state->frontend.ops, &or51132_ops, sizeof(struct dvb_frontend_ops)); state->frontend.demodulator_priv = state; return &state->frontend; - -error: - kfree(state); - return NULL; } static struct dvb_frontend_ops or51132_ops = { diff --git a/linux/drivers/media/dvb/frontends/or51211.c b/linux/drivers/media/dvb/frontends/or51211.c index f02bd9445..6a6b0d727 100644 --- a/linux/drivers/media/dvb/frontends/or51211.c +++ b/linux/drivers/media/dvb/frontends/or51211.c @@ -529,7 +529,7 @@ struct dvb_frontend* or51211_attach(const struct or51211_config* config, /* Allocate memory for the internal state */ state = kmalloc(sizeof(struct or51211_state), GFP_KERNEL); if (state == NULL) - goto error; + return NULL; /* Setup the state */ state->config = config; @@ -541,10 +541,6 @@ struct dvb_frontend* or51211_attach(const struct or51211_config* config, memcpy(&state->frontend.ops, &or51211_ops, sizeof(struct dvb_frontend_ops)); state->frontend.demodulator_priv = state; return &state->frontend; - -error: - kfree(state); - return NULL; } static struct dvb_frontend_ops or51211_ops = { -- cgit v1.2.3 From 34ea7bfe97b2fc9f3cb86a3065cbb89e1f43b3af Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 17 Jan 2008 12:54:53 -0500 Subject: fix broken build when CONFIG_USB_SI470X is set From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/radio/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/Makefile b/linux/drivers/media/radio/Makefile index f36cf4e63..a30159f6f 100644 --- a/linux/drivers/media/radio/Makefile +++ b/linux/drivers/media/radio/Makefile @@ -21,6 +21,6 @@ obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o obj-$(CONFIG_RADIO_TRUST) += radio-trust.o obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o obj-$(CONFIG_USB_DSBR) += dsbr100.o -obj-$(CONFIG_USB_SI470X) := radio-si470x.o +obj-$(CONFIG_USB_SI470X) += radio-si470x.o EXTRA_CFLAGS += -Isound -- cgit v1.2.3 From 9a3cca9ddec155f7c751f0e0dbc2facb344f66d9 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 19 Jan 2008 15:41:04 -0500 Subject: tda18271: when tuning digital, the analog demod must be tri-stated From: Michael Krufky Call analog_ops.standby during tda18271_set_params, to put the tda8295 in tri-state when tuning digital channels. Otherwise the tda8295 will interfere with the signal coming from the tda18271 into the digital demodulator. Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/tda18271-fe.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/tda18271-fe.c b/linux/drivers/media/dvb/frontends/tda18271-fe.c index c0dbec28c..b9e857855 100644 --- a/linux/drivers/media/dvb/frontends/tda18271-fe.c +++ b/linux/drivers/media/dvb/frontends/tda18271-fe.c @@ -860,7 +860,6 @@ static int tda18271_set_params(struct dvb_frontend *fe, priv->mode = TDA18271_DIGITAL; - /* see table 22 */ if (fe->ops.info.type == FE_ATSC) { switch (params->u.vsb.modulation) { case VSB_8: @@ -908,6 +907,10 @@ static int tda18271_set_params(struct dvb_frontend *fe, return -EINVAL; } + /* When tuning digital, the analog demod must be tri-stated */ + if (fe->ops.analog_ops.standby) + fe->ops.analog_ops.standby(fe); + ret = tda18271_tune(fe, sgIF * 1000, freq, bw, std, 0); if (ret < 0) -- cgit v1.2.3 From b090817f003069917ffd7610ded68181de8bd9b0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 20 Jan 2008 20:56:43 +0000 Subject: ansonic branded dvb-t usb stick support in the af9005 driver From: Luca Olivetti Marcos Melero (marcosmelero at gmail.com) reported he could make his dvb-t usb stick work with the af9005 driver by changing the device ids (10b9:6000). The stick is branded "Ansonic" (one of the brands of a spanish chain of supermarkets) with no other identification of the model. Since neither Marcos nor me know the OEM for the stick, in the attached patch I used Ansonic for the ids/description. Signed-off-by: Luca Olivetti Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-usb/af9005.c | 7 ++++++- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-usb/af9005.c b/linux/drivers/media/dvb/dvb-usb/af9005.c index 43f546ad9..042bccd0e 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9005.c +++ b/linux/drivers/media/dvb/dvb-usb/af9005.c @@ -1026,6 +1026,7 @@ static int af9005_usb_probe(struct usb_interface *intf, static struct usb_device_id af9005_usb_table[] = { {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9005)}, {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE)}, + {USB_DEVICE(USB_VID_ANSONIC, USB_PID_ANSONIC_DVBT_USB)}, {0}, }; @@ -1075,7 +1076,7 @@ static struct dvb_usb_device_properties af9005_properties = { .rc_key_map_size = 0, .rc_query = af9005_rc_query, - .num_device_descs = 2, + .num_device_descs = 3, .devices = { {.name = "Afatech DVB-T USB1.1 stick", .cold_ids = {&af9005_usb_table[0], NULL}, @@ -1085,6 +1086,10 @@ static struct dvb_usb_device_properties af9005_properties = { .cold_ids = {&af9005_usb_table[1], NULL}, .warm_ids = {NULL}, }, + {.name = "Ansonic DVB-T USB1.1 stick", + .cold_ids = {&af9005_usb_table[2], NULL}, + .warm_ids = {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 c94d993a6..aee5a6ef8 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -15,6 +15,7 @@ #define USB_VID_ALCOR_MICRO 0x058f #define USB_VID_ALINK 0x05e3 #define USB_VID_ANCHOR 0x0547 +#define USB_VID_ANSONIC 0x10b9 #define USB_VID_ANUBIS_ELECTRONIC 0x10fd #define USB_VID_AVERMEDIA 0x07ca #define USB_VID_COMPRO 0x185b @@ -53,6 +54,7 @@ #define USB_PID_ADSTECH_USB2_WARM 0xa334 #define USB_PID_AFATECH_AF9005 0x9020 #define USB_VID_ALINK_DTU 0xf170 +#define USB_PID_ANSONIC_DVBT_USB 0x6000 #define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001 #define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002 #define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800 -- cgit v1.2.3 From 632f4298b8f361925ed848c6117f0e1f57bd4f00 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 21 Jan 2008 08:55:37 -0500 Subject: make tuner names consistent with standard cases From: Michael Krufky Change TDA9887 to tda9887. TDA8290 shall reflect the actual hardware present in its name, ie: tda8295+18271 tda8290+8275a Signed-off-by: Michael Krufky --- linux/drivers/media/video/tda8290.c | 8 ++------ linux/drivers/media/video/tda9887.c | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tda8290.c b/linux/drivers/media/video/tda8290.c index 31bd84600..1bda0024b 100644 --- a/linux/drivers/media/video/tda8290.c +++ b/linux/drivers/media/video/tda8290.c @@ -671,9 +671,6 @@ static int tda8295_probe(struct tuner_i2c_props *i2c_props) } static struct analog_demod_ops tda8290_ops = { - .info = { - .name = "TDA8290", - }, .set_params = tda8290_set_params, .has_signal = tda8290_has_signal, .standby = tda8290_standby, @@ -682,9 +679,6 @@ static struct analog_demod_ops tda8290_ops = { }; static struct analog_demod_ops tda8295_ops = { - .info = { - .name = "TDA8295", - }, .set_params = tda8295_set_params, .has_signal = tda8295_has_signal, .standby = tda8295_standby, @@ -757,6 +751,8 @@ struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, } tuner_info("type set to %s\n", name); + fe->ops.analog_ops.info.name = name; + if (priv->ver & TDA8290) { tda8290_init_tuner(fe); tda8290_init_if(fe); diff --git a/linux/drivers/media/video/tda9887.c b/linux/drivers/media/video/tda9887.c index 5962e39c3..fda15da1f 100644 --- a/linux/drivers/media/video/tda9887.c +++ b/linux/drivers/media/video/tda9887.c @@ -661,7 +661,7 @@ static void tda9887_release(struct dvb_frontend *fe) static struct analog_demod_ops tda9887_ops = { .info = { - .name = "TDA9887", + .name = "tda9887", }, .set_params = tda9887_set_params, .standby = tda9887_standby, -- cgit v1.2.3 From 09729871a743a1ac9a8cc12d1103b5230a49ce28 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 21 Jan 2008 10:01:34 -0500 Subject: tuner: suppress obsolete tuner i2c address warning for XC5000 tuners From: Michael Krufky We already know that the XC5000 tuner can only be located at i2c address 0x61, 0x62, 0x63 or 0x64 We shouldn't display this warning if the XC5000 tuner is present. Signed-off-by: Michael Krufky --- linux/drivers/media/video/tuner-core.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/tuner-core.c b/linux/drivers/media/video/tuner-core.c index 6305998e2..99bba6415 100644 --- a/linux/drivers/media/video/tuner-core.c +++ b/linux/drivers/media/video/tuner-core.c @@ -326,6 +326,12 @@ static void tuner_i2c_address_check(struct tuner *t) ((t->i2c->addr < 0x64) || (t->i2c->addr > 0x6f))) return; + /* We already know that the XC5000 can only be located at + * i2c address 0x61, 0x62, 0x63 or 0x64 */ + if ((t->type == TUNER_XC5000) && + ((t->i2c->addr <= 0x64)) && (t->i2c->addr >= 0x61)) + return; + tuner_warn("====================== WARNING! ======================\n"); tuner_warn("Support for tuners in i2c address range 0x64 thru 0x6f\n"); tuner_warn("will soon be dropped. This message indicates that your\n"); -- cgit v1.2.3 From 0bf19ca136ed9d99a46a8b55ecf2a3e4018e2e56 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 21 Jan 2008 23:00:33 -0500 Subject: IR corrections for the Pinnacle 800i From: Steven Toth IR corrections for the Pinnacle 800i Signed-off-by: Steven Toth Signed-off-by: Chaogui Zhang --- linux/drivers/media/common/ir-keymaps.c | 35 +++++++++++++++++++++++++++++ linux/drivers/media/video/cx88/cx88-input.c | 6 ++++- linux/include/media/ir-common.h | 1 + 3 files changed, 41 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 713d62c85..d3d3c0e5e 100644 --- a/linux/drivers/media/common/ir-keymaps.c +++ b/linux/drivers/media/common/ir-keymaps.c @@ -1899,6 +1899,41 @@ IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE] = { EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce); +/* Pinnacle PCTV HD 800i mini remote */ +IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE] = { + + [0x0f] = KEY_1, + [0x15] = KEY_2, + [0x10] = KEY_3, + [0x18] = KEY_4, + [0x1b] = KEY_5, + [0x1e] = KEY_6, + [0x11] = KEY_7, + [0x21] = KEY_8, + [0x12] = KEY_9, + [0x27] = KEY_0, + + [0x24] = KEY_ZOOM, + [0x2a] = KEY_SUBTITLE, + + [0x00] = KEY_MUTE, + [0x01] = KEY_ENTER, /* Pinnacle Logo */ + [0x39] = KEY_POWER, + + [0x03] = KEY_VOLUMEUP, + [0x09] = KEY_VOLUMEDOWN, + [0x06] = KEY_CHANNELUP, + [0x0c] = KEY_CHANNELDOWN, + + [0x2d] = KEY_REWIND, + [0x30] = KEY_PLAYPAUSE, + [0x33] = KEY_FASTFORWARD, + [0x3c] = KEY_STOP, + [0x36] = KEY_RECORD, + [0x3f] = KEY_EPG, /* Labeled "?" */ +}; +EXPORT_SYMBOL_GPL(ir_codes_pinnacle_pctv_hd); + /* * Igor Kuznetsov * Andrey J. Melnikov diff --git a/linux/drivers/media/video/cx88/cx88-input.c b/linux/drivers/media/video/cx88/cx88-input.c index 66f4423c4..5aaed62eb 100644 --- a/linux/drivers/media/video/cx88/cx88-input.c +++ b/linux/drivers/media/video/cx88/cx88-input.c @@ -237,7 +237,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: case CX88_BOARD_HAUPPAUGE_HVR1100: case CX88_BOARD_HAUPPAUGE_HVR3000: - case CX88_BOARD_PINNACLE_PCTV_HD_800i: ir_codes = ir_codes_hauppauge_new; ir_type = IR_TYPE_RC5; ir->sampling = 1; @@ -319,6 +318,11 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) ir->mask_keycode = 0xfa; ir->polling = 50; /* ms */ break; + case CX88_BOARD_PINNACLE_PCTV_HD_800i: + ir_codes = ir_codes_pinnacle_pctv_hd; + ir_type = IR_TYPE_RC5; + ir->sampling = 1; + break; } if (NULL == ir_codes) { diff --git a/linux/include/media/ir-common.h b/linux/include/media/ir-common.h index 9c2fc09a7..831547d79 100644 --- a/linux/include/media/ir-common.h +++ b/linux/include/media/ir-common.h @@ -141,6 +141,7 @@ extern IR_KEYTAB_TYPE ir_codes_encore_enltv[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE]; #endif -- cgit v1.2.3 From 96c8b3df2a0b219a58a0873511a8fb7b7f6cfd4f Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 21 Jan 2008 23:03:10 -0500 Subject: cx88: Ensure the tuner is reset correctly From: Steven Toth Previous patches assume the tuner was on a different gpio. This patch corrects this. Signed-off-by: Steven Toth Signed-off-by: Chaogui Zhang --- linux/drivers/media/video/cx88/cx88-cards.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx88/cx88-cards.c b/linux/drivers/media/video/cx88/cx88-cards.c index 4adecb6a9..2a972b34f 100644 --- a/linux/drivers/media/video/cx88/cx88-cards.c +++ b/linux/drivers/media/video/cx88/cx88-cards.c @@ -1939,12 +1939,10 @@ int cx88_tuner_callback(void *priv, int command, int arg) switch(core->boardnr) { case CX88_BOARD_PINNACLE_PCTV_HD_800i: if(command == 0) { /* This is the reset command from xc5000 */ - /* Reset XC5000 tuner via GPIO pin #2 */ - cx_set(MO_GP0_IO, 0x00000400); - cx_clear(MO_GP0_IO, 0x00000004); - mdelay(200); - cx_set(MO_GP0_IO, 0x00000004); - mdelay(200); + /* Reset XC5000 tuner via SYS_RSTO_pin */ + cx_write(MO_SRST_IO, 0); + msleep(10); + cx_write(MO_SRST_IO, 1); return 0; } else { -- cgit v1.2.3 From 739286f8598c1606b5ce283e2afcacd8be8cb96a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 24 Jan 2008 07:59:20 -0200 Subject: em28xx: remove has_tuner From: Mauro Carvalho Chehab has_tuner flag doesn't make much sense, since tuner_type=TUNER_ABSENT means the same thing. Having two ways to say that a tuner is not present is not nice, since it may lead to bad setups. In fact, with the previous code, if a device were using has_tuner=0, but the user forces a tuner, with modprobe option tuner=type, the modprobe option won't work. Also, tveeprom returns TUNER_ABSENT, when tuner is unknown or absent. So, with the previous logic, in this case, the driver should set has_tuner=0, or has_tuner=1 otherwise. Instead of adding several additional tests and setups, better just to remove .has_tuner. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-cards.c | 29 ++++++------------------- linux/drivers/media/video/em28xx/em28xx-video.c | 5 +++-- linux/drivers/media/video/em28xx/em28xx.h | 2 -- 3 files changed, 10 insertions(+), 26 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 14f8fe91e..588e85dfa 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -79,7 +79,6 @@ struct em28xx_board em28xx_boards[] = { .is_em2800 = 1, .vchannels = 2, .tda9887_conf = TDA9887_PRESENT, - .has_tuner = 1, .decoder = EM28XX_SAA7113, .input = { { .type = EM28XX_VMUX_COMPOSITE1, @@ -94,13 +93,14 @@ struct em28xx_board em28xx_boards[] = { [EM2820_BOARD_UNKNOWN] = { .name = "Unknown EM2750/28xx video grabber", .is_em2800 = 0, + .tuner_type = TUNER_ABSENT, }, [EM2820_BOARD_KWORLD_PVRTV2800RF] = { .name = "Kworld PVR TV 2800 RF", .is_em2800 = 0, .vchannels = 2, + .tuner_type = TUNER_TEMIC_PAL, .tda9887_conf = TDA9887_PRESENT, - .has_tuner = 1, .decoder = EM28XX_SAA7113, .input = { { .type = EM28XX_VMUX_COMPOSITE1, @@ -117,7 +117,6 @@ struct em28xx_board em28xx_boards[] = { .vchannels = 3, .tuner_type = TUNER_LG_PAL_NEW_TAPC, .tda9887_conf = TDA9887_PRESENT, - .has_tuner = 1, .decoder = EM28XX_SAA7113, .input = { { .type = EM28XX_VMUX_TELEVISION, @@ -138,7 +137,6 @@ struct em28xx_board em28xx_boards[] = { .vchannels = 3, .tuner_type = TUNER_LG_PAL_NEW_TAPC, .tda9887_conf = TDA9887_PRESENT, - .has_tuner = 1, .decoder = EM28XX_SAA7113, .input = { { .type = EM28XX_VMUX_TELEVISION, @@ -161,7 +159,6 @@ struct em28xx_board em28xx_boards[] = { .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE| TDA9887_PORT2_ACTIVE, - .has_tuner = 1, .decoder = EM28XX_TVP5150, .has_msp34xx = 1, /*FIXME: S-Video not tested */ @@ -181,7 +178,6 @@ struct em28xx_board em28xx_boards[] = { .vchannels = 3, .tda9887_conf = TDA9887_PRESENT, .tuner_type = TUNER_XC2028, - .has_tuner = 1, .mts_firmware = 1, .decoder = EM28XX_TVP5150, .input = { { @@ -203,7 +199,6 @@ struct em28xx_board em28xx_boards[] = { .vchannels = 3, .tda9887_conf = TDA9887_PRESENT, .tuner_type = TUNER_XC2028, - .has_tuner = 1, .mts_firmware = 1, .has_12mhz_i2s = 1, .decoder = EM28XX_TVP5150, @@ -228,7 +223,6 @@ struct em28xx_board em28xx_boards[] = { .name = "Terratec Hybrid XS", .vchannels = 3, .tda9887_conf = TDA9887_PRESENT, - .has_tuner = 1, .tuner_type = TUNER_XC2028, .decoder = EM28XX_TVP5150, .input = { { @@ -252,7 +246,6 @@ struct em28xx_board em28xx_boards[] = { .name = "Terratec Prodigy XS", .vchannels = 3, .tda9887_conf = TDA9887_PRESENT, - .has_tuner = 1, .tuner_type = TUNER_XC2028, .decoder = EM28XX_TVP5150, .input = { { @@ -276,7 +269,6 @@ struct em28xx_board em28xx_boards[] = { .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE | TDA9887_PORT2_ACTIVE, - .has_tuner = 1, .max_range_640_480 = 1, .decoder = EM28XX_SAA7114, @@ -300,7 +292,6 @@ struct em28xx_board em28xx_boards[] = { .vchannels = 3, .tuner_type = TUNER_LG_PAL_NEW_TAPC, .tda9887_conf = TDA9887_PRESENT, - .has_tuner = 1, .decoder = EM28XX_SAA7113, .input = { { .type = EM28XX_VMUX_TELEVISION, @@ -322,7 +313,6 @@ struct em28xx_board em28xx_boards[] = { .vchannels = 3, .tuner_type = TUNER_LG_PAL_NEW_TAPC, .tda9887_conf = TDA9887_PRESENT, - .has_tuner = 1, .decoder = EM28XX_SAA7113, .input = { { .type = EM28XX_VMUX_TELEVISION, @@ -344,7 +334,6 @@ struct em28xx_board em28xx_boards[] = { .vchannels = 3, .tuner_type = TUNER_PHILIPS_ATSC, .tda9887_conf = TDA9887_PRESENT, - .has_tuner = 1, .decoder = EM28XX_SAA7113, .input = { { .type = EM28XX_VMUX_TELEVISION, @@ -363,7 +352,7 @@ struct em28xx_board em28xx_boards[] = { [EM2820_BOARD_PINNACLE_DVC_90] = { .name = "Pinnacle Dazzle DVC 90/DVC 100", .vchannels = 3, - .has_tuner = 0, + .tuner_type = TUNER_ABSENT, .decoder = EM28XX_SAA7113, .input = { { .type = EM28XX_VMUX_COMPOSITE1, @@ -381,7 +370,6 @@ struct em28xx_board em28xx_boards[] = { .vchannels = 3, .tuner_type = TUNER_LG_PAL_NEW_TAPC, .tda9887_conf = TDA9887_PRESENT, - .has_tuner = 1, .decoder = EM28XX_SAA7113, .input = { { .type = EM28XX_VMUX_TELEVISION, @@ -401,7 +389,7 @@ struct em28xx_board em28xx_boards[] = { .name = "Pixelview Prolink PlayTV USB 2.0", .vchannels = 3, .tda9887_conf = TDA9887_PRESENT, - .has_tuner = 1, + .tuner_type = TUNER_YMEC_TVF_5533MF, .decoder = EM28XX_SAA7113, .input = { { .type = EM28XX_VMUX_TELEVISION, @@ -552,7 +540,7 @@ static void em28xx_config_tuner(struct em28xx *dev) struct tuner_setup tun_setup; struct v4l2_frequency f; - if (!dev->has_tuner) + if (dev->tuner_type == TUNER_ABSENT) return; tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; @@ -669,7 +657,6 @@ static int em28xx_hint_board(struct em28xx *dev) static void em28xx_set_model(struct em28xx *dev) { dev->is_em2800 = em28xx_boards[dev->model].is_em2800; - dev->has_tuner = em28xx_boards[dev->model].has_tuner; dev->has_msp34xx = em28xx_boards[dev->model].has_msp34xx; dev->tda9887_conf = em28xx_boards[dev->model].tda9887_conf; dev->decoder = em28xx_boards[dev->model].decoder; @@ -677,9 +664,6 @@ static void em28xx_set_model(struct em28xx *dev) dev->analog_gpio = em28xx_boards[dev->model].analog_gpio; dev->has_12mhz_i2s = em28xx_boards[dev->model].has_12mhz_i2s; dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480; - - if (!em28xx_boards[dev->model].has_tuner) - dev->tuner_type = UNSET; } /* ----------------------------------------------------------------------- */ @@ -746,6 +730,7 @@ void em28xx_card_setup(struct em28xx *dev) tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata); dev->tuner_type = tv.tuner_type; + if (tv.audio_processor == AUDIO_CHIP_MSP34XX) { dev->i2s_speed = 2048000; dev->has_msp34xx = 1; @@ -778,7 +763,7 @@ void em28xx_card_setup(struct em28xx *dev) request_module("saa7115"); if (dev->decoder == EM28XX_TVP5150) request_module("tvp5150"); - if (dev->has_tuner) + if (dev->tuner_type != TUNER_ABSENT) request_module("tuner"); #endif diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index cfec27b3a..e5da0ffac 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -40,6 +40,7 @@ #include "em28xx.h" #include #include +#include #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) #include "i2c-compat.h" #endif @@ -953,7 +954,7 @@ static int vidioc_querycap(struct file *file, void *priv, V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; - if (dev->has_tuner) + if (dev->tuner_type != TUNER_ABSENT) cap->capabilities |= V4L2_CAP_TUNER; return 0; @@ -1977,7 +1978,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, em28xx_errdev("cannot allocate video_device.\n"); goto fail_unreg; } - if (dev->has_tuner) + if (dev->tuner_type != TUNER_ABSENT) dev->vdev->type |= VID_TYPE_TUNER; /* register v4l2 video video_device */ diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index 6d7171a89..efabaf6d1 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -164,7 +164,6 @@ struct em28xx_board { unsigned int tda9887_conf; unsigned int is_em2800:1; - unsigned int has_tuner:1; unsigned int has_msp34xx:1; unsigned int mts_firmware:1; unsigned int has_12mhz_i2s:1; @@ -237,7 +236,6 @@ struct em28xx { int devno; /* marks the number of this device */ unsigned int analog_gpio; unsigned int is_em2800:1; - unsigned int has_tuner:1; unsigned int has_msp34xx:1; unsigned int has_tda9887:1; unsigned int stream_on:1; /* Locks streams */ -- cgit v1.2.3 From 79d7a8fa3abdd3bd08fa3347cb2d4bd7b43555af Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 24 Jan 2008 20:29:46 -0500 Subject: xc5000: Fix OOPS caused by missing firmware. From: Steven Toth xc5000: Fix OOPS caused by missing firmware. Signed-off-by: Chaogui Zhang Acked-by: Steven Toth --- linux/drivers/media/dvb/frontends/xc5000.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/xc5000.c b/linux/drivers/media/dvb/frontends/xc5000.c index 5afa58a06..58235d007 100644 --- a/linux/drivers/media/dvb/frontends/xc5000.c +++ b/linux/drivers/media/dvb/frontends/xc5000.c @@ -577,6 +577,7 @@ static int xc5000_fwupload(struct dvb_frontend* fe) if (ret) { printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); ret = XC_RESULT_RESET_FAILURE; + goto out; } else { printk(KERN_INFO "xc5000: firmware read %Zu bytes.\n", fw->size); @@ -591,6 +592,7 @@ static int xc5000_fwupload(struct dvb_frontend* fe) ret = xc_load_i2c_sequence(fe, fw->data ); } +out: release_firmware(fw); return ret; } -- cgit v1.2.3 From 0285dfe9769ebcd653e55697916c73a6b67a68b3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 25 Jan 2008 05:19:48 -0200 Subject: radio-si470x: Some cleanups From: Tobias Lorenz - code reordered to avoid function prototypes - switch/case defaults are now more user-friendly - unified comment style - applied all checkpatch.pl v1.12 suggestions except the warning about the too long lines with bit comments - renamed FMRADIO to RADIO to cut line length (checkpatch.pl) Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/radio-si470x.c | 859 +++++++++++++++---------------- 1 file changed, 415 insertions(+), 444 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index f34900cd4..805c1b403 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -5,7 +5,7 @@ * - Silicon Labs USB FM Radio Reference Design * - ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF) * - * Copyright (c) 2007 Tobias Lorenz + * Copyright (c) 2008 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 +29,7 @@ * Version 1.0.0 * - First working version * 2008-01-13 Tobias Lorenz - * Version 1.0.1 + * Version 1.0.1 * - Improved error handling, every function now returns errno * - Improved multi user access (start/mute/stop) * - Channel doesn't get lost anymore after start/mute/stop @@ -47,6 +47,14 @@ * - check for firmware version 15 * - code order and prototypes still remain the same * - spacing and bottom of band codes remain the same + * 2008-01-16 Tobias Lorenz + * Version 1.0.3 + * - code reordered to avoid function prototypes + * - switch/case defaults are now more user-friendly + * - unified comment style + * - applied all checkpatch.pl v1.12 suggestions + * except the warning about the too long lines with bit comments + * - renamed FMRADIO to RADIO to cut line length (checkpatch.pl) * * ToDo: * - check USB Vendor/Product ID for ADS/Tech FM Radio Receiver @@ -55,13 +63,14 @@ * - add firmware download/update support * - add possibility to switch off RDS * - RDS support: interrupt mode, instead of polling - * - add LED status output + * - add LED status output (check if that's not already done in firmware) */ + /* driver definitions */ #define DRIVER_AUTHOR "Tobias Lorenz " #define DRIVER_NAME "radio-si470x" -#define DRIVER_VERSION KERNEL_VERSION(1, 0, 2) +#define DRIVER_VERSION KERNEL_VERSION(1, 0, 3) #define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver" #define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers" @@ -81,6 +90,21 @@ #include +/* USB Device ID List */ +static struct usb_device_id si470x_usb_driver_id_table[] = { + /* Silicon Labs USB FM Radio Reference Design */ + { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) }, + /* Terminating entry */ + { } +}; +MODULE_DEVICE_TABLE(usb, si470x_usb_driver_id_table); + + + +/************************************************************************** + * Module Parameters + **************************************************************************/ + /* Radio Nr */ static int radio_nr = -1; module_param(radio_nr, int, 0); @@ -146,8 +170,8 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); /************************************************************************** * Register Definitions **************************************************************************/ -#define FMRADIO_REGISTER_SIZE 2 /* 16 register bit width */ -#define FMRADIO_REGISTER_NUM 16 /* DEVICEID ... RDSD */ +#define RADIO_REGISTER_SIZE 2 /* 16 register bit width */ +#define RADIO_REGISTER_NUM 16 /* DEVICEID ... RDSD */ #define RDS_REGISTER_NUM 6 /* STATUSRSSI ... RDSD */ #define DEVICEID 0 /* Device ID */ @@ -237,23 +261,23 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); /************************************************************************** - * USB HID reports + * USB HID Reports **************************************************************************/ /* Reports 1-16 give direct read/write access to the 16 Si470x registers */ /* with the (REPORT_ID - 1) corresponding to the register address across USB */ /* endpoint 0 using GET_REPORT and SET_REPORT */ -#define REGISTER_REPORT_SIZE (FMRADIO_REGISTER_SIZE + 1) +#define REGISTER_REPORT_SIZE (RADIO_REGISTER_SIZE + 1) #define REGISTER_REPORT(reg) ((reg) + 1) /* Report 17 gives direct read/write access to the entire Si470x register */ /* map across endpoint 0 using GET_REPORT and SET_REPORT */ -#define ENTIRE_REPORT_SIZE (FMRADIO_REGISTER_NUM * FMRADIO_REGISTER_SIZE + 1) +#define ENTIRE_REPORT_SIZE (RADIO_REGISTER_NUM * RADIO_REGISTER_SIZE + 1) #define ENTIRE_REPORT 17 /* Report 18 is used to send the lowest 6 Si470x registers up the HID */ /* interrupt endpoint 1 to Windows every 20 milliseconds for status */ -#define RDS_REPORT_SIZE (RDS_REGISTER_NUM * FMRADIO_REGISTER_SIZE + 1) +#define RDS_REPORT_SIZE (RDS_REGISTER_NUM * RADIO_REGISTER_SIZE + 1) #define RDS_REPORT 18 /* Report 19: LED state */ @@ -282,12 +306,12 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); /************************************************************************** - * software/hardware versions + * Software/Hardware Versions **************************************************************************/ -#define FMRADIO_SW_VERSION_NOT_BOOTLOADABLE 6 -#define FMRADIO_SW_VERSION 7 -#define FMRADIO_SW_VERSION_CURRENT 15 -#define FMRADIO_HW_VERSION 1 +#define RADIO_SW_VERSION_NOT_BOOTLOADABLE 6 +#define RADIO_SW_VERSION 7 +#define RADIO_SW_VERSION_CURRENT 15 +#define RADIO_HW_VERSION 1 #define SCRATCH_PAGE_SW_VERSION 1 #define SCRATCH_PAGE_HW_VERSION 2 @@ -295,7 +319,7 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); /************************************************************************** - * LED State definitions + * LED State Definitions **************************************************************************/ #define LED_COMMAND 0x35 @@ -311,7 +335,7 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); /************************************************************************** - * Stream State definitions + * Stream State Definitions **************************************************************************/ #define STREAM_COMMAND 0x36 #define STREAM_VIDPID 0x00 @@ -320,16 +344,16 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); /************************************************************************** - * bootloader / flash commands + * Bootloader / Flash Commands **************************************************************************/ -/* Unique ID sent to bootloader and required to put into a bootload state */ +/* unique id sent to bootloader and required to put into a bootload state */ #define UNIQUE_BL_ID 0x34 -/* Mask for the flash data */ +/* mask for the flash data */ #define FLASH_DATA_MASK 0x55 -/* Bootloader commands */ +/* bootloader commands */ #define GET_SW_VERSION_COMMAND 0x00 #define SET_PAGE_COMMAND 0x01 #define ERASE_PAGE_COMMAND 0x02 @@ -340,12 +364,12 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); #define GET_HW_VERSION_COMMAND 0x07 #define BLANK 0xff -/* Bootloader command responses */ +/* bootloader command responses */ #define COMMAND_OK 0x01 #define COMMAND_FAILED 0x02 #define COMMAND_PENDING 0x03 -/* Buffer sizes */ +/* buffer sizes */ #define COMMAND_BUFFER_SIZE 4 #define RESPONSE_BUFFER_SIZE 2 #define FLASH_BUFFER_SIZE 64 @@ -354,10 +378,12 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); /************************************************************************** - * Driver private definitions + * General Driver Definitions **************************************************************************/ -/* private data */ +/* + * si470x_device - private data + */ struct si470x_device { /* reference to USB and video device */ struct usb_device *usbdev; @@ -370,12 +396,12 @@ struct si470x_device { unsigned char buf[64]; /* Silabs internal registers (0..15) */ - unsigned short registers[FMRADIO_REGISTER_NUM]; + unsigned short registers[RADIO_REGISTER_NUM]; /* RDS receive buffer */ struct work_struct work; struct timer_list timer; - spinlock_t lock; + spinlock_t lock; /* buffer locking */ unsigned char *buffer; unsigned int buf_size; unsigned int rd_index; @@ -386,177 +412,20 @@ struct si470x_device { int data_available_for_read; }; -/* register acccess functions */ -static int si470x_get_report(struct si470x_device *radio, int size); -static int si470x_set_report(struct si470x_device *radio, int size); -static int si470x_get_register(struct si470x_device *radio, int regnr); -static int si470x_set_register(struct si470x_device *radio, int regnr); -static int si470x_get_all_registers(struct si470x_device *radio); -static int si470x_get_rds_registers(struct si470x_device *radio); - -/* high-level functions */ -static int si470x_start(struct si470x_device *radio); -static int si470x_stop(struct si470x_device *radio); -static int si470x_set_chan(struct si470x_device *radio, int chan); -static int si470x_get_freq(struct si470x_device *radio); -static int si470x_set_freq(struct si470x_device *radio, int freq); - -/* RDS functions */ -static void si470x_rds(struct si470x_device *radio); -static void si470x_timer(unsigned long data); -static void si470x_work(struct work_struct *work); - - - -/************************************************************************** - * USB interface definitions - **************************************************************************/ - -/* USB device ID list (Vendor, Product, Class, SubClass, Protocol) */ -static struct usb_device_id si470x_usb_driver_id_table[] = { - /* Silicon Labs USB FM Radio Reference Design */ - { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) }, - /* Terminating entry */ - { } -}; -MODULE_DEVICE_TABLE (usb, si470x_usb_driver_id_table); - -/* USB driver functions */ -static int si470x_usb_driver_probe(struct usb_interface *intf, - const struct usb_device_id *id); -static void si470x_usb_driver_disconnect(struct usb_interface *intf); - -/* USB driver interface */ -static struct usb_driver si470x_usb_driver = { - .name = DRIVER_NAME, - .probe = si470x_usb_driver_probe, - .disconnect = si470x_usb_driver_disconnect, - .id_table = si470x_usb_driver_id_table, -}; - - - -/************************************************************************** - * Video4Linux interface definitions - **************************************************************************/ -/* The frequency is set in units of 62.5 Hz when using V4L2_TUNER_CAP_LOW, */ -/* 62.5 kHz otherwise. */ -/* The tuner is able to have a channel spacing of 50, 100 or 200 kHz. */ -/* tuner->capability is therefore set to V4L2_TUNER_CAP_LOW */ -/* The FREQ_MUL is then: 1 MHz / 62.5 Hz = 16000 */ +/* + * The frequency is set in units of 62.5 Hz when using V4L2_TUNER_CAP_LOW, + * 62.5 kHz otherwise. + * The tuner is able to have a channel spacing of 50, 100 or 200 kHz. + * tuner->capability is therefore set to V4L2_TUNER_CAP_LOW + * The FREQ_MUL is then: 1 MHz / 62.5 Hz = 16000 + */ #define FREQ_MUL (1000000 / 62.5) -/* File operations functions */ -static ssize_t si470x_fops_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos); -static unsigned int si470x_fops_poll(struct file *file, - struct poll_table_struct *pts); -static int si470x_fops_open(struct inode *inode, struct file *file); -static int si470x_fops_release(struct inode *inode, struct file *file); - -/* File operations interface */ -static const struct file_operations si470x_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .read = si470x_fops_read, - .poll = si470x_fops_poll, - .ioctl = video_ioctl2, - .compat_ioctl = v4l_compat_ioctl32, - .open = si470x_fops_open, - .release = si470x_fops_release, -}; - -/* Video device functions */ -static int si470x_vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *capability); -static int si470x_vidioc_g_input(struct file *file, void *priv, - unsigned int *i); -static int si470x_vidioc_s_input(struct file *file, void *priv, - unsigned int i); -static int si470x_vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qc); -static int si470x_vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl); -static int si470x_vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl); -static int si470x_vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *audio); -static int si470x_vidioc_s_audio(struct file *file, void *priv, - struct v4l2_audio *audio); -static int si470x_vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *tuner); -static int si470x_vidioc_s_tuner(struct file *file, void *priv, - struct v4l2_tuner *tuner); -static int si470x_vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *freq); -static int si470x_vidioc_s_frequency(struct file *file, void *priv, - struct v4l2_frequency *freq); - -/* Video device interface */ -static struct video_device si470x_viddev_template = { - .fops = &si470x_fops, - .name = DRIVER_NAME, - .type = VID_TYPE_TUNER, - .release = video_device_release, - .vidioc_querycap = si470x_vidioc_querycap, - .vidioc_g_input = si470x_vidioc_g_input, - .vidioc_s_input = si470x_vidioc_s_input, - .vidioc_queryctrl = si470x_vidioc_queryctrl, - .vidioc_g_ctrl = si470x_vidioc_g_ctrl, - .vidioc_s_ctrl = si470x_vidioc_s_ctrl, - .vidioc_g_audio = si470x_vidioc_g_audio, - .vidioc_s_audio = si470x_vidioc_s_audio, - .vidioc_g_tuner = si470x_vidioc_g_tuner, - .vidioc_s_tuner = si470x_vidioc_s_tuner, - .vidioc_g_frequency = si470x_vidioc_g_frequency, - .vidioc_s_frequency = si470x_vidioc_s_frequency, - .owner = THIS_MODULE, -}; - -/* Query control */ -static struct v4l2_queryctrl radio_queryctrl[] = { -/* HINT: the disabled controls are only here to satify kradio and such apps */ - { - .id = V4L2_CID_AUDIO_VOLUME, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Volume", - .minimum = 0, - .maximum = 15, - .step = 1, - .default_value = 15, - }, - { - .id = V4L2_CID_AUDIO_BALANCE, - .flags = V4L2_CTRL_FLAG_DISABLED, - }, - { - .id = V4L2_CID_AUDIO_BASS, - .flags = V4L2_CTRL_FLAG_DISABLED, - }, - { - .id = V4L2_CID_AUDIO_TREBLE, - .flags = V4L2_CTRL_FLAG_DISABLED, - }, - { - .id = V4L2_CID_AUDIO_MUTE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mute", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - { - .id = V4L2_CID_AUDIO_LOUDNESS, - .flags = V4L2_CTRL_FLAG_DISABLED, - }, -}; - /************************************************************************** - * Driver private functions + * General Driver Functions **************************************************************************/ /* @@ -634,10 +503,10 @@ static int si470x_get_all_registers(struct si470x_device *radio) retval = si470x_get_report(radio, ENTIRE_REPORT_SIZE); if (retval >= 0) - for (regnr = 0; regnr < FMRADIO_REGISTER_NUM; regnr++) + for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++) radio->registers[regnr] = - (radio->buf[regnr * FMRADIO_REGISTER_SIZE + 1] << 8) | - radio->buf[regnr * FMRADIO_REGISTER_SIZE + 2]; + (radio->buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) | + radio->buf[regnr * RADIO_REGISTER_SIZE + 2]; return (retval < 0) ? -EINVAL : 0; } @@ -658,65 +527,13 @@ static int si470x_get_rds_registers(struct si470x_device *radio) usb_rcvctrlpipe(radio->usbdev, 1), radio->buf, RDS_REPORT_SIZE, &size, usb_timeout); - if (retval >= 0) { - for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) { + if (retval >= 0) + for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) radio->registers[STATUSRSSI + regnr] = - (radio->buf[regnr * FMRADIO_REGISTER_SIZE + 1] << 8) | - radio->buf[regnr * FMRADIO_REGISTER_SIZE + 2]; - } - } + (radio->buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) | + radio->buf[regnr * RADIO_REGISTER_SIZE + 2]; - return (retval < 0) ? - EINVAL : 0; -} - - -/* - * si470x_start - switch on radio - */ -static int si470x_start(struct si470x_device *radio) -{ - int retval; - - /* powercfg */ - radio->registers[POWERCFG] = - POWERCFG_DMUTE | POWERCFG_ENABLE | POWERCFG_RDSM; - retval = si470x_set_register(radio, POWERCFG); - if (retval < 0) - return retval; - - /* sysconfig 1 */ - radio->registers[SYSCONFIG1] = - SYSCONFIG1_DE | SYSCONFIG1_RDS; - retval = si470x_set_register(radio, SYSCONFIG1); - if (retval < 0) - return retval; - - /* sysconfig 2 */ - radio->registers[SYSCONFIG2] = - (0x3f << 8) | /* SEEKTH */ - (band << 6) | /* BAND */ - (space << 4) | /* SPACE */ - 15; /* VOLUME (max) */ - retval = si470x_set_register(radio, SYSCONFIG2); - if (retval < 0) - return retval; - - /* reset last channel */ - return si470x_set_chan(radio, - radio->registers[CHANNEL] & CHANNEL_CHAN); -} - - -/* - * si470x_stop - switch off radio - */ -static int si470x_stop(struct si470x_device *radio) -{ - /* powercfg */ - radio->registers[POWERCFG] &= ~POWERCFG_DMUTE; - /* POWERCFG_ENABLE has to automatically go low */ - radio->registers[POWERCFG] |= POWERCFG_ENABLE | POWERCFG_DISABLE; - return si470x_set_register(radio, POWERCFG); + return (retval < 0) ? -EINVAL : 0; } @@ -762,22 +579,22 @@ static int si470x_get_freq(struct si470x_device *radio) /* Spacing (kHz) */ switch (space) { - /* 0: 200 kHz (USA, Australia) */ - default: spacing = 0.200 * FREQ_MUL; break; - /* 1: 100 kHz (Europe, Japan) */ - case 1 : spacing = 0.100 * FREQ_MUL; break; - /* 2: 50 kHz */ - case 2 : spacing = 0.050 * FREQ_MUL; break; + /* 0: 200 kHz (USA, Australia) */ + case 0 : spacing = 0.200 * FREQ_MUL; break; + /* 1: 100 kHz (Europe, Japan) */ + case 1 : spacing = 0.100 * FREQ_MUL; break; + /* 2: 50 kHz */ + default: spacing = 0.050 * FREQ_MUL; break; }; /* Bottom of Band (MHz) */ switch (band) { - /* 0: 87.5 - 108 MHz (USA, Europe) */ - default: band_bottom = 87.5 * FREQ_MUL; break; - /* 1: 76 - 108 MHz (Japan wide band) */ - case 1 : band_bottom = 76 * FREQ_MUL; break; - /* 2: 76 - 90 MHz (Japan) */ - case 2 : band_bottom = 76 * FREQ_MUL; break; + /* 0: 87.5 - 108 MHz (USA, Europe) */ + case 0 : band_bottom = 87.5 * FREQ_MUL; break; + /* 1: 76 - 108 MHz (Japan wide band) */ + default: band_bottom = 76 * FREQ_MUL; break; + /* 2: 76 - 90 MHz (Japan) */ + case 2 : band_bottom = 76 * FREQ_MUL; break; }; /* read channel */ @@ -802,22 +619,22 @@ static int si470x_set_freq(struct si470x_device *radio, int freq) /* Spacing (kHz) */ switch (space) { - /* 0: 200 kHz (USA, Australia) */ - default: spacing = 0.200 * FREQ_MUL; break; - /* 1: 100 kHz (Europe, Japan) */ - case 1 : spacing = 0.100 * FREQ_MUL; break; - /* 2: 50 kHz */ - case 2 : spacing = 0.050 * FREQ_MUL; break; + /* 0: 200 kHz (USA, Australia) */ + case 0 : spacing = 0.200 * FREQ_MUL; break; + /* 1: 100 kHz (Europe, Japan) */ + case 1 : spacing = 0.100 * FREQ_MUL; break; + /* 2: 50 kHz */ + default: spacing = 0.050 * FREQ_MUL; break; }; /* Bottom of Band (MHz) */ switch (band) { - /* 0: 87.5 - 108 MHz (USA, Europe) */ - default: band_bottom = 87.5 * FREQ_MUL; break; - /* 1: 76 - 108 MHz (Japan wide band) */ - case 1 : band_bottom = 76 * FREQ_MUL; break; - /* 2: 76 - 90 MHz (Japan) */ - case 2 : band_bottom = 76 * FREQ_MUL; break; + /* 0: 87.5 - 108 MHz (USA, Europe) */ + case 0 : band_bottom = 87.5 * FREQ_MUL; break; + /* 1: 76 - 108 MHz (Japan wide band) */ + default: band_bottom = 76 * FREQ_MUL; break; + /* 2: 76 - 90 MHz (Japan) */ + case 2 : band_bottom = 76 * FREQ_MUL; break; }; /* Chan = [ Freq (Mhz) - Bottom of Band (MHz) ] / Spacing (kHz) */ @@ -827,6 +644,60 @@ static int si470x_set_freq(struct si470x_device *radio, int freq) } +/* + * si470x_start - switch on radio + */ +static int si470x_start(struct si470x_device *radio) +{ + int retval; + + /* powercfg */ + radio->registers[POWERCFG] = + POWERCFG_DMUTE | POWERCFG_ENABLE | POWERCFG_RDSM; + retval = si470x_set_register(radio, POWERCFG); + if (retval < 0) + return retval; + + /* sysconfig 1 */ + radio->registers[SYSCONFIG1] = + SYSCONFIG1_DE | SYSCONFIG1_RDS; + retval = si470x_set_register(radio, SYSCONFIG1); + if (retval < 0) + return retval; + + /* sysconfig 2 */ + radio->registers[SYSCONFIG2] = + (0x3f << 8) | /* SEEKTH */ + (band << 6) | /* BAND */ + (space << 4) | /* SPACE */ + 15; /* VOLUME (max) */ + retval = si470x_set_register(radio, SYSCONFIG2); + if (retval < 0) + return retval; + + /* reset last channel */ + return si470x_set_chan(radio, + radio->registers[CHANNEL] & CHANNEL_CHAN); +} + + +/* + * si470x_stop - switch off radio + */ +static int si470x_stop(struct si470x_device *radio) +{ + /* powercfg */ + radio->registers[POWERCFG] &= ~POWERCFG_DMUTE; + /* POWERCFG_ENABLE has to automatically go low */ + radio->registers[POWERCFG] |= POWERCFG_ENABLE | POWERCFG_DISABLE; + return si470x_set_register(radio, POWERCFG); +} + + + +/************************************************************************** + * RDS Driver Functions + **************************************************************************/ /* * si470x_rds - rds processing function @@ -855,26 +726,26 @@ static void si470x_rds(struct si470x_device *radio) for (blocknum = 0; blocknum < 4; blocknum++) { switch (blocknum) { - default: - bler = (radio->registers[STATUSRSSI] & - STATUSRSSI_BLERA) >> 9; - rds = radio->registers[RDSA]; - break; - case 1: - bler = (radio->registers[READCHAN] & - READCHAN_BLERB) >> 14; - rds = radio->registers[RDSB]; - break; - case 2: - bler = (radio->registers[READCHAN] & - READCHAN_BLERC) >> 12; - rds = radio->registers[RDSC]; - break; - case 3: - bler = (radio->registers[READCHAN] & - READCHAN_BLERD) >> 10; - rds = radio->registers[RDSD]; - break; + default: + bler = (radio->registers[STATUSRSSI] & + STATUSRSSI_BLERA) >> 9; + rds = radio->registers[RDSA]; + break; + case 1: + bler = (radio->registers[READCHAN] & + READCHAN_BLERB) >> 14; + rds = radio->registers[RDSB]; + break; + case 2: + bler = (radio->registers[READCHAN] & + READCHAN_BLERC) >> 12; + rds = radio->registers[RDSC]; + break; + case 3: + bler = (radio->registers[READCHAN] & + READCHAN_BLERD) >> 10; + rds = radio->registers[RDSD]; + break; }; /* Fill the V4L2 RDS buffer */ @@ -942,120 +813,20 @@ static void si470x_work(struct work_struct *work) /************************************************************************** - * USB interface functions + * File Operations Interface **************************************************************************/ /* - * si470x_usb_driver_probe - probe for the device + * si470x_fops_read - read RDS data */ -static int si470x_usb_driver_probe(struct usb_interface *intf, - const struct usb_device_id *id) +static ssize_t si470x_fops_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) { - struct si470x_device *radio; - - if (!(radio = kmalloc(sizeof(struct si470x_device), GFP_KERNEL))) - return -ENOMEM; - if (!(radio->videodev = video_device_alloc())) { - kfree(radio); - return -ENOMEM; - } - memcpy(radio->videodev, &si470x_viddev_template, - sizeof(si470x_viddev_template)); - radio->users = 0; - radio->usbdev = interface_to_usbdev(intf); - video_set_drvdata(radio->videodev, radio); - if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) { - printk(KERN_WARNING DRIVER_NAME - ": Could not register video device\n"); - video_device_release(radio->videodev); - kfree(radio); - return -EIO; - } - usb_set_intfdata(intf, radio); - - /* show some infos about the specific device */ - if (si470x_get_all_registers(radio) < 0) { - video_device_release(radio->videodev); - kfree(radio); - return -EIO; - } - printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4x ChipID=0x%4.4x\n", - radio->registers[DEVICEID], radio->registers[CHIPID]); - - /* check if firmware is current */ - if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) - < FMRADIO_SW_VERSION_CURRENT) { - printk(KERN_WARNING DRIVER_NAME - ": This driver is known to work with chip version %d, " - "but the device has firmware %d. If you have some " - "trouble using this driver, please report to V4L ML " - "at video4linux-list@redhat.com\n", - radio->registers[CHIPID] & CHIPID_FIRMWARE, - FMRADIO_SW_VERSION_CURRENT); - } - - /* set initial frequency */ - si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */ - - /* rds initialization */ - radio->buf_size = rds_buf * 3; - if (NULL == (radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL))) { - video_device_release(radio->videodev); - kfree(radio); - return -ENOMEM; - } - radio->block_count = 0; - radio->wr_index = 0; - radio->rd_index = 0; - radio->last_blocknum = 0xff; - init_waitqueue_head(&radio->read_queue); - radio->data_available_for_read = 0; - - /* prepare polling via eventd */ - INIT_WORK(&radio->work, si470x_work); - init_timer(&radio->timer); - radio->timer.function = si470x_timer; - radio->timer.data = (unsigned long) radio; - - return 0; -} - - -/* - * si470x_usb_driver_disconnect - disconnect the device - */ -static void si470x_usb_driver_disconnect(struct usb_interface *intf) -{ - struct si470x_device *radio = usb_get_intfdata(intf); - - del_timer_sync(&radio->timer); - flush_scheduled_work(); - - usb_set_intfdata(intf, NULL); - if (radio) { - video_unregister_device(radio->videodev); - kfree(radio->buffer); - kfree(radio); - } -} - - - -/************************************************************************** - * Video4Linux interface functions - **************************************************************************/ - -/* - * si470x_fops_read - read RDS data - */ -static ssize_t si470x_fops_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - struct si470x_device *radio = video_get_drvdata(video_devdata(file)); - struct rds_command cmd; - unsigned long flags; - unsigned int i; - unsigned int rd_blocks; + struct si470x_device *radio = video_get_drvdata(video_devdata(file)); + struct rds_command cmd; + unsigned long flags; + unsigned int i; + unsigned int rd_blocks; cmd.block_count = count / 3; /* each RDS block needs 3 bytes */ cmd.result = 0; @@ -1166,6 +937,68 @@ static int si470x_fops_release(struct inode *inode, struct file *file) } +/* + * si470x_fops - file operations interface + */ +static const struct file_operations si470x_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = si470x_fops_read, + .poll = si470x_fops_poll, + .ioctl = video_ioctl2, + .compat_ioctl = v4l_compat_ioctl32, + .open = si470x_fops_open, + .release = si470x_fops_release, +}; + + + +/************************************************************************** + * Video4Linux Interface + **************************************************************************/ + +/* + * si470x_v4l2_queryctrl - query control + */ +static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = { +/* HINT: the disabled controls are only here to satify kradio and such apps */ + { + .id = V4L2_CID_AUDIO_VOLUME, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Volume", + .minimum = 0, + .maximum = 15, + .step = 1, + .default_value = 15, + }, + { + .id = V4L2_CID_AUDIO_BALANCE, + .flags = V4L2_CTRL_FLAG_DISABLED, + }, + { + .id = V4L2_CID_AUDIO_BASS, + .flags = V4L2_CTRL_FLAG_DISABLED, + }, + { + .id = V4L2_CID_AUDIO_TREBLE, + .flags = V4L2_CTRL_FLAG_DISABLED, + }, + { + .id = V4L2_CID_AUDIO_MUTE, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + { + .id = V4L2_CID_AUDIO_LOUDNESS, + .flags = V4L2_CTRL_FLAG_DISABLED, + }, +}; + + /* * si470x_vidioc_querycap - query device capabilities */ @@ -1214,9 +1047,9 @@ static int si470x_vidioc_queryctrl(struct file *file, void *priv, { int i; - for (i = 0; i < ARRAY_SIZE(radio_queryctrl); i++) { - if (qc->id && qc->id == radio_queryctrl[i].id) { - memcpy(qc, &(radio_queryctrl[i]), sizeof(*qc)); + for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) { + if (qc->id && qc->id == si470x_v4l2_queryctrl[i].id) { + memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc)); return 0; } } @@ -1234,14 +1067,14 @@ static int si470x_vidioc_g_ctrl(struct file *file, void *priv, struct si470x_device *radio = video_get_drvdata(video_devdata(file)); switch (ctrl->id) { - case V4L2_CID_AUDIO_VOLUME: - ctrl->value = radio->registers[SYSCONFIG2] & - SYSCONFIG2_VOLUME; - break; - case V4L2_CID_AUDIO_MUTE: - ctrl->value = ((radio->registers[POWERCFG] & - POWERCFG_DMUTE) == 0) ? 1 : 0; - break; + case V4L2_CID_AUDIO_VOLUME: + ctrl->value = radio->registers[SYSCONFIG2] & + SYSCONFIG2_VOLUME; + break; + case V4L2_CID_AUDIO_MUTE: + ctrl->value = ((radio->registers[POWERCFG] & + POWERCFG_DMUTE) == 0) ? 1 : 0; + break; } return 0; @@ -1257,16 +1090,16 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv, struct si470x_device *radio = video_get_drvdata(video_devdata(file)); switch (ctrl->id) { - case V4L2_CID_AUDIO_VOLUME: - radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME; - radio->registers[SYSCONFIG2] |= ctrl->value; - return si470x_set_register(radio, SYSCONFIG2); - case V4L2_CID_AUDIO_MUTE: - if (ctrl->value == 1) - radio->registers[POWERCFG] &= ~POWERCFG_DMUTE; - else - radio->registers[POWERCFG] |= POWERCFG_DMUTE; - return si470x_set_register(radio, POWERCFG); + case V4L2_CID_AUDIO_VOLUME: + radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME; + radio->registers[SYSCONFIG2] |= ctrl->value; + return si470x_set_register(radio, SYSCONFIG2); + case V4L2_CID_AUDIO_MUTE: + if (ctrl->value == 1) + radio->registers[POWERCFG] &= ~POWERCFG_DMUTE; + else + radio->registers[POWERCFG] |= POWERCFG_DMUTE; + return si470x_set_register(radio, POWERCFG); } return -EINVAL; @@ -1321,22 +1154,22 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, strcpy(tuner->name, "FM"); tuner->type = V4L2_TUNER_RADIO; - switch(band) { - /* 0: 87.5 - 108 MHz (USA, Europe, default) */ - default: - tuner->rangelow = 87.5 * FREQ_MUL; - tuner->rangehigh = 108 * FREQ_MUL; - break; - /* 1: 76 - 108 MHz (Japan wide band) */ - case 1 : - tuner->rangelow = 76 * FREQ_MUL; - tuner->rangehigh = 108 * FREQ_MUL; - break; - /* 2: 76 - 90 MHz (Japan) */ - case 2 : - tuner->rangelow = 76 * FREQ_MUL; - tuner->rangehigh = 90 * FREQ_MUL; - break; + switch (band) { + /* 0: 87.5 - 108 MHz (USA, Europe, default) */ + default: + tuner->rangelow = 87.5 * FREQ_MUL; + tuner->rangehigh = 108 * FREQ_MUL; + break; + /* 1: 76 - 108 MHz (Japan wide band) */ + case 1 : + tuner->rangelow = 76 * FREQ_MUL; + tuner->rangehigh = 108 * FREQ_MUL; + break; + /* 2: 76 - 90 MHz (Japan) */ + case 2 : + tuner->rangelow = 76 * FREQ_MUL; + tuner->rangehigh = 90 * FREQ_MUL; + break; }; tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; tuner->capability = V4L2_TUNER_CAP_LOW; @@ -1408,9 +1241,147 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv, } +/* + * si470x_viddev_tamples - video device interface + */ +static struct video_device si470x_viddev_template = { + .fops = &si470x_fops, + .name = DRIVER_NAME, + .type = VID_TYPE_TUNER, + .release = video_device_release, + .vidioc_querycap = si470x_vidioc_querycap, + .vidioc_g_input = si470x_vidioc_g_input, + .vidioc_s_input = si470x_vidioc_s_input, + .vidioc_queryctrl = si470x_vidioc_queryctrl, + .vidioc_g_ctrl = si470x_vidioc_g_ctrl, + .vidioc_s_ctrl = si470x_vidioc_s_ctrl, + .vidioc_g_audio = si470x_vidioc_g_audio, + .vidioc_s_audio = si470x_vidioc_s_audio, + .vidioc_g_tuner = si470x_vidioc_g_tuner, + .vidioc_s_tuner = si470x_vidioc_s_tuner, + .vidioc_g_frequency = si470x_vidioc_g_frequency, + .vidioc_s_frequency = si470x_vidioc_s_frequency, + .owner = THIS_MODULE, +}; + + + +/************************************************************************** + * USB Interface + **************************************************************************/ + +/* + * si470x_usb_driver_probe - probe for the device + */ +static int si470x_usb_driver_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct si470x_device *radio; + + /* memory and interface allocations */ + radio = kmalloc(sizeof(struct si470x_device), GFP_KERNEL); + if (!radio) + return -ENOMEM; + radio->videodev = video_device_alloc(); + if (!radio->videodev) { + kfree(radio); + return -ENOMEM; + } + memcpy(radio->videodev, &si470x_viddev_template, + sizeof(si470x_viddev_template)); + radio->users = 0; + radio->usbdev = interface_to_usbdev(intf); + video_set_drvdata(radio->videodev, radio); + if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) { + printk(KERN_WARNING DRIVER_NAME + ": Could not register video device\n"); + video_device_release(radio->videodev); + kfree(radio); + return -EIO; + } + usb_set_intfdata(intf, radio); + + /* show some infos about the specific device */ + if (si470x_get_all_registers(radio) < 0) { + video_device_release(radio->videodev); + kfree(radio); + return -EIO; + } + printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4x ChipID=0x%4.4x\n", + radio->registers[DEVICEID], radio->registers[CHIPID]); + + /* check if firmware is current */ + if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) + < RADIO_SW_VERSION_CURRENT) + printk(KERN_WARNING DRIVER_NAME + ": This driver is known to work with chip version %d, " + "but the device has firmware %d. If you have some " + "trouble using this driver, please report to V4L ML " + "at video4linux-list@redhat.com\n", + radio->registers[CHIPID] & CHIPID_FIRMWARE, + RADIO_SW_VERSION_CURRENT); + + /* set initial frequency */ + si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */ + + /* rds initialization */ + radio->buf_size = rds_buf * 3; + radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); + if (!radio->buffer) { + video_device_release(radio->videodev); + kfree(radio); + return -ENOMEM; + } + radio->block_count = 0; + radio->wr_index = 0; + radio->rd_index = 0; + radio->last_blocknum = 0xff; + init_waitqueue_head(&radio->read_queue); + radio->data_available_for_read = 0; + + /* prepare polling via eventd */ + INIT_WORK(&radio->work, si470x_work); + init_timer(&radio->timer); + radio->timer.function = si470x_timer; + radio->timer.data = (unsigned long) radio; + + return 0; +} + + +/* + * si470x_usb_driver_disconnect - disconnect the device + */ +static void si470x_usb_driver_disconnect(struct usb_interface *intf) +{ + struct si470x_device *radio = usb_get_intfdata(intf); + + del_timer_sync(&radio->timer); + flush_scheduled_work(); + + usb_set_intfdata(intf, NULL); + if (radio) { + video_unregister_device(radio->videodev); + kfree(radio->buffer); + kfree(radio); + } +} + + +/* + * si470x_usb_driver - usb driver interface + */ +static struct usb_driver si470x_usb_driver = { + .name = DRIVER_NAME, + .probe = si470x_usb_driver_probe, + .disconnect = si470x_usb_driver_disconnect, + .id_table = si470x_usb_driver_id_table, +}; + + /************************************************************************** - * Module interface definitions and functions + * Module Interface **************************************************************************/ /* @@ -1438,4 +1409,4 @@ module_exit(si470x_module_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION("1.0.2"); +MODULE_VERSION("1.0.3"); -- cgit v1.2.3 From e2b5f5760598735a680c8ec4b09798919a1647e8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 25 Jan 2008 06:14:57 -0200 Subject: radio-si570x: Some fixes and new USB ID addition From: Tobias Lorenz - avoid poss. locking when doing copy_to_user which may sleep - RDS is automatically activated on read now - code cleaned of unnecessary rds_commands - USB Vendor/Product ID for ADS/Tech FM Radio Receiver verified (thanks to Guillaume RAMOUSSE) Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/radio-si470x.c | 291 +++++++++++++++++-------------- 1 file changed, 156 insertions(+), 135 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index 805c1b403..c5a764b7b 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -55,13 +55,17 @@ * - applied all checkpatch.pl v1.12 suggestions * except the warning about the too long lines with bit comments * - renamed FMRADIO to RADIO to cut line length (checkpatch.pl) + * 2008-01-22 Tobias Lorenz + * Version 1.0.4 + * - avoid poss. locking when doing copy_to_user which may sleep + * - RDS is automatically activated on read now + * - code cleaned of unnecessary rds_commands + * - USB Vendor/Product ID for ADS/Tech FM Radio Receiver verified + * (thanks to Guillaume RAMOUSSE) * * ToDo: - * - check USB Vendor/Product ID for ADS/Tech FM Radio Receiver - * (formerly Instant FM Music) (RDX-155-EF) is 06e1:a155 * - add seeking support * - add firmware download/update support - * - add possibility to switch off RDS * - RDS support: interrupt mode, instead of polling * - add LED status output (check if that's not already done in firmware) */ @@ -70,7 +74,7 @@ /* driver definitions */ #define DRIVER_AUTHOR "Tobias Lorenz " #define DRIVER_NAME "radio-si470x" -#define DRIVER_VERSION KERNEL_VERSION(1, 0, 3) +#define DRIVER_VERSION KERNEL_VERSION(1, 0, 4) #define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver" #define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers" @@ -94,6 +98,8 @@ static struct usb_device_id si470x_usb_driver_id_table[] = { /* Silicon Labs USB FM Radio Reference Design */ { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) }, + /* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */ + { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) }, /* Terminating entry */ { } }; @@ -160,6 +166,7 @@ MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*"); /* RDS poll frequency */ static int rds_poll_time = 40; /* 40 is used by the original USBRadio.exe */ +/* 50 is used by radio-cadet */ /* 75 should be okay */ /* 80 is the usual RDS receive interval */ module_param(rds_poll_time, int, 0); @@ -400,16 +407,13 @@ struct si470x_device { /* RDS receive buffer */ struct work_struct work; + wait_queue_head_t read_queue; struct timer_list timer; spinlock_t lock; /* buffer locking */ - unsigned char *buffer; + unsigned char *buffer; /* size is always multiple of three */ unsigned int buf_size; unsigned int rd_index; unsigned int wr_index; - unsigned int block_count; - unsigned char last_blocknum; - wait_queue_head_t read_queue; - int data_available_for_read; }; @@ -659,8 +663,7 @@ static int si470x_start(struct si470x_device *radio) return retval; /* sysconfig 1 */ - radio->registers[SYSCONFIG1] = - SYSCONFIG1_DE | SYSCONFIG1_RDS; + radio->registers[SYSCONFIG1] = SYSCONFIG1_DE; retval = si470x_set_register(radio, SYSCONFIG1); if (retval < 0) return retval; @@ -686,6 +689,14 @@ static int si470x_start(struct si470x_device *radio) */ static int si470x_stop(struct si470x_device *radio) { + int retval; + + /* sysconfig 1 */ + radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS; + retval = si470x_set_register(radio, SYSCONFIG1); + if (retval < 0) + return retval; + /* powercfg */ radio->registers[POWERCFG] &= ~POWERCFG_DMUTE; /* POWERCFG_ENABLE has to automatically go low */ @@ -694,6 +705,17 @@ static int si470x_stop(struct si470x_device *radio) } +/* + * si470x_rds_on - switch on rds reception + */ +static int si470x_rds_on(struct si470x_device *radio) +{ + /* sysconfig 1 */ + radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDS; + return si470x_set_register(radio, SYSCONFIG1); +} + + /************************************************************************** * RDS Driver Functions @@ -704,15 +726,13 @@ static int si470x_stop(struct si470x_device *radio) */ static void si470x_rds(struct si470x_device *radio) { - unsigned long flags; unsigned char tmpbuf[3]; unsigned char blocknum; - unsigned char bler; /* RDS block errors */ + unsigned char bler; /* rds block errors */ unsigned short rds; unsigned int i; - if (radio->users == 0) - return; + /* get rds blocks */ if (si470x_get_rds_registers(radio) < 0) return; if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0) { @@ -724,63 +744,67 @@ static void si470x_rds(struct si470x_device *radio) return; } - for (blocknum = 0; blocknum < 4; blocknum++) { - switch (blocknum) { - default: - bler = (radio->registers[STATUSRSSI] & - STATUSRSSI_BLERA) >> 9; - rds = radio->registers[RDSA]; - break; - case 1: - bler = (radio->registers[READCHAN] & - READCHAN_BLERB) >> 14; - rds = radio->registers[RDSB]; - break; - case 2: - bler = (radio->registers[READCHAN] & - READCHAN_BLERC) >> 12; - rds = radio->registers[RDSC]; - break; - case 3: - bler = (radio->registers[READCHAN] & - READCHAN_BLERD) >> 10; - rds = radio->registers[RDSD]; - break; - }; - - /* Fill the V4L2 RDS buffer */ - tmpbuf[0] = rds & 0x00ff; /* LSB */ - tmpbuf[1] = (rds & 0xff00) >> 8;/* MSB */ - tmpbuf[2] = blocknum; /* offset name */ - tmpbuf[2] |= blocknum << 3; /* received offset */ - if (bler > max_rds_errors) - tmpbuf[2] |= 0x80; /* uncorrectable errors */ - else if (bler > 0) - tmpbuf[2] |= 0x40; /* corrected error(s) */ - - spin_lock_irqsave(&radio->lock, flags); - - /* copy RDS block to internal buffer */ - for (i = 0; i < 3; i++) { - radio->buffer[radio->wr_index] = tmpbuf[i]; - radio->wr_index++; + /* copy four RDS blocks to internal buffer */ + if (spin_trylock(&radio->lock)) { + /* process each rds block */ + for (blocknum = 0; blocknum < 4; blocknum++) { + switch (blocknum) { + default: + bler = (radio->registers[STATUSRSSI] & + STATUSRSSI_BLERA) >> 9; + rds = radio->registers[RDSA]; + break; + case 1: + bler = (radio->registers[READCHAN] & + READCHAN_BLERB) >> 14; + rds = radio->registers[RDSB]; + break; + case 2: + bler = (radio->registers[READCHAN] & + READCHAN_BLERC) >> 12; + rds = radio->registers[RDSC]; + break; + case 3: + bler = (radio->registers[READCHAN] & + READCHAN_BLERD) >> 10; + rds = radio->registers[RDSD]; + break; + }; + + /* Fill the V4L2 RDS buffer */ + tmpbuf[0] = rds & 0x00ff; /* LSB */ + tmpbuf[1] = (rds & 0xff00) >> 8;/* MSB */ + tmpbuf[2] = blocknum; /* offset name */ + tmpbuf[2] |= blocknum << 3; /* received offset */ + if (bler > max_rds_errors) + tmpbuf[2] |= 0x80; /* uncorrectable errors */ + else if (bler > 0) + tmpbuf[2] |= 0x40; /* corrected error(s) */ + + /* copy RDS block to internal buffer */ + for (i = 0; i < 3; i++) { + radio->buffer[radio->wr_index] = tmpbuf[i]; + radio->wr_index++; + } + + /* wrap write pointer */ + if (radio->wr_index >= radio->buf_size) + radio->wr_index = 0; + + /* check for overflow */ + if (radio->wr_index == radio->rd_index) { + /* increment and wrap read pointer */ + radio->rd_index += 3; + if (radio->rd_index >= radio->buf_size) + radio->rd_index = 0; + } } - - if (radio->wr_index >= radio->buf_size) - radio->wr_index = 0; - - if (radio->wr_index == radio->rd_index) { - radio->rd_index += 3; - if (radio->rd_index >= radio->buf_size) - radio->rd_index = 0; - } else - radio->block_count++; - - spin_unlock_irqrestore(&radio->lock, flags); + spin_unlock(&radio->lock); } - radio->data_available_for_read = 1; - wake_up_interruptible(&radio->read_queue); + /* wake up read queue */ + if (radio->wr_index != radio->rd_index) + wake_up_interruptible(&radio->read_queue); } @@ -796,14 +820,14 @@ static void si470x_timer(unsigned long data) /* - * si470x_timer - rds work function + * si470x_work - rds work function */ static void si470x_work(struct work_struct *work) { struct si470x_device *radio = container_of(work, struct si470x_device, work); - if (radio->users == 0) + if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) return; si470x_rds(radio); @@ -823,53 +847,52 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); - struct rds_command cmd; - unsigned long flags; - unsigned int i; - unsigned int rd_blocks; - - cmd.block_count = count / 3; /* each RDS block needs 3 bytes */ - cmd.result = 0; - cmd.buffer = buf; - cmd.instance = file; - - /* copy RDS block out of internal buffer */ - while (!radio->data_available_for_read) { - if (wait_event_interruptible(radio->read_queue, - radio->data_available_for_read) < 0) - return -EINTR; - } + int retval = 0; + unsigned int block_count = 0; - spin_lock_irqsave(&radio->lock, flags); - rd_blocks = cmd.block_count; - if (rd_blocks > radio->block_count) - rd_blocks = radio->block_count; + /* switch on rds reception */ + if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) { + si470x_rds_on(radio); + schedule_work(&radio->work); + } - if (!rd_blocks) { - spin_unlock_irqrestore(&radio->lock, flags); - return cmd.result; + /* block if no new data available */ + while (radio->wr_index == radio->rd_index) { + if (file->f_flags & O_NONBLOCK) + return -EWOULDBLOCK; + interruptible_sleep_on(&radio->read_queue); } - for (i = 0; i < rd_blocks; i++) { - /* copy RDS block to user buffer */ - if (radio->rd_index == radio->wr_index) - break; + /* calculate block count from byte count */ + count /= 3; + + /* copy RDS block out of internal buffer and to user buffer */ + if (spin_trylock(&radio->lock)) { + while (block_count < count) { + if (radio->rd_index == radio->wr_index) + break; - if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3)) - break; + /* always transfer rds complete blocks */ + if (copy_to_user(buf, + &radio->buffer[radio->rd_index], 3)) + /* retval = -EFAULT; */ + break; - radio->rd_index += 3; - if (radio->rd_index >= radio->buf_size) - radio->rd_index = 0; - radio->block_count--; + /* increment and wrap read pointer */ + radio->rd_index += 3; + if (radio->rd_index >= radio->buf_size) + radio->rd_index = 0; + + /* increment counters */ + block_count++; + buf += 3; + retval += 3; + } - buf += 3; - cmd.result += 3; + spin_unlock(&radio->lock); } - radio->data_available_for_read = (radio->block_count > 0); - spin_unlock_irqrestore(&radio->lock, flags); - return cmd.result; + return retval; } @@ -880,14 +903,19 @@ static unsigned int si470x_fops_poll(struct file *file, struct poll_table_struct *pts) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); - int retval; - retval = 0; - if (radio->data_available_for_read) - retval = POLLIN | POLLRDNORM; + /* switch on rds reception */ + if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) { + si470x_rds_on(radio); + schedule_work(&radio->work); + } + poll_wait(file, &radio->read_queue, pts); - return retval; + if (radio->rd_index != radio->wr_index) + return POLLIN | POLLRDNORM; + + return 0; } @@ -896,17 +924,11 @@ static unsigned int si470x_fops_poll(struct file *file, */ static int si470x_fops_open(struct inode *inode, struct file *file) { - int retval; struct si470x_device *radio = video_get_drvdata(video_devdata(file)); radio->users++; - if (radio->users == 1) { - retval = si470x_start(radio); - if (retval < 0) - return retval; - - schedule_work(&radio->work); - } + if (radio->users == 1) + return si470x_start(radio); return 0; } @@ -917,7 +939,6 @@ static int si470x_fops_open(struct inode *inode, struct file *file) */ static int si470x_fops_release(struct inode *inode, struct file *file) { - int retval; struct si470x_device *radio = video_get_drvdata(video_devdata(file)); if (!radio) @@ -925,12 +946,14 @@ static int si470x_fops_release(struct inode *inode, struct file *file) radio->users--; if (radio->users == 0) { - radio->data_available_for_read = 1; /* ? */ - wake_up_interruptible(&radio->read_queue); /* ? */ + /* stop rds reception */ + del_timer_sync(&radio->timer); + flush_scheduled_work(); - retval = si470x_stop(radio); - if (retval < 0) - return retval; + /* cancel read processes */ + wake_up_interruptible(&radio->read_queue); + + return si470x_stop(radio); } return 0; @@ -1315,9 +1338,10 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, < RADIO_SW_VERSION_CURRENT) printk(KERN_WARNING DRIVER_NAME ": This driver is known to work with chip version %d, " - "but the device has firmware %d. If you have some " - "trouble using this driver, please report to V4L ML " - "at video4linux-list@redhat.com\n", + "but the device has firmware %d.\n" + DRIVER_NAME + "If you have some trouble using this driver, please " + "report to V4L ML at video4linux-list@redhat.com\n", radio->registers[CHIPID] & CHIPID_FIRMWARE, RADIO_SW_VERSION_CURRENT); @@ -1332,12 +1356,9 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, kfree(radio); return -ENOMEM; } - radio->block_count = 0; radio->wr_index = 0; radio->rd_index = 0; - radio->last_blocknum = 0xff; init_waitqueue_head(&radio->read_queue); - radio->data_available_for_read = 0; /* prepare polling via eventd */ INIT_WORK(&radio->work, si470x_work); @@ -1409,4 +1430,4 @@ module_exit(si470x_module_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION("1.0.3"); +MODULE_VERSION("1.0.4"); -- cgit v1.2.3 From c2b42f528d24bfc71feb637fefaa7547f4449532 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Fri, 25 Jan 2008 09:51:48 +0100 Subject: Artec T14BR patches From: Yousef Lamlum Added Artec T14BR support Signed-Off-By: Yousef Lamlum Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 7 ++++++- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 7 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 1aa335d5a..a7088cee1 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -851,6 +851,7 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500_PC) }, /* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) }, /* 21 */{ USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U7000) }, +/* 22 */{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -1018,7 +1019,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .num_device_descs = 2, + .num_device_descs = 3, .devices = { { "DiBcom STK7070P reference design", { &dib0700_usb_id_table[15], NULL }, @@ -1028,6 +1029,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[16], NULL }, { NULL }, }, + { "Artec T14BR DVB-T", + { &dib0700_usb_id_table[22], NULL }, + { NULL }, + } } }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 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 aee5a6ef8..36aeda2b1 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -105,6 +105,7 @@ #define USB_PID_ULTIMA_TVBOX_USB2_WARM 0x810a #define USB_PID_ARTEC_T14_COLD 0x810b #define USB_PID_ARTEC_T14_WARM 0x810c +#define USB_PID_ARTEC_T14BR 0x810f #define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613 #define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002 #define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e -- cgit v1.2.3 From d92957208faa6dc3d2c46b1ed7fa852cb1a7f727 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Fri, 25 Jan 2008 10:02:42 +0100 Subject: [PATCH] ASUS My Cinema U3000 Mini DVBT Tuner From: Daniel Gimpelevich Adding support for ASUS My Cinema U3000 Mini DVBT Tuner Signed-off-by: Daniel Gimpelevich Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 55 ++++++++++++++++++++--- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 3 ++ 2 files changed, 53 insertions(+), 5 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 a7088cee1..de3679089 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -230,6 +230,27 @@ static struct mt2266_config stk7700d_mt2266_config[2] = { } }; +static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap) +{ + if (adap->id == 0) { + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + 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); + } + + adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1), + &stk7700d_dib7000p_mt2266_config[adap->id]); + + return adap->fe == NULL ? -ENODEV : 0; +} + static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap) { if (adap->id == 0) { @@ -850,8 +871,10 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) }, { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500_PC) }, /* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) }, -/* 21 */{ USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U7000) }, -/* 22 */{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) }, + { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U7000) }, + { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) }, + { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000) }, + { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -923,7 +946,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[20] }, { NULL }, }, - /* dom : pour Gigabyte U7000 */ { "Gigabyte U7000", { &dib0700_usb_id_table[21], NULL }, { NULL }, @@ -1005,6 +1027,25 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), .rc_query = dib0700_rc_query + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + + .num_adapters = 1, + .adapter = { + { + .frontend_attach = stk7700P2_frontend_attach, + .tuner_attach = stk7700d_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + }, + }, + + .num_device_descs = 1, + .devices = { + { "ASUS My Cinema U3000 Mini DVBT Tuner", + { &dib0700_usb_id_table[23], NULL }, + { NULL }, + }, + } }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, .num_adapters = 1, @@ -1019,7 +1060,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .num_device_descs = 3, + .num_device_descs = 4, .devices = { { "DiBcom STK7070P reference design", { &dib0700_usb_id_table[15], NULL }, @@ -1032,7 +1073,11 @@ struct dvb_usb_device_properties dib0700_devices[] = { { "Artec T14BR DVB-T", { &dib0700_usb_id_table[22], NULL }, { NULL }, - } + }, + { "ASUS My Cinema U3100 Mini DVBT Tuner", + { &dib0700_usb_id_table[24], NULL }, + { NULL }, + }, } }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 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 36aeda2b1..a411430f8 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -17,6 +17,7 @@ #define USB_VID_ANCHOR 0x0547 #define USB_VID_ANSONIC 0x10b9 #define USB_VID_ANUBIS_ELECTRONIC 0x10fd +#define USB_VID_ASUS 0x0b05 #define USB_VID_AVERMEDIA 0x07ca #define USB_VID_COMPRO 0x185b #define USB_VID_COMPRO_UNK 0x145f @@ -182,5 +183,7 @@ #define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM 0x0513 /* dom pour gigabyte u7000 */ #define USB_PID_GIGABYTE_U7000 0x7001 +#define USB_PID_ASUS_U3000 0x171f +#define USB_PID_ASUS_U3100 0x173f #endif -- cgit v1.2.3 From 055c90f2ea2f98faafdcab7c2520777dc081faf0 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Fri, 25 Jan 2008 10:05:16 +0100 Subject: fix autoserach in the Hauppauge NOVA-T 500 From: Jose Alberto Reguero This patch fix autoserach in the Hauppauge NOVA-T 500. Signed-off-by: Jose Alberto Reguero Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/frontends/dib3000mc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/dib3000mc.c b/linux/drivers/media/dvb/frontends/dib3000mc.c index 75ba0721b..1a8ddedb2 100644 --- a/linux/drivers/media/dvb/frontends/dib3000mc.c +++ b/linux/drivers/media/dvb/frontends/dib3000mc.c @@ -710,7 +710,7 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe, fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) { - int i = 100, found; + int i = 1000, found; dib3000mc_autosearch_start(fe, fep); do { -- cgit v1.2.3 From 4a8446ea26055c018dc44e5021a9ae5433ddc332 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Fri, 25 Jan 2008 10:16:36 +0100 Subject: Add support for WinTV Nova-T-CE driver From: Tim Taubert Add support for WinTV Nova-T-CE driver Signed-off-by: Tim Taubert Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 15 +++++++++++++-- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 14 insertions(+), 2 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 de3679089..4c8c71206 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -875,6 +875,7 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) }, { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000) }, { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100) }, +/* 25 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -1060,7 +1061,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .num_device_descs = 4, + .num_device_descs = 5, .devices = { { "DiBcom STK7070P reference design", { &dib0700_usb_id_table[15], NULL }, @@ -1078,7 +1079,17 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[24], NULL }, { NULL }, }, - } + { "Hauppauge Nova-T Stick", + { &dib0700_usb_id_table[25], 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 = 2, 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 a411430f8..35df40f5f 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -128,6 +128,7 @@ #define USB_PID_HAUPPAUGE_NOVA_T_500_2 0x9950 #define USB_PID_HAUPPAUGE_NOVA_T_STICK 0x7050 #define USB_PID_HAUPPAUGE_NOVA_T_STICK_2 0x7060 +#define USB_PID_HAUPPAUGE_NOVA_T_STICK_3 0x7070 #define USB_PID_HAUPPAUGE_NOVA_TD_STICK 0x9580 #define USB_PID_AVERMEDIA_EXPRESS 0xb568 #define USB_PID_AVERMEDIA_VOLAR 0xa807 -- cgit v1.2.3 From 03409b1d634d67201d42bebf4bcfb7f81dba577c Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Fri, 25 Jan 2008 10:20:02 +0100 Subject: [PATCH] Support for myTV.t From: Darren Salt Here's a roll-up which provides support for both this and the myTV.t. Signed-Off-By: Darren Salt Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 7 ++++++- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 7 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 4c8c71206..36d29f9d2 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -876,6 +876,7 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000) }, { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100) }, /* 25 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) }, + { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -1061,7 +1062,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .num_device_descs = 5, + .num_device_descs = 6, .devices = { { "DiBcom STK7070P reference design", { &dib0700_usb_id_table[15], NULL }, @@ -1083,6 +1084,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[25], NULL }, { NULL }, }, + { "Hauppauge Nova-T MyTV.t", + { &dib0700_usb_id_table[26], NULL }, + { NULL }, + }, }, .rc_interval = DEFAULT_RC_INTERVAL, 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 35df40f5f..aa4844ef8 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -129,6 +129,7 @@ #define USB_PID_HAUPPAUGE_NOVA_T_STICK 0x7050 #define USB_PID_HAUPPAUGE_NOVA_T_STICK_2 0x7060 #define USB_PID_HAUPPAUGE_NOVA_T_STICK_3 0x7070 +#define USB_PID_HAUPPAUGE_MYTV_T 0x7080 #define USB_PID_HAUPPAUGE_NOVA_TD_STICK 0x9580 #define USB_PID_AVERMEDIA_EXPRESS 0xb568 #define USB_PID_AVERMEDIA_VOLAR 0xa807 -- cgit v1.2.3 From b2ca5bfaaed07747dacfcd3de5a2af6e91252e97 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Fri, 25 Jan 2008 10:27:06 +0100 Subject: Fix some tuning problems From: Soeren Moch The attached patch solves all my vdr tuning problems on a dib7000p nova-t stick as far as I could check within the last weekend. It disables streaming while tuning, like that the number of faulty TS packets is reduced. Signed-off-by: Soeren Moch Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/frontends/dib3000mc.c | 8 ++++++-- linux/drivers/media/dvb/frontends/dib7000m.c | 9 ++++++--- linux/drivers/media/dvb/frontends/dib7000p.c | 8 +++++--- 3 files changed, 17 insertions(+), 8 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/dib3000mc.c b/linux/drivers/media/dvb/frontends/dib3000mc.c index 1a8ddedb2..f614bb7c7 100644 --- a/linux/drivers/media/dvb/frontends/dib3000mc.c +++ b/linux/drivers/media/dvb/frontends/dib3000mc.c @@ -694,6 +694,9 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) { struct dib3000mc_state *state = fe->demodulator_priv; + int ret; + + dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z); state->current_bandwidth = fep->u.ofdm.bandwidth; dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth)); @@ -725,10 +728,11 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe, dib3000mc_get_frontend(fe, fep); } + ret = dib3000mc_tune(fe, fep); + /* make this a config parameter */ dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO); - - return dib3000mc_tune(fe, fep); + return ret; } static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat) diff --git a/linux/drivers/media/dvb/frontends/dib7000m.c b/linux/drivers/media/dvb/frontends/dib7000m.c index ff5bc463f..188f6e853 100644 --- a/linux/drivers/media/dvb/frontends/dib7000m.c +++ b/linux/drivers/media/dvb/frontends/dib7000m.c @@ -1207,7 +1207,9 @@ static int dib7000m_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) { struct dib7000m_state *state = fe->demodulator_priv; - int time; + int time, ret; + + dib7000m_set_output_mode(state, OUTMODE_HIGH_Z); state->current_bandwidth = fep->u.ofdm.bandwidth; dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth)); @@ -1242,10 +1244,11 @@ static int dib7000m_set_frontend(struct dvb_frontend* fe, dib7000m_get_frontend(fe, fep); } + ret = dib7000m_tune(fe, fep); + /* make this a config parameter */ dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO); - - return dib7000m_tune(fe, fep); + return ret; } static int dib7000m_read_status(struct dvb_frontend *fe, fe_status_t *stat) diff --git a/linux/drivers/media/dvb/frontends/dib7000p.c b/linux/drivers/media/dvb/frontends/dib7000p.c index f27df535f..4de739607 100644 --- a/linux/drivers/media/dvb/frontends/dib7000p.c +++ b/linux/drivers/media/dvb/frontends/dib7000p.c @@ -1154,8 +1154,9 @@ static int dib7000p_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) { struct dib7000p_state *state = fe->demodulator_priv; - int time; + int time, ret; + dib7000p_set_output_mode(state, OUTMODE_HIGH_Z); state->current_bandwidth = fep->u.ofdm.bandwidth; dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth)); @@ -1192,10 +1193,11 @@ static int dib7000p_set_frontend(struct dvb_frontend* fe, dib7000p_get_frontend(fe, fep); } + ret = dib7000p_tune(fe, fep); + /* make this a config parameter */ dib7000p_set_output_mode(state, OUTMODE_MPEG2_FIFO); - - return dib7000p_tune(fe, fep); + return ret; } static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t *stat) -- cgit v1.2.3 From 6d642ceca1b411004b20634831721cb598055076 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Fri, 25 Jan 2008 10:37:57 +0100 Subject: DiB0700: Start streaming the right way From: Patrick Boettcher There was a mistake in the way how to start the streaming in the dib0700. This patch fixes that. Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dib0700_core.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (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 cab743531..d48425f4a 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -243,7 +243,7 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) u8 b[4]; b[0] = REQUEST_ENABLE_VIDEO; - b[1] = 0x00; + b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */ b[2] = (0x01 << 4); /* Master mode */ b[3] = 0x00; @@ -256,9 +256,6 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) b[2] |= st->channel_state; - if (st->channel_state) /* if at least one channel is active */ - b[1] = (0x01 << 4) | 0x00; - deb_info("data for streaming: %x %x\n",b[1],b[2]); return dib0700_ctrl_wr(adap->dev, b, 4); -- cgit v1.2.3 From 491562f798e88aa424e30a77869e46da44d06786 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Fri, 25 Jan 2008 10:50:07 +0100 Subject: From: Olivier DANET Here is a patch for Hauppage Nova-T-Stick and Nova-T-500 users. It sets the MT2060 IF1 frequency according to the calibration values stored in the EEPROM. It is supposed to enhance the signal quality, but, hey, there is no guarantee. Feedbacks would be much appreciated, to know whether it deserves being applied. Signed-off-by: Olivier DANET Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 32 +++++++++++++++++++---- 1 file changed, 27 insertions(+), 5 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 36d29f9d2..ffecb6ed8 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -94,12 +94,28 @@ static int bristol_frontend_attach(struct dvb_usb_adapter *adap) (10 + adap->id) << 1, &bristol_dib3000mc_config[adap->id])) == NULL ? -ENODEV : 0; } +int eeprom_read(struct i2c_adapter *adap,u8 adrs,u8 *pval) +{ + struct i2c_msg msg[2] = { + { .addr = 0x50, .flags = 0, .buf = &adrs, .len = 1 }, + { .addr = 0x50, .flags = I2C_M_RD, .buf = pval, .len = 1 }, + }; + if (i2c_transfer(adap, msg, 2) != 2) return -EREMOTEIO; + return 0; +} + static int bristol_tuner_attach(struct dvb_usb_adapter *adap) { - struct dib0700_state *st = adap->dev->priv; + struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap; struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1); - return dvb_attach(mt2060_attach,adap->fe, tun_i2c, &bristol_mt2060_config[adap->id], - st->mt2060_if1[adap->id]) == NULL ? -ENODEV : 0; + s8 a; + int if1=1220; + if (adap->dev->udev->descriptor.idVendor == USB_VID_HAUPPAUGE && + adap->dev->udev->descriptor.idProduct == USB_PID_HAUPPAUGE_NOVA_T_500_2) { + if (!eeprom_read(prim_i2c,0x59 + adap->id,&a)) if1=1220+a; + } + return dvb_attach(mt2060_attach,adap->fe, tun_i2c,&bristol_mt2060_config[adap->id], + if1) == NULL ? -ENODEV : 0; } /* STK7700D: Pinnacle/Terratec/Hauppauge Dual DVB-T Diversity */ @@ -628,16 +644,22 @@ static struct mt2060_config stk7700p_mt2060_config = { static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap) { + struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap; struct dib0700_state *st = adap->dev->priv; struct i2c_adapter *tun_i2c; - + s8 a; + int if1=1220; + if (adap->dev->udev->descriptor.idVendor == USB_VID_HAUPPAUGE && + adap->dev->udev->descriptor.idProduct == USB_PID_HAUPPAUGE_NOVA_T_STICK) { + if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a; + } if (st->is_dib7000pc) tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); else tun_i2c = dib7000m_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); return dvb_attach(mt2060_attach, adap->fe, tun_i2c, &stk7700p_mt2060_config, - st->mt2060_if1[0]) == NULL ? -ENODEV : 0; + if1) == NULL ? -ENODEV : 0; } /* DIB7070 generic */ -- cgit v1.2.3 From 37e8e0075faefb10bec87e27293c148236168495 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Fri, 25 Jan 2008 11:25:20 +0100 Subject: DiB7070: Reception quality improved From: Patrick Boettcher Removing two bugs to improve sensitivity for DiB7070 and Dib7000P with MT2266. Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 6 ++++++ linux/drivers/media/dvb/frontends/dib0070.c | 13 +++++++++++-- 2 files changed, 17 insertions(+), 2 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 ffecb6ed8..1c6843c63 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -781,6 +781,8 @@ static struct dib7000p_config dib7070p_dib7000p_config = { .agc_config_count = 1, .agc = &dib7070_agc_config, .bw = &dib7070_bw_config_12_mhz, + .tuner_is_baseband = 1, + .spur_protect = 1, .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, @@ -820,6 +822,8 @@ static struct dib7000p_config stk7070pd_dib7000p_config[2] = { .agc_config_count = 1, .agc = &dib7070_agc_config, .bw = &dib7070_bw_config_12_mhz, + .tuner_is_baseband = 1, + .spur_protect = 1, .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, @@ -832,6 +836,8 @@ static struct dib7000p_config stk7070pd_dib7000p_config[2] = { .agc_config_count = 1, .agc = &dib7070_agc_config, .bw = &dib7070_bw_config_12_mhz, + .tuner_is_baseband = 1, + .spur_protect = 1, .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, diff --git a/linux/drivers/media/dvb/frontends/dib0070.c b/linux/drivers/media/dvb/frontends/dib0070.c index e0a2019b9..e9fab2d3e 100644 --- a/linux/drivers/media/dvb/frontends/dib0070.c +++ b/linux/drivers/media/dvb/frontends/dib0070.c @@ -435,9 +435,14 @@ static u16 dib0070_p1f_defaults[] = 0, }; -static void dib0070_wbd_calibration(struct dib0070_state *state) +static void dib0070_wbd_calibration(struct dvb_frontend *fe) { u16 wbd_offs; + struct dib0070_state *state = fe->tuner_priv; + + if (state->cfg->sleep) + state->cfg->sleep(fe, 0); + dib0070_write_reg(state, 0x0f, 0x6d81); dib0070_write_reg(state, 0x20, 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001); msleep(9); @@ -445,6 +450,10 @@ static void dib0070_wbd_calibration(struct dib0070_state *state) dib0070_write_reg(state, 0x20, 0); state->wbd_ff_offset = ((wbd_offs * 8 * 18 / 33 + 1) / 2); dprintk( "WBDStart = %d (Vargen) - FF = %hd", (u32) wbd_offs * 1800/1024, state->wbd_ff_offset); + + if (state->cfg->sleep) + state->cfg->sleep(fe, 1); + } u16 dib0070_wbd_offset(struct dvb_frontend *fe) @@ -576,7 +585,7 @@ struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter if (dib0070_reset(state) != 0) goto free_mem; - dib0070_wbd_calibration(state); + dib0070_wbd_calibration(fe); printk(KERN_INFO "DiB0070: successfully identified\n"); memcpy(&fe->ops.tuner_ops, &dib0070_ops, sizeof(struct dvb_tuner_ops)); -- cgit v1.2.3 From f4a9737a2bdd72cb0d67a6c047dc9798cfdb48f4 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Fri, 25 Jan 2008 11:31:58 +0100 Subject: DiB7000P: correct tuning problem for 7MHz channel From: Patrick Boettcher Tuning problem for 7Mhz channels fixes Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/frontends/dib7000p.c | 10 ++++------ linux/drivers/media/dvb/frontends/dibx000_common.h | 5 +++++ 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/dib7000p.c b/linux/drivers/media/dvb/frontends/dib7000p.c index 4de739607..9b6702b70 100644 --- a/linux/drivers/media/dvb/frontends/dib7000p.c +++ b/linux/drivers/media/dvb/frontends/dib7000p.c @@ -36,8 +36,8 @@ struct dib7000p_state { u16 wbd_ref; - u8 current_band; - fe_bandwidth_t current_bandwidth; + u8 current_band; + u32 current_bandwidth; struct dibx000_agc_config *current_agc; u32 timf; @@ -1100,7 +1100,7 @@ static int dib7000p_get_frontend(struct dvb_frontend* fe, fep->inversion = INVERSION_AUTO; - fep->u.ofdm.bandwidth = state->current_bandwidth; + fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth); switch ((tps >> 8) & 0x3) { case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break; @@ -1157,10 +1157,8 @@ static int dib7000p_set_frontend(struct dvb_frontend* fe, int time, ret; dib7000p_set_output_mode(state, OUTMODE_HIGH_Z); - state->current_bandwidth = fep->u.ofdm.bandwidth; - dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth)); - /* maybe the parameter has been changed */ + /* maybe the parameter has been changed */ state->sfn_workaround_active = buggy_sfn_workaround; if (fe->ops.tuner_ops.set_params) diff --git a/linux/drivers/media/dvb/frontends/dibx000_common.h b/linux/drivers/media/dvb/frontends/dibx000_common.h index 5e17275af..84e4d5362 100644 --- a/linux/drivers/media/dvb/frontends/dibx000_common.h +++ b/linux/drivers/media/dvb/frontends/dibx000_common.h @@ -128,6 +128,11 @@ enum dibx000_adc_states { (v) == BANDWIDTH_7_MHZ ? 7000 : \ (v) == BANDWIDTH_6_MHZ ? 6000 : 8000 ) +#define BANDWIDTH_TO_INDEX(v) ( \ + (v) == 8000 ? BANDWIDTH_8_MHZ : \ + (v) == 7000 ? BANDWIDTH_7_MHZ : \ + (v) == 6000 ? BANDWIDTH_6_MHZ : BANDWIDTH_8_MHZ ) + /* Chip output mode. */ #define OUTMODE_HIGH_Z 0 #define OUTMODE_MPEG2_PAR_GATED_CLK 1 -- cgit v1.2.3 From 313a6ebc7e481fbb3cb00529a7523dbb3665d5e7 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Fri, 25 Jan 2008 11:32:58 +0100 Subject: Make a local function static From: Patrick Boettcher Make a local function static Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 2 +- 1 file changed, 1 insertion(+), 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 1c6843c63..e7093826e 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -94,7 +94,7 @@ static int bristol_frontend_attach(struct dvb_usb_adapter *adap) (10 + adap->id) << 1, &bristol_dib3000mc_config[adap->id])) == NULL ? -ENODEV : 0; } -int eeprom_read(struct i2c_adapter *adap,u8 adrs,u8 *pval) +static int eeprom_read(struct i2c_adapter *adap,u8 adrs,u8 *pval) { struct i2c_msg msg[2] = { { .addr = 0x50, .flags = 0, .buf = &adrs, .len = 1 }, -- cgit v1.2.3 From c23e02825608cd9d6a9624c5d1e932a10835a5eb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 19 Jan 2008 05:38:59 +0000 Subject: bt878: include KERN_ facility level From: Akinobu Mita printk should use KERN_* levels. CC: Manu Abraham Signed-off-by: Akinobu Mita Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/bt8xx/bt878.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/bt8xx/bt878.c b/linux/drivers/media/dvb/bt8xx/bt878.c index 1da817ee9..8a332a088 100644 --- a/linux/drivers/media/dvb/bt8xx/bt878.c +++ b/linux/drivers/media/dvb/bt8xx/bt878.c @@ -75,7 +75,11 @@ EXPORT_SYMBOL(bt878); #if defined(dprintk) #undef dprintk #endif -#define dprintk if(bt878_debug) printk +#define dprintk(fmt, arg...) \ + do { \ + if (bt878_debug) \ + printk(KERN_DEBUG fmt, ##arg); \ + } while (0) static void bt878_mem_free(struct bt878 *bt) { @@ -154,7 +158,7 @@ static int bt878_make_risc(struct bt878 *bt) } if (bt->line_count > 255) { - printk("bt878: buffer size error!\n"); + printk(KERN_ERR "bt878: buffer size error!\n"); return -EINVAL; } return 0; @@ -289,7 +293,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id) if (astat & (BT878_ASCERR | BT878_AOCERR)) { if (bt878_verbose) { - printk("bt878(%d): irq%s%s risc_pc=%08x\n", + printk(KERN_INFO + "bt878(%d): irq%s%s risc_pc=%08x\n", bt->nr, (astat & BT878_ASCERR) ? " SCERR" : "", @@ -299,8 +304,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id) } if (astat & (BT878_APABORT | BT878_ARIPERR | BT878_APPERR)) { if (bt878_verbose) { - printk - ("bt878(%d): irq%s%s%s risc_pc=%08x\n", + printk(KERN_INFO + "bt878(%d): irq%s%s%s risc_pc=%08x\n", bt->nr, (astat & BT878_APABORT) ? " PABORT" : "", @@ -312,8 +317,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id) } if (astat & (BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS)) { if (bt878_verbose) { - printk - ("bt878(%d): irq%s%s%s risc_pc=%08x\n", + printk(KERN_INFO + "bt878(%d): irq%s%s%s risc_pc=%08x\n", bt->nr, (astat & BT878_AFDSR) ? " FDSR" : "", (astat & BT878_AFTRGT) ? " FTRGT" : @@ -516,7 +521,7 @@ static int __devinit bt878_probe(struct pci_dev *dev, */ if ((result = bt878_mem_alloc(bt))) { - printk("bt878: failed to allocate memory!\n"); + printk(KERN_ERR "bt878: failed to allocate memory!\n"); goto fail2; } @@ -542,7 +547,7 @@ static void __devexit bt878_remove(struct pci_dev *pci_dev) struct bt878 *bt = pci_get_drvdata(pci_dev); if (bt878_verbose) - printk("bt878(%d): unloading\n", bt->nr); + printk(KERN_INFO "bt878(%d): unloading\n", bt->nr); /* turn off all capturing, DMA and IRQs */ btand(~0x13, BT878_AGPIO_DMA_CTL); -- cgit v1.2.3 From b89d5946e0d1e7c1d93eb6cb2edda3f4eb9b83a5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 21 Jan 2008 15:15:19 +0000 Subject: bt878: remove handcrafted PCI subsystem ID check From: Akinobu Mita This patch moves the subsystem ID and subsystem vendor ID check from probing function to the PCI generic function by describing subsystem IDs in pci_device_id table. This enables to add new PCI IDs to a device driver pci_ids table at runtime by new_id file in sysfs pci driver tree. Signed-off-by: Akinobu Mita Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- linux/Documentation/dvb/bt8xx.txt | 12 ++++++ linux/drivers/media/dvb/bt8xx/bt878.c | 76 +++++++++++++++-------------------- linux/drivers/media/dvb/bt8xx/bt878.h | 6 --- 3 files changed, 45 insertions(+), 49 deletions(-) (limited to 'linux') diff --git a/linux/Documentation/dvb/bt8xx.txt b/linux/Documentation/dvb/bt8xx.txt index ecb47adda..b7b1d1b1d 100644 --- a/linux/Documentation/dvb/bt8xx.txt +++ b/linux/Documentation/dvb/bt8xx.txt @@ -78,6 +78,18 @@ Example: For a full list of card ID's please see Documentation/video4linux/CARDLIST.bttv. In case of further problems please subscribe and send questions to the mailing list: linux-dvb@linuxtv.org. +2c) Probing the cards with broken PCI subsystem ID +-------------------------------------------------- +There are some TwinHan cards that the EEPROM has become corrupted for some +reason. The cards do not have correct PCI subsystem ID. But we can force +probing the cards with broken PCI subsystem ID + + $ echo 109e 0878 $subvendor $subdevice > \ + /sys/bus/pci/drivers/bt878/new_id + +109e: PCI_VENDOR_ID_BROOKTREE +0878: PCI_DEVICE_ID_BROOKTREE_878 + Authors: Richard Walker, Jamie Honan, Michael Hunold, diff --git a/linux/drivers/media/dvb/bt8xx/bt878.c b/linux/drivers/media/dvb/bt8xx/bt878.c index 8a332a088..57f0f84b6 100644 --- a/linux/drivers/media/dvb/bt8xx/bt878.c +++ b/linux/drivers/media/dvb/bt8xx/bt878.c @@ -387,23 +387,37 @@ bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet * EXPORT_SYMBOL(bt878_device_control); +#define BROOKTREE_878_DEVICE(vend, dev, name) \ + { \ + .vendor = PCI_VENDOR_ID_BROOKTREE, \ + .device = PCI_DEVICE_ID_BROOKTREE_878, \ + .subvendor = (vend), .subdevice = (dev), \ + .driver_data = (unsigned long) name \ + } -static struct cards card_list[] __devinitdata = { - - { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, - { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, - { 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" }, - { 0x002611bd, BTTV_BOARD_TWINHAN_DST, "Pinnacle PCTV SAT CI" }, - { 0x00011822, BTTV_BOARD_TWINHAN_DST, "Twinhan VisionPlus DVB" }, - { 0xfc00270f, BTTV_BOARD_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" }, - { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, - { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, - { 0xdb1118ac, BTTV_BOARD_DVICO_DVBT_LITE, "Ultraview DVB-T Lite" }, - { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, - { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV" }, - { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini" } +static struct pci_device_id bt878_pci_tbl[] __devinitdata = { + BROOKTREE_878_DEVICE(0x0071, 0x0101, "Nebula Electronics DigiTV"), + BROOKTREE_878_DEVICE(0x1461, 0x0761, "AverMedia AverTV DVB-T 761"), + BROOKTREE_878_DEVICE(0x11bd, 0x001c, "Pinnacle PCTV Sat"), + BROOKTREE_878_DEVICE(0x11bd, 0x0026, "Pinnacle PCTV SAT CI"), + BROOKTREE_878_DEVICE(0x1822, 0x0001, "Twinhan VisionPlus DVB"), + BROOKTREE_878_DEVICE(0x270f, 0xfc00, + "ChainTech digitop DST-1000 DVB-S"), + BROOKTREE_878_DEVICE(0x1461, 0x0771, "AVermedia AverTV DVB-T 771"), + BROOKTREE_878_DEVICE(0x18ac, 0xdb10, "DViCO FusionHDTV DVB-T Lite"), + BROOKTREE_878_DEVICE(0x18ac, 0xdb11, "Ultraview DVB-T Lite"), + BROOKTREE_878_DEVICE(0x18ac, 0xd500, "DViCO FusionHDTV 5 Lite"), + BROOKTREE_878_DEVICE(0x7063, 0x2000, "pcHDTV HD-2000 TV"), + BROOKTREE_878_DEVICE(0x1822, 0x0026, "DNTV Live! Mini"), + { } }; +MODULE_DEVICE_TABLE(pci, bt878_pci_tbl); + +static const char * __devinit card_name(const struct pci_device_id *id) +{ + return id->driver_data ? (const char *)id->driver_data : "Unknown"; +} /***********************/ /* PCI device handling */ @@ -412,15 +426,13 @@ static struct cards card_list[] __devinitdata = { static int __devinit bt878_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) { - int result = 0, has_dvb = 0, i; + int result = 0; unsigned char lat; struct bt878 *bt; #if defined(__powerpc__) unsigned int cmd; #endif unsigned int cardid; - unsigned short id; - struct cards *dvb_cards; printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n", bt878_num); @@ -432,25 +444,11 @@ static int __devinit bt878_probe(struct pci_dev *dev, if (pci_enable_device(dev)) return -EIO; - pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &id); - cardid = id << 16; - pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &id); - cardid |= id; - - for (i = 0, dvb_cards = card_list; i < ARRAY_SIZE(card_list); i++, dvb_cards++) { - if (cardid == dvb_cards->pci_id) { - printk("%s: card id=[0x%x],[ %s ] has DVB functions.\n", - __func__, cardid, dvb_cards->name); - has_dvb = 1; - } - } + cardid = dev->subsystem_device << 16; + cardid |= dev->subsystem_vendor; - if (!has_dvb) { - printk("%s: card id=[0x%x], Unknown card.\nExiting..\n", __func__, cardid); - result = -EINVAL; - - goto fail0; - } + printk(KERN_INFO "%s: card id=[0x%x],[ %s ] has DVB functions.\n", + __func__, cardid, card_name(pci_id)); bt = &bt878[bt878_num]; bt->dev = dev; @@ -581,14 +579,6 @@ static void __devexit bt878_remove(struct pci_dev *pci_dev) return; } -static struct pci_device_id bt878_pci_tbl[] __devinitdata = { - {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BROOKTREE_878, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0,} -}; - -MODULE_DEVICE_TABLE(pci, bt878_pci_tbl); - static struct pci_driver bt878_pci_driver = { .name = "bt878", .id_table = bt878_pci_tbl, diff --git a/linux/drivers/media/dvb/bt8xx/bt878.h b/linux/drivers/media/dvb/bt8xx/bt878.h index 0a60aaf1c..c16a3184f 100644 --- a/linux/drivers/media/dvb/bt8xx/bt878.h +++ b/linux/drivers/media/dvb/bt8xx/bt878.h @@ -104,12 +104,6 @@ #define BTTV_BOARD_DVICO_DVBT_LITE 0x80 #define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87 -struct cards { - __u32 pci_id; - __u16 card_id; - char *name; -}; - extern int bt878_num; struct bt878 { -- cgit v1.2.3 From 67b4eaf2c1b637b81e541fc5df1c79744f01423b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 23 Jan 2008 05:39:39 +0000 Subject: radio: fix sf16fmi section mismatch From: Randy Dunlap isapnp_fmi_probe() is only called by fmi_init(), which is __init, so isapnp_fmi_probe() can also be __init. media/radio/radio-sf16fmi.c: Signed-off-by: Randy Dunlap Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/radio-sf16fmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-sf16fmi.c b/linux/drivers/media/radio/radio-sf16fmi.c index 29276d364..e56129415 100644 --- a/linux/drivers/media/radio/radio-sf16fmi.c +++ b/linux/drivers/media/radio/radio-sf16fmi.c @@ -328,7 +328,7 @@ static struct isapnp_device_id id_table[] __devinitdata = { MODULE_DEVICE_TABLE(isapnp, id_table); -static int isapnp_fmi_probe(void) +static int __init isapnp_fmi_probe(void) { int i = 0; -- cgit v1.2.3 From 79491620a36cd170b0cd818d8837a6fbef5d7c21 Mon Sep 17 00:00:00 2001 From: Antoine Jacquet Date: Fri, 25 Jan 2008 23:00:19 +0100 Subject: zr364xx: fix typo in documentation From: Antoine Jacquet Signed-off-by: Antoine Jacquet --- linux/Documentation/video4linux/zr364xx.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/Documentation/video4linux/zr364xx.txt b/linux/Documentation/video4linux/zr364xx.txt index 4d9a0c33f..754099ce7 100644 --- a/linux/Documentation/video4linux/zr364xx.txt +++ b/linux/Documentation/video4linux/zr364xx.txt @@ -25,7 +25,7 @@ modprobe zr364xx debug=X mode=Y - debug : set to 1 to enable verbose debug messages - mode : 0 = 320x240, 1 = 160x120, 2 = 640x480 You can then use the camera with V4L2 compatible applications, for example Ekiga. -To capture a single image, try this: dd if=/dev/video0 of=test.jpg bs=1 count=1 +To capture a single image, try this: dd if=/dev/video0 of=test.jpg bs=1M count=1 links : http://mxhaard.free.fr/ (support for many others cams including some Aiptek PocketDV) -- cgit v1.2.3 From d697072e9b9127ac03b29f1b32a227f1c425c1e6 Mon Sep 17 00:00:00 2001 From: Antoine Jacquet Date: Fri, 25 Jan 2008 23:01:53 +0100 Subject: zr364xx: add support for Pentax Optio 50 From: Antoine Jacquet Signed-off-by: Antoine Jacquet --- linux/Documentation/video4linux/zr364xx.txt | 1 + linux/drivers/media/video/zr364xx.c | 1 + 2 files changed, 2 insertions(+) (limited to 'linux') diff --git a/linux/Documentation/video4linux/zr364xx.txt b/linux/Documentation/video4linux/zr364xx.txt index 754099ce7..9a1a8c559 100644 --- a/linux/Documentation/video4linux/zr364xx.txt +++ b/linux/Documentation/video4linux/zr364xx.txt @@ -63,3 +63,4 @@ Vendor Product Distributor Model 0x06d6 0x0034 Trust Powerc@m 750 0x0a17 0x0062 Pentax Optio 50L 0x06d6 0x003b Trust Powerc@m 970Z +0x0a17 0x004e Pentax Optio 50 diff --git a/linux/drivers/media/video/zr364xx.c b/linux/drivers/media/video/zr364xx.c index 9acfc11bb..b779b3f49 100644 --- a/linux/drivers/media/video/zr364xx.c +++ b/linux/drivers/media/video/zr364xx.c @@ -94,6 +94,7 @@ static struct usb_device_id device_table[] = { {USB_DEVICE(0x06d6, 0x0034), .driver_info = METHOD0 }, {USB_DEVICE(0x0a17, 0x0062), .driver_info = METHOD2 }, {USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 }, + {USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 }, {} /* Terminating entry */ }; -- cgit v1.2.3 From eff6bc3fed87c7bcae83f7cc2004b373c92c265b Mon Sep 17 00:00:00 2001 From: Antoine Jacquet Date: Fri, 25 Jan 2008 23:03:10 +0100 Subject: zr364xx: add support for Creative DiVi CAM 516 From: Antoine Jacquet Signed-off-by: Antoine Jacquet --- linux/Documentation/video4linux/zr364xx.txt | 1 + linux/drivers/media/video/zr364xx.c | 1 + 2 files changed, 2 insertions(+) (limited to 'linux') diff --git a/linux/Documentation/video4linux/zr364xx.txt b/linux/Documentation/video4linux/zr364xx.txt index 9a1a8c559..5c81e3ae6 100644 --- a/linux/Documentation/video4linux/zr364xx.txt +++ b/linux/Documentation/video4linux/zr364xx.txt @@ -64,3 +64,4 @@ Vendor Product Distributor Model 0x0a17 0x0062 Pentax Optio 50L 0x06d6 0x003b Trust Powerc@m 970Z 0x0a17 0x004e Pentax Optio 50 +0x041e 0x405d Creative DiVi CAM 516 diff --git a/linux/drivers/media/video/zr364xx.c b/linux/drivers/media/video/zr364xx.c index b779b3f49..61d740f57 100644 --- a/linux/drivers/media/video/zr364xx.c +++ b/linux/drivers/media/video/zr364xx.c @@ -95,6 +95,7 @@ static struct usb_device_id device_table[] = { {USB_DEVICE(0x0a17, 0x0062), .driver_info = METHOD2 }, {USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 }, {USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 }, + {USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 }, {} /* Terminating entry */ }; -- cgit v1.2.3 From e558989e7f6ff76a2001308b9ba946843b0a7c9f Mon Sep 17 00:00:00 2001 From: Hartmut Hackmann Date: Sun, 20 Jan 2008 20:27:51 +0100 Subject: support for Twinhan Hybrid DTV-DVB 3056 PCI From: Hermann Pitton S-Video is unconfirmed, but likely correct. The remote is not yet investigated. Thanks go to Sioux for providing code and asking to fix the auto detection. Signed-off-by: sioux Signed-off-by: Hermann Pitton Signed-off-by: Hartmut Hackmann --- linux/Documentation/video4linux/CARDLIST.saa7134 | 1 + linux/drivers/media/video/saa7134/saa7134-cards.c | 41 +++++++++++++++++++++-- linux/drivers/media/video/saa7134/saa7134-dvb.c | 18 ++++++++++ linux/drivers/media/video/saa7134/saa7134.h | 1 + 4 files changed, 59 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/Documentation/video4linux/CARDLIST.saa7134 b/linux/Documentation/video4linux/CARDLIST.saa7134 index 5d3b6b4d2..7a37594b7 100644 --- a/linux/Documentation/video4linux/CARDLIST.saa7134 +++ b/linux/Documentation/video4linux/CARDLIST.saa7134 @@ -129,3 +129,4 @@ 128 -> Beholder BeholdTV Columbus TVFM [0000:5201] 129 -> Beholder BeholdTV 607 / BeholdTV 609 [5ace:6070,5ace:6071,5ace:6072,5ace:6073,5ace:6090,5ace:6091,5ace:6092,5ace:6093] 130 -> Beholder BeholdTV M6 / BeholdTV M6 Extra [5ace:6190,5ace:6193] +131 -> Twinhan Hybrid DTV-DVB 3056 PCI [1822:0022] diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c index bd7728d64..2806f1ec5 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -3951,6 +3951,36 @@ struct saa7134_board saa7134_boards[] = { }, .mpeg = SAA7134_MPEG_EMPRESS, }, + [SAA7134_BOARD_TWINHAN_DTV_DVB_3056] = { + .name = "Twinhan Hybrid DTV-DVB 3056 PCI", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_TDA8290, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tuner_config = 2, + .mpeg = SAA7134_MPEG_DVB, + .gpiomask = 0x0200000, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + }, { + .name = name_comp1, + .vmux = 3, + .amux = LINE1, + }, { + .name = name_svideo, + .vmux = 8, /* untested */ + .amux = LINE1, + } }, + .radio = { + .name = name_radio, + .amux = TV, + .gpio = 0x0200000, + }, + }, }; const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); @@ -4882,7 +4912,13 @@ struct pci_device_id saa7134_pci_tbl[] = { .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x4e42, .subdevice = 0x3502, - .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS + .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS, + }, { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x1822, /*Twinhan Technology Co. Ltd*/ + .subdevice = 0x0022, + .driver_data = SAA7134_BOARD_TWINHAN_DTV_DVB_3056, },{ /* --- boards without eeprom + subsystem ID --- */ .vendor = PCI_VENDOR_ID_PHILIPS, @@ -5308,7 +5344,8 @@ int saa7134_board_init2(struct saa7134_dev *dev) case SAA7134_BOARD_ASUSTeK_P7131_DUAL: case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: case SAA7134_BOARD_MEDION_MD8800_QUADRO: - case SAA7134_BOARD_AVERMEDIA_SUPER_007: + case SAA7134_BOARD_AVERMEDIA_SUPER_007: + case SAA7134_BOARD_TWINHAN_DTV_DVB_3056: /* this is a hybrid board, initialize to analog mode * and configure firmware eeprom address */ diff --git a/linux/drivers/media/video/saa7134/saa7134-dvb.c b/linux/drivers/media/video/saa7134/saa7134-dvb.c index a9ca57308..90f495a67 100644 --- a/linux/drivers/media/video/saa7134/saa7134-dvb.c +++ b/linux/drivers/media/video/saa7134/saa7134-dvb.c @@ -779,6 +779,21 @@ static struct tda1004x_config avermedia_super_007_config = { .request_firmware = philips_tda1004x_request_firmware }; +static struct tda1004x_config twinhan_dtv_dvb_3056_config = { + .demod_address = 0x08, + .invert = 1, + .invert_oclk = 0, + .xtal_freq = TDA10046_XTAL_16M, + .agc_config = TDA10046_AGC_TDA827X, + .gpio_config = TDA10046_GP01_I, + .if_freq = TDA10046_FREQ_045, + .i2c_gate = 0x42, + .tuner_address = 0x61, + .tuner_config = 2, + .antenna_switch = 1, + .request_firmware = philips_tda1004x_request_firmware +}; + /* ------------------------------------------------------------------ * special case: this card uses saa713x GPIO22 for the mode switch */ @@ -1044,6 +1059,9 @@ static int dvb_init(struct saa7134_dev *dev) case SAA7134_BOARD_AVERMEDIA_SUPER_007: configure_tda827x_fe(dev, &avermedia_super_007_config); break; + case SAA7134_BOARD_TWINHAN_DTV_DVB_3056: + configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config); + break; default: wprintk("Huh? unknown DVB card?\n"); break; diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h index 3a74671a5..29d71cbac 100644 --- a/linux/drivers/media/video/saa7134/saa7134.h +++ b/linux/drivers/media/video/saa7134/saa7134.h @@ -260,6 +260,7 @@ struct saa7134_format { #define SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM 128 #define SAA7134_BOARD_BEHOLD_607_9FM 129 #define SAA7134_BOARD_BEHOLD_M6 130 +#define SAA7134_BOARD_TWINHAN_DTV_DVB_3056 131 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 -- cgit v1.2.3 From 1796bcf8745d2ff21657b8d01a9c86ef687188d7 Mon Sep 17 00:00:00 2001 From: Hartmut Hackmann Date: Sun, 20 Jan 2008 20:32:39 +0100 Subject: saa7134: enable radio and external analog audio-in on the md2819 From: Hermann Pitton It also enumerates now the separate composite input at first and adds mute ability to radio and external audio-in. Many thanks to Daftcho Tabakov for reporting the flaws and testing. Signed-off-by: Hermann Pitton Signed-off-by: Hartmut Hackmann --- linux/drivers/media/video/saa7134/saa7134-cards.c | 31 +++++++++++++++-------- 1 file changed, 21 insertions(+), 10 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 2806f1ec5..4f4d2a0d8 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -928,27 +928,38 @@ struct saa7134_board saa7134_boards[] = { .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, + .gpiomask = 0x03, .inputs = {{ .name = name_tv, .vmux = 1, .amux = TV, .tv = 1, - },{ + .gpio = 0x00, + }, { .name = name_comp1, - .vmux = 0, - .amux = LINE2, - },{ - .name = name_comp2, .vmux = 3, - .amux = LINE2, - },{ + .amux = LINE1, + .gpio = 0x02, + }, { + .name = name_comp2, + .vmux = 0, + .amux = LINE1, + .gpio = 0x02, + }, { .name = name_svideo, .vmux = 8, - .amux = LINE2, - }}, + .amux = LINE1, + .gpio = 0x02, + } }, .radio = { .name = name_radio, - .amux = LINE2, + .amux = LINE1, + .gpio = 0x01, + }, + .mute = { + .name = name_mute, + .amux = TV, + .gpio = 0x00, }, }, [SAA7134_BOARD_BMK_MPEX_TUNER] = { -- cgit v1.2.3 From 8d7a69a5f472873147698d4e2721cb4c445ac86e Mon Sep 17 00:00:00 2001 From: Hartmut Hackmann Date: Sun, 20 Jan 2008 20:42:01 +0100 Subject: saa7134: add support for the Medion / Creatix CTX948 card From: Hermann Pitton This adds support for analog inputs and DVB-T. Good sensitivity for DVB-T currently needs to use analog TV first. DVB-S support is not yet completed, but is on the way. Signed-off-by: Hermann Pitton Signed-off-by: Hartmut Hackmann --- linux/Documentation/video4linux/CARDLIST.saa7134 | 2 +- linux/drivers/media/video/saa7134/saa7134-cards.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/Documentation/video4linux/CARDLIST.saa7134 b/linux/Documentation/video4linux/CARDLIST.saa7134 index 7a37594b7..81566df13 100644 --- a/linux/Documentation/video4linux/CARDLIST.saa7134 +++ b/linux/Documentation/video4linux/CARDLIST.saa7134 @@ -94,7 +94,7 @@ 93 -> Medion 7134 Bridge #2 [16be:0005] 94 -> LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB [5168:3306,5168:3502,4e42:3502] 95 -> LifeView FlyVIDEO3000 (NTSC) [5169:0138] - 96 -> Medion Md8800 Quadro [16be:0007,16be:0008] + 96 -> Medion Md8800 Quadro [16be:0007,16be:0008,16be:000d] 97 -> LifeView FlyDVB-S /Acorp TV134DS [5168:0300,4e42:0300] 98 -> Proteus Pro 2309 [0919:2003] 99 -> AVerMedia TV Hybrid A16AR [1461:2c00] diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c index 4f4d2a0d8..e8a1b05b6 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -4601,6 +4601,12 @@ struct pci_device_id saa7134_pci_tbl[] = { .subdevice = 0x0008, .driver_data = SAA7134_BOARD_MEDION_MD8800_QUADRO, },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x16be, + .subdevice = 0x000d, /* triple CTX948_V1.1.1 */ + .driver_data = SAA7134_BOARD_MEDION_MD8800_QUADRO, + }, { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x1461, -- cgit v1.2.3 From 839e9bbc0a61d474ab3d48a86b1c5d74b2199dac Mon Sep 17 00:00:00 2001 From: Hartmut Hackmann Date: Sun, 20 Jan 2008 20:49:51 +0100 Subject: saa7134: detect the LifeView FlyDVB-T Hybrid Mini PCI From: Hermann Pitton Thanks to Angelo Lisco for his initial patch we missed and to Ahmet Dogan Ugurel confirming such a device functional. Signed-off-by: Hermann Pitton Signed-off-by: Hartmut Hackmann --- linux/Documentation/video4linux/CARDLIST.saa7134 | 2 +- linux/drivers/media/video/saa7134/saa7134-cards.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/Documentation/video4linux/CARDLIST.saa7134 b/linux/Documentation/video4linux/CARDLIST.saa7134 index 81566df13..1074925fb 100644 --- a/linux/Documentation/video4linux/CARDLIST.saa7134 +++ b/linux/Documentation/video4linux/CARDLIST.saa7134 @@ -92,7 +92,7 @@ 91 -> AVerMedia A169 B [1461:7360] 92 -> AVerMedia A169 B1 [1461:6360] 93 -> Medion 7134 Bridge #2 [16be:0005] - 94 -> LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB [5168:3306,5168:3502,4e42:3502] + 94 -> LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB [5168:3306,5168:3502,5168:3307,4e42:3502] 95 -> LifeView FlyVIDEO3000 (NTSC) [5169:0138] 96 -> Medion Md8800 Quadro [16be:0007,16be:0008,16be:000d] 97 -> LifeView FlyDVB-S /Acorp TV134DS [5168:0300,4e42:0300] diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c index e8a1b05b6..92219be5f 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -4589,6 +4589,12 @@ struct pci_device_id saa7134_pci_tbl[] = { .subdevice = 0x3502, /* whats the difference to 0x3306 ?*/ .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS, },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5168, + .subdevice = 0x3307, /* FlyDVB-T Hybrid Mini PCI */ + .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS, + }, { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x16be, -- cgit v1.2.3 From 31cc3900fbe9058241f7a60ee2dbb595452decda Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 26 Jan 2008 07:38:01 +0000 Subject: driver: tcm825x - fix logical typo error From: Cyrill Gorcunov This patch does fix potential NULL pointer dereference due to logical typo error. The issue is pointed out by Guennadi Liakhovetski CC: Sakari Ailus Signed-off-by: Cyrill Gorcunov Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/tcm825x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tcm825x.c b/linux/drivers/media/video/tcm825x.c index 41cd6a0b0..fb895f668 100644 --- a/linux/drivers/media/video/tcm825x.c +++ b/linux/drivers/media/video/tcm825x.c @@ -851,7 +851,7 @@ static int tcm825x_probe(struct i2c_client *client) sensor->platform_data = client->dev.platform_data; if (sensor->platform_data == NULL - && !sensor->platform_data->is_okay()) + || !sensor->platform_data->is_okay()) return -ENODEV; sensor->v4l2_int_device = &tcm825x_int_device; -- cgit v1.2.3 From 18e952cd5df8d1f9a8dfdedc805e412f5a4d7514 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 3 Nov 2007 13:10:08 -0400 Subject: tuner-simple: whitespace / comments / codingstyle cleanups From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/video/tuner-simple.c | 146 ++++++++++++++++++------------- 1 file changed, 83 insertions(+), 63 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tuner-simple.c b/linux/drivers/media/video/tuner-simple.c index 78e9bcace..1cb81befe 100644 --- a/linux/drivers/media/video/tuner-simple.c +++ b/linux/drivers/media/video/tuner-simple.c @@ -17,19 +17,19 @@ #include "tuner-i2c.h" #include "tuner-simple.h" -static int debug = 0; +static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable verbose debug messages"); #define PREFIX "tuner-simple" -static int offset = 0; +static int offset; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) MODULE_PARM(offset, "i"); #else module_param(offset, int, 0664); #endif -MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner"); +MODULE_PARM_DESC(offset, "Allows to specify an offset for tuner"); /* ---------------------------------------------------------------------- */ @@ -44,8 +44,8 @@ MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner"); */ #define TEMIC_SET_PAL_I 0x05 #define TEMIC_SET_PAL_DK 0x09 -#define TEMIC_SET_PAL_L 0x0a // SECAM ? -#define TEMIC_SET_PAL_L2 0x0b // change IF ! +#define TEMIC_SET_PAL_L 0x0a /* SECAM ? */ +#define TEMIC_SET_PAL_L2 0x0b /* change IF ! */ #define TEMIC_SET_PAL_BG 0x0c /* tv tuner system standard selection for Philips FQ1216ME @@ -115,7 +115,7 @@ static int tuner_read_status(struct dvb_frontend *fe) struct tuner_simple_priv *priv = fe->tuner_priv; unsigned char byte; - if (1 != tuner_i2c_xfer_recv(&priv->i2c_props,&byte,1)) + if (1 != tuner_i2c_xfer_recv(&priv->i2c_props, &byte, 1)) return 0; return byte; @@ -129,13 +129,13 @@ static inline int tuner_signal(const int status) static inline int tuner_stereo(const int type, const int status) { switch (type) { - case TUNER_PHILIPS_FM1216ME_MK3: - case TUNER_PHILIPS_FM1236_MK3: - case TUNER_PHILIPS_FM1256_IH3: - case TUNER_LG_NTSC_TAPE: - return ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); - default: - return status & TUNER_STEREO; + case TUNER_PHILIPS_FM1216ME_MK3: + case TUNER_PHILIPS_FM1236_MK3: + case TUNER_PHILIPS_FM1256_IH3: + case TUNER_LG_NTSC_TAPE: + return ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); + default: + return status & TUNER_STEREO; } } @@ -233,9 +233,9 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, continue; break; } - /* use default tuner_t_params if desired_type not available */ + /* use default tuner params if desired_type not available */ if (desired_type != tun->params[j].type) { - tuner_dbg("IFPCoff = %d: tuner_t_params undefined for tuner %d\n", + tuner_dbg("IFPCoff = %d: params undefined for tuner %d\n", IFPCoff, priv->type); j = 0; } @@ -248,7 +248,7 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, } if (i == t_params->count) { tuner_dbg("TV frequency out of range (%d > %d)", - params->frequency, t_params->ranges[i - 1].limit); + params->frequency, t_params->ranges[i - 1].limit); params->frequency = t_params->ranges[--i].limit; } config = t_params->ranges[i].config; @@ -256,24 +256,25 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, /* i == 0 -> VHF_LO * i == 1 -> VHF_HI * i == 2 -> UHF */ - tuner_dbg("tv: param %d, range %d\n",j,i); + tuner_dbg("tv: param %d, range %d\n", j, i); - div=params->frequency + IFPCoff + offset; + div = params->frequency + IFPCoff + offset; - tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, Offset=%d.%02d MHz, div=%0d\n", - params->frequency / 16, params->frequency % 16 * 100 / 16, - IFPCoff / 16, IFPCoff % 16 * 100 / 16, - offset / 16, offset % 16 * 100 / 16, - div); + tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, " + "Offset=%d.%02d MHz, div=%0d\n", + params->frequency / 16, params->frequency % 16 * 100 / 16, + IFPCoff / 16, IFPCoff % 16 * 100 / 16, + offset / 16, offset % 16 * 100 / 16, div); /* tv norm specific stuff for multi-norm tuners */ switch (priv->type) { - case TUNER_PHILIPS_SECAM: // FI1216MF + case TUNER_PHILIPS_SECAM: /* FI1216MF */ /* 0x01 -> ??? no change ??? */ /* 0x02 -> PAL BDGHI / SECAM L */ /* 0x04 -> ??? PAL others / SECAM others ??? */ cb &= ~0x03; - if (params->std & V4L2_STD_SECAM_L) //also valid for V4L2_STD_SECAM + if (params->std & V4L2_STD_SECAM_L) + /* also valid for V4L2_STD_SECAM */ cb |= PHILIPS_MF_SET_STD_L; else if (params->std & V4L2_STD_SECAM_LC) cb |= PHILIPS_MF_SET_STD_LC; @@ -347,10 +348,14 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, /* set to the correct mode (analog or digital) */ tuneraddr = priv->i2c_props.addr; priv->i2c_props.addr = 0x0a; - if (2 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,&buffer[0],2))) - tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc); - if (2 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,&buffer[2],2))) - tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc); + rc = tuner_i2c_xfer_send(&priv->i2c_props, &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); + if (2 != rc) + tuner_warn("i2c i/o error: rc == %d " + "(should be 2)\n", rc); priv->i2c_props.addr = tuneraddr; /* FIXME: input */ break; @@ -371,8 +376,10 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, if (t_params->has_tda9887) { struct v4l2_priv_tun_config tda9887_cfg; int config = 0; - int is_secam_l = (params->std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)) && - !(params->std & ~(V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)); + int is_secam_l = (params->std & (V4L2_STD_SECAM_L | + V4L2_STD_SECAM_LC)) && + !(params->std & ~(V4L2_STD_SECAM_L | + V4L2_STD_SECAM_LC)); tda9887_cfg.tuner = TUNER_TDA9887; tda9887_cfg.priv = &config; @@ -382,8 +389,7 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, config |= TDA9887_PORT1_ACTIVE; if (t_params->port2_active ^ t_params->port2_invert_for_secam_lc) config |= TDA9887_PORT2_ACTIVE; - } - else { + } else { if (t_params->port1_active) config |= TDA9887_PORT1_ACTIVE; if (t_params->port2_active) @@ -398,8 +404,7 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, config |= TDA9887_TOP(t_params->default_top_secam_mid); else if (t_params->default_top_secam_high) config |= TDA9887_TOP(t_params->default_top_secam_high); - } - else { + } else { if (i == 0 && t_params->default_top_low) config |= TDA9887_TOP(t_params->default_top_low); else if (i == 1 && t_params->default_top_mid) @@ -413,10 +418,11 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, &tda9887_cfg); } tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", - buffer[0],buffer[1],buffer[2],buffer[3]); + buffer[0], buffer[1], buffer[2], buffer[3]); - if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,buffer,4))) - tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); + rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4); + if (4 != rc) + tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc); switch (priv->type) { case TUNER_LG_TDVS_H06XF: @@ -426,33 +432,40 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, buffer[2] |= 0x18; buffer[3] = 0x20; tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", - buffer[0],buffer[1],buffer[2],buffer[3]); + buffer[0], buffer[1], buffer[2], buffer[3]); - if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,buffer,4))) - tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); + rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4); + if (4 != rc) + tuner_warn("i2c i/o error: rc == %d " + "(should be 4)\n", rc); #else buffer[0] = buffer[2]; buffer[0] &= ~0x20; buffer[0] |= 0x18; buffer[1] = 0x20; - tuner_dbg("tv 0x%02x 0x%02x\n",buffer[0],buffer[1]); + tuner_dbg("tv 0x%02x 0x%02x\n", buffer[0], buffer[1]); - if (2 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,buffer,2))) - tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc); + rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2); + if (2 != rc) + tuner_warn("i2c i/o error: rc == %d " + "(should be 2)\n", rc); #endif break; case TUNER_MICROTUNE_4042FI5: { - // FIXME - this may also work for other tuners + /* FIXME - this may also work for other tuners */ unsigned long timeout = jiffies + msecs_to_jiffies(1); u8 status_byte = 0; /* Wait until the PLL locks */ for (;;) { - if (time_after(jiffies,timeout)) + if (time_after(jiffies, timeout)) return 0; - if (1 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props,&status_byte,1))) { - tuner_warn("i2c i/o read error: rc == %d (should be 1)\n",rc); + rc = tuner_i2c_xfer_recv(&priv->i2c_props, + &status_byte, 1); + if (1 != rc) { + tuner_warn("i2c i/o read error: rc == %d " + "(should be 1)\n", rc); break; } if (status_byte & TUNER_PLL_LOCKED) @@ -467,10 +480,12 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, buffer[2] = config; buffer[3] = cb; tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", - buffer[0],buffer[1],buffer[2],buffer[3]); + buffer[0], buffer[1], buffer[2], buffer[3]); - if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,buffer,4))) - tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); + rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4); + if (4 != rc) + tuner_warn("i2c i/o error: rc == %d " + "(should be 4)\n", rc); break; } } @@ -508,7 +523,8 @@ static int simple_set_radio_freq(struct dvb_frontend *fe, freq += (unsigned int)(41.3*16000); break; default: - tuner_warn("Unsupported radio_if value %d\n", t_params->radio_if); + tuner_warn("Unsupported radio_if value %d\n", + t_params->radio_if); return 0; } @@ -516,7 +532,8 @@ static int simple_set_radio_freq(struct dvb_frontend *fe, switch (priv->type) { case TUNER_TENA_9533_DI: case TUNER_YMEC_TVF_5533MF: - tuner_dbg("This tuner doesn't have FM. Most cards have a TEA5767 for FM\n"); + tuner_dbg("This tuner doesn't have FM. " + "Most cards have a TEA5767 for FM\n"); return 0; case TUNER_PHILIPS_FM1216ME_MK3: case TUNER_PHILIPS_FM1236_MK3: @@ -559,7 +576,7 @@ static int simple_set_radio_freq(struct dvb_frontend *fe, } tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n", - buffer[0],buffer[1],buffer[2],buffer[3]); + buffer[0], buffer[1], buffer[2], buffer[3]); priv->last_div = div; if (t_params->has_tda9887) { @@ -569,9 +586,11 @@ static int simple_set_radio_freq(struct dvb_frontend *fe, tda9887_cfg.tuner = TUNER_TDA9887; tda9887_cfg.priv = &config; - if (t_params->port1_active && !t_params->port1_fm_high_sensitivity) + if (t_params->port1_active && + !t_params->port1_fm_high_sensitivity) config |= TDA9887_PORT1_ACTIVE; - if (t_params->port2_active && !t_params->port2_fm_high_sensitivity) + if (t_params->port2_active && + !t_params->port2_fm_high_sensitivity) config |= TDA9887_PORT2_ACTIVE; if (t_params->intercarrier_mode) config |= TDA9887_INTERCARRIER; @@ -582,10 +601,11 @@ static int simple_set_radio_freq(struct dvb_frontend *fe, if (t_params->radio_if == 2) config |= TDA9887_RIF_41_3; i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG, - &tda9887_cfg); + &tda9887_cfg); } - if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,buffer,4))) - tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); + rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4); + if (4 != rc) + tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc); return 0; } @@ -660,16 +680,16 @@ struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, priv->type = cfg->type; priv->tun = cfg->tun; - memcpy(&fe->ops.tuner_ops, &simple_tuner_ops, sizeof(struct dvb_tuner_ops)); + memcpy(&fe->ops.tuner_ops, &simple_tuner_ops, + sizeof(struct dvb_tuner_ops)); tuner_info("type set to %d (%s)\n", cfg->type, cfg->tun->name); - strlcpy(fe->ops.tuner_ops.info.name, cfg->tun->name, sizeof(fe->ops.tuner_ops.info.name)); + strlcpy(fe->ops.tuner_ops.info.name, cfg->tun->name, + sizeof(fe->ops.tuner_ops.info.name)); return fe; } - - EXPORT_SYMBOL_GPL(simple_tuner_attach); MODULE_DESCRIPTION("Simple 4-control-bytes style tuner driver"); -- cgit v1.2.3 From fb4d18652f9c170bba774056642015fc679637be Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 15 Jan 2008 23:49:32 -0500 Subject: tuner: create a macro for sharing state between hybrid tuner instances From: Michael Krufky Create a macro implementing a standard method to share state amongst multiple instances of a hybrid tuner object. Also, prepare tuner_foo printk macros for the removal of PREFIX Signed-off-by: Michael Krufky --- linux/drivers/media/video/tuner-i2c.h | 112 +++++++++++++++++++++++++++++----- 1 file changed, 96 insertions(+), 16 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tuner-i2c.h b/linux/drivers/media/video/tuner-i2c.h index de52e8ffd..8ec5b41d4 100644 --- a/linux/drivers/media/video/tuner-i2c.h +++ b/linux/drivers/media/video/tuner-i2c.h @@ -26,6 +26,10 @@ struct tuner_i2c_props { u8 addr; struct i2c_adapter *adap; + + /* used for tuner instance management */ + int count; + char *name; }; static inline int tuner_i2c_xfer_send(struct tuner_i2c_props *props, char *buf, int len) @@ -59,29 +63,105 @@ static inline int tuner_i2c_xfer_send_recv(struct tuner_i2c_props *props, return (ret == 2) ? ilen : ret; } -#define tuner_warn(fmt, arg...) do { \ - printk(KERN_WARNING "%s %d-%04x: " fmt, PREFIX, \ - i2c_adapter_id(priv->i2c_props.adap), \ - priv->i2c_props.addr, ##arg); \ +/* Callers must declare as a global for the module: + * + * static LIST_HEAD(hybrid_tuner_instance_list); + * + * hybrid_tuner_instance_list should be the third argument + * passed into hybrid_tuner_request_state(). + * + * state structure must contain the following: + * + * struct list_head hybrid_tuner_instance_list; + * struct tuner_i2c_props i2c_props; + * + * hybrid_tuner_instance_list (both within state structure and globally) + * is only required if the driver is using hybrid_tuner_request_state + * and hybrid_tuner_release_state to manage state sharing between + * multiple instances of hybrid tuners. + */ + +#define tuner_printk(kernlvl, i2cprops, fmt, arg...) do { \ + printk(kernlvl "%s %d-%04x: " fmt, i2cprops.name, \ + i2c_adapter_id(i2cprops.adap), \ + i2cprops.addr, ##arg); \ } while (0) -#define tuner_info(fmt, arg...) do { \ - printk(KERN_INFO "%s %d-%04x: " fmt, PREFIX, \ - i2c_adapter_id(priv->i2c_props.adap), \ - priv->i2c_props.addr , ##arg); \ +/* TO DO: convert all callers of these macros to pass in + * struct tuner_i2c_props, then remove the macro wrappers */ + +#define __tuner_warn(i2cprops, fmt, arg...) do { \ + tuner_printk(KERN_WARNING, i2cprops, fmt, ##arg); \ } while (0) -#define tuner_err(fmt, arg...) do { \ - printk(KERN_ERR "%s %d-%04x: " fmt, PREFIX, \ - i2c_adapter_id(priv->i2c_props.adap), \ - priv->i2c_props.addr , ##arg); \ +#define __tuner_info(i2cprops, fmt, arg...) do { \ + tuner_printk(KERN_INFO, i2cprops, fmt, ##arg); \ } while (0) -#define tuner_dbg(fmt, arg...) do { \ +#define __tuner_err(i2cprops, fmt, arg...) do { \ + tuner_printk(KERN_ERR, i2cprops, fmt, ##arg); \ + } while (0) + +#define __tuner_dbg(i2cprops, fmt, arg...) do { \ if ((debug)) \ - printk(KERN_DEBUG "%s %d-%04x: " fmt, PREFIX, \ - i2c_adapter_id(priv->i2c_props.adap), \ - priv->i2c_props.addr , ##arg); \ + tuner_printk(KERN_DEBUG, i2cprops, fmt, ##arg); \ } while (0) +#define tuner_warn(fmt, arg...) __tuner_warn(priv->i2c_props, fmt, ##arg) +#define tuner_info(fmt, arg...) __tuner_info(priv->i2c_props, fmt, ##arg) +#define tuner_err(fmt, arg...) __tuner_err(priv->i2c_props, fmt, ##arg) +#define tuner_dbg(fmt, arg...) __tuner_dbg(priv->i2c_props, fmt, ##arg) + +/****************************************************************************/ + +/* The return value of hybrid_tuner_request_state indicates the number of + * instances using this tuner object. + * + * 0 - no instances, indicates an error - kzalloc must have failed + * + * 1 - one instance, indicates that the tuner object was created successfully + * + * 2 (or more) instances, indicates that an existing tuner object was found + */ + +#define hybrid_tuner_request_state(type, state, list, i2cadap, i2caddr, devname)\ +({ \ + int __ret = 0; \ + list_for_each_entry(state, &list, hybrid_tuner_instance_list) { \ + if ((i2c_adapter_id(state->i2c_props.adap) == \ + i2c_adapter_id(i2cadap)) && \ + (state->i2c_props.addr == i2caddr)) { \ + __tuner_info(state->i2c_props, \ + "attaching existing instance\n"); \ + state->i2c_props.count++; \ + __ret = state->i2c_props.count; \ + break; \ + } \ + } \ + if (0 == __ret) { \ + state = kzalloc(sizeof(type), GFP_KERNEL); \ + if (NULL == state) \ + goto __fail; \ + state->i2c_props.addr = i2caddr; \ + state->i2c_props.adap = i2cadap; \ + state->i2c_props.name = devname; \ + __tuner_info(state->i2c_props, \ + "creating new instance\n"); \ + list_add_tail(&state->hybrid_tuner_instance_list, &list);\ + state->i2c_props.count++; \ + __ret = state->i2c_props.count; \ + } \ +__fail: \ + __ret; \ +}) + +#define hybrid_tuner_release_state(state) do { \ + state->i2c_props.count--; \ + if (!state->i2c_props.count) { \ + __tuner_info(state->i2c_props, "destroying instance\n");\ + list_del(&state->hybrid_tuner_instance_list); \ + kfree(state); \ + } \ +} while (0) + #endif /* __TUNER_I2C_H__ */ -- cgit v1.2.3 From 4d123d17a4874afde71b5362e54296a7ec12c266 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 2 Feb 2008 22:58:38 -0500 Subject: remove PREFIX from users of tuner_foo printk macros From: Michael Krufky Store a pointer to the device name in the name field of struct tuner_i2c_props, so that we can remove the printk macros defined in tuner-i2c.h Signed-off-by: Michael Krufky --- linux/drivers/media/video/mt20xx.c | 3 +-- linux/drivers/media/video/tda8290.c | 3 +-- linux/drivers/media/video/tda9887.c | 3 +-- linux/drivers/media/video/tea5761.c | 5 ++--- linux/drivers/media/video/tea5767.c | 32 ++++++++++++++++---------------- linux/drivers/media/video/tuner-simple.c | 4 ++-- linux/drivers/media/video/tuner-xc2028.c | 8 ++++---- 7 files changed, 27 insertions(+), 31 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/mt20xx.c b/linux/drivers/media/video/mt20xx.c index cd1122e4d..cdf7450b5 100644 --- a/linux/drivers/media/video/mt20xx.c +++ b/linux/drivers/media/video/mt20xx.c @@ -18,8 +18,6 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable verbose debug messages"); -#define PREFIX "mt20xx" - /* ---------------------------------------------------------------------- */ static unsigned int optimize_vco = 1; @@ -631,6 +629,7 @@ struct dvb_frontend *microtune_attach(struct dvb_frontend *fe, priv->i2c_props.addr = i2c_addr; priv->i2c_props.adap = i2c_adap; + priv->i2c_props.name = "mt20xx"; //priv->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */ diff --git a/linux/drivers/media/video/tda8290.c b/linux/drivers/media/video/tda8290.c index 1bda0024b..74e2e89c3 100644 --- a/linux/drivers/media/video/tda8290.c +++ b/linux/drivers/media/video/tda8290.c @@ -36,8 +36,6 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable verbose debug messages"); -#define PREFIX "tda8290" - /* ---------------------------------------------------------------------- */ struct tda8290_priv { @@ -700,6 +698,7 @@ struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, priv->i2c_props.addr = i2c_addr; priv->i2c_props.adap = i2c_adap; + priv->i2c_props.name = "tda829x"; if (cfg) { priv->cfg.config = cfg->lna_cfg; priv->cfg.tuner_callback = cfg->tuner_callback; diff --git a/linux/drivers/media/video/tda9887.c b/linux/drivers/media/video/tda9887.c index fda15da1f..aa640c470 100644 --- a/linux/drivers/media/video/tda9887.c +++ b/linux/drivers/media/video/tda9887.c @@ -29,8 +29,6 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable verbose debug messages"); -#define PREFIX "tda9887" - struct tda9887_priv { struct tuner_i2c_props i2c_props; @@ -684,6 +682,7 @@ struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe, priv->i2c_props.addr = i2c_addr; priv->i2c_props.adap = i2c_adap; + priv->i2c_props.name = "tda9887"; priv->mode = T_STANDBY; tuner_info("tda988[5/6/7] found\n"); diff --git a/linux/drivers/media/video/tea5761.c b/linux/drivers/media/video/tea5761.c index 3b96d5354..fa1d12d6f 100644 --- a/linux/drivers/media/video/tea5761.c +++ b/linux/drivers/media/video/tea5761.c @@ -19,8 +19,6 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable verbose debug messages"); -#define PREFIX "tea5761" - struct tea5761_priv { struct tuner_i2c_props i2c_props; @@ -132,7 +130,7 @@ static void tea5761_status_dump(unsigned char *buffer) frq = 1000 * (div * 32768 / 1000 + FREQ_OFFSET + 225) / 4; /* Freq in KHz */ - printk(PREFIX "Frequency %d.%03d KHz (divider = 0x%04x)\n", + printk(KERN_INFO "tea5761: Frequency %d.%03d KHz (divider = 0x%04x)\n", frq / 1000, frq % 1000, div); } @@ -308,6 +306,7 @@ struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe, priv->i2c_props.addr = i2c_addr; priv->i2c_props.adap = i2c_adap; + priv->i2c_props.name = "tea5761"; memcpy(&fe->ops.tuner_ops, &tea5761_tuner_ops, sizeof(struct dvb_tuner_ops)); diff --git a/linux/drivers/media/video/tea5767.c b/linux/drivers/media/video/tea5767.c index a19f0a6a9..c4f39a5d3 100644 --- a/linux/drivers/media/video/tea5767.c +++ b/linux/drivers/media/video/tea5767.c @@ -24,8 +24,6 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable verbose debug messages"); -#define PREFIX "tea5767" - /*****************************************************************************/ struct tea5767_priv { @@ -141,14 +139,14 @@ static void tea5767_status_dump(struct tea5767_priv *priv, unsigned int div, frq; if (TEA5767_READY_FLAG_MASK & buffer[0]) - printk(PREFIX "Ready Flag ON\n"); + tuner_info("Ready Flag ON\n"); else - printk(PREFIX "Ready Flag OFF\n"); + tuner_info("Ready Flag OFF\n"); if (TEA5767_BAND_LIMIT_MASK & buffer[0]) - printk(PREFIX "Tuner at band limit\n"); + tuner_info("Tuner at band limit\n"); else - printk(PREFIX "Tuner not at band limit\n"); + tuner_info("Tuner not at band limit\n"); div = ((buffer[0] & 0x3f) << 8) | buffer[1]; @@ -170,23 +168,23 @@ static void tea5767_status_dump(struct tea5767_priv *priv, buffer[0] = (div >> 8) & 0x3f; buffer[1] = div & 0xff; - printk(PREFIX "Frequency %d.%03d KHz (divider = 0x%04x)\n", - frq / 1000, frq % 1000, div); + tuner_info("Frequency %d.%03d KHz (divider = 0x%04x)\n", + frq / 1000, frq % 1000, div); if (TEA5767_STEREO_MASK & buffer[2]) - printk(PREFIX "Stereo\n"); + tuner_info("Stereo\n"); else - printk(PREFIX "Mono\n"); + tuner_info("Mono\n"); - printk(PREFIX "IF Counter = %d\n", buffer[2] & TEA5767_IF_CNTR_MASK); + tuner_info("IF Counter = %d\n", buffer[2] & TEA5767_IF_CNTR_MASK); - printk(PREFIX "ADC Level = %d\n", - (buffer[3] & TEA5767_ADC_LEVEL_MASK) >> 4); + tuner_info("ADC Level = %d\n", + (buffer[3] & TEA5767_ADC_LEVEL_MASK) >> 4); - printk(PREFIX "Chip ID = %d\n", (buffer[3] & TEA5767_CHIP_ID_MASK)); + tuner_info("Chip ID = %d\n", (buffer[3] & TEA5767_CHIP_ID_MASK)); - printk(PREFIX "Reserved = 0x%02x\n", - (buffer[4] & TEA5767_RESERVED_MASK)); + tuner_info("Reserved = 0x%02x\n", + (buffer[4] & TEA5767_RESERVED_MASK)); } /* Freq should be specifyed at 62.5 Hz */ @@ -500,6 +498,8 @@ struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe, priv->i2c_props.addr = i2c_addr; priv->i2c_props.adap = i2c_adap; + priv->i2c_props.name = "tea5767"; + priv->ctrl.xtal_freq = TEA5767_HIGH_LO_32768; priv->ctrl.port1 = 1; priv->ctrl.port2 = 1; diff --git a/linux/drivers/media/video/tuner-simple.c b/linux/drivers/media/video/tuner-simple.c index 5f4b2153e..24f63945d 100644 --- a/linux/drivers/media/video/tuner-simple.c +++ b/linux/drivers/media/video/tuner-simple.c @@ -21,8 +21,6 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable verbose debug messages"); -#define PREFIX "tuner-simple" - static int offset; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) MODULE_PARM(offset, "i"); @@ -773,6 +771,8 @@ struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, priv->i2c_props.addr = i2c_addr; priv->i2c_props.adap = i2c_adap; + priv->i2c_props.name = "tuner-simple"; + priv->type = type; priv->tun = &tuners[type]; diff --git a/linux/drivers/media/video/tuner-xc2028.c b/linux/drivers/media/video/tuner-xc2028.c index 9aed0aabb..95cc51bb7 100644 --- a/linux/drivers/media/video/tuner-xc2028.c +++ b/linux/drivers/media/video/tuner-xc2028.c @@ -34,8 +34,6 @@ #define strcasecmp(a, b) strnicmp(a, b, sizeof(a)) #endif -#define PREFIX "xc2028" - static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable verbose debug messages"); @@ -1169,13 +1167,13 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, void *video_dev; if (debug) - printk(KERN_DEBUG PREFIX ": Xcv2028/3028 init called!\n"); + printk(KERN_DEBUG "xc2028: Xcv2028/3028 init called!\n"); if (NULL == cfg || NULL == cfg->video_dev) return NULL; if (!fe) { - printk(KERN_ERR PREFIX ": No frontend!\n"); + printk(KERN_ERR "xc2028: No frontend!\n"); return NULL; } @@ -1199,6 +1197,8 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, priv->i2c_props.addr = cfg->i2c_addr; priv->i2c_props.adap = cfg->i2c_adap; + priv->i2c_props.name = "xc2028"; + priv->video_dev = video_dev; priv->tuner_callback = cfg->callback; priv->ctrl.max_len = 13; -- cgit v1.2.3 From 935d6f27369c37df462a015d2046f20c36a23ddd Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 15 Jan 2008 23:51:22 -0500 Subject: tda18271: use hybrid_tuner_request_state to manage tuner instances From: Michael Krufky Convert tda18271 to use the new hybrid_tuner_request_state and hybrid_tuner_release_state macros to manage state sharing between hybrid tuner instances. Signed-off-by: Michael Krufky --- .../drivers/media/dvb/frontends/tda18271-common.c | 19 ++++--- linux/drivers/media/dvb/frontends/tda18271-fe.c | 66 ++++++++-------------- linux/drivers/media/dvb/frontends/tda18271-priv.h | 7 +-- 3 files changed, 37 insertions(+), 55 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/tda18271-common.c b/linux/drivers/media/dvb/frontends/tda18271-common.c index acb9dd4ee..d0596b999 100644 --- a/linux/drivers/media/dvb/frontends/tda18271-common.c +++ b/linux/drivers/media/dvb/frontends/tda18271-common.c @@ -125,16 +125,16 @@ int tda18271_read_regs(struct dvb_frontend *fe) unsigned char buf = 0x00; int ret; struct i2c_msg msg[] = { - { .addr = priv->i2c_addr, .flags = 0, + { .addr = priv->i2c_props.addr, .flags = 0, .buf = &buf, .len = 1 }, - { .addr = priv->i2c_addr, .flags = I2C_M_RD, + { .addr = priv->i2c_props.addr, .flags = I2C_M_RD, .buf = regs, .len = 16 } }; tda18271_i2c_gate_ctrl(fe, 1); /* read all registers */ - ret = i2c_transfer(priv->i2c_adap, msg, 2); + ret = i2c_transfer(priv->i2c_props.adap, msg, 2); tda18271_i2c_gate_ctrl(fe, 0); @@ -155,16 +155,16 @@ int tda18271_read_extended(struct dvb_frontend *fe) unsigned char buf = 0x00; int ret, i; struct i2c_msg msg[] = { - { .addr = priv->i2c_addr, .flags = 0, + { .addr = priv->i2c_props.addr, .flags = 0, .buf = &buf, .len = 1 }, - { .addr = priv->i2c_addr, .flags = I2C_M_RD, + { .addr = priv->i2c_props.addr, .flags = I2C_M_RD, .buf = regdump, .len = TDA18271_NUM_REGS } }; tda18271_i2c_gate_ctrl(fe, 1); /* read all registers */ - ret = i2c_transfer(priv->i2c_adap, msg, 2); + ret = i2c_transfer(priv->i2c_props.adap, msg, 2); tda18271_i2c_gate_ctrl(fe, 0); @@ -192,7 +192,7 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len) struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; unsigned char buf[TDA18271_NUM_REGS + 1]; - struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, + struct i2c_msg msg = { .addr = priv->i2c_props.addr, .flags = 0, .buf = buf, .len = len + 1 }; int i, ret; @@ -205,7 +205,7 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len) tda18271_i2c_gate_ctrl(fe, 1); /* write registers */ - ret = i2c_transfer(priv->i2c_adap, &msg, 1); + ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); tda18271_i2c_gate_ctrl(fe, 0); @@ -223,7 +223,8 @@ int tda18271_init_regs(struct dvb_frontend *fe) unsigned char *regs = priv->tda18271_regs; tda_dbg("initializing registers for device @ %d-%04x\n", - i2c_adapter_id(priv->i2c_adap), priv->i2c_addr); + i2c_adapter_id(priv->i2c_props.adap), + priv->i2c_props.addr); /* initialize registers */ switch (priv->id) { diff --git a/linux/drivers/media/dvb/frontends/tda18271-fe.c b/linux/drivers/media/dvb/frontends/tda18271-fe.c index b9e857855..0e14552d0 100644 --- a/linux/drivers/media/dvb/frontends/tda18271-fe.c +++ b/linux/drivers/media/dvb/frontends/tda18271-fe.c @@ -32,8 +32,8 @@ static int tda18271_cal_on_startup; module_param_named(cal, tda18271_cal_on_startup, int, 0644); MODULE_PARM_DESC(cal, "perform RF tracking filter calibration on startup"); -static LIST_HEAD(tda18271_list); static DEFINE_MUTEX(tda18271_list_mutex); +static LIST_HEAD(hybrid_tuner_instance_list); /*---------------------------------------------------------------------*/ @@ -1010,16 +1010,9 @@ static int tda18271_release(struct dvb_frontend *fe) mutex_lock(&tda18271_list_mutex); - priv->count--; + if (priv) + hybrid_tuner_release_state(priv); - if (!priv->count) { - tda_dbg("destroying instance @ %d-%04x\n", - i2c_adapter_id(priv->i2c_adap), - priv->i2c_addr); - list_del(&priv->tda18271_list); - - kfree(priv); - } mutex_unlock(&tda18271_list_mutex); fe->tuner_priv = NULL; @@ -1133,7 +1126,8 @@ static int tda18271_get_id(struct dvb_frontend *fe) } tda_info("%s detected @ %d-%04x%s\n", name, - i2c_adapter_id(priv->i2c_adap), priv->i2c_addr, + i2c_adapter_id(priv->i2c_props.adap), + priv->i2c_props.addr, (0 == ret) ? "" : ", device not supported."); return ret; @@ -1160,46 +1154,25 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, struct tda18271_config *cfg) { struct tda18271_priv *priv = NULL; - int state_found = 0; + int instance; mutex_lock(&tda18271_list_mutex); - list_for_each_entry(priv, &tda18271_list, tda18271_list) { - if ((i2c_adapter_id(priv->i2c_adap) == i2c_adapter_id(i2c)) && - (priv->i2c_addr == addr)) { - tda_dbg("attaching existing tuner @ %d-%04x\n", - i2c_adapter_id(priv->i2c_adap), - priv->i2c_addr); - priv->count++; - fe->tuner_priv = priv; - state_found = 1; - /* allow dvb driver to override i2c gate setting */ - if ((cfg) && (cfg->gate != TDA18271_GATE_ANALOG)) - priv->gate = cfg->gate; - break; - } - } - if (state_found == 0) { - tda_dbg("creating new tuner instance @ %d-%04x\n", - i2c_adapter_id(i2c), addr); - - priv = kzalloc(sizeof(struct tda18271_priv), GFP_KERNEL); - if (priv == NULL) { - mutex_unlock(&tda18271_list_mutex); - return NULL; - } - - priv->i2c_addr = addr; - priv->i2c_adap = i2c; + instance = hybrid_tuner_request_state(struct tda18271_priv, priv, + hybrid_tuner_instance_list, + i2c, addr, "tda18271"); + switch (instance) { + case 0: + goto fail; + break; + case 1: + /* new tuner instance */ priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; priv->cal_initialized = false; mutex_init(&priv->lock); - priv->count++; fe->tuner_priv = priv; - list_add_tail(&priv->tda18271_list, &tda18271_list); - if (tda18271_get_id(fe) < 0) goto fail; @@ -1213,6 +1186,15 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, tda18271_rf_cal_init(fe); mutex_unlock(&priv->lock); + break; + default: + /* existing tuner instance */ + fe->tuner_priv = priv; + + /* allow dvb driver to override i2c gate setting */ + if ((cfg) && (cfg->gate != TDA18271_GATE_ANALOG)) + priv->gate = cfg->gate; + break; } /* override default std map with values in config struct */ diff --git a/linux/drivers/media/dvb/frontends/tda18271-priv.h b/linux/drivers/media/dvb/frontends/tda18271-priv.h index ad4b59771..5f8af8140 100644 --- a/linux/drivers/media/dvb/frontends/tda18271-priv.h +++ b/linux/drivers/media/dvb/frontends/tda18271-priv.h @@ -29,6 +29,7 @@ #else #include #endif +#include "tuner-i2c.h" #include "tda18271.h" #define R_ID 0x00 /* ID byte */ @@ -103,17 +104,15 @@ enum tda18271_ver { }; struct tda18271_priv { - u8 i2c_addr; - struct i2c_adapter *i2c_adap; unsigned char tda18271_regs[TDA18271_NUM_REGS]; - struct list_head tda18271_list; + struct list_head hybrid_tuner_instance_list; + struct tuner_i2c_props i2c_props; enum tda18271_mode mode; enum tda18271_i2c_gate gate; enum tda18271_ver id; - unsigned int count; unsigned int tm_rfcal; unsigned int cal_initialized:1; -- cgit v1.2.3 From 026f98f7aaf190c6598d250120f2a929f4360cfe Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Mon, 4 Feb 2008 17:41:54 -0800 Subject: [v4l] Add new user class controls and deprecate others These changes should appear in the next update of the v4l2spec. HCENTER and VCENTER are unused in the tree so I added a _DEPRECATED postfix so applications can remove their use. Signed-off-by: Brandon Philips --- linux/include/linux/videodev2.h | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'linux') diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index 736600002..f0825c365 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -848,21 +848,34 @@ struct v4l2_querymenu #define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8) #define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9) #define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10) -#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) +#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) /* Deprecated */ #define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12) #define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13) #define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14) #define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15) #define V4L2_CID_GAMMA (V4L2_CID_BASE+16) -#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* ? Not sure */ +#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* Deprecated */ #define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17) #define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18) #define V4L2_CID_GAIN (V4L2_CID_BASE+19) #define V4L2_CID_HFLIP (V4L2_CID_BASE+20) #define V4L2_CID_VFLIP (V4L2_CID_BASE+21) -#define V4L2_CID_HCENTER (V4L2_CID_BASE+22) -#define V4L2_CID_VCENTER (V4L2_CID_BASE+23) -#define V4L2_CID_LASTP1 (V4L2_CID_BASE+24) /* last CID + 1 */ + +/* Deprecated, use V4L2_CID_PAN_RESET and V4L2_CID_TILT_RESET */ +#define V4L2_CID_HCENTER_DEPRECATED (V4L2_CID_BASE+22) +#define V4L2_CID_VCENTER_DEPRECATED (V4L2_CID_BASE+23) + +#define V4L2_CID_POWER_LINE_FREQUENCY (V4L2_CID_BASE+24) +enum v4l2_power_line_frequency { + V4L2_CID_POWER_LINE_FREQUENCY_DISABLED = 0, + V4L2_CID_POWER_LINE_FREQUENCY_50HZ = 1, + V4L2_CID_POWER_LINE_FREQUENCY_60HZ = 2, +}; +#define V4L2_CID_HUE_AUTO (V4L2_CID_BASE+25) +#define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE+26) +#define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27) +#define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28) +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+29) /* last CID + 1 */ /* MPEG-class control IDs defined by V4L2 */ #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) -- cgit v1.2.3 From 88ea998f01ef174ef5e1201af6405186daa34e4c Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Mon, 28 Jan 2008 00:49:26 -0800 Subject: [v4l] Add camera class control definitions Add all of the recently proposed camera class controls. These controls should appear in the next version of the v4l2spec. Signed-off-by: Brandon Philips --- linux/include/linux/videodev2.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'linux') diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index f0825c365..a43a03e02 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -792,6 +792,7 @@ struct v4l2_ext_controls /* Values for ctrl_class field */ #define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */ #define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */ +#define V4L2_CTRL_CLASS_CAMERA 0x009a0000 /* Camera class controls */ #define V4L2_CTRL_ID_MASK (0x0fffffff) #define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL) @@ -1063,6 +1064,32 @@ enum v4l2_mpeg_cx2341x_video_median_filter_type { #define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10) #define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11) +/* Camera class control IDs */ +#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) +#define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1) + +#define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_CAMERA_CLASS_BASE+1) +enum v4l2_exposure_auto_type { + V4L2_EXPOSURE_AUTO = 0, + V4L2_EXPOSURE_MANUAL = 1, + V4L2_EXPOSURE_SHUTTER_PRIORITY = 2, + V4L2_EXPOSURE_APERTURE_PRIORITY = 3 +}; +#define V4L2_CID_EXPOSURE_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+2) +#define V4L2_CID_EXPOSURE_AUTO_PRIORITY (V4L2_CID_CAMERA_CLASS_BASE+3) + +#define V4L2_CID_PAN_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+4) +#define V4L2_CID_TILT_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+5) +#define V4L2_CID_PAN_RESET (V4L2_CID_CAMERA_CLASS_BASE+6) +#define V4L2_CID_TILT_RESET (V4L2_CID_CAMERA_CLASS_BASE+7) + +#define V4L2_CID_PAN_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+8) +#define V4L2_CID_TILT_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+9) + +#define V4L2_CID_FOCUS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+10) +#define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11) +#define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12) + /* * T U N I N G */ -- cgit v1.2.3 From 7def2586b2e59194311664b119b23e310483c6c3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 4 Feb 2008 16:32:42 -0200 Subject: Add two new fourcc codes for 16bpp formats From: Steven Whitehouse This adds two new fourcc codes (as per info at fourcc.org) for 16bpp mono and 16bpp Bayer formats. Signed-off-by: Steven Whitehouse Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/Kconfig | 9 +++++++++ linux/include/linux/videodev2.h | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 37072a21d..c0498ac98 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -836,4 +836,13 @@ config USB_STKWEBCAM endif # V4L_USB_DRIVERS +config SOC_CAMERA + tristate "SoC camera support" + depends on VIDEO_V4L2 + select VIDEOBUF_DMA_SG + help + SoC Camera is a common API to several cameras, not connecting + over a bus like PCI or USB. For example some i2c camera connected + directly to the data bus of an SoC. + endif # VIDEO_CAPTURE_DRIVERS diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index 736600002..55bec7416 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -281,6 +281,7 @@ struct v4l2_pix_format #define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B','G','R','4') /* 32 BGR-8-8-8-8 */ #define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R','G','B','4') /* 32 RGB-8-8-8-8 */ #define V4L2_PIX_FMT_GREY v4l2_fourcc('G','R','E','Y') /* 8 Greyscale */ +#define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y','1','6',' ') /* 16 Greyscale */ #define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P','A','L','8') /* 8 8-bit palette */ #define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y','V','U','9') /* 9 YVU 4:1:0 */ #define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y','V','1','2') /* 12 YVU 4:2:0 */ @@ -307,6 +308,7 @@ struct v4l2_pix_format /* see http://www.siliconimaging.com/RGB%20Bayer.htm */ #define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B','A','8','1') /* 8 BGBG.. GRGR.. */ +#define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B','Y','R','2') /* 16 BGBG.. GRGR.. */ /* compressed formats */ #define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M','J','P','G') /* Motion-JPEG */ @@ -862,7 +864,8 @@ struct v4l2_querymenu #define V4L2_CID_VFLIP (V4L2_CID_BASE+21) #define V4L2_CID_HCENTER (V4L2_CID_BASE+22) #define V4L2_CID_VCENTER (V4L2_CID_BASE+23) -#define V4L2_CID_LASTP1 (V4L2_CID_BASE+24) /* last CID + 1 */ +#define V4L2_CID_AUTOEXPOSURE (V4L2_CID_BASE+24) +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+25) /* last CID + 1 */ /* MPEG-class control IDs defined by V4L2 */ #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) -- cgit v1.2.3 From 585e2c45351b12d0acfabbf83a99f5f43ef40fe6 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Mon, 4 Feb 2008 12:52:20 -0800 Subject: [v4l] Fix v4l against 2.6.25 tree This won't fix the build quite yet since SUBLEVEL hasn't been changed in the Makefile for 2.6.25. But, there isn't much we can do without breaking the build against 2.6.24 too... Fixes the build against these two commits. bdc511f438f6ca40307e06edda00331e6ac0f813 bfb6df24facfde7ec6191edbba798777efb3c375 Signed-off-by: Brandon Philips --- linux/drivers/media/video/ks0127.c | 1 - linux/include/media/v4l2-i2c-drv-legacy.h | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/ks0127.c b/linux/drivers/media/video/ks0127.c index b1d965bcd..90451230d 100644 --- a/linux/drivers/media/video/ks0127.c +++ b/linux/drivers/media/video/ks0127.c @@ -765,7 +765,6 @@ static struct i2c_client ks0127_client_tmpl = .addr = 0, .adapter = NULL, .driver = &i2c_driver_ks0127, - .usage_count = 0 }; static int ks0127_found_proc(struct i2c_adapter *adapter, int addr, int kind) diff --git a/linux/include/media/v4l2-i2c-drv-legacy.h b/linux/include/media/v4l2-i2c-drv-legacy.h index fa55a1479..812f18516 100644 --- a/linux/include/media/v4l2-i2c-drv-legacy.h +++ b/linux/include/media/v4l2-i2c-drv-legacy.h @@ -38,7 +38,11 @@ struct v4l2_i2c_driver_data { }; static struct v4l2_i2c_driver_data v4l2_i2c_data; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) +const static struct i2c_client_address_data addr_data; +#else static struct i2c_client_address_data addr_data; +#endif static struct i2c_driver v4l2_i2c_driver_legacy; static char v4l2_i2c_drv_name_legacy[32]; -- cgit v1.2.3 From c239611668a3d8add80d686d266956a8fcac5ca4 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Mon, 4 Feb 2008 12:52:21 -0800 Subject: [v4l] convert videbuf_vmalloc_memory to videobuf_vmalloc_memory Signed-off-by: Brandon Philips --- linux/drivers/media/video/videobuf-vmalloc.c | 16 +++++++--------- linux/include/media/videobuf-vmalloc.h | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/videobuf-vmalloc.c b/linux/drivers/media/video/videobuf-vmalloc.c index 18e070204..4af0d329f 100644 --- a/linux/drivers/media/video/videobuf-vmalloc.c +++ b/linux/drivers/media/video/videobuf-vmalloc.c @@ -108,7 +108,7 @@ static struct vm_operations_struct videobuf_vm_ops = static void *__videobuf_alloc(size_t size) { - struct videbuf_vmalloc_memory *mem; + struct videobuf_vmalloc_memory *mem; struct videobuf_buffer *vb; vb = kzalloc(size+sizeof(*mem),GFP_KERNEL); @@ -128,9 +128,7 @@ static int __videobuf_iolock (struct videobuf_queue* q, struct v4l2_framebuffer *fbuf) { int pages; - - struct videbuf_vmalloc_memory *mem=vb->priv; - + struct videobuf_vmalloc_memory *mem=vb->priv; BUG_ON(!mem); @@ -196,7 +194,7 @@ static int __videobuf_mmap_free(struct videobuf_queue *q) static int __videobuf_mmap_mapper(struct videobuf_queue *q, struct vm_area_struct *vma) { - struct videbuf_vmalloc_memory *mem; + struct videobuf_vmalloc_memory *mem; struct videobuf_mapping *map; unsigned int first; int retval; @@ -268,7 +266,7 @@ static int __videobuf_copy_to_user ( struct videobuf_queue *q, char __user *data, size_t count, int nonblocking ) { - struct videbuf_vmalloc_memory *mem=q->read_buf->priv; + struct videobuf_vmalloc_memory *mem=q->read_buf->priv; BUG_ON (!mem); MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM); @@ -289,7 +287,7 @@ static int __videobuf_copy_stream ( struct videobuf_queue *q, int vbihack, int nonblocking ) { unsigned int *fc; - struct videbuf_vmalloc_memory *mem=q->read_buf->priv; + struct videobuf_vmalloc_memory *mem=q->read_buf->priv; BUG_ON (!mem); MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM); @@ -342,7 +340,7 @@ EXPORT_SYMBOL_GPL(videobuf_queue_vmalloc_init); void *videobuf_to_vmalloc (struct videobuf_buffer *buf) { - struct videbuf_vmalloc_memory *mem=buf->priv; + struct videobuf_vmalloc_memory *mem=buf->priv; BUG_ON (!mem); MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM); @@ -352,7 +350,7 @@ EXPORT_SYMBOL_GPL(videobuf_to_vmalloc); void videobuf_vmalloc_free (struct videobuf_buffer *buf) { - struct videbuf_vmalloc_memory *mem=buf->priv; + struct videobuf_vmalloc_memory *mem=buf->priv; BUG_ON (!mem); MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM); diff --git a/linux/include/media/videobuf-vmalloc.h b/linux/include/media/videobuf-vmalloc.h index 26a8958d2..ec63ab0fa 100644 --- a/linux/include/media/videobuf-vmalloc.h +++ b/linux/include/media/videobuf-vmalloc.h @@ -17,7 +17,7 @@ /* --------------------------------------------------------------------- */ -struct videbuf_vmalloc_memory +struct videobuf_vmalloc_memory { u32 magic; -- cgit v1.2.3 From 64258f263ffc8746f1365db19d6c2800c871d1bf Mon Sep 17 00:00:00 2001 From: Hartmut Hackmann Date: Sun, 10 Feb 2008 00:54:24 +0100 Subject: tda10086: make the 22kHz tone for DISEQC a config option From: Hartmut Hackmann Some cards need the diseqc signal modulated, while some just need the envelope to control the LNB supply. This fixes Bug 9887 Signed-off-by: Hartmut Hackmann Acked-By: Patrick Boettcher Acked-by: Oliver Endriss --- linux/drivers/media/dvb/dvb-usb/ttusb2.c | 1 + linux/drivers/media/dvb/frontends/tda10086.c | 28 +++++++++++++++++++------ linux/drivers/media/dvb/frontends/tda10086.h | 3 +++ linux/drivers/media/dvb/ttpci/budget.c | 1 + linux/drivers/media/video/saa7134/saa7134-dvb.c | 5 +++-- 5 files changed, 30 insertions(+), 8 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-usb/ttusb2.c b/linux/drivers/media/dvb/dvb-usb/ttusb2.c index fc47d53f5..bafe82f66 100644 --- a/linux/drivers/media/dvb/dvb-usb/ttusb2.c +++ b/linux/drivers/media/dvb/dvb-usb/ttusb2.c @@ -150,6 +150,7 @@ static int ttusb2_streaming_ctrl(struct dvb_usb_device *d, int onoff) static struct tda10086_config tda10086_config = { .demod_address = 0x0e, .invert = 0, + .diseqc_tone = 1, }; static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap) diff --git a/linux/drivers/media/dvb/frontends/tda10086.c b/linux/drivers/media/dvb/frontends/tda10086.c index 0eef34b6f..a4b48bdf2 100644 --- a/linux/drivers/media/dvb/frontends/tda10086.c +++ b/linux/drivers/media/dvb/frontends/tda10086.c @@ -107,9 +107,12 @@ static int tda10086_write_mask(struct tda10086_state *state, int reg, int mask, static int tda10086_init(struct dvb_frontend* fe) { struct tda10086_state* state = fe->demodulator_priv; + u8 t22k_off = 0x80; dprintk ("%s\n", __FUNCTION__); + if (state->config->diseqc_tone) + t22k_off = 0; // reset tda10086_write_byte(state, 0x00, 0x00); msleep(10); @@ -159,7 +162,7 @@ static int tda10086_init(struct dvb_frontend* fe) tda10086_write_byte(state, 0x3d, 0x80); // setup SEC - tda10086_write_byte(state, 0x36, 0x80); // all SEC off, no 22k tone + tda10086_write_byte(state, 0x36, t22k_off); // all SEC off, 22k tone tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000))); // } tone frequency tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8); // } @@ -181,16 +184,20 @@ static void tda10086_diseqc_wait(struct tda10086_state *state) static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) { struct tda10086_state* state = fe->demodulator_priv; + u8 t22k_off = 0x80; dprintk ("%s\n", __FUNCTION__); + if (state->config->diseqc_tone) + t22k_off = 0; + switch (tone) { case SEC_TONE_OFF: - tda10086_write_byte(state, 0x36, 0x80); + tda10086_write_byte(state, 0x36, t22k_off); break; case SEC_TONE_ON: - tda10086_write_byte(state, 0x36, 0x81); + tda10086_write_byte(state, 0x36, 0x01 + t22k_off); break; } @@ -203,9 +210,13 @@ static int tda10086_send_master_cmd (struct dvb_frontend* fe, struct tda10086_state* state = fe->demodulator_priv; int i; u8 oldval; + u8 t22k_off = 0x80; dprintk ("%s\n", __FUNCTION__); + if (state->config->diseqc_tone) + t22k_off = 0; + if (cmd->msg_len > 6) return -EINVAL; oldval = tda10086_read_byte(state, 0x36); @@ -213,7 +224,8 @@ static int tda10086_send_master_cmd (struct dvb_frontend* fe, for(i=0; i< cmd->msg_len; i++) { tda10086_write_byte(state, 0x48+i, cmd->msg[i]); } - tda10086_write_byte(state, 0x36, 0x88 | ((cmd->msg_len - 1) << 4)); + tda10086_write_byte(state, 0x36, (0x08 + t22k_off) + | ((cmd->msg_len - 1) << 4)); tda10086_diseqc_wait(state); @@ -226,16 +238,20 @@ static int tda10086_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minic { struct tda10086_state* state = fe->demodulator_priv; u8 oldval = tda10086_read_byte(state, 0x36); + u8 t22k_off = 0x80; dprintk ("%s\n", __FUNCTION__); + if (state->config->diseqc_tone) + t22k_off = 0; + switch(minicmd) { case SEC_MINI_A: - tda10086_write_byte(state, 0x36, 0x84); + tda10086_write_byte(state, 0x36, 0x04 + t22k_off); break; case SEC_MINI_B: - tda10086_write_byte(state, 0x36, 0x86); + tda10086_write_byte(state, 0x36, 0x06 + t22k_off); break; } diff --git a/linux/drivers/media/dvb/frontends/tda10086.h b/linux/drivers/media/dvb/frontends/tda10086.h index ed584a8f4..eeceaeee7 100644 --- a/linux/drivers/media/dvb/frontends/tda10086.h +++ b/linux/drivers/media/dvb/frontends/tda10086.h @@ -33,6 +33,9 @@ struct tda10086_config /* does the "inversion" need inverted? */ u8 invert; + + /* do we need the diseqc signal with carrier? */ + u8 diseqc_tone; }; #if defined(CONFIG_DVB_TDA10086) || (defined(CONFIG_DVB_TDA10086_MODULE) && defined(MODULE)) diff --git a/linux/drivers/media/dvb/ttpci/budget.c b/linux/drivers/media/dvb/ttpci/budget.c index 9268a82ba..14b00f57b 100644 --- a/linux/drivers/media/dvb/ttpci/budget.c +++ b/linux/drivers/media/dvb/ttpci/budget.c @@ -351,6 +351,7 @@ static struct s5h1420_config s5h1420_config = { static struct tda10086_config tda10086_config = { .demod_address = 0x0e, .invert = 0, + .diseqc_tone = 1, }; static u8 read_pwm(struct budget* budget) diff --git a/linux/drivers/media/video/saa7134/saa7134-dvb.c b/linux/drivers/media/video/saa7134/saa7134-dvb.c index 02a4f7dbd..9d61d74fa 100644 --- a/linux/drivers/media/video/saa7134/saa7134-dvb.c +++ b/linux/drivers/media/video/saa7134/saa7134-dvb.c @@ -841,6 +841,7 @@ static struct tda1004x_config ads_tech_duo_config = { static struct tda10086_config flydvbs = { .demod_address = 0x0e, .invert = 0, + .diseqc_tone = 0, }; /* ================================================================== @@ -955,9 +956,9 @@ static int dvb_init(struct saa7134_dev *dev) configure_tda827x_fe(dev, &tda827x_lifeview_config); break; case SAA7134_BOARD_FLYDVB_TRIO: - if(! use_frontend) { //terrestrial + if(! use_frontend) { /* terrestrial */ configure_tda827x_fe(dev, &lifeview_trio_config); - } else { //satellite + } else { /* satellite */ dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); if (dev->dvb.frontend) { if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63, -- cgit v1.2.3 From f24dbc55111e61322e06334d7f0bc7f39ebbde0d Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 10 Feb 2008 15:13:25 -0500 Subject: radio-si470x: fix build warning From: Michael Krufky fix the following build warning: radio-si470x.c: In function 'si470x_get_rds_registers': radio-si470x.c:562: warning: format '%ld' expects type 'long int', but argument 3 has type 'unsigned int' Signed-off-by: Michael Krufky --- linux/drivers/media/radio/radio-si470x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index 7be7b0916..fa4feb774 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -559,7 +559,7 @@ static int si470x_get_rds_registers(struct si470x_device *radio) (void *) &buf, sizeof(buf), &size, usb_timeout); if (size != sizeof(buf)) printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_register: " - "return size differs: %d != %ld\n", size, sizeof(buf)); + "return size differs: %d != %uld\n", size, sizeof(buf)); if (retval < 0) printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: " "usb_interrupt_msg returned %d\n", retval); -- cgit v1.2.3 From 3551bb176929327211be22bd960a486ea8499d87 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 10 Feb 2008 19:02:59 -0500 Subject: make hybrid_tuner_request_state tolerant of devices without i2c adapters From: Michael Krufky Some dvb demodulators access the tuner directly without using i2c. In these cases, i2c_adap may be NULL. This patch fixes hybrid_tuner_request_state to allow for NULL i2c_adapters. Signed-off-by: Michael Krufky --- linux/drivers/media/video/tuner-i2c.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tuner-i2c.h b/linux/drivers/media/video/tuner-i2c.h index c53c327a4..60ba79480 100644 --- a/linux/drivers/media/video/tuner-i2c.h +++ b/linux/drivers/media/video/tuner-i2c.h @@ -83,7 +83,8 @@ static inline int tuner_i2c_xfer_send_recv(struct tuner_i2c_props *props, #define tuner_printk(kernlvl, i2cprops, fmt, arg...) do { \ printk(kernlvl "%s %d-%04x: " fmt, i2cprops.name, \ - i2c_adapter_id(i2cprops.adap), \ + i2cprops.adap ? \ + i2c_adapter_id(i2cprops.adap) : -1, \ i2cprops.addr, ##arg); \ } while (0) @@ -128,9 +129,10 @@ static inline int tuner_i2c_xfer_send_recv(struct tuner_i2c_props *props, ({ \ int __ret = 0; \ list_for_each_entry(state, &list, hybrid_tuner_instance_list) { \ - if ((i2c_adapter_id(state->i2c_props.adap) == \ - i2c_adapter_id(i2cadap)) && \ - (state->i2c_props.addr == i2caddr)) { \ + if ((state->i2c_props.addr == i2caddr) && \ + ((state->i2c_props.adap ? \ + i2c_adapter_id(state->i2c_props.adap) : -1) == \ + (i2cadap ? i2c_adapter_id(i2cadap) : -1))) { \ __tuner_info(state->i2c_props, \ "attaching existing instance\n"); \ state->i2c_props.count++; \ -- cgit v1.2.3 From d693688003ff6719bc5d00b8957871ab127461bb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 11 Feb 2008 10:15:22 -0200 Subject: em28xx: Fix undefined symbol error with CONFIG_SND=N From: S.Caglar Onur Following patch fixes following undefined symbol errors with CONFIG_SND=N Signed-off-by: S.Caglar Onur Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/Kconfig b/linux/drivers/media/video/em28xx/Kconfig index abbd38c1e..0f7a0bd86 100644 --- a/linux/drivers/media/video/em28xx/Kconfig +++ b/linux/drivers/media/video/em28xx/Kconfig @@ -13,7 +13,8 @@ config VIDEO_EM28XX module will be called em28xx config VIDEO_EM28XX_ALSA - depends on VIDEO_EM28XX + depends on VIDEO_EM28XX && SND + select SND_PCM tristate "Empia EM28xx ALSA audio module" ---help--- This is an ALSA driver for some Empia 28xx based TV cards. -- cgit v1.2.3 From 756b235475905bd9751677f963bc8486b17b8f42 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 4 Feb 2008 22:26:08 +0000 Subject: radio-si470x version 1.0.6 From: Tobias Lorenz This patch combines all the finished discussions and its resulting patches from the mailing list. The version 1.0.6 is mainly influenced by Oliver Neukum. He found a lot of small issues, that are fixed with this patch now. For me the most interesting thing is, that it's now safer to use it on other architectures. The history for version 1.0.6 is: - fixed coverity checker warnings in *_usb_driver_disconnect - probe()/open() race by correct ordering in probe() - DMA coherency rules by separate allocation of all buffers - use of endianness macros - abuse of spinlock, replaced by mutex - racy handling of timer in disconnect, replaced by delayed_work - racy interruptible_sleep_on(), replaced with wait_event_interruptible() - handle signals in read() The driver is tested with all Debian/testing radio programs and rdsd. The patch is tested against checkpatch.pl v1.12. Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/radio-si470x.c | 330 ++++++++++++++++--------------- 1 file changed, 167 insertions(+), 163 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index fa4feb774..f1f1430f3 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -66,8 +66,21 @@ * Version 1.0.5 * - number of seek_retries changed to tune_timeout * - fixed problem with incomplete tune operations by own buffers - * - optimization of variables + * - optimization of variables and printf types * - improved error logging + * 2008-01-31 Tobias Lorenz + * Oliver Neukum + * Version 1.0.6 + * - fixed coverity checker warnings in *_usb_driver_disconnect + * - probe()/open() race by correct ordering in probe() + * - DMA coherency rules by separate allocation of all buffers + * - use of endianness macros + * - abuse of spinlock, replaced by mutex + * - racy handling of timer in disconnect, + * replaced by delayed_work + * - racy interruptible_sleep_on(), + * replaced with wait_event_interruptible() + * - handle signals in read() * * ToDo: * - add seeking support @@ -80,10 +93,10 @@ /* driver definitions */ #define DRIVER_AUTHOR "Tobias Lorenz " #define DRIVER_NAME "radio-si470x" -#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 5) +#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 6) #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.5" +#define DRIVER_VERSION "1.0.6" /* kernel includes */ @@ -97,8 +110,10 @@ #include #include "compat.h" #include +#include #include #include +#include /* USB Device ID List */ @@ -410,10 +425,9 @@ struct si470x_device { unsigned short registers[RADIO_REGISTER_NUM]; /* RDS receive buffer */ - struct work_struct work; + struct delayed_work work; wait_queue_head_t read_queue; - struct timer_list timer; - spinlock_t lock; /* buffer locking */ + struct mutex lock; /* buffer locking */ unsigned char *buffer; /* size is always multiple of three */ unsigned int buf_size; unsigned int rd_index; @@ -495,7 +509,8 @@ static int si470x_get_register(struct si470x_device *radio, int regnr) retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); if (retval >= 0) - radio->registers[regnr] = (buf[1] << 8) | buf[2]; + radio->registers[regnr] = be16_to_cpu(get_unaligned( + (unsigned short *) &buf[1])); return (retval < 0) ? -EINVAL : 0; } @@ -510,8 +525,8 @@ static int si470x_set_register(struct si470x_device *radio, int regnr) int retval; buf[0] = REGISTER_REPORT(regnr); - buf[1] = (radio->registers[regnr] & 0xff00) >> 8; - buf[2] = (radio->registers[regnr] & 0x00ff); + put_unaligned(cpu_to_be16(radio->registers[regnr]), + (unsigned short *) &buf[1]); retval = si470x_set_report(radio, (void *) &buf, sizeof(buf)); @@ -534,9 +549,9 @@ static int si470x_get_all_registers(struct si470x_device *radio) if (retval >= 0) for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++) - radio->registers[regnr] = - (buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) | - buf[regnr * RADIO_REGISTER_SIZE + 2]; + radio->registers[regnr] = be16_to_cpu(get_unaligned( + (unsigned short *) + &buf[regnr * RADIO_REGISTER_SIZE + 1])); return (retval < 0) ? -EINVAL : 0; } @@ -559,7 +574,7 @@ static int si470x_get_rds_registers(struct si470x_device *radio) (void *) &buf, sizeof(buf), &size, usb_timeout); if (size != sizeof(buf)) printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_register: " - "return size differs: %d != %uld\n", size, sizeof(buf)); + "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); @@ -567,8 +582,8 @@ static int si470x_get_rds_registers(struct si470x_device *radio) if (retval >= 0) for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) radio->registers[STATUSRSSI + regnr] = - (buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) | - buf[regnr * RADIO_REGISTER_SIZE + 2]; + be16_to_cpu(get_unaligned((unsigned short *) + &buf[regnr * RADIO_REGISTER_SIZE + 1])); return (retval < 0) ? -EINVAL : 0; } @@ -601,7 +616,7 @@ static int si470x_set_chan(struct si470x_device *radio, unsigned short chan) (!timed_out)); if (timed_out) printk(KERN_WARNING DRIVER_NAME - ": seek does not finish after %d ms\n", tune_timeout); + ": seek does not finish after %u ms\n", tune_timeout); /* stop tuning */ radio->registers[CHANNEL] &= ~CHANNEL_TUNE; @@ -764,6 +779,11 @@ static int si470x_rds_on(struct si470x_device *radio) */ static void si470x_rds(struct si470x_device *radio) { + unsigned char blocknum; + unsigned short bler; /* rds block errors */ + unsigned short rds; + unsigned char tmpbuf[3]; + /* get rds blocks */ if (si470x_get_rds_registers(radio) < 0) return; @@ -776,69 +796,58 @@ static void si470x_rds(struct si470x_device *radio) return; } - /* copy four RDS blocks to internal buffer */ - if (spin_trylock(&radio->lock)) { - unsigned char blocknum; - unsigned short bler; /* rds block errors */ - unsigned short rds; - unsigned char tmpbuf[3]; - unsigned char i; - - /* process each rds block */ - for (blocknum = 0; blocknum < 4; blocknum++) { - switch (blocknum) { - default: - bler = (radio->registers[STATUSRSSI] & - STATUSRSSI_BLERA) >> 9; - rds = radio->registers[RDSA]; - break; - case 1: - bler = (radio->registers[READCHAN] & - READCHAN_BLERB) >> 14; - rds = radio->registers[RDSB]; - break; - case 2: - bler = (radio->registers[READCHAN] & - READCHAN_BLERC) >> 12; - rds = radio->registers[RDSC]; - break; - case 3: - bler = (radio->registers[READCHAN] & - READCHAN_BLERD) >> 10; - rds = radio->registers[RDSD]; - break; - }; - - /* Fill the V4L2 RDS buffer */ - tmpbuf[0] = rds & 0x00ff; /* LSB */ - tmpbuf[1] = (rds & 0xff00) >> 8;/* MSB */ - tmpbuf[2] = blocknum; /* offset name */ - tmpbuf[2] |= blocknum << 3; /* received offset */ - if (bler > max_rds_errors) - tmpbuf[2] |= 0x80; /* uncorrectable errors */ - else if (bler > 0) - tmpbuf[2] |= 0x40; /* corrected error(s) */ - - /* copy RDS block to internal buffer */ - for (i = 0; i < 3; i++) { - radio->buffer[radio->wr_index] = tmpbuf[i]; - radio->wr_index++; - } - - /* wrap write pointer */ - if (radio->wr_index >= radio->buf_size) - radio->wr_index = 0; - - /* check for overflow */ - if (radio->wr_index == radio->rd_index) { - /* increment and wrap read pointer */ - radio->rd_index += 3; - if (radio->rd_index >= radio->buf_size) - radio->rd_index = 0; - } + /* copy all four RDS blocks to internal buffer */ + mutex_lock(&radio->lock); + for (blocknum = 0; blocknum < 4; blocknum++) { + switch (blocknum) { + default: + bler = (radio->registers[STATUSRSSI] & + STATUSRSSI_BLERA) >> 9; + rds = radio->registers[RDSA]; + break; + case 1: + bler = (radio->registers[READCHAN] & + READCHAN_BLERB) >> 14; + rds = radio->registers[RDSB]; + break; + case 2: + bler = (radio->registers[READCHAN] & + READCHAN_BLERC) >> 12; + rds = radio->registers[RDSC]; + break; + case 3: + bler = (radio->registers[READCHAN] & + READCHAN_BLERD) >> 10; + rds = radio->registers[RDSD]; + break; + }; + + /* Fill the V4L2 RDS buffer */ + put_unaligned(cpu_to_le16(rds), (unsigned short *) &tmpbuf); + tmpbuf[2] = blocknum; /* offset name */ + tmpbuf[2] |= blocknum << 3; /* received offset */ + if (bler > max_rds_errors) + tmpbuf[2] |= 0x80; /* uncorrectable errors */ + else if (bler > 0) + tmpbuf[2] |= 0x40; /* corrected error(s) */ + + /* copy RDS block to internal buffer */ + memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3); + radio->wr_index += 3; + + /* wrap write pointer */ + if (radio->wr_index >= radio->buf_size) + radio->wr_index = 0; + + /* check for overflow */ + if (radio->wr_index == radio->rd_index) { + /* increment and wrap read pointer */ + radio->rd_index += 3; + if (radio->rd_index >= radio->buf_size) + radio->rd_index = 0; } - spin_unlock(&radio->lock); } + mutex_unlock(&radio->lock); /* wake up read queue */ if (radio->wr_index != radio->rd_index) @@ -846,30 +855,19 @@ static void si470x_rds(struct si470x_device *radio) } -/* - * si470x_timer - rds timer function - */ -static void si470x_timer(unsigned long data) -{ - struct si470x_device *radio = (struct si470x_device *) data; - - schedule_work(&radio->work); -} - - /* * si470x_work - rds work function */ static void si470x_work(struct work_struct *work) { struct si470x_device *radio = container_of(work, struct si470x_device, - work); + work.work); if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) return; si470x_rds(radio); - mod_timer(&radio->timer, jiffies + msecs_to_jiffies(rds_poll_time)); + schedule_delayed_work(&radio->work, msecs_to_jiffies(rds_poll_time)); } @@ -886,49 +884,49 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf, { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval = 0; + unsigned int block_count = 0; /* switch on rds reception */ if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) { si470x_rds_on(radio); - schedule_work(&radio->work); + schedule_delayed_work(&radio->work, + msecs_to_jiffies(rds_poll_time)); } /* block if no new data available */ while (radio->wr_index == radio->rd_index) { if (file->f_flags & O_NONBLOCK) return -EWOULDBLOCK; - interruptible_sleep_on(&radio->read_queue); + if (wait_event_interruptible(radio->read_queue, + radio->wr_index != radio->rd_index) < 0) + return -EINTR; } /* calculate block count from byte count */ count /= 3; /* copy RDS block out of internal buffer and to user buffer */ - if (spin_trylock(&radio->lock)) { - unsigned int block_count = 0; - while (block_count < count) { - if (radio->rd_index == radio->wr_index) - break; - - /* always transfer rds complete blocks */ - if (copy_to_user(buf, - &radio->buffer[radio->rd_index], 3)) - /* retval = -EFAULT; */ - break; + mutex_lock(&radio->lock); + while (block_count < count) { + if (radio->rd_index == radio->wr_index) + break; - /* increment and wrap read pointer */ - radio->rd_index += 3; - if (radio->rd_index >= radio->buf_size) - radio->rd_index = 0; + /* always transfer rds complete blocks */ + if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3)) + /* retval = -EFAULT; */ + break; - /* increment counters */ - block_count++; - buf += 3; - retval += 3; - } + /* increment and wrap read pointer */ + radio->rd_index += 3; + if (radio->rd_index >= radio->buf_size) + radio->rd_index = 0; - spin_unlock(&radio->lock); + /* increment counters */ + block_count++; + buf += 3; + retval += 3; } + mutex_unlock(&radio->lock); return retval; } @@ -945,7 +943,8 @@ static unsigned int si470x_fops_poll(struct file *file, /* switch on rds reception */ if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) { si470x_rds_on(radio); - schedule_work(&radio->work); + schedule_delayed_work(&radio->work, + msecs_to_jiffies(rds_poll_time)); } poll_wait(file, &radio->read_queue, pts); @@ -985,8 +984,7 @@ static int si470x_fops_release(struct inode *inode, struct file *file) radio->users--; if (radio->users == 0) { /* stop rds reception */ - del_timer_sync(&radio->timer); - flush_scheduled_work(); + cancel_delayed_work_sync(&radio->work); /* cancel read processes */ wake_up_interruptible(&radio->read_queue); @@ -1363,73 +1361,82 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct si470x_device *radio; + int retval = -ENOMEM; - /* memory and interface allocations */ - radio = kmalloc(sizeof(struct si470x_device), GFP_KERNEL); + /* private data allocation */ + radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL); if (!radio) - return -ENOMEM; + goto err_initial; + + /* video device allocation */ radio->videodev = video_device_alloc(); - if (!radio->videodev) { - kfree(radio); - return -ENOMEM; - } + if (!radio->videodev) + goto err_radio; + + /* initial configuration */ memcpy(radio->videodev, &si470x_viddev_template, sizeof(si470x_viddev_template)); radio->users = 0; radio->usbdev = interface_to_usbdev(intf); + mutex_init(&radio->lock); video_set_drvdata(radio->videodev, radio); - if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) { - printk(KERN_WARNING DRIVER_NAME - ": Could not register video device\n"); - video_device_release(radio->videodev); - kfree(radio); - return -EIO; - } - usb_set_intfdata(intf, radio); /* show some infos about the specific device */ - if (si470x_get_all_registers(radio) < 0) { - video_device_release(radio->videodev); - kfree(radio); - return -EIO; - } - printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4x ChipID=0x%4.4x\n", + retval = -EIO; + if (si470x_get_all_registers(radio) < 0) + goto err_all; + 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 */ if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) - < RADIO_SW_VERSION_CURRENT) + < RADIO_SW_VERSION_CURRENT) { + printk(KERN_WARNING DRIVER_NAME + ": This driver is known to work with " + "firmware version %hu,\n", RADIO_SW_VERSION_CURRENT); + printk(KERN_WARNING DRIVER_NAME + ": but the device has firmware version %hu.\n", + radio->registers[CHIPID] & CHIPID_FIRMWARE); + printk(KERN_WARNING DRIVER_NAME + ": If you have some trouble using this driver,\n"); printk(KERN_WARNING DRIVER_NAME - ": This driver is known to work with chip version %d, " - "but the device has firmware %d.\n" - DRIVER_NAME - "If you have some trouble using this driver, please " - "report to V4L ML at video4linux-list@redhat.com\n", - radio->registers[CHIPID] & CHIPID_FIRMWARE, - RADIO_SW_VERSION_CURRENT); + ": please report to V4L ML at " + "video4linux-list@redhat.com\n"); + } /* set initial frequency */ si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */ - /* rds initialization */ + /* rds buffer allocation */ radio->buf_size = rds_buf * 3; radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); - if (!radio->buffer) { - video_device_release(radio->videodev); - kfree(radio); - return -ENOMEM; - } + if (!radio->buffer) + goto err_all; + + /* rds buffer configuration */ radio->wr_index = 0; radio->rd_index = 0; init_waitqueue_head(&radio->read_queue); - /* prepare polling via eventd */ - INIT_WORK(&radio->work, si470x_work); - init_timer(&radio->timer); - radio->timer.function = si470x_timer; - radio->timer.data = (unsigned long) radio; + /* prepare rds work function */ + INIT_DELAYED_WORK(&radio->work, si470x_work); + + /* register video device */ + if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) { + printk(KERN_WARNING DRIVER_NAME + ": Could not register video device\n"); + goto err_all; + } + usb_set_intfdata(intf, radio); return 0; +err_all: + video_device_release(radio->videodev); + kfree(radio->buffer); +err_radio: + kfree(radio); +err_initial: + return retval; } @@ -1440,14 +1447,11 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf) { struct si470x_device *radio = usb_get_intfdata(intf); + cancel_delayed_work_sync(&radio->work); usb_set_intfdata(intf, NULL); - if (radio) { - del_timer_sync(&radio->timer); - flush_scheduled_work(); - video_unregister_device(radio->videodev); - kfree(radio->buffer); - kfree(radio); - } + video_unregister_device(radio->videodev); + kfree(radio->buffer); + kfree(radio); } -- cgit v1.2.3 From 6258413a9bbb8ef25d4846ae2e58ef69f091c93d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 10:26:24 -0200 Subject: revert changeset 7141 From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/Kconfig | 9 --------- linux/include/linux/videodev2.h | 5 +---- 2 files changed, 1 insertion(+), 13 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index c0498ac98..37072a21d 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -836,13 +836,4 @@ config USB_STKWEBCAM endif # V4L_USB_DRIVERS -config SOC_CAMERA - tristate "SoC camera support" - depends on VIDEO_V4L2 - select VIDEOBUF_DMA_SG - help - SoC Camera is a common API to several cameras, not connecting - over a bus like PCI or USB. For example some i2c camera connected - directly to the data bus of an SoC. - endif # VIDEO_CAPTURE_DRIVERS diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index 55bec7416..736600002 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -281,7 +281,6 @@ struct v4l2_pix_format #define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B','G','R','4') /* 32 BGR-8-8-8-8 */ #define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R','G','B','4') /* 32 RGB-8-8-8-8 */ #define V4L2_PIX_FMT_GREY v4l2_fourcc('G','R','E','Y') /* 8 Greyscale */ -#define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y','1','6',' ') /* 16 Greyscale */ #define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P','A','L','8') /* 8 8-bit palette */ #define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y','V','U','9') /* 9 YVU 4:1:0 */ #define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y','V','1','2') /* 12 YVU 4:2:0 */ @@ -308,7 +307,6 @@ struct v4l2_pix_format /* see http://www.siliconimaging.com/RGB%20Bayer.htm */ #define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B','A','8','1') /* 8 BGBG.. GRGR.. */ -#define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B','Y','R','2') /* 16 BGBG.. GRGR.. */ /* compressed formats */ #define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M','J','P','G') /* Motion-JPEG */ @@ -864,8 +862,7 @@ struct v4l2_querymenu #define V4L2_CID_VFLIP (V4L2_CID_BASE+21) #define V4L2_CID_HCENTER (V4L2_CID_BASE+22) #define V4L2_CID_VCENTER (V4L2_CID_BASE+23) -#define V4L2_CID_AUTOEXPOSURE (V4L2_CID_BASE+24) -#define V4L2_CID_LASTP1 (V4L2_CID_BASE+25) /* last CID + 1 */ +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+24) /* last CID + 1 */ /* MPEG-class control IDs defined by V4L2 */ #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) -- cgit v1.2.3 From 56eb8c85473f48c34f74e3591b956e3c63957262 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 10:29:31 -0200 Subject: backport kernel commit 9004acc70e8c49c50c4c7b652f906f1e0ed5709d From: Mauro Carvalho Chehab Original patch comments: Author: Takashi Iwai Date: Tue Jan 8 18:13:27 2008 +0100 [ALSA] Remove sound/driver.h This header file exists only for some hacks to adapt alsa-driver tree. It's useless for building in the kernel. Let's move a few lines in it to sound/core.h and remove it. With this patch, sound/driver.h isn't removed but has just a single compile warning to include it. This should be really killed in future. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/cx88/cx88-alsa.c | 1 - linux/drivers/media/video/saa7134/saa7134-alsa.c | 1 - linux/drivers/media/video/saa7134/saa7134.h | 1 - linux/sound/i2c/other/tea575x-tuner.c | 1 - linux/sound/pci/bt87x.c | 1 - 5 files changed, 5 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx88/cx88-alsa.c b/linux/drivers/media/video/cx88/cx88-alsa.c index f5d65f675..ae69ba065 100644 --- a/linux/drivers/media/video/cx88/cx88-alsa.c +++ b/linux/drivers/media/video/cx88/cx88-alsa.c @@ -33,7 +33,6 @@ #include #include -#include #include #include #include diff --git a/linux/drivers/media/video/saa7134/saa7134-alsa.c b/linux/drivers/media/video/saa7134/saa7134-alsa.c index 49ff12d08..d9660becc 100644 --- a/linux/drivers/media/video/saa7134/saa7134-alsa.c +++ b/linux/drivers/media/video/saa7134/saa7134-alsa.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h index 29d71cbac..b7464c706 100644 --- a/linux/drivers/media/video/saa7134/saa7134.h +++ b/linux/drivers/media/video/saa7134/saa7134.h @@ -44,7 +44,6 @@ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,64) #include "i2c-compat.h" #else -#include #include #include #endif diff --git a/linux/sound/i2c/other/tea575x-tuner.c b/linux/sound/i2c/other/tea575x-tuner.c index 52d190597..4c100300c 100644 --- a/linux/sound/i2c/other/tea575x-tuner.c +++ b/linux/sound/i2c/other/tea575x-tuner.c @@ -20,7 +20,6 @@ * */ -#include #include #include #include diff --git a/linux/sound/pci/bt87x.c b/linux/sound/pci/bt87x.c index 86c922635..3e820f75c 100644 --- a/linux/sound/pci/bt87x.c +++ b/linux/sound/pci/bt87x.c @@ -21,7 +21,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include #include #include #include -- cgit v1.2.3 From 615ceed14a9faf54d4d8a70d978da0d4c355cbfa Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 09:34:31 -0200 Subject: backport kernel commit c84e6036ba7177a404cc860cb5a440e06fad92dd From: Mauro Carvalho Chehab Original changelog: Author: Joe Perches Date: Sun Feb 3 17:18:59 2008 +0200 drivers/media/: Spelling fixes kernel-sync: Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/saa7146_core.c | 2 +- linux/drivers/media/dvb/dvb-core/dvb_net.c | 2 +- linux/drivers/media/video/bt8xx/bttv-cards.c | 2 +- linux/drivers/media/video/indycam.c | 2 +- linux/drivers/media/video/mt20xx.c | 2 +- linux/drivers/media/video/pvrusb2/pvrusb2.h | 2 +- linux/drivers/media/video/tea6420.c | 2 +- linux/drivers/media/video/usbvideo/quickcam_messenger.c | 2 +- linux/drivers/media/video/usbvision/usbvision-video.c | 2 +- linux/drivers/media/video/vpx3220.c | 2 +- linux/drivers/media/video/zoran_card.c | 2 +- linux/drivers/media/video/zr36050.c | 2 +- linux/drivers/media/video/zr36060.c | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/common/saa7146_core.c b/linux/drivers/media/common/saa7146_core.c index 7fb263dc1..c36634248 100644 --- a/linux/drivers/media/common/saa7146_core.c +++ b/linux/drivers/media/common/saa7146_core.c @@ -392,7 +392,7 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent } dev->revision &= 0xf; - /* remap the memory from virtual to physical adress */ + /* remap the memory from virtual to physical address */ err = pci_request_region(pci, 0, "saa7146"); if (err < 0) diff --git a/linux/drivers/media/dvb/dvb-core/dvb_net.c b/linux/drivers/media/dvb/dvb-core/dvb_net.c index e2eae4ca7..627096688 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_net.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_net.c @@ -703,7 +703,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) drop = 1; /* else: destination address matches the MAC address of our receiver device */ } - /* else: promiscious mode; pass everything up the stack */ + /* else: promiscuous mode; pass everything up the stack */ if (drop) { #ifdef ULE_DEBUG diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c index 98270aaaf..00be77d4f 100644 --- a/linux/drivers/media/video/bt8xx/bttv-cards.c +++ b/linux/drivers/media/video/bt8xx/bttv-cards.c @@ -4445,7 +4445,7 @@ static void rv605_muxsel(struct bttv *btv, unsigned int input) gpio_bits(0x200,0x000); mdelay(1); - /* create a new conection */ + /* create a new connection */ gpio_bits(0x480,0x080); gpio_bits(0x480,0x480); mdelay(1); diff --git a/linux/drivers/media/video/indycam.c b/linux/drivers/media/video/indycam.c index 5c2c4029f..84b9e4f2b 100644 --- a/linux/drivers/media/video/indycam.c +++ b/linux/drivers/media/video/indycam.c @@ -326,7 +326,7 @@ static int indycam_attach(struct i2c_adapter *adap, int addr, int kind) // initialize err = indycam_write_block(client, 0, sizeof(initseq), (u8 *)&initseq); if (err) { - printk(KERN_ERR "IndyCam initalization failed\n"); + printk(KERN_ERR "IndyCam initialization failed\n"); err = -EIO; goto out_detach_client; } diff --git a/linux/drivers/media/video/mt20xx.c b/linux/drivers/media/video/mt20xx.c index cdf7450b5..5a8a53d8a 100644 --- a/linux/drivers/media/video/mt20xx.c +++ b/linux/drivers/media/video/mt20xx.c @@ -379,7 +379,7 @@ static struct dvb_tuner_ops mt2032_tuner_ops = { .get_frequency = microtune_get_frequency, }; -// Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001 +// Initialization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001 static int mt2032_init(struct dvb_frontend *fe) { struct microtune_priv *priv = fe->tuner_priv; diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2.h b/linux/drivers/media/video/pvrusb2/pvrusb2.h index 074533e9c..1a9a4baf1 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2.h @@ -27,7 +27,7 @@ might want to increase this - however the driver operation will not be impaired if it is too small. Instead additional units just won't have an ID assigned and it might not be possible to specify - module paramters for those extra units. */ + module parameters for those extra units. */ #define PVR_NUM 20 #endif /* __PVRUSB2_H */ diff --git a/linux/drivers/media/video/tea6420.c b/linux/drivers/media/video/tea6420.c index 916794e60..261675012 100644 --- a/linux/drivers/media/video/tea6420.c +++ b/linux/drivers/media/video/tea6420.c @@ -66,7 +66,7 @@ static int tea6420_switch(struct i2c_client *client, int i, int o, int g) dprintk("adr:0x%02x, i:%d, o:%d, g:%d\n", client->addr, i, o, g); - /* check if the paramters are valid */ + /* check if the parameters are valid */ if (i < 1 || i > 6 || o < 1 || o > 4 || g < 0 || g > 6 || g % 2 != 0) return -1; diff --git a/linux/drivers/media/video/usbvideo/quickcam_messenger.c b/linux/drivers/media/video/usbvideo/quickcam_messenger.c index e2af2d132..4b4e4d9f2 100644 --- a/linux/drivers/media/video/usbvideo/quickcam_messenger.c +++ b/linux/drivers/media/video/usbvideo/quickcam_messenger.c @@ -275,7 +275,7 @@ static void qcm_hsv2rgb(u16 hue, u16 sat, u16 val, u16 *r, u16 *g, u16 *b) unsigned int p; /* - the registers controling gain are 8 bit of which + the registers controlling gain are 8 bit of which we affect only the last 4 bits with our gain. we know that if saturation is 0, (unsaturated) then we're grayscale (center axis of the colour cone) so diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c index 5dc67e90d..e64547d12 100644 --- a/linux/drivers/media/video/usbvision/usbvision-video.c +++ b/linux/drivers/media/video/usbvision/usbvision-video.c @@ -137,7 +137,7 @@ static struct usbvision_v4l2_format_st usbvision_v4l2_format[] = { /* Function prototypes */ static void usbvision_release(struct usb_usbvision *usbvision); -/* Default initalization of device driver parameters */ +/* Default initialization of device driver parameters */ /* Set the default format for ISOC endpoint */ static int isocMode = ISOC_MODE_COMPRESS; /* Set the default Debug Mode of the device driver */ diff --git a/linux/drivers/media/video/vpx3220.c b/linux/drivers/media/video/vpx3220.c index 8a2dca0bb..989166eec 100644 --- a/linux/drivers/media/video/vpx3220.c +++ b/linux/drivers/media/video/vpx3220.c @@ -567,7 +567,7 @@ vpx3220_init_client (struct i2c_client *client) } /* ----------------------------------------------------------------------- - * Client managment code + * Client management code */ /* diff --git a/linux/drivers/media/video/zoran_card.c b/linux/drivers/media/video/zoran_card.c index 1ad4ebaef..946dee4eb 100644 --- a/linux/drivers/media/video/zoran_card.c +++ b/linux/drivers/media/video/zoran_card.c @@ -1273,7 +1273,7 @@ zoran_setup_videocodec (struct zoran *zr, } /* - * Scan for a Buz card (actually for the PCI contoler ZR36057), + * Scan for a Buz card (actually for the PCI controller ZR36057), * request the irq and map the io memory */ static int __devinit diff --git a/linux/drivers/media/video/zr36050.c b/linux/drivers/media/video/zr36050.c index 44e68d7a8..cf8b271a1 100644 --- a/linux/drivers/media/video/zr36050.c +++ b/linux/drivers/media/video/zr36050.c @@ -160,7 +160,7 @@ zr36050_wait_end (struct zr36050 *ptr) udelay(1); if (i++ > 200000) { // 200ms, there is for sure something wrong!!! dprintk(1, - "%s: timout at wait_end (last status: 0x%02x)\n", + "%s: timeout at wait_end (last status: 0x%02x)\n", ptr->name, ptr->status1); break; } diff --git a/linux/drivers/media/video/zr36060.c b/linux/drivers/media/video/zr36060.c index 940055191..8e74054d5 100644 --- a/linux/drivers/media/video/zr36060.c +++ b/linux/drivers/media/video/zr36060.c @@ -163,7 +163,7 @@ zr36060_wait_end (struct zr36060 *ptr) udelay(1); if (i++ > 200000) { // 200ms, there is for sure something wrong!!! dprintk(1, - "%s: timout at wait_end (last status: 0x%02x)\n", + "%s: timeout at wait_end (last status: 0x%02x)\n", ptr->name, ptr->status); break; } -- cgit v1.2.3 From 2806626f1cd30e7ba3109dfdd19d9999e75e62af Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 09:41:05 -0200 Subject: backport kernel commit e48d33193d94175f012c3ed606a1d1e574ed726a From: Mauro Carvalho Chehab Original changelog: Author: Jean Delvare Date: Sun Jan 27 18:14:48 2008 +0100 i2c: Change prototypes of refcounting functions Use more standard prototypes for i2c_use_client() and i2c_release_client(). The former now returns a pointer to the client, and the latter no longer returns anything. This matches what all other subsystems do. kernel-sync: Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/vino.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/vino.c b/linux/drivers/media/video/vino.c index 776edf222..01a4b9d3e 100644 --- a/linux/drivers/media/video/vino.c +++ b/linux/drivers/media/video/vino.c @@ -2593,11 +2593,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs) /* First try D1 and then SAA7191 */ if (vino_drvdata->camera.driver && (vino_drvdata->camera.owner == VINO_NO_CHANNEL)) { - if (i2c_use_client(vino_drvdata->camera.driver)) { - ret = -ENODEV; - goto out; - } - + i2c_use_client(vino_drvdata->camera.driver); vino_drvdata->camera.owner = vcs->channel; vcs->input = VINO_INPUT_D1; vcs->data_norm = VINO_DATA_NORM_D1; @@ -2606,11 +2602,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs) int input, data_norm; int saa7191_input; - if (i2c_use_client(vino_drvdata->decoder.driver)) { - ret = -ENODEV; - goto out; - } - + i2c_use_client(vino_drvdata->decoder.driver); input = VINO_INPUT_COMPOSITE; saa7191_input = vino_get_saa7191_input(input); @@ -2692,10 +2684,7 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input) } if (vino_drvdata->decoder.owner == VINO_NO_CHANNEL) { - if (i2c_use_client(vino_drvdata->decoder.driver)) { - ret = -ENODEV; - goto out; - } + i2c_use_client(vino_drvdata->decoder.driver); vino_drvdata->decoder.owner = vcs->channel; } @@ -2763,10 +2752,7 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input) } if (vino_drvdata->camera.owner == VINO_NO_CHANNEL) { - if (i2c_use_client(vino_drvdata->camera.driver)) { - ret = -ENODEV; - goto out; - } + i2c_use_client(vino_drvdata->camera.driver); vino_drvdata->camera.owner = vcs->channel; } -- cgit v1.2.3 From 82f5d43d8ee488c6e20a99d71b2e666a72e9e8f9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 09:43:02 -0200 Subject: backport Kernel commit 961f80f9c0c0f7c45d7818f9c9969dfaa9e4463d From: Mauro Carvalho Chehab Original Changelog: Author: Jean Delvare Date: Sun Jan 27 18:14:51 2008 +0100 i2c: Drivers stop using the redundant client list The redundant i2c client list maintained by i2c-core is going away soon, so drivers should stop using it now. Instead, they can use the standard iterator provided by the device driver model (device_for_each_child). Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/dpc7146.c | 19 ++++++++++++++---- linux/drivers/media/video/mxb.c | 40 +++++++++++++++++++++++-------------- 2 files changed, 40 insertions(+), 19 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/dpc7146.c b/linux/drivers/media/video/dpc7146.c index 9ac8e8682..258d46407 100644 --- a/linux/drivers/media/video/dpc7146.c +++ b/linux/drivers/media/video/dpc7146.c @@ -88,11 +88,24 @@ struct dpc int cur_input; /* current input */ }; +static int dpc_check_clients(struct device *dev, void *data) +{ + struct dpc* dpc = data; + struct i2c_client *client = i2c_verify_client(dev); + + if( !client ) + return 0; + + if( I2C_SAA7111A == client->addr ) + dpc->saa7111a = client; + + return 0; +} + /* fixme: add vbi stuff here */ static int dpc_probe(struct saa7146_dev* dev) { struct dpc* dpc = NULL; - struct i2c_client *client; dpc = kzalloc(sizeof(struct dpc), GFP_KERNEL); if( NULL == dpc ) { @@ -116,9 +129,7 @@ static int dpc_probe(struct saa7146_dev* dev) } /* loop through all i2c-devices on the bus and look who is there */ - list_for_each_entry(client, &dpc->i2c_adapter.clients, list) - if( I2C_SAA7111A == client->addr ) - dpc->saa7111a = client; + device_for_each_child(&dpc->i2c_adapter.dev, dpc, dpc_check_clients); /* check if all devices are present */ if( 0 == dpc->saa7111a ) { diff --git a/linux/drivers/media/video/mxb.c b/linux/drivers/media/video/mxb.c index 354ecaf8d..97cc92c82 100644 --- a/linux/drivers/media/video/mxb.c +++ b/linux/drivers/media/video/mxb.c @@ -150,10 +150,33 @@ struct mxb 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; + + return 0; +} + static int mxb_probe(struct saa7146_dev* dev) { struct mxb* mxb = NULL; - struct i2c_client *client; int result; if ((result = request_module("saa7111")) < 0) { @@ -196,20 +219,7 @@ static int mxb_probe(struct saa7146_dev* dev) } /* loop through all i2c-devices on the bus and look who is there */ - list_for_each_entry(client, &mxb->i2c_adapter.clients, list) { - 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; - } + device_for_each_child(&mxb->i2c_adapter.dev, mxb, mxb_check_clients); /* check if all devices are present */ if( 0 == mxb->tea6420_1 || 0 == mxb->tea6420_2 || 0 == mxb->tea6415c -- cgit v1.2.3 From c39fbb761698258a2a8e707db7373f41f5a54051 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 09:51:59 -0200 Subject: Synchronize with kernel From: Mauro Carvalho Chehab kernel-sync: Signed-off-by: Mauro Carvalho Chehab --- linux/include/linux/i2c-id.h | 67 +++----------------------------------------- 1 file changed, 4 insertions(+), 63 deletions(-) (limited to 'linux') diff --git a/linux/include/linux/i2c-id.h b/linux/include/linux/i2c-id.h index bbd13a764..f922b0601 100644 --- a/linux/include/linux/i2c-id.h +++ b/linux/include/linux/i2c-id.h @@ -23,29 +23,23 @@ #ifndef LINUX_I2C_ID_H #define LINUX_I2C_ID_H +/* Please note that I2C driver IDs are optional. They are only needed if a + legacy chip driver needs to identify a bus or a bus driver needs to + identify a legacy client. If you don't need them, just don't set them. */ + /* * ---- Driver types ----------------------------------------------------- */ #define I2C_DRIVERID_MSP3400 1 #define I2C_DRIVERID_TUNER 2 -#define I2C_DRIVERID_VIDEOTEX 3 /* please rename */ #define I2C_DRIVERID_TDA8425 4 /* stereo sound processor */ #define I2C_DRIVERID_TEA6420 5 /* audio matrix switch */ #define I2C_DRIVERID_TEA6415C 6 /* video matrix switch */ #define I2C_DRIVERID_TDA9840 7 /* stereo sound processor */ #define I2C_DRIVERID_SAA7111A 8 /* video input processor */ -#define I2C_DRIVERID_SAA5281 9 /* videotext decoder */ -#define I2C_DRIVERID_SAA7112 10 /* video decoder, image scaler */ -#define I2C_DRIVERID_SAA7120 11 /* video encoder */ -#define I2C_DRIVERID_SAA7121 12 /* video encoder */ #define I2C_DRIVERID_SAA7185B 13 /* video encoder */ -#define I2C_DRIVERID_CH7003 14 /* digital pc to tv encoder */ -#define I2C_DRIVERID_PCF8574A 15 /* i2c expander - 8 bit in/out */ -#define I2C_DRIVERID_PCF8582C 16 /* eeprom */ -#define I2C_DRIVERID_AT24Cxx 17 /* eeprom 1/2/4/8/16 K */ #define I2C_DRIVERID_TEA6300 18 /* audio mixer */ -#define I2C_DRIVERID_BT829 19 /* pc to tv encoder */ #define I2C_DRIVERID_TDA9850 20 /* audio mixer */ #define I2C_DRIVERID_TDA9855 21 /* audio mixer */ #define I2C_DRIVERID_SAA7110 22 /* video decoder */ @@ -56,42 +50,19 @@ #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_DPL3518 30 /* Dolby decoder chip */ #define I2C_DRIVERID_TDA9873 31 /* TV sound decoder chip */ #define I2C_DRIVERID_TDA9875 32 /* TV sound decoder chip */ #define I2C_DRIVERID_PIC16C54_PV9 33 /* Audio mux/ir receiver */ - -#define I2C_DRIVERID_SBATT 34 /* Smart Battery Device */ -#define I2C_DRIVERID_SBS 35 /* SB System Manager */ -#define I2C_DRIVERID_VES1893 36 /* VLSI DVB-S decoder */ -#define I2C_DRIVERID_VES1820 37 /* VLSI DVB-C decoder */ -#define I2C_DRIVERID_SAA7113 38 /* video decoder */ -#define I2C_DRIVERID_TDA8444 39 /* octuple 6-bit DAC */ #define I2C_DRIVERID_BT819 40 /* video decoder */ #define I2C_DRIVERID_BT856 41 /* video encoder */ #define I2C_DRIVERID_VPX3220 42 /* video decoder+vbi/vtxt */ -#define I2C_DRIVERID_DRP3510 43 /* ADR decoder (Astra Radio) */ -#define I2C_DRIVERID_SP5055 44 /* Satellite tuner */ -#define I2C_DRIVERID_STV0030 45 /* Multipurpose switch */ -#define I2C_DRIVERID_SAA7108 46 /* video decoder, image scaler */ -#define I2C_DRIVERID_DS1307 47 /* DS1307 real time clock */ #define I2C_DRIVERID_ADV7175 48 /* ADV 7175/7176 video encoder */ #define I2C_DRIVERID_SAA7114 49 /* video decoder */ -#define I2C_DRIVERID_ZR36120 50 /* Zoran 36120 video encoder */ -#define I2C_DRIVERID_24LC32A 51 /* Microchip 24LC32A 32k EEPROM */ -#define I2C_DRIVERID_STM41T00 52 /* real time clock */ -#define I2C_DRIVERID_UDA1342 53 /* UDA1342 audio codec */ #define I2C_DRIVERID_ADV7170 54 /* video encoder */ -#define I2C_DRIVERID_MAX1617 56 /* temp sensor */ #define I2C_DRIVERID_SAA7191 57 /* video decoder */ #define I2C_DRIVERID_INDYCAM 58 /* SGI IndyCam */ -#define I2C_DRIVERID_BT832 59 /* CMOS camera video processor */ -#define I2C_DRIVERID_TDA9887 60 /* TDA988x IF-PLL demodulator */ #define I2C_DRIVERID_OVCAMCHIP 61 /* OmniVision CMOS image sens. */ -#define I2C_DRIVERID_TDA7313 62 /* TDA7313 audio processor */ #define I2C_DRIVERID_MAX6900 63 /* MAX6900 real-time clock */ -#define I2C_DRIVERID_SAA7114H 64 /* video decoder */ -#define I2C_DRIVERID_DS1374 65 /* DS1374 real time clock */ #define I2C_DRIVERID_TDA9874 66 /* TV sound decoder */ #define I2C_DRIVERID_SAA6752HS 67 /* MPEG2 encoder */ #define I2C_DRIVERID_TVEEPROM 68 /* TV EEPROM */ @@ -110,7 +81,6 @@ #define I2C_DRIVERID_DS1672 81 /* Dallas/Maxim DS1672 RTC */ #define I2C_DRIVERID_X1205 82 /* Xicor/Intersil X1205 RTC */ #define I2C_DRIVERID_PCF8563 83 /* Philips PCF8563 RTC */ -#define I2C_DRIVERID_RS5C372 84 /* Ricoh RS5C372 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 */ @@ -125,8 +95,6 @@ #define I2C_DRIVERID_CS5345 96 /* cs5345 audio processor */ #define I2C_DRIVERID_I2CDEV 900 -#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ -#define I2C_DRIVERID_ALERT 903 /* SMBus Alert Responder Client */ /* IDs -- Use DRIVERIDs 1000-1999 for sensors. These were originally in sensors.h in the lm_sensors package */ @@ -172,24 +140,16 @@ /* --- Bit algorithm adapters */ #define I2C_HW_B_LP 0x010000 /* Parallel port Philips style */ -#define I2C_HW_B_SER 0x010002 /* Serial line interface */ #define I2C_HW_B_BT848 0x010005 /* BT848 video boards */ -#define I2C_HW_B_WNV 0x010006 /* Winnov Videums */ #define I2C_HW_B_VIA 0x010007 /* Via vt82c586b */ #define I2C_HW_B_HYDRA 0x010008 /* Apple Hydra Mac I/O */ #define I2C_HW_B_G400 0x010009 /* Matrox G400 */ #define I2C_HW_B_I810 0x01000a /* Intel I810 */ #define I2C_HW_B_VOO 0x01000b /* 3dfx Voodoo 3 / Banshee */ -#define I2C_HW_B_PPORT 0x01000c /* Primitive parallel port adapter */ -#define I2C_HW_B_SAVG 0x01000d /* Savage 4 */ #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_TSUNA 0x010012 /* DEC Tsunami chipset */ -#define I2C_HW_B_OMAHA 0x010014 /* Omaha I2C interface (ARM) */ -#define I2C_HW_B_GUIDE 0x010015 /* Guide bit-basher */ #define I2C_HW_B_IXP2000 0x010016 /* GPIO on IXP2000 systems */ -#define I2C_HW_B_IXP4XX 0x010017 /* GPIO on IXP4XX systems */ #define I2C_HW_B_S3VIA 0x010018 /* S3Via ProSavage adapter */ #define I2C_HW_B_ZR36067 0x010019 /* Zoran-36057/36067 based boards */ #define I2C_HW_B_PCILYNX 0x01001a /* TI PCILynx I2C adapter */ @@ -203,22 +163,11 @@ #define I2C_HW_B_CX23885 0x010022 /* conexant 23885 based tv cards (bus1) */ /* --- PCF 8584 based algorithms */ -#define I2C_HW_P_LP 0x020000 /* Parallel port interface */ -#define I2C_HW_P_ISA 0x020001 /* generic ISA Bus inteface card */ #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 */ -/* --- ACPI Embedded controller algorithms */ -#define I2C_HW_ACPI_EC 0x1f0000 - -/* --- MPC824x PowerPC adapters */ -#define I2C_HW_MPC824X 0x100001 /* Motorola 8240 / 8245 */ - -/* --- MPC8xx PowerPC adapters */ -#define I2C_HW_MPC8XX_EPON 0x110000 /* Eponymous MPC8xx I2C adapter */ - /* --- PowerPC on-chip adapters */ #define I2C_HW_OCP 0x120000 /* IBM on-chip I2C adapter */ @@ -227,7 +176,6 @@ /* --- SGI adapters */ #define I2C_HW_SGI_VINO 0x160000 -#define I2C_HW_SGI_MACE 0x160001 /* --- XSCALE on-chip adapters */ #define I2C_HW_IOP3XX 0x140000 @@ -251,17 +199,10 @@ #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_OV519 0x040010 /* OV519 USB 1.1 webcam IC */ #define I2C_HW_SMBUS_OVFX2 0x040011 /* Cypress/OmniVision FX2 webcam */ #define I2C_HW_SMBUS_CAFE 0x040012 /* Marvell 88ALP01 "CAFE" cam */ #define I2C_HW_SMBUS_ALI1563 0x040013 -/* --- ISA pseudo-adapter */ -#define I2C_HW_ISA 0x050000 - -/* --- IPMB adapter */ -#define I2C_HW_IPMB 0x0c0000 - /* --- MCP107 adapter */ #define I2C_HW_MPC107 0x0d0000 -- cgit v1.2.3 From debafa4c14110eb6c01ab9756953c5f9cd351f05 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 09:57:44 -0200 Subject: backport kernel commit 69252128ec628e9d19739db0101e1826d993aecb From: Mauro Carvalho Chehab Original Changelog: Author: Andy Shevchenko Date: Thu Jan 24 18:11:53 2008 +0100 [ALSA] fm801 - Add mute support for FM-only card with FM801 PCI to tuner bridge This is improvement of the early support of the FM-only cards where the fm801 chip represents the PCI to tuner bridge. The tuner initialization isn't included the mute on as well as mute support via V4L request. Proposed patch should fix this at least for 64-PCR model. Signed-off-by: Mauro Carvalho Chehab --- linux/include/sound/tea575x-tuner.h | 1 + linux/sound/i2c/other/tea575x-tuner.c | 8 ++++++++ 2 files changed, 9 insertions(+) (limited to 'linux') diff --git a/linux/include/sound/tea575x-tuner.h b/linux/include/sound/tea575x-tuner.h index e29915916..c85aeca78 100644 --- a/linux/include/sound/tea575x-tuner.h +++ b/linux/include/sound/tea575x-tuner.h @@ -39,6 +39,7 @@ struct snd_tea575x_ops { #else void (*write)(struct snd_tea575x *tea, unsigned int val); unsigned int (*read)(struct snd_tea575x *tea); + void (*mute)(struct snd_tea575x *tea, unsigned int mute); #endif }; diff --git a/linux/sound/i2c/other/tea575x-tuner.c b/linux/sound/i2c/other/tea575x-tuner.c index 4c100300c..6d1dc0f9f 100644 --- a/linux/sound/i2c/other/tea575x-tuner.c +++ b/linux/sound/i2c/other/tea575x-tuner.c @@ -166,6 +166,10 @@ static int snd_tea575x_ioctl(struct inode *inode, struct file *file, struct video_audio v; if(copy_from_user(&v, arg, sizeof(v))) return -EFAULT; + if (tea->ops->mute) + tea->ops->mute(tea, + (v.flags & + VIDEO_AUDIO_MUTE) ? 1 : 0); if(v.audio) return -EINVAL; return 0; @@ -217,6 +221,10 @@ void snd_tea575x_init(struct snd_tea575x *tea) tea->freq = 90500 * 16; /* 90.5Mhz default */ snd_tea575x_set_freq(tea); + + /* mute on init */ + if (tea->ops->mute) + tea->ops->mute(tea, 1); } #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,17) -- cgit v1.2.3 From 7bb957ce707856c2df5092cdd8773601e22aa1fb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 10:36:50 -0200 Subject: Order is wrong, when comparing with kernel version From: Mauro Carvalho Chehab kernel-sync: Signed-off-by: Mauro Carvalho Chehab --- linux/include/media/v4l2-i2c-drv-legacy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/include/media/v4l2-i2c-drv-legacy.h b/linux/include/media/v4l2-i2c-drv-legacy.h index 812f18516..10c3231f0 100644 --- a/linux/include/media/v4l2-i2c-drv-legacy.h +++ b/linux/include/media/v4l2-i2c-drv-legacy.h @@ -39,7 +39,7 @@ struct v4l2_i2c_driver_data { static struct v4l2_i2c_driver_data v4l2_i2c_data; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) -const static struct i2c_client_address_data addr_data; +static const struct i2c_client_address_data addr_data; #else static struct i2c_client_address_data addr_data; #endif -- cgit v1.2.3 From e4d2ad96d3876243a74af7ccdf5a984bebf90ea5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 10:40:14 -0200 Subject: More English fixes from kernel tree From: Mauro Carvalho Chehab kernel-sync: Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/pwc/pwc-if.c | 2 +- linux/include/media/rds.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pwc/pwc-if.c b/linux/drivers/media/video/pwc/pwc-if.c index b09443b09..6e8474fc0 100644 --- a/linux/drivers/media/video/pwc/pwc-if.c +++ b/linux/drivers/media/video/pwc/pwc-if.c @@ -542,7 +542,7 @@ int pwc_handle_frame(struct pwc_device *pdev) } if (pdev->read_frame != NULL) { - /* Decompression is a lenghty process, so it's outside of the lock. + /* Decompression is a lengthy process, so it's outside of the lock. This gives the isoc_handler the opportunity to fill more frames in the mean time. */ diff --git a/linux/include/media/rds.h b/linux/include/media/rds.h index 951c1ae0b..a89426667 100644 --- a/linux/include/media/rds.h +++ b/linux/include/media/rds.h @@ -4,7 +4,7 @@ saa6588.c and every driver (e.g. bttv-driver.c) that wants to use the saa6588 module. - Instead of having a seperate rds.h, I'd prefer to include + Instead of having a separate rds.h, I'd prefer to include this stuff in one of the already existing files like tuner.h (c) 2005 by Hans J. Koch -- cgit v1.2.3 From 24db565af4ebc0897b57f76e70753dbf5232e52e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 10:42:44 -0200 Subject: backport commit a3c53e2310192e63e49610ffcb6a36b2a706fa3e From: Mauro Carvalho Chehab Original Changelog: Author: Daniel Walker Date: Thu Jan 17 12:52:05 2008 -0800 fix wrong sized spinlock flags argument Correct wrong sized spinlock flags, form int to unsigned long. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-core.c | 3 +-- 1 file changed, 1 insertion(+), 2 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 0f9c06942..862d1f6a4 100644 --- a/linux/drivers/media/video/saa7134/saa7134-core.c +++ b/linux/drivers/media/video/saa7134/saa7134-core.c @@ -1312,9 +1312,8 @@ static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state) static int saa7134_resume(struct pci_dev *pci_dev) { - struct saa7134_dev *dev = pci_get_drvdata(pci_dev); - unsigned int flags; + unsigned long flags; pci_set_power_state(pci_dev, PCI_D0); pci_restore_state(pci_dev); -- cgit v1.2.3 From 4ce8ef90769df3644a1eb9fee1b7746dea09e753 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 07:37:21 +0000 Subject: em28xx/em28xx-core.c: fix use of potentially uninitialized variable From: Andrew Morton drivers/media/video/em28xx/em28xx-core.c: In function 'em28xx_set_audio_source': drivers/media/video/em28xx/em28xx-core.c:276: warning: 'no_ac97' may be used uninitialized in this function This looks like a genuine bug to me. Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c index a0ec1cfbc..952755c8e 100644 --- a/linux/drivers/media/video/em28xx/em28xx-core.c +++ b/linux/drivers/media/video/em28xx/em28xx-core.c @@ -324,7 +324,8 @@ int em28xx_set_audio_source(struct em28xx *dev) static char *enable = "\x08\x08"; static char *disable = "\x08\x88"; char *video = enable, *line = disable; - int ret, no_ac97; + int ret; + int no_ac97 = 0; u8 input; if (dev->is_em2800) { -- cgit v1.2.3 From 4ac1cd8ad088bf6e13b4448feb8806a56c361a17 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 11:21:32 -0200 Subject: Fix compilation against kernel 2.6.23 From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/cx88/cx88-alsa.c | 2 +- linux/drivers/media/video/saa7134/saa7134-alsa.c | 1 + linux/sound/i2c/other/tea575x-tuner.c | 1 + linux/sound/pci/bt87x.c | 3 +++ 4 files changed, 6 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx88/cx88-alsa.c b/linux/drivers/media/video/cx88/cx88-alsa.c index ae69ba065..dce005b14 100644 --- a/linux/drivers/media/video/cx88/cx88-alsa.c +++ b/linux/drivers/media/video/cx88/cx88-alsa.c @@ -33,6 +33,7 @@ #include #include +#include "compat.h" #include #include #include @@ -42,7 +43,6 @@ #include #endif -#include "compat.h" #include "cx88.h" #include "cx88-reg.h" diff --git a/linux/drivers/media/video/saa7134/saa7134-alsa.c b/linux/drivers/media/video/saa7134/saa7134-alsa.c index d9660becc..6f480f61e 100644 --- a/linux/drivers/media/video/saa7134/saa7134-alsa.c +++ b/linux/drivers/media/video/saa7134/saa7134-alsa.c @@ -22,6 +22,7 @@ #include #include #include +#include "compat.h" #include #include #include diff --git a/linux/sound/i2c/other/tea575x-tuner.c b/linux/sound/i2c/other/tea575x-tuner.c index 6d1dc0f9f..a7fbe18d0 100644 --- a/linux/sound/i2c/other/tea575x-tuner.c +++ b/linux/sound/i2c/other/tea575x-tuner.c @@ -24,6 +24,7 @@ #include #include #include +#include "compat.h" #include #include diff --git a/linux/sound/pci/bt87x.c b/linux/sound/pci/bt87x.c index 3e820f75c..d1d91bbdc 100644 --- a/linux/sound/pci/bt87x.c +++ b/linux/sound/pci/bt87x.c @@ -28,6 +28,9 @@ #include #include #include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) +#include +#endif #include #include #include -- cgit v1.2.3 From 6ed8c3ecd4f0af1020033702ba9e7236984e542e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 20:29:26 -0200 Subject: Fix em28xx audio initialization From: Mauro Carvalho Chehab AC97 register initialization seem to always be needed. This patch fixes audio for Prolink/Pixelview USB2 board. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-cards.c | 6 +++--- linux/drivers/media/video/em28xx/em28xx-core.c | 11 +++-------- 2 files changed, 6 insertions(+), 11 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 1a9236e24..db07cbbe3 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -394,15 +394,15 @@ struct em28xx_board em28xx_boards[] = { .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = SAA7115_COMPOSITE2, - .amux = 1, + .amux = EM28XX_AMUX_LINE_IN, }, { .type = EM28XX_VMUX_COMPOSITE1, .vmux = SAA7115_COMPOSITE0, - .amux = 1, + .amux = EM28XX_AMUX_LINE_IN, }, { .type = EM28XX_VMUX_SVIDEO, .vmux = SAA7115_SVIDEO3, - .amux = 1, + .amux = EM28XX_AMUX_LINE_IN, } }, }, }; diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c index 952755c8e..3af2792a7 100644 --- a/linux/drivers/media/video/em28xx/em28xx-core.c +++ b/linux/drivers/media/video/em28xx/em28xx-core.c @@ -325,7 +325,6 @@ int em28xx_set_audio_source(struct em28xx *dev) static char *disable = "\x08\x88"; char *video = enable, *line = disable; int ret; - int no_ac97 = 0; u8 input; if (dev->is_em2800) { @@ -345,11 +344,9 @@ int em28xx_set_audio_source(struct em28xx *dev) switch (dev->ctl_ainput) { case EM28XX_AMUX_VIDEO: input = EM28XX_AUDIO_SRC_TUNER; - no_ac97 = 1; break; case EM28XX_AMUX_LINE_IN: input = EM28XX_AUDIO_SRC_LINE; - no_ac97 = 1; break; case EM28XX_AMUX_AC97_VIDEO: input = EM28XX_AUDIO_SRC_LINE; @@ -366,11 +363,9 @@ int em28xx_set_audio_source(struct em28xx *dev) if (ret < 0) return ret; - if (no_ac97) - return 0; - - /* Sets AC97 mixer registers */ - + /* Sets AC97 mixer registers + This is seems to be needed, even for non-ac97 configs + */ ret = em28xx_write_ac97(dev, VIDEO_AC97, video); if (ret < 0) return ret; -- cgit v1.2.3 From 6d8efedeb82d64e349ac05e4371b5c7be6c3e239 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Feb 2008 07:00:41 -0200 Subject: em28xx: Allow register dump/setting for debug From: Mauro Carvalho Chehab Adds vidioc_[g|s]_register handlers. This allows getting/setting register from em28xx. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-video.c | 66 +++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index 7af56469e..72117b5bf 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -852,6 +852,64 @@ static int vidioc_s_frequency(struct file *file, void *priv, return 0; } +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int em28xx_reg_len(int reg) +{ + switch (reg) { + case AC97LSB_REG: + case HSCALELOW_REG: + case VSCALELOW_REG: + + return 2; + default: + return 1; + } +} + +static int vidioc_g_register(struct file *file, void *priv, + struct v4l2_register *reg) +{ + struct em28xx_fh *fh = priv; + struct em28xx *dev = fh->dev; + int ret; + + if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) + return -EINVAL; + + if (em28xx_reg_len(reg->reg) == 1) { + ret = em28xx_read_reg(dev, reg->reg); + if (ret < 0) + return ret; + + reg->val = ret; + } else { + u16 val; + ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, + reg->reg, (char *)&val, 2); + if (ret < 0) + return ret; + + reg->val = val; + } + + return 0; +} + +static int vidioc_s_register(struct file *file, void *priv, + struct v4l2_register *reg) +{ + struct em28xx_fh *fh = priv; + struct em28xx *dev = fh->dev; + u16 buf; + + buf = be16_to_cpu((__u16)reg->val); + + return em28xx_write_regs(dev, reg->reg, (char *)&buf, + em28xx_reg_len(reg->reg)); +} +#endif + + static int vidioc_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cc) { @@ -1805,6 +1863,10 @@ static const struct video_device em28xx_video_template = { .vidioc_s_tuner = vidioc_s_tuner, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .vidioc_g_register = vidioc_g_register, + .vidioc_s_register = vidioc_s_register, +#endif .tvnorms = V4L2_STD_ALL, .current_norm = V4L2_STD_PAL, @@ -1827,6 +1889,10 @@ static struct video_device em28xx_radio_template = { .vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .vidioc_g_register = vidioc_g_register, + .vidioc_s_register = vidioc_s_register, +#endif }; /******************************** usb interface *****************************************/ -- cgit v1.2.3 From f7fd21f70b935c84ecc4e250369d381eb187482a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Feb 2008 13:55:19 -0200 Subject: em28xx: Fix printing debug values higher than 127 From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c index 3af2792a7..f2686bde0 100644 --- a/linux/drivers/media/video/em28xx/em28xx-core.c +++ b/linux/drivers/media/video/em28xx/em28xx-core.c @@ -201,7 +201,7 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, if (reg_debug){ printk(ret < 0 ? " failed!\n" : "%02x values: ", ret); for (byte = 0; byte < len; byte++) { - printk(" %02x", buf[byte]); + printk(" %02x", (unsigned char)buf[byte]); } printk("\n"); } @@ -228,7 +228,8 @@ int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg) 0x0000, reg, &val, 1, HZ); if (reg_debug) - printk(ret < 0 ? " failed!\n" : "%02x\n", val); + printk(ret < 0 ? " failed!\n" : + "%02x\n", (unsigned char) val); if (ret < 0) return ret; -- cgit v1.2.3 From dc7b5fd0a294c2db79154467e4c635a039849ab3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Feb 2008 13:56:16 -0200 Subject: em28xx: Fix endian and returns the correct values From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-video.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 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 72117b5bf..a5d8797e4 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -883,13 +883,13 @@ static int vidioc_g_register(struct file *file, void *priv, reg->val = ret; } else { - u16 val; + u64 val = 0; ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, reg->reg, (char *)&val, 2); if (ret < 0) return ret; - reg->val = val; + reg->val = cpu_to_le64((__u64)val); } return 0; @@ -900,9 +900,9 @@ static int vidioc_s_register(struct file *file, void *priv, { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - u16 buf; + u64 buf; - buf = be16_to_cpu((__u16)reg->val); + buf = le64_to_cpu((__u64)reg->val); return em28xx_write_regs(dev, reg->reg, (char *)&buf, em28xx_reg_len(reg->reg)); -- cgit v1.2.3 From db10010189a9bdd6f1bbb39f5c575169c139ea7b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Feb 2008 16:34:13 -0200 Subject: em28xx: makes audio settings more stable From: Mauro Carvalho Chehab Improves audio configurations on em28xx: - mutes audio before changing amux; - adds a delay after setting audio src; - waits up to 50ms for ac97 busy. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-core.c | 28 ++++++++++++++++++------- linux/drivers/media/video/em28xx/em28xx-video.c | 3 +-- 2 files changed, 21 insertions(+), 10 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c index f2686bde0..441413016 100644 --- a/linux/drivers/media/video/em28xx/em28xx-core.c +++ b/linux/drivers/media/video/em28xx/em28xx-core.c @@ -306,21 +306,26 @@ static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, */ static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val) { - int ret; + int ret, i; u8 addr = reg & 0x7f; if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0) return ret; if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0) return ret; - if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0) - return ret; - else if (((u8) ret) & 0x01) { - em28xx_warn ("AC97 command still being executed: not handled properly!\n"); + + /* Wait up to 50 ms for AC97 command to complete */ + for (i = 0; i < 10; i++) { + if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0) + return ret; + if (!((u8) ret) & 0x01) + return 0; + msleep(5); } + em28xx_warn ("AC97 command still being executed: not handled properly!\n"); return 0; } -int em28xx_set_audio_source(struct em28xx *dev) +static int em28xx_set_audio_source(struct em28xx *dev) { static char *enable = "\x08\x08"; static char *disable = "\x08\x88"; @@ -363,6 +368,7 @@ int em28xx_set_audio_source(struct em28xx *dev) ret = em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0); if (ret < 0) return ret; + msleep(5); /* Sets AC97 mixer registers This is seems to be needed, even for non-ac97 configs @@ -385,9 +391,10 @@ int em28xx_audio_analog_set(struct em28xx *dev) s[0] |= 0x1f - dev->volume; s[1] |= 0x1f - dev->volume; - if (dev->mute) - s[1] |= 0x80; + /* Mute */ + s[1] |= 0x80; ret = em28xx_write_ac97(dev, MASTER_AC97, s); + if (ret < 0) return ret; @@ -405,6 +412,11 @@ int em28xx_audio_analog_set(struct em28xx *dev) /* Selects the proper audio input */ ret = em28xx_set_audio_source(dev); + /* Unmute device */ + if (!dev->mute) + s[1] &= ~0x80; + ret = em28xx_write_ac97(dev, MASTER_AC97, s); + return ret; } EXPORT_SYMBOL_GPL(em28xx_audio_analog_set); diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index a5d8797e4..bf8693dbf 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -211,7 +211,7 @@ static void video_mux(struct em28xx *dev, int index) em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route); } - em28xx_set_audio_source(dev); + em28xx_audio_analog_set(dev); } /* Usage lock check functions */ @@ -859,7 +859,6 @@ static int em28xx_reg_len(int reg) case AC97LSB_REG: case HSCALELOW_REG: case VSCALELOW_REG: - return 2; default: return 1; -- cgit v1.2.3 From 0852978825971c0dcf401c56733067a916237a96 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Feb 2008 16:52:15 -0200 Subject: em28xx-alsa: Add a missing mutex From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-audio.c | 5 +++++ linux/drivers/media/video/em28xx/em28xx.h | 1 - 2 files changed, 5 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 e97446778..37e893455 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -300,8 +300,11 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) dprintk("opening device and trying to acquire exclusive lock\n"); /* Sets volume, mute, etc */ + dev->mute = 0; + mutex_lock(&dev->lock); ret = em28xx_audio_analog_set(dev); + mutex_unlock(&dev->lock); if (ret < 0) goto err; @@ -337,7 +340,9 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream) dprintk("closing device\n"); dev->mute = 1; + mutex_lock(&dev->lock); 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); diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index 2a797f622..fae498926 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -360,7 +360,6 @@ int em28xx_read_reg(struct em28xx *dev, u16 reg); int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, int len); int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len); -int em28xx_set_audio_source(struct em28xx *dev); int em28xx_audio_analog_set(struct em28xx *dev); int em28xx_colorlevels_set_default(struct em28xx *dev); -- cgit v1.2.3 From 2e060eac7c0a23ea0e3fa3accb9a6992f673d3a5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 17:46:39 +0000 Subject: Add chip IDs for Micron mt9m001 and mt9v022 CMOS cameras From: Guennadi Liakhovetski Add V4L2_IDENT chip IDs for mt9m001 and mt9v022 cameras, will be used by future patches, primarily to implement the g_chip_ident ioctl. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- linux/include/media/v4l2-chip-ident.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'linux') diff --git a/linux/include/media/v4l2-chip-ident.h b/linux/include/media/v4l2-chip-ident.h index 032bb75f6..0ea0bd85c 100644 --- a/linux/include/media/v4l2-chip-ident.h +++ b/linux/include/media/v4l2-chip-ident.h @@ -153,6 +153,12 @@ enum { V4L2_IDENT_MSP4428G = 44287, V4L2_IDENT_MSP4448G = 44487, V4L2_IDENT_MSP4458G = 44587, + + /* Micron CMOS sensor chips: 45000-45099 */ + V4L2_IDENT_MT9M001C12ST = 45000, + V4L2_IDENT_MT9M001C12STM = 45005, + V4L2_IDENT_MT9V022IX7ATC = 45010, /* No way to detect "normal" I77ATx */ + V4L2_IDENT_MT9V022IX7ATM = 45015, /* and "lead free" IA7ATx chips */ }; #endif -- cgit v1.2.3 From 4ecdcc3c9d89b126c5e40cef0f4860083a9829cd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 17:46:13 +0000 Subject: soc_camera V4L2 driver for directly-connected SoC-based cameras From: Guennadi Liakhovetski This driver provides an interface between platform-specific camera busses and camera devices. It should be used if the camera is connected not over a "proper" bus like PCI or USB, but over a special bus, like, for example, the Quick Capture interface on PXA270 SoCs. Later it should also be used for i.MX31 SoCs from Freescale. It can handle multiple cameras and / or multiple busses, which can be used, e.g., in stereo-vision applications. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/Kconfig | 9 + linux/drivers/media/video/Makefile | 2 + linux/drivers/media/video/soc_camera.c | 973 +++++++++++++++++++++++++++++++++ linux/include/media/soc_camera.h | 147 +++++ 4 files changed, 1131 insertions(+) create mode 100644 linux/drivers/media/video/soc_camera.c create mode 100644 linux/include/media/soc_camera.h (limited to 'linux') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 37072a21d..c0498ac98 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -836,4 +836,13 @@ config USB_STKWEBCAM endif # V4L_USB_DRIVERS +config SOC_CAMERA + tristate "SoC camera support" + depends on VIDEO_V4L2 + select VIDEOBUF_DMA_SG + help + SoC Camera is a common API to several cameras, not connecting + over a bus like PCI or USB. For example some i2c camera connected + directly to the data bus of an SoC. + endif # VIDEO_CAPTURE_DRIVERS diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index cd4ee0584..0bf47f83b 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -137,5 +137,7 @@ obj-$(CONFIG_VIDEO_IVTV) += ivtv/ obj-$(CONFIG_VIDEO_VIVI) += vivi.o obj-$(CONFIG_VIDEO_CX23885) += cx23885/ +obj-$(CONFIG_SOC_CAMERA) += soc_camera.o + EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/frontends diff --git a/linux/drivers/media/video/soc_camera.c b/linux/drivers/media/video/soc_camera.c new file mode 100644 index 000000000..904e9dfc1 --- /dev/null +++ b/linux/drivers/media/video/soc_camera.c @@ -0,0 +1,973 @@ +/* + * camera image capture (abstract) bus driver + * + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This driver provides an interface between platform-specific camera + * busses and camera devices. It should be used if the camera is + * connected not over a "proper" bus like PCI or USB, but over a + * special bus, like, for example, the Quick Capture interface on PXA270 + * SoCs. Later it should also be used for i.MX31 SoCs from Freescale. + * It can handle multiple cameras and / or multiple busses, which can + * be used, e.g., in stereo-vision applications. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static LIST_HEAD(hosts); +static LIST_HEAD(devices); +static DEFINE_MUTEX(list_lock); +static DEFINE_MUTEX(video_lock); + +const static struct soc_camera_data_format* +format_by_fourcc(struct soc_camera_device *icd, unsigned int fourcc) +{ + unsigned int i; + + for (i = 0; i < icd->ops->num_formats; i++) + if (icd->ops->formats[i].fourcc == fourcc) + return icd->ops->formats + i; + return NULL; +} + +static int soc_camera_try_fmt_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + struct soc_camera_host *ici = + to_soc_camera_host(icd->dev.parent); + enum v4l2_field field; + const struct soc_camera_data_format *fmt; + int ret; + + WARN_ON(priv != file->private_data); + + fmt = format_by_fourcc(icd, f->fmt.pix.pixelformat); + if (!fmt) { + dev_dbg(&icd->dev, "invalid format 0x%08x\n", + f->fmt.pix.pixelformat); + return -EINVAL; + } + + dev_dbg(&icd->dev, "fmt: 0x%08x\n", fmt->fourcc); + + field = f->fmt.pix.field; + + if (field == V4L2_FIELD_ANY) { + field = V4L2_FIELD_NONE; + } else if (V4L2_FIELD_NONE != field) { + dev_err(&icd->dev, "Field type invalid.\n"); + return -EINVAL; + } + + /* limit to host capabilities */ + ret = ici->try_fmt_cap(ici, f); + + /* limit to sensor capabilities */ + if (!ret) + ret = icd->ops->try_fmt_cap(icd, f); + + /* calculate missing fields */ + f->fmt.pix.field = field; + f->fmt.pix.bytesperline = + (f->fmt.pix.width * fmt->depth) >> 3; + f->fmt.pix.sizeimage = + f->fmt.pix.height * f->fmt.pix.bytesperline; + + return ret; +} + +static int soc_camera_enum_input(struct file *file, void *priv, + struct v4l2_input *inp) +{ + if (inp->index != 0) + return -EINVAL; + + inp->type = V4L2_INPUT_TYPE_CAMERA; + inp->std = V4L2_STD_UNKNOWN; + strcpy(inp->name, "Camera"); + + return 0; +} + +static int soc_camera_g_input(struct file *file, void *priv, unsigned int *i) +{ + *i = 0; + + return 0; +} + +static int soc_camera_s_input(struct file *file, void *priv, unsigned int i) +{ + if (i > 0) + return -EINVAL; + + return 0; +} + +static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a) +{ + return 0; +} + +static int soc_camera_reqbufs(struct file *file, void *priv, + struct v4l2_requestbuffers *p) +{ + int ret; + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + struct soc_camera_host *ici = + to_soc_camera_host(icd->dev.parent); + + WARN_ON(priv != file->private_data); + + dev_dbg(&icd->dev, "%s: %d\n", __FUNCTION__, p->memory); + + ret = videobuf_reqbufs(&icf->vb_vidq, p); + if (ret < 0) + return ret; + + return ici->reqbufs(icf, p); + + return ret; +} + +static int soc_camera_querybuf(struct file *file, void *priv, + struct v4l2_buffer *p) +{ + struct soc_camera_file *icf = file->private_data; + + WARN_ON(priv != file->private_data); + + return videobuf_querybuf(&icf->vb_vidq, p); +} + +static int soc_camera_qbuf(struct file *file, void *priv, + struct v4l2_buffer *p) +{ + struct soc_camera_file *icf = file->private_data; + + WARN_ON(priv != file->private_data); + + return videobuf_qbuf(&icf->vb_vidq, p); +} + +static int soc_camera_dqbuf(struct file *file, void *priv, + struct v4l2_buffer *p) +{ + struct soc_camera_file *icf = file->private_data; + + WARN_ON(priv != file->private_data); + + return videobuf_dqbuf(&icf->vb_vidq, p, file->f_flags & O_NONBLOCK); +} + +static int soc_camera_open(struct inode *inode, struct file *file) +{ + struct video_device *vdev = video_devdata(file); + struct soc_camera_device *icd = container_of(vdev->dev, + struct soc_camera_device, dev); + struct soc_camera_host *ici = + to_soc_camera_host(icd->dev.parent); + struct soc_camera_file *icf; + int ret; + + icf = vmalloc(sizeof(*icf)); + if (!icf) + return -ENOMEM; + + icf->icd = icd; + + if (!try_module_get(icd->ops->owner)) { + dev_err(&icd->dev, "Couldn't lock sensor driver.\n"); + ret = -EINVAL; + goto emgd; + } + + if (!try_module_get(ici->owner)) { + dev_err(&icd->dev, "Couldn't lock capture bus driver.\n"); + ret = -EINVAL; + goto emgi; + } + + file->private_data = icf; + dev_dbg(&icd->dev, "camera device open\n"); + + /* We must pass NULL as dev pointer, then all pci_* dma operations + * transform to normal dma_* ones. Do we need an irqlock? */ + videobuf_queue_pci_init(&icf->vb_vidq, ici->vbq_ops, NULL, NULL, + V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, + ici->msize, icd); + + return 0; + +emgi: + module_put(icd->ops->owner); +emgd: + vfree(icf); + return ret; +} + +static int soc_camera_close(struct inode *inode, struct file *file) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct video_device *vdev = icd->vdev; + + module_put(icd->ops->owner); + module_put(ici->owner); + vfree(file->private_data); + + dev_dbg(vdev->dev, "camera device close\n"); + + return 0; +} + +static int soc_camera_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + struct video_device *vdev = icd->vdev; + int err = -EINVAL; + + dev_err(vdev->dev, "camera device read not implemented\n"); + + return err; +} + +static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + int err; + + dev_dbg(&icd->dev, "mmap called, vma=0x%08lx\n", (unsigned long)vma); + + err = videobuf_mmap_mapper(&icf->vb_vidq, vma); + + dev_dbg(&icd->dev, "vma start=0x%08lx, size=%ld, ret=%d\n", + (unsigned long)vma->vm_start, + (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, + err); + + return err; +} + +static unsigned int soc_camera_poll(struct file *file, poll_table *pt) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + struct soc_camera_host *ici = + to_soc_camera_host(icd->dev.parent); + + if (list_empty(&icf->vb_vidq.stream)) { + dev_err(&icd->dev, "Trying to poll with no queued buffers!\n"); + return POLLERR; + } + + return ici->poll(file, pt); +} + + +static struct file_operations soc_camera_fops = { + .owner = THIS_MODULE, + .open = soc_camera_open, + .release = soc_camera_close, + .ioctl = video_ioctl2, + .read = soc_camera_read, + .mmap = soc_camera_mmap, + .poll = soc_camera_poll, + .llseek = no_llseek, +}; + + +static int soc_camera_s_fmt_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + struct soc_camera_host *ici = + to_soc_camera_host(icd->dev.parent); + int ret; + struct v4l2_rect rect; + const static struct soc_camera_data_format *data_fmt; + + WARN_ON(priv != file->private_data); + + data_fmt = format_by_fourcc(icd, f->fmt.pix.pixelformat); + if (!data_fmt) + return -EINVAL; + + /* cached_datawidth may be further adjusted by the ici */ + icd->cached_datawidth = data_fmt->depth; + + ret = soc_camera_try_fmt_cap(file, icf, f); + if (ret < 0) + return ret; + + rect.left = icd->x_current; + rect.top = icd->y_current; + rect.width = f->fmt.pix.width; + rect.height = f->fmt.pix.height; + ret = ici->set_capture_format(icd, f->fmt.pix.pixelformat, &rect); + + if (!ret) { + icd->current_fmt = data_fmt; + icd->width = rect.width; + icd->height = rect.height; + icf->vb_vidq.field = f->fmt.pix.field; + if (V4L2_BUF_TYPE_VIDEO_CAPTURE != f->type) + dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n", + f->type); + + dev_dbg(&icd->dev, "set width: %d height: %d\n", + icd->width, icd->height); + } + + return ret; +} + +static int soc_camera_enum_fmt_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + const struct soc_camera_data_format *format; + + WARN_ON(priv != file->private_data); + + if (f->index >= icd->ops->num_formats) + return -EINVAL; + + format = &icd->ops->formats[f->index]; + + strlcpy(f->description, format->name, sizeof(f->description)); + f->pixelformat = format->fourcc; + return 0; +} + +static int soc_camera_g_fmt_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + + WARN_ON(priv != file->private_data); + + f->fmt.pix.width = icd->width; + f->fmt.pix.height = icd->height; + f->fmt.pix.field = icf->vb_vidq.field; + f->fmt.pix.pixelformat = icd->current_fmt->fourcc; + f->fmt.pix.bytesperline = + (f->fmt.pix.width * icd->current_fmt->depth) >> 3; + f->fmt.pix.sizeimage = + f->fmt.pix.height * f->fmt.pix.bytesperline; + dev_dbg(&icd->dev, "current_fmt->fourcc: 0x%08x\n", + icd->current_fmt->fourcc); + return 0; +} + +static int soc_camera_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + struct soc_camera_host *ici = + to_soc_camera_host(icd->dev.parent); + + WARN_ON(priv != file->private_data); + + strlcpy(cap->driver, ici->drv_name, sizeof(cap->driver)); + return ici->querycap(ici, cap); +} + +static int soc_camera_streamon(struct file *file, void *priv, + enum v4l2_buf_type i) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + + WARN_ON(priv != file->private_data); + + dev_dbg(&icd->dev, "%s\n", __FUNCTION__); + + if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + icd->ops->start_capture(icd); + + /* This calls buf_queue from host driver's videobuf_queue_ops */ + return videobuf_streamon(&icf->vb_vidq); +} + +static int soc_camera_streamoff(struct file *file, void *priv, + enum v4l2_buf_type i) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + + WARN_ON(priv != file->private_data); + + dev_dbg(&icd->dev, "%s\n", __FUNCTION__); + + if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + /* This calls buf_release from host driver's videobuf_queue_ops for all + * remaining buffers. When the last buffer is freed, stop capture */ + videobuf_streamoff(&icf->vb_vidq); + + icd->ops->stop_capture(icd); + + return 0; +} + +static int soc_camera_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *qc) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + int i; + + WARN_ON(priv != file->private_data); + + if (!qc->id) + return -EINVAL; + + for (i = 0; i < icd->ops->num_controls; i++) + if (qc->id == icd->ops->controls[i].id) { + memcpy(qc, &(icd->ops->controls[i]), + sizeof(*qc)); + return 0; + } + + return -EINVAL; +} + +static int soc_camera_g_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + + WARN_ON(priv != file->private_data); + + switch (ctrl->id) { + case V4L2_CID_GAIN: + if (icd->gain == (unsigned short)~0) + return -EINVAL; + ctrl->value = icd->gain; + return 0; + case V4L2_CID_EXPOSURE: + if (icd->exposure == (unsigned short)~0) + return -EINVAL; + ctrl->value = icd->exposure; + return 0; + } + + if (icd->ops->get_control) + return icd->ops->get_control(icd, ctrl); + return -EINVAL; +} + +static int soc_camera_s_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + + WARN_ON(priv != file->private_data); + + if (icd->ops->set_control) + return icd->ops->set_control(icd, ctrl); + return -EINVAL; +} + +static int soc_camera_cropcap(struct file *file, void *fh, + struct v4l2_cropcap *a) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + a->bounds.left = icd->x_min; + a->bounds.top = icd->y_min; + a->bounds.width = icd->width_max; + a->bounds.height = icd->height_max; + a->defrect.left = icd->x_min; + a->defrect.top = icd->y_min; + a->defrect.width = 640; + a->defrect.height = 480; + a->pixelaspect.numerator = 1; + a->pixelaspect.denominator = 1; + + return 0; +} + +static int soc_camera_g_crop(struct file *file, void *fh, + struct v4l2_crop *a) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + a->c.left = icd->x_current; + a->c.top = icd->y_current; + a->c.width = icd->width; + a->c.height = icd->height; + + return 0; +} + +static int soc_camera_s_crop(struct file *file, void *fh, + struct v4l2_crop *a) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + struct soc_camera_host *ici = + to_soc_camera_host(icd->dev.parent); + int ret; + + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + ret = ici->set_capture_format(icd, 0, &a->c); + if (!ret) { + icd->width = a->c.width; + icd->height = a->c.height; + icd->x_current = a->c.left; + icd->y_current = a->c.top; + } + + return ret; +} + +static int soc_camera_g_chip_ident(struct file *file, void *fh, + struct v4l2_chip_ident *id) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + + if (!icd->ops->get_chip_id) + return -EINVAL; + + return icd->ops->get_chip_id(icd, id); +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int soc_camera_g_register(struct file *file, void *fh, + struct v4l2_register *reg) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + + if (!icd->ops->get_register) + return -EINVAL; + + return icd->ops->get_register(icd, reg); +} + +static int soc_camera_s_register(struct file *file, void *fh, + struct v4l2_register *reg) +{ + struct soc_camera_file *icf = file->private_data; + struct soc_camera_device *icd = icf->icd; + + if (!icd->ops->set_register) + return -EINVAL; + + return icd->ops->set_register(icd, reg); +} +#endif + +static int device_register_link(struct soc_camera_device *icd) +{ + int ret = device_register(&icd->dev); + + if (ret < 0) { + /* Prevent calling device_unregister() */ + icd->dev.parent = NULL; + dev_err(&icd->dev, "Cannot register device: %d\n", ret); + /* Even if probe() was unsuccessful for all registered drivers, + * device_register() returns 0, and we add the link, just to + * document this camera's control device */ + } else if (icd->control) + /* Have to sysfs_remove_link() before device_unregister()? */ + if (sysfs_create_link(&icd->dev.kobj, &icd->control->kobj, + "control")) + dev_warn(&icd->dev, + "Failed creating the control symlink\n"); + return ret; +} + +/* So far this function cannot fail */ +static void scan_add_host(struct soc_camera_host *ici) +{ + struct soc_camera_device *icd; + + mutex_lock(&list_lock); + + list_for_each_entry(icd, &devices, list) { + if (icd->iface == ici->nr) { + icd->dev.parent = &ici->dev; + device_register_link(icd); + } + } + + mutex_unlock(&list_lock); +} + +/* return: 0 if no match found or a match found and + * device_register() successful, error code otherwise */ +static int scan_add_device(struct soc_camera_device *icd) +{ + struct soc_camera_host *ici; + int ret = 0; + + mutex_lock(&list_lock); + + list_add_tail(&icd->list, &devices); + + /* Watch out for class_for_each_device / class_find_device API by + * Dave Young */ + list_for_each_entry(ici, &hosts, list) { + if (icd->iface == ici->nr) { + ret = 1; + icd->dev.parent = &ici->dev; + break; + } + } + + mutex_unlock(&list_lock); + + if (ret) + ret = device_register_link(icd); + + return ret; +} + +static int soc_camera_probe(struct device *dev) +{ + struct soc_camera_device *icd = to_soc_camera_dev(dev); + struct soc_camera_host *ici = + to_soc_camera_host(icd->dev.parent); + int ret; + + if (!icd->probe) + return -ENODEV; + + ret = ici->add(icd); + if (ret < 0) + return ret; + + ret = icd->probe(icd); + if (ret < 0) + ici->remove(icd); + else { + const struct v4l2_queryctrl *qctrl; + + qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_GAIN); + icd->gain = qctrl ? qctrl->default_value : (unsigned short)~0; + qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); + icd->exposure = qctrl ? qctrl->default_value : + (unsigned short)~0; + } + + return ret; +} + +/* This is called on device_unregister, which only means we have to disconnect + * from the host, but not remove ourselves from the device list */ +static int soc_camera_remove(struct device *dev) +{ + struct soc_camera_device *icd = to_soc_camera_dev(dev); + struct soc_camera_host *ici = + to_soc_camera_host(icd->dev.parent); + + if (icd->remove) + icd->remove(icd); + + ici->remove(icd); + + return 0; +} + +static struct bus_type soc_camera_bus_type = { + .name = "soc-camera", + .probe = soc_camera_probe, + .remove = soc_camera_remove, +}; + +static struct device_driver ic_drv = { + .name = "camera", + .bus = &soc_camera_bus_type, + .owner = THIS_MODULE, +}; + +/* + * Image capture host - this is a host device, not a bus device, so, + * no bus reference, no probing. + */ +static struct class soc_camera_host_class = { + .owner = THIS_MODULE, + .name = "camera_host", +}; + +static void dummy_release(struct device *dev) +{ +} + +int soc_camera_host_register(struct soc_camera_host *ici, struct module *owner) +{ + int ret; + struct soc_camera_host *ix; + + if (!ici->vbq_ops || !ici->add || !ici->remove || !owner) + return -EINVAL; + + /* Number might be equal to the platform device ID */ + sprintf(ici->dev.bus_id, "camera_host%d", ici->nr); + ici->dev.class = &soc_camera_host_class; + + mutex_lock(&list_lock); + list_for_each_entry(ix, &hosts, list) { + if (ix->nr == ici->nr) { + mutex_unlock(&list_lock); + return -EBUSY; + } + } + + list_add_tail(&ici->list, &hosts); + mutex_unlock(&list_lock); + + ici->owner = owner; + ici->dev.release = dummy_release; + + ret = device_register(&ici->dev); + + if (ret) + goto edevr; + + scan_add_host(ici); + + return 0; + +edevr: + mutex_lock(&list_lock); + list_del(&ici->list); + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(soc_camera_host_register); + +/* Unregister all clients! */ +void soc_camera_host_unregister(struct soc_camera_host *ici) +{ + struct soc_camera_device *icd; + + mutex_lock(&list_lock); + + list_del(&ici->list); + + list_for_each_entry(icd, &devices, list) { + if (icd->dev.parent == &ici->dev) { + device_unregister(&icd->dev); + /* Not before device_unregister(), .remove + * needs parent to call ici->remove() */ + icd->dev.parent = NULL; + memset(&icd->dev.kobj, 0, sizeof(icd->dev.kobj)); + } + } + + mutex_unlock(&list_lock); + + device_unregister(&ici->dev); +} +EXPORT_SYMBOL(soc_camera_host_unregister); + +/* Image capture device */ +int soc_camera_device_register(struct soc_camera_device *icd) +{ + struct soc_camera_device *ix; + int num = -1, i; + + if (!icd) + return -EINVAL; + + for (i = 0; i < 256 && num < 0; i++) { + num = i; + list_for_each_entry(ix, &devices, list) { + if (ix->iface == icd->iface && ix->devnum == i) { + num = -1; + break; + } + } + } + + if (num < 0) + /* ok, we have 256 cameras on this host... + * man, stay reasonable... */ + return -ENOMEM; + + icd->devnum = num; + icd->dev.bus = &soc_camera_bus_type; + snprintf(icd->dev.bus_id, sizeof(icd->dev.bus_id), + "%u-%u", icd->iface, icd->devnum); + + icd->dev.release = dummy_release; + + if (icd->ops->get_datawidth) + icd->cached_datawidth = icd->ops->get_datawidth(icd); + + return scan_add_device(icd); +} +EXPORT_SYMBOL(soc_camera_device_register); + +void soc_camera_device_unregister(struct soc_camera_device *icd) +{ + mutex_lock(&list_lock); + list_del(&icd->list); + + /* The bus->remove will be eventually called */ + if (icd->dev.parent) + device_unregister(&icd->dev); + mutex_unlock(&list_lock); +} +EXPORT_SYMBOL(soc_camera_device_unregister); + +int soc_camera_video_start(struct soc_camera_device *icd) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + int err = -ENOMEM; + struct video_device *vdev; + + if (!icd->dev.parent) + return -ENODEV; + + vdev = video_device_alloc(); + if (!vdev) + goto evidallocd; + dev_dbg(&ici->dev, "Allocated video_device %p\n", vdev); + + strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name)); + /* Maybe better &ici->dev */ + vdev->dev = &icd->dev; + vdev->type = VID_TYPE_CAPTURE; + vdev->current_norm = V4L2_STD_UNKNOWN; + vdev->fops = &soc_camera_fops; + vdev->release = video_device_release; + vdev->minor = -1; + vdev->tvnorms = V4L2_STD_UNKNOWN, + vdev->vidioc_querycap = soc_camera_querycap; + vdev->vidioc_g_fmt_cap = soc_camera_g_fmt_cap; + vdev->vidioc_enum_fmt_cap = soc_camera_enum_fmt_cap; + vdev->vidioc_s_fmt_cap = soc_camera_s_fmt_cap; + vdev->vidioc_enum_input = soc_camera_enum_input; + vdev->vidioc_g_input = soc_camera_g_input; + vdev->vidioc_s_input = soc_camera_s_input; + vdev->vidioc_s_std = soc_camera_s_std; + vdev->vidioc_reqbufs = soc_camera_reqbufs; + vdev->vidioc_try_fmt_cap = soc_camera_try_fmt_cap; + vdev->vidioc_querybuf = soc_camera_querybuf; + vdev->vidioc_qbuf = soc_camera_qbuf; + vdev->vidioc_dqbuf = soc_camera_dqbuf; + vdev->vidioc_streamon = soc_camera_streamon; + vdev->vidioc_streamoff = soc_camera_streamoff; + vdev->vidioc_queryctrl = soc_camera_queryctrl; + vdev->vidioc_g_ctrl = soc_camera_g_ctrl; + vdev->vidioc_s_ctrl = soc_camera_s_ctrl; + vdev->vidioc_cropcap = soc_camera_cropcap; + vdev->vidioc_g_crop = soc_camera_g_crop; + vdev->vidioc_s_crop = soc_camera_s_crop; + vdev->vidioc_g_chip_ident = soc_camera_g_chip_ident; +#ifdef CONFIG_VIDEO_ADV_DEBUG + vdev->vidioc_g_register = soc_camera_g_register; + vdev->vidioc_s_register = soc_camera_s_register; +#endif + + icd->current_fmt = &icd->ops->formats[0]; + + err = video_register_device(vdev, VFL_TYPE_GRABBER, vdev->minor); + if (err < 0) { + dev_err(vdev->dev, "video_register_device failed\n"); + goto evidregd; + } + icd->vdev = vdev; + + return 0; + +evidregd: + video_device_release(vdev); +evidallocd: + return err; +} +EXPORT_SYMBOL(soc_camera_video_start); + +void soc_camera_video_stop(struct soc_camera_device *icd) +{ + struct video_device *vdev = icd->vdev; + + dev_dbg(&icd->dev, "%s\n", __FUNCTION__); + + if (!icd->dev.parent || !vdev) + return; + + mutex_lock(&video_lock); + video_unregister_device(vdev); + icd->vdev = NULL; + mutex_unlock(&video_lock); +} +EXPORT_SYMBOL(soc_camera_video_stop); + +static int __init soc_camera_init(void) +{ + int ret = bus_register(&soc_camera_bus_type); + if (ret) + return ret; + ret = driver_register(&ic_drv); + if (ret) + goto edrvr; + ret = class_register(&soc_camera_host_class); + if (ret) + goto eclr; + + return 0; + +eclr: + driver_unregister(&ic_drv); +edrvr: + bus_unregister(&soc_camera_bus_type); + return ret; +} + +static void __exit soc_camera_exit(void) +{ + class_unregister(&soc_camera_host_class); + driver_unregister(&ic_drv); + bus_unregister(&soc_camera_bus_type); +} + +module_init(soc_camera_init); +module_exit(soc_camera_exit); + +MODULE_DESCRIPTION("Image capture bus driver"); +MODULE_AUTHOR("Guennadi Liakhovetski "); +MODULE_LICENSE("GPL"); diff --git a/linux/include/media/soc_camera.h b/linux/include/media/soc_camera.h new file mode 100644 index 000000000..69aba7188 --- /dev/null +++ b/linux/include/media/soc_camera.h @@ -0,0 +1,147 @@ +/* + * camera image capture (abstract) bus driver header + * + * Copyright (C) 2006, Sascha Hauer, Pengutronix + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef SOC_CAMERA_H +#define SOC_CAMERA_H + +#include +#include + +struct soc_camera_device { + struct list_head list; + struct device dev; + struct device *control; + unsigned short width; /* Current window */ + unsigned short height; /* sizes */ + unsigned short x_min; /* Camera capabilities */ + unsigned short y_min; + unsigned short x_current; /* Current window location */ + unsigned short y_current; + unsigned short width_min; + unsigned short width_max; + unsigned short height_min; + unsigned short height_max; + unsigned short y_skip_top; /* Lines to skip at the top */ + unsigned short gain; + unsigned short exposure; + unsigned char iface; /* Host number */ + unsigned char devnum; /* Device number per host */ + unsigned char cached_datawidth; /* See comment in .c */ + struct soc_camera_ops *ops; + struct video_device *vdev; + const struct soc_camera_data_format *current_fmt; + int (*probe)(struct soc_camera_device *icd); + void (*remove)(struct soc_camera_device *icd); + struct module *owner; +}; + +struct soc_camera_file { + struct soc_camera_device *icd; + struct videobuf_queue vb_vidq; +}; + +struct soc_camera_host { + struct list_head list; + struct device dev; + unsigned char nr; /* Host number */ + size_t msize; + struct videobuf_queue_ops *vbq_ops; + struct module *owner; + void *priv; + char *drv_name; + int (*add)(struct soc_camera_device *); + void (*remove)(struct soc_camera_device *); + int (*set_capture_format)(struct soc_camera_device *, __u32, + struct v4l2_rect *); + int (*try_fmt_cap)(struct soc_camera_host *, struct v4l2_format *); + int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *); + int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); + unsigned int (*poll)(struct file *, poll_table *); +}; + +struct soc_camera_link { + /* Camera bus id, used to match a camera and a bus */ + int bus_id; + /* GPIO number to switch between 8 and 10 bit modes */ + unsigned int gpio; +}; + +static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev) +{ + return container_of(dev, struct soc_camera_device, dev); +} + +static inline struct soc_camera_host *to_soc_camera_host(struct device *dev) +{ + return container_of(dev, struct soc_camera_host, dev); +} + +extern int soc_camera_host_register(struct soc_camera_host *ici, + struct module *owner); +extern void soc_camera_host_unregister(struct soc_camera_host *ici); +extern int soc_camera_device_register(struct soc_camera_device *icd); +extern void soc_camera_device_unregister(struct soc_camera_device *icd); + +extern int soc_camera_video_start(struct soc_camera_device *icd); +extern void soc_camera_video_stop(struct soc_camera_device *icd); + +struct soc_camera_data_format { + char *name; + unsigned int depth; + __u32 fourcc; + enum v4l2_colorspace colorspace; +}; + +struct soc_camera_ops { + struct module *owner; + int (*init)(struct soc_camera_device *); + int (*release)(struct soc_camera_device *); + int (*start_capture)(struct soc_camera_device *); + int (*stop_capture)(struct soc_camera_device *); + int (*set_capture_format)(struct soc_camera_device *, __u32, + struct v4l2_rect *, unsigned int); + int (*try_fmt_cap)(struct soc_camera_device *, struct v4l2_format *); + int (*get_chip_id)(struct soc_camera_device *, + struct v4l2_chip_ident *); +#ifdef CONFIG_VIDEO_ADV_DEBUG + int (*get_register)(struct soc_camera_device *, struct v4l2_register *); + int (*set_register)(struct soc_camera_device *, struct v4l2_register *); +#endif + const struct soc_camera_data_format *formats; + int num_formats; + int (*get_control)(struct soc_camera_device *, struct v4l2_control *); + int (*set_control)(struct soc_camera_device *, struct v4l2_control *); + const struct v4l2_queryctrl *controls; + int num_controls; + unsigned int(*get_datawidth)(struct soc_camera_device *icd); +}; + +static inline struct v4l2_queryctrl const *soc_camera_find_qctrl( + struct soc_camera_ops *ops, int id) +{ + int i; + + for (i = 0; i < ops->num_controls; i++) + if (ops->controls[i].id == id) + return &ops->controls[i]; + + return NULL; +} + +#define IS_MASTER (1<<0) +#define IS_HSYNC_ACTIVE_HIGH (1<<1) +#define IS_VSYNC_ACTIVE_HIGH (1<<2) +#define IS_DATAWIDTH_8 (1<<3) +#define IS_DATAWIDTH_9 (1<<4) +#define IS_DATAWIDTH_10 (1<<5) +#define IS_PCLK_SAMPLE_RISING (1<<6) + +#endif -- cgit v1.2.3 From 5fa2b467c8f690078304940a302769c272842893 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 Feb 2008 11:39:11 -0200 Subject: Import pxa specific code, needed by pxa-camera driver From: Mauro Carvalho Chehab kernel-sync: Signed-off-by: Mauro Carvalho Chehab --- linux/arch/arm/mach-pxa/devices.c | 663 +++++++++ linux/include/asm-arm/arch-pxa/pxa-regs.h | 2134 +++++++++++++++++++++++++++++ 2 files changed, 2797 insertions(+) create mode 100644 linux/arch/arm/mach-pxa/devices.c create mode 100644 linux/include/asm-arm/arch-pxa/pxa-regs.h (limited to 'linux') diff --git a/linux/arch/arm/mach-pxa/devices.c b/linux/arch/arm/mach-pxa/devices.c new file mode 100644 index 000000000..bfccb80ac --- /dev/null +++ b/linux/arch/arm/mach-pxa/devices.c @@ -0,0 +1,663 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "devices.h" + +void __init pxa_register_device(struct platform_device *dev, void *data) +{ + int ret; + + dev->dev.platform_data = data; + + ret = platform_device_register(dev); + if (ret) + dev_err(&dev->dev, "unable to register device: %d\n", ret); +} + +static struct resource pxamci_resources[] = { + [0] = { + .start = 0x41100000, + .end = 0x41100fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MMC, + .end = IRQ_MMC, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = 21, + .end = 21, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = 22, + .end = 22, + .flags = IORESOURCE_DMA, + }, +}; + +static u64 pxamci_dmamask = 0xffffffffUL; + +struct platform_device pxa_device_mci = { + .name = "pxa2xx-mci", + .id = 0, + .dev = { + .dma_mask = &pxamci_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxamci_resources), + .resource = pxamci_resources, +}; + +void __init pxa_set_mci_info(struct pxamci_platform_data *info) +{ + pxa_register_device(&pxa_device_mci, info); +} + + +static struct pxa2xx_udc_mach_info pxa_udc_info; + +void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info) +{ + memcpy(&pxa_udc_info, info, sizeof *info); +} + +static struct resource pxa2xx_udc_resources[] = { + [0] = { + .start = 0x40600000, + .end = 0x4060ffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_USB, + .end = IRQ_USB, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 udc_dma_mask = ~(u32)0; + +struct platform_device pxa_device_udc = { + .name = "pxa2xx-udc", + .id = -1, + .resource = pxa2xx_udc_resources, + .num_resources = ARRAY_SIZE(pxa2xx_udc_resources), + .dev = { + .platform_data = &pxa_udc_info, + .dma_mask = &udc_dma_mask, + } +}; + +static struct resource pxafb_resources[] = { + [0] = { + .start = 0x44000000, + .end = 0x4400ffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_LCD, + .end = IRQ_LCD, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 fb_dma_mask = ~(u64)0; + +struct platform_device pxa_device_fb = { + .name = "pxa2xx-fb", + .id = -1, + .dev = { + .dma_mask = &fb_dma_mask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxafb_resources), + .resource = pxafb_resources, +}; + +void __init set_pxa_fb_info(struct pxafb_mach_info *info) +{ + pxa_register_device(&pxa_device_fb, info); +} + +void __init set_pxa_fb_parent(struct device *parent_dev) +{ + pxa_device_fb.dev.parent = parent_dev; +} + +static struct resource pxa_resource_ffuart[] = { + { + .start = __PREG(FFUART), + .end = __PREG(FFUART) + 35, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_FFUART, + .end = IRQ_FFUART, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device pxa_device_ffuart= { + .name = "pxa2xx-uart", + .id = 0, + .resource = pxa_resource_ffuart, + .num_resources = ARRAY_SIZE(pxa_resource_ffuart), +}; + +static struct resource pxa_resource_btuart[] = { + { + .start = __PREG(BTUART), + .end = __PREG(BTUART) + 35, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_BTUART, + .end = IRQ_BTUART, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device pxa_device_btuart = { + .name = "pxa2xx-uart", + .id = 1, + .resource = pxa_resource_btuart, + .num_resources = ARRAY_SIZE(pxa_resource_btuart), +}; + +static struct resource pxa_resource_stuart[] = { + { + .start = __PREG(STUART), + .end = __PREG(STUART) + 35, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_STUART, + .end = IRQ_STUART, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device pxa_device_stuart = { + .name = "pxa2xx-uart", + .id = 2, + .resource = pxa_resource_stuart, + .num_resources = ARRAY_SIZE(pxa_resource_stuart), +}; + +static struct resource pxa_resource_hwuart[] = { + { + .start = __PREG(HWUART), + .end = __PREG(HWUART) + 47, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_HWUART, + .end = IRQ_HWUART, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device pxa_device_hwuart = { + .name = "pxa2xx-uart", + .id = 3, + .resource = pxa_resource_hwuart, + .num_resources = ARRAY_SIZE(pxa_resource_hwuart), +}; + +static struct resource pxai2c_resources[] = { + { + .start = 0x40301680, + .end = 0x403016a3, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_I2C, + .end = IRQ_I2C, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device pxa_device_i2c = { + .name = "pxa2xx-i2c", + .id = 0, + .resource = pxai2c_resources, + .num_resources = ARRAY_SIZE(pxai2c_resources), +}; + +void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info) +{ + pxa_register_device(&pxa_device_i2c, info); +} + +static struct resource pxai2s_resources[] = { + { + .start = 0x40400000, + .end = 0x40400083, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_I2S, + .end = IRQ_I2S, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device pxa_device_i2s = { + .name = "pxa2xx-i2s", + .id = -1, + .resource = pxai2s_resources, + .num_resources = ARRAY_SIZE(pxai2s_resources), +}; + +static u64 pxaficp_dmamask = ~(u32)0; + +struct platform_device pxa_device_ficp = { + .name = "pxa2xx-ir", + .id = -1, + .dev = { + .dma_mask = &pxaficp_dmamask, + .coherent_dma_mask = 0xffffffff, + }, +}; + +void __init pxa_set_ficp_info(struct pxaficp_platform_data *info) +{ + pxa_register_device(&pxa_device_ficp, info); +} + +struct platform_device pxa_device_rtc = { + .name = "sa1100-rtc", + .id = -1, +}; + +#ifdef CONFIG_PXA25x + +static u64 pxa25x_ssp_dma_mask = DMA_BIT_MASK(32); + +static struct resource pxa25x_resource_ssp[] = { + [0] = { + .start = 0x41000000, + .end = 0x4100001f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_SSP, + .end = IRQ_SSP, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* DRCMR for RX */ + .start = 13, + .end = 13, + .flags = IORESOURCE_DMA, + }, + [3] = { + /* DRCMR for TX */ + .start = 14, + .end = 14, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device pxa25x_device_ssp = { + .name = "pxa25x-ssp", + .id = 0, + .dev = { + .dma_mask = &pxa25x_ssp_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = pxa25x_resource_ssp, + .num_resources = ARRAY_SIZE(pxa25x_resource_ssp), +}; + +static u64 pxa25x_nssp_dma_mask = DMA_BIT_MASK(32); + +static struct resource pxa25x_resource_nssp[] = { + [0] = { + .start = 0x41400000, + .end = 0x4140002f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_NSSP, + .end = IRQ_NSSP, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* DRCMR for RX */ + .start = 15, + .end = 15, + .flags = IORESOURCE_DMA, + }, + [3] = { + /* DRCMR for TX */ + .start = 16, + .end = 16, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device pxa25x_device_nssp = { + .name = "pxa25x-nssp", + .id = 1, + .dev = { + .dma_mask = &pxa25x_nssp_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = pxa25x_resource_nssp, + .num_resources = ARRAY_SIZE(pxa25x_resource_nssp), +}; + +static u64 pxa25x_assp_dma_mask = DMA_BIT_MASK(32); + +static struct resource pxa25x_resource_assp[] = { + [0] = { + .start = 0x41500000, + .end = 0x4150002f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_ASSP, + .end = IRQ_ASSP, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* DRCMR for RX */ + .start = 23, + .end = 23, + .flags = IORESOURCE_DMA, + }, + [3] = { + /* DRCMR for TX */ + .start = 24, + .end = 24, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device pxa25x_device_assp = { + /* ASSP is basically equivalent to NSSP */ + .name = "pxa25x-nssp", + .id = 2, + .dev = { + .dma_mask = &pxa25x_assp_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = pxa25x_resource_assp, + .num_resources = ARRAY_SIZE(pxa25x_resource_assp), +}; +#endif /* CONFIG_PXA25x */ + +#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) + +static u64 pxa27x_ohci_dma_mask = DMA_BIT_MASK(32); + +static struct resource pxa27x_resource_ohci[] = { + [0] = { + .start = 0x4C000000, + .end = 0x4C00ff6f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_USBH1, + .end = IRQ_USBH1, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device pxa27x_device_ohci = { + .name = "pxa27x-ohci", + .id = -1, + .dev = { + .dma_mask = &pxa27x_ohci_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(pxa27x_resource_ohci), + .resource = pxa27x_resource_ohci, +}; + +void __init pxa_set_ohci_info(struct pxaohci_platform_data *info) +{ + pxa_register_device(&pxa27x_device_ohci, info); +} + +static u64 pxa27x_ssp1_dma_mask = DMA_BIT_MASK(32); + +static struct resource pxa27x_resource_ssp1[] = { + [0] = { + .start = 0x41000000, + .end = 0x4100003f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_SSP, + .end = IRQ_SSP, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* DRCMR for RX */ + .start = 13, + .end = 13, + .flags = IORESOURCE_DMA, + }, + [3] = { + /* DRCMR for TX */ + .start = 14, + .end = 14, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device pxa27x_device_ssp1 = { + .name = "pxa27x-ssp", + .id = 0, + .dev = { + .dma_mask = &pxa27x_ssp1_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = pxa27x_resource_ssp1, + .num_resources = ARRAY_SIZE(pxa27x_resource_ssp1), +}; + +static u64 pxa27x_ssp2_dma_mask = DMA_BIT_MASK(32); + +static struct resource pxa27x_resource_ssp2[] = { + [0] = { + .start = 0x41700000, + .end = 0x4170003f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_SSP2, + .end = IRQ_SSP2, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* DRCMR for RX */ + .start = 15, + .end = 15, + .flags = IORESOURCE_DMA, + }, + [3] = { + /* DRCMR for TX */ + .start = 16, + .end = 16, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device pxa27x_device_ssp2 = { + .name = "pxa27x-ssp", + .id = 1, + .dev = { + .dma_mask = &pxa27x_ssp2_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = pxa27x_resource_ssp2, + .num_resources = ARRAY_SIZE(pxa27x_resource_ssp2), +}; + +static u64 pxa27x_ssp3_dma_mask = DMA_BIT_MASK(32); + +static struct resource pxa27x_resource_ssp3[] = { + [0] = { + .start = 0x41900000, + .end = 0x4190003f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_SSP3, + .end = IRQ_SSP3, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* DRCMR for RX */ + .start = 66, + .end = 66, + .flags = IORESOURCE_DMA, + }, + [3] = { + /* DRCMR for TX */ + .start = 67, + .end = 67, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device pxa27x_device_ssp3 = { + .name = "pxa27x-ssp", + .id = 2, + .dev = { + .dma_mask = &pxa27x_ssp3_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = pxa27x_resource_ssp3, + .num_resources = ARRAY_SIZE(pxa27x_resource_ssp3), +}; +#endif /* CONFIG_PXA27x || CONFIG_PXA3xx */ + +#ifdef CONFIG_PXA3xx +static u64 pxa3xx_ssp4_dma_mask = DMA_BIT_MASK(32); + +static struct resource pxa3xx_resource_ssp4[] = { + [0] = { + .start = 0x41a00000, + .end = 0x41a0003f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_SSP4, + .end = IRQ_SSP4, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* DRCMR for RX */ + .start = 2, + .end = 2, + .flags = IORESOURCE_DMA, + }, + [3] = { + /* DRCMR for TX */ + .start = 3, + .end = 3, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device pxa3xx_device_ssp4 = { + /* PXA3xx SSP is basically equivalent to PXA27x */ + .name = "pxa27x-ssp", + .id = 3, + .dev = { + .dma_mask = &pxa3xx_ssp4_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = pxa3xx_resource_ssp4, + .num_resources = ARRAY_SIZE(pxa3xx_resource_ssp4), +}; + +static struct resource pxa3xx_resources_mci2[] = { + [0] = { + .start = 0x42000000, + .end = 0x42000fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MMC2, + .end = IRQ_MMC2, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = 93, + .end = 93, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = 94, + .end = 94, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device pxa3xx_device_mci2 = { + .name = "pxa2xx-mci", + .id = 1, + .dev = { + .dma_mask = &pxamci_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxa3xx_resources_mci2), + .resource = pxa3xx_resources_mci2, +}; + +void __init pxa3xx_set_mci2_info(struct pxamci_platform_data *info) +{ + pxa_register_device(&pxa3xx_device_mci2, info); +} + +static struct resource pxa3xx_resources_mci3[] = { + [0] = { + .start = 0x42500000, + .end = 0x42500fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MMC3, + .end = IRQ_MMC3, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = 100, + .end = 100, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = 101, + .end = 101, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device pxa3xx_device_mci3 = { + .name = "pxa2xx-mci", + .id = 2, + .dev = { + .dma_mask = &pxamci_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxa3xx_resources_mci3), + .resource = pxa3xx_resources_mci3, +}; + +void __init pxa3xx_set_mci3_info(struct pxamci_platform_data *info) +{ + pxa_register_device(&pxa3xx_device_mci3, info); +} + +#endif /* CONFIG_PXA3xx */ diff --git a/linux/include/asm-arm/arch-pxa/pxa-regs.h b/linux/include/asm-arm/arch-pxa/pxa-regs.h new file mode 100644 index 000000000..16ed24dbd --- /dev/null +++ b/linux/include/asm-arm/arch-pxa/pxa-regs.h @@ -0,0 +1,2134 @@ +/* + * linux/include/asm-arm/arch-pxa/pxa-regs.h + * + * Author: Nicolas Pitre + * Created: Jun 15, 2001 + * Copyright: MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __PXA_REGS_H +#define __PXA_REGS_H + + +/* + * PXA Chip selects + */ + +#define PXA_CS0_PHYS 0x00000000 +#define PXA_CS1_PHYS 0x04000000 +#define PXA_CS2_PHYS 0x08000000 +#define PXA_CS3_PHYS 0x0C000000 +#define PXA_CS4_PHYS 0x10000000 +#define PXA_CS5_PHYS 0x14000000 + + +/* + * Personal Computer Memory Card International Association (PCMCIA) sockets + */ + +#define PCMCIAPrtSp 0x04000000 /* PCMCIA Partition Space [byte] */ +#define PCMCIASp (4*PCMCIAPrtSp) /* PCMCIA Space [byte] */ +#define PCMCIAIOSp PCMCIAPrtSp /* PCMCIA I/O Space [byte] */ +#define PCMCIAAttrSp PCMCIAPrtSp /* PCMCIA Attribute Space [byte] */ +#define PCMCIAMemSp PCMCIAPrtSp /* PCMCIA Memory Space [byte] */ + +#define PCMCIA0Sp PCMCIASp /* PCMCIA 0 Space [byte] */ +#define PCMCIA0IOSp PCMCIAIOSp /* PCMCIA 0 I/O Space [byte] */ +#define PCMCIA0AttrSp PCMCIAAttrSp /* PCMCIA 0 Attribute Space [byte] */ +#define PCMCIA0MemSp PCMCIAMemSp /* PCMCIA 0 Memory Space [byte] */ + +#define PCMCIA1Sp PCMCIASp /* PCMCIA 1 Space [byte] */ +#define PCMCIA1IOSp PCMCIAIOSp /* PCMCIA 1 I/O Space [byte] */ +#define PCMCIA1AttrSp PCMCIAAttrSp /* PCMCIA 1 Attribute Space [byte] */ +#define PCMCIA1MemSp PCMCIAMemSp /* PCMCIA 1 Memory Space [byte] */ + +#define _PCMCIA(Nb) /* PCMCIA [0..1] */ \ + (0x20000000 + (Nb)*PCMCIASp) +#define _PCMCIAIO(Nb) _PCMCIA (Nb) /* PCMCIA I/O [0..1] */ +#define _PCMCIAAttr(Nb) /* PCMCIA Attribute [0..1] */ \ + (_PCMCIA (Nb) + 2*PCMCIAPrtSp) +#define _PCMCIAMem(Nb) /* PCMCIA Memory [0..1] */ \ + (_PCMCIA (Nb) + 3*PCMCIAPrtSp) + +#define _PCMCIA0 _PCMCIA (0) /* PCMCIA 0 */ +#define _PCMCIA0IO _PCMCIAIO (0) /* PCMCIA 0 I/O */ +#define _PCMCIA0Attr _PCMCIAAttr (0) /* PCMCIA 0 Attribute */ +#define _PCMCIA0Mem _PCMCIAMem (0) /* PCMCIA 0 Memory */ + +#define _PCMCIA1 _PCMCIA (1) /* PCMCIA 1 */ +#define _PCMCIA1IO _PCMCIAIO (1) /* PCMCIA 1 I/O */ +#define _PCMCIA1Attr _PCMCIAAttr (1) /* PCMCIA 1 Attribute */ +#define _PCMCIA1Mem _PCMCIAMem (1) /* PCMCIA 1 Memory */ + + + +/* + * DMA Controller + */ + +#define DCSR0 __REG(0x40000000) /* DMA Control / Status Register for Channel 0 */ +#define DCSR1 __REG(0x40000004) /* DMA Control / Status Register for Channel 1 */ +#define DCSR2 __REG(0x40000008) /* DMA Control / Status Register for Channel 2 */ +#define DCSR3 __REG(0x4000000c) /* DMA Control / Status Register for Channel 3 */ +#define DCSR4 __REG(0x40000010) /* DMA Control / Status Register for Channel 4 */ +#define DCSR5 __REG(0x40000014) /* DMA Control / Status Register for Channel 5 */ +#define DCSR6 __REG(0x40000018) /* DMA Control / Status Register for Channel 6 */ +#define DCSR7 __REG(0x4000001c) /* DMA Control / Status Register for Channel 7 */ +#define DCSR8 __REG(0x40000020) /* DMA Control / Status Register for Channel 8 */ +#define DCSR9 __REG(0x40000024) /* DMA Control / Status Register for Channel 9 */ +#define DCSR10 __REG(0x40000028) /* DMA Control / Status Register for Channel 10 */ +#define DCSR11 __REG(0x4000002c) /* DMA Control / Status Register for Channel 11 */ +#define DCSR12 __REG(0x40000030) /* DMA Control / Status Register for Channel 12 */ +#define DCSR13 __REG(0x40000034) /* DMA Control / Status Register for Channel 13 */ +#define DCSR14 __REG(0x40000038) /* DMA Control / Status Register for Channel 14 */ +#define DCSR15 __REG(0x4000003c) /* DMA Control / Status Register for Channel 15 */ + +#define DCSR(x) __REG2(0x40000000, (x) << 2) + +#define DCSR_RUN (1 << 31) /* Run Bit (read / write) */ +#define DCSR_NODESC (1 << 30) /* No-Descriptor Fetch (read / write) */ +#define DCSR_STOPIRQEN (1 << 29) /* Stop Interrupt Enable (read / write) */ +#ifdef CONFIG_PXA27x +#define DCSR_EORIRQEN (1 << 28) /* End of Receive Interrupt Enable (R/W) */ +#define DCSR_EORJMPEN (1 << 27) /* Jump to next descriptor on EOR */ +#define DCSR_EORSTOPEN (1 << 26) /* STOP on an EOR */ +#define DCSR_SETCMPST (1 << 25) /* Set Descriptor Compare Status */ +#define DCSR_CLRCMPST (1 << 24) /* Clear Descriptor Compare Status */ +#define DCSR_CMPST (1 << 10) /* The Descriptor Compare Status */ +#define DCSR_EORINTR (1 << 9) /* The end of Receive */ +#endif +#define DCSR_REQPEND (1 << 8) /* Request Pending (read-only) */ +#define DCSR_STOPSTATE (1 << 3) /* Stop State (read-only) */ +#define DCSR_ENDINTR (1 << 2) /* End Interrupt (read / write) */ +#define DCSR_STARTINTR (1 << 1) /* Start Interrupt (read / write) */ +#define DCSR_BUSERR (1 << 0) /* Bus Error Interrupt (read / write) */ + +#define DALGN __REG(0x400000a0) /* DMA Alignment Register */ +#define DINT __REG(0x400000f0) /* DMA Interrupt Register */ + +#define DRCMR(n) (*(((n) < 64) ? \ + &__REG2(0x40000100, ((n) & 0x3f) << 2) : \ + &__REG2(0x40001100, ((n) & 0x3f) << 2))) + +#define DRCMR0 __REG(0x40000100) /* Request to Channel Map Register for DREQ 0 */ +#define DRCMR1 __REG(0x40000104) /* Request to Channel Map Register for DREQ 1 */ +#define DRCMR2 __REG(0x40000108) /* Request to Channel Map Register for I2S receive Request */ +#define DRCMR3 __REG(0x4000010c) /* Request to Channel Map Register for I2S transmit Request */ +#define DRCMR4 __REG(0x40000110) /* Request to Channel Map Register for BTUART receive Request */ +#define DRCMR5 __REG(0x40000114) /* Request to Channel Map Register for BTUART transmit Request. */ +#define DRCMR6 __REG(0x40000118) /* Request to Channel Map Register for FFUART receive Request */ +#define DRCMR7 __REG(0x4000011c) /* Request to Channel Map Register for FFUART transmit Request */ +#define DRCMR8 __REG(0x40000120) /* Request to Channel Map Register for AC97 microphone Request */ +#define DRCMR9 __REG(0x40000124) /* Request to Channel Map Register for AC97 modem receive Request */ +#define DRCMR10 __REG(0x40000128) /* Request to Channel Map Register for AC97 modem transmit Request */ +#define DRCMR11 __REG(0x4000012c) /* Request to Channel Map Register for AC97 audio receive Request */ +#define DRCMR12 __REG(0x40000130) /* Request to Channel Map Register for AC97 audio transmit Request */ +#define DRCMR13 __REG(0x40000134) /* Request to Channel Map Register for SSP receive Request */ +#define DRCMR14 __REG(0x40000138) /* Request to Channel Map Register for SSP transmit Request */ +#define DRCMR15 __REG(0x4000013c) /* Request to Channel Map Register for SSP2 receive Request */ +#define DRCMR16 __REG(0x40000140) /* Request to Channel Map Register for SSP2 transmit Request */ +#define DRCMR17 __REG(0x40000144) /* Request to Channel Map Register for ICP receive Request */ +#define DRCMR18 __REG(0x40000148) /* Request to Channel Map Register for ICP transmit Request */ +#define DRCMR19 __REG(0x4000014c) /* Request to Channel Map Register for STUART receive Request */ +#define DRCMR20 __REG(0x40000150) /* Request to Channel Map Register for STUART transmit Request */ +#define DRCMR21 __REG(0x40000154) /* Request to Channel Map Register for MMC receive Request */ +#define DRCMR22 __REG(0x40000158) /* Request to Channel Map Register for MMC transmit Request */ +#define DRCMR23 __REG(0x4000015c) /* Reserved */ +#define DRCMR24 __REG(0x40000160) /* Reserved */ +#define DRCMR25 __REG(0x40000164) /* Request to Channel Map Register for USB endpoint 1 Request */ +#define DRCMR26 __REG(0x40000168) /* Request to Channel Map Register for USB endpoint 2 Request */ +#define DRCMR27 __REG(0x4000016C) /* Request to Channel Map Register for USB endpoint 3 Request */ +#define DRCMR28 __REG(0x40000170) /* Request to Channel Map Register for USB endpoint 4 Request */ +#define DRCMR29 __REG(0x40000174) /* Reserved */ +#define DRCMR30 __REG(0x40000178) /* Request to Channel Map Register for USB endpoint 6 Request */ +#define DRCMR31 __REG(0x4000017C) /* Request to Channel Map Register for USB endpoint 7 Request */ +#define DRCMR32 __REG(0x40000180) /* Request to Channel Map Register for USB endpoint 8 Request */ +#define DRCMR33 __REG(0x40000184) /* Request to Channel Map Register for USB endpoint 9 Request */ +#define DRCMR34 __REG(0x40000188) /* Reserved */ +#define DRCMR35 __REG(0x4000018C) /* Request to Channel Map Register for USB endpoint 11 Request */ +#define DRCMR36 __REG(0x40000190) /* Request to Channel Map Register for USB endpoint 12 Request */ +#define DRCMR37 __REG(0x40000194) /* Request to Channel Map Register for USB endpoint 13 Request */ +#define DRCMR38 __REG(0x40000198) /* Request to Channel Map Register for USB endpoint 14 Request */ +#define DRCMR39 __REG(0x4000019C) /* Reserved */ +#define DRCMR66 __REG(0x40001108) /* Request to Channel Map Register for SSP3 receive Request */ +#define DRCMR67 __REG(0x4000110C) /* Request to Channel Map Register for SSP3 transmit Request */ +#define DRCMR68 __REG(0x40001110) /* Request to Channel Map Register for Camera FIFO 0 Request */ +#define DRCMR69 __REG(0x40001114) /* Request to Channel Map Register for Camera FIFO 1 Request */ +#define DRCMR70 __REG(0x40001118) /* Request to Channel Map Register for Camera FIFO 2 Request */ + +#define DRCMRRXSADR DRCMR2 +#define DRCMRTXSADR DRCMR3 +#define DRCMRRXBTRBR DRCMR4 +#define DRCMRTXBTTHR DRCMR5 +#define DRCMRRXFFRBR DRCMR6 +#define DRCMRTXFFTHR DRCMR7 +#define DRCMRRXMCDR DRCMR8 +#define DRCMRRXMODR DRCMR9 +#define DRCMRTXMODR DRCMR10 +#define DRCMRRXPCDR DRCMR11 +#define DRCMRTXPCDR DRCMR12 +#define DRCMRRXSSDR DRCMR13 +#define DRCMRTXSSDR DRCMR14 +#define DRCMRRXSS2DR DRCMR15 +#define DRCMRTXSS2DR DRCMR16 +#define DRCMRRXICDR DRCMR17 +#define DRCMRTXICDR DRCMR18 +#define DRCMRRXSTRBR DRCMR19 +#define DRCMRTXSTTHR DRCMR20 +#define DRCMRRXMMC DRCMR21 +#define DRCMRTXMMC DRCMR22 +#define DRCMRRXSS3DR DRCMR66 +#define DRCMRTXSS3DR DRCMR67 +#define DRCMRUDC(x) DRCMR((x) + 24) + +#define DRCMR_MAPVLD (1 << 7) /* Map Valid (read / write) */ +#define DRCMR_CHLNUM 0x1f /* mask for Channel Number (read / write) */ + +#define DDADR0 __REG(0x40000200) /* DMA Descriptor Address Register Channel 0 */ +#define DSADR0 __REG(0x40000204) /* DMA Source Address Register Channel 0 */ +#define DTADR0 __REG(0x40000208) /* DMA Target Address Register Channel 0 */ +#define DCMD0 __REG(0x4000020c) /* DMA Command Address Register Channel 0 */ +#define DDADR1 __REG(0x40000210) /* DMA Descriptor Address Register Channel 1 */ +#define DSADR1 __REG(0x40000214) /* DMA Source Address Register Channel 1 */ +#define DTADR1 __REG(0x40000218) /* DMA Target Address Register Channel 1 */ +#define DCMD1 __REG(0x4000021c) /* DMA Command Address Register Channel 1 */ +#define DDADR2 __REG(0x40000220) /* DMA Descriptor Address Register Channel 2 */ +#define DSADR2 __REG(0x40000224) /* DMA Source Address Register Channel 2 */ +#define DTADR2 __REG(0x40000228) /* DMA Target Address Register Channel 2 */ +#define DCMD2 __REG(0x4000022c) /* DMA Command Address Register Channel 2 */ +#define DDADR3 __REG(0x40000230) /* DMA Descriptor Address Register Channel 3 */ +#define DSADR3 __REG(0x40000234) /* DMA Source Address Register Channel 3 */ +#define DTADR3 __REG(0x40000238) /* DMA Target Address Register Channel 3 */ +#define DCMD3 __REG(0x4000023c) /* DMA Command Address Register Channel 3 */ +#define DDADR4 __REG(0x40000240) /* DMA Descriptor Address Register Channel 4 */ +#define DSADR4 __REG(0x40000244) /* DMA Source Address Register Channel 4 */ +#define DTADR4 __REG(0x40000248) /* DMA Target Address Register Channel 4 */ +#define DCMD4 __REG(0x4000024c) /* DMA Command Address Register Channel 4 */ +#define DDADR5 __REG(0x40000250) /* DMA Descriptor Address Register Channel 5 */ +#define DSADR5 __REG(0x40000254) /* DMA Source Address Register Channel 5 */ +#define DTADR5 __REG(0x40000258) /* DMA Target Address Register Channel 5 */ +#define DCMD5 __REG(0x4000025c) /* DMA Command Address Register Channel 5 */ +#define DDADR6 __REG(0x40000260) /* DMA Descriptor Address Register Channel 6 */ +#define DSADR6 __REG(0x40000264) /* DMA Source Address Register Channel 6 */ +#define DTADR6 __REG(0x40000268) /* DMA Target Address Register Channel 6 */ +#define DCMD6 __REG(0x4000026c) /* DMA Command Address Register Channel 6 */ +#define DDADR7 __REG(0x40000270) /* DMA Descriptor Address Register Channel 7 */ +#define DSADR7 __REG(0x40000274) /* DMA Source Address Register Channel 7 */ +#define DTADR7 __REG(0x40000278) /* DMA Target Address Register Channel 7 */ +#define DCMD7 __REG(0x4000027c) /* DMA Command Address Register Channel 7 */ +#define DDADR8 __REG(0x40000280) /* DMA Descriptor Address Register Channel 8 */ +#define DSADR8 __REG(0x40000284) /* DMA Source Address Register Channel 8 */ +#define DTADR8 __REG(0x40000288) /* DMA Target Address Register Channel 8 */ +#define DCMD8 __REG(0x4000028c) /* DMA Command Address Register Channel 8 */ +#define DDADR9 __REG(0x40000290) /* DMA Descriptor Address Register Channel 9 */ +#define DSADR9 __REG(0x40000294) /* DMA Source Address Register Channel 9 */ +#define DTADR9 __REG(0x40000298) /* DMA Target Address Register Channel 9 */ +#define DCMD9 __REG(0x4000029c) /* DMA Command Address Register Channel 9 */ +#define DDADR10 __REG(0x400002a0) /* DMA Descriptor Address Register Channel 10 */ +#define DSADR10 __REG(0x400002a4) /* DMA Source Address Register Channel 10 */ +#define DTADR10 __REG(0x400002a8) /* DMA Target Address Register Channel 10 */ +#define DCMD10 __REG(0x400002ac) /* DMA Command Address Register Channel 10 */ +#define DDADR11 __REG(0x400002b0) /* DMA Descriptor Address Register Channel 11 */ +#define DSADR11 __REG(0x400002b4) /* DMA Source Address Register Channel 11 */ +#define DTADR11 __REG(0x400002b8) /* DMA Target Address Register Channel 11 */ +#define DCMD11 __REG(0x400002bc) /* DMA Command Address Register Channel 11 */ +#define DDADR12 __REG(0x400002c0) /* DMA Descriptor Address Register Channel 12 */ +#define DSADR12 __REG(0x400002c4) /* DMA Source Address Register Channel 12 */ +#define DTADR12 __REG(0x400002c8) /* DMA Target Address Register Channel 12 */ +#define DCMD12 __REG(0x400002cc) /* DMA Command Address Register Channel 12 */ +#define DDADR13 __REG(0x400002d0) /* DMA Descriptor Address Register Channel 13 */ +#define DSADR13 __REG(0x400002d4) /* DMA Source Address Register Channel 13 */ +#define DTADR13 __REG(0x400002d8) /* DMA Target Address Register Channel 13 */ +#define DCMD13 __REG(0x400002dc) /* DMA Command Address Register Channel 13 */ +#define DDADR14 __REG(0x400002e0) /* DMA Descriptor Address Register Channel 14 */ +#define DSADR14 __REG(0x400002e4) /* DMA Source Address Register Channel 14 */ +#define DTADR14 __REG(0x400002e8) /* DMA Target Address Register Channel 14 */ +#define DCMD14 __REG(0x400002ec) /* DMA Command Address Register Channel 14 */ +#define DDADR15 __REG(0x400002f0) /* DMA Descriptor Address Register Channel 15 */ +#define DSADR15 __REG(0x400002f4) /* DMA Source Address Register Channel 15 */ +#define DTADR15 __REG(0x400002f8) /* DMA Target Address Register Channel 15 */ +#define DCMD15 __REG(0x400002fc) /* DMA Command Address Register Channel 15 */ + +#define DDADR(x) __REG2(0x40000200, (x) << 4) +#define DSADR(x) __REG2(0x40000204, (x) << 4) +#define DTADR(x) __REG2(0x40000208, (x) << 4) +#define DCMD(x) __REG2(0x4000020c, (x) << 4) + +#define DDADR_DESCADDR 0xfffffff0 /* Address of next descriptor (mask) */ +#define DDADR_STOP (1 << 0) /* Stop (read / write) */ + +#define DCMD_INCSRCADDR (1 << 31) /* Source Address Increment Setting. */ +#define DCMD_INCTRGADDR (1 << 30) /* Target Address Increment Setting. */ +#define DCMD_FLOWSRC (1 << 29) /* Flow Control by the source. */ +#define DCMD_FLOWTRG (1 << 28) /* Flow Control by the target. */ +#define DCMD_STARTIRQEN (1 << 22) /* Start Interrupt Enable */ +#define DCMD_ENDIRQEN (1 << 21) /* End Interrupt Enable */ +#define DCMD_ENDIAN (1 << 18) /* Device Endian-ness. */ +#define DCMD_BURST8 (1 << 16) /* 8 byte burst */ +#define DCMD_BURST16 (2 << 16) /* 16 byte burst */ +#define DCMD_BURST32 (3 << 16) /* 32 byte burst */ +#define DCMD_WIDTH1 (1 << 14) /* 1 byte width */ +#define DCMD_WIDTH2 (2 << 14) /* 2 byte width (HalfWord) */ +#define DCMD_WIDTH4 (3 << 14) /* 4 byte width (Word) */ +#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */ + + +/* + * UARTs + */ + +/* Full Function UART (FFUART) */ +#define FFUART FFRBR +#define FFRBR __REG(0x40100000) /* Receive Buffer Register (read only) */ +#define FFTHR __REG(0x40100000) /* Transmit Holding Register (write only) */ +#define FFIER __REG(0x40100004) /* Interrupt Enable Register (read/write) */ +#define FFIIR __REG(0x40100008) /* Interrupt ID Register (read only) */ +#define FFFCR __REG(0x40100008) /* FIFO Control Register (write only) */ +#define FFLCR __REG(0x4010000C) /* Line Control Register (read/write) */ +#define FFMCR __REG(0x40100010) /* Modem Control Register (read/write) */ +#define FFLSR __REG(0x40100014) /* Line Status Register (read only) */ +#define FFMSR __REG(0x40100018) /* Modem Status Register (read only) */ +#define FFSPR __REG(0x4010001C) /* Scratch Pad Register (read/write) */ +#define FFISR __REG(0x40100020) /* Infrared Selection Register (read/write) */ +#define FFDLL __REG(0x40100000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */ +#define FFDLH __REG(0x40100004) /* Divisor Latch High Register (DLAB = 1) (read/write) */ + +/* Bluetooth UART (BTUART) */ +#define BTUART BTRBR +#define BTRBR __REG(0x40200000) /* Receive Buffer Register (read only) */ +#define BTTHR __REG(0x40200000) /* Transmit Holding Register (write only) */ +#define BTIER __REG(0x40200004) /* Interrupt Enable Register (read/write) */ +#define BTIIR __REG(0x40200008) /* Interrupt ID Register (read only) */ +#define BTFCR __REG(0x40200008) /* FIFO Control Register (write only) */ +#define BTLCR __REG(0x4020000C) /* Line Control Register (read/write) */ +#define BTMCR __REG(0x40200010) /* Modem Control Register (read/write) */ +#define BTLSR __REG(0x40200014) /* Line Status Register (read only) */ +#define BTMSR __REG(0x40200018) /* Modem Status Register (read only) */ +#define BTSPR __REG(0x4020001C) /* Scratch Pad Register (read/write) */ +#define BTISR __REG(0x40200020) /* Infrared Selection Register (read/write) */ +#define BTDLL __REG(0x40200000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */ +#define BTDLH __REG(0x40200004) /* Divisor Latch High Register (DLAB = 1) (read/write) */ + +/* Standard UART (STUART) */ +#define STUART STRBR +#define STRBR __REG(0x40700000) /* Receive Buffer Register (read only) */ +#define STTHR __REG(0x40700000) /* Transmit Holding Register (write only) */ +#define STIER __REG(0x40700004) /* Interrupt Enable Register (read/write) */ +#define STIIR __REG(0x40700008) /* Interrupt ID Register (read only) */ +#define STFCR __REG(0x40700008) /* FIFO Control Register (write only) */ +#define STLCR __REG(0x4070000C) /* Line Control Register (read/write) */ +#define STMCR __REG(0x40700010) /* Modem Control Register (read/write) */ +#define STLSR __REG(0x40700014) /* Line Status Register (read only) */ +#define STMSR __REG(0x40700018) /* Reserved */ +#define STSPR __REG(0x4070001C) /* Scratch Pad Register (read/write) */ +#define STISR __REG(0x40700020) /* Infrared Selection Register (read/write) */ +#define STDLL __REG(0x40700000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */ +#define STDLH __REG(0x40700004) /* Divisor Latch High Register (DLAB = 1) (read/write) */ + +/* Hardware UART (HWUART) */ +#define HWUART HWRBR +#define HWRBR __REG(0x41600000) /* Receive Buffer Register (read only) */ +#define HWTHR __REG(0x41600000) /* Transmit Holding Register (write only) */ +#define HWIER __REG(0x41600004) /* Interrupt Enable Register (read/write) */ +#define HWIIR __REG(0x41600008) /* Interrupt ID Register (read only) */ +#define HWFCR __REG(0x41600008) /* FIFO Control Register (write only) */ +#define HWLCR __REG(0x4160000C) /* Line Control Register (read/write) */ +#define HWMCR __REG(0x41600010) /* Modem Control Register (read/write) */ +#define HWLSR __REG(0x41600014) /* Line Status Register (read only) */ +#define HWMSR __REG(0x41600018) /* Modem Status Register (read only) */ +#define HWSPR __REG(0x4160001C) /* Scratch Pad Register (read/write) */ +#define HWISR __REG(0x41600020) /* Infrared Selection Register (read/write) */ +#define HWFOR __REG(0x41600024) /* Receive FIFO Occupancy Register (read only) */ +#define HWABR __REG(0x41600028) /* Auto-Baud Control Register (read/write) */ +#define HWACR __REG(0x4160002C) /* Auto-Baud Count Register (read only) */ +#define HWDLL __REG(0x41600000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */ +#define HWDLH __REG(0x41600004) /* Divisor Latch High Register (DLAB = 1) (read/write) */ + +#define IER_DMAE (1 << 7) /* DMA Requests Enable */ +#define IER_UUE (1 << 6) /* UART Unit Enable */ +#define IER_NRZE (1 << 5) /* NRZ coding Enable */ +#define IER_RTIOE (1 << 4) /* Receiver Time Out Interrupt Enable */ +#define IER_MIE (1 << 3) /* Modem Interrupt Enable */ +#define IER_RLSE (1 << 2) /* Receiver Line Status Interrupt Enable */ +#define IER_TIE (1 << 1) /* Transmit Data request Interrupt Enable */ +#define IER_RAVIE (1 << 0) /* Receiver Data Available Interrupt Enable */ + +#define IIR_FIFOES1 (1 << 7) /* FIFO Mode Enable Status */ +#define IIR_FIFOES0 (1 << 6) /* FIFO Mode Enable Status */ +#define IIR_TOD (1 << 3) /* Time Out Detected */ +#define IIR_IID2 (1 << 2) /* Interrupt Source Encoded */ +#define IIR_IID1 (1 << 1) /* Interrupt Source Encoded */ +#define IIR_IP (1 << 0) /* Interrupt Pending (active low) */ + +#define FCR_ITL2 (1 << 7) /* Interrupt Trigger Level */ +#define FCR_ITL1 (1 << 6) /* Interrupt Trigger Level */ +#define FCR_RESETTF (1 << 2) /* Reset Transmitter FIFO */ +#define FCR_RESETRF (1 << 1) /* Reset Receiver FIFO */ +#define FCR_TRFIFOE (1 << 0) /* Transmit and Receive FIFO Enable */ +#define FCR_ITL_1 (0) +#define FCR_ITL_8 (FCR_ITL1) +#define FCR_ITL_16 (FCR_ITL2) +#define FCR_ITL_32 (FCR_ITL2|FCR_ITL1) + +#define LCR_DLAB (1 << 7) /* Divisor Latch Access Bit */ +#define LCR_SB (1 << 6) /* Set Break */ +#define LCR_STKYP (1 << 5) /* Sticky Parity */ +#define LCR_EPS (1 << 4) /* Even Parity Select */ +#define LCR_PEN (1 << 3) /* Parity Enable */ +#define LCR_STB (1 << 2) /* Stop Bit */ +#define LCR_WLS1 (1 << 1) /* Word Length Select */ +#define LCR_WLS0 (1 << 0) /* Word Length Select */ + +#define LSR_FIFOE (1 << 7) /* FIFO Error Status */ +#define LSR_TEMT (1 << 6) /* Transmitter Empty */ +#define LSR_TDRQ (1 << 5) /* Transmit Data Request */ +#define LSR_BI (1 << 4) /* Break Interrupt */ +#define LSR_FE (1 << 3) /* Framing Error */ +#define LSR_PE (1 << 2) /* Parity Error */ +#define LSR_OE (1 << 1) /* Overrun Error */ +#define LSR_DR (1 << 0) /* Data Ready */ + +#define MCR_LOOP (1 << 4) +#define MCR_OUT2 (1 << 3) /* force MSR_DCD in loopback mode */ +#define MCR_OUT1 (1 << 2) /* force MSR_RI in loopback mode */ +#define MCR_RTS (1 << 1) /* Request to Send */ +#define MCR_DTR (1 << 0) /* Data Terminal Ready */ + +#define MSR_DCD (1 << 7) /* Data Carrier Detect */ +#define MSR_RI (1 << 6) /* Ring Indicator */ +#define MSR_DSR (1 << 5) /* Data Set Ready */ +#define MSR_CTS (1 << 4) /* Clear To Send */ +#define MSR_DDCD (1 << 3) /* Delta Data Carrier Detect */ +#define MSR_TERI (1 << 2) /* Trailing Edge Ring Indicator */ +#define MSR_DDSR (1 << 1) /* Delta Data Set Ready */ +#define MSR_DCTS (1 << 0) /* Delta Clear To Send */ + +/* + * IrSR (Infrared Selection Register) + */ +#define STISR_RXPL (1 << 4) /* Receive Data Polarity */ +#define STISR_TXPL (1 << 3) /* Transmit Data Polarity */ +#define STISR_XMODE (1 << 2) /* Transmit Pulse Width Select */ +#define STISR_RCVEIR (1 << 1) /* Receiver SIR Enable */ +#define STISR_XMITIR (1 << 0) /* Transmitter SIR Enable */ + + +/* + * I2C registers + */ + +#define IBMR __REG(0x40301680) /* I2C Bus Monitor Register - IBMR */ +#define IDBR __REG(0x40301688) /* I2C Data Buffer Register - IDBR */ +#define ICR __REG(0x40301690) /* I2C Control Register - ICR */ +#define ISR __REG(0x40301698) /* I2C Status Register - ISR */ +#define ISAR __REG(0x403016A0) /* I2C Slave Address Register - ISAR */ + +#define PWRIBMR __REG(0x40f00180) /* Power I2C Bus Monitor Register-IBMR */ +#define PWRIDBR __REG(0x40f00188) /* Power I2C Data Buffer Register-IDBR */ +#define PWRICR __REG(0x40f00190) /* Power I2C Control Register - ICR */ +#define PWRISR __REG(0x40f00198) /* Power I2C Status Register - ISR */ +#define PWRISAR __REG(0x40f001A0) /*Power I2C Slave Address Register-ISAR */ + +#define ICR_START (1 << 0) /* start bit */ +#define ICR_STOP (1 << 1) /* stop bit */ +#define ICR_ACKNAK (1 << 2) /* send ACK(0) or NAK(1) */ +#define ICR_TB (1 << 3) /* transfer byte bit */ +#define ICR_MA (1 << 4) /* master abort */ +#define ICR_SCLE (1 << 5) /* master clock enable */ +#define ICR_IUE (1 << 6) /* unit enable */ +#define ICR_GCD (1 << 7) /* general call disable */ +#define ICR_ITEIE (1 << 8) /* enable tx interrupts */ +#define ICR_IRFIE (1 << 9) /* enable rx interrupts */ +#define ICR_BEIE (1 << 10) /* enable bus error ints */ +#define ICR_SSDIE (1 << 11) /* slave STOP detected int enable */ +#define ICR_ALDIE (1 << 12) /* enable arbitration interrupt */ +#define ICR_SADIE (1 << 13) /* slave address detected int enable */ +#define ICR_UR (1 << 14) /* unit reset */ + +#define ISR_RWM (1 << 0) /* read/write mode */ +#define ISR_ACKNAK (1 << 1) /* ack/nak status */ +#define ISR_UB (1 << 2) /* unit busy */ +#define ISR_IBB (1 << 3) /* bus busy */ +#define ISR_SSD (1 << 4) /* slave stop detected */ +#define ISR_ALD (1 << 5) /* arbitration loss detected */ +#define ISR_ITE (1 << 6) /* tx buffer empty */ +#define ISR_IRF (1 << 7) /* rx buffer full */ +#define ISR_GCAD (1 << 8) /* general call address detected */ +#define ISR_SAD (1 << 9) /* slave address detected */ +#define ISR_BED (1 << 10) /* bus error no ACK/NAK */ + + +/* + * Serial Audio Controller + */ + +#define SACR0 __REG(0x40400000) /* Global Control Register */ +#define SACR1 __REG(0x40400004) /* Serial Audio I 2 S/MSB-Justified Control Register */ +#define SASR0 __REG(0x4040000C) /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */ +#define SAIMR __REG(0x40400014) /* Serial Audio Interrupt Mask Register */ +#define SAICR __REG(0x40400018) /* Serial Audio Interrupt Clear Register */ +#define SADIV __REG(0x40400060) /* Audio Clock Divider Register. */ +#define SADR __REG(0x40400080) /* Serial Audio Data Register (TX and RX FIFO access Register). */ + +#define SACR0_RFTH(x) ((x) << 12) /* Rx FIFO Interrupt or DMA Trigger Threshold */ +#define SACR0_TFTH(x) ((x) << 8) /* Tx FIFO Interrupt or DMA Trigger Threshold */ +#define SACR0_STRF (1 << 5) /* FIFO Select for EFWR Special Function */ +#define SACR0_EFWR (1 << 4) /* Enable EFWR Function */ +#define SACR0_RST (1 << 3) /* FIFO, i2s Register Reset */ +#define SACR0_BCKD (1 << 2) /* Bit Clock Direction */ +#define SACR0_ENB (1 << 0) /* Enable I2S Link */ +#define SACR1_ENLBF (1 << 5) /* Enable Loopback */ +#define SACR1_DRPL (1 << 4) /* Disable Replaying Function */ +#define SACR1_DREC (1 << 3) /* Disable Recording Function */ +#define SACR1_AMSL (1 << 0) /* Specify Alternate Mode */ + +#define SASR0_I2SOFF (1 << 7) /* Controller Status */ +#define SASR0_ROR (1 << 6) /* Rx FIFO Overrun */ +#define SASR0_TUR (1 << 5) /* Tx FIFO Underrun */ +#define SASR0_RFS (1 << 4) /* Rx FIFO Service Request */ +#define SASR0_TFS (1 << 3) /* Tx FIFO Service Request */ +#define SASR0_BSY (1 << 2) /* I2S Busy */ +#define SASR0_RNE (1 << 1) /* Rx FIFO Not Empty */ +#define SASR0_TNF (1 << 0) /* Tx FIFO Not Empty */ + +#define SAICR_ROR (1 << 6) /* Clear Rx FIFO Overrun Interrupt */ +#define SAICR_TUR (1 << 5) /* Clear Tx FIFO Underrun Interrupt */ + +#define SAIMR_ROR (1 << 6) /* Enable Rx FIFO Overrun Condition Interrupt */ +#define SAIMR_TUR (1 << 5) /* Enable Tx FIFO Underrun Condition Interrupt */ +#define SAIMR_RFS (1 << 4) /* Enable Rx FIFO Service Interrupt */ +#define SAIMR_TFS (1 << 3) /* Enable Tx FIFO Service Interrupt */ + +/* + * AC97 Controller registers + */ + +#define POCR __REG(0x40500000) /* PCM Out Control Register */ +#define POCR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */ +#define POCR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */ + +#define PICR __REG(0x40500004) /* PCM In Control Register */ +#define PICR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */ +#define PICR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */ + +#define MCCR __REG(0x40500008) /* Mic In Control Register */ +#define MCCR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */ +#define MCCR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */ + +#define GCR __REG(0x4050000C) /* Global Control Register */ +#define GCR_nDMAEN (1 << 24) /* non DMA Enable */ +#define GCR_CDONE_IE (1 << 19) /* Command Done Interrupt Enable */ +#define GCR_SDONE_IE (1 << 18) /* Status Done Interrupt Enable */ +#define GCR_SECRDY_IEN (1 << 9) /* Secondary Ready Interrupt Enable */ +#define GCR_PRIRDY_IEN (1 << 8) /* Primary Ready Interrupt Enable */ +#define GCR_SECRES_IEN (1 << 5) /* Secondary Resume Interrupt Enable */ +#define GCR_PRIRES_IEN (1 << 4) /* Primary Resume Interrupt Enable */ +#define GCR_ACLINK_OFF (1 << 3) /* AC-link Shut Off */ +#define GCR_WARM_RST (1 << 2) /* AC97 Warm Reset */ +#define GCR_COLD_RST (1 << 1) /* AC'97 Cold Reset (0 = active) */ +#define GCR_GIE (1 << 0) /* Codec GPI Interrupt Enable */ + +#define POSR __REG(0x40500010) /* PCM Out Status Register */ +#define POSR_FIFOE (1 << 4) /* FIFO error */ +#define POSR_FSR (1 << 2) /* FIFO Service Request */ + +#define PISR __REG(0x40500014) /* PCM In Status Register */ +#define PISR_FIFOE (1 << 4) /* FIFO error */ +#define PISR_EOC (1 << 3) /* DMA End-of-Chain (exclusive clear) */ +#define PISR_FSR (1 << 2) /* FIFO Service Request */ + +#define MCSR __REG(0x40500018) /* Mic In Status Register */ +#define MCSR_FIFOE (1 << 4) /* FIFO error */ +#define MCSR_EOC (1 << 3) /* DMA End-of-Chain (exclusive clear) */ +#define MCSR_FSR (1 << 2) /* FIFO Service Request */ + +#define GSR __REG(0x4050001C) /* Global Status Register */ +#define GSR_CDONE (1 << 19) /* Command Done */ +#define GSR_SDONE (1 << 18) /* Status Done */ +#define GSR_RDCS (1 << 15) /* Read Completion Status */ +#define GSR_BIT3SLT12 (1 << 14) /* Bit 3 of slot 12 */ +#define GSR_BIT2SLT12 (1 << 13) /* Bit 2 of slot 12 */ +#define GSR_BIT1SLT12 (1 << 12) /* Bit 1 of slot 12 */ +#define GSR_SECRES (1 << 11) /* Secondary Resume Interrupt */ +#define GSR_PRIRES (1 << 10) /* Primary Resume Interrupt */ +#define GSR_SCR (1 << 9) /* Secondary Codec Ready */ +#define GSR_PCR (1 << 8) /* Primary Codec Ready */ +#define GSR_MCINT (1 << 7) /* Mic In Interrupt */ +#define GSR_POINT (1 << 6) /* PCM Out Interrupt */ +#define GSR_PIINT (1 << 5) /* PCM In Interrupt */ +#define GSR_ACOFFD (1 << 3) /* AC-link Shut Off Done */ +#define GSR_MOINT (1 << 2) /* Modem Out Interrupt */ +#define GSR_MIINT (1 << 1) /* Modem In Interrupt */ +#define GSR_GSCI (1 << 0) /* Codec GPI Status Change Interrupt */ + +#define CAR __REG(0x40500020) /* CODEC Access Register */ +#define CAR_CAIP (1 << 0) /* Codec Access In Progress */ + +#define PCDR __REG(0x40500040) /* PCM FIFO Data Register */ +#define MCDR __REG(0x40500060) /* Mic-in FIFO Data Register */ + +#define MOCR __REG(0x40500100) /* Modem Out Control Register */ +#define MOCR_FEIE (1 << 3) /* FIFO Error */ +#define MOCR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */ + +#define MICR __REG(0x40500108) /* Modem In Control Register */ +#define MICR_FEIE (1 << 3) /* FIFO Error */ +#define MICR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */ + +#define MOSR __REG(0x40500110) /* Modem Out Status Register */ +#define MOSR_FIFOE (1 << 4) /* FIFO error */ +#define MOSR_FSR (1 << 2) /* FIFO Service Request */ + +#define MISR __REG(0x40500118) /* Modem In Status Register */ +#define MISR_FIFOE (1 << 4) /* FIFO error */ +#define MISR_EOC (1 << 3) /* DMA End-of-Chain (exclusive clear) */ +#define MISR_FSR (1 << 2) /* FIFO Service Request */ + +#define MODR __REG(0x40500140) /* Modem FIFO Data Register */ + +#define PAC_REG_BASE __REG(0x40500200) /* Primary Audio Codec */ +#define SAC_REG_BASE __REG(0x40500300) /* Secondary Audio Codec */ +#define PMC_REG_BASE __REG(0x40500400) /* Primary Modem Codec */ +#define SMC_REG_BASE __REG(0x40500500) /* Secondary Modem Codec */ + + +/* + * USB Device Controller + * PXA25x and PXA27x USB device controller registers are different. + */ +#if defined(CONFIG_PXA25x) + +#define UDC_RES1 __REG(0x40600004) /* UDC Undocumented - Reserved1 */ +#define UDC_RES2 __REG(0x40600008) /* UDC Undocumented - Reserved2 */ +#define UDC_RES3 __REG(0x4060000C) /* UDC Undocumented - Reserved3 */ + +#define UDCCR __REG(0x40600000) /* UDC Control Register */ +#define UDCCR_UDE (1 << 0) /* UDC enable */ +#define UDCCR_UDA (1 << 1) /* UDC active */ +#define UDCCR_RSM (1 << 2) /* Device resume */ +#define UDCCR_RESIR (1 << 3) /* Resume interrupt request */ +#define UDCCR_SUSIR (1 << 4) /* Suspend interrupt request */ +#define UDCCR_SRM (1 << 5) /* Suspend/resume interrupt mask */ +#define UDCCR_RSTIR (1 << 6) /* Reset interrupt request */ +#define UDCCR_REM (1 << 7) /* Reset interrupt mask */ + +#define UDCCS0 __REG(0x40600010) /* UDC Endpoint 0 Control/Status Register */ +#define UDCCS0_OPR (1 << 0) /* OUT packet ready */ +#define UDCCS0_IPR (1 << 1) /* IN packet ready */ +#define UDCCS0_FTF (1 << 2) /* Flush Tx FIFO */ +#define UDCCS0_DRWF (1 << 3) /* Device remote wakeup feature */ +#define UDCCS0_SST (1 << 4) /* Sent stall */ +#define UDCCS0_FST (1 << 5) /* Force stall */ +#define UDCCS0_RNE (1 << 6) /* Receive FIFO no empty */ +#define UDCCS0_SA (1 << 7) /* Setup active */ + +/* Bulk IN - Endpoint 1,6,11 */ +#define UDCCS1 __REG(0x40600014) /* UDC Endpoint 1 (IN) Control/Status Register */ +#define UDCCS6 __REG(0x40600028) /* UDC Endpoint 6 (IN) Control/Status Register */ +#define UDCCS11 __REG(0x4060003C) /* UDC Endpoint 11 (IN) Control/Status Register */ + +#define UDCCS_BI_TFS (1 << 0) /* Transmit FIFO service */ +#define UDCCS_BI_TPC (1 << 1) /* Transmit packet complete */ +#define UDCCS_BI_FTF (1 << 2) /* Flush Tx FIFO */ +#define UDCCS_BI_TUR (1 << 3) /* Transmit FIFO underrun */ +#define UDCCS_BI_SST (1 << 4) /* Sent stall */ +#define UDCCS_BI_FST (1 << 5) /* Force stall */ +#define UDCCS_BI_TSP (1 << 7) /* Transmit short packet */ + +/* Bulk OUT - Endpoint 2,7,12 */ +#define UDCCS2 __REG(0x40600018) /* UDC Endpoint 2 (OUT) Control/Status Register */ +#define UDCCS7 __REG(0x4060002C) /* UDC Endpoint 7 (OUT) Control/Status Register */ +#define UDCCS12 __REG(0x40600040) /* UDC Endpoint 12 (OUT) Control/Status Register */ + +#define UDCCS_BO_RFS (1 << 0) /* Receive FIFO service */ +#define UDCCS_BO_RPC (1 << 1) /* Receive packet complete */ +#define UDCCS_BO_DME (1 << 3) /* DMA enable */ +#define UDCCS_BO_SST (1 << 4) /* Sent stall */ +#define UDCCS_BO_FST (1 << 5) /* Force stall */ +#define UDCCS_BO_RNE (1 << 6) /* Receive FIFO not empty */ +#define UDCCS_BO_RSP (1 << 7) /* Receive short packet */ + +/* Isochronous IN - Endpoint 3,8,13 */ +#define UDCCS3 __REG(0x4060001C) /* UDC Endpoint 3 (IN) Control/Status Register */ +#define UDCCS8 __REG(0x40600030) /* UDC Endpoint 8 (IN) Control/Status Register */ +#define UDCCS13 __REG(0x40600044) /* UDC Endpoint 13 (IN) Control/Status Register */ + +#define UDCCS_II_TFS (1 << 0) /* Transmit FIFO service */ +#define UDCCS_II_TPC (1 << 1) /* Transmit packet complete */ +#define UDCCS_II_FTF (1 << 2) /* Flush Tx FIFO */ +#define UDCCS_II_TUR (1 << 3) /* Transmit FIFO underrun */ +#define UDCCS_II_TSP (1 << 7) /* Transmit short packet */ + +/* Isochronous OUT - Endpoint 4,9,14 */ +#define UDCCS4 __REG(0x40600020) /* UDC Endpoint 4 (OUT) Control/Status Register */ +#define UDCCS9 __REG(0x40600034) /* UDC Endpoint 9 (OUT) Control/Status Register */ +#define UDCCS14 __REG(0x40600048) /* UDC Endpoint 14 (OUT) Control/Status Register */ + +#define UDCCS_IO_RFS (1 << 0) /* Receive FIFO service */ +#define UDCCS_IO_RPC (1 << 1) /* Receive packet complete */ +#define UDCCS_IO_ROF (1 << 2) /* Receive overflow */ +#define UDCCS_IO_DME (1 << 3) /* DMA enable */ +#define UDCCS_IO_RNE (1 << 6) /* Receive FIFO not empty */ +#define UDCCS_IO_RSP (1 << 7) /* Receive short packet */ + +/* Interrupt IN - Endpoint 5,10,15 */ +#define UDCCS5 __REG(0x40600024) /* UDC Endpoint 5 (Interrupt) Control/Status Register */ +#define UDCCS10 __REG(0x40600038) /* UDC Endpoint 10 (Interrupt) Control/Status Register */ +#define UDCCS15 __REG(0x4060004C) /* UDC Endpoint 15 (Interrupt) Control/Status Register */ + +#define UDCCS_INT_TFS (1 << 0) /* Transmit FIFO service */ +#define UDCCS_INT_TPC (1 << 1) /* Transmit packet complete */ +#define UDCCS_INT_FTF (1 << 2) /* Flush Tx FIFO */ +#define UDCCS_INT_TUR (1 << 3) /* Transmit FIFO underrun */ +#define UDCCS_INT_SST (1 << 4) /* Sent stall */ +#define UDCCS_INT_FST (1 << 5) /* Force stall */ +#define UDCCS_INT_TSP (1 << 7) /* Transmit short packet */ + +#define UFNRH __REG(0x40600060) /* UDC Frame Number Register High */ +#define UFNRL __REG(0x40600064) /* UDC Frame Number Register Low */ +#define UBCR2 __REG(0x40600068) /* UDC Byte Count Reg 2 */ +#define UBCR4 __REG(0x4060006c) /* UDC Byte Count Reg 4 */ +#define UBCR7 __REG(0x40600070) /* UDC Byte Count Reg 7 */ +#define UBCR9 __REG(0x40600074) /* UDC Byte Count Reg 9 */ +#define UBCR12 __REG(0x40600078) /* UDC Byte Count Reg 12 */ +#define UBCR14 __REG(0x4060007c) /* UDC Byte Count Reg 14 */ +#define UDDR0 __REG(0x40600080) /* UDC Endpoint 0 Data Register */ +#define UDDR1 __REG(0x40600100) /* UDC Endpoint 1 Data Register */ +#define UDDR2 __REG(0x40600180) /* UDC Endpoint 2 Data Register */ +#define UDDR3 __REG(0x40600200) /* UDC Endpoint 3 Data Register */ +#define UDDR4 __REG(0x40600400) /* UDC Endpoint 4 Data Register */ +#define UDDR5 __REG(0x406000A0) /* UDC Endpoint 5 Data Register */ +#define UDDR6 __REG(0x40600600) /* UDC Endpoint 6 Data Register */ +#define UDDR7 __REG(0x40600680) /* UDC Endpoint 7 Data Register */ +#define UDDR8 __REG(0x40600700) /* UDC Endpoint 8 Data Register */ +#define UDDR9 __REG(0x40600900) /* UDC Endpoint 9 Data Register */ +#define UDDR10 __REG(0x406000C0) /* UDC Endpoint 10 Data Register */ +#define UDDR11 __REG(0x40600B00) /* UDC Endpoint 11 Data Register */ +#define UDDR12 __REG(0x40600B80) /* UDC Endpoint 12 Data Register */ +#define UDDR13 __REG(0x40600C00) /* UDC Endpoint 13 Data Register */ +#define UDDR14 __REG(0x40600E00) /* UDC Endpoint 14 Data Register */ +#define UDDR15 __REG(0x406000E0) /* UDC Endpoint 15 Data Register */ + +#define UICR0 __REG(0x40600050) /* UDC Interrupt Control Register 0 */ + +#define UICR0_IM0 (1 << 0) /* Interrupt mask ep 0 */ +#define UICR0_IM1 (1 << 1) /* Interrupt mask ep 1 */ +#define UICR0_IM2 (1 << 2) /* Interrupt mask ep 2 */ +#define UICR0_IM3 (1 << 3) /* Interrupt mask ep 3 */ +#define UICR0_IM4 (1 << 4) /* Interrupt mask ep 4 */ +#define UICR0_IM5 (1 << 5) /* Interrupt mask ep 5 */ +#define UICR0_IM6 (1 << 6) /* Interrupt mask ep 6 */ +#define UICR0_IM7 (1 << 7) /* Interrupt mask ep 7 */ + +#define UICR1 __REG(0x40600054) /* UDC Interrupt Control Register 1 */ + +#define UICR1_IM8 (1 << 0) /* Interrupt mask ep 8 */ +#define UICR1_IM9 (1 << 1) /* Interrupt mask ep 9 */ +#define UICR1_IM10 (1 << 2) /* Interrupt mask ep 10 */ +#define UICR1_IM11 (1 << 3) /* Interrupt mask ep 11 */ +#define UICR1_IM12 (1 << 4) /* Interrupt mask ep 12 */ +#define UICR1_IM13 (1 << 5) /* Interrupt mask ep 13 */ +#define UICR1_IM14 (1 << 6) /* Interrupt mask ep 14 */ +#define UICR1_IM15 (1 << 7) /* Interrupt mask ep 15 */ + +#define USIR0 __REG(0x40600058) /* UDC Status Interrupt Register 0 */ + +#define USIR0_IR0 (1 << 0) /* Interrupt request ep 0 */ +#define USIR0_IR1 (1 << 1) /* Interrupt request ep 1 */ +#define USIR0_IR2 (1 << 2) /* Interrupt request ep 2 */ +#define USIR0_IR3 (1 << 3) /* Interrupt request ep 3 */ +#define USIR0_IR4 (1 << 4) /* Interrupt request ep 4 */ +#define USIR0_IR5 (1 << 5) /* Interrupt request ep 5 */ +#define USIR0_IR6 (1 << 6) /* Interrupt request ep 6 */ +#define USIR0_IR7 (1 << 7) /* Interrupt request ep 7 */ + +#define USIR1 __REG(0x4060005C) /* UDC Status Interrupt Register 1 */ + +#define USIR1_IR8 (1 << 0) /* Interrupt request ep 8 */ +#define USIR1_IR9 (1 << 1) /* Interrupt request ep 9 */ +#define USIR1_IR10 (1 << 2) /* Interrupt request ep 10 */ +#define USIR1_IR11 (1 << 3) /* Interrupt request ep 11 */ +#define USIR1_IR12 (1 << 4) /* Interrupt request ep 12 */ +#define USIR1_IR13 (1 << 5) /* Interrupt request ep 13 */ +#define USIR1_IR14 (1 << 6) /* Interrupt request ep 14 */ +#define USIR1_IR15 (1 << 7) /* Interrupt request ep 15 */ + +#elif defined(CONFIG_PXA27x) + +#define UDCCR __REG(0x40600000) /* UDC Control Register */ +#define UDCCR_OEN (1 << 31) /* On-the-Go Enable */ +#define UDCCR_AALTHNP (1 << 30) /* A-device Alternate Host Negotiation + Protocol Port Support */ +#define UDCCR_AHNP (1 << 29) /* A-device Host Negotiation Protocol + Support */ +#define UDCCR_BHNP (1 << 28) /* B-device Host Negotiation Protocol + Enable */ +#define UDCCR_DWRE (1 << 16) /* Device Remote Wake-up Enable */ +#define UDCCR_ACN (0x03 << 11) /* Active UDC configuration Number */ +#define UDCCR_ACN_S 11 +#define UDCCR_AIN (0x07 << 8) /* Active UDC interface Number */ +#define UDCCR_AIN_S 8 +#define UDCCR_AAISN (0x07 << 5) /* Active UDC Alternate Interface + Setting Number */ +#define UDCCR_AAISN_S 5 +#define UDCCR_SMAC (1 << 4) /* Switch Endpoint Memory to Active + Configuration */ +#define UDCCR_EMCE (1 << 3) /* Endpoint Memory Configuration + Error */ +#define UDCCR_UDR (1 << 2) /* UDC Resume */ +#define UDCCR_UDA (1 << 1) /* UDC Active */ +#define UDCCR_UDE (1 << 0) /* UDC Enable */ + +#define UDCICR0 __REG(0x40600004) /* UDC Interrupt Control Register0 */ +#define UDCICR1 __REG(0x40600008) /* UDC Interrupt Control Register1 */ +#define UDCICR_FIFOERR (1 << 1) /* FIFO Error interrupt for EP */ +#define UDCICR_PKTCOMPL (1 << 0) /* Packet Complete interrupt for EP */ + +#define UDC_INT_FIFOERROR (0x2) +#define UDC_INT_PACKETCMP (0x1) + +#define UDCICR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) +#define UDCICR1_IECC (1 << 31) /* IntEn - Configuration Change */ +#define UDCICR1_IESOF (1 << 30) /* IntEn - Start of Frame */ +#define UDCICR1_IERU (1 << 29) /* IntEn - Resume */ +#define UDCICR1_IESU (1 << 28) /* IntEn - Suspend */ +#define UDCICR1_IERS (1 << 27) /* IntEn - Reset */ + +#define UDCISR0 __REG(0x4060000C) /* UDC Interrupt Status Register 0 */ +#define UDCISR1 __REG(0x40600010) /* UDC Interrupt Status Register 1 */ +#define UDCISR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) +#define UDCISR1_IRCC (1 << 31) /* IntReq - Configuration Change */ +#define UDCISR1_IRSOF (1 << 30) /* IntReq - Start of Frame */ +#define UDCISR1_IRRU (1 << 29) /* IntReq - Resume */ +#define UDCISR1_IRSU (1 << 28) /* IntReq - Suspend */ +#define UDCISR1_IRRS (1 << 27) /* IntReq - Reset */ + +#define UDCFNR __REG(0x40600014) /* UDC Frame Number Register */ +#define UDCOTGICR __REG(0x40600018) /* UDC On-The-Go interrupt control */ +#define UDCOTGICR_IESF (1 << 24) /* OTG SET_FEATURE command recvd */ +#define UDCOTGICR_IEXR (1 << 17) /* Extra Transciever Interrupt + Rising Edge Interrupt Enable */ +#define UDCOTGICR_IEXF (1 << 16) /* Extra Transciever Interrupt + Falling Edge Interrupt Enable */ +#define UDCOTGICR_IEVV40R (1 << 9) /* OTG Vbus Valid 4.0V Rising Edge + Interrupt Enable */ +#define UDCOTGICR_IEVV40F (1 << 8) /* OTG Vbus Valid 4.0V Falling Edge + Interrupt Enable */ +#define UDCOTGICR_IEVV44R (1 << 7) /* OTG Vbus Valid 4.4V Rising Edge + Interrupt Enable */ +#define UDCOTGICR_IEVV44F (1 << 6) /* OTG Vbus Valid 4.4V Falling Edge + Interrupt Enable */ +#define UDCOTGICR_IESVR (1 << 5) /* OTG Session Valid Rising Edge + Interrupt Enable */ +#define UDCOTGICR_IESVF (1 << 4) /* OTG Session Valid Falling Edge + Interrupt Enable */ +#define UDCOTGICR_IESDR (1 << 3) /* OTG A-Device SRP Detect Rising + Edge Interrupt Enable */ +#define UDCOTGICR_IESDF (1 << 2) /* OTG A-Device SRP Detect Falling + Edge Interrupt Enable */ +#define UDCOTGICR_IEIDR (1 << 1) /* OTG ID Change Rising Edge + Interrupt Enable */ +#define UDCOTGICR_IEIDF (1 << 0) /* OTG ID Change Falling Edge + Interrupt Enable */ + +#define UP2OCR __REG(0x40600020) /* USB Port 2 Output Control register */ + +#define UP2OCR_CPVEN (1 << 0) /* Charge Pump Vbus Enable */ +#define UP2OCR_CPVPE (1 << 1) /* Charge Pump Vbus Pulse Enable */ +#define UP2OCR_DPPDE (1 << 2) /* Host Port 2 Transceiver D+ Pull Down Enable */ +#define UP2OCR_DMPDE (1 << 3) /* Host Port 2 Transceiver D- Pull Down Enable */ +#define UP2OCR_DPPUE (1 << 4) /* Host Port 2 Transceiver D+ Pull Up Enable */ +#define UP2OCR_DMPUE (1 << 5) /* Host Port 2 Transceiver D- Pull Up Enable */ +#define UP2OCR_DPPUBE (1 << 6) /* Host Port 2 Transceiver D+ Pull Up Bypass Enable */ +#define UP2OCR_DMPUBE (1 << 7) /* Host Port 2 Transceiver D- Pull Up Bypass Enable */ +#define UP2OCR_EXSP (1 << 8) /* External Transceiver Speed Control */ +#define UP2OCR_EXSUS (1 << 9) /* External Transceiver Speed Enable */ +#define UP2OCR_IDON (1 << 10) /* OTG ID Read Enable */ +#define UP2OCR_HXS (1 << 16) /* Host Port 2 Transceiver Output Select */ +#define UP2OCR_HXOE (1 << 17) /* Host Port 2 Transceiver Output Enable */ +#define UP2OCR_SEOS (1 << 24) /* Single-Ended Output Select */ + +#define UDCCSN(x) __REG2(0x40600100, (x) << 2) +#define UDCCSR0 __REG(0x40600100) /* UDC Control/Status register - Endpoint 0 */ +#define UDCCSR0_SA (1 << 7) /* Setup Active */ +#define UDCCSR0_RNE (1 << 6) /* Receive FIFO Not Empty */ +#define UDCCSR0_FST (1 << 5) /* Force Stall */ +#define UDCCSR0_SST (1 << 4) /* Sent Stall */ +#define UDCCSR0_DME (1 << 3) /* DMA Enable */ +#define UDCCSR0_FTF (1 << 2) /* Flush Transmit FIFO */ +#define UDCCSR0_IPR (1 << 1) /* IN Packet Ready */ +#define UDCCSR0_OPC (1 << 0) /* OUT Packet Complete */ + +#define UDCCSRA __REG(0x40600104) /* UDC Control/Status register - Endpoint A */ +#define UDCCSRB __REG(0x40600108) /* UDC Control/Status register - Endpoint B */ +#define UDCCSRC __REG(0x4060010C) /* UDC Control/Status register - Endpoint C */ +#define UDCCSRD __REG(0x40600110) /* UDC Control/Status register - Endpoint D */ +#define UDCCSRE __REG(0x40600114) /* UDC Control/Status register - Endpoint E */ +#define UDCCSRF __REG(0x40600118) /* UDC Control/Status register - Endpoint F */ +#define UDCCSRG __REG(0x4060011C) /* UDC Control/Status register - Endpoint G */ +#define UDCCSRH __REG(0x40600120) /* UDC Control/Status register - Endpoint H */ +#define UDCCSRI __REG(0x40600124) /* UDC Control/Status register - Endpoint I */ +#define UDCCSRJ __REG(0x40600128) /* UDC Control/Status register - Endpoint J */ +#define UDCCSRK __REG(0x4060012C) /* UDC Control/Status register - Endpoint K */ +#define UDCCSRL __REG(0x40600130) /* UDC Control/Status register - Endpoint L */ +#define UDCCSRM __REG(0x40600134) /* UDC Control/Status register - Endpoint M */ +#define UDCCSRN __REG(0x40600138) /* UDC Control/Status register - Endpoint N */ +#define UDCCSRP __REG(0x4060013C) /* UDC Control/Status register - Endpoint P */ +#define UDCCSRQ __REG(0x40600140) /* UDC Control/Status register - Endpoint Q */ +#define UDCCSRR __REG(0x40600144) /* UDC Control/Status register - Endpoint R */ +#define UDCCSRS __REG(0x40600148) /* UDC Control/Status register - Endpoint S */ +#define UDCCSRT __REG(0x4060014C) /* UDC Control/Status register - Endpoint T */ +#define UDCCSRU __REG(0x40600150) /* UDC Control/Status register - Endpoint U */ +#define UDCCSRV __REG(0x40600154) /* UDC Control/Status register - Endpoint V */ +#define UDCCSRW __REG(0x40600158) /* UDC Control/Status register - Endpoint W */ +#define UDCCSRX __REG(0x4060015C) /* UDC Control/Status register - Endpoint X */ + +#define UDCCSR_DPE (1 << 9) /* Data Packet Error */ +#define UDCCSR_FEF (1 << 8) /* Flush Endpoint FIFO */ +#define UDCCSR_SP (1 << 7) /* Short Packet Control/Status */ +#define UDCCSR_BNE (1 << 6) /* Buffer Not Empty (IN endpoints) */ +#define UDCCSR_BNF (1 << 6) /* Buffer Not Full (OUT endpoints) */ +#define UDCCSR_FST (1 << 5) /* Force STALL */ +#define UDCCSR_SST (1 << 4) /* Sent STALL */ +#define UDCCSR_DME (1 << 3) /* DMA Enable */ +#define UDCCSR_TRN (1 << 2) /* Tx/Rx NAK */ +#define UDCCSR_PC (1 << 1) /* Packet Complete */ +#define UDCCSR_FS (1 << 0) /* FIFO needs service */ + +#define UDCBCN(x) __REG2(0x40600200, (x)<<2) +#define UDCBCR0 __REG(0x40600200) /* Byte Count Register - EP0 */ +#define UDCBCRA __REG(0x40600204) /* Byte Count Register - EPA */ +#define UDCBCRB __REG(0x40600208) /* Byte Count Register - EPB */ +#define UDCBCRC __REG(0x4060020C) /* Byte Count Register - EPC */ +#define UDCBCRD __REG(0x40600210) /* Byte Count Register - EPD */ +#define UDCBCRE __REG(0x40600214) /* Byte Count Register - EPE */ +#define UDCBCRF __REG(0x40600218) /* Byte Count Register - EPF */ +#define UDCBCRG __REG(0x4060021C) /* Byte Count Register - EPG */ +#define UDCBCRH __REG(0x40600220) /* Byte Count Register - EPH */ +#define UDCBCRI __REG(0x40600224) /* Byte Count Register - EPI */ +#define UDCBCRJ __REG(0x40600228) /* Byte Count Register - EPJ */ +#define UDCBCRK __REG(0x4060022C) /* Byte Count Register - EPK */ +#define UDCBCRL __REG(0x40600230) /* Byte Count Register - EPL */ +#define UDCBCRM __REG(0x40600234) /* Byte Count Register - EPM */ +#define UDCBCRN __REG(0x40600238) /* Byte Count Register - EPN */ +#define UDCBCRP __REG(0x4060023C) /* Byte Count Register - EPP */ +#define UDCBCRQ __REG(0x40600240) /* Byte Count Register - EPQ */ +#define UDCBCRR __REG(0x40600244) /* Byte Count Register - EPR */ +#define UDCBCRS __REG(0x40600248) /* Byte Count Register - EPS */ +#define UDCBCRT __REG(0x4060024C) /* Byte Count Register - EPT */ +#define UDCBCRU __REG(0x40600250) /* Byte Count Register - EPU */ +#define UDCBCRV __REG(0x40600254) /* Byte Count Register - EPV */ +#define UDCBCRW __REG(0x40600258) /* Byte Count Register - EPW */ +#define UDCBCRX __REG(0x4060025C) /* Byte Count Register - EPX */ + +#define UDCDN(x) __REG2(0x40600300, (x)<<2) +#define PHYS_UDCDN(x) (0x40600300 + ((x)<<2)) +#define PUDCDN(x) (volatile u32 *)(io_p2v(PHYS_UDCDN((x)))) +#define UDCDR0 __REG(0x40600300) /* Data Register - EP0 */ +#define UDCDRA __REG(0x40600304) /* Data Register - EPA */ +#define UDCDRB __REG(0x40600308) /* Data Register - EPB */ +#define UDCDRC __REG(0x4060030C) /* Data Register - EPC */ +#define UDCDRD __REG(0x40600310) /* Data Register - EPD */ +#define UDCDRE __REG(0x40600314) /* Data Register - EPE */ +#define UDCDRF __REG(0x40600318) /* Data Register - EPF */ +#define UDCDRG __REG(0x4060031C) /* Data Register - EPG */ +#define UDCDRH __REG(0x40600320) /* Data Register - EPH */ +#define UDCDRI __REG(0x40600324) /* Data Register - EPI */ +#define UDCDRJ __REG(0x40600328) /* Data Register - EPJ */ +#define UDCDRK __REG(0x4060032C) /* Data Register - EPK */ +#define UDCDRL __REG(0x40600330) /* Data Register - EPL */ +#define UDCDRM __REG(0x40600334) /* Data Register - EPM */ +#define UDCDRN __REG(0x40600338) /* Data Register - EPN */ +#define UDCDRP __REG(0x4060033C) /* Data Register - EPP */ +#define UDCDRQ __REG(0x40600340) /* Data Register - EPQ */ +#define UDCDRR __REG(0x40600344) /* Data Register - EPR */ +#define UDCDRS __REG(0x40600348) /* Data Register - EPS */ +#define UDCDRT __REG(0x4060034C) /* Data Register - EPT */ +#define UDCDRU __REG(0x40600350) /* Data Register - EPU */ +#define UDCDRV __REG(0x40600354) /* Data Register - EPV */ +#define UDCDRW __REG(0x40600358) /* Data Register - EPW */ +#define UDCDRX __REG(0x4060035C) /* Data Register - EPX */ + +#define UDCCN(x) __REG2(0x40600400, (x)<<2) +#define UDCCRA __REG(0x40600404) /* Configuration register EPA */ +#define UDCCRB __REG(0x40600408) /* Configuration register EPB */ +#define UDCCRC __REG(0x4060040C) /* Configuration register EPC */ +#define UDCCRD __REG(0x40600410) /* Configuration register EPD */ +#define UDCCRE __REG(0x40600414) /* Configuration register EPE */ +#define UDCCRF __REG(0x40600418) /* Configuration register EPF */ +#define UDCCRG __REG(0x4060041C) /* Configuration register EPG */ +#define UDCCRH __REG(0x40600420) /* Configuration register EPH */ +#define UDCCRI __REG(0x40600424) /* Configuration register EPI */ +#define UDCCRJ __REG(0x40600428) /* Configuration register EPJ */ +#define UDCCRK __REG(0x4060042C) /* Configuration register EPK */ +#define UDCCRL __REG(0x40600430) /* Configuration register EPL */ +#define UDCCRM __REG(0x40600434) /* Configuration register EPM */ +#define UDCCRN __REG(0x40600438) /* Configuration register EPN */ +#define UDCCRP __REG(0x4060043C) /* Configuration register EPP */ +#define UDCCRQ __REG(0x40600440) /* Configuration register EPQ */ +#define UDCCRR __REG(0x40600444) /* Configuration register EPR */ +#define UDCCRS __REG(0x40600448) /* Configuration register EPS */ +#define UDCCRT __REG(0x4060044C) /* Configuration register EPT */ +#define UDCCRU __REG(0x40600450) /* Configuration register EPU */ +#define UDCCRV __REG(0x40600454) /* Configuration register EPV */ +#define UDCCRW __REG(0x40600458) /* Configuration register EPW */ +#define UDCCRX __REG(0x4060045C) /* Configuration register EPX */ + +#define UDCCONR_CN (0x03 << 25) /* Configuration Number */ +#define UDCCONR_CN_S (25) +#define UDCCONR_IN (0x07 << 22) /* Interface Number */ +#define UDCCONR_IN_S (22) +#define UDCCONR_AISN (0x07 << 19) /* Alternate Interface Number */ +#define UDCCONR_AISN_S (19) +#define UDCCONR_EN (0x0f << 15) /* Endpoint Number */ +#define UDCCONR_EN_S (15) +#define UDCCONR_ET (0x03 << 13) /* Endpoint Type: */ +#define UDCCONR_ET_S (13) +#define UDCCONR_ET_INT (0x03 << 13) /* Interrupt */ +#define UDCCONR_ET_BULK (0x02 << 13) /* Bulk */ +#define UDCCONR_ET_ISO (0x01 << 13) /* Isochronous */ +#define UDCCONR_ET_NU (0x00 << 13) /* Not used */ +#define UDCCONR_ED (1 << 12) /* Endpoint Direction */ +#define UDCCONR_MPS (0x3ff << 2) /* Maximum Packet Size */ +#define UDCCONR_MPS_S (2) +#define UDCCONR_DE (1 << 1) /* Double Buffering Enable */ +#define UDCCONR_EE (1 << 0) /* Endpoint Enable */ + + +#define UDC_INT_FIFOERROR (0x2) +#define UDC_INT_PACKETCMP (0x1) + +#define UDC_FNR_MASK (0x7ff) + +#define UDCCSR_WR_MASK (UDCCSR_DME|UDCCSR_FST) +#define UDC_BCR_MASK (0x3ff) +#endif + +/* + * Fast Infrared Communication Port + */ + +#define FICP __REG(0x40800000) /* Start of FICP area */ +#define ICCR0 __REG(0x40800000) /* ICP Control Register 0 */ +#define ICCR1 __REG(0x40800004) /* ICP Control Register 1 */ +#define ICCR2 __REG(0x40800008) /* ICP Control Register 2 */ +#define ICDR __REG(0x4080000c) /* ICP Data Register */ +#define ICSR0 __REG(0x40800014) /* ICP Status Register 0 */ +#define ICSR1 __REG(0x40800018) /* ICP Status Register 1 */ + +#define ICCR0_AME (1 << 7) /* Address match enable */ +#define ICCR0_TIE (1 << 6) /* Transmit FIFO interrupt enable */ +#define ICCR0_RIE (1 << 5) /* Recieve FIFO interrupt enable */ +#define ICCR0_RXE (1 << 4) /* Receive enable */ +#define ICCR0_TXE (1 << 3) /* Transmit enable */ +#define ICCR0_TUS (1 << 2) /* Transmit FIFO underrun select */ +#define ICCR0_LBM (1 << 1) /* Loopback mode */ +#define ICCR0_ITR (1 << 0) /* IrDA transmission */ + +#define ICCR2_RXP (1 << 3) /* Receive Pin Polarity select */ +#define ICCR2_TXP (1 << 2) /* Transmit Pin Polarity select */ +#define ICCR2_TRIG (3 << 0) /* Receive FIFO Trigger threshold */ +#define ICCR2_TRIG_8 (0 << 0) /* >= 8 bytes */ +#define ICCR2_TRIG_16 (1 << 0) /* >= 16 bytes */ +#define ICCR2_TRIG_32 (2 << 0) /* >= 32 bytes */ + +#ifdef CONFIG_PXA27x +#define ICSR0_EOC (1 << 6) /* DMA End of Descriptor Chain */ +#endif +#define ICSR0_FRE (1 << 5) /* Framing error */ +#define ICSR0_RFS (1 << 4) /* Receive FIFO service request */ +#define ICSR0_TFS (1 << 3) /* Transnit FIFO service request */ +#define ICSR0_RAB (1 << 2) /* Receiver abort */ +#define ICSR0_TUR (1 << 1) /* Trunsmit FIFO underun */ +#define ICSR0_EIF (1 << 0) /* End/Error in FIFO */ + +#define ICSR1_ROR (1 << 6) /* Receiver FIFO underrun */ +#define ICSR1_CRE (1 << 5) /* CRC error */ +#define ICSR1_EOF (1 << 4) /* End of frame */ +#define ICSR1_TNF (1 << 3) /* Transmit FIFO not full */ +#define ICSR1_RNE (1 << 2) /* Receive FIFO not empty */ +#define ICSR1_TBY (1 << 1) /* Tramsmiter busy flag */ +#define ICSR1_RSY (1 << 0) /* Recevier synchronized flag */ + + +/* + * Real Time Clock + */ + +#define RCNR __REG(0x40900000) /* RTC Count Register */ +#define RTAR __REG(0x40900004) /* RTC Alarm Register */ +#define RTSR __REG(0x40900008) /* RTC Status Register */ +#define RTTR __REG(0x4090000C) /* RTC Timer Trim Register */ +#define PIAR __REG(0x40900038) /* Periodic Interrupt Alarm Register */ + +#define RTSR_PICE (1 << 15) /* Periodic interrupt count enable */ +#define RTSR_PIALE (1 << 14) /* Periodic interrupt Alarm enable */ +#define RTSR_HZE (1 << 3) /* HZ interrupt enable */ +#define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */ +#define RTSR_HZ (1 << 1) /* HZ rising-edge detected */ +#define RTSR_AL (1 << 0) /* RTC alarm detected */ + + +/* + * OS Timer & Match Registers + */ + +#define OSMR0 __REG(0x40A00000) /* */ +#define OSMR1 __REG(0x40A00004) /* */ +#define OSMR2 __REG(0x40A00008) /* */ +#define OSMR3 __REG(0x40A0000C) /* */ +#define OSMR4 __REG(0x40A00080) /* */ +#define OSCR __REG(0x40A00010) /* OS Timer Counter Register */ +#define OSCR4 __REG(0x40A00040) /* OS Timer Counter Register */ +#define OMCR4 __REG(0x40A000C0) /* */ +#define OSSR __REG(0x40A00014) /* OS Timer Status Register */ +#define OWER __REG(0x40A00018) /* OS Timer Watchdog Enable Register */ +#define OIER __REG(0x40A0001C) /* OS Timer Interrupt Enable Register */ + +#define OSSR_M3 (1 << 3) /* Match status channel 3 */ +#define OSSR_M2 (1 << 2) /* Match status channel 2 */ +#define OSSR_M1 (1 << 1) /* Match status channel 1 */ +#define OSSR_M0 (1 << 0) /* Match status channel 0 */ + +#define OWER_WME (1 << 0) /* Watchdog Match Enable */ + +#define OIER_E3 (1 << 3) /* Interrupt enable channel 3 */ +#define OIER_E2 (1 << 2) /* Interrupt enable channel 2 */ +#define OIER_E1 (1 << 1) /* Interrupt enable channel 1 */ +#define OIER_E0 (1 << 0) /* Interrupt enable channel 0 */ + + +/* + * Pulse Width Modulator + */ + +#define PWM_CTRL0 __REG(0x40B00000) /* PWM 0 Control Register */ +#define PWM_PWDUTY0 __REG(0x40B00004) /* PWM 0 Duty Cycle Register */ +#define PWM_PERVAL0 __REG(0x40B00008) /* PWM 0 Period Control Register */ + +#define PWM_CTRL1 __REG(0x40C00000) /* PWM 1Control Register */ +#define PWM_PWDUTY1 __REG(0x40C00004) /* PWM 1 Duty Cycle Register */ +#define PWM_PERVAL1 __REG(0x40C00008) /* PWM 1 Period Control Register */ + + +/* + * Interrupt Controller + */ + +#define ICIP __REG(0x40D00000) /* Interrupt Controller IRQ Pending Register */ +#define ICMR __REG(0x40D00004) /* Interrupt Controller Mask Register */ +#define ICLR __REG(0x40D00008) /* Interrupt Controller Level Register */ +#define ICFP __REG(0x40D0000C) /* Interrupt Controller FIQ Pending Register */ +#define ICPR __REG(0x40D00010) /* Interrupt Controller Pending Register */ +#define ICCR __REG(0x40D00014) /* Interrupt Controller Control Register */ + + +/* + * General Purpose I/O + */ + +#define GPLR0 __REG(0x40E00000) /* GPIO Pin-Level Register GPIO<31:0> */ +#define GPLR1 __REG(0x40E00004) /* GPIO Pin-Level Register GPIO<63:32> */ +#define GPLR2 __REG(0x40E00008) /* GPIO Pin-Level Register GPIO<80:64> */ + +#define GPDR0 __REG(0x40E0000C) /* GPIO Pin Direction Register GPIO<31:0> */ +#define GPDR1 __REG(0x40E00010) /* GPIO Pin Direction Register GPIO<63:32> */ +#define GPDR2 __REG(0x40E00014) /* GPIO Pin Direction Register GPIO<80:64> */ + +#define GPSR0 __REG(0x40E00018) /* GPIO Pin Output Set Register GPIO<31:0> */ +#define GPSR1 __REG(0x40E0001C) /* GPIO Pin Output Set Register GPIO<63:32> */ +#define GPSR2 __REG(0x40E00020) /* GPIO Pin Output Set Register GPIO<80:64> */ + +#define GPCR0 __REG(0x40E00024) /* GPIO Pin Output Clear Register GPIO<31:0> */ +#define GPCR1 __REG(0x40E00028) /* GPIO Pin Output Clear Register GPIO <63:32> */ +#define GPCR2 __REG(0x40E0002C) /* GPIO Pin Output Clear Register GPIO <80:64> */ + +#define GRER0 __REG(0x40E00030) /* GPIO Rising-Edge Detect Register GPIO<31:0> */ +#define GRER1 __REG(0x40E00034) /* GPIO Rising-Edge Detect Register GPIO<63:32> */ +#define GRER2 __REG(0x40E00038) /* GPIO Rising-Edge Detect Register GPIO<80:64> */ + +#define GFER0 __REG(0x40E0003C) /* GPIO Falling-Edge Detect Register GPIO<31:0> */ +#define GFER1 __REG(0x40E00040) /* GPIO Falling-Edge Detect Register GPIO<63:32> */ +#define GFER2 __REG(0x40E00044) /* GPIO Falling-Edge Detect Register GPIO<80:64> */ + +#define GEDR0 __REG(0x40E00048) /* GPIO Edge Detect Status Register GPIO<31:0> */ +#define GEDR1 __REG(0x40E0004C) /* GPIO Edge Detect Status Register GPIO<63:32> */ +#define GEDR2 __REG(0x40E00050) /* GPIO Edge Detect Status Register GPIO<80:64> */ + +#define GAFR0_L __REG(0x40E00054) /* GPIO Alternate Function Select Register GPIO<15:0> */ +#define GAFR0_U __REG(0x40E00058) /* GPIO Alternate Function Select Register GPIO<31:16> */ +#define GAFR1_L __REG(0x40E0005C) /* GPIO Alternate Function Select Register GPIO<47:32> */ +#define GAFR1_U __REG(0x40E00060) /* GPIO Alternate Function Select Register GPIO<63:48> */ +#define GAFR2_L __REG(0x40E00064) /* GPIO Alternate Function Select Register GPIO<79:64> */ +#define GAFR2_U __REG(0x40E00068) /* GPIO Alternate Function Select Register GPIO<95-80> */ +#define GAFR3_L __REG(0x40E0006C) /* GPIO Alternate Function Select Register GPIO<111:96> */ +#define GAFR3_U __REG(0x40E00070) /* GPIO Alternate Function Select Register GPIO<127:112> */ + +#define GPLR3 __REG(0x40E00100) /* GPIO Pin-Level Register GPIO<127:96> */ +#define GPDR3 __REG(0x40E0010C) /* GPIO Pin Direction Register GPIO<127:96> */ +#define GPSR3 __REG(0x40E00118) /* GPIO Pin Output Set Register GPIO<127:96> */ +#define GPCR3 __REG(0x40E00124) /* GPIO Pin Output Clear Register GPIO<127:96> */ +#define GRER3 __REG(0x40E00130) /* GPIO Rising-Edge Detect Register GPIO<127:96> */ +#define GFER3 __REG(0x40E0013C) /* GPIO Falling-Edge Detect Register GPIO<127:96> */ +#define GEDR3 __REG(0x40E00148) /* GPIO Edge Detect Status Register GPIO<127:96> */ + +/* More handy macros. The argument is a literal GPIO number. */ + +#define GPIO_bit(x) (1 << ((x) & 0x1f)) + +#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) + +/* Interrupt Controller */ + +#define ICIP2 __REG(0x40D0009C) /* Interrupt Controller IRQ Pending Register 2 */ +#define ICMR2 __REG(0x40D000A0) /* Interrupt Controller Mask Register 2 */ +#define ICLR2 __REG(0x40D000A4) /* Interrupt Controller Level Register 2 */ +#define ICFP2 __REG(0x40D000A8) /* Interrupt Controller FIQ Pending Register 2 */ +#define ICPR2 __REG(0x40D000AC) /* Interrupt Controller Pending Register 2 */ + +#define _GPLR(x) __REG2(0x40E00000, ((x) & 0x60) >> 3) +#define _GPDR(x) __REG2(0x40E0000C, ((x) & 0x60) >> 3) +#define _GPSR(x) __REG2(0x40E00018, ((x) & 0x60) >> 3) +#define _GPCR(x) __REG2(0x40E00024, ((x) & 0x60) >> 3) +#define _GRER(x) __REG2(0x40E00030, ((x) & 0x60) >> 3) +#define _GFER(x) __REG2(0x40E0003C, ((x) & 0x60) >> 3) +#define _GEDR(x) __REG2(0x40E00048, ((x) & 0x60) >> 3) +#define _GAFR(x) __REG2(0x40E00054, ((x) & 0x70) >> 2) + +#define GPLR(x) (*((((x) & 0x7f) < 96) ? &_GPLR(x) : &GPLR3)) +#define GPDR(x) (*((((x) & 0x7f) < 96) ? &_GPDR(x) : &GPDR3)) +#define GPSR(x) (*((((x) & 0x7f) < 96) ? &_GPSR(x) : &GPSR3)) +#define GPCR(x) (*((((x) & 0x7f) < 96) ? &_GPCR(x) : &GPCR3)) +#define GRER(x) (*((((x) & 0x7f) < 96) ? &_GRER(x) : &GRER3)) +#define GFER(x) (*((((x) & 0x7f) < 96) ? &_GFER(x) : &GFER3)) +#define GEDR(x) (*((((x) & 0x7f) < 96) ? &_GEDR(x) : &GEDR3)) +#define GAFR(x) (*((((x) & 0x7f) < 96) ? &_GAFR(x) : \ + ((((x) & 0x7f) < 112) ? &GAFR3_L : &GAFR3_U))) +#else + +#define GPLR(x) __REG2(0x40E00000, ((x) & 0x60) >> 3) +#define GPDR(x) __REG2(0x40E0000C, ((x) & 0x60) >> 3) +#define GPSR(x) __REG2(0x40E00018, ((x) & 0x60) >> 3) +#define GPCR(x) __REG2(0x40E00024, ((x) & 0x60) >> 3) +#define GRER(x) __REG2(0x40E00030, ((x) & 0x60) >> 3) +#define GFER(x) __REG2(0x40E0003C, ((x) & 0x60) >> 3) +#define GEDR(x) __REG2(0x40E00048, ((x) & 0x60) >> 3) +#define GAFR(x) __REG2(0x40E00054, ((x) & 0x70) >> 2) + +#endif + + +/* GPIO alternate function assignments */ + +#define GPIO1_RST 1 /* reset */ +#define GPIO6_MMCCLK 6 /* MMC Clock */ +#define GPIO7_48MHz 7 /* 48 MHz clock output */ +#define GPIO8_MMCCS0 8 /* MMC Chip Select 0 */ +#define GPIO9_MMCCS1 9 /* MMC Chip Select 1 */ +#define GPIO10_RTCCLK 10 /* real time clock (1 Hz) */ +#define GPIO11_3_6MHz 11 /* 3.6 MHz oscillator out */ +#define GPIO12_32KHz 12 /* 32 kHz out */ +#define GPIO13_MBGNT 13 /* memory controller grant */ +#define GPIO14_MBREQ 14 /* alternate bus master request */ +#define GPIO15_nCS_1 15 /* chip select 1 */ +#define GPIO16_PWM0 16 /* PWM0 output */ +#define GPIO17_PWM1 17 /* PWM1 output */ +#define GPIO18_RDY 18 /* Ext. Bus Ready */ +#define GPIO19_DREQ1 19 /* External DMA Request */ +#define GPIO20_DREQ0 20 /* External DMA Request */ +#define GPIO23_SCLK 23 /* SSP clock */ +#define GPIO24_SFRM 24 /* SSP Frame */ +#define GPIO25_STXD 25 /* SSP transmit */ +#define GPIO26_SRXD 26 /* SSP receive */ +#define GPIO27_SEXTCLK 27 /* SSP ext_clk */ +#define GPIO28_BITCLK 28 /* AC97/I2S bit_clk */ +#define GPIO29_SDATA_IN 29 /* AC97 Sdata_in0 / I2S Sdata_in */ +#define GPIO30_SDATA_OUT 30 /* AC97/I2S Sdata_out */ +#define GPIO31_SYNC 31 /* AC97/I2S sync */ +#define GPIO32_SDATA_IN1 32 /* AC97 Sdata_in1 */ +#define GPIO32_SYSCLK 32 /* I2S System Clock */ +#define GPIO32_MMCCLK 32 /* MMC Clock (PXA270) */ +#define GPIO33_nCS_5 33 /* chip select 5 */ +#define GPIO34_FFRXD 34 /* FFUART receive */ +#define GPIO34_MMCCS0 34 /* MMC Chip Select 0 */ +#define GPIO35_FFCTS 35 /* FFUART Clear to send */ +#define GPIO36_FFDCD 36 /* FFUART Data carrier detect */ +#define GPIO37_FFDSR 37 /* FFUART data set ready */ +#define GPIO38_FFRI 38 /* FFUART Ring Indicator */ +#define GPIO39_MMCCS1 39 /* MMC Chip Select 1 */ +#define GPIO39_FFTXD 39 /* FFUART transmit data */ +#define GPIO40_FFDTR 40 /* FFUART data terminal Ready */ +#define GPIO41_FFRTS 41 /* FFUART request to send */ +#define GPIO42_BTRXD 42 /* BTUART receive data */ +#define GPIO42_HWRXD 42 /* HWUART receive data */ +#define GPIO43_BTTXD 43 /* BTUART transmit data */ +#define GPIO43_HWTXD 43 /* HWUART transmit data */ +#define GPIO44_BTCTS 44 /* BTUART clear to send */ +#define GPIO44_HWCTS 44 /* HWUART clear to send */ +#define GPIO45_BTRTS 45 /* BTUART request to send */ +#define GPIO45_HWRTS 45 /* HWUART request to send */ +#define GPIO45_AC97_SYSCLK 45 /* AC97 System Clock */ +#define GPIO46_ICPRXD 46 /* ICP receive data */ +#define GPIO46_STRXD 46 /* STD_UART receive data */ +#define GPIO47_ICPTXD 47 /* ICP transmit data */ +#define GPIO47_STTXD 47 /* STD_UART transmit data */ +#define GPIO48_nPOE 48 /* Output Enable for Card Space */ +#define GPIO49_nPWE 49 /* Write Enable for Card Space */ +#define GPIO50_nPIOR 50 /* I/O Read for Card Space */ +#define GPIO51_nPIOW 51 /* I/O Write for Card Space */ +#define GPIO52_nPCE_1 52 /* Card Enable for Card Space */ +#define GPIO53_nPCE_2 53 /* Card Enable for Card Space */ +#define GPIO53_MMCCLK 53 /* MMC Clock */ +#define GPIO54_MMCCLK 54 /* MMC Clock */ +#define GPIO54_pSKTSEL 54 /* Socket Select for Card Space */ +#define GPIO54_nPCE_2 54 /* Card Enable for Card Space (PXA27x) */ +#define GPIO55_nPREG 55 /* Card Address bit 26 */ +#define GPIO56_nPWAIT 56 /* Wait signal for Card Space */ +#define GPIO57_nIOIS16 57 /* Bus Width select for I/O Card Space */ +#define GPIO58_LDD_0 58 /* LCD data pin 0 */ +#define GPIO59_LDD_1 59 /* LCD data pin 1 */ +#define GPIO60_LDD_2 60 /* LCD data pin 2 */ +#define GPIO61_LDD_3 61 /* LCD data pin 3 */ +#define GPIO62_LDD_4 62 /* LCD data pin 4 */ +#define GPIO63_LDD_5 63 /* LCD data pin 5 */ +#define GPIO64_LDD_6 64 /* LCD data pin 6 */ +#define GPIO65_LDD_7 65 /* LCD data pin 7 */ +#define GPIO66_LDD_8 66 /* LCD data pin 8 */ +#define GPIO66_MBREQ 66 /* alternate bus master req */ +#define GPIO67_LDD_9 67 /* LCD data pin 9 */ +#define GPIO67_MMCCS0 67 /* MMC Chip Select 0 */ +#define GPIO68_LDD_10 68 /* LCD data pin 10 */ +#define GPIO68_MMCCS1 68 /* MMC Chip Select 1 */ +#define GPIO69_LDD_11 69 /* LCD data pin 11 */ +#define GPIO69_MMCCLK 69 /* MMC_CLK */ +#define GPIO70_LDD_12 70 /* LCD data pin 12 */ +#define GPIO70_RTCCLK 70 /* Real Time clock (1 Hz) */ +#define GPIO71_LDD_13 71 /* LCD data pin 13 */ +#define GPIO71_3_6MHz 71 /* 3.6 MHz Oscillator clock */ +#define GPIO72_LDD_14 72 /* LCD data pin 14 */ +#define GPIO72_32kHz 72 /* 32 kHz clock */ +#define GPIO73_LDD_15 73 /* LCD data pin 15 */ +#define GPIO73_MBGNT 73 /* Memory controller grant */ +#define GPIO74_LCD_FCLK 74 /* LCD Frame clock */ +#define GPIO75_LCD_LCLK 75 /* LCD line clock */ +#define GPIO76_LCD_PCLK 76 /* LCD Pixel clock */ +#define GPIO77_LCD_ACBIAS 77 /* LCD AC Bias */ +#define GPIO78_nCS_2 78 /* chip select 2 */ +#define GPIO79_nCS_3 79 /* chip select 3 */ +#define GPIO80_nCS_4 80 /* chip select 4 */ +#define GPIO81_NSCLK 81 /* NSSP clock */ +#define GPIO82_NSFRM 82 /* NSSP Frame */ +#define GPIO83_NSTXD 83 /* NSSP transmit */ +#define GPIO84_NSRXD 84 /* NSSP receive */ +#define GPIO85_nPCE_1 85 /* Card Enable for Card Space (PXA27x) */ +#define GPIO92_MMCDAT0 92 /* MMC DAT0 (PXA27x) */ +#define GPIO102_nPCE_1 102 /* PCMCIA (PXA27x) */ +#define GPIO109_MMCDAT1 109 /* MMC DAT1 (PXA27x) */ +#define GPIO110_MMCDAT2 110 /* MMC DAT2 (PXA27x) */ +#define GPIO110_MMCCS0 110 /* MMC Chip Select 0 (PXA27x) */ +#define GPIO111_MMCDAT3 111 /* MMC DAT3 (PXA27x) */ +#define GPIO111_MMCCS1 111 /* MMC Chip Select 1 (PXA27x) */ +#define GPIO112_MMCCMD 112 /* MMC CMD (PXA27x) */ +#define GPIO113_I2S_SYSCLK 113 /* I2S System Clock (PXA27x) */ +#define GPIO113_AC97_RESET_N 113 /* AC97 NRESET on (PXA27x) */ + +/* GPIO alternate function mode & direction */ + +#define GPIO_IN 0x000 +#define GPIO_OUT 0x080 +#define GPIO_ALT_FN_1_IN 0x100 +#define GPIO_ALT_FN_1_OUT 0x180 +#define GPIO_ALT_FN_2_IN 0x200 +#define GPIO_ALT_FN_2_OUT 0x280 +#define GPIO_ALT_FN_3_IN 0x300 +#define GPIO_ALT_FN_3_OUT 0x380 +#define GPIO_MD_MASK_NR 0x07f +#define GPIO_MD_MASK_DIR 0x080 +#define GPIO_MD_MASK_FN 0x300 +#define GPIO_DFLT_LOW 0x400 +#define GPIO_DFLT_HIGH 0x800 + +#define GPIO1_RTS_MD ( 1 | GPIO_ALT_FN_1_IN) +#define GPIO6_MMCCLK_MD ( 6 | GPIO_ALT_FN_1_OUT) +#define GPIO7_48MHz_MD ( 7 | GPIO_ALT_FN_1_OUT) +#define GPIO8_MMCCS0_MD ( 8 | GPIO_ALT_FN_1_OUT) +#define GPIO9_MMCCS1_MD ( 9 | GPIO_ALT_FN_1_OUT) +#define GPIO10_RTCCLK_MD (10 | GPIO_ALT_FN_1_OUT) +#define GPIO11_3_6MHz_MD (11 | GPIO_ALT_FN_1_OUT) +#define GPIO12_32KHz_MD (12 | GPIO_ALT_FN_1_OUT) +#define GPIO13_MBGNT_MD (13 | GPIO_ALT_FN_2_OUT) +#define GPIO14_MBREQ_MD (14 | GPIO_ALT_FN_1_IN) +#define GPIO15_nCS_1_MD (15 | GPIO_ALT_FN_2_OUT) +#define GPIO16_PWM0_MD (16 | GPIO_ALT_FN_2_OUT) +#define GPIO17_PWM1_MD (17 | GPIO_ALT_FN_2_OUT) +#define GPIO18_RDY_MD (18 | GPIO_ALT_FN_1_IN) +#define GPIO19_DREQ1_MD (19 | GPIO_ALT_FN_1_IN) +#define GPIO20_DREQ0_MD (20 | GPIO_ALT_FN_1_IN) +#define GPIO23_SCLK_MD (23 | GPIO_ALT_FN_2_OUT) +#define GPIO24_SFRM_MD (24 | GPIO_ALT_FN_2_OUT) +#define GPIO25_STXD_MD (25 | GPIO_ALT_FN_2_OUT) +#define GPIO26_SRXD_MD (26 | GPIO_ALT_FN_1_IN) +#define GPIO27_SEXTCLK_MD (27 | GPIO_ALT_FN_1_IN) +#define GPIO28_BITCLK_AC97_MD (28 | GPIO_ALT_FN_1_IN) +#define GPIO28_BITCLK_IN_I2S_MD (28 | GPIO_ALT_FN_2_IN) +#define GPIO28_BITCLK_OUT_I2S_MD (28 | GPIO_ALT_FN_1_OUT) +#define GPIO29_SDATA_IN_AC97_MD (29 | GPIO_ALT_FN_1_IN) +#define GPIO29_SDATA_IN_I2S_MD (29 | GPIO_ALT_FN_2_IN) +#define GPIO30_SDATA_OUT_AC97_MD (30 | GPIO_ALT_FN_2_OUT) +#define GPIO30_SDATA_OUT_I2S_MD (30 | GPIO_ALT_FN_1_OUT) +#define GPIO31_SYNC_I2S_MD (31 | GPIO_ALT_FN_1_OUT) +#define GPIO31_SYNC_AC97_MD (31 | GPIO_ALT_FN_2_OUT) +#define GPIO32_SDATA_IN1_AC97_MD (32 | GPIO_ALT_FN_1_IN) +#define GPIO32_SYSCLK_I2S_MD (32 | GPIO_ALT_FN_1_OUT) +#define GPIO32_MMCCLK_MD ( 32 | GPIO_ALT_FN_2_OUT) +#define GPIO33_nCS_5_MD (33 | GPIO_ALT_FN_2_OUT) +#define GPIO34_FFRXD_MD (34 | GPIO_ALT_FN_1_IN) +#define GPIO34_MMCCS0_MD (34 | GPIO_ALT_FN_2_OUT) +#define GPIO35_FFCTS_MD (35 | GPIO_ALT_FN_1_IN) +#define GPIO36_FFDCD_MD (36 | GPIO_ALT_FN_1_IN) +#define GPIO37_FFDSR_MD (37 | GPIO_ALT_FN_1_IN) +#define GPIO38_FFRI_MD (38 | GPIO_ALT_FN_1_IN) +#define GPIO39_MMCCS1_MD (39 | GPIO_ALT_FN_1_OUT) +#define GPIO39_FFTXD_MD (39 | GPIO_ALT_FN_2_OUT) +#define GPIO40_FFDTR_MD (40 | GPIO_ALT_FN_2_OUT) +#define GPIO41_FFRTS_MD (41 | GPIO_ALT_FN_2_OUT) +#define GPIO42_BTRXD_MD (42 | GPIO_ALT_FN_1_IN) +#define GPIO42_HWRXD_MD (42 | GPIO_ALT_FN_3_IN) +#define GPIO43_BTTXD_MD (43 | GPIO_ALT_FN_2_OUT) +#define GPIO43_HWTXD_MD (43 | GPIO_ALT_FN_3_OUT) +#define GPIO44_BTCTS_MD (44 | GPIO_ALT_FN_1_IN) +#define GPIO44_HWCTS_MD (44 | GPIO_ALT_FN_3_IN) +#define GPIO45_BTRTS_MD (45 | GPIO_ALT_FN_2_OUT) +#define GPIO45_HWRTS_MD (45 | GPIO_ALT_FN_3_OUT) +#define GPIO45_SYSCLK_AC97_MD (45 | GPIO_ALT_FN_1_OUT) +#define GPIO46_ICPRXD_MD (46 | GPIO_ALT_FN_1_IN) +#define GPIO46_STRXD_MD (46 | GPIO_ALT_FN_2_IN) +#define GPIO47_ICPTXD_MD (47 | GPIO_ALT_FN_2_OUT) +#define GPIO47_STTXD_MD (47 | GPIO_ALT_FN_1_OUT) +#define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT) +#define GPIO48_HWTXD_MD (48 | GPIO_ALT_FN_1_OUT) +#define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT) +#define GPIO49_HWRXD_MD (49 | GPIO_ALT_FN_1_IN) +#define GPIO49_nPWE_MD (49 | GPIO_ALT_FN_2_OUT) +#define GPIO50_nPIOR_MD (50 | GPIO_ALT_FN_2_OUT) +#define GPIO50_HWCTS_MD (50 | GPIO_ALT_FN_1_IN) +#define GPIO51_HWRTS_MD (51 | GPIO_ALT_FN_1_OUT) +#define GPIO51_nPIOW_MD (51 | GPIO_ALT_FN_2_OUT) +#define GPIO52_nPCE_1_MD (52 | GPIO_ALT_FN_2_OUT) +#define GPIO53_nPCE_2_MD (53 | GPIO_ALT_FN_2_OUT) +#define GPIO53_MMCCLK_MD (53 | GPIO_ALT_FN_1_OUT) +#define GPIO54_MMCCLK_MD (54 | GPIO_ALT_FN_1_OUT) +#define GPIO54_nPCE_2_MD (54 | GPIO_ALT_FN_2_OUT) +#define GPIO54_pSKTSEL_MD (54 | GPIO_ALT_FN_2_OUT) +#define GPIO55_nPREG_MD (55 | GPIO_ALT_FN_2_OUT) +#define GPIO56_nPWAIT_MD (56 | GPIO_ALT_FN_1_IN) +#define GPIO57_nIOIS16_MD (57 | GPIO_ALT_FN_1_IN) +#define GPIO58_LDD_0_MD (58 | GPIO_ALT_FN_2_OUT) +#define GPIO59_LDD_1_MD (59 | GPIO_ALT_FN_2_OUT) +#define GPIO60_LDD_2_MD (60 | GPIO_ALT_FN_2_OUT) +#define GPIO61_LDD_3_MD (61 | GPIO_ALT_FN_2_OUT) +#define GPIO62_LDD_4_MD (62 | GPIO_ALT_FN_2_OUT) +#define GPIO63_LDD_5_MD (63 | GPIO_ALT_FN_2_OUT) +#define GPIO64_LDD_6_MD (64 | GPIO_ALT_FN_2_OUT) +#define GPIO65_LDD_7_MD (65 | GPIO_ALT_FN_2_OUT) +#define GPIO66_LDD_8_MD (66 | GPIO_ALT_FN_2_OUT) +#define GPIO66_MBREQ_MD (66 | GPIO_ALT_FN_1_IN) +#define GPIO67_LDD_9_MD (67 | GPIO_ALT_FN_2_OUT) +#define GPIO67_MMCCS0_MD (67 | GPIO_ALT_FN_1_OUT) +#define GPIO68_LDD_10_MD (68 | GPIO_ALT_FN_2_OUT) +#define GPIO68_MMCCS1_MD (68 | GPIO_ALT_FN_1_OUT) +#define GPIO69_LDD_11_MD (69 | GPIO_ALT_FN_2_OUT) +#define GPIO69_MMCCLK_MD (69 | GPIO_ALT_FN_1_OUT) +#define GPIO70_LDD_12_MD (70 | GPIO_ALT_FN_2_OUT) +#define GPIO70_RTCCLK_MD (70 | GPIO_ALT_FN_1_OUT) +#define GPIO71_LDD_13_MD (71 | GPIO_ALT_FN_2_OUT) +#define GPIO71_3_6MHz_MD (71 | GPIO_ALT_FN_1_OUT) +#define GPIO72_LDD_14_MD (72 | GPIO_ALT_FN_2_OUT) +#define GPIO72_32kHz_MD (72 | GPIO_ALT_FN_1_OUT) +#define GPIO73_LDD_15_MD (73 | GPIO_ALT_FN_2_OUT) +#define GPIO73_MBGNT_MD (73 | GPIO_ALT_FN_1_OUT) +#define GPIO74_LCD_FCLK_MD (74 | GPIO_ALT_FN_2_OUT) +#define GPIO75_LCD_LCLK_MD (75 | GPIO_ALT_FN_2_OUT) +#define GPIO76_LCD_PCLK_MD (76 | GPIO_ALT_FN_2_OUT) +#define GPIO77_LCD_ACBIAS_MD (77 | GPIO_ALT_FN_2_OUT) +#define GPIO78_nCS_2_MD (78 | GPIO_ALT_FN_2_OUT) +#define GPIO79_nCS_3_MD (79 | GPIO_ALT_FN_2_OUT) +#define GPIO79_pSKTSEL_MD (79 | GPIO_ALT_FN_1_OUT) +#define GPIO80_nCS_4_MD (80 | GPIO_ALT_FN_2_OUT) +#define GPIO81_NSSP_CLK_OUT (81 | GPIO_ALT_FN_1_OUT) +#define GPIO81_NSSP_CLK_IN (81 | GPIO_ALT_FN_1_IN) +#define GPIO82_NSSP_FRM_OUT (82 | GPIO_ALT_FN_1_OUT) +#define GPIO82_NSSP_FRM_IN (82 | GPIO_ALT_FN_1_IN) +#define GPIO83_NSSP_TX (83 | GPIO_ALT_FN_1_OUT) +#define GPIO83_NSSP_RX (83 | GPIO_ALT_FN_2_IN) +#define GPIO84_NSSP_TX (84 | GPIO_ALT_FN_1_OUT) +#define GPIO84_NSSP_RX (84 | GPIO_ALT_FN_2_IN) +#define GPIO85_nPCE_1_MD (85 | GPIO_ALT_FN_1_OUT) +#define GPIO92_MMCDAT0_MD (92 | GPIO_ALT_FN_1_OUT) +#define GPIO102_nPCE_1_MD (102 | GPIO_ALT_FN_1_OUT) +#define GPIO104_pSKTSEL_MD (104 | GPIO_ALT_FN_1_OUT) +#define GPIO109_MMCDAT1_MD (109 | GPIO_ALT_FN_1_OUT) +#define GPIO110_MMCDAT2_MD (110 | GPIO_ALT_FN_1_OUT) +#define GPIO110_MMCCS0_MD (110 | GPIO_ALT_FN_1_OUT) +#define GPIO111_MMCDAT3_MD (111 | GPIO_ALT_FN_1_OUT) +#define GPIO110_MMCCS1_MD (111 | GPIO_ALT_FN_1_OUT) +#define GPIO112_MMCCMD_MD (112 | GPIO_ALT_FN_1_OUT) +#define GPIO113_I2S_SYSCLK_MD (113 | GPIO_ALT_FN_1_OUT) +#define GPIO113_AC97_RESET_N_MD (113 | GPIO_ALT_FN_2_OUT) +#define GPIO117_I2CSCL_MD (117 | GPIO_ALT_FN_1_IN) +#define GPIO118_I2CSDA_MD (118 | GPIO_ALT_FN_1_IN) + +/* + * Power Manager + */ + +#define PMCR __REG(0x40F00000) /* Power Manager Control Register */ +#define PSSR __REG(0x40F00004) /* Power Manager Sleep Status Register */ +#define PSPR __REG(0x40F00008) /* Power Manager Scratch Pad Register */ +#define PWER __REG(0x40F0000C) /* Power Manager Wake-up Enable Register */ +#define PRER __REG(0x40F00010) /* Power Manager GPIO Rising-Edge Detect Enable Register */ +#define PFER __REG(0x40F00014) /* Power Manager GPIO Falling-Edge Detect Enable Register */ +#define PEDR __REG(0x40F00018) /* Power Manager GPIO Edge Detect Status Register */ +#define PCFR __REG(0x40F0001C) /* Power Manager General Configuration Register */ +#define PGSR0 __REG(0x40F00020) /* Power Manager GPIO Sleep State Register for GP[31-0] */ +#define PGSR1 __REG(0x40F00024) /* Power Manager GPIO Sleep State Register for GP[63-32] */ +#define PGSR2 __REG(0x40F00028) /* Power Manager GPIO Sleep State Register for GP[84-64] */ +#define PGSR3 __REG(0x40F0002C) /* Power Manager GPIO Sleep State Register for GP[118-96] */ +#define RCSR __REG(0x40F00030) /* Reset Controller Status Register */ + +#define PSLR __REG(0x40F00034) /* Power Manager Sleep Config Register */ +#define PSTR __REG(0x40F00038) /*Power Manager Standby Config Register */ +#define PSNR __REG(0x40F0003C) /*Power Manager Sense Config Register */ +#define PVCR __REG(0x40F00040) /*Power Manager VoltageControl Register */ +#define PKWR __REG(0x40F00050) /* Power Manager KB Wake-up Enable Reg */ +#define PKSR __REG(0x40F00054) /* Power Manager KB Level-Detect Register */ +#define PCMD(x) __REG2(0x40F00080, (x)<<2) +#define PCMD0 __REG(0x40F00080 + 0 * 4) +#define PCMD1 __REG(0x40F00080 + 1 * 4) +#define PCMD2 __REG(0x40F00080 + 2 * 4) +#define PCMD3 __REG(0x40F00080 + 3 * 4) +#define PCMD4 __REG(0x40F00080 + 4 * 4) +#define PCMD5 __REG(0x40F00080 + 5 * 4) +#define PCMD6 __REG(0x40F00080 + 6 * 4) +#define PCMD7 __REG(0x40F00080 + 7 * 4) +#define PCMD8 __REG(0x40F00080 + 8 * 4) +#define PCMD9 __REG(0x40F00080 + 9 * 4) +#define PCMD10 __REG(0x40F00080 + 10 * 4) +#define PCMD11 __REG(0x40F00080 + 11 * 4) +#define PCMD12 __REG(0x40F00080 + 12 * 4) +#define PCMD13 __REG(0x40F00080 + 13 * 4) +#define PCMD14 __REG(0x40F00080 + 14 * 4) +#define PCMD15 __REG(0x40F00080 + 15 * 4) +#define PCMD16 __REG(0x40F00080 + 16 * 4) +#define PCMD17 __REG(0x40F00080 + 17 * 4) +#define PCMD18 __REG(0x40F00080 + 18 * 4) +#define PCMD19 __REG(0x40F00080 + 19 * 4) +#define PCMD20 __REG(0x40F00080 + 20 * 4) +#define PCMD21 __REG(0x40F00080 + 21 * 4) +#define PCMD22 __REG(0x40F00080 + 22 * 4) +#define PCMD23 __REG(0x40F00080 + 23 * 4) +#define PCMD24 __REG(0x40F00080 + 24 * 4) +#define PCMD25 __REG(0x40F00080 + 25 * 4) +#define PCMD26 __REG(0x40F00080 + 26 * 4) +#define PCMD27 __REG(0x40F00080 + 27 * 4) +#define PCMD28 __REG(0x40F00080 + 28 * 4) +#define PCMD29 __REG(0x40F00080 + 29 * 4) +#define PCMD30 __REG(0x40F00080 + 30 * 4) +#define PCMD31 __REG(0x40F00080 + 31 * 4) + +#define PCMD_MBC (1<<12) +#define PCMD_DCE (1<<11) +#define PCMD_LC (1<<10) +/* FIXME: PCMD_SQC need be checked. */ +#define PCMD_SQC (3<<8) /* currently only bit 8 is changeable, + bit 9 should be 0 all day. */ +#define PVCR_VCSA (0x1<<14) +#define PVCR_CommandDelay (0xf80) +#define PCFR_PI2C_EN (0x1 << 6) + +#define PSSR_OTGPH (1 << 6) /* OTG Peripheral control Hold */ +#define PSSR_RDH (1 << 5) /* Read Disable Hold */ +#define PSSR_PH (1 << 4) /* Peripheral Control Hold */ +#define PSSR_STS (1 << 3) /* Standby Mode Status */ +#define PSSR_VFS (1 << 2) /* VDD Fault Status */ +#define PSSR_BFS (1 << 1) /* Battery Fault Status */ +#define PSSR_SSS (1 << 0) /* Software Sleep Status */ + +#define PSLR_SL_ROD (1 << 20) /* Sleep-Mode/Depp-Sleep Mode nRESET_OUT Disable */ + +#define PCFR_RO (1 << 15) /* RDH Override */ +#define PCFR_PO (1 << 14) /* PH Override */ +#define PCFR_GPROD (1 << 12) /* GPIO nRESET_OUT Disable */ +#define PCFR_L1_EN (1 << 11) /* Sleep Mode L1 converter Enable */ +#define PCFR_FVC (1 << 10) /* Frequency/Voltage Change */ +#define PCFR_DC_EN (1 << 7) /* Sleep/deep-sleep DC-DC Converter Enable */ +#define PCFR_PI2CEN (1 << 6) /* Enable PI2C controller */ +#define PCFR_GPR_EN (1 << 4) /* nRESET_GPIO Pin Enable */ +#define PCFR_DS (1 << 3) /* Deep Sleep Mode */ +#define PCFR_FS (1 << 2) /* Float Static Chip Selects */ +#define PCFR_FP (1 << 1) /* Float PCMCIA controls */ +#define PCFR_OPDE (1 << 0) /* 3.6864 MHz oscillator power-down enable */ + +#define RCSR_GPR (1 << 3) /* GPIO Reset */ +#define RCSR_SMR (1 << 2) /* Sleep Mode */ +#define RCSR_WDR (1 << 1) /* Watchdog Reset */ +#define RCSR_HWR (1 << 0) /* Hardware Reset */ + +#define PWER_GPIO(Nb) (1 << Nb) /* GPIO [0..15] wake-up enable */ +#define PWER_GPIO0 PWER_GPIO (0) /* GPIO [0] wake-up enable */ +#define PWER_GPIO1 PWER_GPIO (1) /* GPIO [1] wake-up enable */ +#define PWER_GPIO2 PWER_GPIO (2) /* GPIO [2] wake-up enable */ +#define PWER_GPIO3 PWER_GPIO (3) /* GPIO [3] wake-up enable */ +#define PWER_GPIO4 PWER_GPIO (4) /* GPIO [4] wake-up enable */ +#define PWER_GPIO5 PWER_GPIO (5) /* GPIO [5] wake-up enable */ +#define PWER_GPIO6 PWER_GPIO (6) /* GPIO [6] wake-up enable */ +#define PWER_GPIO7 PWER_GPIO (7) /* GPIO [7] wake-up enable */ +#define PWER_GPIO8 PWER_GPIO (8) /* GPIO [8] wake-up enable */ +#define PWER_GPIO9 PWER_GPIO (9) /* GPIO [9] wake-up enable */ +#define PWER_GPIO10 PWER_GPIO (10) /* GPIO [10] wake-up enable */ +#define PWER_GPIO11 PWER_GPIO (11) /* GPIO [11] wake-up enable */ +#define PWER_GPIO12 PWER_GPIO (12) /* GPIO [12] wake-up enable */ +#define PWER_GPIO13 PWER_GPIO (13) /* GPIO [13] wake-up enable */ +#define PWER_GPIO14 PWER_GPIO (14) /* GPIO [14] wake-up enable */ +#define PWER_GPIO15 PWER_GPIO (15) /* GPIO [15] wake-up enable */ +#define PWER_RTC 0x80000000 /* RTC alarm wake-up enable */ + +/* + * SSP Serial Port Registers - see include/asm-arm/arch-pxa/regs-ssp.h + */ + +/* + * MultiMediaCard (MMC) controller - see drivers/mmc/host/pxamci.h + */ + +/* + * Core Clock + */ + +#define CCCR __REG(0x41300000) /* Core Clock Configuration Register */ +#define CKEN __REG(0x41300004) /* Clock Enable Register */ +#define OSCC __REG(0x41300008) /* Oscillator Configuration Register */ +#define CCSR __REG(0x4130000C) /* Core Clock Status Register */ + +#define CCCR_N_MASK 0x0380 /* Run Mode Frequency to Turbo Mode Frequency Multiplier */ +#define CCCR_M_MASK 0x0060 /* Memory Frequency to Run Mode Frequency Multiplier */ +#define CCCR_L_MASK 0x001f /* Crystal Frequency to Memory Frequency Multiplier */ + +#define CKEN_AC97CONF (31) /* AC97 Controller Configuration */ +#define CKEN_CAMERA (24) /* Camera Interface Clock Enable */ +#define CKEN_SSP1 (23) /* SSP1 Unit Clock Enable */ +#define CKEN_MEMC (22) /* Memory Controller Clock Enable */ +#define CKEN_MEMSTK (21) /* Memory Stick Host Controller */ +#define CKEN_IM (20) /* Internal Memory Clock Enable */ +#define CKEN_KEYPAD (19) /* Keypad Interface Clock Enable */ +#define CKEN_USIM (18) /* USIM Unit Clock Enable */ +#define CKEN_MSL (17) /* MSL Unit Clock Enable */ +#define CKEN_LCD (16) /* LCD Unit Clock Enable */ +#define CKEN_PWRI2C (15) /* PWR I2C Unit Clock Enable */ +#define CKEN_I2C (14) /* I2C Unit Clock Enable */ +#define CKEN_FICP (13) /* FICP Unit Clock Enable */ +#define CKEN_MMC (12) /* MMC Unit Clock Enable */ +#define CKEN_USB (11) /* USB Unit Clock Enable */ +#define CKEN_ASSP (10) /* ASSP (SSP3) Clock Enable */ +#define CKEN_USBHOST (10) /* USB Host Unit Clock Enable */ +#define CKEN_OSTIMER (9) /* OS Timer Unit Clock Enable */ +#define CKEN_NSSP (9) /* NSSP (SSP2) Clock Enable */ +#define CKEN_I2S (8) /* I2S Unit Clock Enable */ +#define CKEN_BTUART (7) /* BTUART Unit Clock Enable */ +#define CKEN_FFUART (6) /* FFUART Unit Clock Enable */ +#define CKEN_STUART (5) /* STUART Unit Clock Enable */ +#define CKEN_HWUART (4) /* HWUART Unit Clock Enable */ +#define CKEN_SSP3 (4) /* SSP3 Unit Clock Enable */ +#define CKEN_SSP (3) /* SSP Unit Clock Enable */ +#define CKEN_SSP2 (3) /* SSP2 Unit Clock Enable */ +#define CKEN_AC97 (2) /* AC97 Unit Clock Enable */ +#define CKEN_PWM1 (1) /* PWM1 Clock Enable */ +#define CKEN_PWM0 (0) /* PWM0 Clock Enable */ + +#define OSCC_OON (1 << 1) /* 32.768kHz OON (write-once only bit) */ +#define OSCC_OOK (1 << 0) /* 32.768kHz OOK (read-only bit) */ + + +/* + * LCD + */ + +#define LCCR0 __REG(0x44000000) /* LCD Controller Control Register 0 */ +#define LCCR1 __REG(0x44000004) /* LCD Controller Control Register 1 */ +#define LCCR2 __REG(0x44000008) /* LCD Controller Control Register 2 */ +#define LCCR3 __REG(0x4400000C) /* LCD Controller Control Register 3 */ +#define LCCR4 __REG(0x44000010) /* LCD Controller Control Register 3 */ +#define DFBR0 __REG(0x44000020) /* DMA Channel 0 Frame Branch Register */ +#define DFBR1 __REG(0x44000024) /* DMA Channel 1 Frame Branch Register */ +#define LCSR __REG(0x44000038) /* LCD Controller Status Register */ +#define LIIDR __REG(0x4400003C) /* LCD Controller Interrupt ID Register */ +#define TMEDRGBR __REG(0x44000040) /* TMED RGB Seed Register */ +#define TMEDCR __REG(0x44000044) /* TMED Control Register */ + +#define LCCR3_1BPP (0 << 24) +#define LCCR3_2BPP (1 << 24) +#define LCCR3_4BPP (2 << 24) +#define LCCR3_8BPP (3 << 24) +#define LCCR3_16BPP (4 << 24) + +#define LCCR3_PDFOR_0 (0 << 30) +#define LCCR3_PDFOR_1 (1 << 30) +#define LCCR3_PDFOR_2 (2 << 30) +#define LCCR3_PDFOR_3 (3 << 30) + +#define LCCR4_PAL_FOR_0 (0 << 15) +#define LCCR4_PAL_FOR_1 (1 << 15) +#define LCCR4_PAL_FOR_2 (2 << 15) +#define LCCR4_PAL_FOR_MASK (3 << 15) + +#define FDADR0 __REG(0x44000200) /* DMA Channel 0 Frame Descriptor Address Register */ +#define FSADR0 __REG(0x44000204) /* DMA Channel 0 Frame Source Address Register */ +#define FIDR0 __REG(0x44000208) /* DMA Channel 0 Frame ID Register */ +#define LDCMD0 __REG(0x4400020C) /* DMA Channel 0 Command Register */ +#define FDADR1 __REG(0x44000210) /* DMA Channel 1 Frame Descriptor Address Register */ +#define FSADR1 __REG(0x44000214) /* DMA Channel 1 Frame Source Address Register */ +#define FIDR1 __REG(0x44000218) /* DMA Channel 1 Frame ID Register */ +#define LDCMD1 __REG(0x4400021C) /* DMA Channel 1 Command Register */ + +#define LCCR0_ENB (1 << 0) /* LCD Controller enable */ +#define LCCR0_CMS (1 << 1) /* Color/Monochrome Display Select */ +#define LCCR0_Color (LCCR0_CMS*0) /* Color display */ +#define LCCR0_Mono (LCCR0_CMS*1) /* Monochrome display */ +#define LCCR0_SDS (1 << 2) /* Single/Dual Panel Display */ + /* Select */ +#define LCCR0_Sngl (LCCR0_SDS*0) /* Single panel display */ +#define LCCR0_Dual (LCCR0_SDS*1) /* Dual panel display */ + +#define LCCR0_LDM (1 << 3) /* LCD Disable Done Mask */ +#define LCCR0_SFM (1 << 4) /* Start of frame mask */ +#define LCCR0_IUM (1 << 5) /* Input FIFO underrun mask */ +#define LCCR0_EFM (1 << 6) /* End of Frame mask */ +#define LCCR0_PAS (1 << 7) /* Passive/Active display Select */ +#define LCCR0_Pas (LCCR0_PAS*0) /* Passive display (STN) */ +#define LCCR0_Act (LCCR0_PAS*1) /* Active display (TFT) */ +#define LCCR0_DPD (1 << 9) /* Double Pixel Data (monochrome */ + /* display mode) */ +#define LCCR0_4PixMono (LCCR0_DPD*0) /* 4-Pixel/clock Monochrome */ + /* display */ +#define LCCR0_8PixMono (LCCR0_DPD*1) /* 8-Pixel/clock Monochrome */ + /* display */ +#define LCCR0_DIS (1 << 10) /* LCD Disable */ +#define LCCR0_QDM (1 << 11) /* LCD Quick Disable mask */ +#define LCCR0_PDD (0xff << 12) /* Palette DMA request delay */ +#define LCCR0_PDD_S 12 +#define LCCR0_BM (1 << 20) /* Branch mask */ +#define LCCR0_OUM (1 << 21) /* Output FIFO underrun mask */ +#define LCCR0_LCDT (1 << 22) /* LCD panel type */ +#define LCCR0_RDSTM (1 << 23) /* Read status interrupt mask */ +#define LCCR0_CMDIM (1 << 24) /* Command interrupt mask */ +#define LCCR0_OUC (1 << 25) /* Overlay Underlay control bit */ +#define LCCR0_LDDALT (1 << 26) /* LDD alternate mapping control */ + +#define LCCR1_PPL Fld (10, 0) /* Pixels Per Line - 1 */ +#define LCCR1_DisWdth(Pixel) /* Display Width [1..800 pix.] */ \ + (((Pixel) - 1) << FShft (LCCR1_PPL)) + +#define LCCR1_HSW Fld (6, 10) /* Horizontal Synchronization */ +#define LCCR1_HorSnchWdth(Tpix) /* Horizontal Synchronization */ \ + /* pulse Width [1..64 Tpix] */ \ + (((Tpix) - 1) << FShft (LCCR1_HSW)) + +#define LCCR1_ELW Fld (8, 16) /* End-of-Line pixel clock Wait */ + /* count - 1 [Tpix] */ +#define LCCR1_EndLnDel(Tpix) /* End-of-Line Delay */ \ + /* [1..256 Tpix] */ \ + (((Tpix) - 1) << FShft (LCCR1_ELW)) + +#define LCCR1_BLW Fld (8, 24) /* Beginning-of-Line pixel clock */ + /* Wait count - 1 [Tpix] */ +#define LCCR1_BegLnDel(Tpix) /* Beginning-of-Line Delay */ \ + /* [1..256 Tpix] */ \ + (((Tpix) - 1) << FShft (LCCR1_BLW)) + + +#define LCCR2_LPP Fld (10, 0) /* Line Per Panel - 1 */ +#define LCCR2_DisHght(Line) /* Display Height [1..1024 lines] */ \ + (((Line) - 1) << FShft (LCCR2_LPP)) + +#define LCCR2_VSW Fld (6, 10) /* Vertical Synchronization pulse */ + /* Width - 1 [Tln] (L_FCLK) */ +#define LCCR2_VrtSnchWdth(Tln) /* Vertical Synchronization pulse */ \ + /* Width [1..64 Tln] */ \ + (((Tln) - 1) << FShft (LCCR2_VSW)) + +#define LCCR2_EFW Fld (8, 16) /* End-of-Frame line clock Wait */ + /* count [Tln] */ +#define LCCR2_EndFrmDel(Tln) /* End-of-Frame Delay */ \ + /* [0..255 Tln] */ \ + ((Tln) << FShft (LCCR2_EFW)) + +#define LCCR2_BFW Fld (8, 24) /* Beginning-of-Frame line clock */ + /* Wait count [Tln] */ +#define LCCR2_BegFrmDel(Tln) /* Beginning-of-Frame Delay */ \ + /* [0..255 Tln] */ \ + ((Tln) << FShft (LCCR2_BFW)) + +#if 0 +#define LCCR3_PCD (0xff) /* Pixel clock divisor */ +#define LCCR3_ACB (0xff << 8) /* AC Bias pin frequency */ +#define LCCR3_ACB_S 8 +#endif + +#define LCCR3_API (0xf << 16) /* AC Bias pin trasitions per interrupt */ +#define LCCR3_API_S 16 +#define LCCR3_VSP (1 << 20) /* vertical sync polarity */ +#define LCCR3_HSP (1 << 21) /* horizontal sync polarity */ +#define LCCR3_PCP (1 << 22) /* Pixel Clock Polarity (L_PCLK) */ +#define LCCR3_PixRsEdg (LCCR3_PCP*0) /* Pixel clock Rising-Edge */ +#define LCCR3_PixFlEdg (LCCR3_PCP*1) /* Pixel clock Falling-Edge */ + +#define LCCR3_OEP (1 << 23) /* Output Enable Polarity (L_BIAS, */ + /* active display mode) */ +#define LCCR3_OutEnH (LCCR3_OEP*0) /* Output Enable active High */ +#define LCCR3_OutEnL (LCCR3_OEP*1) /* Output Enable active Low */ + +#if 0 +#define LCCR3_BPP (7 << 24) /* bits per pixel */ +#define LCCR3_BPP_S 24 +#endif +#define LCCR3_DPC (1 << 27) /* double pixel clock mode */ + + +#define LCCR3_PCD Fld (8, 0) /* Pixel Clock Divisor */ +#define LCCR3_PixClkDiv(Div) /* Pixel Clock Divisor */ \ + (((Div) << FShft (LCCR3_PCD))) + + +#define LCCR3_BPP Fld (3, 24) /* Bit Per Pixel */ +#define LCCR3_Bpp(Bpp) /* Bit Per Pixel */ \ + (((Bpp) << FShft (LCCR3_BPP))) + +#define LCCR3_ACB Fld (8, 8) /* AC Bias */ +#define LCCR3_Acb(Acb) /* BAC Bias */ \ + (((Acb) << FShft (LCCR3_ACB))) + +#define LCCR3_HorSnchH (LCCR3_HSP*0) /* Horizontal Synchronization */ + /* pulse active High */ +#define LCCR3_HorSnchL (LCCR3_HSP*1) /* Horizontal Synchronization */ + +#define LCCR3_VrtSnchH (LCCR3_VSP*0) /* Vertical Synchronization pulse */ + /* active High */ +#define LCCR3_VrtSnchL (LCCR3_VSP*1) /* Vertical Synchronization pulse */ + /* active Low */ + +#define LCSR_LDD (1 << 0) /* LCD Disable Done */ +#define LCSR_SOF (1 << 1) /* Start of frame */ +#define LCSR_BER (1 << 2) /* Bus error */ +#define LCSR_ABC (1 << 3) /* AC Bias count */ +#define LCSR_IUL (1 << 4) /* input FIFO underrun Lower panel */ +#define LCSR_IUU (1 << 5) /* input FIFO underrun Upper panel */ +#define LCSR_OU (1 << 6) /* output FIFO underrun */ +#define LCSR_QD (1 << 7) /* quick disable */ +#define LCSR_EOF (1 << 8) /* end of frame */ +#define LCSR_BS (1 << 9) /* branch status */ +#define LCSR_SINT (1 << 10) /* subsequent interrupt */ + +#define LDCMD_PAL (1 << 26) /* instructs DMA to load palette buffer */ + +#define LCSR_LDD (1 << 0) /* LCD Disable Done */ +#define LCSR_SOF (1 << 1) /* Start of frame */ +#define LCSR_BER (1 << 2) /* Bus error */ +#define LCSR_ABC (1 << 3) /* AC Bias count */ +#define LCSR_IUL (1 << 4) /* input FIFO underrun Lower panel */ +#define LCSR_IUU (1 << 5) /* input FIFO underrun Upper panel */ +#define LCSR_OU (1 << 6) /* output FIFO underrun */ +#define LCSR_QD (1 << 7) /* quick disable */ +#define LCSR_EOF (1 << 8) /* end of frame */ +#define LCSR_BS (1 << 9) /* branch status */ +#define LCSR_SINT (1 << 10) /* subsequent interrupt */ + +#define LDCMD_PAL (1 << 26) /* instructs DMA to load palette buffer */ + +#ifdef CONFIG_PXA27x + +/* + * Keypad + */ +#define KPC __REG(0x41500000) /* Keypad Interface Control register */ +#define KPDK __REG(0x41500008) /* Keypad Interface Direct Key register */ +#define KPREC __REG(0x41500010) /* Keypad Interface Rotary Encoder register */ +#define KPMK __REG(0x41500018) /* Keypad Interface Matrix Key register */ +#define KPAS __REG(0x41500020) /* Keypad Interface Automatic Scan register */ +#define KPASMKP0 __REG(0x41500028) /* Keypad Interface Automatic Scan Multiple Key Presser register 0 */ +#define KPASMKP1 __REG(0x41500030) /* Keypad Interface Automatic Scan Multiple Key Presser register 1 */ +#define KPASMKP2 __REG(0x41500038) /* Keypad Interface Automatic Scan Multiple Key Presser register 2 */ +#define KPASMKP3 __REG(0x41500040) /* Keypad Interface Automatic Scan Multiple Key Presser register 3 */ +#define KPKDI __REG(0x41500048) /* Keypad Interface Key Debounce Interval register */ + +#define KPC_AS (0x1 << 30) /* Automatic Scan bit */ +#define KPC_ASACT (0x1 << 29) /* Automatic Scan on Activity */ +#define KPC_MI (0x1 << 22) /* Matrix interrupt bit */ +#define KPC_IMKP (0x1 << 21) /* Ignore Multiple Key Press */ +#define KPC_MS7 (0x1 << 20) /* Matrix scan line 7 */ +#define KPC_MS6 (0x1 << 19) /* Matrix scan line 6 */ +#define KPC_MS5 (0x1 << 18) /* Matrix scan line 5 */ +#define KPC_MS4 (0x1 << 17) /* Matrix scan line 4 */ +#define KPC_MS3 (0x1 << 16) /* Matrix scan line 3 */ +#define KPC_MS2 (0x1 << 15) /* Matrix scan line 2 */ +#define KPC_MS1 (0x1 << 14) /* Matrix scan line 1 */ +#define KPC_MS0 (0x1 << 13) /* Matrix scan line 0 */ +#define KPC_MS_ALL (KPC_MS0 | KPC_MS1 | KPC_MS2 | KPC_MS3 | KPC_MS4 | KPC_MS5 | KPC_MS6 | KPC_MS7) +#define KPC_ME (0x1 << 12) /* Matrix Keypad Enable */ +#define KPC_MIE (0x1 << 11) /* Matrix Interrupt Enable */ +#define KPC_DK_DEB_SEL (0x1 << 9) /* Direct Keypad Debounce Select */ +#define KPC_DI (0x1 << 5) /* Direct key interrupt bit */ +#define KPC_RE_ZERO_DEB (0x1 << 4) /* Rotary Encoder Zero Debounce */ +#define KPC_REE1 (0x1 << 3) /* Rotary Encoder1 Enable */ +#define KPC_REE0 (0x1 << 2) /* Rotary Encoder0 Enable */ +#define KPC_DE (0x1 << 1) /* Direct Keypad Enable */ +#define KPC_DIE (0x1 << 0) /* Direct Keypad interrupt Enable */ + +#define KPDK_DKP (0x1 << 31) +#define KPDK_DK7 (0x1 << 7) +#define KPDK_DK6 (0x1 << 6) +#define KPDK_DK5 (0x1 << 5) +#define KPDK_DK4 (0x1 << 4) +#define KPDK_DK3 (0x1 << 3) +#define KPDK_DK2 (0x1 << 2) +#define KPDK_DK1 (0x1 << 1) +#define KPDK_DK0 (0x1 << 0) + +#define KPREC_OF1 (0x1 << 31) +#define kPREC_UF1 (0x1 << 30) +#define KPREC_OF0 (0x1 << 15) +#define KPREC_UF0 (0x1 << 14) + +#define KPMK_MKP (0x1 << 31) +#define KPAS_SO (0x1 << 31) +#define KPASMKPx_SO (0x1 << 31) + +/* Camera Interface */ +#define CICR0 __REG(0x50000000) +#define CICR1 __REG(0x50000004) +#define CICR2 __REG(0x50000008) +#define CICR3 __REG(0x5000000C) +#define CICR4 __REG(0x50000010) +#define CISR __REG(0x50000014) +#define CIFR __REG(0x50000018) +#define CITOR __REG(0x5000001C) +#define CIBR0 __REG(0x50000028) +#define CIBR1 __REG(0x50000030) +#define CIBR2 __REG(0x50000038) + +#define CICR0_DMAEN (1 << 31) /* DMA request enable */ +#define CICR0_PAR_EN (1 << 30) /* Parity enable */ +#define CICR0_SL_CAP_EN (1 << 29) /* Capture enable for slave mode */ +#define CICR0_ENB (1 << 28) /* Camera interface enable */ +#define CICR0_DIS (1 << 27) /* Camera interface disable */ +#define CICR0_SIM (0x7 << 24) /* Sensor interface mode mask */ +#define CICR0_TOM (1 << 9) /* Time-out mask */ +#define CICR0_RDAVM (1 << 8) /* Receive-data-available mask */ +#define CICR0_FEM (1 << 7) /* FIFO-empty mask */ +#define CICR0_EOLM (1 << 6) /* End-of-line mask */ +#define CICR0_PERRM (1 << 5) /* Parity-error mask */ +#define CICR0_QDM (1 << 4) /* Quick-disable mask */ +#define CICR0_CDM (1 << 3) /* Disable-done mask */ +#define CICR0_SOFM (1 << 2) /* Start-of-frame mask */ +#define CICR0_EOFM (1 << 1) /* End-of-frame mask */ +#define CICR0_FOM (1 << 0) /* FIFO-overrun mask */ + +#define CICR1_TBIT (1 << 31) /* Transparency bit */ +#define CICR1_RGBT_CONV (0x3 << 30) /* RGBT conversion mask */ +#define CICR1_PPL (0x7ff << 15) /* Pixels per line mask */ +#define CICR1_RGB_CONV (0x7 << 12) /* RGB conversion mask */ +#define CICR1_RGB_F (1 << 11) /* RGB format */ +#define CICR1_YCBCR_F (1 << 10) /* YCbCr format */ +#define CICR1_RGB_BPP (0x7 << 7) /* RGB bis per pixel mask */ +#define CICR1_RAW_BPP (0x3 << 5) /* Raw bis per pixel mask */ +#define CICR1_COLOR_SP (0x3 << 3) /* Color space mask */ +#define CICR1_DW (0x7 << 0) /* Data width mask */ + +#define CICR2_BLW (0xff << 24) /* Beginning-of-line pixel clock + wait count mask */ +#define CICR2_ELW (0xff << 16) /* End-of-line pixel clock + wait count mask */ +#define CICR2_HSW (0x3f << 10) /* Horizontal sync pulse width mask */ +#define CICR2_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock + wait count mask */ +#define CICR2_FSW (0x7 << 0) /* Frame stabilization + wait count mask */ + +#define CICR3_BFW (0xff << 24) /* Beginning-of-frame line clock + wait count mask */ +#define CICR3_EFW (0xff << 16) /* End-of-frame line clock + wait count mask */ +#define CICR3_VSW (0x3f << 10) /* Vertical sync pulse width mask */ +#define CICR3_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock + wait count mask */ +#define CICR3_LPF (0x7ff << 0) /* Lines per frame mask */ + +#define CICR4_MCLK_DLY (0x3 << 24) /* MCLK Data Capture Delay mask */ +#define CICR4_PCLK_EN (1 << 23) /* Pixel clock enable */ +#define CICR4_PCP (1 << 22) /* Pixel clock polarity */ +#define CICR4_HSP (1 << 21) /* Horizontal sync polarity */ +#define CICR4_VSP (1 << 20) /* Vertical sync polarity */ +#define CICR4_MCLK_EN (1 << 19) /* MCLK enable */ +#define CICR4_FR_RATE (0x7 << 8) /* Frame rate mask */ +#define CICR4_DIV (0xff << 0) /* Clock divisor mask */ + +#define CISR_FTO (1 << 15) /* FIFO time-out */ +#define CISR_RDAV_2 (1 << 14) /* Channel 2 receive data available */ +#define CISR_RDAV_1 (1 << 13) /* Channel 1 receive data available */ +#define CISR_RDAV_0 (1 << 12) /* Channel 0 receive data available */ +#define CISR_FEMPTY_2 (1 << 11) /* Channel 2 FIFO empty */ +#define CISR_FEMPTY_1 (1 << 10) /* Channel 1 FIFO empty */ +#define CISR_FEMPTY_0 (1 << 9) /* Channel 0 FIFO empty */ +#define CISR_EOL (1 << 8) /* End of line */ +#define CISR_PAR_ERR (1 << 7) /* Parity error */ +#define CISR_CQD (1 << 6) /* Camera interface quick disable */ +#define CISR_CDD (1 << 5) /* Camera interface disable done */ +#define CISR_SOF (1 << 4) /* Start of frame */ +#define CISR_EOF (1 << 3) /* End of frame */ +#define CISR_IFO_2 (1 << 2) /* FIFO overrun for Channel 2 */ +#define CISR_IFO_1 (1 << 1) /* FIFO overrun for Channel 1 */ +#define CISR_IFO_0 (1 << 0) /* FIFO overrun for Channel 0 */ + +#define CIFR_FLVL2 (0x7f << 23) /* FIFO 2 level mask */ +#define CIFR_FLVL1 (0x7f << 16) /* FIFO 1 level mask */ +#define CIFR_FLVL0 (0xff << 8) /* FIFO 0 level mask */ +#define CIFR_THL_0 (0x3 << 4) /* Threshold Level for Channel 0 FIFO */ +#define CIFR_RESET_F (1 << 3) /* Reset input FIFOs */ +#define CIFR_FEN2 (1 << 2) /* FIFO enable for channel 2 */ +#define CIFR_FEN1 (1 << 1) /* FIFO enable for channel 1 */ +#define CIFR_FEN0 (1 << 0) /* FIFO enable for channel 0 */ + +#define SRAM_SIZE 0x40000 /* 4x64K */ + +#define SRAM_MEM_PHYS 0x5C000000 + +#define IMPMCR __REG(0x58000000) /* IM Power Management Control Reg */ +#define IMPMSR __REG(0x58000008) /* IM Power Management Status Reg */ + +#define IMPMCR_PC3 (0x3 << 22) /* Bank 3 Power Control */ +#define IMPMCR_PC3_RUN_MODE (0x0 << 22) /* Run mode */ +#define IMPMCR_PC3_STANDBY_MODE (0x1 << 22) /* Standby mode */ +#define IMPMCR_PC3_AUTO_MODE (0x3 << 22) /* Automatically controlled */ + +#define IMPMCR_PC2 (0x3 << 20) /* Bank 2 Power Control */ +#define IMPMCR_PC2_RUN_MODE (0x0 << 20) /* Run mode */ +#define IMPMCR_PC2_STANDBY_MODE (0x1 << 20) /* Standby mode */ +#define IMPMCR_PC2_AUTO_MODE (0x3 << 20) /* Automatically controlled */ + +#define IMPMCR_PC1 (0x3 << 18) /* Bank 1 Power Control */ +#define IMPMCR_PC1_RUN_MODE (0x0 << 18) /* Run mode */ +#define IMPMCR_PC1_STANDBY_MODE (0x1 << 18) /* Standby mode */ +#define IMPMCR_PC1_AUTO_MODE (0x3 << 18) /* Automatically controlled */ + +#define IMPMCR_PC0 (0x3 << 16) /* Bank 0 Power Control */ +#define IMPMCR_PC0_RUN_MODE (0x0 << 16) /* Run mode */ +#define IMPMCR_PC0_STANDBY_MODE (0x1 << 16) /* Standby mode */ +#define IMPMCR_PC0_AUTO_MODE (0x3 << 16) /* Automatically controlled */ + +#define IMPMCR_AW3 (1 << 11) /* Bank 3 Automatic Wake-up enable */ +#define IMPMCR_AW2 (1 << 10) /* Bank 2 Automatic Wake-up enable */ +#define IMPMCR_AW1 (1 << 9) /* Bank 1 Automatic Wake-up enable */ +#define IMPMCR_AW0 (1 << 8) /* Bank 0 Automatic Wake-up enable */ + +#define IMPMCR_DST (0xFF << 0) /* Delay Standby Time, ms */ + +#define IMPMSR_PS3 (0x3 << 6) /* Bank 3 Power Status: */ +#define IMPMSR_PS3_RUN_MODE (0x0 << 6) /* Run mode */ +#define IMPMSR_PS3_STANDBY_MODE (0x1 << 6) /* Standby mode */ + +#define IMPMSR_PS2 (0x3 << 4) /* Bank 2 Power Status: */ +#define IMPMSR_PS2_RUN_MODE (0x0 << 4) /* Run mode */ +#define IMPMSR_PS2_STANDBY_MODE (0x1 << 4) /* Standby mode */ + +#define IMPMSR_PS1 (0x3 << 2) /* Bank 1 Power Status: */ +#define IMPMSR_PS1_RUN_MODE (0x0 << 2) /* Run mode */ +#define IMPMSR_PS1_STANDBY_MODE (0x1 << 2) /* Standby mode */ + +#define IMPMSR_PS0 (0x3 << 0) /* Bank 0 Power Status: */ +#define IMPMSR_PS0_RUN_MODE (0x0 << 0) /* Run mode */ +#define IMPMSR_PS0_STANDBY_MODE (0x1 << 0) /* Standby mode */ + +#endif + +#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) +/* + * UHC: USB Host Controller (OHCI-like) register definitions + */ +#define UHC_BASE_PHYS (0x4C000000) +#define UHCREV __REG(0x4C000000) /* UHC HCI Spec Revision */ +#define UHCHCON __REG(0x4C000004) /* UHC Host Control Register */ +#define UHCCOMS __REG(0x4C000008) /* UHC Command Status Register */ +#define UHCINTS __REG(0x4C00000C) /* UHC Interrupt Status Register */ +#define UHCINTE __REG(0x4C000010) /* UHC Interrupt Enable */ +#define UHCINTD __REG(0x4C000014) /* UHC Interrupt Disable */ +#define UHCHCCA __REG(0x4C000018) /* UHC Host Controller Comm. Area */ +#define UHCPCED __REG(0x4C00001C) /* UHC Period Current Endpt Descr */ +#define UHCCHED __REG(0x4C000020) /* UHC Control Head Endpt Descr */ +#define UHCCCED __REG(0x4C000024) /* UHC Control Current Endpt Descr */ +#define UHCBHED __REG(0x4C000028) /* UHC Bulk Head Endpt Descr */ +#define UHCBCED __REG(0x4C00002C) /* UHC Bulk Current Endpt Descr */ +#define UHCDHEAD __REG(0x4C000030) /* UHC Done Head */ +#define UHCFMI __REG(0x4C000034) /* UHC Frame Interval */ +#define UHCFMR __REG(0x4C000038) /* UHC Frame Remaining */ +#define UHCFMN __REG(0x4C00003C) /* UHC Frame Number */ +#define UHCPERS __REG(0x4C000040) /* UHC Periodic Start */ +#define UHCLS __REG(0x4C000044) /* UHC Low Speed Threshold */ + +#define UHCRHDA __REG(0x4C000048) /* UHC Root Hub Descriptor A */ +#define UHCRHDA_NOCP (1 << 12) /* No over current protection */ + +#define UHCRHDB __REG(0x4C00004C) /* UHC Root Hub Descriptor B */ +#define UHCRHS __REG(0x4C000050) /* UHC Root Hub Status */ +#define UHCRHPS1 __REG(0x4C000054) /* UHC Root Hub Port 1 Status */ +#define UHCRHPS2 __REG(0x4C000058) /* UHC Root Hub Port 2 Status */ +#define UHCRHPS3 __REG(0x4C00005C) /* UHC Root Hub Port 3 Status */ + +#define UHCSTAT __REG(0x4C000060) /* UHC Status Register */ +#define UHCSTAT_UPS3 (1 << 16) /* USB Power Sense Port3 */ +#define UHCSTAT_SBMAI (1 << 15) /* System Bus Master Abort Interrupt*/ +#define UHCSTAT_SBTAI (1 << 14) /* System Bus Target Abort Interrupt*/ +#define UHCSTAT_UPRI (1 << 13) /* USB Port Resume Interrupt */ +#define UHCSTAT_UPS2 (1 << 12) /* USB Power Sense Port 2 */ +#define UHCSTAT_UPS1 (1 << 11) /* USB Power Sense Port 1 */ +#define UHCSTAT_HTA (1 << 10) /* HCI Target Abort */ +#define UHCSTAT_HBA (1 << 8) /* HCI Buffer Active */ +#define UHCSTAT_RWUE (1 << 7) /* HCI Remote Wake Up Event */ + +#define UHCHR __REG(0x4C000064) /* UHC Reset Register */ +#define UHCHR_SSEP3 (1 << 11) /* Sleep Standby Enable for Port3 */ +#define UHCHR_SSEP2 (1 << 10) /* Sleep Standby Enable for Port2 */ +#define UHCHR_SSEP1 (1 << 9) /* Sleep Standby Enable for Port1 */ +#define UHCHR_PCPL (1 << 7) /* Power control polarity low */ +#define UHCHR_PSPL (1 << 6) /* Power sense polarity low */ +#define UHCHR_SSE (1 << 5) /* Sleep Standby Enable */ +#define UHCHR_UIT (1 << 4) /* USB Interrupt Test */ +#define UHCHR_SSDC (1 << 3) /* Simulation Scale Down Clock */ +#define UHCHR_CGR (1 << 2) /* Clock Generation Reset */ +#define UHCHR_FHR (1 << 1) /* Force Host Controller Reset */ +#define UHCHR_FSBIR (1 << 0) /* Force System Bus Iface Reset */ + +#define UHCHIE __REG(0x4C000068) /* UHC Interrupt Enable Register*/ +#define UHCHIE_UPS3IE (1 << 14) /* Power Sense Port3 IntEn */ +#define UHCHIE_UPRIE (1 << 13) /* Port Resume IntEn */ +#define UHCHIE_UPS2IE (1 << 12) /* Power Sense Port2 IntEn */ +#define UHCHIE_UPS1IE (1 << 11) /* Power Sense Port1 IntEn */ +#define UHCHIE_TAIE (1 << 10) /* HCI Interface Transfer Abort + Interrupt Enable*/ +#define UHCHIE_HBAIE (1 << 8) /* HCI Buffer Active IntEn */ +#define UHCHIE_RWIE (1 << 7) /* Remote Wake-up IntEn */ + +#define UHCHIT __REG(0x4C00006C) /* UHC Interrupt Test register */ + +#endif /* CONFIG_PXA27x || CONFIG_PXA3xx */ + +/* PWRMODE register M field values */ + +#define PWRMODE_IDLE 0x1 +#define PWRMODE_STANDBY 0x2 +#define PWRMODE_SLEEP 0x3 +#define PWRMODE_DEEPSLEEP 0x7 + +#endif -- cgit v1.2.3 From c6568fd43197352eb4c82e1271717a835af9fc27 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 17:46:25 +0000 Subject: V4L2 soc_camera driver for PXA27x processors From: Guennadi Liakhovetski This patch adds a driver for the Quick Capture Interface on the PXA270. It is based on the original driver from Intel, but has been re-worked multiple times since then, now for the first time it supports the V4L2 API. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- linux/arch/arm/mach-pxa/devices.c | 32 + linux/drivers/media/video/Kconfig | 7 + linux/drivers/media/video/Makefile | 1 + linux/drivers/media/video/pxa_camera.c | 937 ++++++++++++++++++++++++++++++ linux/include/asm-arm/arch-pxa/camera.h | 48 ++ linux/include/asm-arm/arch-pxa/pxa-regs.h | 166 ++++-- 6 files changed, 1155 insertions(+), 36 deletions(-) create mode 100644 linux/drivers/media/video/pxa_camera.c create mode 100644 linux/include/asm-arm/arch-pxa/camera.h (limited to 'linux') diff --git a/linux/arch/arm/mach-pxa/devices.c b/linux/arch/arm/mach-pxa/devices.c index bfccb80ac..3838aabdf 100644 --- a/linux/arch/arm/mach-pxa/devices.c +++ b/linux/arch/arm/mach-pxa/devices.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "devices.h" @@ -540,6 +541,37 @@ struct platform_device pxa27x_device_ssp3 = { .resource = pxa27x_resource_ssp3, .num_resources = ARRAY_SIZE(pxa27x_resource_ssp3), }; + +static struct resource pxa27x_resource_camera[] = { + [0] = { + .start = 0x50000000, + .end = 0x50000fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_CAMERA, + .end = IRQ_CAMERA, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 pxa27x_dma_mask_camera = DMA_BIT_MASK(32); + +static struct platform_device pxa27x_device_camera = { + .name = "pxa27x-camera", + .id = 0, /* This is used to put cameras on this interface */ + .dev = { + .dma_mask = &pxa27x_dma_mask_camera, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxa27x_resource_camera), + .resource = pxa27x_resource_camera, +}; + +void __init pxa_set_camera_info(struct pxacamera_platform_data *info) +{ + pxa_register_device(&pxa27x_device_camera, info); +} #endif /* CONFIG_PXA27x || CONFIG_PXA3xx */ #ifdef CONFIG_PXA3xx diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index c0498ac98..8e2c9f2dd 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -845,4 +845,11 @@ config SOC_CAMERA over a bus like PCI or USB. For example some i2c camera connected directly to the data bus of an SoC. +config VIDEO_PXA27x + tristate "PXA27x Quick Capture Interface driver" + depends on VIDEO_DEV && PXA27x + select SOC_CAMERA + ---help--- + This is a v4l2 driver for the PXA27x Quick Capture Interface + endif # VIDEO_CAPTURE_DRIVERS diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index 0bf47f83b..4ab0a0348 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -137,6 +137,7 @@ obj-$(CONFIG_VIDEO_IVTV) += ivtv/ obj-$(CONFIG_VIDEO_VIVI) += vivi.o obj-$(CONFIG_VIDEO_CX23885) += cx23885/ +obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o obj-$(CONFIG_SOC_CAMERA) += soc_camera.o EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core diff --git a/linux/drivers/media/video/pxa_camera.c b/linux/drivers/media/video/pxa_camera.c new file mode 100644 index 000000000..11aecad76 --- /dev/null +++ b/linux/drivers/media/video/pxa_camera.c @@ -0,0 +1,937 @@ +/* + * V4L2 Driver for PXA camera host + * + * Copyright (C) 2006, Sascha Hauer, Pengutronix + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#define PXA_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 5) +#define PXA_CAM_DRV_NAME "pxa27x-camera" + +#define CICR0_IRQ_MASK (CICR0_TOM | CICR0_RDAVM | CICR0_FEM | CICR0_EOLM | \ + CICR0_PERRM | CICR0_QDM | CICR0_CDM | CICR0_SOFM | \ + CICR0_EOFM | CICR0_FOM) + +static DEFINE_MUTEX(camera_lock); + +/* + * Structures + */ + +/* buffer for one video frame */ +struct pxa_buffer { + /* common v4l buffer stuff -- must be first */ + struct videobuf_buffer vb; + + const struct soc_camera_data_format *fmt; + + /* our descriptor list needed for the PXA DMA engine */ + dma_addr_t sg_dma; + struct pxa_dma_desc *sg_cpu; + size_t sg_size; + int inwork; +}; + +struct pxa_framebuffer_queue { + dma_addr_t sg_last_dma; + struct pxa_dma_desc *sg_last_cpu; +}; + +struct pxa_camera_dev { + struct device *dev; + /* PXA27x is only supposed to handle one camera on its Quick Capture + * interface. If anyone ever builds hardware to enable more than + * one camera, they will have to modify this driver too */ + struct soc_camera_device *icd; + struct clk *clk; + + unsigned int irq; + void __iomem *base; + unsigned int dma_chan_y; + + enum v4l2_buf_type type; + + struct pxacamera_platform_data *pdata; + struct resource *res; + unsigned long platform_flags; + unsigned long platform_mclk_10khz; + + struct list_head capture; + + spinlock_t lock; + + int dma_running; + + struct pxa_buffer *active; +}; + +static const char *pxa_cam_driver_description = "PXA_Camera"; + +static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ + +/* + * Videobuf operations + */ +static int +pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, + unsigned int *size) +{ + struct soc_camera_device *icd = vq->priv_data; + + dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size); + + *size = icd->width * icd->height * ((icd->current_fmt->depth + 7) >> 3); + + if (0 == *count) + *count = 32; + while (*size * *count > vid_limit * 1024 * 1024) + (*count)--; + + return 0; +} + +static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf) +{ + struct soc_camera_device *icd = vq->priv_data; + struct soc_camera_host *ici = + to_soc_camera_host(icd->dev.parent); + struct pxa_camera_dev *pcdev = ici->priv; + struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); + + BUG_ON(in_interrupt()); + + dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __FUNCTION__, + &buf->vb, buf->vb.baddr, buf->vb.bsize); + + /* This waits until this buffer is out of danger, i.e., until it is no + * longer in STATE_QUEUED or STATE_ACTIVE */ + videobuf_waiton(&buf->vb, 0, 0); + videobuf_dma_unmap(vq, dma); + videobuf_dma_free(dma); + + if (buf->sg_cpu) + dma_free_coherent(pcdev->dev, buf->sg_size, buf->sg_cpu, + buf->sg_dma); + buf->sg_cpu = NULL; + + buf->vb.state = VIDEOBUF_NEEDS_INIT; +} + +static int +pxa_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, + enum v4l2_field field) +{ + struct soc_camera_device *icd = vq->priv_data; + struct soc_camera_host *ici = + to_soc_camera_host(icd->dev.parent); + struct pxa_camera_dev *pcdev = ici->priv; + struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); + int i, ret; + + dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __FUNCTION__, + vb, vb->baddr, vb->bsize); + + /* Added list head initialization on alloc */ + WARN_ON(!list_empty(&vb->queue)); + +#ifdef DEBUG + /* This can be useful if you want to see if we actually fill + * the buffer with something */ + memset((void *)vb->baddr, 0xaa, vb->bsize); +#endif + + BUG_ON(NULL == icd->current_fmt); + + /* I think, in buf_prepare you only have to protect global data, + * the actual buffer is yours */ + buf->inwork = 1; + + if (buf->fmt != icd->current_fmt || + vb->width != icd->width || + vb->height != icd->height || + vb->field != field) { + buf->fmt = icd->current_fmt; + vb->width = icd->width; + vb->height = icd->height; + vb->field = field; + vb->state = VIDEOBUF_NEEDS_INIT; + } + + vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3); + if (0 != vb->baddr && vb->bsize < vb->size) { + ret = -EINVAL; + goto out; + } + + if (vb->state == VIDEOBUF_NEEDS_INIT) { + unsigned int size = vb->size; + struct videobuf_dmabuf *dma = videobuf_to_dma(vb); + + ret = videobuf_iolock(vq, vb, NULL); + if (ret) + goto fail; + + if (buf->sg_cpu) + dma_free_coherent(pcdev->dev, buf->sg_size, buf->sg_cpu, + buf->sg_dma); + + buf->sg_size = (dma->sglen + 1) * sizeof(struct pxa_dma_desc); + buf->sg_cpu = dma_alloc_coherent(pcdev->dev, buf->sg_size, + &buf->sg_dma, GFP_KERNEL); + if (!buf->sg_cpu) { + ret = -ENOMEM; + goto fail; + } + + dev_dbg(&icd->dev, "nents=%d size: %d sg=0x%p\n", + dma->sglen, size, dma->sglist); + for (i = 0; i < dma->sglen; i++) { + struct scatterlist *sg = dma->sglist; + unsigned int dma_len = sg_dma_len(&sg[i]), xfer_len; + + /* CIBR0 */ + buf->sg_cpu[i].dsadr = pcdev->res->start + 0x28; + buf->sg_cpu[i].dtadr = sg_dma_address(&sg[i]); + /* PXA270 Developer's Manual 27.4.4.1: + * round up to 8 bytes */ + xfer_len = (min(dma_len, size) + 7) & ~7; + if (xfer_len & 7) + dev_err(&icd->dev, "Unaligned buffer: " + "dma_len %u, size %u\n", dma_len, size); + buf->sg_cpu[i].dcmd = DCMD_FLOWSRC | DCMD_BURST8 | + DCMD_INCTRGADDR | xfer_len; + size -= dma_len; + buf->sg_cpu[i].ddadr = buf->sg_dma + (i + 1) * + sizeof(struct pxa_dma_desc); + } + buf->sg_cpu[dma->sglen - 1].ddadr = DDADR_STOP; + buf->sg_cpu[dma->sglen - 1].dcmd |= DCMD_ENDIRQEN; + + vb->state = VIDEOBUF_PREPARED; + } + + buf->inwork = 0; + + return 0; + +fail: + free_buffer(vq, buf); +out: + buf->inwork = 0; + return ret; +} + +static void +pxa_videobuf_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) +{ + struct soc_camera_device *icd = vq->priv_data; + struct soc_camera_host *ici = + to_soc_camera_host(icd->dev.parent); + struct pxa_camera_dev *pcdev = ici->priv; + struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); + struct pxa_buffer *active = pcdev->active; + struct videobuf_dmabuf *dma = videobuf_to_dma(vb); + int nents = dma->sglen; + unsigned long flags; + + dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __FUNCTION__, + vb, vb->baddr, vb->bsize); + spin_lock_irqsave(&pcdev->lock, flags); + + list_add_tail(&vb->queue, &pcdev->capture); + + vb->state = VIDEOBUF_ACTIVE; + + if (!pcdev->active) { + CIFR |= CIFR_RESET_F; + DDADR(pcdev->dma_chan_y) = buf->sg_dma; + DCSR(pcdev->dma_chan_y) = DCSR_RUN; + pcdev->active = buf; + CICR0 |= CICR0_ENB; + } else { + struct videobuf_dmabuf *active_dma = + videobuf_to_dma(&active->vb); + /* Stop DMA engine */ + DCSR(pcdev->dma_chan_y) = 0; + + /* Add the descriptors we just initialized to the currently + * running chain + */ + active->sg_cpu[active_dma->sglen - 1].ddadr = buf->sg_dma; + + /* Setup a dummy descriptor with the DMA engines current + * state + */ + /* CIBR0 */ + buf->sg_cpu[nents].dsadr = pcdev->res->start + 0x28; + buf->sg_cpu[nents].dtadr = DTADR(pcdev->dma_chan_y); + buf->sg_cpu[nents].dcmd = DCMD(pcdev->dma_chan_y); + + if (DDADR(pcdev->dma_chan_y) == DDADR_STOP) { + /* The DMA engine is on the last descriptor, set the + * next descriptors address to the descriptors + * we just initialized + */ + buf->sg_cpu[nents].ddadr = buf->sg_dma; + } else { + buf->sg_cpu[nents].ddadr = DDADR(pcdev->dma_chan_y); + } + + /* The next descriptor is the dummy descriptor */ + DDADR(pcdev->dma_chan_y) = buf->sg_dma + nents * + sizeof(struct pxa_dma_desc); + +#ifdef DEBUG + if (CISR & CISR_IFO_0) { + dev_warn(pcdev->dev, "FIFO overrun\n"); + DDADR(pcdev->dma_chan_y) = pcdev->active->sg_dma; + + CICR0 &= ~CICR0_ENB; + CIFR |= CIFR_RESET_F; + DCSR(pcdev->dma_chan_y) = DCSR_RUN; + CICR0 |= CICR0_ENB; + } else +#endif + DCSR(pcdev->dma_chan_y) = DCSR_RUN; + } + + spin_unlock_irqrestore(&pcdev->lock, flags); + +} + +static void pxa_videobuf_release(struct videobuf_queue *vq, + struct videobuf_buffer *vb) +{ + struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); +#ifdef DEBUG + struct soc_camera_device *icd = vq->priv_data; + + dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __FUNCTION__, + vb, vb->baddr, vb->bsize); + + switch (vb->state) { + case VIDEOBUF_ACTIVE: + dev_dbg(&icd->dev, "%s (active)\n", __FUNCTION__); + break; + case VIDEOBUF_QUEUED: + dev_dbg(&icd->dev, "%s (queued)\n", __FUNCTION__); + break; + case VIDEOBUF_PREPARED: + dev_dbg(&icd->dev, "%s (prepared)\n", __FUNCTION__); + break; + default: + dev_dbg(&icd->dev, "%s (unknown)\n", __FUNCTION__); + break; + } +#endif + + free_buffer(vq, buf); +} + +static void pxa_camera_dma_irq_y(int channel, void *data) +{ + struct pxa_camera_dev *pcdev = data; + struct pxa_buffer *buf; + unsigned long flags; + unsigned int status; + struct videobuf_buffer *vb; + + spin_lock_irqsave(&pcdev->lock, flags); + + status = DCSR(pcdev->dma_chan_y); + if (status & DCSR_BUSERR) { + dev_err(pcdev->dev, "%s: Bus Error\n", __FUNCTION__); + DCSR(pcdev->dma_chan_y) |= DCSR_BUSERR; + goto out; + } + + if (!(status & DCSR_ENDINTR)) { + dev_err(pcdev->dev, "%s: unknown dma interrupt source. " + "status: 0x%08x\n", __FUNCTION__, status); + goto out; + } + + DCSR(pcdev->dma_chan_y) |= DCSR_ENDINTR; + + if (!pcdev->active) { + dev_err(pcdev->dev, "%s: no active buf\n", __FUNCTION__); + goto out; + } + + vb = &pcdev->active->vb; + buf = container_of(vb, struct pxa_buffer, vb); + WARN_ON(buf->inwork || list_empty(&vb->queue)); + dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __FUNCTION__, + vb, vb->baddr, vb->bsize); + + /* _init is used to debug races, see comment in pxa_is_reqbufs() */ + list_del_init(&vb->queue); + vb->state = VIDEOBUF_DONE; + do_gettimeofday(&vb->ts); + vb->field_count++; + wake_up(&vb->done); + + if (list_empty(&pcdev->capture)) { + pcdev->active = NULL; + DCSR(pcdev->dma_chan_y) = 0; + CICR0 &= ~CICR0_ENB; + goto out; + } + + pcdev->active = list_entry(pcdev->capture.next, struct pxa_buffer, + vb.queue); + +out: + spin_unlock_irqrestore(&pcdev->lock, flags); +} + +static struct videobuf_queue_ops pxa_video_ops = { + .buf_setup = pxa_videobuf_setup, + .buf_prepare = pxa_videobuf_prepare, + .buf_queue = pxa_videobuf_queue, + .buf_release = pxa_videobuf_release, +}; + +static int mclk_get_divisor(struct pxa_camera_dev *pcdev) +{ + unsigned int mclk_10khz = pcdev->platform_mclk_10khz; + unsigned long div; + unsigned long lcdclk; + + lcdclk = clk_get_rate(pcdev->clk) / 10000; + + /* We verify platform_mclk_10khz != 0, so if anyone breaks it, here + * they get a nice Oops */ + div = (lcdclk + 2 * mclk_10khz - 1) / (2 * mclk_10khz) - 1; + + dev_dbg(pcdev->dev, "LCD clock %lukHz, target freq %dkHz, " + "divisor %lu\n", lcdclk * 10, mclk_10khz * 10, div); + + return div; +} + +static void pxa_is_activate(struct pxa_camera_dev *pcdev) +{ + struct pxacamera_platform_data *pdata = pcdev->pdata; + u32 cicr4 = 0; + + dev_dbg(pcdev->dev, "Registered platform device at %p data %p\n", + pcdev, pdata); + + if (pdata && pdata->init) { + dev_dbg(pcdev->dev, "%s: Init gpios\n", __FUNCTION__); + pdata->init(pcdev->dev); + } + + if (pdata && pdata->power) { + dev_dbg(pcdev->dev, "%s: Power on camera\n", __FUNCTION__); + pdata->power(pcdev->dev, 1); + } + + if (pdata && pdata->reset) { + dev_dbg(pcdev->dev, "%s: Releasing camera reset\n", + __FUNCTION__); + pdata->reset(pcdev->dev, 1); + } + + CICR0 = 0x3FF; /* disable all interrupts */ + + if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) + cicr4 |= CICR4_PCLK_EN; + if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN) + cicr4 |= CICR4_MCLK_EN; + if (pcdev->platform_flags & PXA_CAMERA_PCP) + cicr4 |= CICR4_PCP; + if (pcdev->platform_flags & PXA_CAMERA_HSP) + cicr4 |= CICR4_HSP; + if (pcdev->platform_flags & PXA_CAMERA_VSP) + cicr4 |= CICR4_VSP; + + CICR4 = mclk_get_divisor(pcdev) | cicr4; + + clk_enable(pcdev->clk); +} + +static void pxa_is_deactivate(struct pxa_camera_dev *pcdev) +{ + struct pxacamera_platform_data *board = pcdev->pdata; + + clk_disable(pcdev->clk); + + if (board && board->reset) { + dev_dbg(pcdev->dev, "%s: Asserting camera reset\n", + __FUNCTION__); + board->reset(pcdev->dev, 0); + } + + if (board && board->power) { + dev_dbg(pcdev->dev, "%s: Power off camera\n", __FUNCTION__); + board->power(pcdev->dev, 0); + } +} + +static irqreturn_t pxa_camera_irq(int irq, void *data) +{ + struct pxa_camera_dev *pcdev = data; + unsigned int status = CISR; + + dev_dbg(pcdev->dev, "Camera interrupt status 0x%x\n", status); + + CISR = status; + + return IRQ_HANDLED; +} + +/* The following two functions absolutely depend on the fact, that + * there can be only one camera on PXA quick capture interface */ +static int pxa_is_add_device(struct soc_camera_device *icd) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct pxa_camera_dev *pcdev = ici->priv; + int ret; + + mutex_lock(&camera_lock); + + if (pcdev->icd) { + ret = -EBUSY; + goto ebusy; + } + + dev_info(&icd->dev, "PXA Camera driver attached to camera %d\n", + icd->devnum); + + pxa_is_activate(pcdev); + ret = icd->ops->init(icd); + + if (!ret) + pcdev->icd = icd; + +ebusy: + mutex_unlock(&camera_lock); + + return ret; +} + +static void pxa_is_remove_device(struct soc_camera_device *icd) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct pxa_camera_dev *pcdev = ici->priv; + + BUG_ON(icd != pcdev->icd); + + dev_info(&icd->dev, "PXA Camera driver detached from camera %d\n", + icd->devnum); + + /* disable capture, disable interrupts */ + CICR0 = 0x3ff; + /* Stop DMA engine */ + DCSR(pcdev->dma_chan_y) = 0; + + icd->ops->release(icd); + + pxa_is_deactivate(pcdev); + + pcdev->icd = NULL; +} + +static int pxa_is_set_capture_format(struct soc_camera_device *icd, + __u32 pixfmt, struct v4l2_rect *rect) +{ + struct soc_camera_host *ici = + to_soc_camera_host(icd->dev.parent); + struct pxa_camera_dev *pcdev = ici->priv; + unsigned int datawidth = 0, dw, bpp; + u32 cicr0, cicr4 = 0; + int ret; + + /* If requested data width is supported by the platform, use it */ + switch (icd->cached_datawidth) { + case 10: + if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10) + datawidth = IS_DATAWIDTH_10; + break; + case 9: + if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_9) + datawidth = IS_DATAWIDTH_9; + break; + case 8: + if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8) + datawidth = IS_DATAWIDTH_8; + } + if (!datawidth) + return -EINVAL; + + ret = icd->ops->set_capture_format(icd, pixfmt, rect, + datawidth | + (pcdev->platform_flags & PXA_CAMERA_MASTER ? + IS_MASTER : 0) | + (pcdev->platform_flags & PXA_CAMERA_HSP ? + 0 : IS_HSYNC_ACTIVE_HIGH) | + (pcdev->platform_flags & PXA_CAMERA_VSP ? + 0 : IS_VSYNC_ACTIVE_HIGH) | + (pcdev->platform_flags & PXA_CAMERA_PCP ? + 0 : IS_PCLK_SAMPLE_RISING)); + if (ret < 0) + return ret; + + /* Datawidth is now guaranteed to be equal to one of the three values. + * We fix bit-per-pixel equal to data-width... */ + switch (datawidth) { + case IS_DATAWIDTH_10: + icd->cached_datawidth = 10; + dw = 4; + bpp = 0x40; + break; + case IS_DATAWIDTH_9: + icd->cached_datawidth = 9; + dw = 3; + bpp = 0x20; + break; + default: + /* Actually it can only be 8 now, + * default is just to silence compiler warnings */ + case IS_DATAWIDTH_8: + icd->cached_datawidth = 8; + dw = 2; + bpp = 0; + } + + if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) + cicr4 |= CICR4_PCLK_EN; + if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN) + cicr4 |= CICR4_MCLK_EN; + if (pcdev->platform_flags & PXA_CAMERA_PCP) + cicr4 |= CICR4_PCP; + if (pcdev->platform_flags & PXA_CAMERA_HSP) + cicr4 |= CICR4_HSP; + if (pcdev->platform_flags & PXA_CAMERA_VSP) + cicr4 |= CICR4_VSP; + + cicr0 = CICR0; + if (cicr0 & CICR0_ENB) + CICR0 = cicr0 & ~CICR0_ENB; + CICR1 = CICR1_PPL_VAL(rect->width - 1) | bpp | dw; + CICR2 = 0; + CICR3 = CICR3_LPF_VAL(rect->height - 1) | + CICR3_BFW_VAL(min((unsigned short)255, icd->y_skip_top)); + CICR4 = mclk_get_divisor(pcdev) | cicr4; + + /* CIF interrupts are not used, only DMA */ + CICR0 = (pcdev->platform_flags & PXA_CAMERA_MASTER ? + 0 : (CICR0_SL_CAP_EN | CICR0_SIM_SP)) | + CICR0_DMAEN | CICR0_IRQ_MASK | (cicr0 & CICR0_ENB); + + return 0; +} + +static int pxa_is_try_fmt_cap(struct soc_camera_host *ici, + struct v4l2_format *f) +{ + /* limit to pxa hardware capabilities */ + if (f->fmt.pix.height < 32) + f->fmt.pix.height = 32; + if (f->fmt.pix.height > 2048) + f->fmt.pix.height = 2048; + if (f->fmt.pix.width < 48) + f->fmt.pix.width = 48; + if (f->fmt.pix.width > 2048) + f->fmt.pix.width = 2048; + f->fmt.pix.width &= ~0x01; + + return 0; +} + +static int pxa_is_reqbufs(struct soc_camera_file *icf, + struct v4l2_requestbuffers *p) +{ + int i; + + /* This is for locking debugging only. I removed spinlocks and now I + * check whether .prepare is ever called on a linked buffer, or whether + * a dma IRQ can occur for an in-work or unlinked buffer. Until now + * it hadn't triggered */ + for (i = 0; i < p->count; i++) { + struct pxa_buffer *buf = container_of(icf->vb_vidq.bufs[i], + struct pxa_buffer, vb); + buf->inwork = 0; + INIT_LIST_HEAD(&buf->vb.queue); + } + + return 0; +} + +static unsigned int pxa_is_poll(struct file *file, poll_table *pt) +{ + struct soc_camera_file *icf = file->private_data; + struct pxa_buffer *buf; + + buf = list_entry(icf->vb_vidq.stream.next, struct pxa_buffer, + vb.stream); + + poll_wait(file, &buf->vb.done, pt); + + if (buf->vb.state == VIDEOBUF_DONE || + buf->vb.state == VIDEOBUF_ERROR) + return POLLIN|POLLRDNORM; + + return 0; +} + +static int pxa_is_querycap(struct soc_camera_host *ici, + struct v4l2_capability *cap) +{ + /* cap->name is set by the firendly caller:-> */ + strlcpy(cap->card, pxa_cam_driver_description, sizeof(cap->card)); + cap->version = PXA_CAM_VERSION_CODE; + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + + return 0; +} + +/* Should beallocated dynamically too, but we have only one. */ +static struct soc_camera_host pxa_soc_camera_host = { + .drv_name = PXA_CAM_DRV_NAME, + .vbq_ops = &pxa_video_ops, + .add = pxa_is_add_device, + .remove = pxa_is_remove_device, + .msize = sizeof(struct pxa_buffer), + .set_capture_format = pxa_is_set_capture_format, + .try_fmt_cap = pxa_is_try_fmt_cap, + .reqbufs = pxa_is_reqbufs, + .poll = pxa_is_poll, + .querycap = pxa_is_querycap, +}; + +static int pxa_camera_probe(struct platform_device *pdev) +{ + struct pxa_camera_dev *pcdev; + struct resource *res; + void __iomem *base; + unsigned int irq; + int err = 0; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); + if (!res || !irq) { + err = -ENODEV; + goto exit; + } + + pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL); + if (!pcdev) { + dev_err(&pdev->dev, "%s: Could not allocate pcdev\n", + __FUNCTION__); + err = -ENOMEM; + goto exit; + } + + pcdev->clk = clk_get(&pdev->dev, "CAMCLK"); + if (IS_ERR(pcdev->clk)) { + err = PTR_ERR(pcdev->clk); + goto exit_kfree; + } + + dev_set_drvdata(&pdev->dev, pcdev); + pcdev->res = res; + + pcdev->pdata = pdev->dev.platform_data; + pcdev->platform_flags = pcdev->pdata->flags; + if (!pcdev->platform_flags & (PXA_CAMERA_DATAWIDTH_8 | + PXA_CAMERA_DATAWIDTH_9 | PXA_CAMERA_DATAWIDTH_10)) { + /* Platform hasn't set available data widths. This is bad. + * Warn and use a default. */ + dev_warn(&pdev->dev, "WARNING! Platform hasn't set available " + "data widths, using default 10 bit\n"); + pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10; + } + pcdev->platform_mclk_10khz = pcdev->pdata->mclk_10khz; + if (!pcdev->platform_mclk_10khz) { + dev_warn(&pdev->dev, + "mclk_10khz == 0! Please, fix your platform data. " + "Using default 20MHz\n"); + pcdev->platform_mclk_10khz = 2000; + } + + INIT_LIST_HEAD(&pcdev->capture); + spin_lock_init(&pcdev->lock); + + /* + * Request the regions. + */ + if (!request_mem_region(res->start, res->end - res->start + 1, + PXA_CAM_DRV_NAME)) { + err = -EBUSY; + goto exit_clk; + } + + base = ioremap(res->start, res->end - res->start + 1); + if (!base) { + err = -ENOMEM; + goto exit_release; + } + pcdev->irq = irq; + pcdev->base = base; + pcdev->dev = &pdev->dev; + + /* request dma */ + pcdev->dma_chan_y = pxa_request_dma("CI_Y", DMA_PRIO_HIGH, + pxa_camera_dma_irq_y, pcdev); + if (pcdev->dma_chan_y < 0) { + dev_err(pcdev->dev, "Can't request DMA for Y\n"); + err = -ENOMEM; + goto exit_iounmap; + } + dev_dbg(pcdev->dev, "got DMA channel %d\n", pcdev->dma_chan_y); + + DRCMR68 = pcdev->dma_chan_y | DRCMR_MAPVLD; + + /* request irq */ + err = request_irq(pcdev->irq, pxa_camera_irq, 0, PXA_CAM_DRV_NAME, + pcdev); + if (err) { + dev_err(pcdev->dev, "Camera interrupt register failed \n"); + goto exit_free_dma; + } + + pxa_soc_camera_host.priv = pcdev; + pxa_soc_camera_host.dev.parent = &pdev->dev; + pxa_soc_camera_host.nr = pdev->id; + err = soc_camera_host_register(&pxa_soc_camera_host, THIS_MODULE); + if (err) + goto exit_free_irq; + + return 0; + +exit_free_irq: + free_irq(pcdev->irq, pcdev); +exit_free_dma: + pxa_free_dma(pcdev->dma_chan_y); +exit_iounmap: + iounmap(base); +exit_release: + release_mem_region(res->start, res->end - res->start + 1); +exit_clk: + clk_put(pcdev->clk); +exit_kfree: + kfree(pcdev); +exit: + return err; +} + +static int __devexit pxa_camera_remove(struct platform_device *pdev) +{ + struct pxa_camera_dev *pcdev = platform_get_drvdata(pdev); + struct resource *res; + + clk_put(pcdev->clk); + + pxa_free_dma(pcdev->dma_chan_y); + free_irq(pcdev->irq, pcdev); + + soc_camera_host_unregister(&pxa_soc_camera_host); + + iounmap(pcdev->base); + + res = pcdev->res; + release_mem_region(res->start, res->end - res->start + 1); + + kfree(pcdev); + + dev_info(&pdev->dev, "%s: PXA Camera driver unloaded\n", __FUNCTION__); + + return 0; +} + +/* + * Suspend the Camera Module. + */ +static int pxa_camera_suspend(struct platform_device *pdev, pm_message_t level) +{ + struct pxa_camera_dev *pcdev = platform_get_drvdata(pdev); + + dev_info(&pdev->dev, "camera suspend\n"); + disable_irq(pcdev->irq); + return 0; +} + +/* + * Resume the Camera Module. + */ +static int pxa_camera_resume(struct platform_device *pdev) +{ + struct pxa_camera_dev *pcdev = platform_get_drvdata(pdev); + + dev_info(&pdev->dev, "camera resume\n"); + enable_irq(pcdev->irq); + +/* if (pcdev) { */ /* FIXME: dev in use? */ +/* DRCMR68 = pcdev->dma_chan_y | DRCMR_MAPVLD; */ +/* DRCMR69 = pcdev->dma_chan_cb | DRCMR_MAPVLD; */ +/* DRCMR70 = pcdev->dma_chan_cr | DRCMR_MAPVLD; */ +/* } */ + + return 0; +} + + +static struct platform_driver pxa_camera_driver = { + .driver = { + .name = PXA_CAM_DRV_NAME, + }, + .probe = pxa_camera_probe, + .remove = __exit_p(pxa_camera_remove), + .suspend = pxa_camera_suspend, + .resume = pxa_camera_resume, +}; + + +static int __devinit pxa_camera_init(void) +{ + return platform_driver_register(&pxa_camera_driver); +} + +static void __exit pxa_camera_exit(void) +{ + return platform_driver_unregister(&pxa_camera_driver); +} + +module_init(pxa_camera_init); +module_exit(pxa_camera_exit); + +MODULE_DESCRIPTION("PXA27x SoC Camera Host driver"); +MODULE_AUTHOR("Guennadi Liakhovetski "); +MODULE_LICENSE("GPL"); diff --git a/linux/include/asm-arm/arch-pxa/camera.h b/linux/include/asm-arm/arch-pxa/camera.h new file mode 100644 index 000000000..39516ced8 --- /dev/null +++ b/linux/include/asm-arm/arch-pxa/camera.h @@ -0,0 +1,48 @@ +/* + camera.h - PXA camera driver header file + + Copyright (C) 2003, Intel Corporation + Copyright (C) 2008, Guennadi Liakhovetski + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License 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 __ASM_ARCH_CAMERA_H_ +#define __ASM_ARCH_CAMERA_H_ + +#define PXA_CAMERA_MASTER 1 +#define PXA_CAMERA_DATAWIDTH_4 2 +#define PXA_CAMERA_DATAWIDTH_5 4 +#define PXA_CAMERA_DATAWIDTH_8 8 +#define PXA_CAMERA_DATAWIDTH_9 0x10 +#define PXA_CAMERA_DATAWIDTH_10 0x20 +#define PXA_CAMERA_PCLK_EN 0x40 +#define PXA_CAMERA_MCLK_EN 0x80 +#define PXA_CAMERA_PCP 0x100 +#define PXA_CAMERA_HSP 0x200 +#define PXA_CAMERA_VSP 0x400 + +struct pxacamera_platform_data { + int (*init)(struct device *); + int (*power)(struct device *, int); + int (*reset)(struct device *, int); + + unsigned long flags; + unsigned long mclk_10khz; +}; + +extern void pxa_set_camera_info(struct pxacamera_platform_data *); + +#endif /* __ASM_ARCH_CAMERA_H_ */ diff --git a/linux/include/asm-arm/arch-pxa/pxa-regs.h b/linux/include/asm-arm/arch-pxa/pxa-regs.h index 16ed24dbd..2eb05e746 100644 --- a/linux/include/asm-arm/arch-pxa/pxa-regs.h +++ b/linux/include/asm-arm/arch-pxa/pxa-regs.h @@ -46,13 +46,13 @@ #define PCMCIA1AttrSp PCMCIAAttrSp /* PCMCIA 1 Attribute Space [byte] */ #define PCMCIA1MemSp PCMCIAMemSp /* PCMCIA 1 Memory Space [byte] */ -#define _PCMCIA(Nb) /* PCMCIA [0..1] */ \ - (0x20000000 + (Nb)*PCMCIASp) +#define _PCMCIA(Nb) /* PCMCIA [0..1] */ \ + (0x20000000 + (Nb)*PCMCIASp) #define _PCMCIAIO(Nb) _PCMCIA (Nb) /* PCMCIA I/O [0..1] */ -#define _PCMCIAAttr(Nb) /* PCMCIA Attribute [0..1] */ \ - (_PCMCIA (Nb) + 2*PCMCIAPrtSp) -#define _PCMCIAMem(Nb) /* PCMCIA Memory [0..1] */ \ - (_PCMCIA (Nb) + 3*PCMCIAPrtSp) +#define _PCMCIAAttr(Nb) /* PCMCIA Attribute [0..1] */ \ + (_PCMCIA (Nb) + 2*PCMCIAPrtSp) +#define _PCMCIAMem(Nb) /* PCMCIA Memory [0..1] */ \ + (_PCMCIA (Nb) + 3*PCMCIAPrtSp) #define _PCMCIA0 _PCMCIA (0) /* PCMCIA 0 */ #define _PCMCIA0IO _PCMCIAIO (0) /* PCMCIA 0 I/O */ @@ -1232,19 +1232,26 @@ #define GPIO10_RTCCLK 10 /* real time clock (1 Hz) */ #define GPIO11_3_6MHz 11 /* 3.6 MHz oscillator out */ #define GPIO12_32KHz 12 /* 32 kHz out */ +#define GPIO12_CIF_DD7 12 /* Capture Interface D7 (PXA27x) */ #define GPIO13_MBGNT 13 /* memory controller grant */ #define GPIO14_MBREQ 14 /* alternate bus master request */ #define GPIO15_nCS_1 15 /* chip select 1 */ #define GPIO16_PWM0 16 /* PWM0 output */ #define GPIO17_PWM1 17 /* PWM1 output */ +#define GPIO17_CIF_DD6 17 /* Capture Interface D6 (PXA27x) */ #define GPIO18_RDY 18 /* Ext. Bus Ready */ #define GPIO19_DREQ1 19 /* External DMA Request */ #define GPIO20_DREQ0 20 /* External DMA Request */ #define GPIO23_SCLK 23 /* SSP clock */ +#define GPIO23_CIF_MCLK 23 /* Capture Interface MCLK (PXA27x) */ #define GPIO24_SFRM 24 /* SSP Frame */ +#define GPIO24_CIF_FV 24 /* Capture Interface FV (PXA27x) */ #define GPIO25_STXD 25 /* SSP transmit */ +#define GPIO25_CIF_LV 25 /* Capture Interface LV (PXA27x) */ #define GPIO26_SRXD 26 /* SSP receive */ +#define GPIO26_CIF_PCLK 26 /* Capture Interface PCLK (PXA27x) */ #define GPIO27_SEXTCLK 27 /* SSP ext_clk */ +#define GPIO27_CIF_DD0 27 /* Capture Interface D0 (PXA27x) */ #define GPIO28_BITCLK 28 /* AC97/I2S bit_clk */ #define GPIO29_SDATA_IN 29 /* AC97 Sdata_in0 / I2S Sdata_in */ #define GPIO30_SDATA_OUT 30 /* AC97/I2S Sdata_out */ @@ -1265,28 +1272,40 @@ #define GPIO41_FFRTS 41 /* FFUART request to send */ #define GPIO42_BTRXD 42 /* BTUART receive data */ #define GPIO42_HWRXD 42 /* HWUART receive data */ +#define GPIO42_CIF_MCLK 42 /* Capture interface MCLK (PXA27x) */ #define GPIO43_BTTXD 43 /* BTUART transmit data */ #define GPIO43_HWTXD 43 /* HWUART transmit data */ +#define GPIO43_CIF_FV 43 /* Capture interface FV (PXA27x) */ #define GPIO44_BTCTS 44 /* BTUART clear to send */ #define GPIO44_HWCTS 44 /* HWUART clear to send */ +#define GPIO44_CIF_LV 44 /* Capture interface LV (PXA27x) */ #define GPIO45_BTRTS 45 /* BTUART request to send */ #define GPIO45_HWRTS 45 /* HWUART request to send */ #define GPIO45_AC97_SYSCLK 45 /* AC97 System Clock */ +#define GPIO45_CIF_PCLK 45 /* Capture interface PCLK (PXA27x) */ #define GPIO46_ICPRXD 46 /* ICP receive data */ #define GPIO46_STRXD 46 /* STD_UART receive data */ #define GPIO47_ICPTXD 47 /* ICP transmit data */ #define GPIO47_STTXD 47 /* STD_UART transmit data */ +#define GPIO47_CIF_DD0 47 /* Capture interface D0 (PXA27x) */ #define GPIO48_nPOE 48 /* Output Enable for Card Space */ +#define GPIO48_CIF_DD5 48 /* Capture interface D5 (PXA27x) */ #define GPIO49_nPWE 49 /* Write Enable for Card Space */ #define GPIO50_nPIOR 50 /* I/O Read for Card Space */ +#define GPIO50_CIF_DD3 50 /* Capture interface D3 (PXA27x) */ #define GPIO51_nPIOW 51 /* I/O Write for Card Space */ +#define GPIO51_CIF_DD2 51 /* Capture interface D2 (PXA27x) */ #define GPIO52_nPCE_1 52 /* Card Enable for Card Space */ +#define GPIO52_CIF_DD4 52 /* Capture interface D4 (PXA27x) */ #define GPIO53_nPCE_2 53 /* Card Enable for Card Space */ #define GPIO53_MMCCLK 53 /* MMC Clock */ +#define GPIO53_CIF_MCLK 53 /* Capture interface MCLK (PXA27x) */ #define GPIO54_MMCCLK 54 /* MMC Clock */ #define GPIO54_pSKTSEL 54 /* Socket Select for Card Space */ #define GPIO54_nPCE_2 54 /* Card Enable for Card Space (PXA27x) */ +#define GPIO54_CIF_PCLK 54 /* Capture interface PCLK (PXA27x) */ #define GPIO55_nPREG 55 /* Card Address bit 26 */ +#define GPIO55_CIF_DD1 55 /* Capture interface D1 (PXA27x) */ #define GPIO56_nPWAIT 56 /* Wait signal for Card Space */ #define GPIO57_nIOIS16 57 /* Bus Width select for I/O Card Space */ #define GPIO58_LDD_0 58 /* LCD data pin 0 */ @@ -1321,11 +1340,28 @@ #define GPIO79_nCS_3 79 /* chip select 3 */ #define GPIO80_nCS_4 80 /* chip select 4 */ #define GPIO81_NSCLK 81 /* NSSP clock */ +#define GPIO81_CIF_DD0 81 /* Capture Interface D0 (PXA27x) */ #define GPIO82_NSFRM 82 /* NSSP Frame */ +#define GPIO82_CIF_DD5 82 /* Capture Interface D5 (PXA27x) */ #define GPIO83_NSTXD 83 /* NSSP transmit */ +#define GPIO83_CIF_DD4 83 /* Capture Interface D4 (PXA27x) */ #define GPIO84_NSRXD 84 /* NSSP receive */ +#define GPIO84_CIF_FV 84 /* Capture Interface FV (PXA27x) */ #define GPIO85_nPCE_1 85 /* Card Enable for Card Space (PXA27x) */ +#define GPIO85_CIF_LV 85 /* Capture Interface LV (PXA27x) */ +#define GPIO90_CIF_DD4 90 /* Capture Interface DD4 (PXA27x) */ +#define GPIO91_CIF_DD5 91 /* Capture Interface DD5 (PXA27x) */ #define GPIO92_MMCDAT0 92 /* MMC DAT0 (PXA27x) */ +#define GPIO93_CIF_DD6 93 /* Capture interface D6 (PXA27x) */ +#define GPIO94_CIF_DD5 94 /* Capture interface D5 (PXA27x) */ +#define GPIO95_CIF_DD4 95 /* Capture interface D4 (PXA27x) */ +#define GPIO98_CIF_DD0 98 /* Capture interface D0 (PXA27x) */ +#define GPIO103_CIF_DD3 103 /* Capture interface D3 (PXA27x) */ +#define GPIO104_CIF_DD2 104 /* Capture interface D2 (PXA27x) */ +#define GPIO105_CIF_DD1 105 /* Capture interface D1 (PXA27x) */ +#define GPIO106_CIF_DD9 106 /* Capture interface D9 (PXA27x) */ +#define GPIO107_CIF_DD8 107 /* Capture interface D8 (PXA27x) */ +#define GPIO108_CIF_DD7 108 /* Capture interface D7 (PXA27x) */ #define GPIO102_nPCE_1 102 /* PCMCIA (PXA27x) */ #define GPIO109_MMCDAT1 109 /* MMC DAT1 (PXA27x) */ #define GPIO110_MMCDAT2 110 /* MMC DAT2 (PXA27x) */ @@ -1335,6 +1371,9 @@ #define GPIO112_MMCCMD 112 /* MMC CMD (PXA27x) */ #define GPIO113_I2S_SYSCLK 113 /* I2S System Clock (PXA27x) */ #define GPIO113_AC97_RESET_N 113 /* AC97 NRESET on (PXA27x) */ +#define GPIO114_CIF_DD1 114 /* Capture interface D1 (PXA27x) */ +#define GPIO115_CIF_DD3 115 /* Capture interface D3 (PXA27x) */ +#define GPIO116_CIF_DD2 116 /* Capture interface D2 (PXA27x) */ /* GPIO alternate function mode & direction */ @@ -1360,19 +1399,26 @@ #define GPIO10_RTCCLK_MD (10 | GPIO_ALT_FN_1_OUT) #define GPIO11_3_6MHz_MD (11 | GPIO_ALT_FN_1_OUT) #define GPIO12_32KHz_MD (12 | GPIO_ALT_FN_1_OUT) +#define GPIO12_CIF_DD7_MD (12 | GPIO_ALT_FN_2_IN) #define GPIO13_MBGNT_MD (13 | GPIO_ALT_FN_2_OUT) #define GPIO14_MBREQ_MD (14 | GPIO_ALT_FN_1_IN) #define GPIO15_nCS_1_MD (15 | GPIO_ALT_FN_2_OUT) #define GPIO16_PWM0_MD (16 | GPIO_ALT_FN_2_OUT) #define GPIO17_PWM1_MD (17 | GPIO_ALT_FN_2_OUT) +#define GPIO17_CIF_DD6_MD (17 | GPIO_ALT_FN_2_IN) #define GPIO18_RDY_MD (18 | GPIO_ALT_FN_1_IN) #define GPIO19_DREQ1_MD (19 | GPIO_ALT_FN_1_IN) #define GPIO20_DREQ0_MD (20 | GPIO_ALT_FN_1_IN) +#define GPIO23_CIF_MCLK_MD (23 | GPIO_ALT_FN_1_OUT) #define GPIO23_SCLK_MD (23 | GPIO_ALT_FN_2_OUT) +#define GPIO24_CIF_FV_MD (24 | GPIO_ALT_FN_1_OUT) #define GPIO24_SFRM_MD (24 | GPIO_ALT_FN_2_OUT) +#define GPIO25_CIF_LV_MD (25 | GPIO_ALT_FN_1_OUT) #define GPIO25_STXD_MD (25 | GPIO_ALT_FN_2_OUT) #define GPIO26_SRXD_MD (26 | GPIO_ALT_FN_1_IN) +#define GPIO26_CIF_PCLK_MD (26 | GPIO_ALT_FN_2_IN) #define GPIO27_SEXTCLK_MD (27 | GPIO_ALT_FN_1_IN) +#define GPIO27_CIF_DD0_MD (27 | GPIO_ALT_FN_3_IN) #define GPIO28_BITCLK_AC97_MD (28 | GPIO_ALT_FN_1_IN) #define GPIO28_BITCLK_IN_I2S_MD (28 | GPIO_ALT_FN_2_IN) #define GPIO28_BITCLK_OUT_I2S_MD (28 | GPIO_ALT_FN_1_OUT) @@ -1397,34 +1443,46 @@ #define GPIO40_FFDTR_MD (40 | GPIO_ALT_FN_2_OUT) #define GPIO41_FFRTS_MD (41 | GPIO_ALT_FN_2_OUT) #define GPIO42_BTRXD_MD (42 | GPIO_ALT_FN_1_IN) +#define GPIO42_CIF_MCLK_MD (42 | GPIO_ALT_FN_3_OUT) #define GPIO42_HWRXD_MD (42 | GPIO_ALT_FN_3_IN) #define GPIO43_BTTXD_MD (43 | GPIO_ALT_FN_2_OUT) +#define GPIO43_CIF_FV_MD (43 | GPIO_ALT_FN_3_OUT) #define GPIO43_HWTXD_MD (43 | GPIO_ALT_FN_3_OUT) #define GPIO44_BTCTS_MD (44 | GPIO_ALT_FN_1_IN) #define GPIO44_HWCTS_MD (44 | GPIO_ALT_FN_3_IN) +#define GPIO44_CIF_LV_MD (44 | GPIO_ALT_FN_3_OUT) #define GPIO45_BTRTS_MD (45 | GPIO_ALT_FN_2_OUT) #define GPIO45_HWRTS_MD (45 | GPIO_ALT_FN_3_OUT) #define GPIO45_SYSCLK_AC97_MD (45 | GPIO_ALT_FN_1_OUT) +#define GPIO45_CIF_PCLK_MD (45 | GPIO_ALT_FN_3_IN) #define GPIO46_ICPRXD_MD (46 | GPIO_ALT_FN_1_IN) #define GPIO46_STRXD_MD (46 | GPIO_ALT_FN_2_IN) #define GPIO47_ICPTXD_MD (47 | GPIO_ALT_FN_2_OUT) #define GPIO47_STTXD_MD (47 | GPIO_ALT_FN_1_OUT) +#define GPIO47_CIF_DD0_MD (47 | GPIO_ALT_FN_1_IN) #define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT) +#define GPIO48_CIF_DD5_MD (48 | GPIO_ALT_FN_1_IN) #define GPIO48_HWTXD_MD (48 | GPIO_ALT_FN_1_OUT) #define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT) #define GPIO49_HWRXD_MD (49 | GPIO_ALT_FN_1_IN) #define GPIO49_nPWE_MD (49 | GPIO_ALT_FN_2_OUT) #define GPIO50_nPIOR_MD (50 | GPIO_ALT_FN_2_OUT) +#define GPIO50_CIF_DD3_MD (50 | GPIO_ALT_FN_1_IN) #define GPIO50_HWCTS_MD (50 | GPIO_ALT_FN_1_IN) #define GPIO51_HWRTS_MD (51 | GPIO_ALT_FN_1_OUT) #define GPIO51_nPIOW_MD (51 | GPIO_ALT_FN_2_OUT) +#define GPIO51_CIF_DD2_MD (51 | GPIO_ALT_FN_1_IN) #define GPIO52_nPCE_1_MD (52 | GPIO_ALT_FN_2_OUT) +#define GPIO52_CIF_DD4_MD (52 | GPIO_ALT_FN_1_IN) #define GPIO53_nPCE_2_MD (53 | GPIO_ALT_FN_2_OUT) #define GPIO53_MMCCLK_MD (53 | GPIO_ALT_FN_1_OUT) +#define GPIO53_CIF_MCLK_MD (53 | GPIO_ALT_FN_2_OUT) #define GPIO54_MMCCLK_MD (54 | GPIO_ALT_FN_1_OUT) #define GPIO54_nPCE_2_MD (54 | GPIO_ALT_FN_2_OUT) #define GPIO54_pSKTSEL_MD (54 | GPIO_ALT_FN_2_OUT) +#define GPIO54_CIF_PCLK_MD (54 | GPIO_ALT_FN_3_IN) #define GPIO55_nPREG_MD (55 | GPIO_ALT_FN_2_OUT) +#define GPIO55_CIF_DD1_MD (55 | GPIO_ALT_FN_1_IN) #define GPIO56_nPWAIT_MD (56 | GPIO_ALT_FN_1_IN) #define GPIO57_nIOIS16_MD (57 | GPIO_ALT_FN_1_IN) #define GPIO58_LDD_0_MD (58 | GPIO_ALT_FN_2_OUT) @@ -1461,16 +1519,33 @@ #define GPIO80_nCS_4_MD (80 | GPIO_ALT_FN_2_OUT) #define GPIO81_NSSP_CLK_OUT (81 | GPIO_ALT_FN_1_OUT) #define GPIO81_NSSP_CLK_IN (81 | GPIO_ALT_FN_1_IN) +#define GPIO81_CIF_DD0_MD (81 | GPIO_ALT_FN_2_IN) #define GPIO82_NSSP_FRM_OUT (82 | GPIO_ALT_FN_1_OUT) #define GPIO82_NSSP_FRM_IN (82 | GPIO_ALT_FN_1_IN) +#define GPIO82_CIF_DD5_MD (82 | GPIO_ALT_FN_3_IN) #define GPIO83_NSSP_TX (83 | GPIO_ALT_FN_1_OUT) #define GPIO83_NSSP_RX (83 | GPIO_ALT_FN_2_IN) +#define GPIO83_CIF_DD4_MD (83 | GPIO_ALT_FN_3_IN) #define GPIO84_NSSP_TX (84 | GPIO_ALT_FN_1_OUT) #define GPIO84_NSSP_RX (84 | GPIO_ALT_FN_2_IN) +#define GPIO84_CIF_FV_MD (84 | GPIO_ALT_FN_3_OUT) #define GPIO85_nPCE_1_MD (85 | GPIO_ALT_FN_1_OUT) +#define GPIO85_CIF_LV_MD (85 | GPIO_ALT_FN_3_OUT) +#define GPIO90_CIF_DD4_MD (90 | GPIO_ALT_FN_3_IN) +#define GPIO91_CIF_DD5_MD (91 | GPIO_ALT_FN_3_IN) #define GPIO92_MMCDAT0_MD (92 | GPIO_ALT_FN_1_OUT) +#define GPIO93_CIF_DD6_MD (93 | GPIO_ALT_FN_2_IN) +#define GPIO94_CIF_DD5_MD (94 | GPIO_ALT_FN_2_IN) +#define GPIO95_CIF_DD4_MD (95 | GPIO_ALT_FN_2_IN) +#define GPIO98_CIF_DD0_MD (98 | GPIO_ALT_FN_2_IN) #define GPIO102_nPCE_1_MD (102 | GPIO_ALT_FN_1_OUT) +#define GPIO103_CIF_DD3_MD (103 | GPIO_ALT_FN_1_IN) #define GPIO104_pSKTSEL_MD (104 | GPIO_ALT_FN_1_OUT) +#define GPIO104_CIF_DD2_MD (104 | GPIO_ALT_FN_1_IN) +#define GPIO105_CIF_DD1_MD (105 | GPIO_ALT_FN_1_IN) +#define GPIO106_CIF_DD9_MD (106 | GPIO_ALT_FN_1_IN) +#define GPIO107_CIF_DD8_MD (107 | GPIO_ALT_FN_1_IN) +#define GPIO108_CIF_DD7_MD (108 | GPIO_ALT_FN_1_IN) #define GPIO109_MMCDAT1_MD (109 | GPIO_ALT_FN_1_OUT) #define GPIO110_MMCDAT2_MD (110 | GPIO_ALT_FN_1_OUT) #define GPIO110_MMCCS0_MD (110 | GPIO_ALT_FN_1_OUT) @@ -1699,7 +1774,7 @@ #define LCCR0_Color (LCCR0_CMS*0) /* Color display */ #define LCCR0_Mono (LCCR0_CMS*1) /* Monochrome display */ #define LCCR0_SDS (1 << 2) /* Single/Dual Panel Display */ - /* Select */ + /* Select */ #define LCCR0_Sngl (LCCR0_SDS*0) /* Single panel display */ #define LCCR0_Dual (LCCR0_SDS*1) /* Dual panel display */ @@ -1711,11 +1786,11 @@ #define LCCR0_Pas (LCCR0_PAS*0) /* Passive display (STN) */ #define LCCR0_Act (LCCR0_PAS*1) /* Active display (TFT) */ #define LCCR0_DPD (1 << 9) /* Double Pixel Data (monochrome */ - /* display mode) */ + /* display mode) */ #define LCCR0_4PixMono (LCCR0_DPD*0) /* 4-Pixel/clock Monochrome */ - /* display */ + /* display */ #define LCCR0_8PixMono (LCCR0_DPD*1) /* 8-Pixel/clock Monochrome */ - /* display */ + /* display */ #define LCCR0_DIS (1 << 10) /* LCD Disable */ #define LCCR0_QDM (1 << 11) /* LCD Quick Disable mask */ #define LCCR0_PDD (0xff << 12) /* Palette DMA request delay */ @@ -1730,47 +1805,47 @@ #define LCCR1_PPL Fld (10, 0) /* Pixels Per Line - 1 */ #define LCCR1_DisWdth(Pixel) /* Display Width [1..800 pix.] */ \ - (((Pixel) - 1) << FShft (LCCR1_PPL)) + (((Pixel) - 1) << FShft (LCCR1_PPL)) #define LCCR1_HSW Fld (6, 10) /* Horizontal Synchronization */ #define LCCR1_HorSnchWdth(Tpix) /* Horizontal Synchronization */ \ - /* pulse Width [1..64 Tpix] */ \ - (((Tpix) - 1) << FShft (LCCR1_HSW)) + /* pulse Width [1..64 Tpix] */ \ + (((Tpix) - 1) << FShft (LCCR1_HSW)) #define LCCR1_ELW Fld (8, 16) /* End-of-Line pixel clock Wait */ - /* count - 1 [Tpix] */ + /* count - 1 [Tpix] */ #define LCCR1_EndLnDel(Tpix) /* End-of-Line Delay */ \ - /* [1..256 Tpix] */ \ - (((Tpix) - 1) << FShft (LCCR1_ELW)) + /* [1..256 Tpix] */ \ + (((Tpix) - 1) << FShft (LCCR1_ELW)) #define LCCR1_BLW Fld (8, 24) /* Beginning-of-Line pixel clock */ - /* Wait count - 1 [Tpix] */ + /* Wait count - 1 [Tpix] */ #define LCCR1_BegLnDel(Tpix) /* Beginning-of-Line Delay */ \ - /* [1..256 Tpix] */ \ - (((Tpix) - 1) << FShft (LCCR1_BLW)) + /* [1..256 Tpix] */ \ + (((Tpix) - 1) << FShft (LCCR1_BLW)) #define LCCR2_LPP Fld (10, 0) /* Line Per Panel - 1 */ #define LCCR2_DisHght(Line) /* Display Height [1..1024 lines] */ \ - (((Line) - 1) << FShft (LCCR2_LPP)) + (((Line) - 1) << FShft (LCCR2_LPP)) #define LCCR2_VSW Fld (6, 10) /* Vertical Synchronization pulse */ - /* Width - 1 [Tln] (L_FCLK) */ + /* Width - 1 [Tln] (L_FCLK) */ #define LCCR2_VrtSnchWdth(Tln) /* Vertical Synchronization pulse */ \ - /* Width [1..64 Tln] */ \ - (((Tln) - 1) << FShft (LCCR2_VSW)) + /* Width [1..64 Tln] */ \ + (((Tln) - 1) << FShft (LCCR2_VSW)) #define LCCR2_EFW Fld (8, 16) /* End-of-Frame line clock Wait */ - /* count [Tln] */ + /* count [Tln] */ #define LCCR2_EndFrmDel(Tln) /* End-of-Frame Delay */ \ - /* [0..255 Tln] */ \ - ((Tln) << FShft (LCCR2_EFW)) + /* [0..255 Tln] */ \ + ((Tln) << FShft (LCCR2_EFW)) #define LCCR2_BFW Fld (8, 24) /* Beginning-of-Frame line clock */ - /* Wait count [Tln] */ + /* Wait count [Tln] */ #define LCCR2_BegFrmDel(Tln) /* Beginning-of-Frame Delay */ \ - /* [0..255 Tln] */ \ - ((Tln) << FShft (LCCR2_BFW)) + /* [0..255 Tln] */ \ + ((Tln) << FShft (LCCR2_BFW)) #if 0 #define LCCR3_PCD (0xff) /* Pixel clock divisor */ @@ -1787,7 +1862,7 @@ #define LCCR3_PixFlEdg (LCCR3_PCP*1) /* Pixel clock Falling-Edge */ #define LCCR3_OEP (1 << 23) /* Output Enable Polarity (L_BIAS, */ - /* active display mode) */ + /* active display mode) */ #define LCCR3_OutEnH (LCCR3_OEP*0) /* Output Enable active High */ #define LCCR3_OutEnL (LCCR3_OEP*1) /* Output Enable active Low */ @@ -1800,25 +1875,25 @@ #define LCCR3_PCD Fld (8, 0) /* Pixel Clock Divisor */ #define LCCR3_PixClkDiv(Div) /* Pixel Clock Divisor */ \ - (((Div) << FShft (LCCR3_PCD))) + (((Div) << FShft (LCCR3_PCD))) #define LCCR3_BPP Fld (3, 24) /* Bit Per Pixel */ #define LCCR3_Bpp(Bpp) /* Bit Per Pixel */ \ - (((Bpp) << FShft (LCCR3_BPP))) + (((Bpp) << FShft (LCCR3_BPP))) #define LCCR3_ACB Fld (8, 8) /* AC Bias */ #define LCCR3_Acb(Acb) /* BAC Bias */ \ - (((Acb) << FShft (LCCR3_ACB))) + (((Acb) << FShft (LCCR3_ACB))) #define LCCR3_HorSnchH (LCCR3_HSP*0) /* Horizontal Synchronization */ - /* pulse active High */ + /* pulse active High */ #define LCCR3_HorSnchL (LCCR3_HSP*1) /* Horizontal Synchronization */ #define LCCR3_VrtSnchH (LCCR3_VSP*0) /* Vertical Synchronization pulse */ - /* active High */ + /* active High */ #define LCCR3_VrtSnchL (LCCR3_VSP*1) /* Vertical Synchronization pulse */ - /* active Low */ + /* active Low */ #define LCSR_LDD (1 << 0) /* LCD Disable Done */ #define LCSR_SOF (1 << 1) /* Start of frame */ @@ -1925,6 +2000,11 @@ #define CICR0_ENB (1 << 28) /* Camera interface enable */ #define CICR0_DIS (1 << 27) /* Camera interface disable */ #define CICR0_SIM (0x7 << 24) /* Sensor interface mode mask */ +#define CICR0_SIM_MP (0 << 24) +#define CICR0_SIM_SP (1 << 24) +#define CICR0_SIM_MS (2 << 24) +#define CICR0_SIM_EP (3 << 24) +#define CICR0_SIM_ES (4 << 24) #define CICR0_TOM (1 << 9) /* Time-out mask */ #define CICR0_RDAVM (1 << 8) /* Receive-data-available mask */ #define CICR0_FEM (1 << 7) /* FIFO-empty mask */ @@ -1975,6 +2055,20 @@ #define CICR4_FR_RATE (0x7 << 8) /* Frame rate mask */ #define CICR4_DIV (0xff << 0) /* Clock divisor mask */ +#define CICR1_DW_VAL(x) ((x) & CICR1_DW) /* Data bus width */ +#define CICR1_PPL_VAL(x) (((x) << 15) & CICR1_PPL) /* Pixels per line */ + +#define CICR2_BLW_VAL(x) (((x) << 24) & CICR2_BLW) /* Beginning-of-line pixel clock wait count */ +#define CICR2_ELW_VAL(x) (((x) << 16) & CICR2_ELW) /* End-of-line pixel clock wait count */ +#define CICR2_HSW_VAL(x) (((x) << 10) & CICR2_HSW) /* Horizontal sync pulse width */ +#define CICR2_BFPW_VAL(x) (((x) << 3) & CICR2_BFPW) /* Beginning-of-frame pixel clock wait count */ +#define CICR2_FSW_VAL(x) (((x) << 0) & CICR2_FSW) /* Frame stabilization wait count */ + +#define CICR3_BFW_VAL(x) (((x) << 24) & CICR3_BFW) /* Beginning-of-frame line clock wait count */ +#define CICR3_EFW_VAL(x) (((x) << 16) & CICR3_EFW) /* End-of-frame line clock wait count */ +#define CICR3_VSW_VAL(x) (((x) << 11) & CICR3_VSW) /* Vertical sync pulse width */ +#define CICR3_LPF_VAL(x) (((x) << 0) & CICR3_LPF) /* Lines per frame */ + #define CISR_FTO (1 << 15) /* FIFO time-out */ #define CISR_RDAV_2 (1 << 14) /* Channel 2 receive data available */ #define CISR_RDAV_1 (1 << 13) /* Channel 1 receive data available */ -- cgit v1.2.3 From c1c0cdb70b4b308e2cf24eec0345a1f897c17c46 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 17:47:05 +0000 Subject: Add support for the MT9M001 camera From: Guennadi Liakhovetski This driver supports Micron MT9M001 monochrome and colour cameras. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/Kconfig | 15 + linux/drivers/media/video/Makefile | 1 + linux/drivers/media/video/mt9m001.c | 694 ++++++++++++++++++++++++++++++++++++ 3 files changed, 710 insertions(+) create mode 100644 linux/drivers/media/video/mt9m001.c (limited to 'linux') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 8e2c9f2dd..061252b14 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -845,6 +845,21 @@ config SOC_CAMERA over a bus like PCI or USB. For example some i2c camera connected directly to the data bus of an SoC. +config SOC_CAMERA_MT9M001 + tristate "mt9m001 support" + depends on SOC_CAMERA + select GPIO_PCA953X if MT9M001_PCA9536_SWITCH + help + This driver supports MT9M001 cameras from Micron, monochrome + and colour models. + +config MT9M001_PCA9536_SWITCH + bool "pca9536 datawidth switch for mt9m001" + depends on SOC_CAMERA_MT9M001 + help + Select this if your MT9M001 camera uses a PCA9536 I2C GPIO + extender to switch between 8 and 10 bit datawidth modes + config VIDEO_PXA27x tristate "PXA27x Quick Capture Interface driver" depends on VIDEO_DEV && PXA27x diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index 4ab0a0348..7cd0fb9b2 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -139,6 +139,7 @@ obj-$(CONFIG_VIDEO_CX23885) += cx23885/ obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o obj-$(CONFIG_SOC_CAMERA) += soc_camera.o +obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/frontends diff --git a/linux/drivers/media/video/mt9m001.c b/linux/drivers/media/video/mt9m001.c new file mode 100644 index 000000000..3c5867c37 --- /dev/null +++ b/linux/drivers/media/video/mt9m001.c @@ -0,0 +1,694 @@ +/* + * Driver for MT9M001 CMOS Image Sensor from Micron + * + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include + +/* mt9m001 i2c address 0x5d + * The platform has to define i2c_board_info + * and call i2c_register_board_info() */ + +/* mt9m001 selected register addresses */ +#define MT9M001_CHIP_VERSION 0x00 +#define MT9M001_ROW_START 0x01 +#define MT9M001_COLUMN_START 0x02 +#define MT9M001_WINDOW_HEIGHT 0x03 +#define MT9M001_WINDOW_WIDTH 0x04 +#define MT9M001_HORIZONTAL_BLANKING 0x05 +#define MT9M001_VERTICAL_BLANKING 0x06 +#define MT9M001_OUTPUT_CONTROL 0x07 +#define MT9M001_SHUTTER_WIDTH 0x09 +#define MT9M001_FRAME_RESTART 0x0b +#define MT9M001_SHUTTER_DELAY 0x0c +#define MT9M001_RESET 0x0d +#define MT9M001_READ_OPTIONS1 0x1e +#define MT9M001_READ_OPTIONS2 0x20 +#define MT9M001_GLOBAL_GAIN 0x35 +#define MT9M001_CHIP_ENABLE 0xF1 + +static const struct soc_camera_data_format mt9m001_colour_formats[] = { + { + .name = "RGB Bayer (sRGB)", + .depth = 16, + .fourcc = V4L2_PIX_FMT_SBGGR8, + .colorspace = V4L2_COLORSPACE_SRGB, + } +}; + +static const struct soc_camera_data_format mt9m001_monochrome_formats[] = { + { + .name = "Monochrome 10 bit", + .depth = 10, + .fourcc = V4L2_PIX_FMT_Y16, + }, { + .name = "Monochrome 8 bit", + .depth = 8, + .fourcc = V4L2_PIX_FMT_GREY, + }, +}; + +struct mt9m001 { + struct i2c_client *client; + struct soc_camera_device icd; + int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ + int switch_gpio; + unsigned char autoexposure; + unsigned char datawidth; +}; + +static int reg_read(struct soc_camera_device *icd, const u8 reg) +{ + struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); + struct i2c_client *client = mt9m001->client; + s32 data = i2c_smbus_read_word_data(client, reg); + return data < 0 ? data : swab16(data); +} + +static int reg_write(struct soc_camera_device *icd, const u8 reg, + const u16 data) +{ + struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); + return i2c_smbus_write_word_data(mt9m001->client, reg, swab16(data)); +} + +static int reg_set(struct soc_camera_device *icd, const u8 reg, + const u16 data) +{ + int ret; + + ret = reg_read(icd, reg); + if (ret < 0) + return ret; + return reg_write(icd, reg, ret | data); +} + +static int reg_clear(struct soc_camera_device *icd, const u8 reg, + const u16 data) +{ + int ret; + + ret = reg_read(icd, reg); + if (ret < 0) + return ret; + return reg_write(icd, reg, ret & ~data); +} + +static int mt9m001_init(struct soc_camera_device *icd) +{ + int ret; + + /* Disable chip, synchronous option update */ + dev_dbg(icd->vdev->dev, "%s\n", __FUNCTION__); + + ret = reg_write(icd, MT9M001_RESET, 1); + if (ret >= 0) + ret = reg_write(icd, MT9M001_RESET, 0); + if (ret >= 0) + ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); + + return ret >= 0 ? 0 : -EIO; +} + +static int mt9m001_release(struct soc_camera_device *icd) +{ + /* Disable the chip */ + reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); + return 0; +} + +static int mt9m001_start_capture(struct soc_camera_device *icd) +{ + /* Switch to master "normal" mode */ + if (reg_write(icd, MT9M001_OUTPUT_CONTROL, 2) < 0) + return -EIO; + return 0; +} + +static int mt9m001_stop_capture(struct soc_camera_device *icd) +{ + /* Stop sensor readout */ + if (reg_write(icd, MT9M001_OUTPUT_CONTROL, 0) < 0) + return -EIO; + return 0; +} + +static int bus_switch_request(struct mt9m001 *mt9m001, + struct soc_camera_link *icl) +{ +#ifdef CONFIG_MT9M001_PCA9536_SWITCH + int ret; + unsigned int gpio = icl->gpio; + + if (gpio != NO_GPIO) { + /* We have a data bus switch. */ + ret = gpio_request(gpio, "mt9m001"); + if (ret < 0) { + dev_err(&mt9m001->client->dev, "Cannot get GPIO %u\n", + gpio); + return ret; + } + + ret = gpio_direction_output(gpio, 0); + if (ret < 0) { + dev_err(&mt9m001->client->dev, + "Cannot set GPIO %u to output\n", gpio); + gpio_free(gpio); + return ret; + } + } + + mt9m001->switch_gpio = gpio; +#else + mt9m001->switch_gpio = NO_GPIO; +#endif + return 0; +} + +static void bus_switch_release(struct mt9m001 *mt9m001) +{ +#ifdef CONFIG_MT9M001_PCA9536_SWITCH + if (mt9m001->switch_gpio != NO_GPIO) + gpio_free(mt9m001->switch_gpio); +#endif +} + +static int bus_switch_act(struct mt9m001 *mt9m001, int go8bit) +{ +#ifdef CONFIG_MT9M001_PCA9536_SWITCH + if (mt9m001->switch_gpio == NO_GPIO) + return -ENODEV; + + gpio_set_value_cansleep(mt9m001->switch_gpio, go8bit); + return 0; +#else + return -ENODEV; +#endif +} + +static int mt9m001_set_capture_format(struct soc_camera_device *icd, + __u32 pixfmt, struct v4l2_rect *rect, unsigned int flags) +{ + struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); + unsigned int width_flag = flags & (IS_DATAWIDTH_10 | IS_DATAWIDTH_9 | + IS_DATAWIDTH_8); + int ret; + const u16 hblank = 9, vblank = 25; + + /* MT9M001 has all capture_format parameters fixed */ + if (!(flags & IS_MASTER) || + !(flags & IS_PCLK_SAMPLE_RISING) || + !(flags & IS_HSYNC_ACTIVE_HIGH) || + !(flags & IS_VSYNC_ACTIVE_HIGH)) + return -EINVAL; + + /* Only one width bit may be set */ + if (!is_power_of_2(width_flag)) + return -EINVAL; + + if ((mt9m001->datawidth != 10 && (width_flag == IS_DATAWIDTH_10)) || + (mt9m001->datawidth != 9 && (width_flag == IS_DATAWIDTH_9)) || + (mt9m001->datawidth != 8 && (width_flag == IS_DATAWIDTH_8))) { + /* data width switch requested */ + if (mt9m001->switch_gpio == NO_GPIO) + return -EINVAL; + + /* Well, we actually only can do 10 or 8 bits... */ + if (width_flag == IS_DATAWIDTH_9) + return -EINVAL; + ret = bus_switch_act(mt9m001, + width_flag == IS_DATAWIDTH_8); + if (ret < 0) + return ret; + + mt9m001->datawidth = width_flag == IS_DATAWIDTH_8 ? 8 : 10; + } + + /* Blanking and start values - default... */ + ret = reg_write(icd, MT9M001_HORIZONTAL_BLANKING, hblank); + if (ret >= 0) + ret = reg_write(icd, MT9M001_VERTICAL_BLANKING, vblank); + + /* The caller provides a supported format, as verified per + * call to icd->try_fmt_cap() */ + if (ret >= 0) + ret = reg_write(icd, MT9M001_COLUMN_START, rect->left); + if (ret >= 0) + ret = reg_write(icd, MT9M001_ROW_START, rect->top); + if (ret >= 0) + ret = reg_write(icd, MT9M001_WINDOW_WIDTH, rect->width - 1); + if (ret >= 0) + ret = reg_write(icd, MT9M001_WINDOW_HEIGHT, + rect->height + icd->y_skip_top - 1); + if (ret >= 0 && mt9m001->autoexposure) { + ret = reg_write(icd, MT9M001_SHUTTER_WIDTH, + rect->height + icd->y_skip_top + vblank); + if (ret >= 0) { + const struct v4l2_queryctrl *qctrl = + soc_camera_find_qctrl(icd->ops, + V4L2_CID_EXPOSURE); + icd->exposure = (524 + (rect->height + icd->y_skip_top + + vblank - 1) * + (qctrl->maximum - qctrl->minimum)) / + 1048 + qctrl->minimum; + } + } + + return ret < 0 ? ret : 0; +} + +static int mt9m001_try_fmt_cap(struct soc_camera_device *icd, + struct v4l2_format *f) +{ + if (f->fmt.pix.height < 32 + icd->y_skip_top) + f->fmt.pix.height = 32 + icd->y_skip_top; + if (f->fmt.pix.height > 1024 + icd->y_skip_top) + f->fmt.pix.height = 1024 + icd->y_skip_top; + if (f->fmt.pix.width < 48) + f->fmt.pix.width = 48; + if (f->fmt.pix.width > 1280) + f->fmt.pix.width = 1280; + f->fmt.pix.width &= ~0x01; /* has to be even, unsure why was ~3 */ + + return 0; +} + +static int mt9m001_get_chip_id(struct soc_camera_device *icd, + struct v4l2_chip_ident *id) +{ + struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); + + if (id->match_type != V4L2_CHIP_MATCH_I2C_ADDR) + return -EINVAL; + + if (id->match_chip != mt9m001->client->addr) + return -ENODEV; + + id->ident = mt9m001->model; + id->revision = 0; + + return 0; +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int mt9m001_get_register(struct soc_camera_device *icd, + struct v4l2_register *reg) +{ + struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); + + if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) + return -EINVAL; + + if (reg->match_chip != mt9m001->client->addr) + return -ENODEV; + + reg->val = reg_read(icd, reg->reg); + + if (reg->val > 0xffff) + return -EIO; + + return 0; +} + +static int mt9m001_set_register(struct soc_camera_device *icd, + struct v4l2_register *reg) +{ + struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); + + if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) + return -EINVAL; + + if (reg->match_chip != mt9m001->client->addr) + return -ENODEV; + + if (reg_write(icd, reg->reg, reg->val) < 0) + return -EIO; + + return 0; +} +#endif + +static unsigned int mt9m001_get_datawidth(struct soc_camera_device *icd) +{ + struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); + return mt9m001->datawidth; +} + +const struct v4l2_queryctrl mt9m001_controls[] = { + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Vertically", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gain", + .minimum = 0, + .maximum = 127, + .step = 1, + .default_value = 64, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure", + .minimum = 1, + .maximum = 255, + .step = 1, + .default_value = 255, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_EXPOSURE_AUTO, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Automatic Exposure", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + } +}; + +static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl); +static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl); + +static struct soc_camera_ops mt9m001_ops = { + .owner = THIS_MODULE, + .init = mt9m001_init, + .release = mt9m001_release, + .start_capture = mt9m001_start_capture, + .stop_capture = mt9m001_stop_capture, + .set_capture_format = mt9m001_set_capture_format, + .try_fmt_cap = mt9m001_try_fmt_cap, + .formats = NULL, /* Filled in later depending on the */ + .num_formats = 0, /* camera type and data widths */ + .get_datawidth = mt9m001_get_datawidth, + .controls = mt9m001_controls, + .num_controls = ARRAY_SIZE(mt9m001_controls), + .get_control = mt9m001_get_control, + .set_control = mt9m001_set_control, + .get_chip_id = mt9m001_get_chip_id, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .get_register = mt9m001_get_register, + .set_register = mt9m001_set_register, +#endif +}; + +static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) +{ + struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); + int data; + + switch (ctrl->id) { + case V4L2_CID_VFLIP: + data = reg_read(icd, MT9M001_READ_OPTIONS2); + if (data < 0) + return -EIO; + ctrl->value = !!(data & 0x8000); + break; + case V4L2_CID_EXPOSURE_AUTO: + ctrl->value = mt9m001->autoexposure; + break; + } + return 0; +} + +static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) +{ + struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); + const struct v4l2_queryctrl *qctrl; + int data; + + qctrl = soc_camera_find_qctrl(&mt9m001_ops, ctrl->id); + + if (!qctrl) + return -EINVAL; + + switch (ctrl->id) { + case V4L2_CID_VFLIP: + if (ctrl->value) + data = reg_set(icd, MT9M001_READ_OPTIONS2, 0x8000); + else + data = reg_clear(icd, MT9M001_READ_OPTIONS2, 0x8000); + if (data < 0) + return -EIO; + break; + case V4L2_CID_GAIN: + if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) + return -EINVAL; + /* See Datasheet Table 7, Gain settings. */ + if (ctrl->value <= qctrl->default_value) { + /* Pack it into 0..1 step 0.125, register values 0..8 */ + unsigned long range = qctrl->default_value - qctrl->minimum; + data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; + + dev_dbg(&icd->dev, "Setting gain %d\n", data); + data = reg_write(icd, MT9M001_GLOBAL_GAIN, data); + if (data < 0) + return -EIO; + } else { + /* Pack it into 1.125..15 variable step, register values 9..67 */ + /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */ + unsigned long range = qctrl->maximum - qctrl->default_value - 1; + unsigned long gain = ((ctrl->value - qctrl->default_value - 1) * + 111 + range / 2) / range + 9; + + if (gain <= 32) + data = gain; + else if (gain <= 64) + data = ((gain - 32) * 16 + 16) / 32 + 80; + else + data = ((gain - 64) * 7 + 28) / 56 + 96; + + dev_dbg(&icd->dev, "Setting gain from %d to %d\n", + reg_read(icd, MT9M001_GLOBAL_GAIN), data); + data = reg_write(icd, MT9M001_GLOBAL_GAIN, data); + if (data < 0) + return -EIO; + } + + /* Success */ + icd->gain = ctrl->value; + break; + case V4L2_CID_EXPOSURE: + /* mt9m001 has maximum == default */ + if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) + return -EINVAL; + else { + unsigned long range = qctrl->maximum - qctrl->minimum; + unsigned long shutter = ((ctrl->value - qctrl->minimum) * 1048 + + range / 2) / range + 1; + + dev_dbg(&icd->dev, "Setting shutter width from %d to %lu\n", + reg_read(icd, MT9M001_SHUTTER_WIDTH), shutter); + if (reg_write(icd, MT9M001_SHUTTER_WIDTH, shutter) < 0) + return -EIO; + icd->exposure = ctrl->value; + mt9m001->autoexposure = 0; + } + break; + case V4L2_CID_EXPOSURE_AUTO: + if (ctrl->value) { + const u16 vblank = 25; + if (reg_write(icd, MT9M001_SHUTTER_WIDTH, icd->height + + icd->y_skip_top + vblank) < 0) + return -EIO; + qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); + icd->exposure = (524 + (icd->height + icd->y_skip_top + vblank - 1) * + (qctrl->maximum - qctrl->minimum)) / + 1048 + qctrl->minimum; + mt9m001->autoexposure = 1; + } else + mt9m001->autoexposure = 0; + break; + } + return 0; +} + +/* Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one */ +static int mt9m001_video_probe(struct soc_camera_device *icd) +{ + struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); + s32 data; + int ret; + + /* We must have a parent by now. And it cannot be a wrong one. + * So this entire test is completely redundant. */ + if (!icd->dev.parent || + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) + return -ENODEV; + + /* Enable the chip */ + data = reg_write(&mt9m001->icd, MT9M001_CHIP_ENABLE, 1); + dev_dbg(&icd->dev, "write: %d\n", data); + + /* Read out the chip version register */ + data = reg_read(icd, MT9M001_CHIP_VERSION); + + /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */ + switch (data) { + case 0x8411: + case 0x8421: + mt9m001->model = V4L2_IDENT_MT9M001C12ST; + mt9m001_ops.formats = mt9m001_colour_formats; + mt9m001_ops.num_formats = ARRAY_SIZE(mt9m001_colour_formats); + break; + case 0x8431: + mt9m001->model = V4L2_IDENT_MT9M001C12STM; + mt9m001_ops.formats = mt9m001_monochrome_formats; + if (mt9m001->client->dev.platform_data) + mt9m001_ops.num_formats = ARRAY_SIZE(mt9m001_monochrome_formats); + else + mt9m001_ops.num_formats = 1; + break; + default: + ret = -ENODEV; + dev_err(&icd->dev, + "No MT9M001 chip detected, register read %x\n", data); + goto ei2c; + } + + dev_info(&icd->dev, "Detected a MT9M001 chip ID %x (%s)\n", data, + data == 0x8431 ? "C12STM" : "C12ST"); + + /* Now that we know the model, we can start video */ + ret = soc_camera_video_start(icd); + if (ret) + goto eisis; + + return 0; + +eisis: +ei2c: + return ret; +} + +static void mt9m001_video_remove(struct soc_camera_device *icd) +{ + struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); + + dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m001->client->addr, + mt9m001->icd.dev.parent, mt9m001->icd.vdev); + soc_camera_video_stop(&mt9m001->icd); +} + +static int mt9m001_probe(struct i2c_client *client) +{ + struct mt9m001 *mt9m001; + struct soc_camera_device *icd; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct soc_camera_link *icl = client->dev.platform_data; + int ret; + + if (!icl) { + dev_err(&client->dev, "MT9M001 driver needs platform data\n"); + return -EINVAL; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); + return -EIO; + } + + mt9m001 = kzalloc(sizeof(struct mt9m001), GFP_KERNEL); + if (!mt9m001) + return -ENOMEM; + + mt9m001->client = client; + i2c_set_clientdata(client, mt9m001); + + /* Second stage probe - when a capture adapter is there */ + icd = &mt9m001->icd; + icd->probe = mt9m001_video_probe; + icd->remove = mt9m001_video_remove; + icd->ops = &mt9m001_ops; + icd->control = &client->dev; + icd->x_min = 20; + icd->y_min = 12; + icd->x_current = 20; + icd->y_current = 12; + icd->width_min = 48; + icd->width_max = 1280; + icd->height_min = 32; + icd->height_max = 1024; + icd->y_skip_top = 1; + icd->iface = icl->bus_id; + /* Default datawidth - this is the only width this camera (normally) + * supports. It is only with extra logic that it can support + * other widths. Therefore it seems to be a sensible default. */ + mt9m001->datawidth = 10; + /* Simulated autoexposure. If enabled, we calculate shutter width + * ourselves in the driver based on vertical blanking and frame width */ + mt9m001->autoexposure = 1; + + ret = bus_switch_request(mt9m001, icl); + if (ret) + goto eswinit; + + ret = soc_camera_device_register(icd); + if (ret) + goto eisdr; + + return 0; + +eisdr: + bus_switch_release(mt9m001); +eswinit: + kfree(mt9m001); + return ret; +} + +static int mt9m001_remove(struct i2c_client *client) +{ + struct mt9m001 *mt9m001 = i2c_get_clientdata(client); + + soc_camera_device_unregister(&mt9m001->icd); + bus_switch_release(mt9m001); + kfree(mt9m001); + + return 0; +} + +static struct i2c_driver mt9m001_i2c_driver = { + .driver = { + .name = "mt9m001", + }, + .probe = mt9m001_probe, + .remove = mt9m001_remove, +}; + +static int __init mt9m001_mod_init(void) +{ + return i2c_add_driver(&mt9m001_i2c_driver); +} + +static void __exit mt9m001_mod_exit(void) +{ + i2c_del_driver(&mt9m001_i2c_driver); +} + +module_init(mt9m001_mod_init); +module_exit(mt9m001_mod_exit); + +MODULE_DESCRIPTION("Micron MT9M001 Camera driver"); +MODULE_AUTHOR("Guennadi Liakhovetski "); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 6bccdb31811a650929dfb824fc19f0f52d8e1580 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 17:47:24 +0000 Subject: Add support for the MT9V022 camera From: Guennadi Liakhovetski This driver supports Micron MT9V022 colour camera. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/Kconfig | 14 + linux/drivers/media/video/Makefile | 1 + linux/drivers/media/video/mt9v022.c | 804 ++++++++++++++++++++++++++++++++++++ 3 files changed, 819 insertions(+) create mode 100644 linux/drivers/media/video/mt9v022.c (limited to 'linux') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 061252b14..d9fc92a82 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -860,6 +860,20 @@ config MT9M001_PCA9536_SWITCH Select this if your MT9M001 camera uses a PCA9536 I2C GPIO extender to switch between 8 and 10 bit datawidth modes +config SOC_CAMERA_MT9V022 + tristate "mt9v022 support" + depends on SOC_CAMERA + select GPIO_PCA953X if MT9V022_PCA9536_SWITCH + help + This driver supports MT9V022 cameras from Micron + +config MT9V022_PCA9536_SWITCH + bool "pca9536 datawidth switch for mt9v022" + depends on SOC_CAMERA_MT9V022 + help + Select this if your MT9V022 camera uses a PCA9536 I2C GPIO + extender to switch between 8 and 10 bit datawidth modes + config VIDEO_PXA27x tristate "PXA27x Quick Capture Interface driver" depends on VIDEO_DEV && PXA27x diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index 7cd0fb9b2..a03f06c74 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -140,6 +140,7 @@ obj-$(CONFIG_VIDEO_CX23885) += cx23885/ obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o obj-$(CONFIG_SOC_CAMERA) += soc_camera.o obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o +obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/frontends diff --git a/linux/drivers/media/video/mt9v022.c b/linux/drivers/media/video/mt9v022.c new file mode 100644 index 000000000..9b406e419 --- /dev/null +++ b/linux/drivers/media/video/mt9v022.c @@ -0,0 +1,804 @@ +/* + * Driver for MT9V022 CMOS Image Sensor from Micron + * + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +/* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c + * The platform has to define i2c_board_info + * and call i2c_register_board_info() */ + +static char *sensor_type; +module_param(sensor_type, charp, S_IRUGO); +MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"\n"); + +/* mt9v022 selected register addresses */ +#define MT9V022_CHIP_VERSION 0x00 +#define MT9V022_COLUMN_START 0x01 +#define MT9V022_ROW_START 0x02 +#define MT9V022_WINDOW_HEIGHT 0x03 +#define MT9V022_WINDOW_WIDTH 0x04 +#define MT9V022_HORIZONTAL_BLANKING 0x05 +#define MT9V022_VERTICAL_BLANKING 0x06 +#define MT9V022_CHIP_CONTROL 0x07 +#define MT9V022_SHUTTER_WIDTH1 0x08 +#define MT9V022_SHUTTER_WIDTH2 0x09 +#define MT9V022_SHUTTER_WIDTH_CTRL 0x0a +#define MT9V022_TOTAL_SHUTTER_WIDTH 0x0b +#define MT9V022_RESET 0x0c +#define MT9V022_READ_MODE 0x0d +#define MT9V022_MONITOR_MODE 0x0e +#define MT9V022_PIXEL_OPERATION_MODE 0x0f +#define MT9V022_LED_OUT_CONTROL 0x1b +#define MT9V022_ADC_MODE_CONTROL 0x1c +#define MT9V022_ANALOG_GAIN 0x34 +#define MT9V022_BLACK_LEVEL_CALIB_CTRL 0x47 +#define MT9V022_PIXCLK_FV_LV 0x74 +#define MT9V022_DIGITAL_TEST_PATTERN 0x7f +#define MT9V022_AEC_AGC_ENABLE 0xAF +#define MT9V022_MAX_TOTAL_SHUTTER_WIDTH 0xBD + +/* Progressive scan, master, defaults */ +#define MT9V022_CHIP_CONTROL_DEFAULT 0x188 + +static const struct soc_camera_data_format mt9v022_formats[] = { + { + .name = "RGB Bayer (sRGB)", + .depth = 8, + .fourcc = V4L2_PIX_FMT_SBGGR8, + .colorspace = V4L2_COLORSPACE_SRGB, + }, { + .name = "RGB Bayer (sRGB)", + .depth = 10, + .fourcc = V4L2_PIX_FMT_SBGGR16, + .colorspace = V4L2_COLORSPACE_SRGB, + }, { + .name = "Monochrome 10 bit", + .depth = 10, + .fourcc = V4L2_PIX_FMT_Y16, + }, { + .name = "Monochrome 8 bit", + .depth = 8, + .fourcc = V4L2_PIX_FMT_GREY, + }, +}; + +struct mt9v022 { + struct i2c_client *client; + struct soc_camera_device icd; + int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ + int switch_gpio; + u16 chip_control; + unsigned char datawidth; +}; + +static int reg_read(struct soc_camera_device *icd, const u8 reg) +{ + struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); + struct i2c_client *client = mt9v022->client; + s32 data = i2c_smbus_read_word_data(client, reg); + return data < 0 ? data : swab16(data); +} + +static int reg_write(struct soc_camera_device *icd, const u8 reg, + const u16 data) +{ + struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); + return i2c_smbus_write_word_data(mt9v022->client, reg, swab16(data)); +} + +static int reg_set(struct soc_camera_device *icd, const u8 reg, + const u16 data) +{ + int ret; + + ret = reg_read(icd, reg); + if (ret < 0) + return ret; + return reg_write(icd, reg, ret | data); +} + +static int reg_clear(struct soc_camera_device *icd, const u8 reg, + const u16 data) +{ + int ret; + + ret = reg_read(icd, reg); + if (ret < 0) + return ret; + return reg_write(icd, reg, ret & ~data); +} + +static int mt9v022_init(struct soc_camera_device *icd) +{ + struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); + int ret; + + /* Almost the default mode: master, parallel, simultaneous, and an + * undocumented bit 0x200, which is present in table 7, but not in 8, + * plus snapshot mode to disable scan for now */ + mt9v022->chip_control |= 0x10; + ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control); + if (ret >= 0) + reg_write(icd, MT9V022_READ_MODE, 0x300); + + /* All defaults */ + if (ret >= 0) + /* AEC, AGC on */ + ret = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x3); + if (ret >= 0) + ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480); + if (ret >= 0) + /* default - auto */ + ret = reg_clear(icd, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1); + if (ret >= 0) + ret = reg_write(icd, MT9V022_DIGITAL_TEST_PATTERN, 0); + + return ret >= 0 ? 0 : -EIO; +} + +static int mt9v022_release(struct soc_camera_device *icd) +{ + /* Nothing? */ + return 0; +} + +static int mt9v022_start_capture(struct soc_camera_device *icd) +{ + struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); + /* Switch to master "normal" mode */ + mt9v022->chip_control &= ~0x10; + if (reg_write(icd, MT9V022_CHIP_CONTROL, + mt9v022->chip_control) < 0) + return -EIO; + return 0; +} + +static int mt9v022_stop_capture(struct soc_camera_device *icd) +{ + struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); + /* Switch to snapshot mode */ + mt9v022->chip_control |= 0x10; + if (reg_write(icd, MT9V022_CHIP_CONTROL, + mt9v022->chip_control) < 0) + return -EIO; + return 0; +} + +static int bus_switch_request(struct mt9v022 *mt9v022, struct soc_camera_link *icl) +{ +#ifdef CONFIG_MT9V022_PCA9536_SWITCH + int ret; + unsigned int gpio = icl->gpio; + + if (gpio != NO_GPIO) { + /* We have a data bus switch. */ + ret = gpio_request(gpio, "mt9v022"); + if (ret < 0) { + dev_err(&mt9v022->client->dev, "Cannot get GPIO %u\n", gpio); + return ret; + } + + ret = gpio_direction_output(gpio, 0); + if (ret < 0) { + dev_err(&mt9v022->client->dev, + "Cannot set GPIO %u to output\n", gpio); + gpio_free(gpio); + return ret; + } + } + + mt9v022->switch_gpio = gpio; +#else + mt9v022->switch_gpio = NO_GPIO; +#endif + return 0; +} + +static void bus_switch_release(struct mt9v022 *mt9v022) +{ +#ifdef CONFIG_MT9V022_PCA9536_SWITCH + if (mt9v022->switch_gpio != NO_GPIO) + gpio_free(mt9v022->switch_gpio); +#endif +} + +static int bus_switch_act(struct mt9v022 *mt9v022, int go8bit) +{ +#ifdef CONFIG_MT9V022_PCA9536_SWITCH + if (mt9v022->switch_gpio == NO_GPIO) + return -ENODEV; + + gpio_set_value_cansleep(mt9v022->switch_gpio, go8bit); + return 0; +#else + return -ENODEV; +#endif +} + +static int mt9v022_set_capture_format(struct soc_camera_device *icd, + __u32 pixfmt, struct v4l2_rect *rect, unsigned int flags) +{ + struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); + unsigned int width_flag = flags & (IS_DATAWIDTH_10 | IS_DATAWIDTH_9 | + IS_DATAWIDTH_8); + u16 pixclk = 0; + int ret; + + /* Only one width bit may be set */ + if (!is_power_of_2(width_flag)) + return -EINVAL; + + /* The caller provides a supported format, as verified per call to + * icd->try_fmt_cap(), datawidth is from our supported format list */ + switch (pixfmt) { + case V4L2_PIX_FMT_GREY: + case V4L2_PIX_FMT_Y16: + if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM) + return -EINVAL; + break; + case V4L2_PIX_FMT_SBGGR8: + case V4L2_PIX_FMT_SBGGR16: + if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC) + return -EINVAL; + break; + case 0: + /* No format change, only geometry */ + break; + default: + return -EINVAL; + } + + /* Like in example app. Contradicts the datasheet though */ + ret = reg_read(icd, MT9V022_AEC_AGC_ENABLE); + if (ret >= 0) { + if (ret & 1) /* Autoexposure */ + ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, + rect->height + icd->y_skip_top + 43); + else + ret = reg_write(icd, MT9V022_TOTAL_SHUTTER_WIDTH, + rect->height + icd->y_skip_top + 43); + } + /* Setup frame format: defaults apart from width and height */ + if (ret >= 0) + ret = reg_write(icd, MT9V022_COLUMN_START, rect->left); + if (ret >= 0) + ret = reg_write(icd, MT9V022_ROW_START, rect->top); + if (ret >= 0) + /* Default 94, Phytec driver says: + * "width + horizontal blank >= 660" */ + ret = reg_write(icd, MT9V022_HORIZONTAL_BLANKING, + rect->width > 660 - 43 ? 43 : + 660 - rect->width); + if (ret >= 0) + ret = reg_write(icd, MT9V022_VERTICAL_BLANKING, 45); + if (ret >= 0) + ret = reg_write(icd, MT9V022_WINDOW_WIDTH, rect->width); + if (ret >= 0) + ret = reg_write(icd, MT9V022_WINDOW_HEIGHT, + rect->height + icd->y_skip_top); + + if (ret < 0) + return ret; + + dev_dbg(&icd->dev, "Frame %ux%u pixel\n", rect->width, rect->height); + + if ((mt9v022->datawidth != 10 && (width_flag == IS_DATAWIDTH_10)) || + (mt9v022->datawidth != 9 && (width_flag == IS_DATAWIDTH_9)) || + (mt9v022->datawidth != 8 && (width_flag == IS_DATAWIDTH_8))) { + /* data width switch requested */ + if (mt9v022->switch_gpio == NO_GPIO) + return -EINVAL; + + /* Well, we actually only can do 10 or 8 bits... */ + if (width_flag == IS_DATAWIDTH_9) + return -EINVAL; + + ret = bus_switch_act(mt9v022, + width_flag == IS_DATAWIDTH_8); + if (ret < 0) + return ret; + + mt9v022->datawidth = width_flag == IS_DATAWIDTH_8 ? 8 : 10; + } + + if (flags & IS_PCLK_SAMPLE_RISING) + pixclk |= 0x10; + + if (!(flags & IS_HSYNC_ACTIVE_HIGH)) + pixclk |= 0x1; + + if (!(flags & IS_VSYNC_ACTIVE_HIGH)) + pixclk |= 0x2; + + ret = reg_write(icd, MT9V022_PIXCLK_FV_LV, pixclk); + if (ret < 0) + return ret; + + if (!(flags & IS_MASTER)) + mt9v022->chip_control &= ~0x8; + + ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control); + if (ret < 0) + return ret; + + dev_dbg(&icd->dev, "Calculated pixclk 0x%x, chip control 0x%x\n", + pixclk, mt9v022->chip_control); + + return 0; +} + +static int mt9v022_try_fmt_cap(struct soc_camera_device *icd, + struct v4l2_format *f) +{ + if (f->fmt.pix.height < 32 + icd->y_skip_top) + f->fmt.pix.height = 32 + icd->y_skip_top; + if (f->fmt.pix.height > 480 + icd->y_skip_top) + f->fmt.pix.height = 480 + icd->y_skip_top; + if (f->fmt.pix.width < 48) + f->fmt.pix.width = 48; + if (f->fmt.pix.width > 752) + f->fmt.pix.width = 752; + f->fmt.pix.width &= ~0x03; /* ? */ + + return 0; +} + +static int mt9v022_get_chip_id(struct soc_camera_device *icd, + struct v4l2_chip_ident *id) +{ + struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); + + if (id->match_type != V4L2_CHIP_MATCH_I2C_ADDR) + return -EINVAL; + + if (id->match_chip != mt9v022->client->addr) + return -ENODEV; + + id->ident = mt9v022->model; + id->revision = 0; + + return 0; +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int mt9v022_get_register(struct soc_camera_device *icd, + struct v4l2_register *reg) +{ + struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); + + if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) + return -EINVAL; + + if (reg->match_chip != mt9v022->client->addr) + return -ENODEV; + + reg->val = reg_read(icd, reg->reg); + + if (reg->val > 0xffff) + return -EIO; + + return 0; +} + +static int mt9v022_set_register(struct soc_camera_device *icd, + struct v4l2_register *reg) +{ + struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); + + if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) + return -EINVAL; + + if (reg->match_chip != mt9v022->client->addr) + return -ENODEV; + + if (reg_write(icd, reg->reg, reg->val) < 0) + return -EIO; + + return 0; +} +#endif + +static unsigned int mt9v022_get_datawidth(struct soc_camera_device *icd) +{ + struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); + return mt9v022->datawidth; +} + +const struct v4l2_queryctrl mt9v022_controls[] = { + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Vertically", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Horizontally", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Analog Gain", + .minimum = 64, + .maximum = 127, + .step = 1, + .default_value = 64, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure", + .minimum = 1, + .maximum = 255, + .step = 1, + .default_value = 255, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Automatic Gain", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, { + .id = V4L2_CID_EXPOSURE_AUTO, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Automatic Exposure", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + } +}; + +static int mt9v022_get_control(struct soc_camera_device *icd, + struct v4l2_control *ctrl); +static int mt9v022_set_control(struct soc_camera_device *icd, + struct v4l2_control *ctrl); + +static struct soc_camera_ops mt9v022_ops = { + .owner = THIS_MODULE, + .init = mt9v022_init, + .release = mt9v022_release, + .start_capture = mt9v022_start_capture, + .stop_capture = mt9v022_stop_capture, + .set_capture_format = mt9v022_set_capture_format, + .try_fmt_cap = mt9v022_try_fmt_cap, + .formats = mt9v022_formats, + .num_formats = ARRAY_SIZE(mt9v022_formats), + .get_datawidth = mt9v022_get_datawidth, + .controls = mt9v022_controls, + .num_controls = ARRAY_SIZE(mt9v022_controls), + .get_control = mt9v022_get_control, + .set_control = mt9v022_set_control, + .get_chip_id = mt9v022_get_chip_id, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .get_register = mt9v022_get_register, + .set_register = mt9v022_set_register, +#endif +}; + +static int mt9v022_get_control(struct soc_camera_device *icd, + struct v4l2_control *ctrl) +{ + int data; + + switch (ctrl->id) { + case V4L2_CID_VFLIP: + data = reg_read(icd, MT9V022_READ_MODE); + if (data < 0) + return -EIO; + ctrl->value = !!(data & 0x10); + break; + case V4L2_CID_HFLIP: + data = reg_read(icd, MT9V022_READ_MODE); + if (data < 0) + return -EIO; + ctrl->value = !!(data & 0x20); + break; + case V4L2_CID_EXPOSURE_AUTO: + data = reg_read(icd, MT9V022_AEC_AGC_ENABLE); + if (data < 0) + return -EIO; + ctrl->value = !!(data & 0x1); + break; + case V4L2_CID_AUTOGAIN: + data = reg_read(icd, MT9V022_AEC_AGC_ENABLE); + if (data < 0) + return -EIO; + ctrl->value = !!(data & 0x2); + break; + } + return 0; +} + +static int mt9v022_set_control(struct soc_camera_device *icd, + struct v4l2_control *ctrl) +{ + int data; + const struct v4l2_queryctrl *qctrl; + + qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id); + + if (!qctrl) + return -EINVAL; + + switch (ctrl->id) { + case V4L2_CID_VFLIP: + if (ctrl->value) + data = reg_set(icd, MT9V022_READ_MODE, 0x10); + else + data = reg_clear(icd, MT9V022_READ_MODE, 0x10); + if (data < 0) + return -EIO; + break; + case V4L2_CID_HFLIP: + if (ctrl->value) + data = reg_set(icd, MT9V022_READ_MODE, 0x20); + else + data = reg_clear(icd, MT9V022_READ_MODE, 0x20); + if (data < 0) + return -EIO; + break; + case V4L2_CID_GAIN: + /* mt9v022 has minimum == default */ + if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) + return -EINVAL; + else { + unsigned long range = qctrl->maximum - qctrl->minimum; + /* Datasheet says 16 to 64. autogain only works properly + * after setting gain to maximum 14. Larger values + * produce "white fly" noise effect. On the whole, + * manually setting analog gain does no good. */ + unsigned long gain = ((ctrl->value - qctrl->minimum) * + 10 + range / 2) / range + 4; + if (gain >= 32) + gain &= ~1; + /* The user wants to set gain manually, hope, she + * knows, what she's doing... Switch AGC off. */ + + if (reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) + return -EIO; + + dev_info(&icd->dev, "Setting gain from %d to %lu\n", + reg_read(icd, MT9V022_ANALOG_GAIN), gain); + if (reg_write(icd, MT9V022_ANALOG_GAIN, gain) < 0) + return -EIO; + icd->gain = ctrl->value; + } + break; + case V4L2_CID_EXPOSURE: + /* mt9v022 has maximum == default */ + if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) + return -EINVAL; + else { + unsigned long range = qctrl->maximum - qctrl->minimum; + unsigned long shutter = ((ctrl->value - qctrl->minimum) * + 479 + range / 2) / range + 1; + /* The user wants to set shutter width manually, hope, + * she knows, what she's doing... Switch AEC off. */ + + if (reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x1) < 0) + return -EIO; + + dev_dbg(&icd->dev, "Shutter width from %d to %lu\n", + reg_read(icd, MT9V022_TOTAL_SHUTTER_WIDTH), + shutter); + if (reg_write(icd, MT9V022_TOTAL_SHUTTER_WIDTH, + shutter) < 0) + return -EIO; + icd->exposure = ctrl->value; + } + break; + case V4L2_CID_AUTOGAIN: + if (ctrl->value) + data = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x2); + else + data = reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x2); + if (data < 0) + return -EIO; + break; + case V4L2_CID_EXPOSURE_AUTO: + if (ctrl->value) + data = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x1); + else + data = reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x1); + if (data < 0) + return -EIO; + break; + } + return 0; +} + +/* Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one */ +static int mt9v022_video_probe(struct soc_camera_device *icd) +{ + struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); + s32 data; + int ret; + + if (!icd->dev.parent || + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) + return -ENODEV; + + /* Read out the chip version register */ + data = reg_read(icd, MT9V022_CHIP_VERSION); + + /* must be 0x1311 or 0x1313 */ + if (data != 0x1311 && data != 0x1313) { + ret = -ENODEV; + dev_info(&icd->dev, "No MT9V022 detected, ID register 0x%x\n", + data); + goto ei2c; + } + + /* Soft reset */ + ret = reg_write(icd, MT9V022_RESET, 1); + if (ret < 0) + goto ei2c; + /* 15 clock cycles */ + udelay(200); + if (reg_read(icd, MT9V022_RESET)) { + dev_err(&icd->dev, "Resetting MT9V022 failed!\n"); + goto ei2c; + } + + /* Set monochrome or colour sensor type */ + if (sensor_type && (!strcmp("colour", sensor_type) || + !strcmp("color", sensor_type))) { + ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11); + mt9v022->model = V4L2_IDENT_MT9V022IX7ATC; + } else { + ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 0x11); + mt9v022->model = V4L2_IDENT_MT9V022IX7ATM; + } + + if (ret >= 0) + ret = soc_camera_video_start(icd); + if (ret < 0) + goto eisis; + + dev_info(&icd->dev, "Detected a MT9V022 chip ID %x, %s sensor\n", + data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ? + "monochrome" : "colour"); + + return 0; + +eisis: +ei2c: + return ret; +} + +static void mt9v022_video_remove(struct soc_camera_device *icd) +{ + struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); + + dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr, + mt9v022->icd.dev.parent, mt9v022->icd.vdev); + soc_camera_video_stop(&mt9v022->icd); +} + +static int mt9v022_probe(struct i2c_client *client) +{ + struct mt9v022 *mt9v022; + struct soc_camera_device *icd; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct soc_camera_link *icl = client->dev.platform_data; + int ret; + + if (!icl) { + dev_err(&client->dev, "MT9V022 driver needs platform data\n"); + return -EINVAL; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); + return -EIO; + } + + mt9v022 = kzalloc(sizeof(struct mt9v022), GFP_KERNEL); + if (!mt9v022) + return -ENOMEM; + + mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT; + mt9v022->client = client; + i2c_set_clientdata(client, mt9v022); + + icd = &mt9v022->icd; + icd->probe = mt9v022_video_probe; + icd->remove = mt9v022_video_remove; + icd->ops = &mt9v022_ops; + icd->control = &client->dev; + icd->x_min = 1; + icd->y_min = 4; + icd->x_current = 1; + icd->y_current = 4; + icd->width_min = 48; + icd->width_max = 752; + icd->height_min = 32; + icd->height_max = 480; + icd->y_skip_top = 1; + icd->iface = icl->bus_id; + /* Default datawidth - this is the only width this camera (normally) + * supports. It is only with extra logic that it can support + * other widths. Therefore it seems to be a sensible default. */ + mt9v022->datawidth = 10; + + ret = bus_switch_request(mt9v022, icl); + if (ret) + goto eswinit; + + ret = soc_camera_device_register(icd); + if (ret) + goto eisdr; + + return 0; + +eisdr: + bus_switch_release(mt9v022); +eswinit: + kfree(mt9v022); + return ret; +} + +static int mt9v022_remove(struct i2c_client *client) +{ + struct mt9v022 *mt9v022 = i2c_get_clientdata(client); + + soc_camera_device_unregister(&mt9v022->icd); + bus_switch_release(mt9v022); + kfree(mt9v022); + + return 0; +} + +static struct i2c_driver mt9v022_i2c_driver = { + .driver = { + .name = "mt9v022", + }, + .probe = mt9v022_probe, + .remove = mt9v022_remove, +}; + +static int __init mt9v022_mod_init(void) +{ + return i2c_add_driver(&mt9v022_i2c_driver); +} + +static void __exit mt9v022_mod_exit(void) +{ + i2c_del_driver(&mt9v022_i2c_driver); +} + +module_init(mt9v022_mod_init); +module_exit(mt9v022_mod_exit); + +MODULE_DESCRIPTION("Micron MT9V022 Camera driver"); +MODULE_AUTHOR("Guennadi Liakhovetski "); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From fb39812c220ce874907557a3d1687c02bf6e2b6d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 Feb 2008 11:41:53 -0200 Subject: Import pcm990-baseboard, needed by PXA270 Quick Capture driver From: Mauro Carvalho Chehab kernel-sync: Signed-off-by: Mauro Carvalho Chehab --- linux/arch/arm/mach-pxa/pcm990-baseboard.c | 330 +++++++++++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100644 linux/arch/arm/mach-pxa/pcm990-baseboard.c (limited to 'linux') diff --git a/linux/arch/arm/mach-pxa/pcm990-baseboard.c b/linux/arch/arm/mach-pxa/pcm990-baseboard.c new file mode 100644 index 000000000..3dda16a20 --- /dev/null +++ b/linux/arch/arm/mach-pxa/pcm990-baseboard.c @@ -0,0 +1,330 @@ +/* + * arch/arm/mach-pxa/pcm990-baseboard.c + * Support for the Phytec phyCORE-PXA270 Development Platform (PCM-990). + * + * Refer + * http://www.phytec.com/products/rdk/ARM-XScale/phyCORE-XScale-PXA270.html + * for additional hardware info + * + * Author: Juergen Kilb + * Created: April 05, 2005 + * Copyright: Phytec Messtechnik GmbH + * e-Mail: armlinux@phytec.de + * + * based on Intel Mainstone Board + * + * Copyright 2007 Juergen Beisert @ Pengutronix (j.beisert@pengutronix.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * The PCM-990 development baseboard uses PCM-027's hardeware in the + * following way: + * + * - LCD support is in use + * - GPIO16 is output for back light on/off with PWM + * - GPIO58 ... GPIO73 are outputs for display data + * - GPIO74 is output output for LCDFCLK + * - GPIO75 is output for LCDLCLK + * - GPIO76 is output for LCDPCLK + * - GPIO77 is output for LCDBIAS + * - MMC support is in use + * - GPIO32 is output for MMCCLK + * - GPIO92 is MMDAT0 + * - GPIO109 is MMDAT1 + * - GPIO110 is MMCS0 + * - GPIO111 is MMCS1 + * - GPIO112 is MMCMD + * - IDE/CF card is in use + * - GPIO48 is output /POE + * - GPIO49 is output /PWE + * - GPIO50 is output /PIOR + * - GPIO51 is output /PIOW + * - GPIO54 is output /PCE2 + * - GPIO55 is output /PREG + * - GPIO56 is input /PWAIT + * - GPIO57 is output /PIOS16 + * - GPIO79 is output PSKTSEL + * - GPIO85 is output /PCE1 + * - FFUART is in use + * - GPIO34 is input FFRXD + * - GPIO35 is input FFCTS + * - GPIO36 is input FFDCD + * - GPIO37 is input FFDSR + * - GPIO38 is input FFRI + * - GPIO39 is output FFTXD + * - GPIO40 is output FFDTR + * - GPIO41 is output FFRTS + * - BTUART is in use + * - GPIO42 is input BTRXD + * - GPIO43 is output BTTXD + * - GPIO44 is input BTCTS + * - GPIO45 is output BTRTS + * - IRUART is in use + * - GPIO46 is input STDRXD + * - GPIO47 is output STDTXD + * - AC97 is in use*) + * - GPIO28 is input AC97CLK + * - GPIO29 is input AC97DatIn + * - GPIO30 is output AC97DatO + * - GPIO31 is output AC97SYNC + * - GPIO113 is output AC97_RESET + * - SSP is in use + * - GPIO23 is output SSPSCLK + * - GPIO24 is output chip select to Max7301 + * - GPIO25 is output SSPTXD + * - GPIO26 is input SSPRXD + * - GPIO27 is input for Max7301 IRQ + * - GPIO53 is input SSPSYSCLK + * - SSP3 is in use + * - GPIO81 is output SSPTXD3 + * - GPIO82 is input SSPRXD3 + * - GPIO83 is output SSPSFRM + * - GPIO84 is output SSPCLK3 + * + * Otherwise claimed GPIOs: + * GPIO1 -> IRQ from user switch + * GPIO9 -> IRQ from power management + * GPIO10 -> IRQ from WML9712 AC97 controller + * GPIO11 -> IRQ from IDE controller + * GPIO12 -> IRQ from CF controller + * GPIO13 -> IRQ from CF controller + * GPIO14 -> GPIO free + * GPIO15 -> /CS1 selects baseboard's Control CPLD (U7, 16 bit wide data path) + * GPIO19 -> GPIO free + * GPIO20 -> /SDCS2 + * GPIO21 -> /CS3 PC card socket select + * GPIO33 -> /CS5 network controller select + * GPIO78 -> /CS2 (16 bit wide data path) + * GPIO80 -> /CS4 (16 bit wide data path) + * GPIO86 -> GPIO free + * GPIO87 -> GPIO free + * GPIO90 -> LED0 on CPU module + * GPIO91 -> LED1 on CPI module + * GPIO117 -> SCL + * GPIO118 -> SDA + */ + +static unsigned long pcm990_irq_enabled; + +static void pcm990_mask_ack_irq(unsigned int irq) +{ + int pcm990_irq = (irq - PCM027_IRQ(0)); + PCM990_INTMSKENA = (pcm990_irq_enabled &= ~(1 << pcm990_irq)); +} + +static void pcm990_unmask_irq(unsigned int irq) +{ + int pcm990_irq = (irq - PCM027_IRQ(0)); + /* the irq can be acknowledged only if deasserted, so it's done here */ + PCM990_INTSETCLR |= 1 << pcm990_irq; + PCM990_INTMSKENA = (pcm990_irq_enabled |= (1 << pcm990_irq)); +} + +static struct irq_chip pcm990_irq_chip = { + .mask_ack = pcm990_mask_ack_irq, + .unmask = pcm990_unmask_irq, +}; + +static void pcm990_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + unsigned long pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled; + + do { + GEDR(PCM990_CTRL_INT_IRQ_GPIO) = + GPIO_bit(PCM990_CTRL_INT_IRQ_GPIO); + if (likely(pending)) { + irq = PCM027_IRQ(0) + __ffs(pending); + desc = irq_desc + irq; + desc_handle_irq(irq, desc); + } + pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled; + } while (pending); +} + +static void __init pcm990_init_irq(void) +{ + int irq; + + /* setup extra PCM990 irqs */ + for (irq = PCM027_IRQ(0); irq <= PCM027_IRQ(3); irq++) { + set_irq_chip(irq, &pcm990_irq_chip); + set_irq_handler(irq, handle_level_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + + PCM990_INTMSKENA = 0x00; /* disable all Interrupts */ + PCM990_INTSETCLR = 0xFF; + + set_irq_chained_handler(PCM990_CTRL_INT_IRQ, pcm990_irq_handler); + set_irq_type(PCM990_CTRL_INT_IRQ, PCM990_CTRL_INT_IRQ_EDGE); +} + +static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int, + void *data) +{ + int err; + + /* + * enable GPIO for PXA27x MMC controller + */ + pxa_gpio_mode(GPIO32_MMCCLK_MD); + pxa_gpio_mode(GPIO112_MMCCMD_MD); + pxa_gpio_mode(GPIO92_MMCDAT0_MD); + pxa_gpio_mode(GPIO109_MMCDAT1_MD); + pxa_gpio_mode(GPIO110_MMCDAT2_MD); + pxa_gpio_mode(GPIO111_MMCDAT3_MD); + + err = request_irq(PCM027_MMCDET_IRQ, mci_detect_int, IRQF_DISABLED, + "MMC card detect", data); + if (err) + printk(KERN_ERR "pcm990_mci_init: MMC/SD: can't request MMC " + "card detect IRQ\n"); + + return err; +} + +static void pcm990_mci_setpower(struct device *dev, unsigned int vdd) +{ + struct pxamci_platform_data *p_d = dev->platform_data; + + if ((1 << vdd) & p_d->ocr_mask) + __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5) = + PCM990_CTRL_MMC2PWR; + else + __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5) = + ~PCM990_CTRL_MMC2PWR; +} + +static void pcm990_mci_exit(struct device *dev, void *data) +{ + free_irq(PCM027_MMCDET_IRQ, data); +} + +#define MSECS_PER_JIFFY (1000/HZ) + +static struct pxamci_platform_data pcm990_mci_platform_data = { + .detect_delay = 250 / MSECS_PER_JIFFY, + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .init = pcm990_mci_init, + .setpower = pcm990_mci_setpower, + .exit = pcm990_mci_exit, +}; + +/* + * init OHCI hardware to work with + * + * Note: Only USB port 1 (host only) is connected + * + * GPIO88 (USBHPWR#1): overcurrent in, overcurrent when low + * GPIO89 (USBHPEN#1): power-on out, on when low + */ +static int pcm990_ohci_init(struct device *dev) +{ + pxa_gpio_mode(PCM990_USB_OVERCURRENT); + pxa_gpio_mode(PCM990_USB_PWR_EN); + /* + * disable USB port 2 and 3 + * power sense is active low + */ + UHCHR = ((UHCHR) | UHCHR_PCPL | UHCHR_PSPL | UHCHR_SSEP2 | + UHCHR_SSEP3) & ~(UHCHR_SSEP1 | UHCHR_SSE); + /* + * wait 10ms after Power on + * overcurrent per port + * power switch per port + */ + UHCRHDA = (5<<24) | (1<<11) | (1<<8); /* FIXME: Required? */ + + return 0; +} + +static struct pxaohci_platform_data pcm990_ohci_platform_data = { + .port_mode = PMM_PERPORT_MODE, + .init = pcm990_ohci_init, + .exit = NULL, +}; + +/* + * AC97 support + * Note: The connected AC97 mixer also reports interrupts at PCM990_AC97_IRQ + */ +static struct resource pxa27x_ac97_resources[] = { + [0] = { + .start = 0x40500000, + .end = 0x40500000 + 0xfff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_AC97, + .end = IRQ_AC97, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 pxa_ac97_dmamask = 0xffffffffUL; + +static struct platform_device pxa27x_device_ac97 = { + .name = "pxa2xx-ac97", + .id = -1, + .dev = { + .dma_mask = &pxa_ac97_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxa27x_ac97_resources), + .resource = pxa27x_ac97_resources, +}; + +/* + * enable generic access to the base board control CPLDs U6 and U7 + */ +static struct map_desc pcm990_io_desc[] __initdata = { + { + .virtual = PCM990_CTRL_BASE, + .pfn = __phys_to_pfn(PCM990_CTRL_PHYS), + .length = PCM990_CTRL_SIZE, + .type = MT_DEVICE /* CPLD */ + }, { + .virtual = PCM990_CF_PLD_BASE, + .pfn = __phys_to_pfn(PCM990_CF_PLD_PHYS), + .length = PCM990_CF_PLD_SIZE, + .type = MT_DEVICE /* CPLD */ + } +}; + +/* + * system init for baseboard usage. Will be called by pcm027 init. + * + * Add platform devices present on this baseboard and init + * them from CPU side as far as required to use them later on + */ +void __init pcm990_baseboard_init(void) +{ + /* register CPLD access */ + iotable_init(pcm990_io_desc, ARRAY_SIZE(pcm990_io_desc)); + + /* register CPLD's IRQ controller */ + pcm990_init_irq(); + + platform_device_register(&pxa27x_device_ac97); + + /* MMC */ + pxa_set_mci_info(&pcm990_mci_platform_data); + + /* USB host */ + pxa_set_ohci_info(&pcm990_ohci_platform_data); + + printk(KERN_INFO"PCM-990 Evaluation baseboard initialized\n"); +} -- cgit v1.2.3 From 9c4abbef3b6964bb50ab0b2d3792c41c94013c76 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 17:47:33 +0000 Subject: Phycore pcm-990-specific code for the PXA270 Quick Capture driver From: Guennadi Liakhovetski Platform-specific code for Phytec's phyCORE-PXA270 platform Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- linux/arch/arm/mach-pxa/pcm990-baseboard.c | 86 ++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'linux') diff --git a/linux/arch/arm/mach-pxa/pcm990-baseboard.c b/linux/arch/arm/mach-pxa/pcm990-baseboard.c index 3dda16a20..07ac050f2 100644 --- a/linux/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/linux/arch/arm/mach-pxa/pcm990-baseboard.c @@ -23,6 +23,13 @@ #include #include #include +#include + +#include + +#include +#include +#include #include #include #include @@ -257,6 +264,76 @@ static struct pxaohci_platform_data pcm990_ohci_platform_data = { .exit = NULL, }; +/* + * PXA27x Camera specific stuff + */ +#if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE) +static int pcm990_pxacamera_init(struct device *dev) +{ + pxa_gpio_mode(GPIO98_CIF_DD0_MD); + pxa_gpio_mode(GPIO105_CIF_DD1_MD); + pxa_gpio_mode(GPIO104_CIF_DD2_MD); + pxa_gpio_mode(GPIO103_CIF_DD3_MD); + pxa_gpio_mode(GPIO95_CIF_DD4_MD); + pxa_gpio_mode(GPIO94_CIF_DD5_MD); + pxa_gpio_mode(GPIO93_CIF_DD6_MD); + pxa_gpio_mode(GPIO108_CIF_DD7_MD); + pxa_gpio_mode(GPIO107_CIF_DD8_MD); + pxa_gpio_mode(GPIO106_CIF_DD9_MD); + pxa_gpio_mode(GPIO42_CIF_MCLK_MD); + pxa_gpio_mode(GPIO45_CIF_PCLK_MD); + pxa_gpio_mode(GPIO43_CIF_FV_MD); + pxa_gpio_mode(GPIO44_CIF_LV_MD); + + return 0; +} + +/* + * CICR4: PCLK_EN: Pixel clock is supplied by the sensor + * MCLK_EN: Master clock is generated by PXA + * PCP: Data sampled on the falling edge of pixel clock + */ +struct pxacamera_platform_data pcm990_pxacamera_platform_data = { + .init = pcm990_pxacamera_init, + .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 | PXA_CAMERA_DATAWIDTH_10 | + PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN/* | PXA_CAMERA_PCP*/, + .mclk_10khz = 1000, +}; + +#include + +static struct pca953x_platform_data pca9536_data = { + .gpio_base = NR_BUILTIN_GPIO + 1, +}; + +static struct soc_camera_link iclink[] = { + { + .bus_id = 0, /* Must match with the camera ID above */ + .gpio = NR_BUILTIN_GPIO + 1, + }, { + .bus_id = 0, /* Must match with the camera ID above */ + } +}; + +/* Board I2C devices. */ +static struct i2c_board_info __initdata pcm990_i2c_devices[] = { + { + /* Must initialize before the camera(s) */ + I2C_BOARD_INFO("pca953x", 0x41), + .type = "pca9536", + .platform_data = &pca9536_data, + }, { + I2C_BOARD_INFO("mt9v022", 0x48), + .type = "mt9v022", + .platform_data = &iclink[0], /* With extender */ + }, { + I2C_BOARD_INFO("mt9m001", 0x5d), + .type = "mt9m001", + .platform_data = &iclink[0], /* With extender */ + }, +}; +#endif /* CONFIG_VIDEO_PXA27x ||CONFIG_VIDEO_PXA27x_MODULE */ + /* * AC97 support * Note: The connected AC97 mixer also reports interrupts at PCM990_AC97_IRQ @@ -326,5 +403,14 @@ void __init pcm990_baseboard_init(void) /* USB host */ pxa_set_ohci_info(&pcm990_ohci_platform_data); + pxa_set_i2c_info(NULL); + +#if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE) + pxa_set_camera_info(&pcm990_pxacamera_platform_data); + + i2c_register_board_info(0, pcm990_i2c_devices, + ARRAY_SIZE(pcm990_i2c_devices)); +#endif + printk(KERN_INFO"PCM-990 Evaluation baseboard initialized\n"); } -- cgit v1.2.3 From 3cf41ff6b196d684a316e5e007b5cacf7acb977a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 Feb 2008 20:46:16 +0000 Subject: Add two new fourcc codes for 16bpp formats From: Steven Whitehouse This adds two new fourcc codes (as per info at fourcc.org) for 16bpp mono and 16bpp Bayer formats. Signed-off-by: Steven Whitehouse Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- linux/include/linux/videodev2.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'linux') diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index a43a03e02..cbaf58c86 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -281,6 +281,7 @@ struct v4l2_pix_format #define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B','G','R','4') /* 32 BGR-8-8-8-8 */ #define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R','G','B','4') /* 32 RGB-8-8-8-8 */ #define V4L2_PIX_FMT_GREY v4l2_fourcc('G','R','E','Y') /* 8 Greyscale */ +#define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y','1','6',' ') /* 16 Greyscale */ #define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P','A','L','8') /* 8 8-bit palette */ #define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y','V','U','9') /* 9 YVU 4:1:0 */ #define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y','V','1','2') /* 12 YVU 4:2:0 */ @@ -307,6 +308,7 @@ struct v4l2_pix_format /* see http://www.siliconimaging.com/RGB%20Bayer.htm */ #define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B','A','8','1') /* 8 BGBG.. GRGR.. */ +#define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B','Y','R','2') /* 16 BGBG.. GRGR.. */ /* compressed formats */ #define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M','J','P','G') /* Motion-JPEG */ -- cgit v1.2.3 From 783fe175c2266d2de9ced54cefe104e6343d7c14 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 8 Feb 2008 13:44:25 -0200 Subject: Allow more than one em28xx board From: Mauro Carvalho Chehab em28xx driver is capable of handling more than one usb device. However, isoc transfers require a large amount of data to be transfered. Before this patch, just one em28xx board were enough to allocate more than 50% URBs: T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 8 B: Alloc=480/800 us (60%), #Int= 0, #Iso= 2 D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS=64 #Cfgs= 1 So, only one board could use an USB host at the same time. After the patch, it is possible to use more than one em28xx at the same time, on the same usb host, if the image size is slower or equal to 345600, since those images will require about 30% of the URBs: T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 8 B: Alloc=232/800 us (29%), #Int= 0, #Iso= 2 D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS=64 #Cfgs= 1 So, in thesis, after the patch, it would be possible to use up to 3 boards by each usb host, if the devices are generating small images. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-core.c | 78 ++++++++++++------------- linux/drivers/media/video/em28xx/em28xx-video.c | 4 +- linux/drivers/media/video/em28xx/em28xx.h | 2 +- 3 files changed, 42 insertions(+), 42 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c index 441413016..5fba63bb0 100644 --- a/linux/drivers/media/video/em28xx/em28xx-core.c +++ b/linux/drivers/media/video/em28xx/em28xx-core.c @@ -114,7 +114,8 @@ u32 em28xx_request_buffers(struct em28xx *dev, u32 count) const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */ void *buff = NULL; u32 i; - em28xx_coredbg("requested %i buffers with size %zi", count, imagesize); + em28xx_coredbg("requested %i buffers with size %zi\n", + count, imagesize); if (count > EM28XX_NUM_FRAMES) count = EM28XX_NUM_FRAMES; @@ -739,7 +740,7 @@ static void em28xx_isocIrq(struct urb *urb) continue; } if (urb->iso_frame_desc[i].actual_length > - dev->max_pkt_size) { + urb->iso_frame_desc[i].length) { em28xx_isocdbg("packet bigger than packet size"); continue; } @@ -785,8 +786,11 @@ void em28xx_uninit_isoc(struct em28xx *dev) for (i = 0; i < EM28XX_NUM_BUFS; i++) { if (dev->urb[i]) { usb_kill_urb(dev->urb[i]); - if (dev->transfer_buffer[i]){ - usb_buffer_free(dev->udev,(EM28XX_NUM_PACKETS*dev->max_pkt_size),dev->transfer_buffer[i],dev->urb[i]->transfer_dma); + if (dev->transfer_buffer[i]) { + usb_buffer_free(dev->udev, + dev->urb[i]->transfer_buffer_length, + dev->transfer_buffer[i], + dev->urb[i]->transfer_dma); } usb_free_urb(dev->urb[i]); } @@ -804,7 +808,10 @@ int em28xx_init_isoc(struct em28xx *dev) { /* change interface to 3 which allows the biggest packet sizes */ int i, errCode; - const int sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size; + int sb_size; + + em28xx_set_alternate(dev); + sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size; /* reset streaming vars */ dev->frame_current = NULL; @@ -813,7 +820,7 @@ int em28xx_init_isoc(struct em28xx *dev) /* allocate urbs */ for (i = 0; i < EM28XX_NUM_BUFS; i++) { struct urb *urb; - int j, k; + int j; /* allocate transfer buffer */ urb = usb_alloc_urb(EM28XX_NUM_PACKETS, GFP_KERNEL); if (!urb){ @@ -821,7 +828,9 @@ int em28xx_init_isoc(struct em28xx *dev) em28xx_uninit_isoc(dev); return -ENOMEM; } - dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,&urb->transfer_dma); + dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, + GFP_KERNEL, + &urb->transfer_dma); if (!dev->transfer_buffer[i]) { em28xx_errdev ("unable to allocate %i bytes for transfer buffer %i\n", @@ -840,16 +849,16 @@ int em28xx_init_isoc(struct em28xx *dev) urb->complete = em28xx_isocIrq; urb->number_of_packets = EM28XX_NUM_PACKETS; urb->transfer_buffer_length = sb_size; - for (j = k = 0; j < EM28XX_NUM_PACKETS; - j++, k += dev->max_pkt_size) { - urb->iso_frame_desc[j].offset = k; - urb->iso_frame_desc[j].length = - dev->max_pkt_size; + for (j = 0; j < EM28XX_NUM_PACKETS; j++) { + urb->iso_frame_desc[j].offset = j * dev->max_pkt_size; + urb->iso_frame_desc[j].length = dev->max_pkt_size; } dev->urb[i] = urb; } /* submit urbs */ + em28xx_coredbg("Submitting %d urbs of %d packets (%d each)\n", + EM28XX_NUM_BUFS, EM28XX_NUM_PACKETS, dev->max_pkt_size); for (i = 0; i < EM28XX_NUM_BUFS; i++) { errCode = usb_submit_urb(dev->urb[i], GFP_KERNEL); if (errCode) { @@ -866,40 +875,31 @@ int em28xx_init_isoc(struct em28xx *dev) int em28xx_set_alternate(struct em28xx *dev) { int errCode, prev_alt = dev->alt; - dev->alt = alt; - if (dev->alt == 0) { - int i; -#if 1 /* Always try to get the maximum size value */ - for(i=0;i< dev->num_alt; i++) - if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt]) - dev->alt=i; -#endif -#if 0 /* Should be dependent of horizontal size */ - if(dev->is_em2800){ /* always use the max packet size for em2800 based devices */ - for(i=0;i< dev->num_alt; i++) - if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt]) - dev->alt=i; - }else{ - unsigned int min_pkt_size = dev->field_size / 137; /* FIXME: empiric magic number */ - em28xx_coredbg("minimum isoc packet size: %u", min_pkt_size); - dev->alt = 7; - for (i = 0; i < dev->num_alt; i ++) - if (dev->alt_max_pkt_size[i] >= min_pkt_size) { - dev->alt = i; + int i; + unsigned int min_pkt_size = dev->bytesperline+4; + + /* When image size is bigger than a ceirtain value, + the frame size should be increased, otherwise, only + green screen will be received. + */ + if (dev->frame_size > 720*240*2) + min_pkt_size *= 2; + + for (i = 0; i < dev->num_alt; i++) + if (dev->alt_max_pkt_size[i] >= min_pkt_size) break; - } - } -#endif - } + dev->alt = i; if (dev->alt != prev_alt) { + em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n", + min_pkt_size, dev->alt); dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt]; - em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", dev->alt, - dev->max_pkt_size); + em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", + dev->alt, dev->max_pkt_size); errCode = usb_set_interface(dev->udev, 0, dev->alt); if (errCode < 0) { em28xx_errdev ("cannot change alternate number to %d (error=%i)\n", - dev->alt, errCode); + dev->alt, errCode); return errCode; } } diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index bf8693dbf..4999897ed 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -1411,8 +1411,6 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) filp->private_data = fh; if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { - em28xx_set_alternate(dev); - dev->width = norm_maxw(dev); dev->height = norm_maxh(dev); dev->frame_size = dev->width * dev->height * 2; @@ -1421,6 +1419,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) dev->hscale = 0; dev->vscale = 0; + em28xx_set_alternate(dev); em28xx_capture_start(dev, 1); em28xx_resolution_set(dev); @@ -2224,6 +2223,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, snprintf(dev->name, 29, "em28xx #%d", nr); dev->devno = nr; dev->model = id->driver_info; + dev->alt = -1; /* Checks if audio is provided by some interface */ for (i = 0; i < udev->config->desc.bNumInterfaces; i++) { diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index fae498926..980989f11 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -36,7 +36,7 @@ #define UNSET -1 /* maximum number of em28xx boards */ -#define EM28XX_MAXBOARDS 1 /*FIXME: should be bigger */ +#define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */ /* maximum number of frames that can be queued */ #define EM28XX_NUM_FRAMES 5 -- cgit v1.2.3 From b1053c3334bca750f73689da1b1f2204bb9683de Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 8 Feb 2008 14:07:04 -0200 Subject: em28xx: add URB_NO_TRANSFER_DMA_MAP, since urb->transfer_dma is set From: Mauro Carvalho Chehab Thanks to Alan Stern for pointing this issue. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c index 5fba63bb0..a77cb8099 100644 --- a/linux/drivers/media/video/em28xx/em28xx-core.c +++ b/linux/drivers/media/video/em28xx/em28xx-core.c @@ -843,7 +843,7 @@ int em28xx_init_isoc(struct em28xx *dev) urb->dev = dev->udev; urb->context = dev; urb->pipe = usb_rcvisocpipe(dev->udev, 0x82); - urb->transfer_flags = URB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; urb->interval = 1; urb->transfer_buffer = dev->transfer_buffer[i]; urb->complete = em28xx_isocIrq; -- cgit v1.2.3 From a042cc6d0f7afd9f007a070fded78d32606b0133 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 9 Feb 2008 16:08:24 +0000 Subject: autosuspend support From: Tobias Lorenz Together with Oliver Neukum from Novell, USB autosuspend support was added. Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/radio-si470x.c | 83 +++++++++++++++++++++++++++++--- 1 file changed, 75 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 f1f1430f3..772c3a126 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -81,6 +81,10 @@ * - racy interruptible_sleep_on(), * replaced with wait_event_interruptible() * - handle signals in read() + * 2008-02-08 Tobias Lorenz + * Oliver Neukum + * Version 1.0.7 + * - usb autosuspend support * * ToDo: * - add seeking support @@ -416,6 +420,7 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); struct si470x_device { /* reference to USB and video device */ struct usb_device *usbdev; + struct usb_interface *intf; struct video_device *videodev; /* driver management */ @@ -763,9 +768,17 @@ static int si470x_stop(struct si470x_device *radio) */ static int si470x_rds_on(struct si470x_device *radio) { + int retval; + /* sysconfig 1 */ + mutex_lock(&radio->lock); radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDS; - return si470x_set_register(radio, SYSCONFIG1); + retval = si470x_set_register(radio, SYSCONFIG1); + if (retval < 0) + radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS; + mutex_unlock(&radio->lock); + + return retval; } @@ -962,10 +975,22 @@ static unsigned int si470x_fops_poll(struct file *file, static int si470x_fops_open(struct inode *inode, struct file *file) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); + int retval; radio->users++; - if (radio->users == 1) - return si470x_start(radio); + + retval = usb_autopm_get_interface(radio->intf); + if (retval < 0) { + radio->users--; + return -EIO; + } + + if (radio->users == 1) { + retval = si470x_start(radio); + if (retval < 0) + usb_autopm_put_interface(radio->intf); + return retval; + } return 0; } @@ -977,6 +1002,7 @@ static int si470x_fops_open(struct inode *inode, struct file *file) static int si470x_fops_release(struct inode *inode, struct file *file) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); + int retval; if (!radio) return -ENODEV; @@ -989,7 +1015,9 @@ static int si470x_fops_release(struct inode *inode, struct file *file) /* cancel read processes */ wake_up_interruptible(&radio->read_queue); - return si470x_stop(radio); + retval = si470x_stop(radio); + usb_autopm_put_interface(radio->intf); + return retval; } return 0; @@ -1378,6 +1406,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, sizeof(si470x_viddev_template)); radio->users = 0; radio->usbdev = interface_to_usbdev(intf); + radio->intf = intf; mutex_init(&radio->lock); video_set_drvdata(radio->videodev, radio); @@ -1440,6 +1469,41 @@ err_initial: } +/* + * si470x_usb_driver_suspend - suspend the device + */ +static int si470x_usb_driver_suspend(struct usb_interface *intf, + pm_message_t message) +{ + struct si470x_device *radio = usb_get_intfdata(intf); + + printk(KERN_INFO DRIVER_NAME ": suspending now...\n"); + + cancel_delayed_work_sync(&radio->work); + + return 0; +} + + +/* + * si470x_usb_driver_resume - resume the device + */ +static int si470x_usb_driver_resume(struct usb_interface *intf) +{ + struct si470x_device *radio = usb_get_intfdata(intf); + + printk(KERN_INFO DRIVER_NAME ": resuming now...\n"); + + mutex_lock(&radio->lock); + if (radio->users && radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) + schedule_delayed_work(&radio->work, + msecs_to_jiffies(rds_poll_time)); + mutex_unlock(&radio->lock); + + return 0; +} + + /* * si470x_usb_driver_disconnect - disconnect the device */ @@ -1459,10 +1523,13 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf) * si470x_usb_driver - usb driver interface */ static struct usb_driver si470x_usb_driver = { - .name = DRIVER_NAME, - .probe = si470x_usb_driver_probe, - .disconnect = si470x_usb_driver_disconnect, - .id_table = si470x_usb_driver_id_table, + .name = DRIVER_NAME, + .probe = si470x_usb_driver_probe, + .disconnect = si470x_usb_driver_disconnect, + .suspend = si470x_usb_driver_suspend, + .resume = si470x_usb_driver_resume, + .id_table = si470x_usb_driver_id_table, + .supports_autosuspend = 1, }; -- cgit v1.2.3 From 5af359015ddc9e36fc7a6620dbc0e8a1bdd08e93 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 10 Feb 2008 15:39:20 -0200 Subject: arv/planb/vino: Add kernel validation to mutex From: Douglas Schilling Landgraf Added kernel validation to support mutex/semaphore. (kernel < 2.6.16) Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/video/arv.c | 7 +++++++ linux/drivers/media/video/planb.c | 3 +++ linux/drivers/media/video/planb.h | 4 ++++ linux/drivers/media/video/vino.c | 12 ++++++++++++ 4 files changed, 26 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/arv.c b/linux/drivers/media/video/arv.c index 479ca4b46..0cd7f1d5e 100644 --- a/linux/drivers/media/video/arv.c +++ b/linux/drivers/media/video/arv.c @@ -30,7 +30,10 @@ #include "compat.h" #include #include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 16) #include +#endif #include #include @@ -116,7 +119,11 @@ struct ar_device { int width, height; int frame_bytes, line_bytes; wait_queue_head_t wait; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 16) struct mutex lock; +#else + struct semaphore lock; +#endif }; static int video_nr = -1; /* video device number (first free) */ diff --git a/linux/drivers/media/video/planb.c b/linux/drivers/media/video/planb.c index 358dc2996..e9860c883 100644 --- a/linux/drivers/media/video/planb.c +++ b/linux/drivers/media/video/planb.c @@ -50,7 +50,10 @@ #include #include #include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 16) #include +#endif #include "planb.h" #include "saa7196.h" diff --git a/linux/drivers/media/video/planb.h b/linux/drivers/media/video/planb.h index e21b5735c..944e4960a 100644 --- a/linux/drivers/media/video/planb.h +++ b/linux/drivers/media/video/planb.h @@ -174,7 +174,11 @@ struct planb { int user; unsigned int tab_size; int maxlines; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 16) struct mutex lock; +#else + struct semaphore lock; +#endif unsigned int irq; /* interrupt number */ volatile unsigned int intr_mask; struct pci_dev *dev; /* Our PCI device */ diff --git a/linux/drivers/media/video/vino.c b/linux/drivers/media/video/vino.c index 01a4b9d3e..b867e7e8c 100644 --- a/linux/drivers/media/video/vino.c +++ b/linux/drivers/media/video/vino.c @@ -41,7 +41,10 @@ #include #include #include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 16) #include +#endif #include #include @@ -245,7 +248,11 @@ struct vino_framebuffer_queue { struct vino_framebuffer *buffer[VINO_FRAMEBUFFER_COUNT_MAX]; spinlock_t queue_lock; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 16) struct mutex queue_mutex; +#else + struct semaphore queue_mutex; +#endif wait_queue_head_t frame_wait_queue; }; @@ -283,7 +290,12 @@ struct vino_channel_settings { /* the driver is currently processing the queue */ int capturing; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 16) struct mutex mutex; +#else + struct semaphore mutex; +#endif + spinlock_t capture_lock; unsigned int users; -- cgit v1.2.3 From c9d118cc0e102ecbd6bfa490ba556fd9e996dfed Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 11 Feb 2008 10:40:53 -0200 Subject: Adds support for Genius TVGo A11MCE From: Adrian Pardini Signed-off-by: Adrian Pardini Signed-off-by: Mauro Carvalho Chehab --- linux/Documentation/video4linux/CARDLIST.saa7134 | 1 + linux/drivers/media/common/ir-keymaps.c | 46 +++++++++++++++++++++++ linux/drivers/media/video/saa7134/saa7134-cards.c | 39 +++++++++++++++++++ linux/drivers/media/video/saa7134/saa7134-input.c | 6 +++ linux/drivers/media/video/saa7134/saa7134.h | 1 + linux/include/media/ir-common.h | 1 + 6 files changed, 94 insertions(+) (limited to 'linux') diff --git a/linux/Documentation/video4linux/CARDLIST.saa7134 b/linux/Documentation/video4linux/CARDLIST.saa7134 index 1074925fb..0424901eb 100644 --- a/linux/Documentation/video4linux/CARDLIST.saa7134 +++ b/linux/Documentation/video4linux/CARDLIST.saa7134 @@ -130,3 +130,4 @@ 129 -> Beholder BeholdTV 607 / BeholdTV 609 [5ace:6070,5ace:6071,5ace:6072,5ace:6073,5ace:6090,5ace:6091,5ace:6092,5ace:6093] 130 -> Beholder BeholdTV M6 / BeholdTV M6 Extra [5ace:6190,5ace:6193] 131 -> Twinhan Hybrid DTV-DVB 3056 PCI [1822:0022] +132 -> Genius TVGO AM11MCE diff --git a/linux/drivers/media/common/ir-keymaps.c b/linux/drivers/media/common/ir-keymaps.c index d3d3c0e5e..3f5f9ad94 100644 --- a/linux/drivers/media/common/ir-keymaps.c +++ b/linux/drivers/media/common/ir-keymaps.c @@ -2037,3 +2037,49 @@ IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE] = { }; EXPORT_SYMBOL_GPL(ir_codes_behold); + +/* + * Remote control for the Genius TVGO A11MCE + * Adrian Pardini + */ +IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE] = { + /* Keys 0 to 9 */ + [0x48] = KEY_0, + [0x09] = KEY_1, + [0x1d] = KEY_2, + [0x1f] = KEY_3, + [0x19] = KEY_4, + [0x1b] = KEY_5, + [0x11] = KEY_6, + [0x17] = KEY_7, + [0x12] = KEY_8, + [0x16] = KEY_9, + + [0x54] = KEY_RECORD, /* recording */ + [0x06] = KEY_MUTE, /* mute */ + [0x10] = KEY_POWER, + [0x40] = KEY_LAST, /* recall */ + [0x4c] = KEY_CHANNELUP, /* channel / program + */ + [0x00] = KEY_CHANNELDOWN, /* channel / program - */ + [0x0d] = KEY_VOLUMEUP, + [0x15] = KEY_VOLUMEDOWN, + [0x4d] = KEY_OK, /* also labeled as Pause */ + [0x1c] = KEY_ZOOM, /* full screen and Stop*/ + [0x02] = KEY_MODE, /* AV Source or Rewind*/ + [0x04] = KEY_LIST, /* -/-- */ + /* small arrows above numbers */ + [0x1a] = KEY_NEXT, /* also Fast Forward */ + [0x0e] = KEY_PREVIOUS, /* also Rewind */ + /* these are in a rather non standard layout and have + an alternate name written */ + [0x1e] = KEY_UP, /* Video Setting */ + [0x0a] = KEY_DOWN, /* Video Default */ + [0x05] = KEY_LEFT, /* Snapshot */ + [0x0c] = KEY_RIGHT, /* Hide Panel */ + /* Four buttons without label */ + [0x49] = KEY_RED, + [0x0b] = KEY_GREEN, + [0x13] = KEY_YELLOW, + [0x50] = KEY_BLUE, +}; +EXPORT_SYMBOL_GPL(ir_codes_genius_tvgo_a11mce); diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c index 92219be5f..af9dfe35d 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -3992,6 +3992,44 @@ struct saa7134_board saa7134_boards[] = { .gpio = 0x0200000, }, }, + [SAA7134_BOARD_GENIUS_TVGO_A11MCE] = { + /* Adrian Pardini */ + .name = "Genius TVGO AM11MCE", + .audio_clock = 0x00200000, + .tuner_type = TUNER_TNF_5335MF, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .gpiomask = 0xf000, + .inputs = {{ + .name = name_tv_mono, + .vmux = 1, + .amux = LINE2, + .gpio = 0x0000, + .tv = 1, + }, { + .name = name_comp1, + .vmux = 3, + .amux = LINE1, + .gpio = 0x2000, + .tv = 1 + }, { + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + .gpio = 0x2000, + } }, + .radio = { + .name = name_radio, + .amux = LINE2, + .gpio = 0x1000, + }, + .mute = { + .name = name_mute, + .amux = LINE2, + .gpio = 0x6000, + }, + }, }; const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); @@ -5130,6 +5168,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_BEHOLD_409: case SAA7134_BOARD_BEHOLD_505FM: case SAA7134_BOARD_BEHOLD_507_9FM: + case SAA7134_BOARD_GENIUS_TVGO_A11MCE: dev->has_remote = SAA7134_REMOTE_GPIO; break; case SAA7134_BOARD_FLYDVBS_LR300: diff --git a/linux/drivers/media/video/saa7134/saa7134-input.c b/linux/drivers/media/video/saa7134/saa7134-input.c index 09414dd6d..225f075e5 100644 --- a/linux/drivers/media/video/saa7134/saa7134-input.c +++ b/linux/drivers/media/video/saa7134/saa7134-input.c @@ -406,6 +406,12 @@ int saa7134_input_init1(struct saa7134_dev *dev) mask_keyup = 0x8000000; polling = 50; //ms break; + case SAA7134_BOARD_GENIUS_TVGO_A11MCE: + ir_codes = ir_codes_genius_tvgo_a11mce; + mask_keycode = 0xff; + mask_keydown = 0xf00000; + polling = 50; /* ms */ + break; } if (NULL == ir_codes) { printk("%s: Oops: IR config error [card=%d]\n", diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h index b7464c706..d89255d03 100644 --- a/linux/drivers/media/video/saa7134/saa7134.h +++ b/linux/drivers/media/video/saa7134/saa7134.h @@ -260,6 +260,7 @@ struct saa7134_format { #define SAA7134_BOARD_BEHOLD_607_9FM 129 #define SAA7134_BOARD_BEHOLD_M6 130 #define SAA7134_BOARD_TWINHAN_DTV_DVB_3056 131 +#define SAA7134_BOARD_GENIUS_TVGO_A11MCE 132 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 diff --git a/linux/include/media/ir-common.h b/linux/include/media/ir-common.h index 831547d79..a4274203f 100644 --- a/linux/include/media/ir-common.h +++ b/linux/include/media/ir-common.h @@ -142,6 +142,7 @@ extern IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE]; #endif -- cgit v1.2.3 From 620e3e5b821537944f45aff74ef46b136d8e12e1 Mon Sep 17 00:00:00 2001 From: Ricardo Cerqueira Date: Wed, 16 Jan 2008 19:56:55 +0000 Subject: tveeprom: Add proper tuner mapping for hauppauge eeprom id 133 From: Ricardo Cerqueira Do away with the need to set tuner=63 on cx88xx with recent HVR-1300 boards Signed-off-by: Ricardo Cerqueira --- linux/drivers/media/video/tveeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tveeprom.c b/linux/drivers/media/video/tveeprom.c index 30b3ba468..9b95d2f28 100644 --- a/linux/drivers/media/video/tveeprom.c +++ b/linux/drivers/media/video/tveeprom.c @@ -246,7 +246,7 @@ hauppauge_tuner[] = { TUNER_ABSENT, "TCL M2523_3DBH_E"}, { TUNER_ABSENT, "TCL M2523_3DIH_E"}, { TUNER_ABSENT, "TCL MFPE05_2_U"}, - { TUNER_ABSENT, "Philips FMD1216MEX"}, + { TUNER_PHILIPS_FMD1216ME_MK3, "Philips FMD1216MEX"}, { TUNER_ABSENT, "Philips FRH2036B"}, { TUNER_ABSENT, "Panasonic ENGF75_01GF"}, { TUNER_ABSENT, "MaxLinear MXL5005"}, -- cgit v1.2.3 From 031442503c1ea2fc56a32c1027c5dd1c4e8f05b7 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 27 Jan 2008 15:01:16 -0500 Subject: tuner-simple: create separate t_params and ranges lookup functions From: Michael Krufky Move some reuseable code out of simple_set_tv_freq into separate functions. Signed-off-by: Michael Krufky --- linux/drivers/media/video/tuner-simple.c | 109 +++++++++++++++++++++++-------- 1 file changed, 80 insertions(+), 29 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tuner-simple.c b/linux/drivers/media/video/tuner-simple.c index 1cb81befe..0f657cb7c 100644 --- a/linux/drivers/media/video/tuner-simple.c +++ b/linux/drivers/media/video/tuner-simple.c @@ -187,6 +187,82 @@ static int simple_get_rf_strength(struct dvb_frontend *fe, u16 *strength) /* ---------------------------------------------------------------------- */ +static inline char *tuner_param_name(enum param_type type) +{ + char *name; + + switch (type) { + case TUNER_PARAM_TYPE_RADIO: + name = "radio"; + break; + case TUNER_PARAM_TYPE_PAL: + name = "pal"; + break; + case TUNER_PARAM_TYPE_SECAM: + name = "secam"; + break; + case TUNER_PARAM_TYPE_NTSC: + name = "ntsc"; + break; + default: + name = "unknown"; + break; + } + return name; +} + +static struct tuner_params *simple_tuner_params(struct dvb_frontend *fe, + enum param_type desired_type) +{ + struct tuner_simple_priv *priv = fe->tuner_priv; + struct tunertype *tun = priv->tun; + int i; + + for (i = 0; i < tun->count; i++) + if (desired_type == tun->params[i].type) + break; + + /* use default tuner params if desired_type not available */ + if (i == tun->count) { + tuner_dbg("desired params (%s) undefined for tuner %d\n", + tuner_param_name(desired_type), priv->type); + i = 0; + } + + tuner_dbg("using tuner params #%d (%s)\n", i, + tuner_param_name(tun->params[i].type)); + + return &tun->params[i]; +} + +static int simple_config_lookup(struct dvb_frontend *fe, + struct tuner_params *t_params, + int *frequency, u8 *config, u8 *cb) +{ + struct tuner_simple_priv *priv = fe->tuner_priv; + int i; + + for (i = 0; i < t_params->count; i++) { + if (*frequency > t_params->ranges[i].limit) + continue; + break; + } + if (i == t_params->count) { + tuner_dbg("frequency out of range (%d > %d)\n", + *frequency, t_params->ranges[i - 1].limit); + *frequency = t_params->ranges[--i].limit; + } + *config = t_params->ranges[i].config; + *cb = t_params->ranges[i].cb; + + tuner_dbg("freq = %d, range = %d, config = 0x%02x, cb = 0x%02x\n", + *frequency, i, *config, *cb); + + return i; +} + +/* ---------------------------------------------------------------------- */ + static int simple_set_tv_freq(struct dvb_frontend *fe, struct analog_parameters *params) { @@ -195,7 +271,7 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, u16 div; struct tunertype *tun; u8 buffer[4]; - int rc, IFPCoff, i, j; + int rc, IFPCoff, i; enum param_type desired_type; struct tuner_params *t_params; @@ -228,35 +304,10 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, desired_type = TUNER_PARAM_TYPE_PAL; } - for (j = 0; j < tun->count-1; j++) { - if (desired_type != tun->params[j].type) - continue; - break; - } - /* use default tuner params if desired_type not available */ - if (desired_type != tun->params[j].type) { - tuner_dbg("IFPCoff = %d: params undefined for tuner %d\n", - IFPCoff, priv->type); - j = 0; - } - t_params = &tun->params[j]; + t_params = simple_tuner_params(fe, desired_type); - for (i = 0; i < t_params->count; i++) { - if (params->frequency > t_params->ranges[i].limit) - continue; - break; - } - if (i == t_params->count) { - tuner_dbg("TV frequency out of range (%d > %d)", - params->frequency, t_params->ranges[i - 1].limit); - params->frequency = t_params->ranges[--i].limit; - } - config = t_params->ranges[i].config; - cb = t_params->ranges[i].cb; - /* i == 0 -> VHF_LO - * i == 1 -> VHF_HI - * i == 2 -> UHF */ - tuner_dbg("tv: param %d, range %d\n", j, i); + i = simple_config_lookup(fe, t_params, ¶ms->frequency, + &config, &cb); div = params->frequency + IFPCoff + offset; -- cgit v1.2.3 From 6115a22c6160858176408cd0bc3622f46db6b012 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 27 Jan 2008 20:21:05 -0500 Subject: tuner-simple: display frequency in MHz From: Michael Krufky fix debug in simple_config_lookup to display frequency in MHz Signed-off-by: Michael Krufky --- linux/drivers/media/video/tuner-simple.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tuner-simple.c b/linux/drivers/media/video/tuner-simple.c index 0f657cb7c..a89dee2a7 100644 --- a/linux/drivers/media/video/tuner-simple.c +++ b/linux/drivers/media/video/tuner-simple.c @@ -255,8 +255,10 @@ static int simple_config_lookup(struct dvb_frontend *fe, *config = t_params->ranges[i].config; *cb = t_params->ranges[i].cb; - tuner_dbg("freq = %d, range = %d, config = 0x%02x, cb = 0x%02x\n", - *frequency, i, *config, *cb); + tuner_dbg("freq = %d.%02d (%d), range = %d, " + "config = 0x%02x, cb = 0x%02x\n", + *frequency / 16, *frequency % 16 * 100 / 16, *frequency, + i, *config, *cb); return i; } -- cgit v1.2.3 From cf7557e23cb16338cdbcfa4075ff34ebf2ba0ca5 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 27 Jan 2008 18:18:04 -0500 Subject: tuner: build tuner-types independently of tuner-core From: Michael Krufky tuner-types is needed for tuner-simple, and does not need to be bound to tuner-core. Any caller of tuner-simple, including tuner-core, needs to pass a structure from tuner-types into tuner-simple at attach-time. Export the two needed symbols from tuner-types for now, so that card-level drivers can attach tuner-simple for hybrid dvb_frontend devices. We will remove this dependency altogether as tuner refactoring phase 3 progresses. Signed-off-by: Michael Krufky --- linux/drivers/media/Kconfig | 5 +++++ linux/drivers/media/video/Makefile | 3 ++- linux/drivers/media/video/tuner-types.c | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/Kconfig b/linux/drivers/media/Kconfig index 8f4a45346..0bf2fb1fa 100644 --- a/linux/drivers/media/Kconfig +++ b/linux/drivers/media/Kconfig @@ -66,9 +66,13 @@ source "drivers/media/dvb/Kconfig" source "drivers/media/common/Kconfig" +config VIDEO_TUNER_TYPES + tristate + config VIDEO_TUNER tristate depends on I2C + select VIDEO_TUNER_TYPES select TUNER_XC2028 if !VIDEO_TUNER_CUSTOMIZE select TUNER_MT20XX if !VIDEO_TUNER_CUSTOMIZE select TUNER_TDA8290 if !VIDEO_TUNER_CUSTOMIZE @@ -131,6 +135,7 @@ config TUNER_TEA5767 config TUNER_SIMPLE tristate "Simple tuner support" depends on I2C + select VIDEO_TUNER_TYPES select TUNER_TDA9887 default m if VIDEO_TUNER_CUSTOMIZE help diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index 28ddd146c..e202d2a0c 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -4,7 +4,7 @@ zr36067-objs := zoran_procfs.o zoran_device.o \ zoran_driver.o zoran_card.o -tuner-objs := tuner-core.o tuner-types.o +tuner-objs := tuner-core.o msp3400-objs := msp3400-driver.o msp3400-kthreads.o @@ -84,6 +84,7 @@ obj-$(CONFIG_VIDEO_DPC) += dpc7146.o obj-$(CONFIG_TUNER_3036) += tuner-3036.o obj-$(CONFIG_VIDEO_TUNER) += tuner.o +obj-$(CONFIG_VIDEO_TUNER_TYPES) += tuner-types.o obj-$(CONFIG_TUNER_XC2028) += tuner-xc2028.o obj-$(CONFIG_TUNER_SIMPLE) += tuner-simple.o diff --git a/linux/drivers/media/video/tuner-types.c b/linux/drivers/media/video/tuner-types.c index 8b78a2140..2e93a9c57 100644 --- a/linux/drivers/media/video/tuner-types.c +++ b/linux/drivers/media/video/tuner-types.c @@ -1528,5 +1528,19 @@ struct tunertype tuners[] = { /* see xc5000.c for details */ }, }; +EXPORT_SYMBOL(tuners); unsigned const int tuner_count = ARRAY_SIZE(tuners); +EXPORT_SYMBOL(tuner_count); + +MODULE_DESCRIPTION("Simple tuner device type database"); +MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer"); +MODULE_LICENSE("GPL"); + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ -- cgit v1.2.3 From 5c7b0a4903598f353459c8f2101e7f0023d3e8af Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 28 Jan 2008 08:50:21 -0500 Subject: tuner: move tuner type ID check to simple_tuner_attach From: Michael Krufky Move tuner type ID check from tuner-core::set_type to simple_tuner_attach. Since tuner-core forwards all attach requests to tuner-simple as the default case, unless a specific attach function is specified in set_type, this change is an appropriate cleanup. Signed-off-by: Michael Krufky --- linux/drivers/media/video/tuner-core.c | 5 ----- linux/drivers/media/video/tuner-simple.c | 6 ++++++ 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tuner-core.c b/linux/drivers/media/video/tuner-core.c index 95bb41cee..c35528799 100644 --- a/linux/drivers/media/video/tuner-core.c +++ b/linux/drivers/media/video/tuner-core.c @@ -381,11 +381,6 @@ static void set_type(struct i2c_client *c, unsigned int type, return; } - if (type >= tuner_count) { - tuner_warn ("tuner 0x%02x: Tuner count greater than %d\n",c->addr,tuner_count); - return; - } - t->type = type; t->config = new_config; if (tuner_callback != NULL) { diff --git a/linux/drivers/media/video/tuner-simple.c b/linux/drivers/media/video/tuner-simple.c index a89dee2a7..cd3a3bae9 100644 --- a/linux/drivers/media/video/tuner-simple.c +++ b/linux/drivers/media/video/tuner-simple.c @@ -723,6 +723,12 @@ struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, { struct tuner_simple_priv *priv = NULL; + if (type >= tuner_count) { + printk(KERN_WARNING "%s: invalid tuner type: %d (max: %d)\n", + __FUNCTION__, type, tuner_count-1); + return NULL; + } + priv = kzalloc(sizeof(struct tuner_simple_priv), GFP_KERNEL); if (priv == NULL) return NULL; -- cgit v1.2.3 From 7883d9b792eee4d57e9c7e7f7df45ca17c8bfdab Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 29 Jan 2008 01:47:25 -0500 Subject: tuner: remove dependency of tuner-core on tuner-types From: Michael Krufky This patch fully removes the dependency of tuner-core on tuner-types. There is no longer any need to pass struct tunertype in attach-time config structure - instead pass the tuner type ID. Signed-off-by: Michael Krufky --- linux/drivers/media/video/tuner-core.c | 11 +++-------- linux/drivers/media/video/tuner-simple.c | 10 +++++----- linux/drivers/media/video/tuner-simple.h | 11 ++--------- 3 files changed, 10 insertions(+), 22 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tuner-core.c b/linux/drivers/media/video/tuner-core.c index c35528799..9fb321088 100644 --- a/linux/drivers/media/video/tuner-core.c +++ b/linux/drivers/media/video/tuner-core.c @@ -342,18 +342,13 @@ static void tuner_i2c_address_check(struct tuner *t) tuner_warn("output to v4l-dvb-maintainer@linuxtv.org\n"); tuner_warn("Please use subject line: \"obsolete tuner i2c address.\"\n"); tuner_warn("driver: %s, addr: 0x%02x, type: %d (%s)\n", - t->i2c->adapter->name, t->i2c->addr, t->type, - tuners[t->type].name); + t->i2c->adapter->name, t->i2c->addr, t->type, t->i2c->name); tuner_warn("====================== WARNING! ======================\n"); } -static void attach_simple_tuner(struct tuner *t) +static inline void attach_simple_tuner(struct tuner *t) { - struct simple_tuner_config cfg = { - .type = t->type, - .tun = &tuners[t->type] - }; - simple_tuner_attach(&t->fe, t->i2c->adapter, t->i2c->addr, &cfg); + simple_tuner_attach(&t->fe, t->i2c->adapter, t->i2c->addr, t->type); } static void attach_tda829x(struct tuner *t) diff --git a/linux/drivers/media/video/tuner-simple.c b/linux/drivers/media/video/tuner-simple.c index cd3a3bae9..c23407067 100644 --- a/linux/drivers/media/video/tuner-simple.c +++ b/linux/drivers/media/video/tuner-simple.c @@ -719,7 +719,7 @@ static struct dvb_tuner_ops simple_tuner_ops = { struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c_adap, u8 i2c_addr, - struct simple_tuner_config *cfg) + unsigned int type) { struct tuner_simple_priv *priv = NULL; @@ -736,15 +736,15 @@ struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, priv->i2c_props.addr = i2c_addr; priv->i2c_props.adap = i2c_adap; - priv->type = cfg->type; - priv->tun = cfg->tun; + priv->type = type; + priv->tun = &tuners[type]; memcpy(&fe->ops.tuner_ops, &simple_tuner_ops, sizeof(struct dvb_tuner_ops)); - tuner_info("type set to %d (%s)\n", cfg->type, cfg->tun->name); + tuner_info("type set to %d (%s)\n", priv->type, priv->tun->name); - strlcpy(fe->ops.tuner_ops.info.name, cfg->tun->name, + strlcpy(fe->ops.tuner_ops.info.name, priv->tun->name, sizeof(fe->ops.tuner_ops.info.name)); return fe; diff --git a/linux/drivers/media/video/tuner-simple.h b/linux/drivers/media/video/tuner-simple.h index 9089939a8..bf425f325 100644 --- a/linux/drivers/media/video/tuner-simple.h +++ b/linux/drivers/media/video/tuner-simple.h @@ -20,23 +20,16 @@ #include #include "dvb_frontend.h" -struct simple_tuner_config -{ - /* chip type */ - unsigned int type; - struct tunertype *tun; -}; - #if defined(CONFIG_TUNER_SIMPLE) || (defined(CONFIG_TUNER_SIMPLE_MODULE) && defined(MODULE)) extern struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c_adap, u8 i2c_addr, - struct simple_tuner_config *cfg); + unsigned int type); #else static inline struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c_adap, u8 i2c_addr, - struct simple_tuner_config *cfg) + unsigned int type) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); return NULL; -- cgit v1.2.3 From b8a8b11e41806fa8b84600f783ba8db358baf088 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 28 Jan 2008 08:55:06 -0500 Subject: tuner: properly handle failed calls to simple_tuner_attach From: Michael Krufky If simple_tuner_attach fails, set t->type to TUNER_ABSENT, set t->mode_mask to T_UNINITIALIZED, and exit the set_type function. Signed-off-by: Michael Krufky --- linux/drivers/media/video/tuner-core.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tuner-core.c b/linux/drivers/media/video/tuner-core.c index 9fb321088..2117254b7 100644 --- a/linux/drivers/media/video/tuner-core.c +++ b/linux/drivers/media/video/tuner-core.c @@ -346,11 +346,6 @@ static void tuner_i2c_address_check(struct tuner *t) tuner_warn("====================== WARNING! ======================\n"); } -static inline void attach_simple_tuner(struct tuner *t) -{ - simple_tuner_attach(&t->fe, t->i2c->adapter, t->i2c->addr, t->type); -} - static void attach_tda829x(struct tuner *t) { struct tda829x_config cfg = { @@ -428,7 +423,12 @@ static void set_type(struct i2c_client *c, unsigned int type, buffer[2] = 0x86; buffer[3] = 0x54; i2c_master_send(c, buffer, 4); - attach_simple_tuner(t); + if (simple_tuner_attach(&t->fe, t->i2c->adapter, t->i2c->addr, + t->type) == NULL) { + t->type = TUNER_ABSENT; + t->mode_mask = T_UNINITIALIZED; + return; + } break; case TUNER_PHILIPS_TD1316: buffer[0] = 0x0b; @@ -436,7 +436,12 @@ static void set_type(struct i2c_client *c, unsigned int type, buffer[2] = 0x86; buffer[3] = 0xa4; i2c_master_send(c,buffer,4); - attach_simple_tuner(t); + if (simple_tuner_attach(&t->fe, t->i2c->adapter, + t->i2c->addr, t->type) == NULL) { + t->type = TUNER_ABSENT; + t->mode_mask = T_UNINITIALIZED; + return; + } break; case TUNER_XC2028: { @@ -474,7 +479,12 @@ static void set_type(struct i2c_client *c, unsigned int type, } break; default: - attach_simple_tuner(t); + if (simple_tuner_attach(&t->fe, t->i2c->adapter, + t->i2c->addr, t->type) == NULL) { + t->type = TUNER_ABSENT; + t->mode_mask = T_UNINITIALIZED; + return; + } break; } -- cgit v1.2.3 From 3a2d80a72ac6da7718889e9ec3dd67688f61159e Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 26 Jan 2008 23:52:34 -0500 Subject: tuner-simple: move device-specific code into three separate functions From: Michael Krufky Move the switch..case blocks with device-specific code from functions simple_set_tv_freq and simple_set_radio_freq ...into three new functions: simple_std_setup, simple_post_tune and simple_radio_bandswitch Signed-off-by: Michael Krufky --- linux/drivers/media/video/tuner-simple.c | 351 +++++++++++++++++-------------- 1 file changed, 194 insertions(+), 157 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tuner-simple.c b/linux/drivers/media/video/tuner-simple.c index c23407067..5f4b2153e 100644 --- a/linux/drivers/media/video/tuner-simple.c +++ b/linux/drivers/media/video/tuner-simple.c @@ -265,59 +265,13 @@ static int simple_config_lookup(struct dvb_frontend *fe, /* ---------------------------------------------------------------------- */ -static int simple_set_tv_freq(struct dvb_frontend *fe, - struct analog_parameters *params) +static int simple_std_setup(struct dvb_frontend *fe, + struct analog_parameters *params, + u8 *buffer, u8 *config, u8 *cb) { struct tuner_simple_priv *priv = fe->tuner_priv; - u8 config, cb, tuneraddr; - u16 div; - struct tunertype *tun; - u8 buffer[4]; - int rc, IFPCoff, i; - enum param_type desired_type; - struct tuner_params *t_params; - - tun = priv->tun; - - /* IFPCoff = Video Intermediate Frequency - Vif: - 940 =16*58.75 NTSC/J (Japan) - 732 =16*45.75 M/N STD - 704 =16*44 ATSC (at DVB code) - 632 =16*39.50 I U.K. - 622.4=16*38.90 B/G D/K I, L STD - 592 =16*37.00 D China - 590 =16.36.875 B Australia - 543.2=16*33.95 L' STD - 171.2=16*10.70 FM Radio (at set_radio_freq) - */ - - if (params->std == V4L2_STD_NTSC_M_JP) { - IFPCoff = 940; - desired_type = TUNER_PARAM_TYPE_NTSC; - } else if ((params->std & V4L2_STD_MN) && - !(params->std & ~V4L2_STD_MN)) { - IFPCoff = 732; - desired_type = TUNER_PARAM_TYPE_NTSC; - } else if (params->std == V4L2_STD_SECAM_LC) { - IFPCoff = 543; - desired_type = TUNER_PARAM_TYPE_SECAM; - } else { - IFPCoff = 623; - desired_type = TUNER_PARAM_TYPE_PAL; - } - - t_params = simple_tuner_params(fe, desired_type); - - i = simple_config_lookup(fe, t_params, ¶ms->frequency, - &config, &cb); - - div = params->frequency + IFPCoff + offset; - - tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, " - "Offset=%d.%02d MHz, div=%0d\n", - params->frequency / 16, params->frequency % 16 * 100 / 16, - IFPCoff / 16, IFPCoff % 16 * 100 / 16, - offset / 16, offset % 16 * 100 / 16, div); + u8 tuneraddr; + int rc; /* tv norm specific stuff for multi-norm tuners */ switch (priv->type) { @@ -325,45 +279,45 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, /* 0x01 -> ??? no change ??? */ /* 0x02 -> PAL BDGHI / SECAM L */ /* 0x04 -> ??? PAL others / SECAM others ??? */ - cb &= ~0x03; + *cb &= ~0x03; if (params->std & V4L2_STD_SECAM_L) /* also valid for V4L2_STD_SECAM */ - cb |= PHILIPS_MF_SET_STD_L; + *cb |= PHILIPS_MF_SET_STD_L; else if (params->std & V4L2_STD_SECAM_LC) - cb |= PHILIPS_MF_SET_STD_LC; + *cb |= PHILIPS_MF_SET_STD_LC; else /* V4L2_STD_B|V4L2_STD_GH */ - cb |= PHILIPS_MF_SET_STD_BG; + *cb |= PHILIPS_MF_SET_STD_BG; break; case TUNER_TEMIC_4046FM5: - cb &= ~0x0f; + *cb &= ~0x0f; if (params->std & V4L2_STD_PAL_BG) { - cb |= TEMIC_SET_PAL_BG; + *cb |= TEMIC_SET_PAL_BG; } else if (params->std & V4L2_STD_PAL_I) { - cb |= TEMIC_SET_PAL_I; + *cb |= TEMIC_SET_PAL_I; } else if (params->std & V4L2_STD_PAL_DK) { - cb |= TEMIC_SET_PAL_DK; + *cb |= TEMIC_SET_PAL_DK; } else if (params->std & V4L2_STD_SECAM_L) { - cb |= TEMIC_SET_PAL_L; + *cb |= TEMIC_SET_PAL_L; } break; case TUNER_PHILIPS_FQ1216ME: - cb &= ~0x0f; + *cb &= ~0x0f; if (params->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) { - cb |= PHILIPS_SET_PAL_BGDK; + *cb |= PHILIPS_SET_PAL_BGDK; } else if (params->std & V4L2_STD_PAL_I) { - cb |= PHILIPS_SET_PAL_I; + *cb |= PHILIPS_SET_PAL_I; } else if (params->std & V4L2_STD_SECAM_L) { - cb |= PHILIPS_SET_PAL_L; + *cb |= PHILIPS_SET_PAL_L; } break; @@ -373,15 +327,15 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, /* 0x01 -> ATSC antenna input 2 */ /* 0x02 -> NTSC antenna input 1 */ /* 0x03 -> NTSC antenna input 2 */ - cb &= ~0x03; + *cb &= ~0x03; if (!(params->std & V4L2_STD_ATSC)) - cb |= 2; + *cb |= 2; /* FIXME: input */ break; case TUNER_MICROTUNE_4042FI5: /* Set the charge pump for fast tuning */ - config |= TUNER_CHARGE_PUMP; + *config |= TUNER_CHARGE_PUMP; break; case TUNER_PHILIPS_TUV1236D: @@ -393,9 +347,9 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, buffer[1] = 0x00; buffer[2] = 0x17; buffer[3] = 0x00; - cb &= ~0x40; + *cb &= ~0x40; if (params->std & V4L2_STD_ATSC) { - cb |= 0x40; + *cb |= 0x40; buffer[1] = 0x04; } /* set to the correct mode (analog or digital) */ @@ -414,68 +368,14 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, break; } - if (t_params->cb_first_if_lower_freq && div < priv->last_div) { - buffer[0] = config; - buffer[1] = cb; - buffer[2] = (div>>8) & 0x7f; - buffer[3] = div & 0xff; - } else { - buffer[0] = (div>>8) & 0x7f; - buffer[1] = div & 0xff; - buffer[2] = config; - buffer[3] = cb; - } - priv->last_div = div; - if (t_params->has_tda9887) { - struct v4l2_priv_tun_config tda9887_cfg; - int config = 0; - int is_secam_l = (params->std & (V4L2_STD_SECAM_L | - V4L2_STD_SECAM_LC)) && - !(params->std & ~(V4L2_STD_SECAM_L | - V4L2_STD_SECAM_LC)); - - tda9887_cfg.tuner = TUNER_TDA9887; - tda9887_cfg.priv = &config; - - if (params->std == V4L2_STD_SECAM_LC) { - if (t_params->port1_active ^ t_params->port1_invert_for_secam_lc) - config |= TDA9887_PORT1_ACTIVE; - if (t_params->port2_active ^ t_params->port2_invert_for_secam_lc) - config |= TDA9887_PORT2_ACTIVE; - } else { - if (t_params->port1_active) - config |= TDA9887_PORT1_ACTIVE; - if (t_params->port2_active) - config |= TDA9887_PORT2_ACTIVE; - } - if (t_params->intercarrier_mode) - config |= TDA9887_INTERCARRIER; - if (is_secam_l) { - if (i == 0 && t_params->default_top_secam_low) - config |= TDA9887_TOP(t_params->default_top_secam_low); - else if (i == 1 && t_params->default_top_secam_mid) - config |= TDA9887_TOP(t_params->default_top_secam_mid); - else if (t_params->default_top_secam_high) - config |= TDA9887_TOP(t_params->default_top_secam_high); - } else { - if (i == 0 && t_params->default_top_low) - config |= TDA9887_TOP(t_params->default_top_low); - else if (i == 1 && t_params->default_top_mid) - config |= TDA9887_TOP(t_params->default_top_mid); - else if (t_params->default_top_high) - config |= TDA9887_TOP(t_params->default_top_high); - } - if (t_params->default_pll_gating_18) - config |= TDA9887_GATING_18; - i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG, - &tda9887_cfg); - } - tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", - buffer[0], buffer[1], buffer[2], buffer[3]); + return 0; +} - rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4); - if (4 != rc) - tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc); +static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer, + u16 div, u8 config, u8 cb) +{ + struct tuner_simple_priv *priv = fe->tuner_priv; + int rc; switch (priv->type) { case TUNER_LG_TDVS_H06XF: @@ -542,6 +442,169 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, break; } } + + return 0; +} + +static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer) +{ + struct tuner_simple_priv *priv = fe->tuner_priv; + + switch (priv->type) { + case TUNER_TENA_9533_DI: + case TUNER_YMEC_TVF_5533MF: + tuner_dbg("This tuner doesn't have FM. " + "Most cards have a TEA5767 for FM\n"); + return 0; + case TUNER_PHILIPS_FM1216ME_MK3: + case TUNER_PHILIPS_FM1236_MK3: + case TUNER_PHILIPS_FMD1216ME_MK3: + case TUNER_LG_NTSC_TAPE: + case TUNER_PHILIPS_FM1256_IH3: + buffer[3] = 0x19; + break; + case TUNER_TNF_5335MF: + buffer[3] = 0x11; + break; + case TUNER_LG_PAL_FM: + buffer[3] = 0xa5; + break; + case TUNER_THOMSON_DTT761X: + buffer[3] = 0x39; + break; + case TUNER_MICROTUNE_4049FM5: + default: + buffer[3] = 0xa4; + break; + } + + return 0; +} + +/* ---------------------------------------------------------------------- */ + +static int simple_set_tv_freq(struct dvb_frontend *fe, + struct analog_parameters *params) +{ + struct tuner_simple_priv *priv = fe->tuner_priv; + u8 config, cb; + u16 div; + struct tunertype *tun; + u8 buffer[4]; + int rc, IFPCoff, i; + enum param_type desired_type; + struct tuner_params *t_params; + + tun = priv->tun; + + /* IFPCoff = Video Intermediate Frequency - Vif: + 940 =16*58.75 NTSC/J (Japan) + 732 =16*45.75 M/N STD + 704 =16*44 ATSC (at DVB code) + 632 =16*39.50 I U.K. + 622.4=16*38.90 B/G D/K I, L STD + 592 =16*37.00 D China + 590 =16.36.875 B Australia + 543.2=16*33.95 L' STD + 171.2=16*10.70 FM Radio (at set_radio_freq) + */ + + if (params->std == V4L2_STD_NTSC_M_JP) { + IFPCoff = 940; + desired_type = TUNER_PARAM_TYPE_NTSC; + } else if ((params->std & V4L2_STD_MN) && + !(params->std & ~V4L2_STD_MN)) { + IFPCoff = 732; + desired_type = TUNER_PARAM_TYPE_NTSC; + } else if (params->std == V4L2_STD_SECAM_LC) { + IFPCoff = 543; + desired_type = TUNER_PARAM_TYPE_SECAM; + } else { + IFPCoff = 623; + desired_type = TUNER_PARAM_TYPE_PAL; + } + + t_params = simple_tuner_params(fe, desired_type); + + i = simple_config_lookup(fe, t_params, ¶ms->frequency, + &config, &cb); + + div = params->frequency + IFPCoff + offset; + + tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, " + "Offset=%d.%02d MHz, div=%0d\n", + params->frequency / 16, params->frequency % 16 * 100 / 16, + IFPCoff / 16, IFPCoff % 16 * 100 / 16, + offset / 16, offset % 16 * 100 / 16, div); + + /* tv norm specific stuff for multi-norm tuners */ + simple_std_setup(fe, params, &buffer[1], &config, &cb); + + if (t_params->cb_first_if_lower_freq && div < priv->last_div) { + buffer[0] = config; + buffer[1] = cb; + buffer[2] = (div>>8) & 0x7f; + buffer[3] = div & 0xff; + } else { + buffer[0] = (div>>8) & 0x7f; + buffer[1] = div & 0xff; + buffer[2] = config; + buffer[3] = cb; + } + priv->last_div = div; + if (t_params->has_tda9887) { + struct v4l2_priv_tun_config tda9887_cfg; + int config = 0; + int is_secam_l = (params->std & (V4L2_STD_SECAM_L | + V4L2_STD_SECAM_LC)) && + !(params->std & ~(V4L2_STD_SECAM_L | + V4L2_STD_SECAM_LC)); + + tda9887_cfg.tuner = TUNER_TDA9887; + tda9887_cfg.priv = &config; + + if (params->std == V4L2_STD_SECAM_LC) { + if (t_params->port1_active ^ t_params->port1_invert_for_secam_lc) + config |= TDA9887_PORT1_ACTIVE; + if (t_params->port2_active ^ t_params->port2_invert_for_secam_lc) + config |= TDA9887_PORT2_ACTIVE; + } else { + if (t_params->port1_active) + config |= TDA9887_PORT1_ACTIVE; + if (t_params->port2_active) + config |= TDA9887_PORT2_ACTIVE; + } + if (t_params->intercarrier_mode) + config |= TDA9887_INTERCARRIER; + if (is_secam_l) { + if (i == 0 && t_params->default_top_secam_low) + config |= TDA9887_TOP(t_params->default_top_secam_low); + else if (i == 1 && t_params->default_top_secam_mid) + config |= TDA9887_TOP(t_params->default_top_secam_mid); + else if (t_params->default_top_secam_high) + config |= TDA9887_TOP(t_params->default_top_secam_high); + } else { + if (i == 0 && t_params->default_top_low) + config |= TDA9887_TOP(t_params->default_top_low); + else if (i == 1 && t_params->default_top_mid) + config |= TDA9887_TOP(t_params->default_top_mid); + else if (t_params->default_top_high) + config |= TDA9887_TOP(t_params->default_top_high); + } + if (t_params->default_pll_gating_18) + config |= TDA9887_GATING_18; + i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG, + &tda9887_cfg); + } + tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", + buffer[0], buffer[1], buffer[2], buffer[3]); + + rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4); + if (4 != rc) + tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc); + + simple_post_tune(fe, &buffer[0], div, config, cb); + return 0; } @@ -582,33 +645,7 @@ static int simple_set_radio_freq(struct dvb_frontend *fe, } /* Bandswitch byte */ - switch (priv->type) { - case TUNER_TENA_9533_DI: - case TUNER_YMEC_TVF_5533MF: - tuner_dbg("This tuner doesn't have FM. " - "Most cards have a TEA5767 for FM\n"); - return 0; - case TUNER_PHILIPS_FM1216ME_MK3: - case TUNER_PHILIPS_FM1236_MK3: - case TUNER_PHILIPS_FMD1216ME_MK3: - case TUNER_LG_NTSC_TAPE: - case TUNER_PHILIPS_FM1256_IH3: - buffer[3] = 0x19; - break; - case TUNER_TNF_5335MF: - buffer[3] = 0x11; - break; - case TUNER_LG_PAL_FM: - buffer[3] = 0xa5; - break; - case TUNER_THOMSON_DTT761X: - buffer[3] = 0x39; - break; - case TUNER_MICROTUNE_4049FM5: - default: - buffer[3] = 0xa4; - break; - } + simple_radio_bandswitch(fe, &buffer[0]); buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */ -- cgit v1.2.3 From cd341029cc227e8d819e700bd693e172ab1b525c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jan 2008 12:24:58 +0000 Subject: V4L: stkwebcam: Add support for YUYV format From: Jaime Velasco Juan Signed-off-by: Jaime Velasco Juan Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/stk-sensor.c | 19 ++++++++++++++++++- linux/drivers/media/video/stk-webcam.c | 7 ++++++- 2 files changed, 24 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/stk-sensor.c b/linux/drivers/media/video/stk-sensor.c index 4a9a0b62e..1a8692d9e 100644 --- a/linux/drivers/media/video/stk-sensor.c +++ b/linux/drivers/media/video/stk-sensor.c @@ -380,7 +380,7 @@ int stk_sensor_init(struct stk_camera *dev) STK_ERROR("Strange error reading sensor ID\n"); return -ENODEV; } - if (idh != 0x7F || idl != 0xA2) { + if (idh != 0x7f || idl != 0xa2) { STK_ERROR("Huh? you don't have a sensor from ovt\n"); return -ENODEV; } @@ -409,6 +409,19 @@ static struct regval ov_fmt_uyvy[] = { {REG_COM15, COM15_R00FF }, {0xff, 0xff}, /* END MARKER */ }; +/* V4L2_PIX_FMT_YUYV */ +static struct regval ov_fmt_yuyv[] = { + {REG_TSLB, 0 }, + { 0x4f, 0x80 }, /* "matrix coefficient 1" */ + { 0x50, 0x80 }, /* "matrix coefficient 2" */ + { 0x51, 0 }, /* vb */ + { 0x52, 0x22 }, /* "matrix coefficient 4" */ + { 0x53, 0x5e }, /* "matrix coefficient 5" */ + { 0x54, 0x80 }, /* "matrix coefficient 6" */ + {REG_COM13, COM13_UVSAT|COM13_CMATRIX}, + {REG_COM15, COM15_R00FF }, + {0xff, 0xff}, /* END MARKER */ +}; /* V4L2_PIX_FMT_RGB565X rrrrrggg gggbbbbb */ static struct regval ov_fmt_rgbr[] = { @@ -519,6 +532,10 @@ int stk_sensor_configure(struct stk_camera *dev) com7 |= COM7_YUV; rv = ov_fmt_uyvy; break; + case V4L2_PIX_FMT_YUYV: + com7 |= COM7_YUV; + rv = ov_fmt_yuyv; + break; case V4L2_PIX_FMT_RGB565: com7 |= COM7_RGB; rv = ov_fmt_rgbp; diff --git a/linux/drivers/media/video/stk-webcam.c b/linux/drivers/media/video/stk-webcam.c index 8621df261..e40f9a9d3 100644 --- a/linux/drivers/media/video/stk-webcam.c +++ b/linux/drivers/media/video/stk-webcam.c @@ -994,6 +994,10 @@ static int stk_vidioc_enum_fmt_cap(struct file *filp, fmtd->pixelformat = V4L2_PIX_FMT_SBGGR8; strcpy(fmtd->description, "Raw bayer"); break; + case 4: + fmtd->pixelformat = V4L2_PIX_FMT_YUYV; + strcpy(fmtd->description, "yuv4:2:2"); + break; default: return -EINVAL; } @@ -1049,6 +1053,7 @@ static int stk_vidioc_try_fmt_cap(struct file *filp, case V4L2_PIX_FMT_RGB565: case V4L2_PIX_FMT_RGB565X: case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_SBGGR8: break; default: @@ -1404,7 +1409,7 @@ static int stk_camera_probe(struct usb_interface *interface, dev->vsettings.brightness = 0x7fff; dev->vsettings.palette = V4L2_PIX_FMT_RGB565; dev->vsettings.mode = MODE_VGA; - dev->frame_size = 640*480*2; + dev->frame_size = 640 * 480 * 2; INIT_LIST_HEAD(&dev->sio_avail); INIT_LIST_HEAD(&dev->sio_full); -- cgit v1.2.3 From 861e732942c7f0f5b943d9903e60dabc7688afaa Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jan 2008 12:24:59 +0000 Subject: V4L: stkwebcam: Power management support From: Jaime Velasco Juan Signed-off-by: Jaime Velasco Juan Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/stk-webcam.c | 92 ++++++++++++++++++++++++++-------- linux/drivers/media/video/stk-webcam.h | 1 + 2 files changed, 73 insertions(+), 20 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/stk-webcam.c b/linux/drivers/media/video/stk-webcam.c index e40f9a9d3..551eafa6d 100644 --- a/linux/drivers/media/video/stk-webcam.c +++ b/linux/drivers/media/video/stk-webcam.c @@ -683,6 +683,7 @@ static int v4l_stk_open(struct inode *inode, struct file *fp) return -ENXIO; fp->private_data = vdev; kref_get(&dev->kref); + usb_autopm_get_interface(dev->interface); return 0; } @@ -704,6 +705,7 @@ static int v4l_stk_release(struct inode *inode, struct file *fp) } if (dev->owner != fp) { + usb_autopm_put_interface(dev->interface); kref_put(&dev->kref, stk_camera_cleanup); return 0; } @@ -714,6 +716,7 @@ static int v4l_stk_release(struct inode *inode, struct file *fp) dev->owner = NULL; + usb_autopm_put_interface(dev->interface); kref_put(&dev->kref, stk_camera_cleanup); return 0; @@ -1086,6 +1089,42 @@ static int stk_vidioc_try_fmt_cap(struct file *filp, return 0; } +static int stk_setup_format(struct stk_camera *dev) +{ + int i = 0; + int depth; + if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8) + depth = 1; + else + depth = 2; + while (stk_sizes[i].m != dev->vsettings.mode + && i < ARRAY_SIZE(stk_sizes)) + i++; + if (i == ARRAY_SIZE(stk_sizes)) { + STK_ERROR("Something is broken in %s\n", __FUNCTION__); + return -EFAULT; + } + /* This registers controls some timings, not sure of what. */ + stk_camera_write_reg(dev, 0x001b, 0x0e); + if (dev->vsettings.mode == MODE_SXGA) + stk_camera_write_reg(dev, 0x001c, 0x0e); + else + stk_camera_write_reg(dev, 0x001c, 0x46); + /* + * Registers 0x0115 0x0114 are the size of each line (bytes), + * regs 0x0117 0x0116 are the heigth of the image. + */ + stk_camera_write_reg(dev, 0x0115, + ((stk_sizes[i].w * depth) >> 8) & 0xff); + stk_camera_write_reg(dev, 0x0114, + (stk_sizes[i].w * depth) & 0xff); + stk_camera_write_reg(dev, 0x0117, + (stk_sizes[i].h >> 8) & 0xff); + stk_camera_write_reg(dev, 0x0116, + stk_sizes[i].h & 0xff); + return stk_sensor_configure(dev); +} + static int stk_vidioc_s_fmt_cap(struct file *filp, void *priv, struct v4l2_format *fmtd) { @@ -1100,10 +1139,10 @@ static int stk_vidioc_s_fmt_cap(struct file *filp, return -EBUSY; if (dev->owner && dev->owner != filp) return -EBUSY; - dev->owner = filp; ret = stk_vidioc_try_fmt_cap(filp, priv, fmtd); if (ret) return ret; + dev->owner = filp; dev->vsettings.palette = fmtd->fmt.pix.pixelformat; stk_free_buffers(dev); @@ -1111,25 +1150,7 @@ static int stk_vidioc_s_fmt_cap(struct file *filp, dev->vsettings.mode = stk_sizes[fmtd->fmt.pix.priv].m; stk_initialise(dev); - /* This registers controls some timings, not sure of what. */ - stk_camera_write_reg(dev, 0x001b, 0x0e); - if (dev->vsettings.mode == MODE_SXGA) - stk_camera_write_reg(dev, 0x001c, 0x0e); - else - stk_camera_write_reg(dev, 0x001c, 0x46); - /* - * Registers 0x0115 0x0114 are the size of each line (bytes), - * regs 0x0117 0x0116 are the heigth of the image. - */ - stk_camera_write_reg(dev, 0x0115, - (fmtd->fmt.pix.bytesperline >> 8) & 0xff); - stk_camera_write_reg(dev, 0x0114, - fmtd->fmt.pix.bytesperline & 0xff); - stk_camera_write_reg(dev, 0x0117, - (fmtd->fmt.pix.height >> 8) & 0xff); - stk_camera_write_reg(dev, 0x0116, - fmtd->fmt.pix.height & 0xff); - return stk_sensor_configure(dev); + return stk_setup_format(dev); } static int stk_vidioc_reqbufs(struct file *filp, @@ -1423,6 +1444,7 @@ static int stk_camera_probe(struct usb_interface *interface, } stk_create_sysfs_files(&dev->vdev); + usb_autopm_enable(dev->interface); return 0; } @@ -1440,11 +1462,41 @@ static void stk_camera_disconnect(struct usb_interface *interface) kref_put(&dev->kref, stk_camera_cleanup); } +#ifdef CONFIG_PM +int stk_camera_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct stk_camera *dev = usb_get_intfdata(intf); + if (is_streaming(dev)) { + stk_stop_stream(dev); + /* yes, this is ugly */ + set_streaming(dev); + } + return 0; +} + +int stk_camera_resume(struct usb_interface *intf) +{ + struct stk_camera *dev = usb_get_intfdata(intf); + if (!is_initialised(dev)) + return 0; + unset_initialised(dev); + stk_initialise(dev); + stk_setup_format(dev); + if (is_streaming(dev)) + stk_start_stream(dev); + return 0; +} +#endif + static struct usb_driver stk_camera_driver = { .name = "stkwebcam", .probe = stk_camera_probe, .disconnect = stk_camera_disconnect, .id_table = stkwebcam_table, +#ifdef CONFIG_PM + .suspend = stk_camera_suspend, + .resume = stk_camera_resume, +#endif }; diff --git a/linux/drivers/media/video/stk-webcam.h b/linux/drivers/media/video/stk-webcam.h index 7e989d1ac..a2164cb1a 100644 --- a/linux/drivers/media/video/stk-webcam.h +++ b/linux/drivers/media/video/stk-webcam.h @@ -79,6 +79,7 @@ enum stk_status { #define unset_present(dev) ((dev)->status &= \ ~(S_PRESENT|S_INITIALISED|S_STREAMING)) #define set_initialised(dev) ((dev)->status |= S_INITIALISED) +#define unset_initialised(dev) ((dev)->status &= ~S_INITIALISED) #define set_memallocd(dev) ((dev)->status |= S_MEMALLOCD) #define unset_memallocd(dev) ((dev)->status &= ~S_MEMALLOCD) #define set_streaming(dev) ((dev)->status |= S_STREAMING) -- cgit v1.2.3 From f29bf2a24e9a67b1b6235c1de88a752f4b5e7994 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jan 2008 12:25:00 +0000 Subject: V4L: stkwebcam: use v4l_compat_ioctl32 From: Jaime Velasco Juan Signed-off-by: Jaime Velasco Juan Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/stk-webcam.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/stk-webcam.c b/linux/drivers/media/video/stk-webcam.c index 551eafa6d..1c64afe71 100644 --- a/linux/drivers/media/video/stk-webcam.c +++ b/linux/drivers/media/video/stk-webcam.c @@ -1315,6 +1315,9 @@ static struct file_operations v4l_stk_fops = { .poll = v4l_stk_poll, .mmap = v4l_stk_mmap, .ioctl = video_ioctl2, +#ifdef CONFIG_COMPAT + .compat_ioctl = v4l_compat_ioctl32, +#endif .llseek = no_llseek }; -- cgit v1.2.3 From 74760b07c965cf47b191f72af5c534e01945f4af Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 27 Jan 2008 12:29:51 -0200 Subject: Fix bugzilla 9699 From: Douglas Schilling Landgraf Changed request_region() validation to avoid crash. Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/radio/radio-sf16fmr2.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-sf16fmr2.c b/linux/drivers/media/radio/radio-sf16fmr2.c index a61076fb2..ef5366099 100644 --- a/linux/drivers/media/radio/radio-sf16fmr2.c +++ b/linux/drivers/media/radio/radio-sf16fmr2.c @@ -475,9 +475,8 @@ static int __init fmr2_init(void) mutex_init(&lock); - if (request_region(io, 2, "sf16fmr2")) - { - printk(KERN_ERR "fmr2: port 0x%x already in use\n", io); + if (!request_region(io, 2, "sf16fmr2")) { + printk(KERN_ERR "radio-sf16fmr2: request_region failed!\n"); return -EBUSY; } -- cgit v1.2.3 From ff1fe4613740e792a39664c6fc8d05876dfef864 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 27 Jan 2008 12:43:20 -0200 Subject: Fix bugzilla 9699 From: Mauro Carvalho Chehab isapnp_fmi_probe attaches device. However, if request_region() fails, the device isn't disattached. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/radio/radio-sf16fmi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-sf16fmi.c b/linux/drivers/media/radio/radio-sf16fmi.c index e56129415..b56c2db8f 100644 --- a/linux/drivers/media/radio/radio-sf16fmi.c +++ b/linux/drivers/media/radio/radio-sf16fmi.c @@ -368,6 +368,7 @@ static int __init fmi_init(void) } if (!request_region(io, 2, "radio-sf16fmi")) { printk(KERN_ERR "radio-sf16fmi: port 0x%x already in use\n", io); + pnp_device_detach(dev); return -EBUSY; } -- cgit v1.2.3 From 0b14b001f4b716b7d53a1413de30bbdb70764651 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jan 2008 14:54:07 +0000 Subject: radio-si470x improvements and seldom problem fixed in tuning functions From: Tobias Lorenz I updated the radio-si470x driver another time. Here are the commented history entries: - number of seek_retries changed to tune_timeout The last versions checked for the end of frequency tuning by polling a si470x register. Therefore polling depended on the usb utilization. This was changed to have a constant timeout now. - fixed problem with incomplete tune operations by own buffers The last version used a shared buffer to assembly the USB HID reports. It sometimes happened, that multiple functions were modifing this buffer simultanuously. When sending such reports, the hardware returned USB stalls (-EPIPE). Now buffers of the correct size (smaller than before) are allocated as local variables. - optimization of variables The size of some variables has been reduced to allow the compiler to generate more optimized code. - improved error logging At some important location, error checking was improved. Especially the usb transfers to access si470x registers and the tuning functions were modified. Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/radio-si470x.c | 223 ++++++++++++++++++++----------- 1 file changed, 143 insertions(+), 80 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index c5a764b7b..ed64929dc 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -62,6 +62,12 @@ * - code cleaned of unnecessary rds_commands * - USB Vendor/Product ID for ADS/Tech FM Radio Receiver verified * (thanks to Guillaume RAMOUSSE) + * 2008-01-27 Tobias Lorenz + * Version 1.0.5 + * - number of seek_retries changed to tune_timeout + * - fixed problem with incomplete tune operations by own buffers + * - optimization of variables + * - improved error logging * * ToDo: * - add seeking support @@ -74,9 +80,10 @@ /* driver definitions */ #define DRIVER_AUTHOR "Tobias Lorenz " #define DRIVER_NAME "radio-si470x" -#define DRIVER_VERSION KERNEL_VERSION(1, 0, 4) +#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 5) #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.5" /* kernel includes */ @@ -120,56 +127,56 @@ MODULE_PARM_DESC(radio_nr, "Radio Nr"); /* 0: 200 kHz (USA, Australia) */ /* 1: 100 kHz (Europe, Japan) */ /* 2: 50 kHz */ -static int space = 2; -module_param(space, int, 0); +static unsigned short space = 2; +module_param(space, ushort, 0); MODULE_PARM_DESC(radio_nr, "Spacing: 0=200kHz 1=100kHz *2=50kHz*"); /* Bottom of Band (MHz) */ /* 0: 87.5 - 108 MHz (USA, Europe)*/ /* 1: 76 - 108 MHz (Japan wide band) */ /* 2: 76 - 90 MHz (Japan) */ -static int band = 1; -module_param(band, int, 0); +static unsigned short band = 1; +module_param(band, ushort, 0); MODULE_PARM_DESC(radio_nr, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz"); /* De-emphasis */ /* 0: 75 us (USA) */ /* 1: 50 us (Europe, Australia, Japan) */ -static int de = 1; -module_param(de, int, 0); +static unsigned short de = 1; +module_param(de, ushort, 0); MODULE_PARM_DESC(radio_nr, "De-emphasis: 0=75us *1=50us*"); /* USB timeout */ -static int usb_timeout = 500; -module_param(usb_timeout, int, 0); +static unsigned int usb_timeout = 500; +module_param(usb_timeout, uint, 0); MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*"); -/* Seek retries */ -static int seek_retries = 100; -module_param(seek_retries, int, 0); -MODULE_PARM_DESC(seek_retries, "Seek retries: *100*"); +/* Tune timeout */ +static unsigned int tune_timeout = 3000; +module_param(tune_timeout, uint, 0); +MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*"); /* RDS buffer blocks */ -static int rds_buf = 100; -module_param(rds_buf, int, 0); +static unsigned int rds_buf = 100; +module_param(rds_buf, uint, 0); MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*"); /* RDS maximum block errors */ -static int max_rds_errors = 1; +static unsigned short max_rds_errors = 1; /* 0 means 0 errors requiring correction */ /* 1 means 1-2 errors requiring correction (used by original USBRadio.exe) */ /* 2 means 3-5 errors requiring correction */ /* 3 means 6+ errors or errors in checkword, correction not possible */ -module_param(max_rds_errors, int, 0); +module_param(max_rds_errors, ushort, 0); MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*"); /* RDS poll frequency */ -static int rds_poll_time = 40; +static unsigned int rds_poll_time = 40; /* 40 is used by the original USBRadio.exe */ /* 50 is used by radio-cadet */ /* 75 should be okay */ /* 80 is the usual RDS receive interval */ -module_param(rds_poll_time, int, 0); +module_param(rds_poll_time, uint, 0); MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); @@ -396,11 +403,8 @@ struct si470x_device { struct usb_device *usbdev; struct video_device *videodev; - /* are these really necessary ? */ - int users; - - /* report buffer (maximum 64 bytes) */ - unsigned char buf[64]; + /* driver management */ + unsigned int users; /* Silabs internal registers (0..15) */ unsigned short registers[RADIO_REGISTER_NUM]; @@ -435,28 +439,46 @@ struct si470x_device { /* * si470x_get_report - receive a HID report */ -static int si470x_get_report(struct si470x_device *radio, int size) +static int si470x_get_report(struct si470x_device *radio, void *buf, int size) { - return usb_control_msg(radio->usbdev, + unsigned char *report = (unsigned char *) buf; + int retval; + + retval = usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), HID_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, - radio->buf[0], 2, - radio->buf, size, usb_timeout); + report[0], 2, + buf, size, usb_timeout); + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": si470x_get_report: usb_control_msg returned %d\n", + retval); + + return retval; } /* * si470x_set_report - send a HID report */ -static int si470x_set_report(struct si470x_device *radio, int size) +static int si470x_set_report(struct si470x_device *radio, void *buf, int size) { - return usb_control_msg(radio->usbdev, + unsigned char *report = (unsigned char *) buf; + int retval; + + retval = usb_control_msg(radio->usbdev, usb_sndctrlpipe(radio->usbdev, 0), HID_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, - radio->buf[0], 2, - radio->buf, size, usb_timeout); + report[0], 2, + buf, size, usb_timeout); + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": si470x_set_report: usb_control_msg returned %d\n", + retval); + + return retval; } @@ -465,13 +487,15 @@ static int si470x_set_report(struct si470x_device *radio, int size) */ static int si470x_get_register(struct si470x_device *radio, int regnr) { + unsigned char buf[REGISTER_REPORT_SIZE]; int retval; - radio->buf[0] = REGISTER_REPORT(regnr); + buf[0] = REGISTER_REPORT(regnr); + + retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); - retval = si470x_get_report(radio, REGISTER_REPORT_SIZE); if (retval >= 0) - radio->registers[regnr] = (radio->buf[1] << 8) | radio->buf[2]; + radio->registers[regnr] = (buf[1] << 8) | buf[2]; return (retval < 0) ? -EINVAL : 0; } @@ -482,13 +506,14 @@ static int si470x_get_register(struct si470x_device *radio, int regnr) */ static int si470x_set_register(struct si470x_device *radio, int regnr) { + unsigned char buf[REGISTER_REPORT_SIZE]; int retval; - radio->buf[0] = REGISTER_REPORT(regnr); - radio->buf[1] = (radio->registers[regnr] & 0xff00) >> 8; - radio->buf[2] = (radio->registers[regnr] & 0x00ff); + buf[0] = REGISTER_REPORT(regnr); + buf[1] = (radio->registers[regnr] & 0xff00) >> 8; + buf[2] = (radio->registers[regnr] & 0x00ff); - retval = si470x_set_report(radio, REGISTER_REPORT_SIZE); + retval = si470x_set_report(radio, (void *) &buf, sizeof(buf)); return (retval < 0) ? -EINVAL : 0; } @@ -499,18 +524,19 @@ static int si470x_set_register(struct si470x_device *radio, int regnr) */ static int si470x_get_all_registers(struct si470x_device *radio) { + unsigned char buf[ENTIRE_REPORT_SIZE]; int retval; - int regnr; + unsigned char regnr; - radio->buf[0] = ENTIRE_REPORT; + buf[0] = ENTIRE_REPORT; - retval = si470x_get_report(radio, ENTIRE_REPORT_SIZE); + retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); if (retval >= 0) for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++) radio->registers[regnr] = - (radio->buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) | - radio->buf[regnr * RADIO_REGISTER_SIZE + 2]; + (buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) | + buf[regnr * RADIO_REGISTER_SIZE + 2]; return (retval < 0) ? -EINVAL : 0; } @@ -521,21 +547,28 @@ static int si470x_get_all_registers(struct si470x_device *radio) */ static int si470x_get_rds_registers(struct si470x_device *radio) { + unsigned char buf[RDS_REPORT_SIZE]; int retval; - int regnr; int size; + unsigned char regnr; - radio->buf[0] = RDS_REPORT; + buf[0] = RDS_REPORT; retval = usb_interrupt_msg(radio->usbdev, - usb_rcvctrlpipe(radio->usbdev, 1), - radio->buf, RDS_REPORT_SIZE, &size, usb_timeout); + usb_rcvintpipe(radio->usbdev, 1), + (void *) &buf, sizeof(buf), &size, usb_timeout); + if (size != sizeof(buf)) + printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_register: " + "return size differs: %d != %d\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] = - (radio->buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) | - radio->buf[regnr * RADIO_REGISTER_SIZE + 2]; + (buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) | + buf[regnr * RADIO_REGISTER_SIZE + 2]; return (retval < 0) ? -EINVAL : 0; } @@ -544,9 +577,11 @@ static int si470x_get_rds_registers(struct si470x_device *radio) /* * si470x_set_chan - set the channel */ -static int si470x_set_chan(struct si470x_device *radio, int chan) +static int si470x_set_chan(struct si470x_device *radio, unsigned short chan) { - int retval, i; + int retval; + unsigned long timeout; + bool timed_out = 0; /* start tuning */ radio->registers[CHANNEL] &= ~CHANNEL_CHAN; @@ -556,16 +591,17 @@ static int si470x_set_chan(struct si470x_device *radio, int chan) return retval; /* wait till seek operation has completed */ - i = 0; + timeout = jiffies + msecs_to_jiffies(tune_timeout); do { retval = si470x_get_register(radio, STATUSRSSI); if (retval < 0) return retval; - } while ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) && - (++i < seek_retries)); - if (i >= seek_retries) + timed_out = time_after(jiffies, timeout); + } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) && + (!timed_out)); + if (timed_out) printk(KERN_WARNING DRIVER_NAME - ": seek does not finish after %d tries\n", i); + ": seek does not finish after %d ms\n", tune_timeout); /* stop tuning */ radio->registers[CHANNEL] &= ~CHANNEL_TUNE; @@ -576,9 +612,10 @@ static int si470x_set_chan(struct si470x_device *radio, int chan) /* * si470x_get_freq - get the frequency */ -static int si470x_get_freq(struct si470x_device *radio) +static unsigned int si470x_get_freq(struct si470x_device *radio) { - int spacing, band_bottom, chan, freq; + unsigned int spacing, band_bottom, freq; + unsigned short chan; int retval; /* Spacing (kHz) */ @@ -617,9 +654,10 @@ static int si470x_get_freq(struct si470x_device *radio) /* * si470x_set_freq - set the frequency */ -static int si470x_set_freq(struct si470x_device *radio, int freq) +static int si470x_set_freq(struct si470x_device *radio, unsigned int freq) { - int spacing, band_bottom, chan; + unsigned int spacing, band_bottom; + unsigned short chan; /* Spacing (kHz) */ switch (space) { @@ -726,12 +764,6 @@ static int si470x_rds_on(struct si470x_device *radio) */ static void si470x_rds(struct si470x_device *radio) { - unsigned char tmpbuf[3]; - unsigned char blocknum; - unsigned char bler; /* rds block errors */ - unsigned short rds; - unsigned int i; - /* get rds blocks */ if (si470x_get_rds_registers(radio) < 0) return; @@ -746,6 +778,12 @@ static void si470x_rds(struct si470x_device *radio) /* copy four RDS blocks to internal buffer */ if (spin_trylock(&radio->lock)) { + unsigned char blocknum; + unsigned short bler; /* rds block errors */ + unsigned short rds; + unsigned char tmpbuf[3]; + unsigned char i; + /* process each rds block */ for (blocknum = 0; blocknum < 4; blocknum++) { switch (blocknum) { @@ -848,7 +886,6 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf, { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval = 0; - unsigned int block_count = 0; /* switch on rds reception */ if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) { @@ -868,6 +905,7 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf, /* copy RDS block out of internal buffer and to user buffer */ if (spin_trylock(&radio->lock)) { + unsigned int block_count = 0; while (block_count < count) { if (radio->rd_index == radio->wr_index) break; @@ -1031,7 +1069,7 @@ static int si470x_vidioc_querycap(struct file *file, void *priv, strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver)); strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); sprintf(capability->bus_info, "USB"); - capability->version = DRIVER_VERSION; + capability->version = DRIVER_KERNEL_VERSION; capability->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; return 0; @@ -1068,16 +1106,21 @@ static int si470x_vidioc_s_input(struct file *filp, void *priv, unsigned int i) static int si470x_vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qc) { - int i; + unsigned char i; + int retval = -EINVAL; for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) { if (qc->id && qc->id == si470x_v4l2_queryctrl[i].id) { memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc)); - return 0; + retval = 0; + break; } } + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": query control failed with %d\n", retval); - return -EINVAL; + return retval; } @@ -1111,21 +1154,29 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); + int retval; switch (ctrl->id) { case V4L2_CID_AUDIO_VOLUME: radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME; radio->registers[SYSCONFIG2] |= ctrl->value; - return si470x_set_register(radio, SYSCONFIG2); + retval = si470x_set_register(radio, SYSCONFIG2); + break; case V4L2_CID_AUDIO_MUTE: if (ctrl->value == 1) radio->registers[POWERCFG] &= ~POWERCFG_DMUTE; else radio->registers[POWERCFG] |= POWERCFG_DMUTE; - return si470x_set_register(radio, POWERCFG); + retval = si470x_set_register(radio, POWERCFG); + break; + default: + retval = -EINVAL; } + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": set control failed with %d\n", retval); - return -EINVAL; + return retval; } @@ -1164,8 +1215,8 @@ static int si470x_vidioc_s_audio(struct file *file, void *priv, static int si470x_vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *tuner) { - int retval; struct si470x_device *radio = video_get_drvdata(video_devdata(file)); + int retval; if (tuner->index > 0) return -EINVAL; @@ -1221,6 +1272,7 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *tuner) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); + int retval; if (tuner->index > 0) return -EINVAL; @@ -1230,7 +1282,12 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv, else radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */ - return si470x_set_register(radio, POWERCFG); + retval = si470x_set_register(radio, POWERCFG); + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": set tuner failed with %d\n", retval); + + return retval; } @@ -1256,11 +1313,17 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *freq) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); + int retval; if (freq->type != V4L2_TUNER_RADIO) return -EINVAL; - return si470x_set_freq(radio, freq->frequency); + retval = si470x_set_freq(radio, freq->frequency); + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": set frequency failed with %d\n", retval); + + return 0; } @@ -1410,7 +1473,7 @@ static struct usb_driver si470x_usb_driver = { */ static int __init si470x_module_init(void) { - printk(KERN_INFO DRIVER_DESC "\n"); + printk(KERN_INFO DRIVER_DESC ", Version " DRIVER_VERSION "\n"); return usb_register(&si470x_usb_driver); } @@ -1430,4 +1493,4 @@ module_exit(si470x_module_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION("1.0.4"); +MODULE_VERSION(DRIVER_VERSION); -- cgit v1.2.3 From 56ab5d5a038d60cd901d04a60c56f4a9e0631c00 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 27 Jan 2008 13:10:44 -0200 Subject: [PATCH] static memory From: Douglas Schilling Landgraf - Static memory is always initialized with 0. - Replaced in some cases C99 comments for /* */ Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/common/ir-functions.c | 2 +- linux/drivers/media/dvb/b2c2/flexcop-pci.c | 2 +- linux/drivers/media/dvb/dvb-core/dvb_net.c | 2 +- linux/drivers/media/dvb/frontends/cx22702.c | 2 +- linux/drivers/media/dvb/frontends/dvb-pll.c | 2 +- linux/drivers/media/dvb/frontends/lgdt330x.c | 2 +- linux/drivers/media/dvb/frontends/nxt6000.c | 2 +- linux/drivers/media/dvb/frontends/s5h1409.c | 2 +- linux/drivers/media/dvb/frontends/s5h1420.c | 2 +- linux/drivers/media/dvb/frontends/sp8870.c | 12 ++++++------ linux/drivers/media/dvb/frontends/tda10086.c | 2 +- linux/drivers/media/dvb/frontends/tda826x.c | 2 +- linux/drivers/media/dvb/frontends/tda827x.c | 2 +- linux/drivers/media/dvb/frontends/ves1x93.c | 2 +- linux/drivers/media/dvb/frontends/zl10353.c | 2 +- linux/drivers/media/dvb/ttpci/budget-ci.c | 2 +- linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | 2 +- linux/drivers/media/radio/miropcm20-rds.c | 2 +- linux/drivers/media/radio/radio-cadet.c | 10 +++++----- linux/drivers/media/radio/radio-typhoon.c | 2 +- linux/drivers/media/video/adv7170.c | 2 +- linux/drivers/media/video/adv7175.c | 2 +- linux/drivers/media/video/arv.c | 4 ++-- linux/drivers/media/video/bt819.c | 2 +- linux/drivers/media/video/bt856.c | 2 +- linux/drivers/media/video/bt8xx/bttv-vbi.c | 2 +- linux/drivers/media/video/bw-qcam.c | 4 ++-- linux/drivers/media/video/c-qcam.c | 4 ++-- linux/drivers/media/video/cafe_ccic.c | 4 ++-- linux/drivers/media/video/cpia2/cpia2_core.c | 4 ++-- linux/drivers/media/video/cpia2/cpia2_usb.c | 2 +- linux/drivers/media/video/cx23885/cx23885-i2c.c | 2 +- linux/drivers/media/video/cx88/cx88-blackbird.c | 2 +- linux/drivers/media/video/cx88/cx88-core.c | 6 +++--- linux/drivers/media/video/cx88/cx88-dvb.c | 2 +- linux/drivers/media/video/cx88/cx88-i2c.c | 4 ++-- linux/drivers/media/video/cx88/cx88-input.c | 2 +- linux/drivers/media/video/cx88/cx88-mpeg.c | 2 +- linux/drivers/media/video/cx88/cx88-tvaudio.c | 6 +++--- linux/drivers/media/video/cx88/cx88-vbi.c | 2 +- linux/drivers/media/video/cx88/cx88-video.c | 4 ++-- linux/drivers/media/video/dpc7146.c | 4 ++-- linux/drivers/media/video/em28xx/em28xx-core.c | 6 +++--- linux/drivers/media/video/em28xx/em28xx-i2c.c | 4 ++-- linux/drivers/media/video/em28xx/em28xx-video.c | 2 +- linux/drivers/media/video/et61x251/et61x251_core.c | 2 +- linux/drivers/media/video/hexium_gemini.c | 4 ++-- linux/drivers/media/video/hexium_orion.c | 4 ++-- linux/drivers/media/video/ir-kbd-i2c.c | 2 +- linux/drivers/media/video/ivtv/ivtv-driver.c | 6 +++--- linux/drivers/media/video/meye.c | 2 +- linux/drivers/media/video/mt20xx.c | 4 ++-- linux/drivers/media/video/mxb.c | 4 ++-- linux/drivers/media/video/pms.c | 4 ++-- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 6 +++--- linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 2 +- linux/drivers/media/video/pwc/pwc-if.c | 8 ++++---- linux/drivers/media/video/saa6588.c | 8 ++++---- linux/drivers/media/video/saa7110.c | 2 +- linux/drivers/media/video/saa7111.c | 2 +- linux/drivers/media/video/saa7114.c | 2 +- linux/drivers/media/video/saa7115.c | 2 +- linux/drivers/media/video/saa711x.c | 4 ++-- linux/drivers/media/video/saa7134/saa7134-alsa.c | 2 +- linux/drivers/media/video/saa7134/saa7134-core.c | 10 +++++----- linux/drivers/media/video/saa7134/saa7134-dvb.c | 6 +++--- linux/drivers/media/video/saa7134/saa7134-empress.c | 2 +- linux/drivers/media/video/saa7134/saa7134-i2c.c | 4 ++-- linux/drivers/media/video/saa7134/saa7134-input.c | 6 +++--- linux/drivers/media/video/saa7134/saa7134-ts.c | 2 +- linux/drivers/media/video/saa7134/saa7134-tvaudio.c | 6 +++--- linux/drivers/media/video/saa7134/saa7134-vbi.c | 2 +- linux/drivers/media/video/saa7134/saa7134-video.c | 2 +- linux/drivers/media/video/saa7185.c | 2 +- linux/drivers/media/video/se401.c | 2 +- linux/drivers/media/video/sn9c102/sn9c102_core.c | 2 +- linux/drivers/media/video/stradis.c | 4 ++-- linux/drivers/media/video/stv680.c | 9 ++++++--- linux/drivers/media/video/tda9840.c | 2 +- linux/drivers/media/video/tea5761.c | 2 +- linux/drivers/media/video/tea5767.c | 2 +- linux/drivers/media/video/tea6415c.c | 2 +- linux/drivers/media/video/tea6420.c | 2 +- linux/drivers/media/video/tuner-core.c | 6 +++--- linux/drivers/media/video/tvaudio.c | 8 ++++---- linux/drivers/media/video/tvp5150.c | 2 +- linux/drivers/media/video/usbvideo/ibmcam.c | 2 +- linux/drivers/media/video/usbvideo/konicawc.c | 2 +- linux/drivers/media/video/usbvideo/quickcam_messenger.c | 2 +- linux/drivers/media/video/usbvideo/ultracam.c | 4 ++-- linux/drivers/media/video/usbvideo/usbvideo.c | 2 +- linux/drivers/media/video/usbvision/usbvision-core.c | 14 ++++++++------ linux/drivers/media/video/usbvision/usbvision-i2c.c | 2 +- linux/drivers/media/video/usbvision/usbvision-video.c | 4 ++-- linux/drivers/media/video/v4l1-compat.c | 2 +- linux/drivers/media/video/videobuf-dma-sg.c | 2 +- linux/drivers/media/video/videobuf-dvb.c | 2 +- linux/drivers/media/video/videobuf-vmalloc.c | 2 +- linux/drivers/media/video/videocodec.c | 4 ++-- linux/drivers/media/video/vino.c | 10 +++++----- linux/drivers/media/video/vpx3220.c | 2 +- linux/drivers/media/video/w9966.c | 4 ++-- linux/drivers/media/video/w9968cf.c | 2 +- linux/drivers/media/video/zc0301/zc0301_core.c | 2 +- linux/drivers/media/video/zoran_card.c | 6 +++--- linux/drivers/media/video/zoran_device.c | 5 +++-- linux/drivers/media/video/zoran_driver.c | 2 +- linux/drivers/media/video/zr36016.c | 5 ++--- linux/drivers/media/video/zr36050.c | 5 ++--- linux/drivers/media/video/zr36060.c | 6 +++--- linux/drivers/media/video/zr364xx.c | 4 ++-- 111 files changed, 197 insertions(+), 193 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/common/ir-functions.c b/linux/drivers/media/common/ir-functions.c index e9a8aa5a3..2adbb6e9f 100644 --- a/linux/drivers/media/common/ir-functions.c +++ b/linux/drivers/media/common/ir-functions.c @@ -35,7 +35,7 @@ static int repeat = 1; module_param(repeat, int, 0444); MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)"); -static int debug = 0; /* debug level (0,1,2) */ +static int debug; /* debug level (0,1,2) */ module_param(debug, int, 0644); #define dprintk(level, fmt, arg...) if (debug >= level) \ diff --git a/linux/drivers/media/dvb/b2c2/flexcop-pci.c b/linux/drivers/media/dvb/b2c2/flexcop-pci.c index 4388a78a1..853a3ccff 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-pci.c @@ -32,7 +32,7 @@ MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently jus #define deb_irq(args...) dprintk(0x08,args) #define deb_chk(args...) dprintk(0x10,args) -static int debug = 0; +static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "set debug level (1=info,2=regs,4=TS,8=irqdma (|-able))." DEBSTATUS); diff --git a/linux/drivers/media/dvb/dvb-core/dvb_net.c b/linux/drivers/media/dvb/dvb-core/dvb_net.c index 793e004fe..e2eae4ca7 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_net.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_net.c @@ -367,7 +367,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) #ifdef ULE_DEBUG /* The code inside ULE_DEBUG keeps a history of the last 100 TS cells processed. */ static unsigned char ule_hist[100*TS_SZ]; - static unsigned char *ule_where = ule_hist, ule_dump = 0; + static unsigned char *ule_where = ule_hist, ule_dump; #endif /* For all TS cells in current buffer. diff --git a/linux/drivers/media/dvb/frontends/cx22702.c b/linux/drivers/media/dvb/frontends/cx22702.c index 1dc164d54..406c4cfa8 100644 --- a/linux/drivers/media/dvb/frontends/cx22702.c +++ b/linux/drivers/media/dvb/frontends/cx22702.c @@ -48,7 +48,7 @@ struct cx22702_state { u8 prevUCBlocks; }; -static int debug = 0; +static int debug; #define dprintk if (debug) printk /* Register values to initialise the demod */ diff --git a/linux/drivers/media/dvb/frontends/dvb-pll.c b/linux/drivers/media/dvb/frontends/dvb-pll.c index 50c8ee294..ae5e48582 100644 --- a/linux/drivers/media/dvb/frontends/dvb-pll.c +++ b/linux/drivers/media/dvb/frontends/dvb-pll.c @@ -45,7 +45,7 @@ struct dvb_pll_priv { static unsigned int dvb_pll_devcount; -static int debug = 0; +static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable verbose debug messages"); diff --git a/linux/drivers/media/dvb/frontends/lgdt330x.c b/linux/drivers/media/dvb/frontends/lgdt330x.c index 8bfd491b5..033b5a18d 100644 --- a/linux/drivers/media/dvb/frontends/lgdt330x.c +++ b/linux/drivers/media/dvb/frontends/lgdt330x.c @@ -50,7 +50,7 @@ /* Use Equalizer Mean Squared Error instead of Phaser Tracker MSE */ /* #define USE_EQMSE */ -static int debug = 0; +static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug,"Turn on/off lgdt330x frontend debugging (default:off)."); #define dprintk(args...) \ diff --git a/linux/drivers/media/dvb/frontends/nxt6000.c b/linux/drivers/media/dvb/frontends/nxt6000.c index d313d7dcf..0eef22dbf 100644 --- a/linux/drivers/media/dvb/frontends/nxt6000.c +++ b/linux/drivers/media/dvb/frontends/nxt6000.c @@ -38,7 +38,7 @@ struct nxt6000_state { struct dvb_frontend frontend; }; -static int debug = 0; +static int debug; #define dprintk if (debug) printk static int nxt6000_writereg(struct nxt6000_state* state, u8 reg, u8 data) diff --git a/linux/drivers/media/dvb/frontends/s5h1409.c b/linux/drivers/media/dvb/frontends/s5h1409.c index 819433485..c5232e8ff 100644 --- a/linux/drivers/media/dvb/frontends/s5h1409.c +++ b/linux/drivers/media/dvb/frontends/s5h1409.c @@ -48,7 +48,7 @@ struct s5h1409_state { u32 qam_state; }; -static int debug = 0; +static int debug; #define dprintk if (debug) printk /* Register values to initialise the demod, this will set VSB by default */ diff --git a/linux/drivers/media/dvb/frontends/s5h1420.c b/linux/drivers/media/dvb/frontends/s5h1420.c index 2c2c344c4..7c64af91e 100644 --- a/linux/drivers/media/dvb/frontends/s5h1420.c +++ b/linux/drivers/media/dvb/frontends/s5h1420.c @@ -53,7 +53,7 @@ static int s5h1420_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings); -static int debug = 0; +static int debug; #define dprintk if (debug) printk static int s5h1420_writereg (struct s5h1420_state* state, u8 reg, u8 data) diff --git a/linux/drivers/media/dvb/frontends/sp8870.c b/linux/drivers/media/dvb/frontends/sp8870.c index da876f7bf..f5b3bfc00 100644 --- a/linux/drivers/media/dvb/frontends/sp8870.c +++ b/linux/drivers/media/dvb/frontends/sp8870.c @@ -449,15 +449,15 @@ static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks return 0; } -// number of trials to recover from lockup +/* number of trials to recover from lockup */ #define MAXTRIALS 5 -// maximum checks for data valid signal +/* maximum checks for data valid signal */ #define MAXCHECKS 100 -// only for debugging: counter for detected lockups -static int lockups = 0; -// only for debugging: counter for channel switches -static int switches = 0; +/* only for debugging: counter for detected lockups */ +static int lockups; +/* only for debugging: counter for channel switches */ +static int switches; static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { diff --git a/linux/drivers/media/dvb/frontends/tda10086.c b/linux/drivers/media/dvb/frontends/tda10086.c index 16b13f834..0eef34b6f 100644 --- a/linux/drivers/media/dvb/frontends/tda10086.c +++ b/linux/drivers/media/dvb/frontends/tda10086.c @@ -44,7 +44,7 @@ struct tda10086_state { bool has_lock; }; -static int debug = 0; +static int debug; #define dprintk(args...) \ do { \ if (debug) printk(KERN_DEBUG "tda10086: " args); \ diff --git a/linux/drivers/media/dvb/frontends/tda826x.c b/linux/drivers/media/dvb/frontends/tda826x.c index 24d6cc11f..71c486b4e 100644 --- a/linux/drivers/media/dvb/frontends/tda826x.c +++ b/linux/drivers/media/dvb/frontends/tda826x.c @@ -27,7 +27,7 @@ #include "tda826x.h" -static int debug = 0; +static int debug; #define dprintk(args...) \ do { \ if (debug) printk(KERN_DEBUG "tda826x: " args); \ diff --git a/linux/drivers/media/dvb/frontends/tda827x.c b/linux/drivers/media/dvb/frontends/tda827x.c index ed1502252..d4f23f961 100644 --- a/linux/drivers/media/dvb/frontends/tda827x.c +++ b/linux/drivers/media/dvb/frontends/tda827x.c @@ -26,7 +26,7 @@ #include "tda827x.h" -static int debug = 0; +static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); diff --git a/linux/drivers/media/dvb/frontends/ves1x93.c b/linux/drivers/media/dvb/frontends/ves1x93.c index 23fd0303c..c041c81f9 100644 --- a/linux/drivers/media/dvb/frontends/ves1x93.c +++ b/linux/drivers/media/dvb/frontends/ves1x93.c @@ -48,7 +48,7 @@ struct ves1x93_state { u8 demod_type; }; -static int debug = 0; +static int debug; #define dprintk if (debug) printk #define DEMOD_VES1893 0 diff --git a/linux/drivers/media/dvb/frontends/zl10353.c b/linux/drivers/media/dvb/frontends/zl10353.c index 79802e023..1ae9f0ef1 100644 --- a/linux/drivers/media/dvb/frontends/zl10353.c +++ b/linux/drivers/media/dvb/frontends/zl10353.c @@ -48,7 +48,7 @@ static int debug; } while (0) #if 1 -static int debug_regs = 0; +static int debug_regs; #endif static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val) diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index 3ccca5d90..c35ad070c 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -86,7 +86,7 @@ static int rc5_device = -1; module_param(rc5_device, int, 0644); MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)"); -static int ir_debug = 0; +static int ir_debug; module_param(ir_debug, int, 0644); MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); diff --git a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 8fd4b615b..b02eb601f 100644 --- a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -550,7 +550,7 @@ static void ttusb_handle_sec_data(struct ttusb_channel *channel, const u8 * data, int len); #endif -static int numpkt = 0, numts, numstuff, numsec, numinvalid; +static int numpkt, numts, numstuff, numsec, numinvalid; static unsigned long lastj; static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack, diff --git a/linux/drivers/media/radio/miropcm20-rds.c b/linux/drivers/media/radio/miropcm20-rds.c index aed114773..06dfed9ef 100644 --- a/linux/drivers/media/radio/miropcm20-rds.c +++ b/linux/drivers/media/radio/miropcm20-rds.c @@ -19,7 +19,7 @@ #include "miropcm20-rds-core.h" static char * text_buffer; -static int rds_users = 0; +static int rds_users; static int rds_f_open(struct inode *in, struct file *fi) diff --git a/linux/drivers/media/radio/radio-cadet.c b/linux/drivers/media/radio/radio-cadet.c index 098ee6197..4275dcb51 100644 --- a/linux/drivers/media/radio/radio-cadet.c +++ b/linux/drivers/media/radio/radio-cadet.c @@ -70,13 +70,13 @@ static struct v4l2_queryctrl radio_qctrl[] = { static int io=-1; /* default to isapnp activation */ static int radio_nr = -1; -static int users=0; -static int curtuner=0; -static int tunestat=0; -static int sigstrength=0; +static int users; +static int curtuner; +static int tunestat; +static int sigstrength; static wait_queue_head_t read_queue; static struct timer_list readtimer; -static __u8 rdsin=0,rdsout=0,rdsstat=0; +static __u8 rdsin, rdsout, rdsstat; static unsigned char rdsbuf[RDS_BUFFER]; static spinlock_t cadet_io_lock; diff --git a/linux/drivers/media/radio/radio-typhoon.c b/linux/drivers/media/radio/radio-typhoon.c index 24042aef3..42f707f08 100644 --- a/linux/drivers/media/radio/radio-typhoon.c +++ b/linux/drivers/media/radio/radio-typhoon.c @@ -409,7 +409,7 @@ MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)"); module_param(radio_nr, int, 0); #ifdef MODULE -static unsigned long mutefreq = 0; +static unsigned long mutefreq; module_param(mutefreq, ulong, 0); MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)"); #endif diff --git a/linux/drivers/media/video/adv7170.c b/linux/drivers/media/video/adv7170.c index 190744da1..0d15ce53d 100644 --- a/linux/drivers/media/video/adv7170.c +++ b/linux/drivers/media/video/adv7170.c @@ -57,7 +57,7 @@ MODULE_LICENSE("GPL"); #define I2C_NAME(x) (x)->name -static int debug = 0; +static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); diff --git a/linux/drivers/media/video/adv7175.c b/linux/drivers/media/video/adv7175.c index aa53c5d60..86345ba5c 100644 --- a/linux/drivers/media/video/adv7175.c +++ b/linux/drivers/media/video/adv7175.c @@ -53,7 +53,7 @@ MODULE_LICENSE("GPL"); #define I2C_NAME(s) (s)->name -static int debug = 0; +static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); diff --git a/linux/drivers/media/video/arv.c b/linux/drivers/media/video/arv.c index 0f578259e..479ca4b46 100644 --- a/linux/drivers/media/video/arv.c +++ b/linux/drivers/media/video/arv.c @@ -126,8 +126,8 @@ static unsigned char yuv[MAX_AR_FRAME_BYTES]; /* default frequency */ #define DEFAULT_FREQ 50 /* 50 or 75 (MHz) is available as BCLK */ static int freq = DEFAULT_FREQ; /* BCLK: available 50 or 70 (MHz) */ -static int vga = 0; /* default mode(0:QVGA mode, other:VGA mode) */ -static int vga_interlace = 0; /* 0 is normal mode for, else interlace mode */ +static int vga; /* default mode(0:QVGA mode, other:VGA mode) */ +static int vga_interlace; /* 0 is normal mode for, else interlace mode */ module_param(freq, int, 0); module_param(vga, int, 0); module_param(vga_interlace, int, 0); diff --git a/linux/drivers/media/video/bt819.c b/linux/drivers/media/video/bt819.c index 580b838d5..9264e2cff 100644 --- a/linux/drivers/media/video/bt819.c +++ b/linux/drivers/media/video/bt819.c @@ -58,7 +58,7 @@ MODULE_LICENSE("GPL"); #define I2C_NAME(s) (s)->name -static int debug = 0; +static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); diff --git a/linux/drivers/media/video/bt856.c b/linux/drivers/media/video/bt856.c index 9c1d3d145..7abfad9a4 100644 --- a/linux/drivers/media/video/bt856.c +++ b/linux/drivers/media/video/bt856.c @@ -57,7 +57,7 @@ MODULE_LICENSE("GPL"); #define I2C_NAME(s) (s)->name -static int debug = 0; +static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); diff --git a/linux/drivers/media/video/bt8xx/bttv-vbi.c b/linux/drivers/media/video/bt8xx/bttv-vbi.c index 1f0cc79e2..d17e583c0 100644 --- a/linux/drivers/media/video/bt8xx/bttv-vbi.c +++ b/linux/drivers/media/video/bt8xx/bttv-vbi.c @@ -54,7 +54,7 @@ #define VBI_DEFLINES 16 static unsigned int vbibufs = 4; -static unsigned int vbi_debug = 0; +static unsigned int vbi_debug; module_param(vbibufs, int, 0444); module_param(vbi_debug, int, 0644); diff --git a/linux/drivers/media/video/bw-qcam.c b/linux/drivers/media/video/bw-qcam.c index 7c165c7cf..14b15dcaf 100644 --- a/linux/drivers/media/video/bw-qcam.c +++ b/linux/drivers/media/video/bw-qcam.c @@ -526,7 +526,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[]) int ret=1; unsigned int hi, lo; unsigned int hi2, lo2; - static int state = 0; + static int state; if (buffer == NULL) { @@ -915,7 +915,7 @@ static struct video_device qcam_template= #define MAX_CAMS 4 static struct qcam_device *qcams[MAX_CAMS]; -static unsigned int num_cams = 0; +static unsigned int num_cams; static int init_bwqcam(struct parport *port) { diff --git a/linux/drivers/media/video/c-qcam.c b/linux/drivers/media/video/c-qcam.c index 933284200..f571c6a69 100644 --- a/linux/drivers/media/video/c-qcam.c +++ b/linux/drivers/media/video/c-qcam.c @@ -76,7 +76,7 @@ struct qcam_device { static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 }; static int probe = 2; -static int force_rgb = 0; +static int force_rgb; static int video_nr = -1; static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i) @@ -748,7 +748,7 @@ static struct qcam_device *qcam_init(struct parport *port) } static struct qcam_device *qcams[MAX_CAMS]; -static unsigned int num_cams = 0; +static unsigned int num_cams; static int init_cqcam(struct parport *port) { diff --git a/linux/drivers/media/video/cafe_ccic.c b/linux/drivers/media/video/cafe_ccic.c index 9c9a33be6..56409d585 100644 --- a/linux/drivers/media/video/cafe_ccic.c +++ b/linux/drivers/media/video/cafe_ccic.c @@ -66,7 +66,7 @@ MODULE_SUPPORTED_DEVICE("Video"); */ #define MAX_DMA_BUFS 3 -static int alloc_bufs_at_read = 0; +static int alloc_bufs_at_read; module_param(alloc_bufs_at_read, bool, 0444); MODULE_PARM_DESC(alloc_bufs_at_read, "Non-zero value causes DMA buffers to be allocated when the " @@ -100,7 +100,7 @@ MODULE_PARM_DESC(max_buffers, "will be allowed to allocate. These buffers are big and live " "in vmalloc space."); -static int flip = 0; +static int flip; module_param(flip, bool, 0444); MODULE_PARM_DESC(flip, "If set, the sensor will be instructed to flip the image " diff --git a/linux/drivers/media/video/cpia2/cpia2_core.c b/linux/drivers/media/video/cpia2/cpia2_core.c index a76bd786c..a439a56c3 100644 --- a/linux/drivers/media/video/cpia2/cpia2_core.c +++ b/linux/drivers/media/video/cpia2/cpia2_core.c @@ -34,7 +34,7 @@ #include #include -//#define _CPIA2_DEBUG_ +/* #define _CPIA2_DEBUG_ */ #include "cpia2patch.h" @@ -48,7 +48,7 @@ static const char *block_name[] = { }; #endif -static unsigned int debugs_on = 0;//DEBUG_REG; +static unsigned int debugs_on; /* default 0 - DEBUG_REG */ /****************************************************************************** diff --git a/linux/drivers/media/video/cpia2/cpia2_usb.c b/linux/drivers/media/video/cpia2/cpia2_usb.c index 87442ede0..01131e984 100644 --- a/linux/drivers/media/video/cpia2/cpia2_usb.c +++ b/linux/drivers/media/video/cpia2/cpia2_usb.c @@ -88,7 +88,7 @@ static struct usb_driver cpia2_driver = { *****************************************************************************/ static void process_frame(struct camera_data *cam) { - static int frame_count = 0; + static int frame_count; unsigned char *inbuff = cam->workbuff->data; diff --git a/linux/drivers/media/video/cx23885/cx23885-i2c.c b/linux/drivers/media/video/cx23885/cx23885-i2c.c index c89e458ce..ab83c88a9 100644 --- a/linux/drivers/media/video/cx23885/cx23885-i2c.c +++ b/linux/drivers/media/video/cx23885/cx23885-i2c.c @@ -34,7 +34,7 @@ static unsigned int i2c_debug; module_param(i2c_debug, int, 0644); MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); -static unsigned int i2c_scan = 0; +static unsigned int i2c_scan; module_param(i2c_scan, int, 0444); MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); diff --git a/linux/drivers/media/video/cx88/cx88-blackbird.c b/linux/drivers/media/video/cx88/cx88-blackbird.c index 8ef0ee322..6de1e1da7 100644 --- a/linux/drivers/media/video/cx88/cx88-blackbird.c +++ b/linux/drivers/media/video/cx88/cx88-blackbird.c @@ -47,7 +47,7 @@ static unsigned int mpegbufs = 32; module_param(mpegbufs,int,0644); MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32"); -static unsigned int debug = 0; +static unsigned int debug; module_param(debug,int,0644); MODULE_PARM_DESC(debug,"enable debug messages [blackbird]"); diff --git a/linux/drivers/media/video/cx88/cx88-core.c b/linux/drivers/media/video/cx88/cx88-core.c index b67aa65e5..25985f7d5 100644 --- a/linux/drivers/media/video/cx88/cx88-core.c +++ b/linux/drivers/media/video/cx88/cx88-core.c @@ -50,15 +50,15 @@ MODULE_LICENSE("GPL"); /* ------------------------------------------------------------------ */ -static unsigned int core_debug = 0; +static unsigned int core_debug; module_param(core_debug,int,0644); MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); -static unsigned int nicam = 0; +static unsigned int nicam; module_param(nicam,int,0644); MODULE_PARM_DESC(nicam,"tv audio is nicam"); -static unsigned int nocomb = 0; +static unsigned int nocomb; module_param(nocomb,int,0644); MODULE_PARM_DESC(nocomb,"disable comb filter"); diff --git a/linux/drivers/media/video/cx88/cx88-dvb.c b/linux/drivers/media/video/cx88/cx88-dvb.c index 1e6eb3123..79aa5bedd 100644 --- a/linux/drivers/media/video/cx88/cx88-dvb.c +++ b/linux/drivers/media/video/cx88/cx88-dvb.c @@ -52,7 +52,7 @@ MODULE_AUTHOR("Chris Pascoe "); MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); MODULE_LICENSE("GPL"); -static unsigned int debug = 0; +static unsigned int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug,"enable debug messages [dvb]"); diff --git a/linux/drivers/media/video/cx88/cx88-i2c.c b/linux/drivers/media/video/cx88/cx88-i2c.c index 20185aeca..44d01352e 100644 --- a/linux/drivers/media/video/cx88/cx88-i2c.c +++ b/linux/drivers/media/video/cx88/cx88-i2c.c @@ -38,11 +38,11 @@ #include "i2c-compat.h" #endif -static unsigned int i2c_debug = 0; +static unsigned int i2c_debug; module_param(i2c_debug, int, 0644); MODULE_PARM_DESC(i2c_debug,"enable debug messages [i2c]"); -static unsigned int i2c_scan = 0; +static unsigned int i2c_scan; module_param(i2c_scan, int, 0444); MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); diff --git a/linux/drivers/media/video/cx88/cx88-input.c b/linux/drivers/media/video/cx88/cx88-input.c index 5aaed62eb..2105cd2e5 100644 --- a/linux/drivers/media/video/cx88/cx88-input.c +++ b/linux/drivers/media/video/cx88/cx88-input.c @@ -58,7 +58,7 @@ struct cx88_IR { u32 mask_keyup; }; -static int ir_debug = 0; +static int ir_debug; module_param(ir_debug, int, 0644); /* debug level [IR] */ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); diff --git a/linux/drivers/media/video/cx88/cx88-mpeg.c b/linux/drivers/media/video/cx88/cx88-mpeg.c index 9ed0af144..30ac9795b 100644 --- a/linux/drivers/media/video/cx88/cx88-mpeg.c +++ b/linux/drivers/media/video/cx88/cx88-mpeg.c @@ -45,7 +45,7 @@ MODULE_AUTHOR("Jelle Foks ,Chris Pascoe revision != 0) -static int debug = 0; +static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "debug verbosity"); -static int dpc_num = 0; +static int dpc_num; #define DPC_INPUTS 2 static struct v4l2_input dpc_inputs[DPC_INPUTS] = { diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c index cb87e7e41..7a15a69fb 100644 --- a/linux/drivers/media/video/em28xx/em28xx-core.c +++ b/linux/drivers/media/video/em28xx/em28xx-core.c @@ -31,7 +31,7 @@ /* #define ENABLE_DEBUG_ISOC_FRAMES */ -static unsigned int core_debug = 0; +static unsigned int core_debug; module_param(core_debug,int,0644); MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); @@ -40,7 +40,7 @@ MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); printk(KERN_INFO "%s %s :"fmt, \ dev->name, __FUNCTION__ , ##arg); } while (0) -static unsigned int reg_debug = 0; +static unsigned int reg_debug; module_param(reg_debug,int,0644); MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]"); @@ -49,7 +49,7 @@ MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]"); printk(KERN_INFO "%s %s :"fmt, \ dev->name, __FUNCTION__ , ##arg); } while (0) -static unsigned int isoc_debug = 0; +static unsigned int isoc_debug; module_param(isoc_debug,int,0644); MODULE_PARM_DESC(isoc_debug,"enable debug messages [isoc transfers]"); diff --git a/linux/drivers/media/video/em28xx/em28xx-i2c.c b/linux/drivers/media/video/em28xx/em28xx-i2c.c index fc59cce34..e13743d67 100644 --- a/linux/drivers/media/video/em28xx/em28xx-i2c.c +++ b/linux/drivers/media/video/em28xx/em28xx-i2c.c @@ -33,11 +33,11 @@ /* ----------------------------------------------------------- */ -static unsigned int i2c_scan = 0; +static unsigned int i2c_scan; module_param(i2c_scan, int, 0444); MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); -static unsigned int i2c_debug = 0; +static unsigned int i2c_debug; module_param(i2c_debug, int, 0644); MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index e5da0ffac..284b385fb 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -94,7 +94,7 @@ MODULE_PARM_DESC(video_nr, "video device numbers"); MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); MODULE_PARM_DESC(radio_nr, "radio device numbers"); -static unsigned int video_debug = 0; +static unsigned int video_debug; module_param(video_debug,int,0644); MODULE_PARM_DESC(video_debug,"enable debug messages [video]"); diff --git a/linux/drivers/media/video/et61x251/et61x251_core.c b/linux/drivers/media/video/et61x251/et61x251_core.c index 466e80b7f..87a39ca42 100644 --- a/linux/drivers/media/video/et61x251/et61x251_core.c +++ b/linux/drivers/media/video/et61x251/et61x251_core.c @@ -2542,7 +2542,7 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) { struct usb_device *udev = interface_to_usbdev(intf); struct et61x251_device* cam; - static unsigned int dev_nr = 0; + static unsigned int dev_nr; unsigned int i; int err = 0; diff --git a/linux/drivers/media/video/hexium_gemini.c b/linux/drivers/media/video/hexium_gemini.c index d1957736b..185a862c0 100644 --- a/linux/drivers/media/video/hexium_gemini.c +++ b/linux/drivers/media/video/hexium_gemini.c @@ -26,12 +26,12 @@ #include #include "compat.h" -static int debug = 0; +static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "debug verbosity"); /* global variables */ -static int hexium_num = 0; +static int hexium_num; #define HEXIUM_GEMINI 4 #define HEXIUM_GEMINI_DUAL 5 diff --git a/linux/drivers/media/video/hexium_orion.c b/linux/drivers/media/video/hexium_orion.c index 2c9eb6923..53db5fabc 100644 --- a/linux/drivers/media/video/hexium_orion.c +++ b/linux/drivers/media/video/hexium_orion.c @@ -26,12 +26,12 @@ #include #include "compat.h" -static int debug = 0; +static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "debug verbosity"); /* global variables */ -static int hexium_num = 0; +static int hexium_num; #define HEXIUM_HV_PCI6_ORION 1 #define HEXIUM_ORION_1SVHS_3BNC 2 diff --git a/linux/drivers/media/video/ir-kbd-i2c.c b/linux/drivers/media/video/ir-kbd-i2c.c index 138be506c..c68add9aa 100644 --- a/linux/drivers/media/video/ir-kbd-i2c.c +++ b/linux/drivers/media/video/ir-kbd-i2c.c @@ -52,7 +52,7 @@ static int debug; module_param(debug, int, 0644); /* debug level (0,1,2) */ -static int hauppauge = 0; +static int hauppauge; module_param(hauppauge, int, 0644); /* Choose Hauppauge remote */ MODULE_PARM_DESC(hauppauge, "Specify Hauppauge remote: 0=black, 1=grey (defaults to 0)"); diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.c b/linux/drivers/media/video/ivtv/ivtv-driver.c index e7741a031..b6c145752 100644 --- a/linux/drivers/media/video/ivtv/ivtv-driver.c +++ b/linux/drivers/media/video/ivtv/ivtv-driver.c @@ -127,11 +127,11 @@ static int dec_mpg_buffers = IVTV_DEFAULT_DEC_MPG_BUFFERS; static int dec_yuv_buffers = IVTV_DEFAULT_DEC_YUV_BUFFERS; static int dec_vbi_buffers = IVTV_DEFAULT_DEC_VBI_BUFFERS; -static int ivtv_yuv_mode = 0; -static int ivtv_yuv_threshold=-1; +static int ivtv_yuv_mode; +static int ivtv_yuv_threshold = -1; static int ivtv_pci_latency = 1; -int ivtv_debug = 0; +int ivtv_debug; static int newi2c = -1; diff --git a/linux/drivers/media/video/meye.c b/linux/drivers/media/video/meye.c index 8f6cbe71f..5e00e1fe3 100644 --- a/linux/drivers/media/video/meye.c +++ b/linux/drivers/media/video/meye.c @@ -794,7 +794,7 @@ static irqreturn_t meye_irq(int irq, void *dev_id) { u32 v; int reqnr; - static int sequence = 0; + static int sequence; v = mchip_read(MCHIP_MM_INTA); diff --git a/linux/drivers/media/video/mt20xx.c b/linux/drivers/media/video/mt20xx.c index d1789d109..cd1122e4d 100644 --- a/linux/drivers/media/video/mt20xx.c +++ b/linux/drivers/media/video/mt20xx.c @@ -14,7 +14,7 @@ #include "i2c-compat.h" #endif -static int debug = 0; +static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable verbose debug messages"); @@ -28,7 +28,7 @@ module_param(optimize_vco, int, 0644); static unsigned int tv_antenna = 1; module_param(tv_antenna, int, 0644); -static unsigned int radio_antenna = 0; +static unsigned int radio_antenna; module_param(radio_antenna, int, 0644); /* ---------------------------------------------------------------------- */ diff --git a/linux/drivers/media/video/mxb.c b/linux/drivers/media/video/mxb.c index 6847f8c93..354ecaf8d 100644 --- a/linux/drivers/media/video/mxb.c +++ b/linux/drivers/media/video/mxb.c @@ -39,7 +39,7 @@ #define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) /* global variable */ -static int mxb_num = 0; +static int mxb_num; /* initial frequence the tuner will be tuned to. in verden (lower saxony, germany) 4148 is a @@ -48,7 +48,7 @@ static int freq = 4148; module_param(freq, int, 0644); MODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup"); -static int debug = 0; +static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); diff --git a/linux/drivers/media/video/pms.c b/linux/drivers/media/video/pms.c index ce69c0399..b976df7bd 100644 --- a/linux/drivers/media/video/pms.c +++ b/linux/drivers/media/video/pms.c @@ -64,11 +64,11 @@ struct i2c_info u8 hits; }; -static int i2c_count = 0; +static int i2c_count; static struct i2c_info i2cinfo[64]; static int decoder = PHILIPS2; -static int standard = 0; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */ +static int standard; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */ /* * I/O ports and Shared Memory diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 0a5d488b8..5b8d6bd33 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -45,13 +45,13 @@ static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL}; static DEFINE_MUTEX(pvr2_unit_mtx); -static int ctlchg = 0; +static int ctlchg; static int initusbreset = 1; -static int procreload = 0; +static int procreload; static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 }; static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 }; static int video_std[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 }; -static int init_pause_msec = 0; +static int init_pause_msec; module_param(ctlchg, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value"); diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index 98d918420..ddf357d1b 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c @@ -36,7 +36,7 @@ */ -static unsigned int i2c_scan = 0; +static unsigned int i2c_scan; module_param(i2c_scan, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); diff --git a/linux/drivers/media/video/pwc/pwc-if.c b/linux/drivers/media/video/pwc/pwc-if.c index 1f5a8a18c..b09443b09 100644 --- a/linux/drivers/media/video/pwc/pwc-if.c +++ b/linux/drivers/media/video/pwc/pwc-if.c @@ -130,8 +130,8 @@ static int default_fbufs = 3; /* Default number of frame buffers */ #ifdef CONFIG_USB_PWC_DEBUG int pwc_trace = PWC_DEBUG_LEVEL; #endif -static int power_save = 0; -static int led_on = 100, led_off = 0; /* defaults to LED that is on while in use */ +static int power_save; +static int led_on = 100, led_off; /* defaults to LED that is on while in use */ static int pwc_preferred_compression = 1; /* 0..3 = uncompressed..high */ static struct { int type; @@ -790,8 +790,8 @@ static void pwc_isoc_handler(struct urb *urb) } /* ..status == 0 */ else { /* This is normally not interesting to the user, unless - * you are really debugging something */ - static int iso_error = 0; + * you are really debugging something, default = 0 */ + static int iso_error; iso_error++; if (iso_error < 20) PWC_DEBUG_FLOW("Iso frame %d of USB has error %d\n", i, fst); diff --git a/linux/drivers/media/video/saa6588.c b/linux/drivers/media/video/saa6588.c index a6a7fa242..0774c351a 100644 --- a/linux/drivers/media/video/saa6588.c +++ b/linux/drivers/media/video/saa6588.c @@ -51,10 +51,10 @@ static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; I2C_CLIENT_INSMOD; /* insmod options */ -static unsigned int debug = 0; -static unsigned int xtal = 0; -static unsigned int rbds = 0; -static unsigned int plvl = 0; +static unsigned int debug; +static unsigned int xtal; +static unsigned int rbds; +static unsigned int plvl; static unsigned int bufblocks = 100; module_param(debug, int, 0644); diff --git a/linux/drivers/media/video/saa7110.c b/linux/drivers/media/video/saa7110.c index c63097963..eb561ce6c 100644 --- a/linux/drivers/media/video/saa7110.c +++ b/linux/drivers/media/video/saa7110.c @@ -47,7 +47,7 @@ MODULE_LICENSE("GPL"); #include #include -static int debug = 0; +static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); diff --git a/linux/drivers/media/video/saa7111.c b/linux/drivers/media/video/saa7111.c index edd035470..df44aed92 100644 --- a/linux/drivers/media/video/saa7111.c +++ b/linux/drivers/media/video/saa7111.c @@ -56,7 +56,7 @@ MODULE_LICENSE("GPL"); #define I2C_NAME(s) (s)->name -static int debug = 0; +static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Debug level (0-1)"); diff --git a/linux/drivers/media/video/saa7114.c b/linux/drivers/media/video/saa7114.c index 6ac610562..ebf42cf9e 100644 --- a/linux/drivers/media/video/saa7114.c +++ b/linux/drivers/media/video/saa7114.c @@ -57,7 +57,7 @@ MODULE_LICENSE("GPL"); #define I2C_NAME(x) (x)->name -static int debug = 0; +static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); diff --git a/linux/drivers/media/video/saa7115.c b/linux/drivers/media/video/saa7115.c index 3b57cb352..97cd126b8 100644 --- a/linux/drivers/media/video/saa7115.c +++ b/linux/drivers/media/video/saa7115.c @@ -61,7 +61,7 @@ MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, " "Hans Verkuil, Mauro Carvalho Chehab"); MODULE_LICENSE("GPL"); -static int debug = 0; +static int debug; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) module_param(debug, bool, 0644); #else diff --git a/linux/drivers/media/video/saa711x.c b/linux/drivers/media/video/saa711x.c index 715e297fd..28e0c5711 100644 --- a/linux/drivers/media/video/saa711x.c +++ b/linux/drivers/media/video/saa711x.c @@ -52,7 +52,7 @@ MODULE_LICENSE("GPL"); #include -static int debug = 0; +static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, " Set the default Debug level. Default: 0 (Off) - (0-1)"); @@ -470,7 +470,7 @@ static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; I2C_CLIENT_INSMOD; #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) -static int saa711x_i2c_id = 0; +static int saa711x_i2c_id; #endif static struct i2c_driver i2c_driver_saa711x; diff --git a/linux/drivers/media/video/saa7134/saa7134-alsa.c b/linux/drivers/media/video/saa7134/saa7134-alsa.c index 8f80a6ab0..49ff12d08 100644 --- a/linux/drivers/media/video/saa7134/saa7134-alsa.c +++ b/linux/drivers/media/video/saa7134/saa7134-alsa.c @@ -33,7 +33,7 @@ #include "saa7134.h" #include "saa7134-reg.h" -static unsigned int debug = 0; +static unsigned int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug,"enable debug messages [alsa]"); diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c index 002422380..0f9c06942 100644 --- a/linux/drivers/media/video/saa7134/saa7134-core.c +++ b/linux/drivers/media/video/saa7134/saa7134-core.c @@ -44,23 +44,23 @@ MODULE_LICENSE("GPL"); /* ------------------------------------------------------------------ */ -static unsigned int irq_debug = 0; +static unsigned int irq_debug; module_param(irq_debug, int, 0644); MODULE_PARM_DESC(irq_debug,"enable debug messages [IRQ handler]"); -static unsigned int core_debug = 0; +static unsigned int core_debug; module_param(core_debug, int, 0644); MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); -static unsigned int gpio_tracking = 0; +static unsigned int gpio_tracking; module_param(gpio_tracking, int, 0644); MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]"); -static unsigned int alsa = 0; +static unsigned int alsa; module_param(alsa, int, 0644); MODULE_PARM_DESC(alsa,"enable ALSA DMA sound [dmasound]"); -static unsigned int oss = 0; +static unsigned int oss; module_param(oss, int, 0644); MODULE_PARM_DESC(oss,"enable OSS DMA sound [dmasound]"); diff --git a/linux/drivers/media/video/saa7134/saa7134-dvb.c b/linux/drivers/media/video/saa7134/saa7134-dvb.c index 90f495a67..3521548f3 100644 --- a/linux/drivers/media/video/saa7134/saa7134-dvb.c +++ b/linux/drivers/media/video/saa7134/saa7134-dvb.c @@ -47,16 +47,16 @@ MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); MODULE_LICENSE("GPL"); -static unsigned int antenna_pwr = 0; +static unsigned int antenna_pwr; module_param(antenna_pwr, int, 0444); MODULE_PARM_DESC(antenna_pwr,"enable antenna power (Pinnacle 300i)"); -static int use_frontend = 0; +static int use_frontend; module_param(use_frontend, int, 0644); MODULE_PARM_DESC(use_frontend,"for cards with multiple frontends (0: terrestrial, 1: satellite)"); -static int debug = 0; +static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off module debugging (default:off)."); diff --git a/linux/drivers/media/video/saa7134/saa7134-empress.c b/linux/drivers/media/video/saa7134/saa7134-empress.c index b406aabef..dbd026a7c 100644 --- a/linux/drivers/media/video/saa7134/saa7134-empress.c +++ b/linux/drivers/media/video/saa7134/saa7134-empress.c @@ -49,7 +49,7 @@ module_param_array(empress_nr, int, NULL, 0444); #endif MODULE_PARM_DESC(empress_nr,"ts device number"); -static unsigned int debug = 0; +static unsigned int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug,"enable debug messages"); diff --git a/linux/drivers/media/video/saa7134/saa7134-i2c.c b/linux/drivers/media/video/saa7134/saa7134-i2c.c index 4a275e4d7..fda6d44cd 100644 --- a/linux/drivers/media/video/saa7134/saa7134-i2c.c +++ b/linux/drivers/media/video/saa7134/saa7134-i2c.c @@ -33,11 +33,11 @@ /* ----------------------------------------------------------- */ -static unsigned int i2c_debug = 0; +static unsigned int i2c_debug; module_param(i2c_debug, int, 0644); MODULE_PARM_DESC(i2c_debug,"enable debug messages [i2c]"); -static unsigned int i2c_scan = 0; +static unsigned int i2c_scan; module_param(i2c_scan, int, 0444); MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); diff --git a/linux/drivers/media/video/saa7134/saa7134-input.c b/linux/drivers/media/video/saa7134/saa7134-input.c index 448bc41d0..09414dd6d 100644 --- a/linux/drivers/media/video/saa7134/saa7134-input.c +++ b/linux/drivers/media/video/saa7134/saa7134-input.c @@ -27,15 +27,15 @@ #include "saa7134-reg.h" #include "saa7134.h" -static unsigned int disable_ir = 0; +static unsigned int disable_ir; module_param(disable_ir, int, 0444); MODULE_PARM_DESC(disable_ir,"disable infrared remote support"); -static unsigned int ir_debug = 0; +static unsigned int ir_debug; module_param(ir_debug, int, 0644); MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); -static int pinnacle_remote = 0; +static int pinnacle_remote; module_param(pinnacle_remote, int, 0644); /* Choose Pinnacle PCTV remote */ MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=grey (defaults to 0)"); diff --git a/linux/drivers/media/video/saa7134/saa7134-ts.c b/linux/drivers/media/video/saa7134/saa7134-ts.c index f1b8fcaeb..eae72fd60 100644 --- a/linux/drivers/media/video/saa7134/saa7134-ts.c +++ b/linux/drivers/media/video/saa7134/saa7134-ts.c @@ -32,7 +32,7 @@ /* ------------------------------------------------------------------ */ -static unsigned int ts_debug = 0; +static unsigned int ts_debug; module_param(ts_debug, int, 0644); MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]"); diff --git a/linux/drivers/media/video/saa7134/saa7134-tvaudio.c b/linux/drivers/media/video/saa7134/saa7134-tvaudio.c index 3ec368172..91d57ea5f 100644 --- a/linux/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/linux/drivers/media/video/saa7134/saa7134-tvaudio.c @@ -37,18 +37,18 @@ /* ------------------------------------------------------------------ */ -static unsigned int audio_debug = 0; +static unsigned int audio_debug; module_param(audio_debug, int, 0644); MODULE_PARM_DESC(audio_debug,"enable debug messages [tv audio]"); -static unsigned int audio_ddep = 0; +static unsigned int audio_ddep; module_param(audio_ddep, int, 0644); MODULE_PARM_DESC(audio_ddep,"audio ddep overwrite"); static int audio_clock_override = UNSET; module_param(audio_clock_override, int, 0644); -static int audio_clock_tweak = 0; +static int audio_clock_tweak; module_param(audio_clock_tweak, int, 0644); MODULE_PARM_DESC(audio_clock_tweak, "Audio clock tick fine tuning for cards with audio crystal that's slightly off (range [-1024 .. 1024])"); diff --git a/linux/drivers/media/video/saa7134/saa7134-vbi.c b/linux/drivers/media/video/saa7134/saa7134-vbi.c index 6abaa70d2..02e3280ac 100644 --- a/linux/drivers/media/video/saa7134/saa7134-vbi.c +++ b/linux/drivers/media/video/saa7134/saa7134-vbi.c @@ -31,7 +31,7 @@ /* ------------------------------------------------------------------ */ -static unsigned int vbi_debug = 0; +static unsigned int vbi_debug; module_param(vbi_debug, int, 0644); MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]"); diff --git a/linux/drivers/media/video/saa7134/saa7134-video.c b/linux/drivers/media/video/saa7134/saa7134-video.c index f71def0fa..16914e455 100644 --- a/linux/drivers/media/video/saa7134/saa7134-video.c +++ b/linux/drivers/media/video/saa7134/saa7134-video.c @@ -40,7 +40,7 @@ unsigned int video_debug; static unsigned int gbuffers = 8; -static unsigned int noninterlaced = 0; +static unsigned int noninterlaced; /* 0 */ static unsigned int gbufsize = 720*576*4; static unsigned int gbufsize_max = 720*576*4; static char secam[] = "--"; diff --git a/linux/drivers/media/video/saa7185.c b/linux/drivers/media/video/saa7185.c index 552553dab..2ac144d9a 100644 --- a/linux/drivers/media/video/saa7185.c +++ b/linux/drivers/media/video/saa7185.c @@ -53,7 +53,7 @@ MODULE_LICENSE("GPL"); #define I2C_NAME(s) (s)->name -static int debug = 0; +static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); diff --git a/linux/drivers/media/video/se401.c b/linux/drivers/media/video/se401.c index 056337372..58db31f22 100644 --- a/linux/drivers/media/video/se401.c +++ b/linux/drivers/media/video/se401.c @@ -35,7 +35,7 @@ static const char version[] = "0.24"; #include #include "se401.h" -static int flickerless=0; +static int flickerless; static int video_nr = -1; static struct usb_device_id device_table [] = { diff --git a/linux/drivers/media/video/sn9c102/sn9c102_core.c b/linux/drivers/media/video/sn9c102/sn9c102_core.c index bb662b3f8..dc8fd17b6 100644 --- a/linux/drivers/media/video/sn9c102/sn9c102_core.c +++ b/linux/drivers/media/video/sn9c102/sn9c102_core.c @@ -3243,7 +3243,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) { struct usb_device *udev = interface_to_usbdev(intf); struct sn9c102_device* cam; - static unsigned int dev_nr = 0; + static unsigned int dev_nr; unsigned int i; int err = 0, r; diff --git a/linux/drivers/media/video/stradis.c b/linux/drivers/media/video/stradis.c index f5de75513..c095e1453 100644 --- a/linux/drivers/media/video/stradis.c +++ b/linux/drivers/media/video/stradis.c @@ -59,7 +59,7 @@ static struct saa7146 saa7146s[SAA7146_MAX]; -static int saa_num = 0; /* number of SAA7146s in use */ +static int saa_num; /* number of SAA7146s in use */ static int video_nr = -1; module_param(video_nr, int, 0); @@ -249,7 +249,7 @@ static void I2CBusScan(struct saa7146 *saa) attach_inform(saa, i); } -static int debiwait_maxwait = 0; +static int debiwait_maxwait; static int wait_for_debi_done(struct saa7146 *saa) { diff --git a/linux/drivers/media/video/stv680.c b/linux/drivers/media/video/stv680.c index ee11c70fa..b1e40ec94 100644 --- a/linux/drivers/media/video/stv680.c +++ b/linux/drivers/media/video/stv680.c @@ -75,10 +75,13 @@ #include "stv680.h" static int video_nr = -1; -static int swapRGB = 0; /* default for auto sleect */ -static int swapRGB_on = 0; /* default to allow auto select; -1=swap never, +1= swap always */ -static unsigned int debug = 0; +static int swapRGB; /* 0 = default for auto select */ + +/* 0 = default to allow auto select; -1 = swap never, +1 = swap always */ +static int swapRGB_on; + +static unsigned int debug; #define PDEBUG(level, fmt, args...) \ do { \ diff --git a/linux/drivers/media/video/tda9840.c b/linux/drivers/media/video/tda9840.c index d74b68ae3..8218f466d 100644 --- a/linux/drivers/media/video/tda9840.c +++ b/linux/drivers/media/video/tda9840.c @@ -32,7 +32,7 @@ #include "tda9840.h" -static int debug = 0; /* insmod parameter */ +static int debug; /* insmod parameter */ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) diff --git a/linux/drivers/media/video/tea5761.c b/linux/drivers/media/video/tea5761.c index fd534d9b3..3b96d5354 100644 --- a/linux/drivers/media/video/tea5761.c +++ b/linux/drivers/media/video/tea5761.c @@ -15,7 +15,7 @@ #include "tuner-i2c.h" #include "tea5761.h" -static int debug = 0; +static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable verbose debug messages"); diff --git a/linux/drivers/media/video/tea5767.c b/linux/drivers/media/video/tea5767.c index d830b1a71..a19f0a6a9 100644 --- a/linux/drivers/media/video/tea5767.c +++ b/linux/drivers/media/video/tea5767.c @@ -20,7 +20,7 @@ #include "i2c-compat.h" #endif -static int debug = 0; +static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable verbose debug messages"); diff --git a/linux/drivers/media/video/tea6415c.c b/linux/drivers/media/video/tea6415c.c index 03716e2c9..003fe1edb 100644 --- a/linux/drivers/media/video/tea6415c.c +++ b/linux/drivers/media/video/tea6415c.c @@ -34,7 +34,7 @@ #include "tea6415c.h" -static int debug = 0; /* insmod parameter */ +static int debug; /* insmod parameter */ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) diff --git a/linux/drivers/media/video/tea6420.c b/linux/drivers/media/video/tea6420.c index d8611e213..916794e60 100644 --- a/linux/drivers/media/video/tea6420.c +++ b/linux/drivers/media/video/tea6420.c @@ -34,7 +34,7 @@ #include "tea6420.h" -static int debug = 0; /* insmod parameter */ +static int debug; /* insmod parameter */ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) diff --git a/linux/drivers/media/video/tuner-core.c b/linux/drivers/media/video/tuner-core.c index 99bba6415..209857aef 100644 --- a/linux/drivers/media/video/tuner-core.c +++ b/linux/drivers/media/video/tuner-core.c @@ -79,9 +79,9 @@ static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; I2C_CLIENT_INSMOD; /* insmod options used at init time => read/only */ -static unsigned int addr = 0; -static unsigned int no_autodetect = 0; -static unsigned int show_i2c = 0; +static unsigned int addr; +static unsigned int no_autodetect; +static unsigned int show_i2c; /* insmod options used at runtime => read/write */ static int tuner_debug; diff --git a/linux/drivers/media/video/tvaudio.c b/linux/drivers/media/video/tvaudio.c index 26591c780..fb155de1d 100644 --- a/linux/drivers/media/video/tvaudio.c +++ b/linux/drivers/media/video/tvaudio.c @@ -45,7 +45,7 @@ /* ---------------------------------------------------------------------- */ /* insmod args */ -static int debug = 0; /* insmod parameter */ +static int debug; /* insmod parameter */ module_param(debug, int, 0644); MODULE_DESCRIPTION("device driver for various i2c TV sound decoder / audiomux chips"); @@ -1252,11 +1252,11 @@ static int tda9850 = 1; static int tda9855 = 1; static int tda9873 = 1; static int tda9874a = 1; -static int tea6300 = 0; /* address clash with msp34xx */ -static int tea6320 = 0; /* address clash with msp34xx */ +static int tea6300; /* default 0 - address clash with msp34xx */ +static int tea6320; /* default 0 - address clash with msp34xx */ static int tea6420 = 1; static int pic16c54 = 1; -static int ta8874z = 0; /* address clash with tda9840 */ +static int ta8874z; /* default 0 - address clash with tda9840 */ module_param(tda8425, int, 0444); module_param(tda9840, int, 0444); diff --git a/linux/drivers/media/video/tvp5150.c b/linux/drivers/media/video/tvp5150.c index 1619c5ff3..22fce5d1e 100644 --- a/linux/drivers/media/video/tvp5150.c +++ b/linux/drivers/media/video/tvp5150.c @@ -37,7 +37,7 @@ static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; #endif I2C_CLIENT_INSMOD; -static int debug = 0; +static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); diff --git a/linux/drivers/media/video/usbvideo/ibmcam.c b/linux/drivers/media/video/usbvideo/ibmcam.c index cb907a45c..1261593cf 100644 --- a/linux/drivers/media/video/usbvideo/ibmcam.c +++ b/linux/drivers/media/video/usbvideo/ibmcam.c @@ -121,7 +121,7 @@ static int init_model2_yb = -1; /* 01.01.08 - Added for RCA video in support -LO */ /* Settings for camera model 3 */ -static int init_model3_input = 0; +static int init_model3_input; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)"); diff --git a/linux/drivers/media/video/usbvideo/konicawc.c b/linux/drivers/media/video/usbvideo/konicawc.c index 850034753..539fe984a 100644 --- a/linux/drivers/media/video/usbvideo/konicawc.c +++ b/linux/drivers/media/video/usbvideo/konicawc.c @@ -68,7 +68,7 @@ static int debug; } #else #define DEBUG(n, arg...) -static const int debug = 0; +static const int debug; #endif diff --git a/linux/drivers/media/video/usbvideo/quickcam_messenger.c b/linux/drivers/media/video/usbvideo/quickcam_messenger.c index b32c0b9e3..e2af2d132 100644 --- a/linux/drivers/media/video/usbvideo/quickcam_messenger.c +++ b/linux/drivers/media/video/usbvideo/quickcam_messenger.c @@ -55,7 +55,7 @@ static int debug; } #else #define DEBUG(n, arg...) -static const int debug = 0; +static const int debug; #endif #define DRIVER_VERSION "v0.01" diff --git a/linux/drivers/media/video/usbvideo/ultracam.c b/linux/drivers/media/video/usbvideo/ultracam.c index 9128efa71..bd89e6862 100644 --- a/linux/drivers/media/video/usbvideo/ultracam.c +++ b/linux/drivers/media/video/usbvideo/ultracam.c @@ -28,9 +28,9 @@ typedef struct { static struct usbvideo *cams = NULL; -static int debug = 0; +static int debug; -static int flags = 0; /* FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */ +static int flags; /* FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */ static const int min_canvasWidth = 8; static const int min_canvasHeight = 4; diff --git a/linux/drivers/media/video/usbvideo/usbvideo.c b/linux/drivers/media/video/usbvideo/usbvideo.c index 484628734..f685aca2f 100644 --- a/linux/drivers/media/video/usbvideo/usbvideo.c +++ b/linux/drivers/media/video/usbvideo/usbvideo.c @@ -522,7 +522,7 @@ void usbvideo_TestPattern(struct uvd *uvd, int fullframe, int pmode) struct usbvideo_frame *frame; int num_cell = 0; int scan_length = 0; - static int num_pass = 0; + static int num_pass; if (uvd == NULL) { err("%s: uvd == NULL", __FUNCTION__); diff --git a/linux/drivers/media/video/usbvision/usbvision-core.c b/linux/drivers/media/video/usbvision/usbvision-core.c index fd6f8667e..f3e1cf287 100644 --- a/linux/drivers/media/video/usbvision/usbvision-core.c +++ b/linux/drivers/media/video/usbvision/usbvision-core.c @@ -59,19 +59,21 @@ #include "usbvision.h" -static unsigned int core_debug = 0; +static unsigned int core_debug; module_param(core_debug,int,0644); MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); -static unsigned int force_testpattern = 0; +static unsigned int force_testpattern; module_param(force_testpattern,int,0644); MODULE_PARM_DESC(force_testpattern,"enable test pattern display [core]"); -static int adjustCompression = 1; // Set the compression to be adaptive +static int adjustCompression = 1; /* Set the compression to be adaptive */ module_param(adjustCompression, int, 0444); MODULE_PARM_DESC(adjustCompression, " Set the ADPCM compression for the device. Default: 1 (On)"); -static int SwitchSVideoInput = 0; // To help people with Black and White output with using s-video input. Some cables and input device are wired differently. +/* To help people with Black and White output with using s-video input. + * Some cables and input device are wired differently. */ +static int SwitchSVideoInput; module_param(SwitchSVideoInput, int, 0444); MODULE_PARM_DESC(SwitchSVideoInput, " Set the S-Video input. Some cables and input device are wired differently. Default: 0 (Off)"); @@ -457,7 +459,7 @@ static void usbvision_testpattern(struct usb_usbvision *usbvision, unsigned char *f; int num_cell = 0; int scan_length = 0; - static int num_pass = 0; + static int num_pass; if (usbvision == NULL) { printk(KERN_ERR "%s: usbvision == NULL\n", proc); @@ -1469,7 +1471,7 @@ static int usbvision_compress_isochronous(struct usb_usbvision *usbvision, } #if ENABLE_HEXDUMP if (totlen > 0) { - static int foo = 0; + static int foo; if (foo < 1) { printk(KERN_DEBUG "+%d.\n", usbvision->scratchlen); usbvision_hexdump(data0, (totlen > 64) ? 64 : totlen); diff --git a/linux/drivers/media/video/usbvision/usbvision-i2c.c b/linux/drivers/media/video/usbvision/usbvision-i2c.c index bea5cfb74..15c54121d 100644 --- a/linux/drivers/media/video/usbvision/usbvision-i2c.c +++ b/linux/drivers/media/video/usbvision/usbvision-i2c.c @@ -43,7 +43,7 @@ #define DBG_I2C 1<<0 -static int i2c_debug = 0; +static int i2c_debug; module_param (i2c_debug, int, 0644); // debug_i2c_usb mode of the device driver MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c index 385b4709a..5dc67e90d 100644 --- a/linux/drivers/media/video/usbvision/usbvision-video.c +++ b/linux/drivers/media/video/usbvision/usbvision-video.c @@ -121,7 +121,7 @@ USBVISION_DRIVER_VERSION_PATCHLEVEL) /* sequential number of usbvision device */ -static int usbvision_nr = 0; +static int usbvision_nr; static struct usbvision_v4l2_format_st usbvision_v4l2_format[] = { { 1, 1, 8, V4L2_PIX_FMT_GREY , "GREY" }, @@ -141,7 +141,7 @@ static void usbvision_release(struct usb_usbvision *usbvision); /* Set the default format for ISOC endpoint */ static int isocMode = ISOC_MODE_COMPRESS; /* Set the default Debug Mode of the device driver */ -static int video_debug = 0; +static int video_debug; /* Set the default device to power on at startup */ static int PowerOnAtOpen = 1; /* Sequential Number of Video Device */ diff --git a/linux/drivers/media/video/v4l1-compat.c b/linux/drivers/media/video/v4l1-compat.c index d631a22a3..f37a4008e 100644 --- a/linux/drivers/media/video/v4l1-compat.c +++ b/linux/drivers/media/video/v4l1-compat.c @@ -40,7 +40,7 @@ #endif #include "compat.h" -static unsigned int debug = 0; +static unsigned int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug,"enable debug messages"); MODULE_AUTHOR("Bill Dirks"); diff --git a/linux/drivers/media/video/videobuf-dma-sg.c b/linux/drivers/media/video/videobuf-dma-sg.c index c5f6d22ce..6382954ca 100644 --- a/linux/drivers/media/video/videobuf-dma-sg.c +++ b/linux/drivers/media/video/videobuf-dma-sg.c @@ -40,7 +40,7 @@ #define MAGIC_CHECK(is,should) if (unlikely((is) != (should))) \ { printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); } -static int debug = 0; +static int debug; module_param(debug, int, 0644); MODULE_DESCRIPTION("helper module to manage video4linux pci dma sg buffers"); diff --git a/linux/drivers/media/video/videobuf-dvb.c b/linux/drivers/media/video/videobuf-dvb.c index 9255be2ae..8966a53db 100644 --- a/linux/drivers/media/video/videobuf-dvb.c +++ b/linux/drivers/media/video/videobuf-dvb.c @@ -36,7 +36,7 @@ MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); MODULE_LICENSE("GPL"); -static unsigned int debug = 0; +static unsigned int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug,"enable debug messages"); diff --git a/linux/drivers/media/video/videobuf-vmalloc.c b/linux/drivers/media/video/videobuf-vmalloc.c index 84bb18565..db00a6fdb 100644 --- a/linux/drivers/media/video/videobuf-vmalloc.c +++ b/linux/drivers/media/video/videobuf-vmalloc.c @@ -34,7 +34,7 @@ #define MAGIC_CHECK(is,should) if (unlikely((is) != (should))) \ { printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); } -static int debug = 0; +static int debug; module_param(debug, int, 0644); MODULE_DESCRIPTION("helper module to manage video4linux vmalloc buffers"); diff --git a/linux/drivers/media/video/videocodec.c b/linux/drivers/media/video/videocodec.c index 87951ec82..b30b6b2a9 100644 --- a/linux/drivers/media/video/videocodec.c +++ b/linux/drivers/media/video/videocodec.c @@ -44,7 +44,7 @@ #include "videocodec.h" -static int debug = 0; +static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-4)"); @@ -325,7 +325,7 @@ videocodec_unregister (const struct videocodec *codec) /* ============ */ static char *videocodec_buf = NULL; -static int videocodec_bufsize = 0; +static int videocodec_bufsize; static int videocodec_build_table (void) diff --git a/linux/drivers/media/video/vino.c b/linux/drivers/media/video/vino.c index 94f38ca7c..776edf222 100644 --- a/linux/drivers/media/video/vino.c +++ b/linux/drivers/media/video/vino.c @@ -333,7 +333,7 @@ struct vino_settings { * * Use non-zero value to enable conversion. */ -static int vino_pixel_conversion = 0; +static int vino_pixel_conversion; module_param_named(pixelconv, vino_pixel_conversion, int, 0); @@ -4388,8 +4388,8 @@ static int vino_ioctl(struct inode *inode, struct file *file, /* Initialization and cleanup */ -// __initdata -static int vino_init_stage = 0; +/* __initdata */ +static int vino_init_stage; static const struct file_operations vino_fops = { .owner = THIS_MODULE, @@ -4403,8 +4403,8 @@ static const struct file_operations vino_fops = { static struct video_device v4l_device_template = { .name = "NOT SET", - //.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE | - // VID_TYPE_CLIPPING | VID_TYPE_SCALES, VID_TYPE_OVERLAY + /*.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE | */ + /* VID_TYPE_CLIPPING | VID_TYPE_SCALES, VID_TYPE_OVERLAY */ .fops = &vino_fops, .minor = -1, }; diff --git a/linux/drivers/media/video/vpx3220.c b/linux/drivers/media/video/vpx3220.c index 01f83d285..8a2dca0bb 100644 --- a/linux/drivers/media/video/vpx3220.c +++ b/linux/drivers/media/video/vpx3220.c @@ -41,7 +41,7 @@ #define I2C_VPX3220 0x86 #define VPX3220_DEBUG KERN_DEBUG "vpx3220: " -static int debug = 0; +static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); diff --git a/linux/drivers/media/video/w9966.c b/linux/drivers/media/video/w9966.c index bad59720a..befbaf723 100644 --- a/linux/drivers/media/video/w9966.c +++ b/linux/drivers/media/video/w9966.c @@ -62,7 +62,7 @@ #include #include -//#define DEBUG // Undef me for production +/*#define DEBUG*/ /* Undef me for production */ #ifdef DEBUG #define DPRINTF(x, a...) printk(KERN_DEBUG "W9966: %s(): "x, __FUNCTION__ , ##a) @@ -135,7 +135,7 @@ MODULE_PARM_DESC(pardev, "pardev: where to search for\n\ \tEg: >pardev=parport3,aggressive,parport2,parport1< would assign\n\ \tcam 1 to parport3 and search every parport for cam 2 etc..."); -static int parmode = 0; +static int parmode; module_param(parmode, int, 0); MODULE_PARM_DESC(parmode, "parmode: transfer mode (0=auto, 1=ecp, 2=epp"); diff --git a/linux/drivers/media/video/w9968cf.c b/linux/drivers/media/video/w9968cf.c index 8d3147a2b..e0bfb4270 100644 --- a/linux/drivers/media/video/w9968cf.c +++ b/linux/drivers/media/video/w9968cf.c @@ -3489,7 +3489,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) enum w9968cf_model_id mod_id; struct list_head* ptr; u8 sc = 0; /* number of simultaneous cameras */ - static unsigned short dev_nr = 0; /* we are handling device number n */ + static unsigned short dev_nr; /* 0 - we are handling device number n */ if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[0].idVendor && le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[0].idProduct) diff --git a/linux/drivers/media/video/zc0301/zc0301_core.c b/linux/drivers/media/video/zc0301/zc0301_core.c index e0c206c7c..503bd70ef 100644 --- a/linux/drivers/media/video/zc0301/zc0301_core.c +++ b/linux/drivers/media/video/zc0301/zc0301_core.c @@ -1943,7 +1943,7 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) { struct usb_device *udev = interface_to_usbdev(intf); struct zc0301_device* cam; - static unsigned int dev_nr = 0; + static unsigned int dev_nr; unsigned int i; int err = 0; diff --git a/linux/drivers/media/video/zoran_card.c b/linux/drivers/media/video/zoran_card.c index 979de640b..1ad4ebaef 100644 --- a/linux/drivers/media/video/zoran_card.c +++ b/linux/drivers/media/video/zoran_card.c @@ -86,7 +86,7 @@ MODULE_PARM_DESC(decoder, "i2c TV decoder"); or set in in a VIDIOCSFBUF ioctl */ -static unsigned long vidmem = 0; /* Video memory base address */ +static unsigned long vidmem; /* default = 0 - Video memory base address */ module_param(vidmem, ulong, 0444); MODULE_PARM_DESC(vidmem, "Default video memory base address"); @@ -94,7 +94,7 @@ MODULE_PARM_DESC(vidmem, "Default video memory base address"); Default input and video norm at startup of the driver. */ -static unsigned int default_input = 0; /* 0=Composite, 1=S-Video */ +static unsigned int default_input; /* default 0 = Composite, 1 = S-Video */ module_param(default_input, uint, 0444); MODULE_PARM_DESC(default_input, "Default input (0=Composite, 1=S-Video, 2=Internal)"); @@ -104,7 +104,7 @@ module_param(default_mux, int, 0644); MODULE_PARM_DESC(default_mux, "Default 6 Eyes mux setting (Input selection)"); -static int default_norm = 0; /* 0=PAL, 1=NTSC 2=SECAM */ +static int default_norm; /* default 0 = PAL, 1 = NTSC 2 = SECAM */ module_param(default_norm, int, 0444); MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)"); diff --git a/linux/drivers/media/video/zoran_device.c b/linux/drivers/media/video/zoran_device.c index f7f8e78ec..b7f62ee8a 100644 --- a/linux/drivers/media/video/zoran_device.c +++ b/linux/drivers/media/video/zoran_device.c @@ -61,7 +61,8 @@ extern const struct zoran_format zoran_formats[]; -static int lml33dpath = 0; /* 1 will use digital path in capture +static int lml33dpath; /* default = 0 + * 1 will use digital path in capture * mode instead of analog. It can be * used for picture adjustments using * tool like xawtv while watching image @@ -988,7 +989,7 @@ void zr36057_enable_jpg (struct zoran *zr, enum zoran_codec_mode mode) { - static int zero = 0; + static int zero; static int one = 1; struct vfe_settings cap; int field_size = diff --git a/linux/drivers/media/video/zoran_driver.c b/linux/drivers/media/video/zoran_driver.c index 4fa613703..5f4825dfb 100644 --- a/linux/drivers/media/video/zoran_driver.c +++ b/linux/drivers/media/video/zoran_driver.c @@ -215,7 +215,7 @@ extern int jpg_nbufs; extern int jpg_bufsize; extern int pass_through; -static int lock_norm = 0; /* 1=Don't change TV standard (norm) */ +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)"); diff --git a/linux/drivers/media/video/zr36016.c b/linux/drivers/media/video/zr36016.c index 587ca3fd4..693a648e9 100644 --- a/linux/drivers/media/video/zr36016.c +++ b/linux/drivers/media/video/zr36016.c @@ -56,11 +56,10 @@ #define MAX_CODECS 20 /* amount of chips attached via this driver */ -static int zr36016_codecs = 0; +static int zr36016_codecs; /* debugging is available via module parameter */ - -static int debug = 0; +static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-4)"); diff --git a/linux/drivers/media/video/zr36050.c b/linux/drivers/media/video/zr36050.c index 9f622e00c..44e68d7a8 100644 --- a/linux/drivers/media/video/zr36050.c +++ b/linux/drivers/media/video/zr36050.c @@ -52,11 +52,10 @@ #define MAX_CODECS 20 /* amount of chips attached via this driver */ -static int zr36050_codecs = 0; +static int zr36050_codecs; /* debugging is available via module parameter */ - -static int debug = 0; +static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-4)"); diff --git a/linux/drivers/media/video/zr36060.c b/linux/drivers/media/video/zr36060.c index 1ef14fef0..940055191 100644 --- a/linux/drivers/media/video/zr36060.c +++ b/linux/drivers/media/video/zr36060.c @@ -52,14 +52,14 @@ #define MAX_CODECS 20 /* amount of chips attached via this driver */ -static int zr36060_codecs = 0; +static int zr36060_codecs; -static int low_bitrate = 0; +static int low_bitrate; module_param(low_bitrate, bool, 0); MODULE_PARM_DESC(low_bitrate, "Buz compatibility option, halves bitrate"); /* debugging is available via module parameter */ -static int debug = 0; +static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-4)"); diff --git a/linux/drivers/media/video/zr364xx.c b/linux/drivers/media/video/zr364xx.c index 61d740f57..0afd1c9c1 100644 --- a/linux/drivers/media/video/zr364xx.c +++ b/linux/drivers/media/video/zr364xx.c @@ -63,8 +63,8 @@ /* Module parameters */ -static int debug = 0; -static int mode = 0; +static int debug; +static int mode; /* Module parameters interface */ -- cgit v1.2.3 From e183b1318d624a8c124c0f9ff44a82c2012b8201 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Jan 2008 10:01:11 -0200 Subject: saa7134-dvb: add missing dvb_attach call (for tda10046_attach) From: Matthias Schwarzott saa7134-dvb: add missing dvb_attach around tda10046_attach This patch adds a possibly missing dvb_attach for tda10046_attach. This removes the hard dependency of saa7134-dvb on tda1004x module. Signed-off-by: Matthias Schwarzott Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-dvb.c | 5 +++-- linux/drivers/media/video/v4l2-common.c | 18 ++++++------------ 2 files changed, 9 insertions(+), 14 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7134/saa7134-dvb.c b/linux/drivers/media/video/saa7134/saa7134-dvb.c index 3521548f3..02a4f7dbd 100644 --- a/linux/drivers/media/video/saa7134/saa7134-dvb.c +++ b/linux/drivers/media/video/saa7134/saa7134-dvb.c @@ -1022,8 +1022,9 @@ static int dvb_init(struct saa7134_dev *dev) } break; case SAA7134_BOARD_ASUS_EUROPA2_HYBRID: - dev->dvb.frontend = tda10046_attach(&medion_cardbus, - &dev->i2c_adap); + dev->dvb.frontend = dvb_attach(tda10046_attach, + &medion_cardbus, + &dev->i2c_adap); if (dev->dvb.frontend) { dev->original_demod_sleep = dev->dvb.frontend->ops.sleep; dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep; diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index 04477421b..690f9059c 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -1585,6 +1585,7 @@ u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id) return **ctrl_classes; } +#ifdef CONFIG_I2C int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_chip) { switch (match_type) { @@ -1596,6 +1597,7 @@ int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_c return 0; } } +EXPORT_SYMBOL(v4l2_chip_match_i2c_client); int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chip, u32 ident, u32 revision) @@ -1612,6 +1614,7 @@ int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chi } return 0; } +EXPORT_SYMBOL(v4l2_chip_ident_i2c_client); int v4l2_chip_match_host(u32 match_type, u32 match_chip) { @@ -1622,6 +1625,7 @@ int v4l2_chip_match_host(u32 match_type, u32 match_chip) return 0; } } +EXPORT_SYMBOL(v4l2_chip_match_host); /* ----------------------------------------------------------------- */ @@ -1656,6 +1660,8 @@ int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver } return err != -ENOMEM ? 0 : err; } +EXPORT_SYMBOL(v4l2_i2c_attach); +#endif /* ----------------------------------------------------------------- */ @@ -1679,15 +1685,3 @@ EXPORT_SYMBOL(v4l2_ctrl_get_menu); EXPORT_SYMBOL(v4l2_ctrl_query_menu); EXPORT_SYMBOL(v4l2_ctrl_query_fill); EXPORT_SYMBOL(v4l2_ctrl_query_fill_std); - -EXPORT_SYMBOL(v4l2_chip_match_i2c_client); -EXPORT_SYMBOL(v4l2_chip_ident_i2c_client); -EXPORT_SYMBOL(v4l2_chip_match_host); - -EXPORT_SYMBOL(v4l2_i2c_attach); - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ -- cgit v1.2.3 From 84a4158b0160301a2d062591b86a6a33bdac2893 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Jan 2008 18:42:38 -0200 Subject: Partially revert changeset 7097:ed7daeb29425 From: Mauro Carvalho Chehab An experimental, incomplete changeset were committed by mistake. Reverting it. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/v4l2-common.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index 690f9059c..04477421b 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -1585,7 +1585,6 @@ u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id) return **ctrl_classes; } -#ifdef CONFIG_I2C int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_chip) { switch (match_type) { @@ -1597,7 +1596,6 @@ int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_c return 0; } } -EXPORT_SYMBOL(v4l2_chip_match_i2c_client); int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chip, u32 ident, u32 revision) @@ -1614,7 +1612,6 @@ int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chi } return 0; } -EXPORT_SYMBOL(v4l2_chip_ident_i2c_client); int v4l2_chip_match_host(u32 match_type, u32 match_chip) { @@ -1625,7 +1622,6 @@ int v4l2_chip_match_host(u32 match_type, u32 match_chip) return 0; } } -EXPORT_SYMBOL(v4l2_chip_match_host); /* ----------------------------------------------------------------- */ @@ -1660,8 +1656,6 @@ int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver } return err != -ENOMEM ? 0 : err; } -EXPORT_SYMBOL(v4l2_i2c_attach); -#endif /* ----------------------------------------------------------------- */ @@ -1685,3 +1679,15 @@ EXPORT_SYMBOL(v4l2_ctrl_get_menu); EXPORT_SYMBOL(v4l2_ctrl_query_menu); EXPORT_SYMBOL(v4l2_ctrl_query_fill); EXPORT_SYMBOL(v4l2_ctrl_query_fill_std); + +EXPORT_SYMBOL(v4l2_chip_match_i2c_client); +EXPORT_SYMBOL(v4l2_chip_ident_i2c_client); +EXPORT_SYMBOL(v4l2_chip_match_host); + +EXPORT_SYMBOL(v4l2_i2c_attach); + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ -- cgit v1.2.3 From 31dc32b2283a00f1f7a343c9aa31701c848254e1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Jan 2008 22:11:15 +0000 Subject: make tuner-core.c:tuner_list static From: Adrian Bunk tuner_list can become static - and it's anyway a way too generic name for a global variable - see commit b00ef4b8d8c29bfb5f6f92ee60bc04b604f36ef2 for a completely different global variable of the same name I just made static... Signed-off-by: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/tuner-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tuner-core.c b/linux/drivers/media/video/tuner-core.c index 209857aef..95bb41cee 100644 --- a/linux/drivers/media/video/tuner-core.c +++ b/linux/drivers/media/video/tuner-core.c @@ -1082,7 +1082,7 @@ static int tuner_resume(struct i2c_client *c) /* ---------------------------------------------------------------------- */ -LIST_HEAD(tuner_list); +static LIST_HEAD(tuner_list); /* Search for existing radio and/or TV tuners on the given I2C adapter. Note that when this function is called from tuner_probe you can be -- cgit v1.2.3 From 4a636593b1830d9139b97e94dca6ce60b95fd2c4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Jan 2008 22:11:01 +0000 Subject: make stk_camera_cleanup() static From: Adrian Bunk stk_camera_cleanup() can become static. Signed-off-by: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/stk-webcam.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/stk-webcam.c b/linux/drivers/media/video/stk-webcam.c index 1c64afe71..589b6aec9 100644 --- a/linux/drivers/media/video/stk-webcam.c +++ b/linux/drivers/media/video/stk-webcam.c @@ -64,7 +64,7 @@ static struct usb_device_id stkwebcam_table[] = { }; MODULE_DEVICE_TABLE(usb, stkwebcam_table); -void stk_camera_cleanup(struct kref *kref) +static void stk_camera_cleanup(struct kref *kref) { struct stk_camera *dev = to_stk_camera(kref); -- cgit v1.2.3 From 5e06720c8034b2f065cfccb91538f37de78e08bb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Jan 2008 22:10:58 +0000 Subject: stk-sensor.c: make 2 functions static From: Adrian Bunk This patch makes the following needlessly global functions static: - stk_sensor_outb() - stk_sensor_inb() Signed-off-by: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/stk-sensor.c | 4 ++-- linux/drivers/media/video/stk-webcam.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/stk-sensor.c b/linux/drivers/media/video/stk-sensor.c index 1a8692d9e..e546b014d 100644 --- a/linux/drivers/media/video/stk-sensor.c +++ b/linux/drivers/media/video/stk-sensor.c @@ -225,7 +225,7 @@ /* Returns 0 if OK */ -int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val) +static int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val) { int i = 0; int tmpval = 0; @@ -250,7 +250,7 @@ int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val) return 0; } -int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val) +static int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val) { int i = 0; int tmpval = 0; diff --git a/linux/drivers/media/video/stk-webcam.h b/linux/drivers/media/video/stk-webcam.h index a2164cb1a..df4dfefc5 100644 --- a/linux/drivers/media/video/stk-webcam.h +++ b/linux/drivers/media/video/stk-webcam.h @@ -128,8 +128,6 @@ void stk_camera_delete(struct kref *); int stk_camera_write_reg(struct stk_camera *, u16, u8); int stk_camera_read_reg(struct stk_camera *, u16, int *); -int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val); -int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val); int stk_sensor_init(struct stk_camera *); int stk_sensor_configure(struct stk_camera *); int stk_sensor_sleep(struct stk_camera *dev); -- cgit v1.2.3 From 61b878bfbc2968d20a75904fe87ccd6151822180 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Jan 2008 22:10:53 +0000 Subject: ivtv-yuv.c: make 3 functions static From: Adrian Bunk This patch makes the following needlessly global functions static: - ivtv_yuv_next_free() - ivtv_yuv_setup_frame() - ivtv_yuv_udma_frame() Signed-off-by: Adrian Bunk Reviewed-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/ivtv/ivtv-yuv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/ivtv/ivtv-yuv.c b/linux/drivers/media/video/ivtv/ivtv-yuv.c index 85183480a..8fdd67cef 100644 --- a/linux/drivers/media/video/ivtv/ivtv-yuv.c +++ b/linux/drivers/media/video/ivtv/ivtv-yuv.c @@ -914,7 +914,7 @@ static void ivtv_yuv_init(struct ivtv *itv) } /* Get next available yuv buffer on PVR350 */ -void ivtv_yuv_next_free(struct ivtv *itv) +static void ivtv_yuv_next_free(struct ivtv *itv) { int draw, display; struct yuv_playback_info *yi = &itv->yuv_info; @@ -937,7 +937,7 @@ void ivtv_yuv_next_free(struct ivtv *itv) } /* Set up frame according to ivtv_dma_frame parameters */ -void ivtv_yuv_setup_frame(struct ivtv *itv, struct ivtv_dma_frame *args) +static void ivtv_yuv_setup_frame(struct ivtv *itv, struct ivtv_dma_frame *args) { struct yuv_playback_info *yi = &itv->yuv_info; u8 frame = yi->draw_frame; @@ -1042,7 +1042,7 @@ void ivtv_yuv_frame_complete(struct ivtv *itv) (itv->yuv_info.draw_frame + 1) % IVTV_YUV_BUFFERS); } -int ivtv_yuv_udma_frame(struct ivtv *itv, struct ivtv_dma_frame *args) +static int ivtv_yuv_udma_frame(struct ivtv *itv, struct ivtv_dma_frame *args) { DEFINE_WAIT(wait); int rc = 0; -- cgit v1.2.3 From 82fd525e0cfcc67834036ebf3ab7ff1503450d4c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Jan 2008 22:10:48 +0000 Subject: em28xx/: make 2 functions static From: Adrian Bunk This patch makes the following needlessly global functions static: - em28xx-core.c:em28xx_write_reg_bits() - em28xx-video.c:em28xx_vdev_init() Signed-off-by: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-core.c | 2 +- linux/drivers/media/video/em28xx/em28xx-video.c | 8 ++++---- linux/drivers/media/video/em28xx/em28xx.h | 2 -- 3 files changed, 5 insertions(+), 7 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c index 7a15a69fb..a0ec1cfbc 100644 --- a/linux/drivers/media/video/em28xx/em28xx-core.c +++ b/linux/drivers/media/video/em28xx/em28xx-core.c @@ -288,7 +288,7 @@ int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len) * sets only some bits (specified by bitmask) of a register, by first reading * the actual value */ -int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, +static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, u8 bitmask) { int oldval; diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index 284b385fb..7af56469e 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -1871,10 +1871,10 @@ void em28xx_unregister_extension(struct em28xx_ops *ops) } EXPORT_SYMBOL(em28xx_unregister_extension); -struct video_device *em28xx_vdev_init(struct em28xx *dev, - const struct video_device *template, - const int type, - const char *type_name) +static struct video_device *em28xx_vdev_init(struct em28xx *dev, + const struct video_device *template, + const int type, + const char *type_name) { struct video_device *vfd; diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index efabaf6d1..2a797f622 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -360,8 +360,6 @@ int em28xx_read_reg(struct em28xx *dev, u16 reg); int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, int len); int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len); -int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, - u8 bitmask); int em28xx_set_audio_source(struct em28xx *dev); int em28xx_audio_analog_set(struct em28xx *dev); -- cgit v1.2.3 From 721d7a5bbbe35a229007ca71acd9eb2276439b14 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Jan 2008 22:10:31 +0000 Subject: frontends/xc5000.c: make a struct static From: Adrian Bunk struct XC5000_Standard[] can become static. Signed-off-by: Adrian Bunk Reviewed-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/xc5000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/xc5000.c b/linux/drivers/media/dvb/frontends/xc5000.c index 58235d007..e50924d97 100644 --- a/linux/drivers/media/dvb/frontends/xc5000.c +++ b/linux/drivers/media/dvb/frontends/xc5000.c @@ -151,7 +151,7 @@ typedef struct { #define FM_Radio_INPUT2 21 #define FM_Radio_INPUT1 22 -XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { +static XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020}, {"M/N-NTSC/PAL-A2", 0x0600, 0x8020}, {"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020}, -- cgit v1.2.3 From 246715c1c023301500e19fa1fcb3ffdd67937963 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Jan 2008 22:12:41 +0000 Subject: frontends/tda18271-common.c: fix off-by-one From: Adrian Bunk This patch fixes an off-by-one error spotted by the Coverity checker. Signed-off-by: Adrian Bunk Reviewed-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/tda18271-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/tda18271-common.c b/linux/drivers/media/dvb/frontends/tda18271-common.c index 6dfabc5a5..acb9dd4ee 100644 --- a/linux/drivers/media/dvb/frontends/tda18271-common.c +++ b/linux/drivers/media/dvb/frontends/tda18271-common.c @@ -171,7 +171,7 @@ int tda18271_read_extended(struct dvb_frontend *fe) if (ret != 2) tda_err("ERROR: i2c_transfer returned: %d\n", ret); - for (i = 0; i <= TDA18271_NUM_REGS; i++) { + for (i = 0; i < TDA18271_NUM_REGS; i++) { /* don't update write-only registers */ if ((i != R_EB9) && (i != R_EB16) && -- cgit v1.2.3 From 385578235efd5f637ce504f497c112c341866a89 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Jan 2008 22:11:19 +0000 Subject: tuner-xc2028.c: make a function static From: Adrian Bunk dump_firm_type_and_int_freq() can become static. Signed-off-by: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/tuner-xc2028.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tuner-xc2028.c b/linux/drivers/media/video/tuner-xc2028.c index 1700b97ea..e7ae8c40f 100644 --- a/linux/drivers/media/video/tuner-xc2028.c +++ b/linux/drivers/media/video/tuner-xc2028.c @@ -160,7 +160,7 @@ static unsigned int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val) } #define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0) -void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq) +static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq) { if (type & BASE) printk("BASE "); @@ -770,10 +770,12 @@ skip_std_specific: } /* Load SCODE firmware, if exists */ - tuner_dbg("Trying to load scode %d\n", new_fw.scode_nr); + if (!new_fw.type & FM) { + tuner_dbg("Trying to load scode %d\n", new_fw.scode_nr); - rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id, - new_fw.int_freq, new_fw.scode_nr); + rc = load_scode(fe, new_fw.type | new_fw.scode_table, + &new_fw.id, new_fw.int_freq, new_fw.scode_nr); + } check_device: if (xc2028_get_reg(priv, 0x0004, &version) < 0 || -- cgit v1.2.3 From a2f115b3bfacbf8b8a22bca80413eb1ae997a18b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Jan 2008 22:43:13 +0000 Subject: radio-si470x.c: check-after-use From: Tobias Lorenz Adrian used the coverity checker against radio-si470x and found this: > The Coverity checker spotted the following check-after-use in > drivers/media/radio/radio-si470x.c: > > <-- snip --> > static void si470x_usb_driver_disconnect(struct usb_interface *intf) > { > struct si470x_device *radio = usb_get_intfdata(intf); > > del_timer_sync(&radio->timer); <------------------ > flush_scheduled_work(); > > usb_set_intfdata(intf, NULL); > if (radio) { <------------------ > video_unregister_device(radio->videodev); > kfree(radio->buffer); > kfree(radio); > } > } > <-- snip --> > > Either "radio" can be NULL and this case has to be properly handled or > the NULL check is not required. These two lines should indeed better be inside the if statement. Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/radio-si470x.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index ed64929dc..0448166ce 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -1440,11 +1440,10 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf) { struct si470x_device *radio = usb_get_intfdata(intf); - del_timer_sync(&radio->timer); - flush_scheduled_work(); - usb_set_intfdata(intf, NULL); if (radio) { + del_timer_sync(&radio->timer); + flush_scheduled_work(); video_unregister_device(radio->videodev); kfree(radio->buffer); kfree(radio); -- cgit v1.2.3 From 9f8c7fb32ee08eddf2358086aef0aa40b0f16b44 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Jan 2008 22:49:14 +0000 Subject: Trivial printf warning fix (radio-si470) From: Tobias Lorenz Thanks to Darren Salt for pointing this issue. Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/radio-si470x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index 0448166ce..7be7b0916 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -559,7 +559,7 @@ static int si470x_get_rds_registers(struct si470x_device *radio) (void *) &buf, sizeof(buf), &size, usb_timeout); if (size != sizeof(buf)) printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_register: " - "return size differs: %d != %d\n", size, sizeof(buf)); + "return size differs: %d != %ld\n", size, sizeof(buf)); if (retval < 0) printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: " "usb_interrupt_msg returned %d\n", retval); -- cgit v1.2.3 From 3856cfc66c20f6900f59a524c0b1a907a12e101b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 29 Jan 2008 09:55:54 -0200 Subject: changeset 5b83176312cc got mangled by an experimental change From: Mauro Carvalho Chehab Reverting the changeset. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/tuner-xc2028.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tuner-xc2028.c b/linux/drivers/media/video/tuner-xc2028.c index e7ae8c40f..1700b97ea 100644 --- a/linux/drivers/media/video/tuner-xc2028.c +++ b/linux/drivers/media/video/tuner-xc2028.c @@ -160,7 +160,7 @@ static unsigned int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val) } #define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0) -static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq) +void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq) { if (type & BASE) printk("BASE "); @@ -770,12 +770,10 @@ skip_std_specific: } /* Load SCODE firmware, if exists */ - if (!new_fw.type & FM) { - tuner_dbg("Trying to load scode %d\n", new_fw.scode_nr); + tuner_dbg("Trying to load scode %d\n", new_fw.scode_nr); - rc = load_scode(fe, new_fw.type | new_fw.scode_table, - &new_fw.id, new_fw.int_freq, new_fw.scode_nr); - } + rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id, + new_fw.int_freq, new_fw.scode_nr); check_device: if (xc2028_get_reg(priv, 0x0004, &version) < 0 || -- cgit v1.2.3 From 2329b257936fc4fac065abf560327406469bbb57 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Jan 2008 22:11:19 +0000 Subject: tuner-xc2028.c: make a function static From: Adrian Bunk dump_firm_type_and_int_freq() can become static. Signed-off-by: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/tuner-xc2028.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tuner-xc2028.c b/linux/drivers/media/video/tuner-xc2028.c index 1700b97ea..9aed0aabb 100644 --- a/linux/drivers/media/video/tuner-xc2028.c +++ b/linux/drivers/media/video/tuner-xc2028.c @@ -160,7 +160,7 @@ static unsigned int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val) } #define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0) -void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq) +static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq) { if (type & BASE) printk("BASE "); -- cgit v1.2.3 From 7913005c82ce9ebc130fb4e39927e6f4965e62da Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 29 Jan 2008 16:32:35 -0200 Subject: Fix bug #9833: regression when compiling V4L without I2C From: Mauro Carvalho Chehab Adrian Bunk reported: > > Commit 8ffbc6559493c64d6194c92d856196fdaeb8a5fb causes the following > > compile error with CONFIG_VIDEO_DEV=y/m, CONFIG_I2C=n: > > > > <-- snip --> > > > > ... > > MODPOST 26 modules > > ERROR: "i2c_attach_client" [drivers/media/video/v4l2-common.ko] undefined! > > make[2]: *** [__modpost] Error 1 > > > > <-- snip --> ... And what should happen if CONFIG_VIDEO_DEV=y, CONFIG_I2C=m? CC: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/Kconfig | 5 +++++ linux/drivers/media/video/Makefile | 5 +++-- linux/drivers/media/video/v4l2-common.c | 38 ++++++++++++++------------------- 3 files changed, 24 insertions(+), 24 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/Kconfig b/linux/drivers/media/Kconfig index 8f4a45346..707b20d7e 100644 --- a/linux/drivers/media/Kconfig +++ b/linux/drivers/media/Kconfig @@ -25,6 +25,11 @@ config VIDEO_DEV To compile this driver as a module, choose M here: the module will be called videodev. +config VIDEO_V4L2_COMMON + tristate + depends on (I2C || I2C=n) && VIDEO_DEV + default (I2C || I2C=n) && VIDEO_DEV + config VIDEO_V4L1 bool "Enable Video For Linux API 1 (DEPRECATED)" depends on VIDEO_DEV diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index 28ddd146c..991f8de0a 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -10,8 +10,9 @@ msp3400-objs := msp3400-driver.o msp3400-kthreads.o stkwebcam-objs := stk-webcam.o stk-sensor.o -obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o compat_ioctl32.o \ - v4l2-int-device.o +obj-$(CONFIG_VIDEO_DEV) += videodev.o compat_ioctl32.o v4l2-int-device.o + +obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y) obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index 04477421b..ba1925401 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -1585,6 +1585,18 @@ u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id) return **ctrl_classes; } +int v4l2_chip_match_host(u32 match_type, u32 match_chip) +{ + switch (match_type) { + case V4L2_CHIP_MATCH_HOST: + return match_chip == 0; + default: + return 0; + } +} +EXPORT_SYMBOL(v4l2_chip_match_host); + +#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_chip) { switch (match_type) { @@ -1596,6 +1608,7 @@ int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_c return 0; } } +EXPORT_SYMBOL(v4l2_chip_match_i2c_client); int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chip, u32 ident, u32 revision) @@ -1612,16 +1625,7 @@ int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chi } return 0; } - -int v4l2_chip_match_host(u32 match_type, u32 match_chip) -{ - switch (match_type) { - case V4L2_CHIP_MATCH_HOST: - return match_chip == 0; - default: - return 0; - } -} +EXPORT_SYMBOL(v4l2_chip_ident_i2c_client); /* ----------------------------------------------------------------- */ @@ -1656,6 +1660,8 @@ int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver } return err != -ENOMEM ? 0 : err; } +EXPORT_SYMBOL(v4l2_i2c_attach); +#endif /* ----------------------------------------------------------------- */ @@ -1679,15 +1685,3 @@ EXPORT_SYMBOL(v4l2_ctrl_get_menu); EXPORT_SYMBOL(v4l2_ctrl_query_menu); EXPORT_SYMBOL(v4l2_ctrl_query_fill); EXPORT_SYMBOL(v4l2_ctrl_query_fill_std); - -EXPORT_SYMBOL(v4l2_chip_match_i2c_client); -EXPORT_SYMBOL(v4l2_chip_ident_i2c_client); -EXPORT_SYMBOL(v4l2_chip_match_host); - -EXPORT_SYMBOL(v4l2_i2c_attach); - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ -- cgit v1.2.3 From db355240b0a966e4db76906427a1ec5db89ae3fd Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Wed, 30 Jan 2008 00:56:51 +0100 Subject: budget-av: Add support for KNC TV Station Plus X4 From: Oliver Endriss Add support for KNC TV Station Plus X4, sub-system id 0x1894:0x0015. Based on a patch submitted by Johannes Deisenhofer. Signed-off-by: Oliver Endriss Thanks-to: Johannes Deisenhofer --- linux/drivers/media/dvb/ttpci/budget-av.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/dvb/ttpci/budget-av.c b/linux/drivers/media/dvb/ttpci/budget-av.c index 3439c9864..15fa88a17 100644 --- a/linux/drivers/media/dvb/ttpci/budget-av.c +++ b/linux/drivers/media/dvb/ttpci/budget-av.c @@ -896,6 +896,7 @@ static u8 read_pwm(struct budget_av *budget_av) #define SUBID_DVBS_CINERGY1200 0x1154 #define SUBID_DVBS_CYNERGY1200N 0x1155 #define SUBID_DVBS_TV_STAR 0x0014 +#define SUBID_DVBS_TV_STAR_PLUS_X4 0x0015 #define SUBID_DVBS_TV_STAR_CI 0x0016 #define SUBID_DVBS_EASYWATCH_1 0x001a #define SUBID_DVBS_EASYWATCH_2 0x001b @@ -957,6 +958,7 @@ static void frontend_init(struct budget_av *budget_av) break; case SUBID_DVBS_TV_STAR: + case SUBID_DVBS_TV_STAR_PLUS_X4: case SUBID_DVBS_TV_STAR_CI: case SUBID_DVBS_CYNERGY1200N: case SUBID_DVBS_EASYWATCH: @@ -1249,6 +1251,7 @@ MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S); MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP); MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3); MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); +MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP); MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3); MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3); @@ -1266,6 +1269,7 @@ static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011), MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011), MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014), + MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015), MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016), MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a), -- cgit v1.2.3 From c810210ce076544a4e6d34ad44ad9adf8132f349 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Wed, 30 Jan 2008 01:42:01 +0100 Subject: budget-av: Add support for Satelco EasyWatch PCI DVB-T From: Kim Sandberg Add support for Satelco EasyWatch PCI DVB-T, sub-id 0x1894:0x003a. Signed-off-by: Kim Sandberg Signed-off-by: Oliver Endriss --- linux/drivers/media/dvb/ttpci/budget-av.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/dvb/ttpci/budget-av.c b/linux/drivers/media/dvb/ttpci/budget-av.c index 15fa88a17..2d64d557b 100644 --- a/linux/drivers/media/dvb/ttpci/budget-av.c +++ b/linux/drivers/media/dvb/ttpci/budget-av.c @@ -911,6 +911,7 @@ static u8 read_pwm(struct budget_av *budget_av) #define SUBID_DVBC_CINERGY1200 0x1156 #define SUBID_DVBC_CINERGY1200_MK3 0x1176 +#define SUBID_DVBT_EASYWATCH 0x003a #define SUBID_DVBT_KNC1_PLUS 0x0031 #define SUBID_DVBT_KNC1 0x0030 #define SUBID_DVBT_CINERGY1200 0x1157 @@ -1020,6 +1021,7 @@ static void frontend_init(struct budget_av *budget_av) } break; + case SUBID_DVBT_EASYWATCH: case SUBID_DVBT_KNC1: case SUBID_DVBT_KNC1_PLUS: case SUBID_DVBT_CINERGY1200: @@ -1250,6 +1252,7 @@ MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S); MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S); MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP); MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3); +MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T); MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP); MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); @@ -1276,6 +1279,7 @@ static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b), MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a), MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c), + MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a), MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022), -- cgit v1.2.3 From 21d49a20ae5f4bf8ad0a1e692ac07336a8ee8c95 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Wed, 30 Jan 2008 02:07:20 +0100 Subject: dvb-ttpci: Improved display of still pictures From: Oliver Endriss Improved display of still pictures (VIDEO_STILLPICTURE ioctl). Ensure that both fields are displayed for progressive frames. Thanks to Reinhard Nissl and Klaus Schmidinger for finding out that the FREEZE command does this. Signed-off-by: Oliver Endriss Thanks-to: Reinhard Nissl Thanks-to: Klaus Schmidinger --- linux/drivers/media/dvb/ttpci/av7110_av.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/ttpci/av7110_av.c b/linux/drivers/media/dvb/ttpci/av7110_av.c index aef6e36d7..3e6b650fb 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_av.c +++ b/linux/drivers/media/dvb/ttpci/av7110_av.c @@ -966,6 +966,7 @@ static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock) { int i, n; + int progressive = 0; dprintk(2, "av7110:%p, \n", av7110); @@ -974,6 +975,14 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len return -EBUSY; } + for (i = 0; i < len - 5; i++) { + /* get progressive flag from picture extension */ + if (buf[i] == 0x00 && buf[i+1] == 0x00 && + buf[i+2] == 0x01 && (unsigned char)buf[i+3] == 0xb5 && + (buf[i+4] & 0xf0) == 0x10) + progressive = buf[i+5] & 0x08; + } + /* setting n always > 1, fixes problems when playing stillframes consisting of I- and P-Frames */ n = MIN_IFRAME / len + 1; @@ -985,7 +994,11 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len dvb_play(av7110, buf, len, 0, 1); av7110_ipack_flush(&av7110->ipack[1]); - return 0; + + if (progressive) + return vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1); + else + return 0; } -- cgit v1.2.3 From ff34055d31f6ecce43c9d4d3747b496b8a039b02 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 31 Jan 2008 11:15:52 -0200 Subject: Remove obsolete code from v4l2-common From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/v4l2-common.c | 617 -------------------------------- linux/include/media/v4l2-common.h | 3 - 2 files changed, 620 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index ba1925401..cd52fbda2 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -82,21 +82,6 @@ MODULE_LICENSE("GPL"); * Video Standard Operations (contributed by Michael Schimek) */ -#if 0 /* seems to have no users */ -/* This is the recommended method to deal with the framerate fields. More - sophisticated drivers will access the fields directly. */ -unsigned int -v4l2_video_std_fps(struct v4l2_standard *vs) -{ - if (vs->frameperiod.numerator > 0) - return (((vs->frameperiod.denominator << 8) / - vs->frameperiod.numerator) + - (1 << 7)) / (1 << 8); - return 0; -} -EXPORT_SYMBOL(v4l2_video_std_fps); -#endif - char *v4l2_norm_to_name(v4l2_std_id id) { char *name; @@ -285,16 +270,6 @@ char *v4l2_type_names[] = { [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over", }; -#if 0 -static char *v4l2_memory_names[] = { - [V4L2_MEMORY_MMAP] = "mmap", - [V4L2_MEMORY_USERPTR] = "userptr", - [V4L2_MEMORY_OVERLAY] = "overlay", -}; -#endif /* 0 */ - -#define prt_names(a,arr) (((a)>=0)&&((a)width,fmt->height, - fmt->pixelformat&0xff, (fmt->pixelformat>>8)&0xff, - (fmt->pixelformat>>16)&0xff, (fmt->pixelformat>>24)&0xff, - prt_names(fmt->field,v4l2_field_names), - fmt->bytesperline,fmt->sizeimage,fmt->colorspace); -}; -#endif /* 0 */ - /* Common ioctl debug function. This function can be used by external ioctl messages as well as internal V4L ioctl */ void v4l_printk_ioctl(unsigned int cmd) @@ -494,585 +456,6 @@ void v4l_printk_ioctl(unsigned int cmd) } } -#if 0 -/* Common ioctl debug function. This function can be used by - external ioctl messages as well as internal V4L ioctl and its - arguments */ -void v4l_printk_ioctl_arg(const char *s, unsigned int cmd, const void *arg) -{ - printk("%s: ", s); - v4l_printk_ioctl(cmd); - switch (cmd) { - case VIDIOC_G_CHIP_IDENT: - { - const struct v4l2_chip_ident *p=arg; - printk("%s: chip_ident=%u, revision = 0x%x\n", s, - p->ident, p->revision); - break; - } - case VIDIOC_G_PRIORITY: - case VIDIOC_S_PRIORITY: - { - const enum v4l2_priority *p=arg; - printk ("%s: priority=%d\n", s, *p); - break; - } - case VIDIOC_INT_S_TUNER_MODE: - { - const enum v4l2_tuner_type *p=arg; - printk ("%s: tuner type=%d\n", s, *p); - break; - } -#ifdef CONFIG_VIDEO_V4L1_COMPAT - case DECODER_SET_VBI_BYPASS: - case DECODER_ENABLE_OUTPUT: - case DECODER_GET_STATUS: - case DECODER_SET_OUTPUT: - case DECODER_SET_INPUT: - case DECODER_SET_GPIO: - case DECODER_SET_NORM: - case VIDIOCCAPTURE: - case VIDIOCSYNC: - case VIDIOCSWRITEMODE: -#endif - case TUNER_SET_TYPE_ADDR: - case TUNER_SET_STANDBY: -#ifdef __OLD_VIDIOC_ - case VIDIOC_OVERLAY_OLD: -#endif - case VIDIOC_STREAMOFF: - case VIDIOC_G_OUTPUT: - case VIDIOC_S_OUTPUT: - case VIDIOC_STREAMON: - case VIDIOC_G_INPUT: - case VIDIOC_OVERLAY: - case VIDIOC_S_INPUT: - { - const int *p=arg; - printk ("%s: value=%d\n", s, *p); - break; - } - case TUNER_SET_CONFIG: - { - const struct v4l2_priv_tun_config *p = arg; - - printk("%s: tuner=%d, config=%p\n", s, p->tuner, p->priv); - break; - } - case VIDIOC_G_AUDIO: - case VIDIOC_S_AUDIO: - case VIDIOC_ENUMAUDIO: -#ifdef __OLD_VIDIOC_ - case VIDIOC_G_AUDIO_OLD: -#endif - { - const struct v4l2_audio *p=arg; - - printk ("%s: index=%d, name=%s, capability=%d, mode=%d\n", - s,p->index, p->name,p->capability, p->mode); - break; - } - case VIDIOC_G_AUDOUT: - case VIDIOC_S_AUDOUT: - case VIDIOC_ENUMAUDOUT: -#ifdef __OLD_VIDIOC_ - case VIDIOC_G_AUDOUT_OLD: -#endif - { - const struct v4l2_audioout *p=arg; - printk ("%s: index=%d, name=%s, capability=%d, mode=%d\n", s, - p->index, p->name, p->capability,p->mode); - break; - } - case VIDIOC_QBUF: - case VIDIOC_DQBUF: - case VIDIOC_QUERYBUF: - { - const struct v4l2_buffer *p=arg; - const struct v4l2_timecode *tc=&p->timecode; - printk ("%s: %02ld:%02d:%02d.%08ld index=%d, type=%s, " - "bytesused=%d, flags=0x%08x, " - "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx\n", - s, - (p->timestamp.tv_sec/3600), - (int)(p->timestamp.tv_sec/60)%60, - (int)(p->timestamp.tv_sec%60), - p->timestamp.tv_usec, - p->index, - prt_names(p->type,v4l2_type_names), - p->bytesused,p->flags, - p->field,p->sequence, - prt_names(p->memory,v4l2_memory_names), - p->m.userptr); - printk ("%s: timecode= %02d:%02d:%02d type=%d, " - "flags=0x%08x, frames=%d, userbits=0x%08x\n", - s,tc->hours,tc->minutes,tc->seconds, - tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits); - break; - } - case VIDIOC_QUERYCAP: - { - const struct v4l2_capability *p=arg; - printk ("%s: driver=%s, card=%s, bus=%s, version=0x%08x, " - "capabilities=0x%08x\n", s, - p->driver,p->card,p->bus_info, - p->version, - p->capabilities); - break; - } - case VIDIOC_G_CTRL: - case VIDIOC_S_CTRL: -#ifdef __OLD_VIDIOC_ - case VIDIOC_S_CTRL_OLD: -#endif - { - const struct v4l2_control *p=arg; - printk ("%s: id=%d, value=%d\n", s, p->id, p->value); - break; - } - case VIDIOC_G_EXT_CTRLS: - case VIDIOC_S_EXT_CTRLS: - case VIDIOC_TRY_EXT_CTRLS: - { - const struct v4l2_ext_controls *p = arg; - int i; - - printk("%s: ctrl_class=%d, count=%d\n", s, p->ctrl_class, p->count); - for (i = 0; i < p->count; i++) { - struct v4l2_ext_control *c = &p->controls[i]; - if (cmd == VIDIOC_G_EXT_CTRLS) - printk("%s: id=%d\n", s, c->id); - else - printk("%s: id=%d, value=%d\n", s, c->id, c->value); - } - break; - } - case VIDIOC_G_CROP: - case VIDIOC_S_CROP: - { - const struct v4l2_crop *p=arg; - /*FIXME: Should also show rect structs */ - printk ("%s: type=%d\n", s, p->type); - break; - } - case VIDIOC_CROPCAP: -#ifdef __OLD_VIDIOC_ - case VIDIOC_CROPCAP_OLD: -#endif - { - const struct v4l2_cropcap *p=arg; - /*FIXME: Should also show rect structs */ - printk ("%s: type=%d\n", s, p->type); - break; - } - case VIDIOC_INT_DECODE_VBI_LINE: - { - const struct v4l2_decode_vbi_line *p=arg; - printk ("%s: is_second_field=%d, ptr=0x%08lx, line=%d, " - "type=%d\n", s, - p->is_second_field,(unsigned long)p->p,p->line,p->type); - break; - } - case VIDIOC_ENUM_FMT: - { - const struct v4l2_fmtdesc *p=arg; - printk ("%s: index=%d, type=%d, flags=%d, description=%s," - " pixelformat=%d\n", s, - p->index, p->type, p->flags,p->description, - p->pixelformat); - - break; - } - case VIDIOC_G_FMT: - case VIDIOC_S_FMT: - case VIDIOC_TRY_FMT: - { - const struct v4l2_format *p=arg; - printk ("%s: type=%s\n", s, - prt_names(p->type,v4l2_type_names)); - switch (p->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - v4l_print_pix_fmt (s, &p->fmt.pix); - break; -#if 0 - /* FIXME: Should be one dump per type*/ - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - case V4L2_BUF_TYPE_VBI_CAPTURE: - case V4L2_BUF_TYPE_VBI_OUTPUT: - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - case V4L2_BUF_TYPE_PRIVATE: - break; -#endif - default: - break; - } - break; - } - case VIDIOC_G_FBUF: - case VIDIOC_S_FBUF: - { - const struct v4l2_framebuffer *p=arg; - printk ("%s: capability=%d, flags=%d, base=0x%08lx\n", s, - p->capability,p->flags, (unsigned long)p->base); - v4l_print_pix_fmt (s, &p->fmt); - break; - } - case VIDIOC_G_FREQUENCY: - case VIDIOC_S_FREQUENCY: - { - const struct v4l2_frequency *p=arg; - printk ("%s: tuner=%d, type=%d, frequency=%d\n", s, - p->tuner,p->type,p->frequency); - break; - } - case VIDIOC_ENUMINPUT: - { - const struct v4l2_input *p=arg; - printk ("%s: index=%d, name=%s, type=%d, audioset=%d, " - "tuner=%d, std=%Ld, status=%d\n", s, - p->index,p->name,p->type,p->audioset, - p->tuner, - (unsigned long long)p->std, - p->status); - break; - } - case VIDIOC_G_JPEGCOMP: - case VIDIOC_S_JPEGCOMP: - { - const struct v4l2_jpegcompression *p=arg; - printk ("%s: quality=%d, APPn=%d, APP_len=%d, COM_len=%d," - " jpeg_markers=%d\n", s, - p->quality,p->APPn,p->APP_len, - p->COM_len,p->jpeg_markers); - break; - } - case VIDIOC_G_MODULATOR: - case VIDIOC_S_MODULATOR: - { - const struct v4l2_modulator *p=arg; - printk ("%s: index=%d, name=%s, capability=%d, rangelow=%d," - " rangehigh=%d, txsubchans=%d\n", s, - p->index, p->name,p->capability,p->rangelow, - p->rangehigh,p->txsubchans); - break; - } - case VIDIOC_ENUMOUTPUT: - { - const struct v4l2_output *p=arg; - printk ("%s: index=%d, name=%s,type=%d, audioset=%d, " - "modulator=%d, std=%Ld\n", - s,p->index,p->name,p->type,p->audioset, - p->modulator, - (unsigned long long)p->std); - break; - } - case VIDIOC_QUERYCTRL: - { - const struct v4l2_queryctrl *p=arg; - printk ("%s: id=%d, type=%d, name=%s, min/max=%d/%d," - " step=%d, default=%d, flags=0x%08x\n", s, - p->id,p->type,p->name,p->minimum,p->maximum, - p->step,p->default_value,p->flags); - break; - } - case VIDIOC_QUERYMENU: - { - const struct v4l2_querymenu *p=arg; - printk ("%s: id=%d, index=%d, name=%s\n", s, - p->id,p->index,p->name); - break; - } -#ifdef CONFIG_VIDEO_ADV_DEBUG - case VIDIOC_DBG_G_REGISTER: - case VIDIOC_DBG_S_REGISTER: - { - const struct v4l2_register *p=arg; - printk ("%s: match_type=%d, match_chip=%d, reg=%llu, val=%llu\n", s, - p->match_type, p->match_chip, - (unsigned long long)p->reg, (unsigned long long)p->val); - - break; - } -#endif - case VIDIOC_REQBUFS: - { - const struct v4l2_requestbuffers *p=arg; - printk ("%s: count=%d, type=%s, memory=%s\n", s, - p->count, - prt_names(p->type,v4l2_type_names), - prt_names(p->memory,v4l2_memory_names)); - break; - } - case VIDIOC_INT_S_AUDIO_ROUTING: - case VIDIOC_INT_S_VIDEO_ROUTING: - case VIDIOC_INT_G_AUDIO_ROUTING: - case VIDIOC_INT_G_VIDEO_ROUTING: - { - const struct v4l2_routing *p=arg; - printk ("%s: input=0x%x, output=0x%x\n", s, p->input, p->output); - break; - } - case VIDIOC_INT_S_CRYSTAL_FREQ: - { - const struct v4l2_crystal_freq *p=arg; - printk ("%s: freq=%u, flags=0x%x\n", s, p->freq, p->flags); - break; - } - case VIDIOC_G_SLICED_VBI_CAP: - { - const struct v4l2_sliced_vbi_cap *p=arg; - printk ("%s: service_set=%d\n", s, - p->service_set); - break; - } - case VIDIOC_INT_S_VBI_DATA: - case VIDIOC_INT_G_VBI_DATA: - { - const struct v4l2_sliced_vbi_data *p=arg; - printk ("%s: id=%d, field=%d, line=%d\n", s, - p->id, p->field, p->line); - break; - } - case VIDIOC_ENUMSTD: - { - const struct v4l2_standard *p=arg; - printk ("%s: index=%d, id=%Ld, name=%s, fps=%d/%d, " - "framelines=%d\n", s, p->index, - (unsigned long long)p->id, p->name, - p->frameperiod.numerator, - p->frameperiod.denominator, - p->framelines); - - break; - } - case VIDIOC_G_PARM: - case VIDIOC_S_PARM: -#ifdef __OLD_VIDIOC_ - case VIDIOC_S_PARM_OLD: -#endif - { - const struct v4l2_streamparm *p=arg; - printk ("%s: type=%d\n", s, p->type); - - break; - } - case VIDIOC_G_TUNER: - case VIDIOC_S_TUNER: - { - const struct v4l2_tuner *p=arg; - printk ("%s: index=%d, name=%s, type=%d, capability=%d, " - "rangelow=%d, rangehigh=%d, signal=%d, afc=%d, " - "rxsubchans=%d, audmode=%d\n", s, - p->index, p->name, p->type, - p->capability, p->rangelow,p->rangehigh, - p->rxsubchans, p->audmode, p->signal, - p->afc); - break; - } -#ifdef CONFIG_VIDEO_V4L1_COMPAT - case VIDIOCGVBIFMT: - case VIDIOCSVBIFMT: - { - const struct vbi_format *p=arg; - printk ("%s: sampling_rate=%d, samples_per_line=%d, " - "sample_format=%d, start=%d/%d, count=%d/%d, flags=%d\n", s, - p->sampling_rate,p->samples_per_line, - p->sample_format,p->start[0],p->start[1], - p->count[0],p->count[1],p->flags); - break; - } - case VIDIOCGAUDIO: - case VIDIOCSAUDIO: - { - const struct video_audio *p=arg; - printk ("%s: audio=%d, volume=%d, bass=%d, treble=%d, " - "flags=%d, name=%s, mode=%d, balance=%d, step=%d\n", - s,p->audio,p->volume,p->bass, p->treble, - p->flags,p->name,p->mode,p->balance,p->step); - break; - } - case VIDIOCGFBUF: - case VIDIOCSFBUF: - { - const struct video_buffer *p=arg; - printk ("%s: base=%08lx, height=%d, width=%d, depth=%d, " - "bytesperline=%d\n", s, - (unsigned long) p->base, p->height, p->width, - p->depth,p->bytesperline); - break; - } - case VIDIOCGCAP: - { - const struct video_capability *p=arg; - printk ("%s: name=%s, type=%d, channels=%d, audios=%d, " - "maxwidth=%d, maxheight=%d, minwidth=%d, minheight=%d\n", - s,p->name,p->type,p->channels,p->audios, - p->maxwidth,p->maxheight,p->minwidth, - p->minheight); - - break; - } - case VIDIOCGCAPTURE: - case VIDIOCSCAPTURE: - { - const struct video_capture *p=arg; - printk ("%s: x=%d, y=%d, width=%d, height=%d, decimation=%d," - " flags=%d\n", s, - p->x, p->y,p->width, p->height, - p->decimation,p->flags); - break; - } - case VIDIOCGCHAN: - case VIDIOCSCHAN: - { - const struct video_channel *p=arg; - printk ("%s: channel=%d, name=%s, tuners=%d, flags=%d, " - "type=%d, norm=%d\n", s, - p->channel,p->name,p->tuners, - p->flags,p->type,p->norm); - - break; - } - case VIDIOCSMICROCODE: - { - const struct video_code *p=arg; - printk ("%s: loadwhat=%s, datasize=%d\n", s, - p->loadwhat,p->datasize); - break; - } - case DECODER_GET_CAPABILITIES: - { - const struct video_decoder_capability *p=arg; - printk ("%s: flags=%d, inputs=%d, outputs=%d\n", s, - p->flags,p->inputs,p->outputs); - break; - } - case DECODER_INIT: - { - const struct video_decoder_init *p=arg; - printk ("%s: len=%c\n", s, p->len); - break; - } - case VIDIOCGPLAYINFO: - { - const struct video_info *p=arg; - printk ("%s: frame_count=%d, h_size=%d, v_size=%d, " - "smpte_timecode=%d, picture_type=%d, " - "temporal_reference=%d, user_data=%s\n", s, - p->frame_count, p->h_size, - p->v_size, p->smpte_timecode, - p->picture_type, p->temporal_reference, - p->user_data); - break; - } - case VIDIOCKEY: - { - const struct video_key *p=arg; - printk ("%s: key=%s, flags=%d\n", s, - p->key, p->flags); - break; - } - case VIDIOCGMBUF: - { - const struct video_mbuf *p=arg; - printk ("%s: size=%d, frames=%d, offsets=0x%08lx\n", s, - p->size, - p->frames, - (unsigned long)p->offsets); - break; - } - case VIDIOCMCAPTURE: - { - const struct video_mmap *p=arg; - printk ("%s: frame=%d, height=%d, width=%d, format=%d\n", s, - p->frame, - p->height, p->width, - p->format); - break; - } - case VIDIOCGPICT: - case VIDIOCSPICT: - case DECODER_SET_PICTURE: - { - const struct video_picture *p=arg; - - printk ("%s: brightness=%d, hue=%d, colour=%d, contrast=%d," - " whiteness=%d, depth=%d, palette=%d\n", s, - p->brightness, p->hue, p->colour, - p->contrast, p->whiteness, p->depth, - p->palette); - break; - } - case VIDIOCSPLAYMODE: - { - const struct video_play_mode *p=arg; - printk ("%s: mode=%d, p1=%d, p2=%d\n", s, - p->mode,p->p1,p->p2); - break; - } - case VIDIOCGTUNER: - case VIDIOCSTUNER: - { - const struct video_tuner *p=arg; - printk ("%s: tuner=%d, name=%s, rangelow=%ld, rangehigh=%ld, " - "flags=%d, mode=%d, signal=%d\n", s, - p->tuner, p->name,p->rangelow, p->rangehigh, - p->flags,p->mode, p->signal); - break; - } - case VIDIOCGUNIT: - { - const struct video_unit *p=arg; - printk ("%s: video=%d, vbi=%d, radio=%d, audio=%d, " - "teletext=%d\n", s, - p->video,p->vbi,p->radio,p->audio,p->teletext); - break; - } - case VIDIOCGWIN: - case VIDIOCSWIN: - { - const struct video_window *p=arg; - printk ("%s: x=%d, y=%d, width=%d, height=%d, chromakey=%d," - " flags=%d, clipcount=%d\n", s, - p->x, p->y,p->width, p->height, - p->chromakey,p->flags, - p->clipcount); - break; - } - case VIDIOCGFREQ: - case VIDIOCSFREQ: - { - const unsigned long *p=arg; - printk ("%s: value=%lu\n", s, *p); - break; - } -#endif - case VIDIOC_INT_AUDIO_CLOCK_FREQ: - case VIDIOC_INT_I2S_CLOCK_FREQ: - case VIDIOC_INT_S_STANDBY: - case VIDIOC_INT_RESET: - { - const u32 *p=arg; - - printk ("%s: value=%d\n", s, *p); - break; - } - case VIDIOC_G_STD: - case VIDIOC_S_STD: - case VIDIOC_QUERYSTD: - { - const v4l2_std_id *p=arg; - - printk ("%s: value=%Lu\n", s, (unsigned long long)*p); - break; - } - } -} -EXPORT_SYMBOL(v4l_printk_ioctl_arg); -#endif /* 0 */ - /* ----------------------------------------------------------------- */ /* Helper functions for control handling */ diff --git a/linux/include/media/v4l2-common.h b/linux/include/media/v4l2-common.h index 10fc32e16..d225eac1e 100644 --- a/linux/include/media/v4l2-common.h +++ b/linux/include/media/v4l2-common.h @@ -69,9 +69,6 @@ /* Prints the ioctl in a human-readable format */ extern void v4l_printk_ioctl(unsigned int cmd); -#if 0 -extern void v4l_printk_ioctl_arg(const char *s, unsigned int cmd, const void *arg); -#endif /* Use this macro for non-I2C drivers. Pass the driver name as the first arg. */ #define v4l_print_ioctl(name, cmd) \ -- cgit v1.2.3 From 7fdad17aa5f5e0f8d164613e27d828962100b4c9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 31 Jan 2008 11:40:04 -0200 Subject: videobuf lock is already initialized at videobuf-core.c From: Mauro Carvalho Chehab Removes the duplicated mutex_init code. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/saa7146_vbi.c | 1 - linux/drivers/media/common/saa7146_video.c | 2 -- 2 files changed, 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/common/saa7146_vbi.c b/linux/drivers/media/common/saa7146_vbi.c index 57e441ed3..50cb69e9d 100644 --- a/linux/drivers/media/common/saa7146_vbi.c +++ b/linux/drivers/media/common/saa7146_vbi.c @@ -414,7 +414,6 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file) V4L2_FIELD_SEQ_TB, // FIXME: does this really work? sizeof(struct saa7146_buf), file); - mutex_init(&fh->vbi_q.lock); init_timer(&fh->vbi_read_timeout); fh->vbi_read_timeout.function = vbi_read_timeout; diff --git a/linux/drivers/media/common/saa7146_video.c b/linux/drivers/media/common/saa7146_video.c index 915bd9089..027d62c04 100644 --- a/linux/drivers/media/common/saa7146_video.c +++ b/linux/drivers/media/common/saa7146_video.c @@ -1418,8 +1418,6 @@ static int video_open(struct saa7146_dev *dev, struct file *file) sizeof(struct saa7146_buf), file); - mutex_init(&fh->video_q.lock); - return 0; } -- cgit v1.2.3 From 88f332f73bffc942ecd8aee59abd34df3fd69d6b Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 31 Jan 2008 08:42:00 -0500 Subject: tuner: remove emacs c-basic-offset override block From: Michael Krufky I'd prefer to leave this here, but official CodingStyle doesn't care what I think :-/ Remove the emacs format override block to comply with Kernel CodingStyle. Signed-off-by: Michael Krufky --- linux/drivers/media/video/tuner-types.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tuner-types.c b/linux/drivers/media/video/tuner-types.c index 2e93a9c57..7eb3c6315 100644 --- a/linux/drivers/media/video/tuner-types.c +++ b/linux/drivers/media/video/tuner-types.c @@ -1536,11 +1536,3 @@ EXPORT_SYMBOL(tuner_count); MODULE_DESCRIPTION("Simple tuner device type database"); MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer"); MODULE_LICENSE("GPL"); - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * --------------------------------------------------------------------------- - * Local variables: - * c-basic-offset: 8 - * End: - */ -- cgit v1.2.3 From 21ed876086e2efb38e6f2dfaf48fae94fe2ec738 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 31 Jan 2008 11:57:53 -0200 Subject: Renames videobuf lock to vb_lock From: Mauro Carvalho Chehab This helps to identify where vb_lock is being used, and find missusages of the locks. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/bt8xx/bttv-driver.c | 50 +++++++------- linux/drivers/media/video/bt8xx/bttv-vbi.c | 4 +- .../drivers/media/video/saa7134/saa7134-empress.c | 8 +-- linux/drivers/media/video/saa7134/saa7134-video.c | 20 +++--- linux/drivers/media/video/videobuf-core.c | 78 +++++++++++----------- linux/drivers/media/video/videobuf-dma-sg.c | 4 +- linux/drivers/media/video/videobuf-vmalloc.c | 4 +- linux/include/media/videobuf-core.h | 4 +- 8 files changed, 85 insertions(+), 87 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 65e3cb500..063bbcc58 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -2395,8 +2395,8 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv, BUG(); } - mutex_lock(&fh->cap.lock); - kfree(fh->ov.clips); + mutex_lock(&fh->cap.vb_lock); + kfree(fh->ov.clips); fh->ov.clips = clips; fh->ov.nclips = n; @@ -2417,7 +2417,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv, bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); retval = bttv_switch_overlay(btv,fh,new); } - mutex_unlock(&fh->cap.lock); + mutex_unlock(&fh->cap.vb_lock); return retval; } @@ -2617,7 +2617,7 @@ static int bttv_s_fmt_cap(struct file *file, void *priv, fmt = format_by_fourcc(f->fmt.pix.pixelformat); /* update our state informations */ - mutex_lock(&fh->cap.lock); + mutex_lock(&fh->cap.vb_lock); fh->fmt = fmt; fh->cap.field = f->fmt.pix.field; fh->cap.last = V4L2_FIELD_NONE; @@ -2626,7 +2626,7 @@ static int bttv_s_fmt_cap(struct file *file, void *priv, btv->init.fmt = fmt; btv->init.width = f->fmt.pix.width; btv->init.height = f->fmt.pix.height; - mutex_unlock(&fh->cap.lock); + mutex_unlock(&fh->cap.vb_lock); return 0; } @@ -2652,11 +2652,11 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) unsigned int i; struct bttv_fh *fh = priv; - mutex_lock(&fh->cap.lock); + mutex_lock(&fh->cap.vb_lock); retval = videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize, V4L2_MEMORY_MMAP); if (retval < 0) { - mutex_unlock(&fh->cap.lock); + mutex_unlock(&fh->cap.vb_lock); return retval; } @@ -2668,7 +2668,7 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) for (i = 0; i < gbuffers; i++) mbuf->offsets[i] = i * gbufsize; - mutex_unlock(&fh->cap.lock); + mutex_unlock(&fh->cap.vb_lock); return 0; } #endif @@ -2797,7 +2797,7 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on) if (!check_alloc_btres(btv, fh, RESOURCE_OVERLAY)) return -EBUSY; - mutex_lock(&fh->cap.lock); + mutex_lock(&fh->cap.vb_lock); if (on) { fh->ov.tvnorm = btv->tvnorm; new = videobuf_pci_alloc(sizeof(*new)); @@ -2808,7 +2808,7 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on) /* switch over */ retval = bttv_switch_overlay(btv, fh, new); - mutex_unlock(&fh->cap.lock); + mutex_unlock(&fh->cap.vb_lock); return retval; } @@ -2847,7 +2847,7 @@ static int bttv_s_fbuf(struct file *file, void *f, } /* ok, accept it */ - mutex_lock(&fh->cap.lock); + mutex_lock(&fh->cap.vb_lock); btv->fbuf.base = fb->base; btv->fbuf.fmt.width = fb->fmt.width; btv->fbuf.fmt.height = fb->fmt.height; @@ -2879,7 +2879,7 @@ static int bttv_s_fbuf(struct file *file, void *f, retval = bttv_switch_overlay(btv, fh, new); } } - mutex_unlock(&fh->cap.lock); + mutex_unlock(&fh->cap.vb_lock); return retval; } @@ -3131,7 +3131,7 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop) fh->do_crop = 1; - mutex_lock(&fh->cap.lock); + mutex_lock(&fh->cap.vb_lock); if (fh->width < c.min_scaled_width) { fh->width = c.min_scaled_width; @@ -3149,7 +3149,7 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop) btv->init.height = c.max_scaled_height; } - mutex_unlock(&fh->cap.lock); + mutex_unlock(&fh->cap.vb_lock); return 0; } @@ -3218,30 +3218,25 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream); } else { /* read() capture */ - mutex_lock(&fh->cap.lock); + mutex_lock(&fh->cap.vb_lock); if (NULL == fh->cap.read_buf) { /* need to capture a new frame */ - if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM)) { - mutex_unlock(&fh->cap.lock); - return POLLERR; - } + if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM)) + goto err; fh->cap.read_buf = videobuf_pci_alloc(fh->cap.msize); - if (NULL == fh->cap.read_buf) { - mutex_unlock(&fh->cap.lock); - return POLLERR; - } + if (NULL == fh->cap.read_buf) + goto err; fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR; field = videobuf_next_field(&fh->cap); if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) { kfree (fh->cap.read_buf); fh->cap.read_buf = NULL; - mutex_unlock(&fh->cap.lock); - return POLLERR; + goto err; } fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); fh->cap.read_off = 0; } - mutex_unlock(&fh->cap.lock); + mutex_unlock(&fh->cap.vb_lock); buf = (struct bttv_buffer*)fh->cap.read_buf; } @@ -3250,6 +3245,9 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) buf->vb.state == VIDEOBUF_ERROR) return POLLIN|POLLRDNORM; return 0; +err: + mutex_unlock(&fh->cap.vb_lock); + return POLLERR; } static int bttv_open(struct inode *inode, struct file *file) diff --git a/linux/drivers/media/video/bt8xx/bttv-vbi.c b/linux/drivers/media/video/bt8xx/bttv-vbi.c index d17e583c0..bfdbc469e 100644 --- a/linux/drivers/media/video/bt8xx/bttv-vbi.c +++ b/linux/drivers/media/video/bt8xx/bttv-vbi.c @@ -352,13 +352,13 @@ int bttv_s_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt) because vbi_fmt.end counts field lines times two. */ end = max(frt->fmt.vbi.start[0], start1) * 2 + 2; - mutex_lock(&fh->vbi.lock); + mutex_lock(&fh->vbi.vb_lock); fh->vbi_fmt.fmt = frt->fmt.vbi; fh->vbi_fmt.tvnorm = tvnorm; fh->vbi_fmt.end = end; - mutex_unlock(&fh->vbi.lock); + mutex_unlock(&fh->vbi.vb_lock); rc = 0; diff --git a/linux/drivers/media/video/saa7134/saa7134-empress.c b/linux/drivers/media/video/saa7134/saa7134-empress.c index dbd026a7c..7803f9983 100644 --- a/linux/drivers/media/video/saa7134/saa7134-empress.c +++ b/linux/drivers/media/video/saa7134/saa7134-empress.c @@ -96,7 +96,7 @@ static int ts_open(struct inode *inode, struct file *file) dprintk("open minor=%d\n",minor); err = -EBUSY; - if (!mutex_trylock(&dev->empress_tsq.lock)) + if (!mutex_trylock(&dev->empress_tsq.vb_lock)) goto done; if (dev->empress_users) goto done_up; @@ -110,7 +110,7 @@ static int ts_open(struct inode *inode, struct file *file) err = 0; done_up: - mutex_unlock(&dev->empress_tsq.lock); + mutex_unlock(&dev->empress_tsq.vb_lock); done: return err; } @@ -119,7 +119,7 @@ static int ts_release(struct inode *inode, struct file *file) { struct saa7134_dev *dev = file->private_data; - mutex_lock(&dev->empress_tsq.lock); + mutex_lock(&dev->empress_tsq.vb_lock); videobuf_stop(&dev->empress_tsq); videobuf_mmap_free(&dev->empress_tsq); dev->empress_users--; @@ -131,7 +131,7 @@ static int ts_release(struct inode *inode, struct file *file) saa_writeb(SAA7134_AUDIO_MUTE_CTRL, saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6)); - mutex_unlock(&dev->empress_tsq.lock); + mutex_unlock(&dev->empress_tsq.vb_lock); return 0; } diff --git a/linux/drivers/media/video/saa7134/saa7134-video.c b/linux/drivers/media/video/saa7134/saa7134-video.c index 16914e455..63e4900b0 100644 --- a/linux/drivers/media/video/saa7134/saa7134-video.c +++ b/linux/drivers/media/video/saa7134/saa7134-video.c @@ -1414,21 +1414,17 @@ video_poll(struct file *file, struct poll_table_struct *wait) if (!list_empty(&fh->cap.stream)) buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream); } else { - mutex_lock(&fh->cap.lock); + mutex_lock(&fh->cap.vb_lock); if (UNSET == fh->cap.read_off) { /* need to capture a new frame */ - if (res_locked(fh->dev,RESOURCE_VIDEO)) { - mutex_unlock(&fh->cap.lock); - return POLLERR; - } - if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) { - mutex_unlock(&fh->cap.lock); - return POLLERR; - } + if (res_locked(fh->dev,RESOURCE_VIDEO)) + goto err; + if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) + goto err; fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); fh->cap.read_off = 0; } - mutex_unlock(&fh->cap.lock); + mutex_unlock(&fh->cap.vb_lock); buf = fh->cap.read_buf; } @@ -1440,6 +1436,10 @@ video_poll(struct file *file, struct poll_table_struct *wait) buf->state == VIDEOBUF_ERROR) return POLLIN|POLLRDNORM; return 0; + +err: + mutex_unlock(&fh->cap.vb_lock); + return POLLERR; } static int video_release(struct inode *inode, struct file *file) diff --git a/linux/drivers/media/video/videobuf-core.c b/linux/drivers/media/video/videobuf-core.c index cf5033b68..b5395c538 100644 --- a/linux/drivers/media/video/videobuf-core.c +++ b/linux/drivers/media/video/videobuf-core.c @@ -148,7 +148,7 @@ void videobuf_queue_core_init(struct videobuf_queue *q, /* Having implementations for abstract methods are mandatory */ BUG_ON(!q->int_ops); - mutex_init(&q->lock); + mutex_init(&q->vb_lock); INIT_LIST_HEAD(&q->stream); } @@ -190,7 +190,7 @@ int videobuf_queue_is_busy(struct videobuf_queue *q) return 0; } -/* Locking: Caller holds q->lock */ +/* Locking: Caller holds q->vb_lock */ void videobuf_queue_cancel(struct videobuf_queue *q) { unsigned long flags = 0; @@ -221,7 +221,7 @@ void videobuf_queue_cancel(struct videobuf_queue *q) /* --------------------------------------------------------------------- */ -/* Locking: Caller holds q->lock */ +/* Locking: Caller holds q->vb_lock */ enum v4l2_field videobuf_next_field(struct videobuf_queue *q) { enum v4l2_field field = q->field; @@ -240,7 +240,7 @@ enum v4l2_field videobuf_next_field(struct videobuf_queue *q) return field; } -/* Locking: Caller holds q->lock */ +/* Locking: Caller holds q->vb_lock */ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, struct videobuf_buffer *vb, enum v4l2_buf_type type) { @@ -296,7 +296,7 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, b->sequence = vb->field_count >> 1; } -/* Locking: Caller holds q->lock */ +/* Locking: Caller holds q->vb_lock */ static int __videobuf_mmap_free(struct videobuf_queue *q) { int i; @@ -329,13 +329,13 @@ static int __videobuf_mmap_free(struct videobuf_queue *q) int videobuf_mmap_free(struct videobuf_queue *q) { int ret; - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); ret = __videobuf_mmap_free(q); - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return ret; } -/* Locking: Caller holds q->lock */ +/* Locking: Caller holds q->vb_lock */ static int __videobuf_mmap_setup(struct videobuf_queue *q, unsigned int bcount, unsigned int bsize, enum v4l2_memory memory) @@ -385,9 +385,9 @@ int videobuf_mmap_setup(struct videobuf_queue *q, enum v4l2_memory memory) { int ret; - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); ret = __videobuf_mmap_setup(q, bcount, bsize, memory); - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return ret; } @@ -409,7 +409,7 @@ int videobuf_reqbufs(struct videobuf_queue *q, return -EINVAL; } - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); if (req->type != q->type) { dprintk(1, "reqbufs: queue type invalid\n"); retval = -EINVAL; @@ -445,7 +445,7 @@ int videobuf_reqbufs(struct videobuf_queue *q, req->count = retval; done: - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return retval; } @@ -453,7 +453,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b) { int ret = -EINVAL; - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); if (unlikely(b->type != q->type)) { dprintk(1, "querybuf: Wrong type.\n"); goto done; @@ -471,7 +471,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b) ret = 0; done: - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return ret; } @@ -488,7 +488,7 @@ int videobuf_qbuf(struct videobuf_queue *q, if (b->memory == V4L2_MEMORY_MMAP) down_read(¤t->mm->mmap_sem); - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); retval = -EBUSY; if (q->reading) { dprintk(1, "qbuf: Reading running...\n"); @@ -574,7 +574,7 @@ int videobuf_qbuf(struct videobuf_queue *q, retval = 0; done: - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); if (b->memory == V4L2_MEMORY_MMAP) up_read(¤t->mm->mmap_sem); @@ -590,7 +590,7 @@ int videobuf_dqbuf(struct videobuf_queue *q, MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); retval = -EBUSY; if (q->reading) { dprintk(1, "dqbuf: Reading running...\n"); @@ -633,7 +633,7 @@ int videobuf_dqbuf(struct videobuf_queue *q, videobuf_status(q, b, buf, q->type); done: - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return retval; } @@ -643,7 +643,7 @@ int videobuf_streamon(struct videobuf_queue *q) unsigned long flags = 0; int retval; - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); retval = -EBUSY; if (q->reading) goto done; @@ -660,11 +660,11 @@ int videobuf_streamon(struct videobuf_queue *q) spin_unlock_irqrestore(q->irqlock, flags); done: - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return retval; } -/* Locking: Caller holds q->lock */ +/* Locking: Caller holds q->vb_lock */ static int __videobuf_streamoff(struct videobuf_queue *q) { if (!q->streaming) @@ -680,14 +680,14 @@ int videobuf_streamoff(struct videobuf_queue *q) { int retval; - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); retval = __videobuf_streamoff(q); - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return retval; } -/* Locking: Caller holds q->lock */ +/* Locking: Caller holds q->vb_lock */ static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data, size_t count, loff_t *ppos) @@ -746,7 +746,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); nbufs = 1; size = 0; q->ops->buf_setup(q, &nbufs, &size); @@ -818,11 +818,11 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, } done: - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return retval; } -/* Locking: Caller holds q->lock */ +/* Locking: Caller holds q->vb_lock */ static int __videobuf_read_start(struct videobuf_queue *q) { enum v4l2_field field; @@ -883,23 +883,23 @@ int videobuf_read_start(struct videobuf_queue *q) { int rc; - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); rc = __videobuf_read_start(q); - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return rc; } void videobuf_read_stop(struct videobuf_queue *q) { - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); __videobuf_read_stop(q); - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); } void videobuf_stop(struct videobuf_queue *q) { - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); if (q->streaming) __videobuf_streamoff(q); @@ -907,7 +907,7 @@ void videobuf_stop(struct videobuf_queue *q) if (q->reading) __videobuf_read_stop(q); - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); } @@ -921,7 +921,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q, MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); dprintk(2, "%s\n", __FUNCTION__); - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); retval = -EBUSY; if (q->streaming) goto done; @@ -981,7 +981,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q, } done: - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return retval; } @@ -992,7 +992,7 @@ unsigned int videobuf_poll_stream(struct file *file, struct videobuf_buffer *buf = NULL; unsigned int rc = 0; - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); if (q->streaming) { if (!list_empty(&q->stream)) buf = list_entry(q->stream.next, @@ -1020,7 +1020,7 @@ unsigned int videobuf_poll_stream(struct file *file, buf->state == VIDEOBUF_ERROR) rc = POLLIN|POLLRDNORM; } - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return rc; } @@ -1031,10 +1031,10 @@ int videobuf_mmap_mapper(struct videobuf_queue *q, MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); retval = CALL(q, mmap_mapper, q, vma); q->is_mmapped = 1; - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return retval; } diff --git a/linux/drivers/media/video/videobuf-dma-sg.c b/linux/drivers/media/video/videobuf-dma-sg.c index 6382954ca..84c7ff649 100644 --- a/linux/drivers/media/video/videobuf-dma-sg.c +++ b/linux/drivers/media/video/videobuf-dma-sg.c @@ -361,7 +361,7 @@ videobuf_vm_close(struct vm_area_struct *vma) map->count--; if (0 == map->count) { dprintk(1,"munmap %p q=%p\n",map,q); - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); for (i = 0; i < VIDEO_MAX_FRAME; i++) { if (NULL == q->bufs[i]) continue; @@ -383,7 +383,7 @@ videobuf_vm_close(struct vm_area_struct *vma) q->bufs[i]->baddr = 0; q->ops->buf_release(q,q->bufs[i]); } - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); kfree(map); } return; diff --git a/linux/drivers/media/video/videobuf-vmalloc.c b/linux/drivers/media/video/videobuf-vmalloc.c index db00a6fdb..18e070204 100644 --- a/linux/drivers/media/video/videobuf-vmalloc.c +++ b/linux/drivers/media/video/videobuf-vmalloc.c @@ -71,7 +71,7 @@ videobuf_vm_close(struct vm_area_struct *vma) map->count--; if (0 == map->count) { dprintk(1,"munmap %p q=%p\n",map,q); - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); for (i = 0; i < VIDEO_MAX_FRAME; i++) { if (NULL == q->bufs[i]) continue; @@ -84,7 +84,7 @@ videobuf_vm_close(struct vm_area_struct *vma) q->bufs[i]->map = NULL; q->bufs[i]->baddr = 0; } - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); kfree(map); } return; diff --git a/linux/include/media/videobuf-core.h b/linux/include/media/videobuf-core.h index 9bb244716..b73f0ffa8 100644 --- a/linux/include/media/videobuf-core.h +++ b/linux/include/media/videobuf-core.h @@ -150,9 +150,9 @@ struct videobuf_qtype_ops { struct videobuf_queue { #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) - struct mutex lock; + struct mutex vb_lock; #else - struct semaphore lock; + struct semaphore vb_lock; #endif spinlock_t *irqlock; void *dev; /* on pci, points to struct pci_dev */ -- cgit v1.2.3 From c7c16254d06970012c0473a2ca358e7725c35d91 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 31 Jan 2008 11:59:29 -0200 Subject: saa7134-empress: Remove back lock From: Mauro Carvalho Chehab videobuf functions at close() method already locks videobuf. It makes no sense to keep the locking at empress close() method. There is also a lock at open() method. I'm not sure if it is safe to remove the locking there. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-empress.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7134/saa7134-empress.c b/linux/drivers/media/video/saa7134/saa7134-empress.c index 7803f9983..6f3f4f0f9 100644 --- a/linux/drivers/media/video/saa7134/saa7134-empress.c +++ b/linux/drivers/media/video/saa7134/saa7134-empress.c @@ -119,7 +119,6 @@ static int ts_release(struct inode *inode, struct file *file) { struct saa7134_dev *dev = file->private_data; - mutex_lock(&dev->empress_tsq.vb_lock); videobuf_stop(&dev->empress_tsq); videobuf_mmap_free(&dev->empress_tsq); dev->empress_users--; @@ -131,7 +130,6 @@ static int ts_release(struct inode *inode, struct file *file) saa_writeb(SAA7134_AUDIO_MUTE_CTRL, saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6)); - mutex_unlock(&dev->empress_tsq.vb_lock); return 0; } -- cgit v1.2.3 From 9c21c1194a044d1b09b3939fae09462be1b497e2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 30 Jan 2008 17:23:00 +0000 Subject: Add USB ID for a newer variant of Hauppauge WinTV-HVR 900 From: Luc Saillard Device description: WinTV-HVR-900 M/R: 65018/B3C0 ##4207 Signed-off-by: Luc Saillard Signed-off-by: Mauro Carvalho Chehab --- linux/Documentation/video4linux/CARDLIST.em28xx | 2 +- linux/drivers/media/video/em28xx/em28xx-cards.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/Documentation/video4linux/CARDLIST.em28xx b/linux/Documentation/video4linux/CARDLIST.em28xx index 6a8469f2b..f40e09296 100644 --- a/linux/Documentation/video4linux/CARDLIST.em28xx +++ b/linux/Documentation/video4linux/CARDLIST.em28xx @@ -8,7 +8,7 @@ 7 -> Leadtek Winfast USB II (em2800) 8 -> Kworld USB2800 (em2800) 9 -> Pinnacle Dazzle DVC 90/DVC 100 (em2820/em2840) [2304:0207,2304:021a] - 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500] + 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500,2040:6502] 11 -> Terratec Hybrid XS (em2880) [0ccd:0042] 12 -> Kworld PVR TV 2800 RF (em2820/em2840) 13 -> Terratec Prodigy XS (em2880) [0ccd:0047] diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index 588e85dfa..1a9236e24 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -442,6 +442,8 @@ struct usb_device_id em28xx_id_table [] = { .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, { USB_DEVICE(0x2040, 0x6500), .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 }, + { USB_DEVICE(0x2040, 0x6502), + .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 }, { USB_DEVICE(0x2040, 0x6513), .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, { USB_DEVICE(0x0ccd, 0x0042), -- cgit v1.2.3 From 035d79af6c56bdefa3f974a15ff6306108ac5dc4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 2 Feb 2008 09:25:31 -0200 Subject: Fix Kconfig dependencies From: Mauro Carvalho Chehab As pointed by Adrian Bunk, with I2C=m and VIDEO_DEV=y, videodev brokes. This patch moves the functions that videodev needs from v4l2-common. It also fixes some Kconfig changes. After this patch, I2C=m / VIDEO_DEV=y will make v4l2 core statically linked into kernel. v4l2-common will be m, and all V4L drivers will also be m. This approach is very conservative, since it is possible to have V4L drivers that don't need I2C or v4l2-common. The better is to map what drivers really need v4l2-common, making them to select v4l2-common, and allowing the others to be 'y', 'm' and 'n'. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/Kconfig | 11 +- linux/drivers/media/common/Kconfig | 2 +- linux/drivers/media/radio/Kconfig | 4 +- linux/drivers/media/video/Kconfig | 4 +- linux/drivers/media/video/v4l2-common.c | 351 +------------------------ linux/drivers/media/video/videodev.c | 444 +++++++++++++++++++++++++++----- linux/include/media/v4l2-common.h | 2 - linux/include/media/v4l2-dev.h | 2 + 8 files changed, 409 insertions(+), 411 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/Kconfig b/linux/drivers/media/Kconfig index a9de06af5..71820ef4f 100644 --- a/linux/drivers/media/Kconfig +++ b/linux/drivers/media/Kconfig @@ -32,9 +32,9 @@ config VIDEO_V4L2_COMMON config VIDEO_V4L1 bool "Enable Video For Linux API 1 (DEPRECATED)" - depends on VIDEO_DEV + depends on VIDEO_DEV && VIDEO_V4L2_COMMON + default VIDEO_DEV && VIDEO_V4L2_COMMON select VIDEO_V4L1_COMPAT - default y ---help--- Enables a compatibility API used by most V4L2 devices to allow its usage with legacy applications that supports only V4L1 api. @@ -44,7 +44,7 @@ config VIDEO_V4L1 config VIDEO_V4L1_COMPAT bool "Enable Video For Linux API 1 compatible Layer" depends on VIDEO_DEV - default y + default VIDEO_DEV ---help--- This api were developed to be used at Kernel 2.2 and 2.4, but lacks support for several video standards. There are several @@ -60,8 +60,8 @@ config VIDEO_V4L1_COMPAT config VIDEO_V4L2 bool - depends on VIDEO_DEV - default y + depends on VIDEO_DEV && VIDEO_V4L2_COMMON + default VIDEO_DEV && VIDEO_V4L2_COMMON source "drivers/media/video/Kconfig" @@ -190,7 +190,6 @@ config VIDEO_TVEEPROM config DAB boolean "DAB adapters" - default y ---help--- Allow selecting support for for Digital Audio Broadcasting (DAB) Receiver adapters. diff --git a/linux/drivers/media/common/Kconfig b/linux/drivers/media/common/Kconfig index 06ca75911..769c6f814 100644 --- a/linux/drivers/media/common/Kconfig +++ b/linux/drivers/media/common/Kconfig @@ -4,6 +4,6 @@ config VIDEO_SAA7146 config VIDEO_SAA7146_VV tristate - depends on VIDEO_DEV + depends on VIDEO_V4L2 select VIDEOBUF_DMA_SG select VIDEO_SAA7146 diff --git a/linux/drivers/media/radio/Kconfig b/linux/drivers/media/radio/Kconfig index 32ffd8103..01ee71e82 100644 --- a/linux/drivers/media/radio/Kconfig +++ b/linux/drivers/media/radio/Kconfig @@ -4,12 +4,12 @@ menuconfig RADIO_ADAPTERS bool "Radio Adapters" - depends on VIDEO_DEV + depends on VIDEO_V4L2 default y ---help--- Say Y here to enable selecting AM/FM radio adapters. -if RADIO_ADAPTERS && VIDEO_DEV +if RADIO_ADAPTERS && VIDEO_V4L2 config RADIO_CADET tristate "ADS Cadet AM/FM Tuner" diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index a2e8987a6..37072a21d 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -4,14 +4,14 @@ menuconfig VIDEO_CAPTURE_DRIVERS bool "Video capture adapters" - depends on VIDEO_DEV + depends on VIDEO_V4L2 default y ---help--- Say Y here to enable selecting the video adapters for webcams, analog TV, and hybrid analog/digital TV. Some of those devices also supports FM radio. -if VIDEO_CAPTURE_DRIVERS && VIDEO_DEV +if VIDEO_CAPTURE_DRIVERS && VIDEO_V4L2 config VIDEO_ADV_DEBUG bool "Enable advanced debug functionality" diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index cd52fbda2..34079657e 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -56,7 +56,6 @@ #include #include #include -#include #define __OLD_VIDIOC_ /* To allow fixing old calls*/ #include #include @@ -82,107 +81,6 @@ MODULE_LICENSE("GPL"); * Video Standard Operations (contributed by Michael Schimek) */ -char *v4l2_norm_to_name(v4l2_std_id id) -{ - char *name; - u32 myid = id; - - /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle - 64 bit comparations. So, on that architecture, with some gcc variants, - compilation fails. Currently, the max value is 30bit wide. - */ - BUG_ON(myid != id); - - switch (myid) { - case V4L2_STD_PAL: - name="PAL"; break; - case V4L2_STD_PAL_BG: - name="PAL-BG"; break; - case V4L2_STD_PAL_DK: - name="PAL-DK"; break; - case V4L2_STD_PAL_B: - name="PAL-B"; break; - case V4L2_STD_PAL_B1: - name="PAL-B1"; break; - case V4L2_STD_PAL_G: - name="PAL-G"; break; - case V4L2_STD_PAL_H: - name="PAL-H"; break; - case V4L2_STD_PAL_I: - name="PAL-I"; break; - case V4L2_STD_PAL_D: - name="PAL-D"; break; - case V4L2_STD_PAL_D1: - name="PAL-D1"; break; - case V4L2_STD_PAL_K: - name="PAL-K"; break; - case V4L2_STD_PAL_M: - name="PAL-M"; break; - case V4L2_STD_PAL_N: - name="PAL-N"; break; - case V4L2_STD_PAL_Nc: - name="PAL-Nc"; break; - case V4L2_STD_PAL_60: - name="PAL-60"; break; - case V4L2_STD_NTSC: - name="NTSC"; break; - case V4L2_STD_NTSC_M: - name="NTSC-M"; break; - case V4L2_STD_NTSC_M_JP: - name="NTSC-M-JP"; break; - case V4L2_STD_NTSC_443: - name="NTSC-443"; break; - case V4L2_STD_NTSC_M_KR: - name="NTSC-M-KR"; break; - case V4L2_STD_SECAM: - name="SECAM"; break; - case V4L2_STD_SECAM_DK: - name="SECAM-DK"; break; - case V4L2_STD_SECAM_B: - name="SECAM-B"; break; - case V4L2_STD_SECAM_D: - name="SECAM-D"; break; - case V4L2_STD_SECAM_G: - name="SECAM-G"; break; - case V4L2_STD_SECAM_H: - name="SECAM-H"; break; - case V4L2_STD_SECAM_K: - name="SECAM-K"; break; - case V4L2_STD_SECAM_K1: - name="SECAM-K1"; break; - case V4L2_STD_SECAM_L: - name="SECAM-L"; break; - case V4L2_STD_SECAM_LC: - name="SECAM-LC"; break; - default: - name="Unknown"; break; - } - - return name; -} - -/* Fill in the fields of a v4l2_standard structure according to the - 'id' and 'transmission' parameters. Returns negative on error. */ -int v4l2_video_std_construct(struct v4l2_standard *vs, - int id, char *name) -{ - u32 index = vs->index; - - memset(vs, 0, sizeof(struct v4l2_standard)); - vs->index = index; - vs->id = id; - if (id & V4L2_STD_525_60) { - vs->frameperiod.numerator = 1001; - vs->frameperiod.denominator = 30000; - vs->framelines = 525; - } else { - vs->frameperiod.numerator = 1; - vs->frameperiod.denominator = 25; - vs->framelines = 625; - } - strlcpy(vs->name,name,sizeof(vs->name)); - return 0; -} /* ----------------------------------------------------------------- */ /* priority handling */ @@ -196,6 +94,7 @@ int v4l2_prio_init(struct v4l2_prio_state *global) memset(global,0,sizeof(*global)); return 0; } +EXPORT_SYMBOL(v4l2_prio_init); int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local, enum v4l2_priority new) @@ -211,11 +110,13 @@ int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local, *local = new; return 0; } +EXPORT_SYMBOL(v4l2_prio_change); int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local) { return v4l2_prio_change(global,local,V4L2_PRIORITY_DEFAULT); } +EXPORT_SYMBOL(v4l2_prio_open); int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local) { @@ -223,6 +124,7 @@ int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local) atomic_dec(&global->prios[*local]); return 0; } +EXPORT_SYMBOL(v4l2_prio_close); enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global) { @@ -234,6 +136,7 @@ enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global) return V4L2_PRIORITY_BACKGROUND; return V4L2_PRIORITY_UNSET; } +EXPORT_SYMBOL(v4l2_prio_max); int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local) { @@ -241,220 +144,7 @@ int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local) return -EBUSY; return 0; } - - -/* ----------------------------------------------------------------- */ -/* some arrays for pretty-printing debug messages of enum types */ - -char *v4l2_field_names[] = { - [V4L2_FIELD_ANY] = "any", - [V4L2_FIELD_NONE] = "none", - [V4L2_FIELD_TOP] = "top", - [V4L2_FIELD_BOTTOM] = "bottom", - [V4L2_FIELD_INTERLACED] = "interlaced", - [V4L2_FIELD_SEQ_TB] = "seq-tb", - [V4L2_FIELD_SEQ_BT] = "seq-bt", - [V4L2_FIELD_ALTERNATE] = "alternate", - [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb", - [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt", -}; - -char *v4l2_type_names[] = { - [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap", - [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over", - [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out", - [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", - [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", - [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap", - [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", - [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over", -}; - -/* ------------------------------------------------------------------ */ -/* debug help functions */ - -#ifdef CONFIG_VIDEO_V4L1_COMPAT -static const char *v4l1_ioctls[] = { - [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP", - [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN", - [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN", - [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER", - [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER", - [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT", - [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT", - [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE", - [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN", - [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN", - [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF", - [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF", - [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY", - [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ", - [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ", - [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO", - [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO", - [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC", - [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE", - [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF", - [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT", - [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE", - [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE", - [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE", - [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE", - [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO", - [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE", - [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT", - [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT" -}; -#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) -#endif - -static const char *v4l2_ioctls[] = { - [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP", - [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED", - [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT", - [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT", - [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT", - [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS", - [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF", - [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF", - [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF", - [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY", - [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF", - [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF", - [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON", - [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF", - [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM", - [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM", - [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD", - [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD", - [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD", - [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT", - [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL", - [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL", - [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER", - [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER", - [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO", - [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO", - [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL", - [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU", - [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT", - [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT", - [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT", - [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT", - [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT", - [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT", - [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT", - [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR", - [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR", - [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY", - [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY", - [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP", - [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP", - [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP", - [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP", - [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP", - [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD", - [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT", - [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO", - [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT", - [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY", - [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY", - [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP", - [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS", - [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS", - [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS", - [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS", -#if 1 /*KEEP*/ - [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES", - [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS", - [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX", - [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD", - [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD", - - [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER", - [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", - - [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT", -#endif -}; -#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) - -static const char *v4l2_int_ioctls[] = { -#ifdef CONFIG_VIDEO_V4L1_COMPAT - [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES", - [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS", - [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM", - [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT", - [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT", - [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT", - [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE", - [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO", - [_IOC_NR(DECODER_INIT)] = "DECODER_INIT", - [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS", - [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP", -#endif - [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO", - - [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR", - [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY", - [_IOC_NR(TUNER_SET_CONFIG)] = "TUNER_SET_CONFIG", - - [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE", - [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET", - [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ", - [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE", - [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA", - [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA", - [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ", - [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY", - [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING", - [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING", - [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING", - [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING", - [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ", - [_IOC_NR(VIDIOC_INT_INIT)] = "VIDIOC_INT_INIT", - [_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)] = "VIDIOC_INT_G_STD_OUTPUT", - [_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)] = "VIDIOC_INT_S_STD_OUTPUT", -}; -#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls) - -/* Common ioctl debug function. This function can be used by - external ioctl messages as well as internal V4L ioctl */ -void v4l_printk_ioctl(unsigned int cmd) -{ - char *dir; - - switch (_IOC_DIR(cmd)) { - case _IOC_NONE: dir = "--"; break; - case _IOC_READ: dir = "r-"; break; - case _IOC_WRITE: dir = "-w"; break; - case _IOC_READ | _IOC_WRITE: dir = "rw"; break; - default: dir = "*ERR*"; break; - } - switch (_IOC_TYPE(cmd)) { - case 'd': - printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n", - (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ? - v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); - break; -#ifdef CONFIG_VIDEO_V4L1_COMPAT - case 'v': - printk("v4l1 ioctl %s, dir=%s (0x%08x)\n", - (_IOC_NR(cmd) < V4L1_IOCTLS) ? - v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); - break; -#endif - case 'V': - printk("v4l2 ioctl %s, dir=%s (0x%08x)\n", - (_IOC_NR(cmd) < V4L2_IOCTLS) ? - v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); - break; - - default: - printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n", - _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); - } -} +EXPORT_SYMBOL(v4l2_prio_check); /* ----------------------------------------------------------------- */ @@ -483,6 +173,7 @@ int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl, } return 0; } +EXPORT_SYMBOL(v4l2_ctrl_check); /* Returns NULL or a character pointer array containing the menu for the given control ID. The pointer array ends with a NULL pointer. @@ -643,6 +334,7 @@ const char **v4l2_ctrl_get_menu(u32 id) return NULL; } } +EXPORT_SYMBOL(v4l2_ctrl_get_menu); /* Fill in a struct v4l2_queryctrl */ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def) @@ -765,6 +457,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste snprintf(qctrl->name, sizeof(qctrl->name), name); return 0; } +EXPORT_SYMBOL(v4l2_ctrl_query_fill); /* Fill in a struct v4l2_queryctrl with standard values based on the control ID. */ @@ -899,6 +592,7 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl) return -EINVAL; } } +EXPORT_SYMBOL(v4l2_ctrl_query_fill_std); /* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and the menu. The qctrl pointer may be NULL, in which case it is ignored. */ @@ -917,6 +611,7 @@ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qc qmenu->reserved = 0; return 0; } +EXPORT_SYMBOL(v4l2_ctrl_query_menu); /* 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. @@ -967,6 +662,7 @@ u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id) return 0; return **ctrl_classes; } +EXPORT_SYMBOL(v4l2_ctrl_next); int v4l2_chip_match_host(u32 match_type, u32 match_chip) { @@ -1045,26 +741,3 @@ int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver } EXPORT_SYMBOL(v4l2_i2c_attach); #endif - -/* ----------------------------------------------------------------- */ - -EXPORT_SYMBOL(v4l2_norm_to_name); -EXPORT_SYMBOL(v4l2_video_std_construct); - -EXPORT_SYMBOL(v4l2_prio_init); -EXPORT_SYMBOL(v4l2_prio_change); -EXPORT_SYMBOL(v4l2_prio_open); -EXPORT_SYMBOL(v4l2_prio_close); -EXPORT_SYMBOL(v4l2_prio_max); -EXPORT_SYMBOL(v4l2_prio_check); - -EXPORT_SYMBOL(v4l2_field_names); -EXPORT_SYMBOL(v4l2_type_names); -EXPORT_SYMBOL(v4l_printk_ioctl); - -EXPORT_SYMBOL(v4l2_ctrl_next); -EXPORT_SYMBOL(v4l2_ctrl_check); -EXPORT_SYMBOL(v4l2_ctrl_get_menu); -EXPORT_SYMBOL(v4l2_ctrl_query_menu); -EXPORT_SYMBOL(v4l2_ctrl_query_fill); -EXPORT_SYMBOL(v4l2_ctrl_query_fill_std); diff --git a/linux/drivers/media/video/videodev.c b/linux/drivers/media/video/videodev.c index 7aed73ee4..43cdb1de5 100644 --- a/linux/drivers/media/video/videodev.c +++ b/linux/drivers/media/video/videodev.c @@ -49,11 +49,374 @@ #include #endif #include +#include #include "compat.h" #define VIDEO_NUM_DEVICES 256 #define VIDEO_NAME "video4linux" +/* video4linux standard ID conversion to standard name + */ +char *v4l2_norm_to_name(v4l2_std_id id) +{ + char *name; + u32 myid = id; + + /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle + 64 bit comparations. So, on that architecture, with some gcc + variants, compilation fails. Currently, the max value is 30bit wide. + */ + BUG_ON(myid != id); + + switch (myid) { + case V4L2_STD_PAL: + name = "PAL"; + break; + case V4L2_STD_PAL_BG: + name = "PAL-BG"; + break; + case V4L2_STD_PAL_DK: + name = "PAL-DK"; + break; + case V4L2_STD_PAL_B: + name = "PAL-B"; + break; + case V4L2_STD_PAL_B1: + name = "PAL-B1"; + break; + case V4L2_STD_PAL_G: + name = "PAL-G"; + break; + case V4L2_STD_PAL_H: + name = "PAL-H"; + break; + case V4L2_STD_PAL_I: + name = "PAL-I"; + break; + case V4L2_STD_PAL_D: + name = "PAL-D"; + break; + case V4L2_STD_PAL_D1: + name = "PAL-D1"; + break; + case V4L2_STD_PAL_K: + name = "PAL-K"; + break; + case V4L2_STD_PAL_M: + name = "PAL-M"; + break; + case V4L2_STD_PAL_N: + name = "PAL-N"; + break; + case V4L2_STD_PAL_Nc: + name = "PAL-Nc"; + break; + case V4L2_STD_PAL_60: + name = "PAL-60"; + break; + case V4L2_STD_NTSC: + name = "NTSC"; + break; + case V4L2_STD_NTSC_M: + name = "NTSC-M"; + break; + case V4L2_STD_NTSC_M_JP: + name = "NTSC-M-JP"; + break; + case V4L2_STD_NTSC_443: + name = "NTSC-443"; + break; + case V4L2_STD_NTSC_M_KR: + name = "NTSC-M-KR"; + break; + case V4L2_STD_SECAM: + name = "SECAM"; + break; + case V4L2_STD_SECAM_DK: + name = "SECAM-DK"; + break; + case V4L2_STD_SECAM_B: + name = "SECAM-B"; + break; + case V4L2_STD_SECAM_D: + name = "SECAM-D"; + break; + case V4L2_STD_SECAM_G: + name = "SECAM-G"; + break; + case V4L2_STD_SECAM_H: + name = "SECAM-H"; + break; + case V4L2_STD_SECAM_K: + name = "SECAM-K"; + break; + case V4L2_STD_SECAM_K1: + name = "SECAM-K1"; + break; + case V4L2_STD_SECAM_L: + name = "SECAM-L"; + break; + case V4L2_STD_SECAM_LC: + name = "SECAM-LC"; + break; + default: + name = "Unknown"; + break; + } + + return name; +} +EXPORT_SYMBOL(v4l2_norm_to_name); + +/* Fill in the fields of a v4l2_standard structure according to the + 'id' and 'transmission' parameters. Returns negative on error. */ +int v4l2_video_std_construct(struct v4l2_standard *vs, + int id, char *name) +{ + u32 index = vs->index; + + memset(vs, 0, sizeof(struct v4l2_standard)); + vs->index = index; + vs->id = id; + if (id & V4L2_STD_525_60) { + vs->frameperiod.numerator = 1001; + vs->frameperiod.denominator = 30000; + vs->framelines = 525; + } else { + vs->frameperiod.numerator = 1; + vs->frameperiod.denominator = 25; + vs->framelines = 625; + } + strlcpy(vs->name, name, sizeof(vs->name)); + return 0; +} +EXPORT_SYMBOL(v4l2_video_std_construct); + +/* ----------------------------------------------------------------- */ +/* some arrays for pretty-printing debug messages of enum types */ + +char *v4l2_field_names[] = { + [V4L2_FIELD_ANY] = "any", + [V4L2_FIELD_NONE] = "none", + [V4L2_FIELD_TOP] = "top", + [V4L2_FIELD_BOTTOM] = "bottom", + [V4L2_FIELD_INTERLACED] = "interlaced", + [V4L2_FIELD_SEQ_TB] = "seq-tb", + [V4L2_FIELD_SEQ_BT] = "seq-bt", + [V4L2_FIELD_ALTERNATE] = "alternate", + [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb", + [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt", +}; +EXPORT_SYMBOL(v4l2_field_names); + +char *v4l2_type_names[] = { + [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap", + [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over", + [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out", + [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", + [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", + [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap", + [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", + [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over", +}; +EXPORT_SYMBOL(v4l2_type_names); + +static char *v4l2_memory_names[] = { + [V4L2_MEMORY_MMAP] = "mmap", + [V4L2_MEMORY_USERPTR] = "userptr", + [V4L2_MEMORY_OVERLAY] = "overlay", +}; + +#define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \ + arr[a] : "unknown") + +/* ------------------------------------------------------------------ */ +/* debug help functions */ + +#ifdef CONFIG_VIDEO_V4L1_COMPAT +static const char *v4l1_ioctls[] = { + [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP", + [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN", + [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN", + [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER", + [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER", + [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT", + [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT", + [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE", + [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN", + [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN", + [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF", + [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF", + [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY", + [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ", + [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ", + [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO", + [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO", + [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC", + [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE", + [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF", + [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT", + [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE", + [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE", + [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE", + [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE", + [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO", + [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE", + [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT", + [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT" +}; +#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) +#endif + +static const char *v4l2_ioctls[] = { + [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP", + [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED", + [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT", + [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT", + [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT", + [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS", + [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF", + [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF", + [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF", + [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY", + [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF", + [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF", + [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON", + [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF", + [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM", + [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM", + [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD", + [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD", + [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD", + [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT", + [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL", + [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL", + [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER", + [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER", + [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO", + [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO", + [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL", + [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU", + [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT", + [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT", + [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT", + [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT", + [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT", + [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT", + [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT", + [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR", + [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR", + [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY", + [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY", + [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP", + [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP", + [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP", + [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP", + [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP", + [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD", + [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT", + [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO", + [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT", + [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY", + [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY", + [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP", + [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS", + [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS", + [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS", + [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS", +#if 1 /*KEEP*/ + [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES", + [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS", + [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX", + [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD", + [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD", + + [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER", + [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", + + [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT", +#endif +}; +#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) + +static const char *v4l2_int_ioctls[] = { +#ifdef CONFIG_VIDEO_V4L1_COMPAT + [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES", + [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS", + [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM", + [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT", + [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT", + [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT", + [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE", + [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO", + [_IOC_NR(DECODER_INIT)] = "DECODER_INIT", + [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS", + [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP", +#endif + [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO", + + [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR", + [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY", + [_IOC_NR(TUNER_SET_CONFIG)] = "TUNER_SET_CONFIG", + + [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE", + [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET", + [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ", + [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE", + [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA", + [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA", + [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ", + [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY", + [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING", + [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING", + [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING", + [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING", + [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ", + [_IOC_NR(VIDIOC_INT_INIT)] = "VIDIOC_INT_INIT", + [_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)] = "VIDIOC_INT_G_STD_OUTPUT", + [_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)] = "VIDIOC_INT_S_STD_OUTPUT", +}; +#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls) + +/* Common ioctl debug function. This function can be used by + external ioctl messages as well as internal V4L ioctl */ +void v4l_printk_ioctl(unsigned int cmd) +{ + char *dir; + + switch (_IOC_DIR(cmd)) { + case _IOC_NONE: dir = "--"; break; + case _IOC_READ: dir = "r-"; break; + case _IOC_WRITE: dir = "-w"; break; + case _IOC_READ | _IOC_WRITE: dir = "rw"; break; + default: dir = "*ERR*"; break; + } + switch (_IOC_TYPE(cmd)) { + case 'd': + printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n", + (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ? + v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); + break; +#ifdef CONFIG_VIDEO_V4L1_COMPAT + case 'v': + printk("v4l1 ioctl %s, dir=%s (0x%08x)\n", + (_IOC_NR(cmd) < V4L1_IOCTLS) ? + v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); + break; +#endif + case 'V': + printk("v4l2 ioctl %s, dir=%s (0x%08x)\n", + (_IOC_NR(cmd) < V4L2_IOCTLS) ? + v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); + break; + + default: + printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n", + _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); + } +} +EXPORT_SYMBOL(v4l_printk_ioctl); + /* * sysfs stuff */ @@ -88,11 +451,13 @@ struct video_device *video_device_alloc(void) vfd = kzalloc(sizeof(*vfd),GFP_KERNEL); return vfd; } +EXPORT_SYMBOL(video_device_alloc); void video_device_release(struct video_device *vfd) { kfree(vfd); } +EXPORT_SYMBOL(video_device_release); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) static void video_release(struct class_device *cd) @@ -143,6 +508,7 @@ struct video_device* video_devdata(struct file *file) return video_device[iminor(file->f_path.dentry->d_inode)]; #endif } +EXPORT_SYMBOL(video_devdata); /* * Open a video device - FIXME: Obsoleted @@ -315,6 +681,7 @@ out: kfree(mbuf); return err; } +EXPORT_SYMBOL(video_usercopy); /* * open/release helper functions -- handle exclusive opens @@ -334,6 +701,7 @@ int video_exclusive_open(struct inode *inode, struct file *file) mutex_unlock(&vfl->lock); return retval; } +EXPORT_SYMBOL(video_exclusive_open); int video_exclusive_release(struct inode *inode, struct file *file) { @@ -342,41 +710,7 @@ int video_exclusive_release(struct inode *inode, struct file *file) vfl->users--; return 0; } - -static char *v4l2_memory_names[] = { - [V4L2_MEMORY_MMAP] = "mmap", - [V4L2_MEMORY_USERPTR] = "userptr", - [V4L2_MEMORY_OVERLAY] = "overlay", -}; - - -/* FIXME: Those stuff are replicated also on v4l2-common.c */ -static char *v4l2_type_names_FIXME[] = { - [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap", - [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over", - [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out", - [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", - [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", - [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", - [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture", - [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over", - [V4L2_BUF_TYPE_PRIVATE] = "private", -}; - -static char *v4l2_field_names_FIXME[] = { - [V4L2_FIELD_ANY] = "any", - [V4L2_FIELD_NONE] = "none", - [V4L2_FIELD_TOP] = "top", - [V4L2_FIELD_BOTTOM] = "bottom", - [V4L2_FIELD_INTERLACED] = "interlaced", - [V4L2_FIELD_SEQ_TB] = "seq-tb", - [V4L2_FIELD_SEQ_BT] = "seq-bt", - [V4L2_FIELD_ALTERNATE] = "alternate", - [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb", - [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt", -}; - -#define prt_names(a,arr) (((a)>=0)&&((a)timestamp.tv_sec%60), p->timestamp.tv_usec, p->index, - prt_names(p->type,v4l2_type_names_FIXME), - p->bytesused,p->flags, - p->field,p->sequence, - prt_names(p->memory,v4l2_memory_names), + prt_names(p->type, v4l2_type_names), + p->bytesused, p->flags, + p->field, p->sequence, + prt_names(p->memory, v4l2_memory_names), p->m.userptr, p->length); dbgarg2 ("timecode= %02d:%02d:%02d type=%d, " "flags=0x%08d, frames=%d, userbits=0x%08x\n", @@ -419,8 +753,8 @@ static inline void v4l_print_pix_fmt (struct video_device *vfd, (fmt->pixelformat >> 8) & 0xff, (fmt->pixelformat >> 16) & 0xff, (fmt->pixelformat >> 24) & 0xff, - prt_names(fmt->field,v4l2_field_names_FIXME), - fmt->bytesperline,fmt->sizeimage,fmt->colorspace); + prt_names(fmt->field, v4l2_field_names), + fmt->bytesperline, fmt->sizeimage, fmt->colorspace); }; @@ -634,7 +968,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, /* FIXME: Should be one dump per type */ dbgarg (cmd, "type=%s\n", prt_names(type, - v4l2_type_names_FIXME)); + v4l2_type_names)); switch (type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: @@ -687,7 +1021,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, /* FIXME: Should be one dump per type */ dbgarg (cmd, "type=%s\n", prt_names(f->type, - v4l2_type_names_FIXME)); + v4l2_type_names)); switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: @@ -739,7 +1073,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, /* FIXME: Should be one dump per type */ dbgarg (cmd, "type=%s\n", prt_names(f->type, - v4l2_type_names_FIXME)); + v4l2_type_names)); switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: if (vfd->vidioc_try_fmt_cap) @@ -805,8 +1139,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ret=vfd->vidioc_reqbufs(file, fh, p); dbgarg (cmd, "count=%d, type=%s, memory=%s\n", p->count, - prt_names(p->type,v4l2_type_names_FIXME), - prt_names(p->memory,v4l2_memory_names)); + prt_names(p->type, v4l2_type_names), + prt_names(p->memory, v4l2_memory_names)); break; } case VIDIOC_QUERYBUF: @@ -895,7 +1229,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, enum v4l2_buf_type i = *(int *)arg; if (!vfd->vidioc_streamon) break; - dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME)); + dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); ret=vfd->vidioc_streamon(file, fh,i); break; } @@ -905,7 +1239,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, if (!vfd->vidioc_streamoff) break; - dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME)); + dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); ret=vfd->vidioc_streamoff(file, fh, i); break; } @@ -1661,7 +1995,7 @@ out: kfree(mbuf); return err; } - +EXPORT_SYMBOL(video_ioctl2); static const struct file_operations video_fops; @@ -1809,6 +2143,7 @@ fail_minor: mutex_unlock(&videodev_lock); return ret; } +EXPORT_SYMBOL(video_register_device); /** * video_unregister_device - unregister a video4linux device @@ -1828,6 +2163,7 @@ void video_unregister_device(struct video_device *vfd) device_unregister(&vfd->class_dev); mutex_unlock(&videodev_lock); } +EXPORT_SYMBOL(video_unregister_device); /* * Video fs operations @@ -1872,16 +2208,6 @@ static void __exit videodev_exit(void) module_init(videodev_init) module_exit(videodev_exit) -EXPORT_SYMBOL(video_register_device); -EXPORT_SYMBOL(video_unregister_device); -EXPORT_SYMBOL(video_devdata); -EXPORT_SYMBOL(video_usercopy); -EXPORT_SYMBOL(video_exclusive_open); -EXPORT_SYMBOL(video_exclusive_release); -EXPORT_SYMBOL(video_ioctl2); -EXPORT_SYMBOL(video_device_alloc); -EXPORT_SYMBOL(video_device_release); - MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab "); MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2"); MODULE_LICENSE("GPL"); diff --git a/linux/include/media/v4l2-common.h b/linux/include/media/v4l2-common.h index d225eac1e..72ed0ddb2 100644 --- a/linux/include/media/v4l2-common.h +++ b/linux/include/media/v4l2-common.h @@ -67,8 +67,6 @@ v4l_client_printk(KERN_DEBUG, client, fmt , ## arg); \ } while (0) -/* Prints the ioctl in a human-readable format */ -extern void v4l_printk_ioctl(unsigned int cmd); /* Use this macro for non-I2C drivers. Pass the driver name as the first arg. */ #define v4l_print_ioctl(name, cmd) \ diff --git a/linux/include/media/v4l2-dev.h b/linux/include/media/v4l2-dev.h index 64918029f..fac381990 100644 --- a/linux/include/media/v4l2-dev.h +++ b/linux/include/media/v4l2-dev.h @@ -50,6 +50,8 @@ extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs); extern char *v4l2_norm_to_name(v4l2_std_id id); extern int v4l2_video_std_construct(struct v4l2_standard *vs, int id, char *name); +/* Prints the ioctl in a human-readable format */ +extern void v4l_printk_ioctl(unsigned int cmd); /* prority handling */ struct v4l2_prio_state { -- cgit v1.2.3 From ac9fa7bdbf76e9a529779421a6d76eef93d175f7 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 3 Feb 2008 17:58:26 -0500 Subject: tuner: return number of instances remaining after hybrid_tuner_release_state From: Michael Krufky Assign the number of instances remaining as the return value of hybrid_tuner_release_state, in case there is any extra cleanup that the tuner driver needs to do after an instance has been destroyed. Signed-off-by: Michael Krufky --- linux/drivers/media/video/tuner-i2c.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tuner-i2c.h b/linux/drivers/media/video/tuner-i2c.h index 8ec5b41d4..c53c327a4 100644 --- a/linux/drivers/media/video/tuner-i2c.h +++ b/linux/drivers/media/video/tuner-i2c.h @@ -155,13 +155,17 @@ __fail: \ __ret; \ }) -#define hybrid_tuner_release_state(state) do { \ +#define hybrid_tuner_release_state(state) \ +({ \ + int __ret; \ state->i2c_props.count--; \ + __ret = state->i2c_props.count; \ if (!state->i2c_props.count) { \ __tuner_info(state->i2c_props, "destroying instance\n");\ list_del(&state->hybrid_tuner_instance_list); \ kfree(state); \ } \ -} while (0) + __ret; \ +}) #endif /* __TUNER_I2C_H__ */ -- cgit v1.2.3 From c5c2eb47966f3a0686fb4b0584686b7db4cedfdc Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 2 Feb 2008 20:20:58 +0000 Subject: add parentheses From: Roel Kluin <12o3l@tiscali.nl> '!' has a higher priority than '&': bitanding has no effect. Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/tvaudio.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/tvaudio.c b/linux/drivers/media/video/tvaudio.c index fb155de1d..9ebe13fd7 100644 --- a/linux/drivers/media/video/tvaudio.c +++ b/linux/drivers/media/video/tvaudio.c @@ -1588,14 +1588,14 @@ static int tvaudio_get_ctrl(struct CHIPSTATE *chip, ctrl->value=chip->muted; return 0; case V4L2_CID_AUDIO_VOLUME: - if (!desc->flags & CHIP_HAS_VOLUME) + if (!(desc->flags & CHIP_HAS_VOLUME)) break; ctrl->value = max(chip->left,chip->right); return 0; case V4L2_CID_AUDIO_BALANCE: { int volume; - if (!desc->flags & CHIP_HAS_VOLUME) + if (!(desc->flags & CHIP_HAS_VOLUME)) break; volume = max(chip->left,chip->right); if (volume) @@ -1638,7 +1638,7 @@ static int tvaudio_set_ctrl(struct CHIPSTATE *chip, { int volume,balance; - if (!desc->flags & CHIP_HAS_VOLUME) + if (!(desc->flags & CHIP_HAS_VOLUME)) break; volume = max(chip->left,chip->right); @@ -1659,7 +1659,7 @@ static int tvaudio_set_ctrl(struct CHIPSTATE *chip, case V4L2_CID_AUDIO_BALANCE: { int volume, balance; - if (!desc->flags & CHIP_HAS_VOLUME) + if (!(desc->flags & CHIP_HAS_VOLUME)) break; volume = max(chip->left,chip->right); @@ -1719,7 +1719,7 @@ static int chip_command(struct i2c_client *client, break; case V4L2_CID_AUDIO_VOLUME: case V4L2_CID_AUDIO_BALANCE: - if (!desc->flags & CHIP_HAS_VOLUME) + if (!(desc->flags & CHIP_HAS_VOLUME)) return -EINVAL; break; case V4L2_CID_AUDIO_BASS: -- cgit v1.2.3 From 2ac7d509228d821c5949b801ade814005e270366 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jan 2008 17:24:26 +0000 Subject: V4L/DVB: constify function pointer tables From: Jan Engelhardt Signed-off-by: Jan Engelhardt Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-core/dvbdev.c | 2 +- linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c index 70b1bbe7f..c70cee304 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.c +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c @@ -108,7 +108,7 @@ static int dvb_device_open(struct inode *inode, struct file *file) } -static struct file_operations dvb_device_fops = +static const struct file_operations dvb_device_fops = { .owner = THIS_MODULE, .open = dvb_device_open, diff --git a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index b02eb601f..2e1572fb9 100644 --- a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -1017,7 +1017,7 @@ static int stc_release(struct inode *inode, struct file *file) return 0; } -static struct file_operations stc_fops = { +static const struct file_operations stc_fops = { .owner = THIS_MODULE, .read = stc_read, .open = stc_open, -- cgit v1.2.3 From 09389dcdc98375eac3c0e525aadc46b341f48385 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 11 Feb 2008 11:00:34 -0200 Subject: cx88-mpeg: Allow concurrent access to cx88-mpeg devices From: Roland Stoll It currently isn't possible to open the frontend device of cx88-mpeg devices (DVB or Blackbird) multiple times concurrently. (for instance, to attach a signal monitoring tool while reading a stream, or to send a frequency change ioctl) This patch fixes that condition. Signed-off-by: Roland Stoll Signed-off-by: Ricardo Cerqueira Reviewed-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/cx88/cx88-mpeg.c | 16 ++++++++++++---- linux/drivers/media/video/cx88/cx88.h | 1 + 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx88/cx88-mpeg.c b/linux/drivers/media/video/cx88/cx88-mpeg.c index 30ac9795b..399c3f1fc 100644 --- a/linux/drivers/media/video/cx88/cx88-mpeg.c +++ b/linux/drivers/media/video/cx88/cx88-mpeg.c @@ -667,13 +667,19 @@ static int cx8802_request_acquire(struct cx8802_driver *drv) struct cx88_core *core = drv->core; /* Fail a request for hardware if the device is busy. */ - if (core->active_type_id != CX88_BOARD_NONE) + if (core->active_type_id != CX88_BOARD_NONE && + core->active_type_id != drv->type_id) return -EBUSY; if (drv->advise_acquire) { - core->active_type_id = drv->type_id; - drv->advise_acquire(drv); + core->active_ref++; + mutex_lock(&drv->core->lock); + if (core->active_type_id == CX88_BOARD_NONE) { + core->active_type_id = drv->type_id; + drv->advise_acquire(drv); + } + mutex_unlock(&drv->core->lock); mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO)); } @@ -686,10 +692,12 @@ static int cx8802_request_release(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; - if (drv->advise_release) + if (drv->advise_release && --core->active_ref == 0) { + mutex_lock(&drv->core->lock); drv->advise_release(drv); core->active_type_id = CX88_BOARD_NONE; + mutex_unlock(&drv->core->lock); mpeg_dbg(1,"%s() Post release GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO)); } diff --git a/linux/drivers/media/video/cx88/cx88.h b/linux/drivers/media/video/cx88/cx88.h index ad0a86c15..bf1e2da46 100644 --- a/linux/drivers/media/video/cx88/cx88.h +++ b/linux/drivers/media/video/cx88/cx88.h @@ -346,6 +346,7 @@ struct cx88_core { /* cx88-video needs to access cx8802 for hybrid tuner pll access. */ struct cx8802_dev *dvbdev; enum cx88_board_type active_type_id; + int active_ref; }; struct cx8800_dev; -- cgit v1.2.3 From 3aed2dda85beece8f89e78d6a8412ec245a9b224 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 12 Feb 2008 02:54:33 +0000 Subject: xc5000: fix build error when built as module From: Tony Breeds drivers/built-in.o: In function `set_type': tuner-core.c:(.text+0x8879d): undefined reference to `xc5000_attach' Signed-off-by: Tony Breeds Reviewed-by: Michael Krufky Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/xc5000.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/xc5000.h b/linux/drivers/media/dvb/frontends/xc5000.h index e0e84562a..32a5f1c86 100644 --- a/linux/drivers/media/dvb/frontends/xc5000.h +++ b/linux/drivers/media/dvb/frontends/xc5000.h @@ -45,7 +45,8 @@ struct xc5000_config { /* xc5000 callback command */ #define XC5000_TUNER_RESET 0 -#if defined(CONFIG_DVB_TUNER_XC5000) || defined(CONFIG_DVB_TUNER_XC5000_MODULE) +#if defined(CONFIG_DVB_TUNER_XC5000) || \ + (defined(CONFIG_DVB_TUNER_XC5000_MODULE) && defined(MODULE)) extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct xc5000_config *cfg); -- cgit v1.2.3 From 4e1fb6e4fc1c61531db960676cee59c17496e2ea Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 11 Feb 2008 21:08:12 +0000 Subject: Lift videobuf-dma-sg's PCI dependency, until it is fixed From: Guennadi Liakhovetski videobuf-dma-sg.c should be converted to the generic DMA API to make it also useful for non-PCI configurations. Even now it can be used thanks to compatibility macros in include/asm-generic/pci-dma-compat.h. This has been verified to work on PXA270 CPU with the pxa_camera.c soc-camera driver. For this the following temporary work-around is needed. Signed-off-by: Guennadi Liakhovetski 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 71820ef4f..6ea1a01d0 100644 --- a/linux/drivers/media/Kconfig +++ b/linux/drivers/media/Kconfig @@ -160,7 +160,7 @@ config VIDEOBUF_GEN tristate config VIDEOBUF_DMA_SG - depends on PCI + depends on PCI || ARCH_PXA select VIDEOBUF_GEN tristate -- cgit v1.2.3 From f8e40c64095cef74bb5b1ab3f382a4f8d88975aa Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 13 Feb 2008 16:38:11 +0000 Subject: bttv: Fix overlay divide error. From: Robert Fitzsimons The initial work to convert the bttv driver to V4L2 "Partial conversion from V4L1 to V4L2" (e84619b17440ccca4e4db7583d126c4189b987e5), missed the line which set the appropriate overlay crop structure in the newly allocated bttv_buffer. This then causes a divide error in the bttv_calc_geo function. Signed-off-by: Robert Fitzsimons Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/bt8xx/bttv-driver.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux') diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index 063bbcc58..0a9e01627 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -2801,6 +2801,7 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on) if (on) { fh->ov.tvnorm = btv->tvnorm; new = videobuf_pci_alloc(sizeof(*new)); + new->crop = btv->crop[!!fh->do_crop].rect; bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); } else { new = NULL; -- cgit v1.2.3 From 5e50ed79abab16753c7949d61a5021eceecf3b80 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 13 Feb 2008 18:04:49 -0200 Subject: V4L, include ioctl.h in videodev headers From: Jiri Slaby Fix compilation of user processes which includes videodev*.h but not includes linux/ioctl.h: v4l2ext_helper.c: In function 'process_ioctl': v4l2ext_helper.c:183: warning: implicit declaration of function '_IOWR' v4l2ext_helper.c:183: error: expected expression before 'struct' v4l2ext_helper.c:183: error: case label does not reduce to an integer constant Signed-off-by: Jiri Slaby Signed-off-by: Mauro Carvalho Chehab --- linux/include/linux/videodev.h | 1 + linux/include/linux/videodev2.h | 1 + 2 files changed, 2 insertions(+) (limited to 'linux') diff --git a/linux/include/linux/videodev.h b/linux/include/linux/videodev.h index 52e3d5fd5..9385a566a 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 #if defined(CONFIG_VIDEO_V4L1_COMPAT) || !defined (__KERNEL__) diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index cbaf58c86..7e0126f03 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -62,6 +62,7 @@ #define __user #include #endif +#include #include /* -- cgit v1.2.3 From 4890c6c64ffcaed9a31fc856b2935f8417f339e7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 13 Feb 2008 18:50:59 -0200 Subject: Fix compat code to work with 2.6.24 From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/sound/pci/bt87x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/sound/pci/bt87x.c b/linux/sound/pci/bt87x.c index d1d91bbdc..ec58f2795 100644 --- a/linux/sound/pci/bt87x.c +++ b/linux/sound/pci/bt87x.c @@ -28,7 +28,7 @@ #include #include #include -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,24) #include #endif #include -- cgit v1.2.3 From 6494d36c801e81065cdfe9d1bf2b61b92e66111e Mon Sep 17 00:00:00 2001 From: Ricardo Cerqueira Date: Wed, 13 Feb 2008 22:41:15 +0000 Subject: cx88-mpeg: Fix race condition in variable access From: Ricardo Cerqueira There was a possible race condition in the increment/decrement of the active device references counter. Thanks to Trent Piepho (xyzzy@speakeasy.org) for bringing it up. Signed-off-by: Ricardo Cerqueira --- linux/drivers/media/video/cx88/cx88-mpeg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx88/cx88-mpeg.c b/linux/drivers/media/video/cx88/cx88-mpeg.c index 399c3f1fc..1f641273c 100644 --- a/linux/drivers/media/video/cx88/cx88-mpeg.c +++ b/linux/drivers/media/video/cx88/cx88-mpeg.c @@ -673,8 +673,8 @@ static int cx8802_request_acquire(struct cx8802_driver *drv) if (drv->advise_acquire) { - core->active_ref++; mutex_lock(&drv->core->lock); + core->active_ref++; if (core->active_type_id == CX88_BOARD_NONE) { core->active_type_id = drv->type_id; drv->advise_acquire(drv); @@ -692,14 +692,14 @@ static int cx8802_request_release(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; + mutex_lock(&drv->core->lock); if (drv->advise_release && --core->active_ref == 0) { - mutex_lock(&drv->core->lock); drv->advise_release(drv); core->active_type_id = CX88_BOARD_NONE; - mutex_unlock(&drv->core->lock); mpeg_dbg(1,"%s() Post release GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO)); } + mutex_unlock(&drv->core->lock); return 0; } -- cgit v1.2.3 From 469a8947e8aa139028418cffff8234abdbaf2b0d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 13 Feb 2008 23:52:48 -0200 Subject: Fix FM firmware loading From: Mauro Carvalho Chehab There's no need to load SCode table for FM. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/tuner-xc2028.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/tuner-xc2028.c b/linux/drivers/media/video/tuner-xc2028.c index 95cc51bb7..89bba71d9 100644 --- a/linux/drivers/media/video/tuner-xc2028.c +++ b/linux/drivers/media/video/tuner-xc2028.c @@ -767,6 +767,9 @@ skip_std_specific: goto check_device; } + if (new_fw.type & FM) + goto check_device; + /* Load SCODE firmware, if exists */ tuner_dbg("Trying to load scode %d\n", new_fw.scode_nr); -- cgit v1.2.3 From 7186cdeeb20a1eeb454b27f9de8b559b113c7959 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 14 Feb 2008 09:40:14 -0200 Subject: Add a missing kernel include at the building system From: Mauro Carvalho Chehab kernel-sync: Signed-off-by: Mauro Carvalho Chehab --- linux/include/linux/meye.h | 66 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 linux/include/linux/meye.h (limited to 'linux') diff --git a/linux/include/linux/meye.h b/linux/include/linux/meye.h new file mode 100644 index 000000000..39fd9c8dd --- /dev/null +++ b/linux/include/linux/meye.h @@ -0,0 +1,66 @@ +/* + * Motion Eye video4linux driver for Sony Vaio PictureBook + * + * Copyright (C) 2001-2003 Stelian Pop + * + * Copyright (C) 2001-2002 AlcĂ´ve + * + * Copyright (C) 2000 Andrew Tridgell + * + * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras. + * + * Some parts borrowed from various video4linux drivers, especially + * bttv-driver.c and zoran.c, see original files for credits. + * + * 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 _MEYE_H_ +#define _MEYE_H_ + +/****************************************************************************/ +/* Private API for handling mjpeg capture / playback. */ +/****************************************************************************/ + +struct meye_params { + unsigned char subsample; + unsigned char quality; + unsigned char sharpness; + unsigned char agc; + unsigned char picture; + unsigned char framerate; +}; + +/* query the extended parameters */ +#define MEYEIOC_G_PARAMS _IOR ('v', BASE_VIDIOCPRIVATE+0, struct meye_params) +/* set the extended parameters */ +#define MEYEIOC_S_PARAMS _IOW ('v', BASE_VIDIOCPRIVATE+1, struct meye_params) +/* queue a buffer for mjpeg capture */ +#define MEYEIOC_QBUF_CAPT _IOW ('v', BASE_VIDIOCPRIVATE+2, int) +/* sync a previously queued mjpeg buffer */ +#define MEYEIOC_SYNC _IOWR('v', BASE_VIDIOCPRIVATE+3, int) +/* get a still uncompressed snapshot */ +#define MEYEIOC_STILLCAPT _IO ('v', BASE_VIDIOCPRIVATE+4) +/* get a jpeg compressed snapshot */ +#define MEYEIOC_STILLJCAPT _IOR ('v', BASE_VIDIOCPRIVATE+5, int) + +/* V4L2 private controls */ +#define V4L2_CID_AGC V4L2_CID_PRIVATE_BASE +#define V4L2_CID_SHARPNESS (V4L2_CID_PRIVATE_BASE + 1) +#define V4L2_CID_PICTURE (V4L2_CID_PRIVATE_BASE + 2) +#define V4L2_CID_JPEGQUAL (V4L2_CID_PRIVATE_BASE + 3) +#define V4L2_CID_FRAMERATE (V4L2_CID_PRIVATE_BASE + 4) + +#endif -- cgit v1.2.3 From 5ec9bf43fd9880ac6ec829ad0e7f7903d4a8e1bb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 13 Feb 2008 21:57:54 +0000 Subject: remove V4L2_CID_SHARPNESS from meye.h and report private control as DISABLED From: Brandon Philips - Continue to support the V4L2_CID_PRIVATE_BASE + 1 control in the ABI - Report the same control as V4L2_CID_SHARPNESS - Report the private control disabled via QUERYCTRL Signed-off-by: Brandon Philips Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/meye.c | 10 +++++++++- linux/include/linux/meye.h | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/meye.c b/linux/drivers/media/video/meye.c index 5e00e1fe3..1613ffb54 100644 --- a/linux/drivers/media/video/meye.c +++ b/linux/drivers/media/video/meye.c @@ -1244,6 +1244,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, c->default_value = 48; c->flags = 0; break; + case V4L2_CID_MEYE_SHARPNESS: case V4L2_CID_SHARPNESS: c->type = V4L2_CTRL_TYPE_INTEGER; strcpy(c->name, "Sharpness"); @@ -1251,7 +1252,12 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, c->maximum = 63; c->step = 1; c->default_value = 32; - c->flags = 0; + + /* Continue to report legacy private SHARPNESS ctrl but + * say it is disabled in preference to ctrl in the spec + */ + c->flags = (c->id == V4L2_CID_SHARPNESS) ? 0 : + V4L2_CTRL_FLAG_DISABLED; break; case V4L2_CID_PICTURE: c->type = V4L2_CTRL_TYPE_INTEGER; @@ -1317,6 +1323,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, meye.params.agc = c->value; break; case V4L2_CID_SHARPNESS: + case V4L2_CID_MEYE_SHARPNESS: sony_pic_camera_command( SONY_PIC_COMMAND_SETCAMERASHARPNESS, c->value); meye.params.sharpness = c->value; @@ -1361,6 +1368,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, c->value = meye.params.agc; break; case V4L2_CID_SHARPNESS: + case V4L2_CID_MEYE_SHARPNESS: c->value = meye.params.sharpness; break; case V4L2_CID_PICTURE: diff --git a/linux/include/linux/meye.h b/linux/include/linux/meye.h index 39fd9c8dd..12010ace1 100644 --- a/linux/include/linux/meye.h +++ b/linux/include/linux/meye.h @@ -58,7 +58,7 @@ struct meye_params { /* V4L2 private controls */ #define V4L2_CID_AGC V4L2_CID_PRIVATE_BASE -#define V4L2_CID_SHARPNESS (V4L2_CID_PRIVATE_BASE + 1) +#define V4L2_CID_MEYE_SHARPNESS (V4L2_CID_PRIVATE_BASE + 1) #define V4L2_CID_PICTURE (V4L2_CID_PRIVATE_BASE + 2) #define V4L2_CID_JPEGQUAL (V4L2_CID_PRIVATE_BASE + 3) #define V4L2_CID_FRAMERATE (V4L2_CID_PRIVATE_BASE + 4) -- cgit v1.2.3 From 14709eca1644316f1fb628e14525e75dac44c591 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Wed, 13 Feb 2008 23:51:26 -0200 Subject: radio-si470x: Add kernel validation to mutex From: Douglas Schilling Landgraf Added kernel validation to support mutex/semaphore. (kernel < 2.6.16) Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/radio/radio-si470x.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index 772c3a126..d7fe70a00 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -114,7 +114,9 @@ #include #include "compat.h" #include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 16) #include +#endif #include #include #include @@ -432,7 +434,11 @@ struct si470x_device { /* RDS receive buffer */ struct delayed_work work; wait_queue_head_t read_queue; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 16) struct mutex lock; /* buffer locking */ +#else + struct semaphore lock; /* buffer locking */ +#endif unsigned char *buffer; /* size is always multiple of three */ unsigned int buf_size; unsigned int rd_index; -- cgit v1.2.3 From 792ee989bae4e2a54629b2b819619163297648ee Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Thu, 14 Feb 2008 00:13:36 -0200 Subject: radio-si470x: Add kernel validation to work queue From: Douglas Schilling Landgraf Added kernel validation to support work_struct/delayed_work. (kernel < 2.6.20) Signed-off-by: Douglas Schilling Landgraf --- linux/drivers/media/radio/radio-si470x.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index d7fe70a00..e999b2fc3 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -432,7 +432,12 @@ struct si470x_device { unsigned short registers[RADIO_REGISTER_NUM]; /* RDS receive buffer */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + struct work_struct work; +#else struct delayed_work work; +#endif + wait_queue_head_t read_queue; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 16) struct mutex lock; /* buffer locking */ -- cgit v1.2.3 From dfb32c854e17815d590d30adbe10c3c303e7f57c Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 14 Feb 2008 00:06:35 -0500 Subject: tda18271: remove duplicated channel configuration code from tda18271c1_tune From: Michael Krufky remove duplicated channel configuration code from tda18271c1_tune, instead call function tda18271_channel_configuration Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/tda18271-fe.c | 48 +------------------------ 1 file changed, 1 insertion(+), 47 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/tda18271-fe.c b/linux/drivers/media/dvb/frontends/tda18271-fe.c index 0e14552d0..c144a4a23 100644 --- a/linux/drivers/media/dvb/frontends/tda18271-fe.c +++ b/linux/drivers/media/dvb/frontends/tda18271-fe.c @@ -776,54 +776,8 @@ static int tda18271c1_tune(struct dvb_frontend *fe, if (0 == tda18271_calc_rf_cal(fe, &freq)) tda18271_write_regs(fe, R_EB14, 1); - /* Channel Configuration */ - - switch (priv->mode) { - case TDA18271_ANALOG: - regs[R_EB22] = 0x2c; - break; - case TDA18271_DIGITAL: - regs[R_EB22] = 0x37; - break; - } - tda18271_write_regs(fe, R_EB22, 1); - - regs[R_EP1] |= 0x40; /* set dis power level on */ - - /* set standard */ - regs[R_EP3] &= ~0x1f; /* clear std bits */ - - /* see table 22 */ - regs[R_EP3] |= std; - - regs[R_EP4] &= ~0x03; /* set cal mode to normal */ - - regs[R_EP4] &= ~0x1c; /* clear if level bits */ - switch (priv->mode) { - case TDA18271_ANALOG: - regs[R_MPD] &= ~0x80; /* IF notch = 0 */ - break; - case TDA18271_DIGITAL: - regs[R_EP4] |= 0x04; - regs[R_MPD] |= 0x80; - break; - } - - if (radio) - regs[R_EP4] |= 0x80; - else - regs[R_EP4] &= ~0x80; - - /* image rejection validity */ - tda18271_calc_ir_measure(fe, &freq); - - /* calculate MAIN PLL */ - N = freq + ifc; - - tda18271_calc_main_pll(fe, N); + tda18271_channel_configuration(fe, ifc, freq, bw, std, radio); - tda18271_write_regs(fe, R_TM, 15); - msleep(5); mutex_unlock(&priv->lock); return 0; -- cgit v1.2.3 From 4862d337c0d4d0b060bc36e525635ca72d8142a4 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 14 Feb 2008 00:07:57 -0500 Subject: tda18271: move rf calibration code from tda18271c1_tune into a new function From: Michael Krufky move rf calibration code from tda18271c1_tune into a new function, tda18271c1_rf_tracking_filter_calibration Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/tda18271-fe.c | 30 ++++++++++++++++--------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/tda18271-fe.c b/linux/drivers/media/dvb/frontends/tda18271-fe.c index c144a4a23..c5a44e77b 100644 --- a/linux/drivers/media/dvb/frontends/tda18271-fe.c +++ b/linux/drivers/media/dvb/frontends/tda18271-fe.c @@ -676,21 +676,13 @@ static int tda18271c2_tune(struct dvb_frontend *fe, /* ------------------------------------------------------------------ */ -static int tda18271c1_tune(struct dvb_frontend *fe, - u32 ifc, u32 freq, u32 bw, u8 std, int radio) +static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe, + u32 freq, u32 bw) { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; u32 N = 0; - tda18271_init(fe); - - mutex_lock(&priv->lock); - - tda_dbg("freq = %d, ifc = %d\n", freq, ifc); - - /* RF tracking filter calibration */ - /* calculate bp filter */ tda18271_calc_bp_filter(fe, &freq); tda18271_write_regs(fe, R_EP1, 1); @@ -761,7 +753,7 @@ static int tda18271c1_tune(struct dvb_frontend *fe, regs[R_EB7] = 0x40; tda18271_write_regs(fe, R_EB7, 1); - msleep(10); + msleep(10); /* pll locking */ regs[R_EB20] = 0xec; tda18271_write_regs(fe, R_EB20, 1); @@ -776,6 +768,22 @@ static int tda18271c1_tune(struct dvb_frontend *fe, if (0 == tda18271_calc_rf_cal(fe, &freq)) tda18271_write_regs(fe, R_EB14, 1); + return 0; +} + +static int tda18271c1_tune(struct dvb_frontend *fe, + u32 ifc, u32 freq, u32 bw, u8 std, int radio) +{ + struct tda18271_priv *priv = fe->tuner_priv; + + tda18271_init(fe); + + mutex_lock(&priv->lock); + + tda_dbg("freq = %d, ifc = %d\n", freq, ifc); + + tda18271c1_rf_tracking_filter_calibration(fe, freq, bw); + tda18271_channel_configuration(fe, ifc, freq, bw, std, radio); mutex_unlock(&priv->lock); -- cgit v1.2.3 From f66278931e5ad6cd06408f65716e6a9c151e1ed2 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 14 Feb 2008 01:17:02 -0500 Subject: tda18271: consolidate tune functions From: Michael Krufky combine tda18271c1_tune and tda18271c2_tune into a single function Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/tda18271-fe.c | 60 +++++++------------------ 1 file changed, 16 insertions(+), 44 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/tda18271-fe.c b/linux/drivers/media/dvb/frontends/tda18271-fe.c index c5a44e77b..304dfb3cc 100644 --- a/linux/drivers/media/dvb/frontends/tda18271-fe.c +++ b/linux/drivers/media/dvb/frontends/tda18271-fe.c @@ -215,8 +215,8 @@ static int tda18271_read_thermometer(struct dvb_frontend *fe) return tm; } -static int tda18271_rf_tracking_filters_correction(struct dvb_frontend *fe, - u32 freq) +static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe, + u32 freq) { struct tda18271_priv *priv = fe->tuner_priv; struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state; @@ -654,26 +654,6 @@ static int tda18271_init(struct dvb_frontend *fe) return 0; } -static int tda18271c2_tune(struct dvb_frontend *fe, - u32 ifc, u32 freq, u32 bw, u8 std, int radio) -{ - struct tda18271_priv *priv = fe->tuner_priv; - - tda_dbg("freq = %d, ifc = %d\n", freq, ifc); - - tda18271_init(fe); - - mutex_lock(&priv->lock); - - tda18271_rf_tracking_filters_correction(fe, freq); - - tda18271_channel_configuration(fe, ifc, freq, bw, std, radio); - - mutex_unlock(&priv->lock); - - return 0; -} - /* ------------------------------------------------------------------ */ static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe, @@ -771,41 +751,33 @@ static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe, return 0; } -static int tda18271c1_tune(struct dvb_frontend *fe, - u32 ifc, u32 freq, u32 bw, u8 std, int radio) +/* ------------------------------------------------------------------ */ + +static int tda18271_tune(struct dvb_frontend *fe, + u32 ifc, u32 freq, u32 bw, u8 std, int radio) { struct tda18271_priv *priv = fe->tuner_priv; + tda_dbg("freq = %d, ifc = %d, bw = %d, std = 0x%02x\n", + freq, ifc, bw, std); + tda18271_init(fe); mutex_lock(&priv->lock); - tda_dbg("freq = %d, ifc = %d\n", freq, ifc); - - tda18271c1_rf_tracking_filter_calibration(fe, freq, bw); - - tda18271_channel_configuration(fe, ifc, freq, bw, std, radio); - - mutex_unlock(&priv->lock); - - return 0; -} - -static inline int tda18271_tune(struct dvb_frontend *fe, - u32 ifc, u32 freq, u32 bw, u8 std, int radio) -{ - struct tda18271_priv *priv = fe->tuner_priv; - int ret = -EINVAL; - switch (priv->id) { case TDA18271HDC1: - ret = tda18271c1_tune(fe, ifc, freq, bw, std, radio); + tda18271c1_rf_tracking_filter_calibration(fe, freq, bw); break; case TDA18271HDC2: - ret = tda18271c2_tune(fe, ifc, freq, bw, std, radio); + tda18271c2_rf_tracking_filters_correction(fe, freq); break; } - return ret; + tda18271_channel_configuration(fe, ifc, freq, bw, std, radio); + + mutex_unlock(&priv->lock); + + return 0; } /* ------------------------------------------------------------------ */ -- cgit v1.2.3 From 6524b78cc55995e6f8fc4474f6ec3af840abc929 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 14 Feb 2008 01:29:32 -0500 Subject: tda18271: move init functions to directly above tda18271_tune From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/tda18271-fe.c | 78 ++++++++++++------------- 1 file changed, 38 insertions(+), 40 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/tda18271-fe.c b/linux/drivers/media/dvb/frontends/tda18271-fe.c index 304dfb3cc..dfa7456de 100644 --- a/linux/drivers/media/dvb/frontends/tda18271-fe.c +++ b/linux/drivers/media/dvb/frontends/tda18271-fe.c @@ -37,22 +37,6 @@ static LIST_HEAD(hybrid_tuner_instance_list); /*---------------------------------------------------------------------*/ -static int tda18271_ir_cal_init(struct dvb_frontend *fe) -{ - struct tda18271_priv *priv = fe->tuner_priv; - unsigned char *regs = priv->tda18271_regs; - - tda18271_read_regs(fe); - - /* test IR_CAL_OK to see if we need init */ - if ((regs[R_EP1] & 0x08) == 0) - tda18271_init_regs(fe); - - return 0; -} - -/* ------------------------------------------------------------------ */ - static int tda18271_channel_configuration(struct dvb_frontend *fe, u32 ifc, u32 freq, u32 bw, u8 std, int radio) @@ -215,6 +199,8 @@ static int tda18271_read_thermometer(struct dvb_frontend *fe) return tm; } +/* ------------------------------------------------------------------ */ + static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe, u32 freq) { @@ -611,7 +597,7 @@ static int tda18271_calc_rf_filter_curve(struct dvb_frontend *fe) /* ------------------------------------------------------------------ */ -static int tda18271_rf_cal_init(struct dvb_frontend *fe) +static int tda18271c2_rf_cal_init(struct dvb_frontend *fe) { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; @@ -634,28 +620,6 @@ static int tda18271_rf_cal_init(struct dvb_frontend *fe) return 0; } -static int tda18271_init(struct dvb_frontend *fe) -{ - struct tda18271_priv *priv = fe->tuner_priv; - - mutex_lock(&priv->lock); - - /* power up */ - tda18271_set_standby_mode(fe, 0, 0, 0); - - /* initialization */ - tda18271_ir_cal_init(fe); - - if (priv->id == TDA18271HDC2) - tda18271_rf_cal_init(fe); - - mutex_unlock(&priv->lock); - - return 0; -} - -/* ------------------------------------------------------------------ */ - static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe, u32 freq, u32 bw) { @@ -753,6 +717,40 @@ static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe, /* ------------------------------------------------------------------ */ +static int tda18271_ir_cal_init(struct dvb_frontend *fe) +{ + struct tda18271_priv *priv = fe->tuner_priv; + unsigned char *regs = priv->tda18271_regs; + + tda18271_read_regs(fe); + + /* test IR_CAL_OK to see if we need init */ + if ((regs[R_EP1] & 0x08) == 0) + tda18271_init_regs(fe); + + return 0; +} + +static int tda18271_init(struct dvb_frontend *fe) +{ + struct tda18271_priv *priv = fe->tuner_priv; + + mutex_lock(&priv->lock); + + /* power up */ + tda18271_set_standby_mode(fe, 0, 0, 0); + + /* initialization */ + tda18271_ir_cal_init(fe); + + if (priv->id == TDA18271HDC2) + tda18271c2_rf_cal_init(fe); + + mutex_unlock(&priv->lock); + + return 0; +} + static int tda18271_tune(struct dvb_frontend *fe, u32 ifc, u32 freq, u32 bw, u8 std, int radio) { @@ -1117,7 +1115,7 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, tda18271_init_regs(fe); if ((tda18271_cal_on_startup) && (priv->id == TDA18271HDC2)) - tda18271_rf_cal_init(fe); + tda18271c2_rf_cal_init(fe); mutex_unlock(&priv->lock); break; -- cgit v1.2.3 From 4c8a2017363238464550e721617b5a63d6608c9a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 14 Feb 2008 07:24:22 +0000 Subject: tuner-xc2028 depends on FW_LOADER. From: Paul Mundt Signed-off-by: Paul Mundt 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 6ea1a01d0..a86504587 100644 --- a/linux/drivers/media/Kconfig +++ b/linux/drivers/media/Kconfig @@ -102,7 +102,7 @@ if VIDEO_TUNER_CUSTOMIZE config TUNER_XC2028 tristate "XCeive xc2028/xc3028 tuners" - depends on I2C + depends on I2C && FW_LOADER default m if VIDEO_TUNER_CUSTOMIZE help Say Y here to include support for the xc2028/xc3028 tuners. -- cgit v1.2.3 From 9287d0a07352ef6599d03464082c2960b7aa435d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 15 Feb 2008 11:18:48 -0200 Subject: Fix dependencies for MT9M001 and MT9V022 From: Stephen Rothwell The MT9M001 and MT9V022 cameras must depend on GENERIC_GPIO since they include asm/gpio.h Signed-off-by: Stephen Rothwell Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index d9fc92a82..4e16d7f16 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -847,7 +847,7 @@ config SOC_CAMERA config SOC_CAMERA_MT9M001 tristate "mt9m001 support" - depends on SOC_CAMERA + depends on SOC_CAMERA && GENERIC_GPIO select GPIO_PCA953X if MT9M001_PCA9536_SWITCH help This driver supports MT9M001 cameras from Micron, monochrome @@ -862,7 +862,7 @@ config MT9M001_PCA9536_SWITCH config SOC_CAMERA_MT9V022 tristate "mt9v022 support" - depends on SOC_CAMERA + depends on SOC_CAMERA && GENERIC_GPIO select GPIO_PCA953X if MT9V022_PCA9536_SWITCH help This driver supports MT9V022 cameras from Micron -- cgit v1.2.3 From 82912e3b888a6232cc26dff49947c7ab36d96c5c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 15 Feb 2008 14:15:57 +0000 Subject: Replace NO_GPIO with gpio_is_valid() From: Guennadi Liakhovetski Upon suggestion by David Brownell use a gpio_is_valid() predicate instead of an explicit NO_GPIO macro. The respective patch to include/asm-generic/gpio.h has been accepted upstream. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/mt9m001.c | 10 +++++----- linux/drivers/media/video/mt9v022.c | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/mt9m001.c b/linux/drivers/media/video/mt9m001.c index 3c5867c37..b65ff7745 100644 --- a/linux/drivers/media/video/mt9m001.c +++ b/linux/drivers/media/video/mt9m001.c @@ -154,7 +154,7 @@ static int bus_switch_request(struct mt9m001 *mt9m001, int ret; unsigned int gpio = icl->gpio; - if (gpio != NO_GPIO) { + if (gpio_is_valid(gpio)) { /* We have a data bus switch. */ ret = gpio_request(gpio, "mt9m001"); if (ret < 0) { @@ -174,7 +174,7 @@ static int bus_switch_request(struct mt9m001 *mt9m001, mt9m001->switch_gpio = gpio; #else - mt9m001->switch_gpio = NO_GPIO; + mt9m001->switch_gpio = -EINVAL; #endif return 0; } @@ -182,7 +182,7 @@ static int bus_switch_request(struct mt9m001 *mt9m001, static void bus_switch_release(struct mt9m001 *mt9m001) { #ifdef CONFIG_MT9M001_PCA9536_SWITCH - if (mt9m001->switch_gpio != NO_GPIO) + if (gpio_is_valid(mt9m001->switch_gpio)) gpio_free(mt9m001->switch_gpio); #endif } @@ -190,7 +190,7 @@ static void bus_switch_release(struct mt9m001 *mt9m001) static int bus_switch_act(struct mt9m001 *mt9m001, int go8bit) { #ifdef CONFIG_MT9M001_PCA9536_SWITCH - if (mt9m001->switch_gpio == NO_GPIO) + if (!gpio_is_valid(mt9m001->switch_gpio)) return -ENODEV; gpio_set_value_cansleep(mt9m001->switch_gpio, go8bit); @@ -224,7 +224,7 @@ static int mt9m001_set_capture_format(struct soc_camera_device *icd, (mt9m001->datawidth != 9 && (width_flag == IS_DATAWIDTH_9)) || (mt9m001->datawidth != 8 && (width_flag == IS_DATAWIDTH_8))) { /* data width switch requested */ - if (mt9m001->switch_gpio == NO_GPIO) + if (!gpio_is_valid(mt9m001->switch_gpio)) return -EINVAL; /* Well, we actually only can do 10 or 8 bits... */ diff --git a/linux/drivers/media/video/mt9v022.c b/linux/drivers/media/video/mt9v022.c index 9b406e419..5fbeaa305 100644 --- a/linux/drivers/media/video/mt9v022.c +++ b/linux/drivers/media/video/mt9v022.c @@ -187,7 +187,7 @@ static int bus_switch_request(struct mt9v022 *mt9v022, struct soc_camera_link *i int ret; unsigned int gpio = icl->gpio; - if (gpio != NO_GPIO) { + if (gpio_is_valid(gpio)) { /* We have a data bus switch. */ ret = gpio_request(gpio, "mt9v022"); if (ret < 0) { @@ -206,7 +206,7 @@ static int bus_switch_request(struct mt9v022 *mt9v022, struct soc_camera_link *i mt9v022->switch_gpio = gpio; #else - mt9v022->switch_gpio = NO_GPIO; + mt9v022->switch_gpio = -EINVAL; #endif return 0; } @@ -214,7 +214,7 @@ static int bus_switch_request(struct mt9v022 *mt9v022, struct soc_camera_link *i static void bus_switch_release(struct mt9v022 *mt9v022) { #ifdef CONFIG_MT9V022_PCA9536_SWITCH - if (mt9v022->switch_gpio != NO_GPIO) + if (gpio_is_valid(mt9v022->switch_gpio)) gpio_free(mt9v022->switch_gpio); #endif } @@ -222,7 +222,7 @@ static void bus_switch_release(struct mt9v022 *mt9v022) static int bus_switch_act(struct mt9v022 *mt9v022, int go8bit) { #ifdef CONFIG_MT9V022_PCA9536_SWITCH - if (mt9v022->switch_gpio == NO_GPIO) + if (!gpio_is_valid(mt9v022->switch_gpio)) return -ENODEV; gpio_set_value_cansleep(mt9v022->switch_gpio, go8bit); @@ -303,7 +303,7 @@ static int mt9v022_set_capture_format(struct soc_camera_device *icd, (mt9v022->datawidth != 9 && (width_flag == IS_DATAWIDTH_9)) || (mt9v022->datawidth != 8 && (width_flag == IS_DATAWIDTH_8))) { /* data width switch requested */ - if (mt9v022->switch_gpio == NO_GPIO) + if (!gpio_is_valid(mt9v022->switch_gpio)) return -EINVAL; /* Well, we actually only can do 10 or 8 bits... */ -- cgit v1.2.3 From a47972fa9d14e12d1adf54ecd767f7c1ce372b36 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 15 Feb 2008 14:17:03 +0000 Subject: Fix breakage in mt9m001 and mt9v022 driver if "CONFIG_GENERIC_GPIO is not set" From: Guennadi Liakhovetski Both camera drivers can function without GPIO support, in which case they will only support the 10 bit data width mode. But the two respective switch have to depend on CONFIG_GENERIC_GPIO. Additionally remove redundant gpio_is_valid tests - they are repeated in bus_switch_request() functions. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/Kconfig | 4 ++-- linux/drivers/media/video/mt9m001.c | 6 ++---- linux/drivers/media/video/mt9v022.c | 6 ++---- 3 files changed, 6 insertions(+), 10 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 4e16d7f16..1e97bc16e 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -855,7 +855,7 @@ config SOC_CAMERA_MT9M001 config MT9M001_PCA9536_SWITCH bool "pca9536 datawidth switch for mt9m001" - depends on SOC_CAMERA_MT9M001 + depends on SOC_CAMERA_MT9M001 && GENERIC_GPIO help Select this if your MT9M001 camera uses a PCA9536 I2C GPIO extender to switch between 8 and 10 bit datawidth modes @@ -869,7 +869,7 @@ config SOC_CAMERA_MT9V022 config MT9V022_PCA9536_SWITCH bool "pca9536 datawidth switch for mt9v022" - depends on SOC_CAMERA_MT9V022 + depends on SOC_CAMERA_MT9V022 && GENERIC_GPIO help Select this if your MT9V022 camera uses a PCA9536 I2C GPIO extender to switch between 8 and 10 bit datawidth modes diff --git a/linux/drivers/media/video/mt9m001.c b/linux/drivers/media/video/mt9m001.c index b65ff7745..e3afc8205 100644 --- a/linux/drivers/media/video/mt9m001.c +++ b/linux/drivers/media/video/mt9m001.c @@ -17,7 +17,9 @@ #include #include +#ifdef CONFIG_MT9M001_PCA9536_SWITCH #include +#endif /* mt9m001 i2c address 0x5d * The platform has to define i2c_board_info @@ -223,10 +225,6 @@ static int mt9m001_set_capture_format(struct soc_camera_device *icd, if ((mt9m001->datawidth != 10 && (width_flag == IS_DATAWIDTH_10)) || (mt9m001->datawidth != 9 && (width_flag == IS_DATAWIDTH_9)) || (mt9m001->datawidth != 8 && (width_flag == IS_DATAWIDTH_8))) { - /* data width switch requested */ - if (!gpio_is_valid(mt9m001->switch_gpio)) - return -EINVAL; - /* Well, we actually only can do 10 or 8 bits... */ if (width_flag == IS_DATAWIDTH_9) return -EINVAL; diff --git a/linux/drivers/media/video/mt9v022.c b/linux/drivers/media/video/mt9v022.c index 5fbeaa305..468333946 100644 --- a/linux/drivers/media/video/mt9v022.c +++ b/linux/drivers/media/video/mt9v022.c @@ -18,7 +18,9 @@ #include #include +#ifdef CONFIG_MT9M001_PCA9536_SWITCH #include +#endif /* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c * The platform has to define i2c_board_info @@ -302,10 +304,6 @@ static int mt9v022_set_capture_format(struct soc_camera_device *icd, if ((mt9v022->datawidth != 10 && (width_flag == IS_DATAWIDTH_10)) || (mt9v022->datawidth != 9 && (width_flag == IS_DATAWIDTH_9)) || (mt9v022->datawidth != 8 && (width_flag == IS_DATAWIDTH_8))) { - /* data width switch requested */ - if (!gpio_is_valid(mt9v022->switch_gpio)) - return -EINVAL; - /* Well, we actually only can do 10 or 8 bits... */ if (width_flag == IS_DATAWIDTH_9) return -EINVAL; -- cgit v1.2.3 From 18ac0ef62eca3a89e0bf1f3c23bb7004e760d15b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 15 Feb 2008 16:41:06 -0200 Subject: zoran: Fix namespace conflicts with Zoran 'GPIO_MAX' enum From: Mauro Carvalho Chehab Thanks to Martin Michlmayr for reporting this issue: The zoran driver fails to compile on the ARM Orion platform with: In file included from drivers/media/video/zoran_procfs.c:50: drivers/media/video/zoran.h:232: error: expected identifier before numeric constant The reason is that drivers/media/video/zoran.h defines an enum with GPIO_MAX in it, but Orion contains a #define GPIO_MAX 32 in include/asm-arm/arch-orion/orion.h Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/zoran.h | 22 +++++++++++----------- linux/drivers/media/video/zoran_device.c | 12 ++++++------ 2 files changed, 17 insertions(+), 17 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/zoran.h b/linux/drivers/media/video/zoran.h index 19810ca14..848dbcf25 100644 --- a/linux/drivers/media/video/zoran.h +++ b/linux/drivers/media/video/zoran.h @@ -221,15 +221,15 @@ enum zoran_map_mode { }; enum gpio_type { - GPIO_JPEG_SLEEP = 0, - GPIO_JPEG_RESET, - GPIO_JPEG_FRAME, - GPIO_VID_DIR, - GPIO_VID_EN, - GPIO_VID_RESET, - GPIO_CLK_SEL1, - GPIO_CLK_SEL2, - GPIO_MAX, + ZR_GPIO_JPEG_SLEEP = 0, + ZR_GPIO_JPEG_RESET, + ZR_GPIO_JPEG_FRAME, + ZR_GPIO_VID_DIR, + ZR_GPIO_VID_EN, + ZR_GPIO_VID_RESET, + ZR_GPIO_CLK_SEL1, + ZR_GPIO_CLK_SEL2, + ZR_GPIO_MAX, }; enum gpcs_type { @@ -378,11 +378,11 @@ struct card_info { u32 jpeg_int; /* JPEG interrupt */ u32 vsync_int; /* VSYNC interrupt */ - s8 gpio[GPIO_MAX]; + s8 gpio[ZR_GPIO_MAX]; u8 gpcs[GPCS_MAX]; struct vfe_polarity vfe_pol; - u8 gpio_pol[GPIO_MAX]; + u8 gpio_pol[ZR_GPIO_MAX]; /* is the /GWS line conected? */ u8 gws_not_connected; diff --git a/linux/drivers/media/video/zoran_device.c b/linux/drivers/media/video/zoran_device.c index b7f62ee8a..ed7ab4be2 100644 --- a/linux/drivers/media/video/zoran_device.c +++ b/linux/drivers/media/video/zoran_device.c @@ -252,7 +252,7 @@ void jpeg_codec_sleep (struct zoran *zr, int sleep) { - GPIO(zr, zr->card.gpio[GPIO_JPEG_SLEEP], !sleep); + GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_SLEEP], !sleep); if (!sleep) { dprintk(3, KERN_DEBUG @@ -279,9 +279,9 @@ jpeg_codec_reset (struct zoran *zr) 0); udelay(2); } else { - GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 0); + GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 0); udelay(2); - GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 1); + GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 1); udelay(2); } @@ -690,7 +690,7 @@ static inline void set_frame (struct zoran *zr, int val) { - GPIO(zr, zr->card.gpio[GPIO_JPEG_FRAME], val); + GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_FRAME], val); } static void @@ -706,8 +706,8 @@ set_videobus_dir (struct zoran *zr, GPIO(zr, 5, 1); break; default: - GPIO(zr, zr->card.gpio[GPIO_VID_DIR], - zr->card.gpio_pol[GPIO_VID_DIR] ? !val : val); + GPIO(zr, zr->card.gpio[ZR_GPIO_VID_DIR], + zr->card.gpio_pol[ZR_GPIO_VID_DIR] ? !val : val); break; } } -- cgit v1.2.3