aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-05 16:36:30 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-05 16:36:30 -0700
commitf4d33337eac4007793ca11fd1ab68d91ce7aa762 (patch)
treeb775ad213179822225a3e1c1a27e4cc16f8aff68 /drivers/staging
parent91c2ff7708d4edf73ef1f0abb3ea4a44b4b0cf1d (diff)
parent0f3bf3dc1ca394a8385079a5653088672b65c5c4 (diff)
downloadlinux-stericsson-f4d33337eac4007793ca11fd1ab68d91ce7aa762.tar.gz
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - removal of sn9c102. This device driver was replaced a long time ago by gspca - solo6x10 and go7007 webcam drivers moved from staging into mainstream. They were waiting for an API to allow setting the image detection matrix - SDR drivers moved from staging into mainstream: sdr-msi3101 (renamed as msi2500) and rtl2832 - added SDR driver for airspy - added demux driver: si2165 - rework at several RC subsystem, making the code for RC-5 SZ variant to be added at the standard RC5 decoder - added decoder for the XMP IR protocol - tuner driver moved from staging into mainstream: msi3101 (renamed as msi001) - added documentation for some additional SDR pixfmt - some device tree bindings documented - added support for exynos3250 at s5p-jpeg - remove the obsolete, unmaintained and broken mx1_camera driver - added support for remote controllers at au0828 driver - added a RC driver: sunxi-cir - several driver fixes, enhancements and cleanups. * 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (455 commits) [media] cx23885: fix UNSET/TUNER_ABSENT confusion [media] coda: fix build error by making reset control optional [media] radio-miropcm20: fix sparse NULL pointer warning [media] MAINTAINERS: Update go7007 pattern [media] MAINTAINERS: Update solo6x10 patterns [media] media: atmel-isi: add primary DT support [media] media: atmel-isi: convert the pdata from pointer to structure [media] media: atmel-isi: add v4l2 async probe support [media] rcar_vin: add devicetree support [media] media: pxa_camera device-tree support [media] media: mt9m111: add device-tree suppport [media] soc_camera: add support for dt binding soc_camera drivers [media] media: soc_camera: pxa_camera documentation device-tree support [media] media: mt9m111: add device-tree documentation [media] s5p-mfc: remove unnecessary calling to function video_devdata() [media] s5p-jpeg: add chroma subsampling adjustment for Exynos3250 [media] s5p-jpeg: Prevent erroneous downscaling for Exynos3250 SoC [media] s5p-jpeg: Assure proper crop rectangle initialization [media] s5p-jpeg: fix g_selection op [media] s5p-jpeg: Adjust jpeg_bound_align_image to Exynos3250 needs ...
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/media/Kconfig10
-rw-r--r--drivers/staging/media/Makefile5
-rw-r--r--drivers/staging/media/bcm2048/radio-bcm2048.c22
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_ipipe.c2
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h1
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_ipipeif.c5
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_resizer.c4
-rw-r--r--drivers/staging/media/davinci_vpfe/vpfe_video.c1
-rw-r--r--drivers/staging/media/go7007/Kconfig51
-rw-r--r--drivers/staging/media/go7007/Makefile15
-rw-r--r--drivers/staging/media/go7007/README137
-rw-r--r--drivers/staging/media/go7007/go7007-driver.c711
-rw-r--r--drivers/staging/media/go7007/go7007-fw.c1628
-rw-r--r--drivers/staging/media/go7007/go7007-i2c.c222
-rw-r--r--drivers/staging/media/go7007/go7007-loader.c145
-rw-r--r--drivers/staging/media/go7007/go7007-priv.h294
-rw-r--r--drivers/staging/media/go7007/go7007-usb.c1349
-rw-r--r--drivers/staging/media/go7007/go7007-v4l2.c1055
-rw-r--r--drivers/staging/media/go7007/go7007.h40
-rw-r--r--drivers/staging/media/go7007/go7007.txt478
-rw-r--r--drivers/staging/media/go7007/s2250-board.c631
-rw-r--r--drivers/staging/media/go7007/saa7134-go7007.c567
-rw-r--r--drivers/staging/media/go7007/snd-go7007.c302
-rw-r--r--drivers/staging/media/lirc/lirc_igorplugusb.c6
-rw-r--r--drivers/staging/media/lirc/lirc_imon.c9
-rw-r--r--drivers/staging/media/lirc/lirc_parallel.c32
-rw-r--r--drivers/staging/media/lirc/lirc_serial.c37
-rw-r--r--drivers/staging/media/msi3101/Kconfig10
-rw-r--r--drivers/staging/media/msi3101/Makefile2
-rw-r--r--drivers/staging/media/msi3101/msi001.c500
-rw-r--r--drivers/staging/media/msi3101/sdr-msi3101.c1518
-rw-r--r--drivers/staging/media/omap4iss/iss.c86
-rw-r--r--drivers/staging/media/omap4iss/iss.h2
-rw-r--r--drivers/staging/media/omap4iss/iss_csi2.c2
-rw-r--r--drivers/staging/media/omap4iss/iss_video.c22
-rw-r--r--drivers/staging/media/rtl2832u_sdr/Kconfig7
-rw-r--r--drivers/staging/media/rtl2832u_sdr/Makefile6
-rw-r--r--drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c1497
-rw-r--r--drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h54
-rw-r--r--drivers/staging/media/sn9c102/Kconfig17
-rw-r--r--drivers/staging/media/sn9c102/Makefile15
-rw-r--r--drivers/staging/media/sn9c102/sn9c102.h214
-rw-r--r--drivers/staging/media/sn9c102/sn9c102.txt592
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_config.h86
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_core.c3465
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_devtable.h145
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_hv7131d.c269
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_hv7131r.c369
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_mi0343.c352
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_mi0360.c453
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_mt9v111.c260
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_ov7630.c634
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_ov7660.c546
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_pas106b.c308
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_pas202bcb.c340
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_sensor.h307
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_tas5110c1b.c154
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_tas5110d.c119
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_tas5130d1b.c165
-rw-r--r--drivers/staging/media/solo6x10/Kconfig18
-rw-r--r--drivers/staging/media/solo6x10/Makefile5
-rw-r--r--drivers/staging/media/solo6x10/TODO15
-rw-r--r--drivers/staging/media/solo6x10/solo6x10-core.c709
-rw-r--r--drivers/staging/media/solo6x10/solo6x10-disp.c322
-rw-r--r--drivers/staging/media/solo6x10/solo6x10-eeprom.c154
-rw-r--r--drivers/staging/media/solo6x10/solo6x10-enc.c344
-rw-r--r--drivers/staging/media/solo6x10/solo6x10-g723.c424
-rw-r--r--drivers/staging/media/solo6x10/solo6x10-gpio.c109
-rw-r--r--drivers/staging/media/solo6x10/solo6x10-i2c.c334
-rw-r--r--drivers/staging/media/solo6x10/solo6x10-jpeg.h193
-rw-r--r--drivers/staging/media/solo6x10/solo6x10-offsets.h87
-rw-r--r--drivers/staging/media/solo6x10/solo6x10-p2m.c333
-rw-r--r--drivers/staging/media/solo6x10/solo6x10-regs.h639
-rw-r--r--drivers/staging/media/solo6x10/solo6x10-tw28.c874
-rw-r--r--drivers/staging/media/solo6x10/solo6x10-tw28.h69
-rw-r--r--drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c1414
-rw-r--r--drivers/staging/media/solo6x10/solo6x10-v4l2.c734
-rw-r--r--drivers/staging/media/solo6x10/solo6x10.h426
78 files changed, 67 insertions, 27411 deletions
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
index a9f2e63a7c9c..3323eb5e77b0 100644
--- a/drivers/staging/media/Kconfig
+++ b/drivers/staging/media/Kconfig
@@ -29,20 +29,10 @@ source "drivers/staging/media/davinci_vpfe/Kconfig"
source "drivers/staging/media/dt3155v4l/Kconfig"
-source "drivers/staging/media/go7007/Kconfig"
-
-source "drivers/staging/media/msi3101/Kconfig"
-
source "drivers/staging/media/omap24xx/Kconfig"
-source "drivers/staging/media/sn9c102/Kconfig"
-
-source "drivers/staging/media/solo6x10/Kconfig"
-
source "drivers/staging/media/omap4iss/Kconfig"
-source "drivers/staging/media/rtl2832u_sdr/Kconfig"
-
# Keep LIRC at the end, as it has sub-menus
source "drivers/staging/media/lirc/Kconfig"
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
index 8e2c5d272162..7db83f373f63 100644
--- a/drivers/staging/media/Makefile
+++ b/drivers/staging/media/Makefile
@@ -2,14 +2,9 @@ obj-$(CONFIG_DVB_AS102) += as102/
obj-$(CONFIG_I2C_BCM2048) += bcm2048/
obj-$(CONFIG_DVB_CXD2099) += cxd2099/
obj-$(CONFIG_LIRC_STAGING) += lirc/
-obj-$(CONFIG_SOLO6X10) += solo6x10/
obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/
-obj-$(CONFIG_VIDEO_GO7007) += go7007/
-obj-$(CONFIG_USB_MSI3101) += msi3101/
obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/
obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/
-obj-$(CONFIG_USB_SN9C102) += sn9c102/
obj-$(CONFIG_VIDEO_OMAP2) += omap24xx/
obj-$(CONFIG_VIDEO_TCM825X) += omap24xx/
-obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832u_sdr/
diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c
index bbf236e842a9..2bba370a47ca 100644
--- a/drivers/staging/media/bcm2048/radio-bcm2048.c
+++ b/drivers/staging/media/bcm2048/radio-bcm2048.c
@@ -369,13 +369,12 @@ static int bcm2048_send_command(struct bcm2048_device *bdev, unsigned int reg,
data[0] = reg & 0xff;
data[1] = value & 0xff;
- if (i2c_master_send(client, data, 2) == 2) {
+ if (i2c_master_send(client, data, 2) == 2)
return 0;
- } else {
- dev_err(&bdev->client->dev, "BCM I2C error!\n");
- dev_err(&bdev->client->dev, "Is Bluetooth up and running?\n");
- return -EIO;
- }
+
+ dev_err(&bdev->client->dev, "BCM I2C error!\n");
+ dev_err(&bdev->client->dev, "Is Bluetooth up and running?\n");
+ return -EIO;
}
static int bcm2048_recv_command(struct bcm2048_device *bdev, unsigned int reg,
@@ -725,8 +724,8 @@ static int bcm2048_get_fm_deemphasis(struct bcm2048_device *bdev)
if (!err) {
if (value & BCM2048_DE_EMPHASIS_SELECT)
return BCM2048_DE_EMPHASIS_75us;
- else
- return BCM2048_DE_EMPHASIS_50us;
+
+ return BCM2048_DE_EMPHASIS_50us;
}
return err;
@@ -1971,7 +1970,8 @@ static ssize_t bcm2048_##prop##_write(struct device *dev, \
if (!bdev) \
return -ENODEV; \
\
- sscanf(buf, mask, &value); \
+ if (sscanf(buf, mask, &value) != 1) \
+ return -EINVAL; \
\
if (check) \
return -EDOM; \
@@ -2242,6 +2242,7 @@ static ssize_t bcm2048_fops_read(struct file *file, char __user *buf,
i = 0;
while (i < count) {
unsigned char tmpbuf[3];
+
tmpbuf[i] = bdev->rds_info.radio_text[bdev->rd_index+i+2];
tmpbuf[i+1] = bdev->rds_info.radio_text[bdev->rd_index+i+1];
tmpbuf[i+2] = ((bdev->rds_info.radio_text[bdev->rd_index+i]
@@ -2598,7 +2599,6 @@ static int bcm2048_i2c_driver_probe(struct i2c_client *client,
bdev = kzalloc(sizeof(*bdev), GFP_KERNEL);
if (!bdev) {
- dev_dbg(&client->dev, "Failed to alloc video device.\n");
err = -ENOMEM;
goto exit;
}
@@ -2618,7 +2618,7 @@ static int bcm2048_i2c_driver_probe(struct i2c_client *client,
if (client->irq) {
err = request_irq(client->irq,
- bcm2048_handler, IRQF_TRIGGER_FALLING | IRQF_DISABLED,
+ bcm2048_handler, IRQF_TRIGGER_FALLING,
client->name, bdev);
if (err < 0) {
dev_err(&client->dev, "Could not request IRQ\n");
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
index b7044a380fe3..bdc7f005b3ba 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
@@ -1268,6 +1268,7 @@ static int ipipe_s_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg)
for (i = 0; i < ARRAY_SIZE(ipipe_modules); i++) {
unsigned int bit = 1 << i;
+
if (cfg->flag & bit) {
const struct ipipe_module_if *module_if =
&ipipe_modules[i];
@@ -1310,6 +1311,7 @@ static int ipipe_g_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg)
for (i = 1; i < ARRAY_SIZE(ipipe_modules); i++) {
unsigned int bit = 1 << i;
+
if (cfg->flag & bit) {
const struct ipipe_module_if *module_if =
&ipipe_modules[i];
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h
index 010fdb247faf..81176fb9d164 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h
@@ -479,7 +479,6 @@
#define RSZ_TYP_Y_SHIFT 0
#define RSZ_TYP_C_SHIFT 1
#define RSZ_LPF_INT_MASK 0x3f
-#define RSZ_LPF_INT_MASK 0x3f
#define RSZ_LPF_INT_C_SHIFT 6
#define RSZ_H_PHS_MASK 0x3fff
#define RSZ_H_DIF_MASK 0x3fff
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
index 59540cd4bb98..6d4893b44c1f 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
@@ -196,6 +196,7 @@ static int ipipeif_hw_setup(struct v4l2_subdev *sd)
int data_shift;
int pack_mode;
int source1;
+ int tmp;
ipipeif_base_addr = ipipeif->ipipeif_base_addr;
@@ -206,8 +207,8 @@ static int ipipeif_hw_setup(struct v4l2_subdev *sd)
outformat = &ipipeif->formats[IPIPEIF_PAD_SOURCE];
/* Combine all the fields to make CFG1 register of IPIPEIF */
- val = get_oneshot_mode(ipipeif->input);
- if (val < 0) {
+ tmp = val = get_oneshot_mode(ipipeif->input);
+ if (tmp < 0) {
pr_err("ipipeif: links setup required");
return -EINVAL;
}
diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
index 8e13bd494c98..8828d6c2aab1 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
@@ -219,7 +219,7 @@ configure_resizer_out_params(struct vpfe_resizer_device *resizer, int index,
* @resizer: Pointer to VPFE resizer subdevice.
* @index: index RSZ_A-resizer-A RSZ_B-resizer-B.
*/
-void
+static void
resizer_calculate_resize_ratios(struct vpfe_resizer_device *resizer, int index)
{
struct resizer_params *param = &resizer->config;
@@ -310,7 +310,7 @@ resizer_calculate_sdram_offsets(struct vpfe_resizer_device *resizer, int index)
return 0;
}
-int resizer_configure_output_win(struct vpfe_resizer_device *resizer)
+static int resizer_configure_output_win(struct vpfe_resizer_device *resizer)
{
struct resizer_params *param = &resizer->config;
struct vpfe_rsz_output_spec output_specs;
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
index d95c427043d4..6f9171c39bdc 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c
@@ -1606,7 +1606,6 @@ int vpfe_video_init(struct vpfe_video_device *video, const char *name)
if (ret < 0)
return ret;
- set_bit(V4L2_FL_USE_FH_PRIO, &video->video_dev.flags);
video_set_drvdata(&video->video_dev, video);
return 0;
diff --git a/drivers/staging/media/go7007/Kconfig b/drivers/staging/media/go7007/Kconfig
deleted file mode 100644
index 95a3af644a92..000000000000
--- a/drivers/staging/media/go7007/Kconfig
+++ /dev/null
@@ -1,51 +0,0 @@
-config VIDEO_GO7007
- tristate "WIS GO7007 MPEG encoder support"
- depends on VIDEO_DEV && I2C
- depends on SND && USB
- select VIDEOBUF2_VMALLOC
- select VIDEO_TUNER
- select CYPRESS_FIRMWARE
- select SND_PCM
- select VIDEO_SONY_BTF_MPX if MEDIA_SUBDRV_AUTOSELECT
- select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT
- select VIDEO_TW2804 if MEDIA_SUBDRV_AUTOSELECT
- select VIDEO_TW9903 if MEDIA_SUBDRV_AUTOSELECT
- select VIDEO_TW9906 if MEDIA_SUBDRV_AUTOSELECT
- select VIDEO_OV7640 if MEDIA_SUBDRV_AUTOSELECT
- select VIDEO_UDA1342 if MEDIA_SUBDRV_AUTOSELECT
- ---help---
- This is a video4linux driver for the WIS GO7007 MPEG
- encoder chip.
-
- To compile this driver as a module, choose M here: the
- module will be called go7007.
-
-config VIDEO_GO7007_USB
- tristate "WIS GO7007 USB support"
- depends on VIDEO_GO7007 && USB
- ---help---
- This is a video4linux driver for the WIS GO7007 MPEG
- encoder chip over USB.
-
- To compile this driver as a module, choose M here: the
- module will be called go7007-usb.
-
-config VIDEO_GO7007_LOADER
- tristate "WIS GO7007 Loader support"
- depends on VIDEO_GO7007
- default y
- ---help---
- This is a go7007 firmware loader driver for the WIS GO7007
- MPEG encoder chip over USB.
-
- To compile this driver as a module, choose M here: the
- module will be called go7007-loader.
-
-config VIDEO_GO7007_USB_S2250_BOARD
- tristate "Sensoray 2250/2251 support"
- depends on VIDEO_GO7007_USB && USB
- ---help---
- This is a video4linux driver for the Sensoray 2250/2251 device.
-
- To compile this driver as a module, choose M here: the
- module will be called s2250.
diff --git a/drivers/staging/media/go7007/Makefile b/drivers/staging/media/go7007/Makefile
deleted file mode 100644
index 9c6ad4a263ec..000000000000
--- a/drivers/staging/media/go7007/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-obj-$(CONFIG_VIDEO_GO7007) += go7007.o
-obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o
-obj-$(CONFIG_VIDEO_GO7007_LOADER) += go7007-loader.o
-obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o
-
-go7007-y := go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \
- snd-go7007.o
-
-s2250-y := s2250-board.o
-
-# Uncomment when the saa7134 patches get into upstream
-#obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o
-#ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/pci/saa7134
-
-ccflags-$(CONFIG_VIDEO_GO7007_LOADER:m=y) += -Idrivers/media/common
diff --git a/drivers/staging/media/go7007/README b/drivers/staging/media/go7007/README
deleted file mode 100644
index 3af0d9062811..000000000000
--- a/drivers/staging/media/go7007/README
+++ /dev/null
@@ -1,137 +0,0 @@
-Todo:
- - create an API for motion detection
- - let s2250-board use i2c subdevs as well instead of hardcoding
- support for the i2c devices.
- - when the driver is moved out of staging, support for saa7134-go7007
- should be added to the saa7134 driver. The patch for that is
- included below.
-
-Patch for saa7134:
-
-diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c
-index dc68cf1..9a53794 100644
---- a/drivers/media/pci/saa7134/saa7134-cards.c
-+++ b/drivers/media/pci/saa7134/saa7134-cards.c
-@@ -5790,6 +5790,29 @@ struct saa7134_board saa7134_boards[] = {
- .gpio = 0x6010000,
- } },
- },
-+ [SAA7134_BOARD_WIS_VOYAGER] = {
-+ .name = "WIS Voyager or compatible",
-+ .audio_clock = 0x00200000,
-+ .tuner_type = TUNER_PHILIPS_TDA8290,
-+ .radio_type = UNSET,
-+ .tuner_addr = ADDR_UNSET,
-+ .radio_addr = ADDR_UNSET,
-+ .mpeg = SAA7134_MPEG_GO7007,
-+ .inputs = { {
-+ .name = name_comp1,
-+ .vmux = 0,
-+ .amux = LINE2,
-+ }, {
-+ .name = name_tv,
-+ .vmux = 3,
-+ .amux = TV,
-+ .tv = 1,
-+ }, {
-+ .name = name_svideo,
-+ .vmux = 6,
-+ .amux = LINE1,
-+ } },
-+ },
-
- };
-
-@@ -7037,6 +7060,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
- .subdevice = 0x0911,
- .driver_data = SAA7134_BOARD_SENSORAY811_911,
- }, {
-+ .vendor = PCI_VENDOR_ID_PHILIPS,
-+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
-+ .subvendor = 0x1905, /* WIS */
-+ .subdevice = 0x7007,
-+ .driver_data = SAA7134_BOARD_WIS_VOYAGER,
-+ }, {
- /* --- boards without eeprom + subsystem ID --- */
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
-diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c
-index 8fd24e7..0a849ea 100644
---- a/drivers/media/pci/saa7134/saa7134-core.c
-+++ b/drivers/media/pci/saa7134/saa7134-core.c
-@@ -156,6 +156,8 @@ static void request_module_async(struct work_struct *work){
- request_module("saa7134-empress");
- if (card_is_dvb(dev))
- request_module("saa7134-dvb");
-+ if (card_is_go7007(dev))
-+ request_module("saa7134-go7007");
- if (alsa) {
- if (dev->pci->device != PCI_DEVICE_ID_PHILIPS_SAA7130)
- request_module("saa7134-alsa");
-@@ -557,8 +559,12 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id)
- saa7134_irq_vbi_done(dev,status);
-
- if ((report & SAA7134_IRQ_REPORT_DONE_RA2) &&
-- card_has_mpeg(dev))
-- saa7134_irq_ts_done(dev,status);
-+ card_has_mpeg(dev)) {
-+ if (dev->mops->irq_ts_done != NULL)
-+ dev->mops->irq_ts_done(dev, status);
-+ else
-+ saa7134_irq_ts_done(dev, status);
-+ }
-
- if (report & SAA7134_IRQ_REPORT_GPIO16) {
- switch (dev->has_remote) {
-diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h
-index 62169dd..5fad39a 100644
---- a/drivers/media/pci/saa7134/saa7134.h
-+++ b/drivers/media/pci/saa7134/saa7134.h
-@@ -334,6 +334,7 @@ struct saa7134_card_ir {
- #define SAA7134_BOARD_KWORLD_PC150U 189
- #define SAA7134_BOARD_ASUSTeK_PS3_100 190
- #define SAA7134_BOARD_HAWELL_HW_9004V1 191
-+#define SAA7134_BOARD_WIS_VOYAGER 192
-
- #define SAA7134_MAXBOARDS 32
- #define SAA7134_INPUT_MAX 8
-@@ -364,6 +365,7 @@ enum saa7134_mpeg_type {
- SAA7134_MPEG_UNUSED,
- SAA7134_MPEG_EMPRESS,
- SAA7134_MPEG_DVB,
-+ SAA7134_MPEG_GO7007,
- };
-
- enum saa7134_mpeg_ts_type {
-@@ -403,6 +405,7 @@ struct saa7134_board {
- #define card_has_radio(dev) (NULL != saa7134_boards[dev->board].radio.name)
- #define card_is_empress(dev) (SAA7134_MPEG_EMPRESS == saa7134_boards[dev->board].mpeg)
- #define card_is_dvb(dev) (SAA7134_MPEG_DVB == saa7134_boards[dev->board].mpeg)
-+#define card_is_go7007(dev) (SAA7134_MPEG_GO7007 == saa7134_boards[dev->board].mpeg)
- #define card_has_mpeg(dev) (SAA7134_MPEG_UNUSED != saa7134_boards[dev->board].mpeg)
- #define card(dev) (saa7134_boards[dev->board])
- #define card_in(dev,n) (saa7134_boards[dev->board].inputs[n])
-@@ -535,6 +538,8 @@ struct saa7134_mpeg_ops {
- int (*init)(struct saa7134_dev *dev);
- int (*fini)(struct saa7134_dev *dev);
- void (*signal_change)(struct saa7134_dev *dev);
-+ void (*irq_ts_done)(struct saa7134_dev *dev,
-+ unsigned long status);
- };
-
- /* global device status */
-diff --git a/drivers/staging/media/go7007/Makefile b/drivers/staging/media/go7007/Makefile
-index 9c6ad4a..1b23689 100644
---- a/drivers/staging/media/go7007/Makefile
-+++ b/drivers/staging/media/go7007/Makefile
-@@ -8,8 +8,7 @@ go7007-y := go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \
-
- s2250-y := s2250-board.o
-
--# Uncomment when the saa7134 patches get into upstream
--#obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o
--#ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/pci/saa7134
-+obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o
-+ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/pci/saa7134
-
- ccflags-$(CONFIG_VIDEO_GO7007_LOADER:m=y) += -Idrivers/media/common
diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c
deleted file mode 100644
index 6f1beca86b2b..000000000000
--- a/drivers/staging/media/go7007/go7007-driver.c
+++ /dev/null
@@ -1,711 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/unistd.h>
-#include <linux/time.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <linux/firmware.h>
-#include <linux/mutex.h>
-#include <linux/uaccess.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <media/tuner.h>
-#include <media/v4l2-common.h>
-
-#include "go7007-priv.h"
-
-/*
- * Wait for an interrupt to be delivered from the GO7007SB and return
- * the associated value and data.
- *
- * Must be called with the hw_lock held.
- */
-int go7007_read_interrupt(struct go7007 *go, u16 *value, u16 *data)
-{
- go->interrupt_available = 0;
- go->hpi_ops->read_interrupt(go);
- if (wait_event_timeout(go->interrupt_waitq,
- go->interrupt_available, 5*HZ) < 0) {
- v4l2_err(&go->v4l2_dev, "timeout waiting for read interrupt\n");
- return -1;
- }
- if (!go->interrupt_available)
- return -1;
- go->interrupt_available = 0;
- *value = go->interrupt_value & 0xfffe;
- *data = go->interrupt_data;
- return 0;
-}
-EXPORT_SYMBOL(go7007_read_interrupt);
-
-/*
- * Read a register/address on the GO7007SB.
- *
- * Must be called with the hw_lock held.
- */
-int go7007_read_addr(struct go7007 *go, u16 addr, u16 *data)
-{
- int count = 100;
- u16 value;
-
- if (go7007_write_interrupt(go, 0x0010, addr) < 0)
- return -EIO;
- while (count-- > 0) {
- if (go7007_read_interrupt(go, &value, data) == 0 &&
- value == 0xa000)
- return 0;
- }
- return -EIO;
-}
-EXPORT_SYMBOL(go7007_read_addr);
-
-/*
- * Send the boot firmware to the encoder, which just wakes it up and lets
- * us talk to the GPIO pins and on-board I2C adapter.
- *
- * Must be called with the hw_lock held.
- */
-static int go7007_load_encoder(struct go7007 *go)
-{
- const struct firmware *fw_entry;
- char fw_name[] = "go7007/go7007fw.bin";
- void *bounce;
- int fw_len, rv = 0;
- u16 intr_val, intr_data;
-
- if (go->boot_fw == NULL) {
- if (request_firmware(&fw_entry, fw_name, go->dev)) {
- v4l2_err(go, "unable to load firmware from file \"%s\"\n", fw_name);
- return -1;
- }
- if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) {
- v4l2_err(go, "file \"%s\" does not appear to be go7007 firmware\n", fw_name);
- release_firmware(fw_entry);
- return -1;
- }
- fw_len = fw_entry->size - 16;
- bounce = kmemdup(fw_entry->data + 16, fw_len, GFP_KERNEL);
- if (bounce == NULL) {
- v4l2_err(go, "unable to allocate %d bytes for firmware transfer\n", fw_len);
- release_firmware(fw_entry);
- return -1;
- }
- release_firmware(fw_entry);
- go->boot_fw_len = fw_len;
- go->boot_fw = bounce;
- }
- if (go7007_interface_reset(go) < 0 ||
- go7007_send_firmware(go, go->boot_fw, go->boot_fw_len) < 0 ||
- go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
- (intr_val & ~0x1) != 0x5a5a) {
- v4l2_err(go, "error transferring firmware\n");
- rv = -1;
- }
- return rv;
-}
-
-MODULE_FIRMWARE("go7007/go7007fw.bin");
-
-/*
- * Boot the encoder and register the I2C adapter if requested. Do the
- * minimum initialization necessary, since the board-specific code may
- * still need to probe the board ID.
- *
- * Must NOT be called with the hw_lock held.
- */
-int go7007_boot_encoder(struct go7007 *go, int init_i2c)
-{
- int ret;
-
- mutex_lock(&go->hw_lock);
- ret = go7007_load_encoder(go);
- mutex_unlock(&go->hw_lock);
- if (ret < 0)
- return -1;
- if (!init_i2c)
- return 0;
- if (go7007_i2c_init(go) < 0)
- return -1;
- go->i2c_adapter_online = 1;
- return 0;
-}
-EXPORT_SYMBOL(go7007_boot_encoder);
-
-/*
- * Configure any hardware-related registers in the GO7007, such as GPIO
- * pins and bus parameters, which are board-specific. This assumes
- * the boot firmware has already been downloaded.
- *
- * Must be called with the hw_lock held.
- */
-static int go7007_init_encoder(struct go7007 *go)
-{
- if (go->board_info->audio_flags & GO7007_AUDIO_I2S_MASTER) {
- go7007_write_addr(go, 0x1000, 0x0811);
- go7007_write_addr(go, 0x1000, 0x0c11);
- }
- switch (go->board_id) {
- case GO7007_BOARDID_MATRIX_REV:
- /* Set GPIO pin 0 to be an output (audio clock control) */
- go7007_write_addr(go, 0x3c82, 0x0001);
- go7007_write_addr(go, 0x3c80, 0x00fe);
- break;
- case GO7007_BOARDID_ADLINK_MPG24:
- /* set GPIO5 to be an output, currently low */
- go7007_write_addr(go, 0x3c82, 0x0000);
- go7007_write_addr(go, 0x3c80, 0x00df);
- break;
- case GO7007_BOARDID_ADS_USBAV_709:
- /* GPIO pin 0: audio clock control */
- /* pin 2: TW9906 reset */
- /* pin 3: capture LED */
- go7007_write_addr(go, 0x3c82, 0x000d);
- go7007_write_addr(go, 0x3c80, 0x00f2);
- break;
- }
- return 0;
-}
-
-/*
- * Send the boot firmware to the GO7007 and configure the registers. This
- * is the only way to stop the encoder once it has started streaming video.
- *
- * Must be called with the hw_lock held.
- */
-int go7007_reset_encoder(struct go7007 *go)
-{
- if (go7007_load_encoder(go) < 0)
- return -1;
- return go7007_init_encoder(go);
-}
-
-/*
- * Attempt to instantiate an I2C client by ID, probably loading a module.
- */
-static int init_i2c_module(struct i2c_adapter *adapter, const struct go_i2c *const i2c)
-{
- struct go7007 *go = i2c_get_adapdata(adapter);
- struct v4l2_device *v4l2_dev = &go->v4l2_dev;
- struct v4l2_subdev *sd;
- struct i2c_board_info info;
-
- memset(&info, 0, sizeof(info));
- strlcpy(info.type, i2c->type, sizeof(info.type));
- info.addr = i2c->addr;
- info.flags = i2c->flags;
-
- sd = v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, NULL);
- if (sd) {
- if (i2c->is_video)
- go->sd_video = sd;
- if (i2c->is_audio)
- go->sd_audio = sd;
- return 0;
- }
-
- printk(KERN_INFO "go7007: probing for module i2c:%s failed\n", i2c->type);
- return -EINVAL;
-}
-
-/*
- * Detach and unregister the encoder. The go7007 struct won't be freed
- * until v4l2 finishes releasing its resources and all associated fds are
- * closed by applications.
- */
-static void go7007_remove(struct v4l2_device *v4l2_dev)
-{
- struct go7007 *go = container_of(v4l2_dev, struct go7007, v4l2_dev);
-
- v4l2_device_unregister(v4l2_dev);
- if (go->hpi_ops->release)
- go->hpi_ops->release(go);
- if (go->i2c_adapter_online) {
- i2c_del_adapter(&go->i2c_adapter);
- go->i2c_adapter_online = 0;
- }
-
- kfree(go->boot_fw);
- go7007_v4l2_remove(go);
- kfree(go);
-}
-
-/*
- * Finalize the GO7007 hardware setup, register the on-board I2C adapter
- * (if used on this board), load the I2C client driver for the sensor
- * (SAA7115 or whatever) and other devices, and register the ALSA and V4L2
- * interfaces.
- *
- * Must NOT be called with the hw_lock held.
- */
-int go7007_register_encoder(struct go7007 *go, unsigned num_i2c_devs)
-{
- int i, ret;
-
- dev_info(go->dev, "go7007: registering new %s\n", go->name);
-
- go->v4l2_dev.release = go7007_remove;
- ret = v4l2_device_register(go->dev, &go->v4l2_dev);
- if (ret < 0)
- return ret;
-
- mutex_lock(&go->hw_lock);
- ret = go7007_init_encoder(go);
- mutex_unlock(&go->hw_lock);
- if (ret < 0)
- return ret;
-
- ret = go7007_v4l2_ctrl_init(go);
- if (ret < 0)
- return ret;
-
- if (!go->i2c_adapter_online &&
- go->board_info->flags & GO7007_BOARD_USE_ONBOARD_I2C) {
- ret = go7007_i2c_init(go);
- if (ret < 0)
- return ret;
- go->i2c_adapter_online = 1;
- }
- if (go->i2c_adapter_online) {
- if (go->board_id == GO7007_BOARDID_ADS_USBAV_709) {
- /* Reset the TW9906 */
- go7007_write_addr(go, 0x3c82, 0x0009);
- msleep(50);
- go7007_write_addr(go, 0x3c82, 0x000d);
- }
- for (i = 0; i < num_i2c_devs; ++i)
- init_i2c_module(&go->i2c_adapter, &go->board_info->i2c_devs[i]);
-
- if (go->tuner_type >= 0) {
- struct tuner_setup setup = {
- .addr = ADDR_UNSET,
- .type = go->tuner_type,
- .mode_mask = T_ANALOG_TV,
- };
-
- v4l2_device_call_all(&go->v4l2_dev, 0, tuner,
- s_type_addr, &setup);
- }
- if (go->board_id == GO7007_BOARDID_ADLINK_MPG24)
- v4l2_subdev_call(go->sd_video, video, s_routing,
- 0, 0, go->channel_number + 1);
- }
-
- ret = go7007_v4l2_init(go);
- if (ret < 0)
- return ret;
-
- if (go->board_info->flags & GO7007_BOARD_HAS_AUDIO) {
- go->audio_enabled = 1;
- go7007_snd_init(go);
- }
- return 0;
-}
-EXPORT_SYMBOL(go7007_register_encoder);
-
-/*
- * Send the encode firmware to the encoder, which will cause it
- * to immediately start delivering the video and audio streams.
- *
- * Must be called with the hw_lock held.
- */
-int go7007_start_encoder(struct go7007 *go)
-{
- u8 *fw;
- int fw_len, rv = 0, i;
- u16 intr_val, intr_data;
-
- go->modet_enable = 0;
- if (!go->dvd_mode)
- for (i = 0; i < 4; ++i) {
- if (go->modet[i].enable) {
- go->modet_enable = 1;
- continue;
- }
- go->modet[i].pixel_threshold = 32767;
- go->modet[i].motion_threshold = 32767;
- go->modet[i].mb_threshold = 32767;
- }
-
- if (go7007_construct_fw_image(go, &fw, &fw_len) < 0)
- return -1;
-
- if (go7007_send_firmware(go, fw, fw_len) < 0 ||
- go7007_read_interrupt(go, &intr_val, &intr_data) < 0) {
- v4l2_err(&go->v4l2_dev, "error transferring firmware\n");
- rv = -1;
- goto start_error;
- }
-
- go->state = STATE_DATA;
- go->parse_length = 0;
- go->seen_frame = 0;
- if (go7007_stream_start(go) < 0) {
- v4l2_err(&go->v4l2_dev, "error starting stream transfer\n");
- rv = -1;
- goto start_error;
- }
-
-start_error:
- kfree(fw);
- return rv;
-}
-
-/*
- * Store a byte in the current video buffer, if there is one.
- */
-static inline void store_byte(struct go7007_buffer *vb, u8 byte)
-{
- if (vb && vb->vb.v4l2_planes[0].bytesused < GO7007_BUF_SIZE) {
- u8 *ptr = vb2_plane_vaddr(&vb->vb, 0);
-
- ptr[vb->vb.v4l2_planes[0].bytesused++] = byte;
- }
-}
-
-/*
- * Deliver the last video buffer and get a new one to start writing to.
- */
-static struct go7007_buffer *frame_boundary(struct go7007 *go, struct go7007_buffer *vb)
-{
- struct go7007_buffer *vb_tmp = NULL;
- u32 *bytesused = &vb->vb.v4l2_planes[0].bytesused;
- int i;
-
- if (vb) {
- if (vb->modet_active) {
- if (*bytesused + 216 < GO7007_BUF_SIZE) {
- for (i = 0; i < 216; ++i)
- store_byte(vb, go->active_map[i]);
- *bytesused -= 216;
- } else
- vb->modet_active = 0;
- }
- vb->vb.v4l2_buf.sequence = go->next_seq++;
- v4l2_get_timestamp(&vb->vb.v4l2_buf.timestamp);
- vb_tmp = vb;
- spin_lock(&go->spinlock);
- list_del(&vb->list);
- if (list_empty(&go->vidq_active))
- vb = NULL;
- else
- vb = list_first_entry(&go->vidq_active, struct go7007_buffer, list);
- go->active_buf = vb;
- spin_unlock(&go->spinlock);
- vb2_buffer_done(&vb_tmp->vb, VB2_BUF_STATE_DONE);
- return vb;
- }
- spin_lock(&go->spinlock);
- if (!list_empty(&go->vidq_active))
- vb = go->active_buf =
- list_first_entry(&go->vidq_active, struct go7007_buffer, list);
- spin_unlock(&go->spinlock);
- go->next_seq++;
- return vb;
-}
-
-static void write_bitmap_word(struct go7007 *go)
-{
- int x, y, i, stride = ((go->width >> 4) + 7) >> 3;
-
- for (i = 0; i < 16; ++i) {
- y = (((go->parse_length - 1) << 3) + i) / (go->width >> 4);
- x = (((go->parse_length - 1) << 3) + i) % (go->width >> 4);
- if (stride * y + (x >> 3) < sizeof(go->active_map))
- go->active_map[stride * y + (x >> 3)] |=
- (go->modet_word & 1) << (x & 0x7);
- go->modet_word >>= 1;
- }
-}
-
-/*
- * Parse a chunk of the video stream into frames. The frames are not
- * delimited by the hardware, so we have to parse the frame boundaries
- * based on the type of video stream we're receiving.
- */
-void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
-{
- struct go7007_buffer *vb = go->active_buf;
- int i, seq_start_code = -1, gop_start_code = -1, frame_start_code = -1;
-
- switch (go->format) {
- case V4L2_PIX_FMT_MPEG4:
- seq_start_code = 0xB0;
- gop_start_code = 0xB3;
- frame_start_code = 0xB6;
- break;
- case V4L2_PIX_FMT_MPEG1:
- case V4L2_PIX_FMT_MPEG2:
- seq_start_code = 0xB3;
- gop_start_code = 0xB8;
- frame_start_code = 0x00;
- break;
- }
-
- for (i = 0; i < length; ++i) {
- if (vb && vb->vb.v4l2_planes[0].bytesused >= GO7007_BUF_SIZE - 3) {
- v4l2_info(&go->v4l2_dev, "dropping oversized frame\n");
- vb->vb.v4l2_planes[0].bytesused = 0;
- vb->frame_offset = 0;
- vb->modet_active = 0;
- vb = go->active_buf = NULL;
- }
-
- switch (go->state) {
- case STATE_DATA:
- switch (buf[i]) {
- case 0x00:
- go->state = STATE_00;
- break;
- case 0xFF:
- go->state = STATE_FF;
- break;
- default:
- store_byte(vb, buf[i]);
- break;
- }
- break;
- case STATE_00:
- switch (buf[i]) {
- case 0x00:
- go->state = STATE_00_00;
- break;
- case 0xFF:
- store_byte(vb, 0x00);
- go->state = STATE_FF;
- break;
- default:
- store_byte(vb, 0x00);
- store_byte(vb, buf[i]);
- go->state = STATE_DATA;
- break;
- }
- break;
- case STATE_00_00:
- switch (buf[i]) {
- case 0x00:
- store_byte(vb, 0x00);
- /* go->state remains STATE_00_00 */
- break;
- case 0x01:
- go->state = STATE_00_00_01;
- break;
- case 0xFF:
- store_byte(vb, 0x00);
- store_byte(vb, 0x00);
- go->state = STATE_FF;
- break;
- default:
- store_byte(vb, 0x00);
- store_byte(vb, 0x00);
- store_byte(vb, buf[i]);
- go->state = STATE_DATA;
- break;
- }
- break;
- case STATE_00_00_01:
- if (buf[i] == 0xF8 && go->modet_enable == 0) {
- /* MODET start code, but MODET not enabled */
- store_byte(vb, 0x00);
- store_byte(vb, 0x00);
- store_byte(vb, 0x01);
- store_byte(vb, 0xF8);
- go->state = STATE_DATA;
- break;
- }
- /* If this is the start of a new MPEG frame,
- * get a new buffer */
- if ((go->format == V4L2_PIX_FMT_MPEG1 ||
- go->format == V4L2_PIX_FMT_MPEG2 ||
- go->format == V4L2_PIX_FMT_MPEG4) &&
- (buf[i] == seq_start_code ||
- buf[i] == gop_start_code ||
- buf[i] == frame_start_code)) {
- if (vb == NULL || go->seen_frame)
- vb = frame_boundary(go, vb);
- go->seen_frame = buf[i] == frame_start_code;
- if (vb && go->seen_frame)
- vb->frame_offset = vb->vb.v4l2_planes[0].bytesused;
- }
- /* Handle any special chunk types, or just write the
- * start code to the (potentially new) buffer */
- switch (buf[i]) {
- case 0xF5: /* timestamp */
- go->parse_length = 12;
- go->state = STATE_UNPARSED;
- break;
- case 0xF6: /* vbi */
- go->state = STATE_VBI_LEN_A;
- break;
- case 0xF8: /* MD map */
- go->parse_length = 0;
- memset(go->active_map, 0,
- sizeof(go->active_map));
- go->state = STATE_MODET_MAP;
- break;
- case 0xFF: /* Potential JPEG start code */
- store_byte(vb, 0x00);
- store_byte(vb, 0x00);
- store_byte(vb, 0x01);
- go->state = STATE_FF;
- break;
- default:
- store_byte(vb, 0x00);
- store_byte(vb, 0x00);
- store_byte(vb, 0x01);
- store_byte(vb, buf[i]);
- go->state = STATE_DATA;
- break;
- }
- break;
- case STATE_FF:
- switch (buf[i]) {
- case 0x00:
- store_byte(vb, 0xFF);
- go->state = STATE_00;
- break;
- case 0xFF:
- store_byte(vb, 0xFF);
- /* go->state remains STATE_FF */
- break;
- case 0xD8:
- if (go->format == V4L2_PIX_FMT_MJPEG)
- vb = frame_boundary(go, vb);
- /* fall through */
- default:
- store_byte(vb, 0xFF);
- store_byte(vb, buf[i]);
- go->state = STATE_DATA;
- break;
- }
- break;
- case STATE_VBI_LEN_A:
- go->parse_length = buf[i] << 8;
- go->state = STATE_VBI_LEN_B;
- break;
- case STATE_VBI_LEN_B:
- go->parse_length |= buf[i];
- if (go->parse_length > 0)
- go->state = STATE_UNPARSED;
- else
- go->state = STATE_DATA;
- break;
- case STATE_MODET_MAP:
- if (go->parse_length < 204) {
- if (go->parse_length & 1) {
- go->modet_word |= buf[i];
- write_bitmap_word(go);
- } else
- go->modet_word = buf[i] << 8;
- } else if (go->parse_length == 207 && vb) {
- vb->modet_active = buf[i];
- }
- if (++go->parse_length == 208)
- go->state = STATE_DATA;
- break;
- case STATE_UNPARSED:
- if (--go->parse_length == 0)
- go->state = STATE_DATA;
- break;
- }
- }
-}
-EXPORT_SYMBOL(go7007_parse_video_stream);
-
-/*
- * Allocate a new go7007 struct. Used by the hardware-specific probe.
- */
-struct go7007 *go7007_alloc(const struct go7007_board_info *board,
- struct device *dev)
-{
- struct go7007 *go;
- int i;
-
- go = kzalloc(sizeof(struct go7007), GFP_KERNEL);
- if (go == NULL)
- return NULL;
- go->dev = dev;
- go->board_info = board;
- go->board_id = 0;
- go->tuner_type = -1;
- go->channel_number = 0;
- go->name[0] = 0;
- mutex_init(&go->hw_lock);
- init_waitqueue_head(&go->frame_waitq);
- spin_lock_init(&go->spinlock);
- go->status = STATUS_INIT;
- memset(&go->i2c_adapter, 0, sizeof(go->i2c_adapter));
- go->i2c_adapter_online = 0;
- go->interrupt_available = 0;
- init_waitqueue_head(&go->interrupt_waitq);
- go->input = 0;
- go7007_update_board(go);
- go->encoder_h_halve = 0;
- go->encoder_v_halve = 0;
- go->encoder_subsample = 0;
- go->format = V4L2_PIX_FMT_MJPEG;
- go->bitrate = 1500000;
- go->fps_scale = 1;
- go->pali = 0;
- go->aspect_ratio = GO7007_RATIO_1_1;
- go->gop_size = 0;
- go->ipb = 0;
- go->closed_gop = 0;
- go->repeat_seqhead = 0;
- go->seq_header_enable = 0;
- go->gop_header_enable = 0;
- go->dvd_mode = 0;
- go->interlace_coding = 0;
- for (i = 0; i < 4; ++i)
- go->modet[i].enable = 0;
- for (i = 0; i < 1624; ++i)
- go->modet_map[i] = 0;
- go->audio_deliver = NULL;
- go->audio_enabled = 0;
-
- return go;
-}
-EXPORT_SYMBOL(go7007_alloc);
-
-void go7007_update_board(struct go7007 *go)
-{
- const struct go7007_board_info *board = go->board_info;
-
- if (board->sensor_flags & GO7007_SENSOR_TV) {
- go->standard = GO7007_STD_NTSC;
- go->std = V4L2_STD_NTSC_M;
- go->width = 720;
- go->height = 480;
- go->sensor_framerate = 30000;
- } else {
- go->standard = GO7007_STD_OTHER;
- go->width = board->sensor_width;
- go->height = board->sensor_height;
- go->sensor_framerate = board->sensor_framerate;
- }
- go->encoder_v_offset = board->sensor_v_offset;
- go->encoder_h_offset = board->sensor_h_offset;
-}
-EXPORT_SYMBOL(go7007_update_board);
-
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/media/go7007/go7007-fw.c b/drivers/staging/media/go7007/go7007-fw.c
deleted file mode 100644
index 814ce08bc44d..000000000000
--- a/drivers/staging/media/go7007/go7007-fw.c
+++ /dev/null
@@ -1,1628 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-/*
- * This file contains code to generate a firmware image for the GO7007SB
- * encoder. Much of the firmware is read verbatim from a file, but some of
- * it concerning bitrate control and other things that can be configured at
- * run-time are generated dynamically. Note that the format headers
- * generated here do not affect the functioning of the encoder; they are
- * merely parroted back to the host at the start of each frame.
- */
-
-#include <linux/module.h>
-#include <linux/time.h>
-#include <linux/mm.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <asm/byteorder.h>
-
-#include "go7007-priv.h"
-
-#define GO7007_FW_NAME "go7007/go7007tv.bin"
-
-/* Constants used in the source firmware image to describe code segments */
-
-#define FLAG_MODE_MJPEG (1)
-#define FLAG_MODE_MPEG1 (1<<1)
-#define FLAG_MODE_MPEG2 (1<<2)
-#define FLAG_MODE_MPEG4 (1<<3)
-#define FLAG_MODE_H263 (1<<4)
-#define FLAG_MODE_ALL (FLAG_MODE_MJPEG | FLAG_MODE_MPEG1 | \
- FLAG_MODE_MPEG2 | FLAG_MODE_MPEG4 | \
- FLAG_MODE_H263)
-#define FLAG_SPECIAL (1<<8)
-
-#define SPECIAL_FRM_HEAD 0
-#define SPECIAL_BRC_CTRL 1
-#define SPECIAL_CONFIG 2
-#define SPECIAL_SEQHEAD 3
-#define SPECIAL_AV_SYNC 4
-#define SPECIAL_FINAL 5
-#define SPECIAL_AUDIO 6
-#define SPECIAL_MODET 7
-
-/* Little data class for creating MPEG headers bit-by-bit */
-
-struct code_gen {
- unsigned char *p; /* destination */
- u32 a; /* collects bits at the top of the variable */
- int b; /* bit position of most recently-written bit */
- int len; /* written out so far */
-};
-
-#define CODE_GEN(name, dest) struct code_gen name = { dest, 0, 32, 0 }
-
-#define CODE_ADD(name, val, length) do { \
- name.b -= (length); \
- name.a |= (val) << name.b; \
- while (name.b <= 24) { \
- *name.p = name.a >> 24; \
- ++name.p; \
- name.a <<= 8; \
- name.b += 8; \
- name.len += 8; \
- } \
-} while (0)
-
-#define CODE_LENGTH(name) (name.len + (32 - name.b))
-
-/* Tables for creating the bitrate control data */
-
-static const s16 converge_speed_ip[101] = {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
- 3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
- 5, 5, 5, 6, 6, 6, 7, 7, 8, 8,
- 9, 10, 10, 11, 12, 13, 14, 15, 16, 17,
- 19, 20, 22, 23, 25, 27, 30, 32, 35, 38,
- 41, 45, 49, 53, 58, 63, 69, 76, 83, 91,
- 100
-};
-
-static const s16 converge_speed_ipb[101] = {
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 5, 5, 5, 5, 5, 6,
- 6, 6, 6, 7, 7, 7, 7, 8, 8, 9,
- 9, 9, 10, 10, 11, 12, 12, 13, 14, 14,
- 15, 16, 17, 18, 19, 20, 22, 23, 25, 26,
- 28, 30, 32, 34, 37, 40, 42, 46, 49, 53,
- 57, 61, 66, 71, 77, 83, 90, 97, 106, 115,
- 125, 135, 147, 161, 175, 191, 209, 228, 249, 273,
- 300
-};
-
-static const s16 LAMBDA_table[4][101] = {
- { 16, 16, 16, 16, 17, 17, 17, 18, 18, 18,
- 19, 19, 19, 20, 20, 20, 21, 21, 22, 22,
- 22, 23, 23, 24, 24, 25, 25, 25, 26, 26,
- 27, 27, 28, 28, 29, 29, 30, 31, 31, 32,
- 32, 33, 33, 34, 35, 35, 36, 37, 37, 38,
- 39, 39, 40, 41, 42, 42, 43, 44, 45, 46,
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
- 67, 68, 69, 70, 72, 73, 74, 76, 77, 78,
- 80, 81, 83, 84, 86, 87, 89, 90, 92, 94,
- 96
- },
- {
- 20, 20, 20, 21, 21, 21, 22, 22, 23, 23,
- 23, 24, 24, 25, 25, 26, 26, 27, 27, 28,
- 28, 29, 29, 30, 30, 31, 31, 32, 33, 33,
- 34, 34, 35, 36, 36, 37, 38, 38, 39, 40,
- 40, 41, 42, 43, 43, 44, 45, 46, 47, 48,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- 58, 59, 60, 61, 62, 64, 65, 66, 67, 68,
- 70, 71, 72, 73, 75, 76, 78, 79, 80, 82,
- 83, 85, 86, 88, 90, 91, 93, 95, 96, 98,
- 100, 102, 103, 105, 107, 109, 111, 113, 115, 117,
- 120
- },
- {
- 24, 24, 24, 25, 25, 26, 26, 27, 27, 28,
- 28, 29, 29, 30, 30, 31, 31, 32, 33, 33,
- 34, 34, 35, 36, 36, 37, 38, 38, 39, 40,
- 41, 41, 42, 43, 44, 44, 45, 46, 47, 48,
- 49, 50, 50, 51, 52, 53, 54, 55, 56, 57,
- 58, 59, 60, 62, 63, 64, 65, 66, 67, 69,
- 70, 71, 72, 74, 75, 76, 78, 79, 81, 82,
- 84, 85, 87, 88, 90, 92, 93, 95, 97, 98,
- 100, 102, 104, 106, 108, 110, 112, 114, 116, 118,
- 120, 122, 124, 127, 129, 131, 134, 136, 138, 141,
- 144
- },
- {
- 32, 32, 33, 33, 34, 34, 35, 36, 36, 37,
- 38, 38, 39, 40, 41, 41, 42, 43, 44, 44,
- 45, 46, 47, 48, 49, 50, 50, 51, 52, 53,
- 54, 55, 56, 57, 58, 59, 60, 62, 63, 64,
- 65, 66, 67, 69, 70, 71, 72, 74, 75, 76,
- 78, 79, 81, 82, 84, 85, 87, 88, 90, 92,
- 93, 95, 97, 98, 100, 102, 104, 106, 108, 110,
- 112, 114, 116, 118, 120, 122, 124, 127, 129, 131,
- 134, 136, 139, 141, 144, 146, 149, 152, 154, 157,
- 160, 163, 166, 169, 172, 175, 178, 181, 185, 188,
- 192
- }
-};
-
-/* MPEG blank frame generation tables */
-
-enum mpeg_frame_type {
- PFRAME,
- BFRAME_PRE,
- BFRAME_POST,
- BFRAME_BIDIR,
- BFRAME_EMPTY
-};
-
-static const u32 addrinctab[33][2] = {
- { 0x01, 1 }, { 0x03, 3 }, { 0x02, 3 }, { 0x03, 4 },
- { 0x02, 4 }, { 0x03, 5 }, { 0x02, 5 }, { 0x07, 7 },
- { 0x06, 7 }, { 0x0b, 8 }, { 0x0a, 8 }, { 0x09, 8 },
- { 0x08, 8 }, { 0x07, 8 }, { 0x06, 8 }, { 0x17, 10 },
- { 0x16, 10 }, { 0x15, 10 }, { 0x14, 10 }, { 0x13, 10 },
- { 0x12, 10 }, { 0x23, 11 }, { 0x22, 11 }, { 0x21, 11 },
- { 0x20, 11 }, { 0x1f, 11 }, { 0x1e, 11 }, { 0x1d, 11 },
- { 0x1c, 11 }, { 0x1b, 11 }, { 0x1a, 11 }, { 0x19, 11 },
- { 0x18, 11 }
-};
-
-/* Standard JPEG tables */
-
-static const u8 default_intra_quant_table[] = {
- 8, 16, 19, 22, 26, 27, 29, 34,
- 16, 16, 22, 24, 27, 29, 34, 37,
- 19, 22, 26, 27, 29, 34, 34, 38,
- 22, 22, 26, 27, 29, 34, 37, 40,
- 22, 26, 27, 29, 32, 35, 40, 48,
- 26, 27, 29, 32, 35, 40, 48, 58,
- 26, 27, 29, 34, 38, 46, 56, 69,
- 27, 29, 35, 38, 46, 56, 69, 83
-};
-
-static const u8 bits_dc_luminance[] = {
- 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
-};
-
-static const u8 val_dc_luminance[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
-};
-
-static const u8 bits_dc_chrominance[] = {
- 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
-};
-
-static const u8 val_dc_chrominance[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
-};
-
-static const u8 bits_ac_luminance[] = {
- 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
-};
-
-static const u8 val_ac_luminance[] = {
- 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
- 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
- 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
- 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
- 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
- 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
- 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
- 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
- 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
- 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
- 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
- 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
- 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
- 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
- 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
- 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
- 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
- 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
- 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
- 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
- 0xf9, 0xfa
-};
-
-static const u8 bits_ac_chrominance[] = {
- 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77
-};
-
-static const u8 val_ac_chrominance[] = {
- 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
- 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
- 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
- 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
- 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
- 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
- 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
- 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
- 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
- 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
- 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
- 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
- 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
- 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
- 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
- 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
- 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
- 0xf9, 0xfa
-};
-
-/* Zig-zag mapping for quant table
- *
- * OK, let's do this mapping on the actual table above so it doesn't have
- * to be done on the fly.
- */
-static const int zz[64] = {
- 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
- 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
- 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
- 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
-};
-
-static int copy_packages(__le16 *dest, u16 *src, int pkg_cnt, int space)
-{
- int i, cnt = pkg_cnt * 32;
-
- if (space < cnt)
- return -1;
-
- for (i = 0; i < cnt; ++i)
- dest[i] = cpu_to_le16p(src + i);
-
- return cnt;
-}
-
-static int mjpeg_frame_header(struct go7007 *go, unsigned char *buf, int q)
-{
- int i, p = 0;
-
- buf[p++] = 0xff;
- buf[p++] = 0xd8;
- buf[p++] = 0xff;
- buf[p++] = 0xdb;
- buf[p++] = 0;
- buf[p++] = 2 + 65;
- buf[p++] = 0;
- buf[p++] = default_intra_quant_table[0];
- for (i = 1; i < 64; ++i)
- /* buf[p++] = (default_intra_quant_table[i] * q) >> 3; */
- buf[p++] = (default_intra_quant_table[zz[i]] * q) >> 3;
- buf[p++] = 0xff;
- buf[p++] = 0xc0;
- buf[p++] = 0;
- buf[p++] = 17;
- buf[p++] = 8;
- buf[p++] = go->height >> 8;
- buf[p++] = go->height & 0xff;
- buf[p++] = go->width >> 8;
- buf[p++] = go->width & 0xff;
- buf[p++] = 3;
- buf[p++] = 1;
- buf[p++] = 0x22;
- buf[p++] = 0;
- buf[p++] = 2;
- buf[p++] = 0x11;
- buf[p++] = 0;
- buf[p++] = 3;
- buf[p++] = 0x11;
- buf[p++] = 0;
- buf[p++] = 0xff;
- buf[p++] = 0xc4;
- buf[p++] = 418 >> 8;
- buf[p++] = 418 & 0xff;
- buf[p++] = 0x00;
- memcpy(buf + p, bits_dc_luminance + 1, 16);
- p += 16;
- memcpy(buf + p, val_dc_luminance, sizeof(val_dc_luminance));
- p += sizeof(val_dc_luminance);
- buf[p++] = 0x01;
- memcpy(buf + p, bits_dc_chrominance + 1, 16);
- p += 16;
- memcpy(buf + p, val_dc_chrominance, sizeof(val_dc_chrominance));
- p += sizeof(val_dc_chrominance);
- buf[p++] = 0x10;
- memcpy(buf + p, bits_ac_luminance + 1, 16);
- p += 16;
- memcpy(buf + p, val_ac_luminance, sizeof(val_ac_luminance));
- p += sizeof(val_ac_luminance);
- buf[p++] = 0x11;
- memcpy(buf + p, bits_ac_chrominance + 1, 16);
- p += 16;
- memcpy(buf + p, val_ac_chrominance, sizeof(val_ac_chrominance));
- p += sizeof(val_ac_chrominance);
- buf[p++] = 0xff;
- buf[p++] = 0xda;
- buf[p++] = 0;
- buf[p++] = 12;
- buf[p++] = 3;
- buf[p++] = 1;
- buf[p++] = 0x00;
- buf[p++] = 2;
- buf[p++] = 0x11;
- buf[p++] = 3;
- buf[p++] = 0x11;
- buf[p++] = 0;
- buf[p++] = 63;
- buf[p++] = 0;
- return p;
-}
-
-static int gen_mjpeghdr_to_package(struct go7007 *go, __le16 *code, int space)
-{
- u8 *buf;
- u16 mem = 0x3e00;
- unsigned int addr = 0x19;
- int size = 0, i, off = 0, chunk;
-
- buf = kzalloc(4096, GFP_KERNEL);
- if (buf == NULL)
- return -1;
-
- for (i = 1; i < 32; ++i) {
- mjpeg_frame_header(go, buf + size, i);
- size += 80;
- }
- chunk = mjpeg_frame_header(go, buf + size, 1);
- memmove(buf + size, buf + size + 80, chunk - 80);
- size += chunk - 80;
-
- for (i = 0; i < size; i += chunk * 2) {
- if (space - off < 32) {
- off = -1;
- goto done;
- }
-
- code[off + 1] = __cpu_to_le16(0x8000 | mem);
-
- chunk = 28;
- if (mem + chunk > 0x4000)
- chunk = 0x4000 - mem;
- if (i + 2 * chunk > size)
- chunk = (size - i) / 2;
-
- if (chunk < 28) {
- code[off] = __cpu_to_le16(0x4000 | chunk);
- code[off + 31] = __cpu_to_le16(addr++);
- mem = 0x3e00;
- } else {
- code[off] = __cpu_to_le16(0x1000 | 28);
- code[off + 31] = 0;
- mem += 28;
- }
-
- memcpy(&code[off + 2], buf + i, chunk * 2);
- off += 32;
- }
-done:
- kfree(buf);
- return off;
-}
-
-static int mpeg1_frame_header(struct go7007 *go, unsigned char *buf,
- int modulo, int pict_struct, enum mpeg_frame_type frame)
-{
- int i, j, mb_code, mb_len;
- int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
- CODE_GEN(c, buf + 6);
-
- switch (frame) {
- case PFRAME:
- mb_code = 0x1;
- mb_len = 3;
- break;
- case BFRAME_PRE:
- mb_code = 0x2;
- mb_len = 4;
- break;
- case BFRAME_POST:
- mb_code = 0x2;
- mb_len = 3;
- break;
- case BFRAME_BIDIR:
- mb_code = 0x2;
- mb_len = 2;
- break;
- default: /* keep the compiler happy */
- mb_code = mb_len = 0;
- break;
- }
-
- CODE_ADD(c, frame == PFRAME ? 0x2 : 0x3, 13);
- CODE_ADD(c, 0xffff, 16);
- CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 0x7 : 0x4, 4);
- if (frame != PFRAME)
- CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 0x7 : 0x4, 4);
- else
- CODE_ADD(c, 0, 4); /* Is this supposed to be here?? */
- CODE_ADD(c, 0, 3); /* What is this?? */
- /* Byte-align with zeros */
- j = 8 - (CODE_LENGTH(c) % 8);
- if (j != 8)
- CODE_ADD(c, 0, j);
-
- if (go->format == V4L2_PIX_FMT_MPEG2) {
- CODE_ADD(c, 0x1, 24);
- CODE_ADD(c, 0xb5, 8);
- CODE_ADD(c, 0x844, 12);
- CODE_ADD(c, frame == PFRAME ? 0xff : 0x44, 8);
- if (go->interlace_coding) {
- CODE_ADD(c, pict_struct, 4);
- if (go->dvd_mode)
- CODE_ADD(c, 0x000, 11);
- else
- CODE_ADD(c, 0x200, 11);
- } else {
- CODE_ADD(c, 0x3, 4);
- CODE_ADD(c, 0x20c, 11);
- }
- /* Byte-align with zeros */
- j = 8 - (CODE_LENGTH(c) % 8);
- if (j != 8)
- CODE_ADD(c, 0, j);
- }
-
- for (i = 0; i < rows; ++i) {
- CODE_ADD(c, 1, 24);
- CODE_ADD(c, i + 1, 8);
- CODE_ADD(c, 0x2, 6);
- CODE_ADD(c, 0x1, 1);
- CODE_ADD(c, mb_code, mb_len);
- if (go->interlace_coding) {
- CODE_ADD(c, 0x1, 2);
- CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
- }
- if (frame == BFRAME_BIDIR) {
- CODE_ADD(c, 0x3, 2);
- if (go->interlace_coding)
- CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
- }
- CODE_ADD(c, 0x3, 2);
- for (j = (go->width >> 4) - 2; j >= 33; j -= 33)
- CODE_ADD(c, 0x8, 11);
- CODE_ADD(c, addrinctab[j][0], addrinctab[j][1]);
- CODE_ADD(c, mb_code, mb_len);
- if (go->interlace_coding) {
- CODE_ADD(c, 0x1, 2);
- CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
- }
- if (frame == BFRAME_BIDIR) {
- CODE_ADD(c, 0x3, 2);
- if (go->interlace_coding)
- CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
- }
- CODE_ADD(c, 0x3, 2);
-
- /* Byte-align with zeros */
- j = 8 - (CODE_LENGTH(c) % 8);
- if (j != 8)
- CODE_ADD(c, 0, j);
- }
-
- i = CODE_LENGTH(c) + 4 * 8;
- buf[2] = 0x00;
- buf[3] = 0x00;
- buf[4] = 0x01;
- buf[5] = 0x00;
- return i;
-}
-
-static int mpeg1_sequence_header(struct go7007 *go, unsigned char *buf, int ext)
-{
- int i, aspect_ratio, picture_rate;
- CODE_GEN(c, buf + 6);
-
- if (go->format == V4L2_PIX_FMT_MPEG1) {
- switch (go->aspect_ratio) {
- case GO7007_RATIO_4_3:
- aspect_ratio = go->standard == GO7007_STD_NTSC ? 3 : 2;
- break;
- case GO7007_RATIO_16_9:
- aspect_ratio = go->standard == GO7007_STD_NTSC ? 5 : 4;
- break;
- default:
- aspect_ratio = 1;
- break;
- }
- } else {
- switch (go->aspect_ratio) {
- case GO7007_RATIO_4_3:
- aspect_ratio = 2;
- break;
- case GO7007_RATIO_16_9:
- aspect_ratio = 3;
- break;
- default:
- aspect_ratio = 1;
- break;
- }
- }
- switch (go->sensor_framerate) {
- case 24000:
- picture_rate = 1;
- break;
- case 24024:
- picture_rate = 2;
- break;
- case 25025:
- picture_rate = go->interlace_coding ? 6 : 3;
- break;
- case 30000:
- picture_rate = go->interlace_coding ? 7 : 4;
- break;
- case 30030:
- picture_rate = go->interlace_coding ? 8 : 5;
- break;
- default:
- picture_rate = 5; /* 30 fps seems like a reasonable default */
- break;
- }
-
- CODE_ADD(c, go->width, 12);
- CODE_ADD(c, go->height, 12);
- CODE_ADD(c, aspect_ratio, 4);
- CODE_ADD(c, picture_rate, 4);
- CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 20000 : 0x3ffff, 18);
- CODE_ADD(c, 1, 1);
- CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 112 : 20, 10);
- CODE_ADD(c, 0, 3);
-
- /* Byte-align with zeros */
- i = 8 - (CODE_LENGTH(c) % 8);
- if (i != 8)
- CODE_ADD(c, 0, i);
-
- if (go->format == V4L2_PIX_FMT_MPEG2) {
- CODE_ADD(c, 0x1, 24);
- CODE_ADD(c, 0xb5, 8);
- CODE_ADD(c, 0x148, 12);
- if (go->interlace_coding)
- CODE_ADD(c, 0x20001, 20);
- else
- CODE_ADD(c, 0xa0001, 20);
- CODE_ADD(c, 0, 16);
-
- /* Byte-align with zeros */
- i = 8 - (CODE_LENGTH(c) % 8);
- if (i != 8)
- CODE_ADD(c, 0, i);
-
- if (ext) {
- CODE_ADD(c, 0x1, 24);
- CODE_ADD(c, 0xb52, 12);
- CODE_ADD(c, go->standard == GO7007_STD_NTSC ? 2 : 1, 3);
- CODE_ADD(c, 0x105, 9);
- CODE_ADD(c, 0x505, 16);
- CODE_ADD(c, go->width, 14);
- CODE_ADD(c, 1, 1);
- CODE_ADD(c, go->height, 14);
-
- /* Byte-align with zeros */
- i = 8 - (CODE_LENGTH(c) % 8);
- if (i != 8)
- CODE_ADD(c, 0, i);
- }
- }
-
- i = CODE_LENGTH(c) + 4 * 8;
- buf[0] = i & 0xff;
- buf[1] = i >> 8;
- buf[2] = 0x00;
- buf[3] = 0x00;
- buf[4] = 0x01;
- buf[5] = 0xb3;
- return i;
-}
-
-static int gen_mpeg1hdr_to_package(struct go7007 *go,
- __le16 *code, int space, int *framelen)
-{
- u8 *buf;
- u16 mem = 0x3e00;
- unsigned int addr = 0x19;
- int i, off = 0, chunk;
-
- buf = kzalloc(5120, GFP_KERNEL);
- if (buf == NULL)
- return -1;
-
- framelen[0] = mpeg1_frame_header(go, buf, 0, 1, PFRAME);
- if (go->interlace_coding)
- framelen[0] += mpeg1_frame_header(go, buf + framelen[0] / 8,
- 0, 2, PFRAME);
- buf[0] = framelen[0] & 0xff;
- buf[1] = framelen[0] >> 8;
- i = 368;
- framelen[1] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_PRE);
- if (go->interlace_coding)
- framelen[1] += mpeg1_frame_header(go, buf + i + framelen[1] / 8,
- 0, 2, BFRAME_PRE);
- buf[i] = framelen[1] & 0xff;
- buf[i + 1] = framelen[1] >> 8;
- i += 1632;
- framelen[2] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_POST);
- if (go->interlace_coding)
- framelen[2] += mpeg1_frame_header(go, buf + i + framelen[2] / 8,
- 0, 2, BFRAME_POST);
- buf[i] = framelen[2] & 0xff;
- buf[i + 1] = framelen[2] >> 8;
- i += 1432;
- framelen[3] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_BIDIR);
- if (go->interlace_coding)
- framelen[3] += mpeg1_frame_header(go, buf + i + framelen[3] / 8,
- 0, 2, BFRAME_BIDIR);
- buf[i] = framelen[3] & 0xff;
- buf[i + 1] = framelen[3] >> 8;
- i += 1632 + 16;
- mpeg1_sequence_header(go, buf + i, 0);
- i += 40;
- for (i = 0; i < 5120; i += chunk * 2) {
- if (space - off < 32) {
- off = -1;
- goto done;
- }
-
- code[off + 1] = __cpu_to_le16(0x8000 | mem);
-
- chunk = 28;
- if (mem + chunk > 0x4000)
- chunk = 0x4000 - mem;
- if (i + 2 * chunk > 5120)
- chunk = (5120 - i) / 2;
-
- if (chunk < 28) {
- code[off] = __cpu_to_le16(0x4000 | chunk);
- code[off + 31] = __cpu_to_le16(addr);
- if (mem + chunk == 0x4000) {
- mem = 0x3e00;
- ++addr;
- }
- } else {
- code[off] = __cpu_to_le16(0x1000 | 28);
- code[off + 31] = 0;
- mem += 28;
- }
-
- memcpy(&code[off + 2], buf + i, chunk * 2);
- off += 32;
- }
-done:
- kfree(buf);
- return off;
-}
-
-static int vti_bitlen(struct go7007 *go)
-{
- unsigned int i, max_time_incr = go->sensor_framerate / go->fps_scale;
-
- for (i = 31; (max_time_incr & ((1 << i) - 1)) == max_time_incr; --i)
- ;
- return i + 1;
-}
-
-static int mpeg4_frame_header(struct go7007 *go, unsigned char *buf,
- int modulo, enum mpeg_frame_type frame)
-{
- int i;
- CODE_GEN(c, buf + 6);
- int mb_count = (go->width >> 4) * (go->height >> 4);
-
- CODE_ADD(c, frame == PFRAME ? 0x1 : 0x2, 2);
- if (modulo)
- CODE_ADD(c, 0x1, 1);
- CODE_ADD(c, 0x1, 2);
- CODE_ADD(c, 0, vti_bitlen(go));
- CODE_ADD(c, 0x3, 2);
- if (frame == PFRAME)
- CODE_ADD(c, 0, 1);
- CODE_ADD(c, 0xc, 11);
- if (frame != PFRAME)
- CODE_ADD(c, 0x4, 3);
- if (frame != BFRAME_EMPTY) {
- for (i = 0; i < mb_count; ++i) {
- switch (frame) {
- case PFRAME:
- CODE_ADD(c, 0x1, 1);
- break;
- case BFRAME_PRE:
- CODE_ADD(c, 0x47, 8);
- break;
- case BFRAME_POST:
- CODE_ADD(c, 0x27, 7);
- break;
- case BFRAME_BIDIR:
- CODE_ADD(c, 0x5f, 8);
- break;
- case BFRAME_EMPTY: /* keep compiler quiet */
- break;
- }
- }
- }
-
- /* Byte-align with a zero followed by ones */
- i = 8 - (CODE_LENGTH(c) % 8);
- CODE_ADD(c, 0, 1);
- CODE_ADD(c, (1 << (i - 1)) - 1, i - 1);
-
- i = CODE_LENGTH(c) + 4 * 8;
- buf[0] = i & 0xff;
- buf[1] = i >> 8;
- buf[2] = 0x00;
- buf[3] = 0x00;
- buf[4] = 0x01;
- buf[5] = 0xb6;
- return i;
-}
-
-static int mpeg4_sequence_header(struct go7007 *go, unsigned char *buf, int ext)
-{
- const unsigned char head[] = { 0x00, 0x00, 0x01, 0xb0, go->pali,
- 0x00, 0x00, 0x01, 0xb5, 0x09,
- 0x00, 0x00, 0x01, 0x00,
- 0x00, 0x00, 0x01, 0x20, };
- int i, aspect_ratio;
- int fps = go->sensor_framerate / go->fps_scale;
- CODE_GEN(c, buf + 2 + sizeof(head));
-
- switch (go->aspect_ratio) {
- case GO7007_RATIO_4_3:
- aspect_ratio = go->standard == GO7007_STD_NTSC ? 3 : 2;
- break;
- case GO7007_RATIO_16_9:
- aspect_ratio = go->standard == GO7007_STD_NTSC ? 5 : 4;
- break;
- default:
- aspect_ratio = 1;
- break;
- }
-
- memcpy(buf + 2, head, sizeof(head));
- CODE_ADD(c, 0x191, 17);
- CODE_ADD(c, aspect_ratio, 4);
- CODE_ADD(c, 0x1, 4);
- CODE_ADD(c, fps, 16);
- CODE_ADD(c, 0x3, 2);
- CODE_ADD(c, 1001, vti_bitlen(go));
- CODE_ADD(c, 1, 1);
- CODE_ADD(c, go->width, 13);
- CODE_ADD(c, 1, 1);
- CODE_ADD(c, go->height, 13);
- CODE_ADD(c, 0x2830, 14);
-
- /* Byte-align */
- i = 8 - (CODE_LENGTH(c) % 8);
- CODE_ADD(c, 0, 1);
- CODE_ADD(c, (1 << (i - 1)) - 1, i - 1);
-
- i = CODE_LENGTH(c) + sizeof(head) * 8;
- buf[0] = i & 0xff;
- buf[1] = i >> 8;
- return i;
-}
-
-static int gen_mpeg4hdr_to_package(struct go7007 *go,
- __le16 *code, int space, int *framelen)
-{
- u8 *buf;
- u16 mem = 0x3e00;
- unsigned int addr = 0x19;
- int i, off = 0, chunk;
-
- buf = kzalloc(5120, GFP_KERNEL);
- if (buf == NULL)
- return -1;
-
- framelen[0] = mpeg4_frame_header(go, buf, 0, PFRAME);
- i = 368;
- framelen[1] = mpeg4_frame_header(go, buf + i, 0, BFRAME_PRE);
- i += 1632;
- framelen[2] = mpeg4_frame_header(go, buf + i, 0, BFRAME_POST);
- i += 1432;
- framelen[3] = mpeg4_frame_header(go, buf + i, 0, BFRAME_BIDIR);
- i += 1632;
- mpeg4_frame_header(go, buf + i, 0, BFRAME_EMPTY);
- i += 16;
- mpeg4_sequence_header(go, buf + i, 0);
- i += 40;
- for (i = 0; i < 5120; i += chunk * 2) {
- if (space - off < 32) {
- off = -1;
- goto done;
- }
-
- code[off + 1] = __cpu_to_le16(0x8000 | mem);
-
- chunk = 28;
- if (mem + chunk > 0x4000)
- chunk = 0x4000 - mem;
- if (i + 2 * chunk > 5120)
- chunk = (5120 - i) / 2;
-
- if (chunk < 28) {
- code[off] = __cpu_to_le16(0x4000 | chunk);
- code[off + 31] = __cpu_to_le16(addr);
- if (mem + chunk == 0x4000) {
- mem = 0x3e00;
- ++addr;
- }
- } else {
- code[off] = __cpu_to_le16(0x1000 | 28);
- code[off + 31] = 0;
- mem += 28;
- }
-
- memcpy(&code[off + 2], buf + i, chunk * 2);
- off += 32;
- }
- mem = 0x3e00;
- addr = go->ipb ? 0x14f9 : 0x0af9;
- memset(buf, 0, 5120);
- framelen[4] = mpeg4_frame_header(go, buf, 1, PFRAME);
- i = 368;
- framelen[5] = mpeg4_frame_header(go, buf + i, 1, BFRAME_PRE);
- i += 1632;
- framelen[6] = mpeg4_frame_header(go, buf + i, 1, BFRAME_POST);
- i += 1432;
- framelen[7] = mpeg4_frame_header(go, buf + i, 1, BFRAME_BIDIR);
- i += 1632;
- mpeg4_frame_header(go, buf + i, 1, BFRAME_EMPTY);
- i += 16;
- for (i = 0; i < 5120; i += chunk * 2) {
- if (space - off < 32) {
- off = -1;
- goto done;
- }
-
- code[off + 1] = __cpu_to_le16(0x8000 | mem);
-
- chunk = 28;
- if (mem + chunk > 0x4000)
- chunk = 0x4000 - mem;
- if (i + 2 * chunk > 5120)
- chunk = (5120 - i) / 2;
-
- if (chunk < 28) {
- code[off] = __cpu_to_le16(0x4000 | chunk);
- code[off + 31] = __cpu_to_le16(addr);
- if (mem + chunk == 0x4000) {
- mem = 0x3e00;
- ++addr;
- }
- } else {
- code[off] = __cpu_to_le16(0x1000 | 28);
- code[off + 31] = 0;
- mem += 28;
- }
-
- memcpy(&code[off + 2], buf + i, chunk * 2);
- off += 32;
- }
-done:
- kfree(buf);
- return off;
-}
-
-static int brctrl_to_package(struct go7007 *go,
- __le16 *code, int space, int *framelen)
-{
- int converge_speed = 0;
- int lambda = (go->format == V4L2_PIX_FMT_MJPEG || go->dvd_mode) ?
- 100 : 0;
- int peak_rate = 6 * go->bitrate / 5;
- int vbv_buffer = go->format == V4L2_PIX_FMT_MJPEG ?
- go->bitrate :
- (go->dvd_mode ? 900000 : peak_rate);
- int fps = go->sensor_framerate / go->fps_scale;
- int q = 0;
- /* Bizarre math below depends on rounding errors in division */
- u32 sgop_expt_addr = go->bitrate / 32 * (go->ipb ? 3 : 1) * 1001 / fps;
- u32 sgop_peak_addr = peak_rate / 32 * 1001 / fps;
- u32 total_expt_addr = go->bitrate / 32 * 1000 / fps * (fps / 1000);
- u32 vbv_alert_addr = vbv_buffer * 3 / (4 * 32);
- u32 cplx[] = {
- q > 0 ? sgop_expt_addr * q :
- 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
- q > 0 ? sgop_expt_addr * q :
- 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
- q > 0 ? sgop_expt_addr * q :
- 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
- q > 0 ? sgop_expt_addr * q :
- 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
- };
- u32 calc_q = q > 0 ? q : cplx[0] / sgop_expt_addr;
- u16 pack[] = {
- 0x200e, 0x0000,
- 0xBF20, go->ipb ? converge_speed_ipb[converge_speed]
- : converge_speed_ip[converge_speed],
- 0xBF21, go->ipb ? 2 : 0,
- 0xBF22, go->ipb ? LAMBDA_table[0][lambda / 2 + 50]
- : 32767,
- 0xBF23, go->ipb ? LAMBDA_table[1][lambda] : 32767,
- 0xBF24, 32767,
- 0xBF25, lambda > 99 ? 32767 : LAMBDA_table[3][lambda],
- 0xBF26, sgop_expt_addr & 0x0000FFFF,
- 0xBF27, sgop_expt_addr >> 16,
- 0xBF28, sgop_peak_addr & 0x0000FFFF,
- 0xBF29, sgop_peak_addr >> 16,
- 0xBF2A, vbv_alert_addr & 0x0000FFFF,
- 0xBF2B, vbv_alert_addr >> 16,
- 0xBF2C, 0,
- 0xBF2D, 0,
- 0, 0,
-
- 0x200e, 0x0000,
- 0xBF2E, vbv_alert_addr & 0x0000FFFF,
- 0xBF2F, vbv_alert_addr >> 16,
- 0xBF30, cplx[0] & 0x0000FFFF,
- 0xBF31, cplx[0] >> 16,
- 0xBF32, cplx[1] & 0x0000FFFF,
- 0xBF33, cplx[1] >> 16,
- 0xBF34, cplx[2] & 0x0000FFFF,
- 0xBF35, cplx[2] >> 16,
- 0xBF36, cplx[3] & 0x0000FFFF,
- 0xBF37, cplx[3] >> 16,
- 0xBF38, 0,
- 0xBF39, 0,
- 0xBF3A, total_expt_addr & 0x0000FFFF,
- 0xBF3B, total_expt_addr >> 16,
- 0, 0,
-
- 0x200e, 0x0000,
- 0xBF3C, total_expt_addr & 0x0000FFFF,
- 0xBF3D, total_expt_addr >> 16,
- 0xBF3E, 0,
- 0xBF3F, 0,
- 0xBF48, 0,
- 0xBF49, 0,
- 0xBF4A, calc_q < 4 ? 4 : (calc_q > 124 ? 124 : calc_q),
- 0xBF4B, 4,
- 0xBF4C, 0,
- 0xBF4D, 0,
- 0xBF4E, 0,
- 0xBF4F, 0,
- 0xBF50, 0,
- 0xBF51, 0,
- 0, 0,
-
- 0x200e, 0x0000,
- 0xBF40, sgop_expt_addr & 0x0000FFFF,
- 0xBF41, sgop_expt_addr >> 16,
- 0xBF42, 0,
- 0xBF43, 0,
- 0xBF44, 0,
- 0xBF45, 0,
- 0xBF46, (go->width >> 4) * (go->height >> 4),
- 0xBF47, 0,
- 0xBF64, 0,
- 0xBF65, 0,
- 0xBF18, framelen[4],
- 0xBF19, framelen[5],
- 0xBF1A, framelen[6],
- 0xBF1B, framelen[7],
- 0, 0,
-
-#if 0
- /* Remove once we don't care about matching */
- 0x200e, 0x0000,
- 0xBF56, 4,
- 0xBF57, 0,
- 0xBF58, 5,
- 0xBF59, 0,
- 0xBF5A, 6,
- 0xBF5B, 0,
- 0xBF5C, 8,
- 0xBF5D, 0,
- 0xBF5E, 1,
- 0xBF5F, 0,
- 0xBF60, 1,
- 0xBF61, 0,
- 0xBF62, 0,
- 0xBF63, 0,
- 0, 0,
-#else
- 0x2008, 0x0000,
- 0xBF56, 4,
- 0xBF57, 0,
- 0xBF58, 5,
- 0xBF59, 0,
- 0xBF5A, 6,
- 0xBF5B, 0,
- 0xBF5C, 8,
- 0xBF5D, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
-#endif
-
- 0x200e, 0x0000,
- 0xBF10, 0,
- 0xBF11, 0,
- 0xBF12, 0,
- 0xBF13, 0,
- 0xBF14, 0,
- 0xBF15, 0,
- 0xBF16, 0,
- 0xBF17, 0,
- 0xBF7E, 0,
- 0xBF7F, 1,
- 0xBF52, framelen[0],
- 0xBF53, framelen[1],
- 0xBF54, framelen[2],
- 0xBF55, framelen[3],
- 0, 0,
- };
-
- return copy_packages(code, pack, 6, space);
-}
-
-static int config_package(struct go7007 *go, __le16 *code, int space)
-{
- int fps = go->sensor_framerate / go->fps_scale / 1000;
- int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
- int brc_window_size = fps;
- int q_min = 2, q_max = 31;
- int THACCoeffSet0 = 0;
- u16 pack[] = {
- 0x200e, 0x0000,
- 0xc002, 0x14b4,
- 0xc003, 0x28b4,
- 0xc004, 0x3c5a,
- 0xdc05, 0x2a77,
- 0xc6c3, go->format == V4L2_PIX_FMT_MPEG4 ? 0 :
- (go->format == V4L2_PIX_FMT_H263 ? 0 : 1),
- 0xc680, go->format == V4L2_PIX_FMT_MPEG4 ? 0xf1 :
- (go->format == V4L2_PIX_FMT_H263 ? 0x61 :
- 0xd3),
- 0xc780, 0x0140,
- 0xe009, 0x0001,
- 0xc60f, 0x0008,
- 0xd4ff, 0x0002,
- 0xe403, 2340,
- 0xe406, 75,
- 0xd411, 0x0001,
- 0xd410, 0xa1d6,
- 0x0001, 0x2801,
-
- 0x200d, 0x0000,
- 0xe402, 0x018b,
- 0xe401, 0x8b01,
- 0xd472, (go->board_info->sensor_flags &
- GO7007_SENSOR_TV) &&
- (!go->interlace_coding) ?
- 0x01b0 : 0x0170,
- 0xd475, (go->board_info->sensor_flags &
- GO7007_SENSOR_TV) &&
- (!go->interlace_coding) ?
- 0x0008 : 0x0009,
- 0xc404, go->interlace_coding ? 0x44 :
- (go->format == V4L2_PIX_FMT_MPEG4 ? 0x11 :
- (go->format == V4L2_PIX_FMT_MPEG1 ? 0x02 :
- (go->format == V4L2_PIX_FMT_MPEG2 ? 0x04 :
- (go->format == V4L2_PIX_FMT_H263 ? 0x08 :
- 0x20)))),
- 0xbf0a, (go->format == V4L2_PIX_FMT_MPEG4 ? 8 :
- (go->format == V4L2_PIX_FMT_MPEG1 ? 1 :
- (go->format == V4L2_PIX_FMT_MPEG2 ? 2 :
- (go->format == V4L2_PIX_FMT_H263 ? 4 : 16)))) |
- ((go->repeat_seqhead ? 1 : 0) << 6) |
- ((go->dvd_mode ? 1 : 0) << 9) |
- ((go->gop_header_enable ? 1 : 0) << 10),
- 0xbf0b, 0,
- 0xdd5a, go->ipb ? 0x14 : 0x0a,
- 0xbf0c, 0,
- 0xbf0d, 0,
- 0xc683, THACCoeffSet0,
- 0xc40a, (go->width << 4) | rows,
- 0xe01a, go->board_info->hpi_buffer_cap,
- 0, 0,
- 0, 0,
-
- 0x2008, 0,
- 0xe402, 0x88,
- 0xe401, 0x8f01,
- 0xbf6a, 0,
- 0xbf6b, 0,
- 0xbf6c, 0,
- 0xbf6d, 0,
- 0xbf6e, 0,
- 0xbf6f, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
-
- 0x200e, 0,
- 0xbf66, brc_window_size,
- 0xbf67, 0,
- 0xbf68, q_min,
- 0xbf69, q_max,
- 0xbfe0, 0,
- 0xbfe1, 0,
- 0xbfe2, 0,
- 0xbfe3, go->ipb ? 3 : 1,
- 0xc031, go->board_info->sensor_flags &
- GO7007_SENSOR_VBI ? 1 : 0,
- 0xc01c, 0x1f,
- 0xdd8c, 0x15,
- 0xdd94, 0x15,
- 0xdd88, go->ipb ? 0x1401 : 0x0a01,
- 0xdd90, go->ipb ? 0x1401 : 0x0a01,
- 0, 0,
-
- 0x200e, 0,
- 0xbfe4, 0,
- 0xbfe5, 0,
- 0xbfe6, 0,
- 0xbfe7, fps << 8,
- 0xbfe8, 0x3a00,
- 0xbfe9, 0,
- 0xbfea, 0,
- 0xbfeb, 0,
- 0xbfec, (go->interlace_coding ? 1 << 15 : 0) |
- (go->modet_enable ? 0xa : 0) |
- (go->board_info->sensor_flags &
- GO7007_SENSOR_VBI ? 1 : 0),
- 0xbfed, 0,
- 0xbfee, 0,
- 0xbfef, 0,
- 0xbff0, go->board_info->sensor_flags &
- GO7007_SENSOR_TV ? 0xf060 : 0xb060,
- 0xbff1, 0,
- 0, 0,
- };
-
- return copy_packages(code, pack, 5, space);
-}
-
-static int seqhead_to_package(struct go7007 *go, __le16 *code, int space,
- int (*sequence_header_func)(struct go7007 *go,
- unsigned char *buf, int ext))
-{
- int vop_time_increment_bitlength = vti_bitlen(go);
- int fps = go->sensor_framerate / go->fps_scale *
- (go->interlace_coding ? 2 : 1);
- unsigned char buf[40] = { };
- int len = sequence_header_func(go, buf, 1);
- u16 pack[] = {
- 0x2006, 0,
- 0xbf08, fps,
- 0xbf09, 0,
- 0xbff2, vop_time_increment_bitlength,
- 0xbff3, (1 << vop_time_increment_bitlength) - 1,
- 0xbfe6, 0,
- 0xbfe7, (fps / 1000) << 8,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
-
- 0x2007, 0,
- 0xc800, buf[2] << 8 | buf[3],
- 0xc801, buf[4] << 8 | buf[5],
- 0xc802, buf[6] << 8 | buf[7],
- 0xc803, buf[8] << 8 | buf[9],
- 0xc406, 64,
- 0xc407, len - 64,
- 0xc61b, 1,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
-
- 0x200e, 0,
- 0xc808, buf[10] << 8 | buf[11],
- 0xc809, buf[12] << 8 | buf[13],
- 0xc80a, buf[14] << 8 | buf[15],
- 0xc80b, buf[16] << 8 | buf[17],
- 0xc80c, buf[18] << 8 | buf[19],
- 0xc80d, buf[20] << 8 | buf[21],
- 0xc80e, buf[22] << 8 | buf[23],
- 0xc80f, buf[24] << 8 | buf[25],
- 0xc810, buf[26] << 8 | buf[27],
- 0xc811, buf[28] << 8 | buf[29],
- 0xc812, buf[30] << 8 | buf[31],
- 0xc813, buf[32] << 8 | buf[33],
- 0xc814, buf[34] << 8 | buf[35],
- 0xc815, buf[36] << 8 | buf[37],
- 0, 0,
- 0, 0,
- 0, 0,
- };
-
- return copy_packages(code, pack, 3, space);
-}
-
-static int relative_prime(int big, int little)
-{
- int remainder;
-
- while (little != 0) {
- remainder = big % little;
- big = little;
- little = remainder;
- }
- return big;
-}
-
-static int avsync_to_package(struct go7007 *go, __le16 *code, int space)
-{
- int arate = go->board_info->audio_rate * 1001 * go->fps_scale;
- int ratio = arate / go->sensor_framerate;
- int adjratio = ratio * 215 / 100;
- int rprime = relative_prime(go->sensor_framerate,
- arate % go->sensor_framerate);
- int f1 = (arate % go->sensor_framerate) / rprime;
- int f2 = (go->sensor_framerate - arate % go->sensor_framerate) / rprime;
- u16 pack[] = {
- 0x200e, 0,
- 0xbf98, (u16)((-adjratio) & 0xffff),
- 0xbf99, (u16)((-adjratio) >> 16),
- 0xbf92, 0,
- 0xbf93, 0,
- 0xbff4, f1 > f2 ? f1 : f2,
- 0xbff5, f1 < f2 ? f1 : f2,
- 0xbff6, f1 < f2 ? ratio : ratio + 1,
- 0xbff7, f1 > f2 ? ratio : ratio + 1,
- 0xbff8, 0,
- 0xbff9, 0,
- 0xbffa, adjratio & 0xffff,
- 0xbffb, adjratio >> 16,
- 0xbf94, 0,
- 0xbf95, 0,
- 0, 0,
- };
-
- return copy_packages(code, pack, 1, space);
-}
-
-static int final_package(struct go7007 *go, __le16 *code, int space)
-{
- int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
- u16 pack[] = {
- 0x8000,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 2,
- ((go->board_info->sensor_flags & GO7007_SENSOR_TV) &&
- (!go->interlace_coding) ?
- (1 << 14) | (1 << 9) : 0) |
- ((go->encoder_subsample ? 1 : 0) << 8) |
- (go->board_info->sensor_flags &
- GO7007_SENSOR_CONFIG_MASK),
- ((go->encoder_v_halve ? 1 : 0) << 14) |
- (go->encoder_v_halve ? rows << 9 : rows << 8) |
- (go->encoder_h_halve ? 1 << 6 : 0) |
- (go->encoder_h_halve ? go->width >> 3 : go->width >> 4),
- (1 << 15) | (go->encoder_v_offset << 6) |
- (1 << 7) | (go->encoder_h_offset >> 2),
- (1 << 6),
- 0,
- 0,
- ((go->fps_scale - 1) << 8) |
- (go->board_info->sensor_flags & GO7007_SENSOR_TV ?
- (1 << 7) : 0) |
- 0x41,
- go->ipb ? 0xd4c : 0x36b,
- (rows << 8) | (go->width >> 4),
- go->format == V4L2_PIX_FMT_MPEG4 ? 0x0404 : 0,
- (1 << 15) | ((go->interlace_coding ? 1 : 0) << 13) |
- ((go->closed_gop ? 1 : 0) << 12) |
- ((go->format == V4L2_PIX_FMT_MPEG4 ? 1 : 0) << 11) |
- /* (1 << 9) | */
- ((go->ipb ? 3 : 0) << 7) |
- ((go->modet_enable ? 1 : 0) << 2) |
- ((go->dvd_mode ? 1 : 0) << 1) | 1,
- (go->format == V4L2_PIX_FMT_MPEG1 ? 0x89a0 :
- (go->format == V4L2_PIX_FMT_MPEG2 ? 0x89a0 :
- (go->format == V4L2_PIX_FMT_MJPEG ? 0x89a0 :
- (go->format == V4L2_PIX_FMT_MPEG4 ? 0x8920 :
- (go->format == V4L2_PIX_FMT_H263 ? 0x8920 : 0))))),
- go->ipb ? 0x1f15 : 0x1f0b,
- go->ipb ? 0x0015 : 0x000b,
- go->ipb ? 0xa800 : 0x5800,
- 0xffff,
- 0x0020 + 0x034b * 0,
- 0x0020 + 0x034b * 1,
- 0x0020 + 0x034b * 2,
- 0x0020 + 0x034b * 3,
- 0x0020 + 0x034b * 4,
- 0x0020 + 0x034b * 5,
- go->ipb ? (go->gop_size / 3) : go->gop_size,
- (go->height >> 4) * (go->width >> 4) * 110 / 100,
- };
-
- return copy_packages(code, pack, 1, space);
-}
-
-static int audio_to_package(struct go7007 *go, __le16 *code, int space)
-{
- int clock_config = ((go->board_info->audio_flags &
- GO7007_AUDIO_I2S_MASTER ? 1 : 0) << 11) |
- ((go->board_info->audio_flags &
- GO7007_AUDIO_OKI_MODE ? 1 : 0) << 8) |
- (((go->board_info->audio_bclk_div / 4) - 1) << 4) |
- (go->board_info->audio_main_div - 1);
- u16 pack[] = {
- 0x200d, 0,
- 0x9002, 0,
- 0x9002, 0,
- 0x9031, 0,
- 0x9032, 0,
- 0x9033, 0,
- 0x9034, 0,
- 0x9035, 0,
- 0x9036, 0,
- 0x9037, 0,
- 0x9040, 0,
- 0x9000, clock_config,
- 0x9001, (go->board_info->audio_flags & 0xffff) |
- (1 << 9),
- 0x9000, ((go->board_info->audio_flags &
- GO7007_AUDIO_I2S_MASTER ?
- 1 : 0) << 10) |
- clock_config,
- 0, 0,
- 0, 0,
- 0x2005, 0,
- 0x9041, 0,
- 0x9042, 256,
- 0x9043, 0,
- 0x9044, 16,
- 0x9045, 16,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- };
-
- return copy_packages(code, pack, 2, space);
-}
-
-static int modet_to_package(struct go7007 *go, __le16 *code, int space)
-{
- int ret, mb, i, addr, cnt = 0;
- u16 pack[32];
- u16 thresholds[] = {
- 0x200e, 0,
- 0xbf82, go->modet[0].pixel_threshold,
- 0xbf83, go->modet[1].pixel_threshold,
- 0xbf84, go->modet[2].pixel_threshold,
- 0xbf85, go->modet[3].pixel_threshold,
- 0xbf86, go->modet[0].motion_threshold,
- 0xbf87, go->modet[1].motion_threshold,
- 0xbf88, go->modet[2].motion_threshold,
- 0xbf89, go->modet[3].motion_threshold,
- 0xbf8a, go->modet[0].mb_threshold,
- 0xbf8b, go->modet[1].mb_threshold,
- 0xbf8c, go->modet[2].mb_threshold,
- 0xbf8d, go->modet[3].mb_threshold,
- 0xbf8e, 0,
- 0xbf8f, 0,
- 0, 0,
- };
-
- ret = copy_packages(code, thresholds, 1, space);
- if (ret < 0)
- return -1;
- cnt += ret;
-
- addr = 0xbac0;
- memset(pack, 0, 64);
- i = 0;
- for (mb = 0; mb < 1624; ++mb) {
- pack[i * 2 + 3] <<= 2;
- pack[i * 2 + 3] |= go->modet_map[mb];
- if (mb % 8 != 7)
- continue;
- pack[i * 2 + 2] = addr++;
- ++i;
- if (i == 10 || mb == 1623) {
- pack[0] = 0x2000 | i;
- ret = copy_packages(code + cnt, pack, 1, space - cnt);
- if (ret < 0)
- return -1;
- cnt += ret;
- i = 0;
- memset(pack, 0, 64);
- }
- pack[i * 2 + 3] = 0;
- }
-
- memset(pack, 0, 64);
- i = 0;
- for (addr = 0xbb90; addr < 0xbbfa; ++addr) {
- pack[i * 2 + 2] = addr;
- pack[i * 2 + 3] = 0;
- ++i;
- if (i == 10 || addr == 0xbbf9) {
- pack[0] = 0x2000 | i;
- ret = copy_packages(code + cnt, pack, 1, space - cnt);
- if (ret < 0)
- return -1;
- cnt += ret;
- i = 0;
- memset(pack, 0, 64);
- }
- }
- return cnt;
-}
-
-static int do_special(struct go7007 *go, u16 type, __le16 *code, int space,
- int *framelen)
-{
- switch (type) {
- case SPECIAL_FRM_HEAD:
- switch (go->format) {
- case V4L2_PIX_FMT_MJPEG:
- return gen_mjpeghdr_to_package(go, code, space);
- case V4L2_PIX_FMT_MPEG1:
- case V4L2_PIX_FMT_MPEG2:
- return gen_mpeg1hdr_to_package(go, code, space,
- framelen);
- case V4L2_PIX_FMT_MPEG4:
- return gen_mpeg4hdr_to_package(go, code, space,
- framelen);
- }
- case SPECIAL_BRC_CTRL:
- return brctrl_to_package(go, code, space, framelen);
- case SPECIAL_CONFIG:
- return config_package(go, code, space);
- case SPECIAL_SEQHEAD:
- switch (go->format) {
- case V4L2_PIX_FMT_MPEG1:
- case V4L2_PIX_FMT_MPEG2:
- return seqhead_to_package(go, code, space,
- mpeg1_sequence_header);
- case V4L2_PIX_FMT_MPEG4:
- return seqhead_to_package(go, code, space,
- mpeg4_sequence_header);
- default:
- return 0;
- }
- case SPECIAL_AV_SYNC:
- return avsync_to_package(go, code, space);
- case SPECIAL_FINAL:
- return final_package(go, code, space);
- case SPECIAL_AUDIO:
- return audio_to_package(go, code, space);
- case SPECIAL_MODET:
- return modet_to_package(go, code, space);
- }
- dev_err(go->dev,
- "firmware file contains unsupported feature %04x\n", type);
- return -1;
-}
-
-int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen)
-{
- const struct firmware *fw_entry;
- __le16 *code, *src;
- int framelen[8] = { }; /* holds the lengths of empty frame templates */
- int codespace = 64 * 1024, i = 0, srclen, chunk_len, chunk_flags;
- int mode_flag;
- int ret;
-
- switch (go->format) {
- case V4L2_PIX_FMT_MJPEG:
- mode_flag = FLAG_MODE_MJPEG;
- break;
- case V4L2_PIX_FMT_MPEG1:
- mode_flag = FLAG_MODE_MPEG1;
- break;
- case V4L2_PIX_FMT_MPEG2:
- mode_flag = FLAG_MODE_MPEG2;
- break;
- case V4L2_PIX_FMT_MPEG4:
- mode_flag = FLAG_MODE_MPEG4;
- break;
- default:
- return -1;
- }
- if (request_firmware(&fw_entry, GO7007_FW_NAME, go->dev)) {
- dev_err(go->dev,
- "unable to load firmware from file \"%s\"\n",
- GO7007_FW_NAME);
- return -1;
- }
- code = kzalloc(codespace * 2, GFP_KERNEL);
- if (code == NULL)
- goto fw_failed;
-
- src = (__le16 *)fw_entry->data;
- srclen = fw_entry->size / 2;
- while (srclen >= 2) {
- chunk_flags = __le16_to_cpu(src[0]);
- chunk_len = __le16_to_cpu(src[1]);
- if (chunk_len + 2 > srclen) {
- dev_err(go->dev,
- "firmware file \"%s\" appears to be corrupted\n",
- GO7007_FW_NAME);
- goto fw_failed;
- }
- if (chunk_flags & mode_flag) {
- if (chunk_flags & FLAG_SPECIAL) {
- ret = do_special(go, __le16_to_cpu(src[2]),
- &code[i], codespace - i, framelen);
- if (ret < 0) {
- dev_err(go->dev,
- "insufficient memory for firmware construction\n");
- goto fw_failed;
- }
- i += ret;
- } else {
- if (codespace - i < chunk_len) {
- dev_err(go->dev,
- "insufficient memory for firmware construction\n");
- goto fw_failed;
- }
- memcpy(&code[i], &src[2], chunk_len * 2);
- i += chunk_len;
- }
- }
- srclen -= chunk_len + 2;
- src += chunk_len + 2;
- }
- release_firmware(fw_entry);
- *fw = (u8 *)code;
- *fwlen = i * 2;
- return 0;
-
-fw_failed:
- kfree(code);
- release_firmware(fw_entry);
- return -1;
-}
-
-MODULE_FIRMWARE(GO7007_FW_NAME);
diff --git a/drivers/staging/media/go7007/go7007-i2c.c b/drivers/staging/media/go7007/go7007-i2c.c
deleted file mode 100644
index 4cf4c0d65085..000000000000
--- a/drivers/staging/media/go7007/go7007-i2c.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/list.h>
-#include <linux/unistd.h>
-#include <linux/time.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-#include <linux/uaccess.h>
-
-#include "go7007-priv.h"
-
-/********************* Driver for on-board I2C adapter *********************/
-
-/* #define GO7007_I2C_DEBUG */
-
-#define SPI_I2C_ADDR_BASE 0x1400
-#define STATUS_REG_ADDR (SPI_I2C_ADDR_BASE + 0x2)
-#define I2C_CTRL_REG_ADDR (SPI_I2C_ADDR_BASE + 0x6)
-#define I2C_DEV_UP_ADDR_REG_ADDR (SPI_I2C_ADDR_BASE + 0x7)
-#define I2C_LO_ADDR_REG_ADDR (SPI_I2C_ADDR_BASE + 0x8)
-#define I2C_DATA_REG_ADDR (SPI_I2C_ADDR_BASE + 0x9)
-#define I2C_CLKFREQ_REG_ADDR (SPI_I2C_ADDR_BASE + 0xa)
-
-#define I2C_STATE_MASK 0x0007
-#define I2C_READ_READY_MASK 0x0008
-
-/* There is only one I2C port on the TW2804 that feeds all four GO7007 VIPs
- * on the Adlink PCI-MPG24, so access is shared between all of them. */
-static DEFINE_MUTEX(adlink_mpg24_i2c_lock);
-
-static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read,
- u16 command, int flags, u8 *data)
-{
- int i, ret = -EIO;
- u16 val;
-
- if (go->status == STATUS_SHUTDOWN)
- return -ENODEV;
-
-#ifdef GO7007_I2C_DEBUG
- if (read)
- dev_dbg(go->dev, "go7007-i2c: reading 0x%02x on 0x%02x\n",
- command, addr);
- else
- dev_dbg(go->dev,
- "go7007-i2c: writing 0x%02x to 0x%02x on 0x%02x\n",
- *data, command, addr);
-#endif
-
- mutex_lock(&go->hw_lock);
-
- if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
- /* Bridge the I2C port on this GO7007 to the shared bus */
- mutex_lock(&adlink_mpg24_i2c_lock);
- go7007_write_addr(go, 0x3c82, 0x0020);
- }
-
- /* Wait for I2C adapter to be ready */
- for (i = 0; i < 10; ++i) {
- if (go7007_read_addr(go, STATUS_REG_ADDR, &val) < 0)
- goto i2c_done;
- if (!(val & I2C_STATE_MASK))
- break;
- msleep(100);
- }
- if (i == 10) {
- dev_err(go->dev, "go7007-i2c: I2C adapter is hung\n");
- goto i2c_done;
- }
-
- /* Set target register (command) */
- go7007_write_addr(go, I2C_CTRL_REG_ADDR, flags);
- go7007_write_addr(go, I2C_LO_ADDR_REG_ADDR, command);
-
- /* If we're writing, send the data and target address and we're done */
- if (!read) {
- go7007_write_addr(go, I2C_DATA_REG_ADDR, *data);
- go7007_write_addr(go, I2C_DEV_UP_ADDR_REG_ADDR,
- (addr << 9) | (command >> 8));
- ret = 0;
- goto i2c_done;
- }
-
- /* Otherwise, we're reading. First clear i2c_rx_data_rdy. */
- if (go7007_read_addr(go, I2C_DATA_REG_ADDR, &val) < 0)
- goto i2c_done;
-
- /* Send the target address plus read flag */
- go7007_write_addr(go, I2C_DEV_UP_ADDR_REG_ADDR,
- (addr << 9) | 0x0100 | (command >> 8));
-
- /* Wait for i2c_rx_data_rdy */
- for (i = 0; i < 10; ++i) {
- if (go7007_read_addr(go, STATUS_REG_ADDR, &val) < 0)
- goto i2c_done;
- if (val & I2C_READ_READY_MASK)
- break;
- msleep(100);
- }
- if (i == 10) {
- dev_err(go->dev, "go7007-i2c: I2C adapter is hung\n");
- goto i2c_done;
- }
-
- /* Retrieve the read byte */
- if (go7007_read_addr(go, I2C_DATA_REG_ADDR, &val) < 0)
- goto i2c_done;
- *data = val;
- ret = 0;
-
-i2c_done:
- if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
- /* Isolate the I2C port on this GO7007 from the shared bus */
- go7007_write_addr(go, 0x3c82, 0x0000);
- mutex_unlock(&adlink_mpg24_i2c_lock);
- }
- mutex_unlock(&go->hw_lock);
- return ret;
-}
-
-static int go7007_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size, union i2c_smbus_data *data)
-{
- struct go7007 *go = i2c_get_adapdata(adapter);
-
- if (size != I2C_SMBUS_BYTE_DATA)
- return -EIO;
- return go7007_i2c_xfer(go, addr, read_write == I2C_SMBUS_READ, command,
- flags & I2C_CLIENT_SCCB ? 0x10 : 0x00, &data->byte);
-}
-
-/* VERY LIMITED I2C master xfer function -- only needed because the
- * SMBus functions only support 8-bit commands and the SAA7135 uses
- * 16-bit commands. The I2C interface on the GO7007, as limited as
- * it is, does support this mode. */
-
-static int go7007_i2c_master_xfer(struct i2c_adapter *adapter,
- struct i2c_msg msgs[], int num)
-{
- struct go7007 *go = i2c_get_adapdata(adapter);
- int i;
-
- for (i = 0; i < num; ++i) {
- /* We can only do two things here -- write three bytes, or
- * write two bytes and read one byte. */
- if (msgs[i].len == 2) {
- if (i + 1 == num || msgs[i].addr != msgs[i + 1].addr ||
- (msgs[i].flags & I2C_M_RD) ||
- !(msgs[i + 1].flags & I2C_M_RD) ||
- msgs[i + 1].len != 1)
- return -EIO;
- if (go7007_i2c_xfer(go, msgs[i].addr, 1,
- (msgs[i].buf[0] << 8) | msgs[i].buf[1],
- 0x01, &msgs[i + 1].buf[0]) < 0)
- return -EIO;
- ++i;
- } else if (msgs[i].len == 3) {
- if (msgs[i].flags & I2C_M_RD)
- return -EIO;
- if (msgs[i].len != 3)
- return -EIO;
- if (go7007_i2c_xfer(go, msgs[i].addr, 0,
- (msgs[i].buf[0] << 8) | msgs[i].buf[1],
- 0x01, &msgs[i].buf[2]) < 0)
- return -EIO;
- } else
- return -EIO;
- }
-
- return num;
-}
-
-static u32 go7007_functionality(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_SMBUS_BYTE_DATA;
-}
-
-static struct i2c_algorithm go7007_algo = {
- .smbus_xfer = go7007_smbus_xfer,
- .master_xfer = go7007_i2c_master_xfer,
- .functionality = go7007_functionality,
-};
-
-static struct i2c_adapter go7007_adap_templ = {
- .owner = THIS_MODULE,
- .name = "WIS GO7007SB",
- .algo = &go7007_algo,
-};
-
-int go7007_i2c_init(struct go7007 *go)
-{
- memcpy(&go->i2c_adapter, &go7007_adap_templ,
- sizeof(go7007_adap_templ));
- go->i2c_adapter.dev.parent = go->dev;
- i2c_set_adapdata(&go->i2c_adapter, go);
- if (i2c_add_adapter(&go->i2c_adapter) < 0) {
- dev_err(go->dev,
- "go7007-i2c: error: i2c_add_adapter failed\n");
- return -1;
- }
- return 0;
-}
diff --git a/drivers/staging/media/go7007/go7007-loader.c b/drivers/staging/media/go7007/go7007-loader.c
deleted file mode 100644
index 491d0e697f5a..000000000000
--- a/drivers/staging/media/go7007/go7007-loader.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2008 Sensoray Company 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/firmware.h>
-#include <cypress_firmware.h>
-
-struct fw_config {
- u16 vendor;
- u16 product;
- const char * const fw_name1;
- const char * const fw_name2;
-};
-
-static struct fw_config fw_configs[] = {
- { 0x1943, 0xa250, "go7007/s2250-1.fw", "go7007/s2250-2.fw" },
- { 0x093b, 0xa002, "go7007/px-m402u.fw", NULL },
- { 0x093b, 0xa004, "go7007/px-tv402u.fw", NULL },
- { 0x0eb1, 0x6666, "go7007/lr192.fw", NULL },
- { 0x0eb1, 0x6668, "go7007/wis-startrek.fw", NULL },
- { 0, 0, NULL, NULL }
-};
-MODULE_FIRMWARE("go7007/s2250-1.fw");
-MODULE_FIRMWARE("go7007/s2250-2.fw");
-MODULE_FIRMWARE("go7007/px-m402u.fw");
-MODULE_FIRMWARE("go7007/px-tv402u.fw");
-MODULE_FIRMWARE("go7007/lr192.fw");
-MODULE_FIRMWARE("go7007/wis-startrek.fw");
-
-static int go7007_loader_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
-{
- struct usb_device *usbdev;
- const struct firmware *fw;
- u16 vendor, product;
- const char *fw1, *fw2;
- int ret;
- int i;
-
- usbdev = usb_get_dev(interface_to_usbdev(interface));
- if (!usbdev)
- goto failed2;
-
- if (usbdev->descriptor.bNumConfigurations != 1) {
- dev_err(&interface->dev, "can't handle multiple config\n");
- goto failed2;
- }
-
- vendor = le16_to_cpu(usbdev->descriptor.idVendor);
- product = le16_to_cpu(usbdev->descriptor.idProduct);
-
- for (i = 0; fw_configs[i].fw_name1; i++)
- if (fw_configs[i].vendor == vendor &&
- fw_configs[i].product == product)
- break;
-
- /* Should never happen */
- if (fw_configs[i].fw_name1 == NULL)
- goto failed2;
-
- fw1 = fw_configs[i].fw_name1;
- fw2 = fw_configs[i].fw_name2;
-
- dev_info(&interface->dev, "loading firmware %s\n", fw1);
-
- if (request_firmware(&fw, fw1, &usbdev->dev)) {
- dev_err(&interface->dev,
- "unable to load firmware from file \"%s\"\n", fw1);
- goto failed2;
- }
- ret = cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
- release_firmware(fw);
- if (0 != ret) {
- dev_err(&interface->dev, "loader download failed\n");
- goto failed2;
- }
-
- if (fw2 == NULL)
- return 0;
-
- if (request_firmware(&fw, fw2, &usbdev->dev)) {
- dev_err(&interface->dev,
- "unable to load firmware from file \"%s\"\n", fw2);
- goto failed2;
- }
- ret = cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
- release_firmware(fw);
- if (0 != ret) {
- dev_err(&interface->dev, "firmware download failed\n");
- goto failed2;
- }
- return 0;
-
-failed2:
- usb_put_dev(usbdev);
- dev_err(&interface->dev, "probe failed\n");
- return -ENODEV;
-}
-
-static void go7007_loader_disconnect(struct usb_interface *interface)
-{
- dev_info(&interface->dev, "disconnect\n");
- usb_put_dev(interface_to_usbdev(interface));
- usb_set_intfdata(interface, NULL);
-}
-
-static const struct usb_device_id go7007_loader_ids[] = {
- { USB_DEVICE(0x1943, 0xa250) },
- { USB_DEVICE(0x093b, 0xa002) },
- { USB_DEVICE(0x093b, 0xa004) },
- { USB_DEVICE(0x0eb1, 0x6666) },
- { USB_DEVICE(0x0eb1, 0x6668) },
- {} /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, go7007_loader_ids);
-
-static struct usb_driver go7007_loader_driver = {
- .name = "go7007-loader",
- .probe = go7007_loader_probe,
- .disconnect = go7007_loader_disconnect,
- .id_table = go7007_loader_ids,
-};
-
-module_usb_driver(go7007_loader_driver);
-
-MODULE_AUTHOR("");
-MODULE_DESCRIPTION("firmware loader for go7007-usb");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
deleted file mode 100644
index 6e16af720504..000000000000
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-/*
- * This is the private include file for the go7007 driver. It should not
- * be included by anybody but the driver itself, and especially not by
- * user-space applications.
- */
-
-#include <media/v4l2-device.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-fh.h>
-#include <media/videobuf2-core.h>
-
-struct go7007;
-
-/* IDs to activate board-specific support code */
-#define GO7007_BOARDID_MATRIX_II 0
-#define GO7007_BOARDID_MATRIX_RELOAD 1
-#define GO7007_BOARDID_STAR_TREK 2
-#define GO7007_BOARDID_PCI_VOYAGER 3
-#define GO7007_BOARDID_XMEN 4
-#define GO7007_BOARDID_XMEN_II 5
-#define GO7007_BOARDID_XMEN_III 6
-#define GO7007_BOARDID_MATRIX_REV 7
-#define GO7007_BOARDID_PX_M402U 8
-#define GO7007_BOARDID_PX_TV402U 9
-#define GO7007_BOARDID_LIFEVIEW_LR192 10 /* TV Walker Ultra */
-#define GO7007_BOARDID_ENDURA 11
-#define GO7007_BOARDID_ADLINK_MPG24 12
-#define GO7007_BOARDID_SENSORAY_2250 13 /* Sensoray 2250/2251 */
-#define GO7007_BOARDID_ADS_USBAV_709 14
-
-/* Various characteristics of each board */
-#define GO7007_BOARD_HAS_AUDIO (1<<0)
-#define GO7007_BOARD_USE_ONBOARD_I2C (1<<1)
-#define GO7007_BOARD_HAS_TUNER (1<<2)
-
-/* Characteristics of sensor devices */
-#define GO7007_SENSOR_VALID_POLAR (1<<0)
-#define GO7007_SENSOR_HREF_POLAR (1<<1)
-#define GO7007_SENSOR_VREF_POLAR (1<<2)
-#define GO7007_SENSOR_FIELD_ID_POLAR (1<<3)
-#define GO7007_SENSOR_BIT_WIDTH (1<<4)
-#define GO7007_SENSOR_VALID_ENABLE (1<<5)
-#define GO7007_SENSOR_656 (1<<6)
-#define GO7007_SENSOR_CONFIG_MASK 0x7f
-#define GO7007_SENSOR_TV (1<<7)
-#define GO7007_SENSOR_VBI (1<<8)
-#define GO7007_SENSOR_SCALING (1<<9)
-#define GO7007_SENSOR_SAA7115 (1<<10)
-
-/* Characteristics of audio sensor devices */
-#define GO7007_AUDIO_I2S_MODE_1 (1)
-#define GO7007_AUDIO_I2S_MODE_2 (2)
-#define GO7007_AUDIO_I2S_MODE_3 (3)
-#define GO7007_AUDIO_BCLK_POLAR (1<<2)
-#define GO7007_AUDIO_WORD_14 (14<<4)
-#define GO7007_AUDIO_WORD_16 (16<<4)
-#define GO7007_AUDIO_ONE_CHANNEL (1<<11)
-#define GO7007_AUDIO_I2S_MASTER (1<<16)
-#define GO7007_AUDIO_OKI_MODE (1<<17)
-
-struct go7007_board_info {
- unsigned int flags;
- int hpi_buffer_cap;
- unsigned int sensor_flags;
- int sensor_width;
- int sensor_height;
- int sensor_framerate;
- int sensor_h_offset;
- int sensor_v_offset;
- unsigned int audio_flags;
- int audio_rate;
- int audio_bclk_div;
- int audio_main_div;
- int num_i2c_devs;
- struct go_i2c {
- const char *type;
- unsigned int is_video:1;
- unsigned int is_audio:1;
- int addr;
- u32 flags;
- } i2c_devs[5];
- int num_inputs;
- struct {
- int video_input;
- int audio_index;
- char *name;
- } inputs[4];
- int video_config;
- int num_aud_inputs;
- struct {
- int audio_input;
- char *name;
- } aud_inputs[3];
-};
-
-struct go7007_hpi_ops {
- int (*interface_reset)(struct go7007 *go);
- int (*write_interrupt)(struct go7007 *go, int addr, int data);
- int (*read_interrupt)(struct go7007 *go);
- int (*stream_start)(struct go7007 *go);
- int (*stream_stop)(struct go7007 *go);
- int (*send_firmware)(struct go7007 *go, u8 *data, int len);
- int (*send_command)(struct go7007 *go, unsigned int cmd, void *arg);
- void (*release)(struct go7007 *go);
-};
-
-/* The video buffer size must be a multiple of PAGE_SIZE */
-#define GO7007_BUF_PAGES (128 * 1024 / PAGE_SIZE)
-#define GO7007_BUF_SIZE (GO7007_BUF_PAGES << PAGE_SHIFT)
-
-struct go7007_buffer {
- struct vb2_buffer vb;
- struct list_head list;
- unsigned int frame_offset;
- u32 modet_active;
-};
-
-#define GO7007_RATIO_1_1 0
-#define GO7007_RATIO_4_3 1
-#define GO7007_RATIO_16_9 2
-
-enum go7007_parser_state {
- STATE_DATA,
- STATE_00,
- STATE_00_00,
- STATE_00_00_01,
- STATE_FF,
- STATE_VBI_LEN_A,
- STATE_VBI_LEN_B,
- STATE_MODET_MAP,
- STATE_UNPARSED,
-};
-
-struct go7007 {
- struct device *dev;
- u8 bus_info[32];
- const struct go7007_board_info *board_info;
- unsigned int board_id;
- int tuner_type;
- int channel_number; /* for multi-channel boards like Adlink PCI-MPG24 */
- char name[64];
- struct video_device vdev;
- void *boot_fw;
- unsigned boot_fw_len;
- struct v4l2_device v4l2_dev;
- struct v4l2_ctrl_handler hdl;
- struct v4l2_ctrl *mpeg_video_encoding;
- struct v4l2_ctrl *mpeg_video_gop_size;
- struct v4l2_ctrl *mpeg_video_gop_closure;
- struct v4l2_ctrl *mpeg_video_bitrate;
- struct v4l2_ctrl *mpeg_video_aspect_ratio;
- struct v4l2_ctrl *mpeg_video_b_frames;
- struct v4l2_ctrl *mpeg_video_rep_seqheader;
- enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;
- spinlock_t spinlock;
- struct mutex hw_lock;
- struct mutex serialize_lock;
- int audio_enabled;
- struct v4l2_subdev *sd_video;
- struct v4l2_subdev *sd_audio;
- u8 usb_buf[16];
-
- /* Video input */
- int input;
- int aud_input;
- enum { GO7007_STD_NTSC, GO7007_STD_PAL, GO7007_STD_OTHER } standard;
- v4l2_std_id std;
- int sensor_framerate;
- int width;
- int height;
- int encoder_h_offset;
- int encoder_v_offset;
- unsigned int encoder_h_halve:1;
- unsigned int encoder_v_halve:1;
- unsigned int encoder_subsample:1;
-
- /* Encoder config */
- u32 format;
- int bitrate;
- int fps_scale;
- int pali;
- int aspect_ratio;
- int gop_size;
- unsigned int ipb:1;
- unsigned int closed_gop:1;
- unsigned int repeat_seqhead:1;
- unsigned int seq_header_enable:1;
- unsigned int gop_header_enable:1;
- unsigned int dvd_mode:1;
- unsigned int interlace_coding:1;
-
- /* Motion detection */
- unsigned int modet_enable:1;
- struct {
- unsigned int enable:1;
- int pixel_threshold;
- int motion_threshold;
- int mb_threshold;
- } modet[4];
- unsigned char modet_map[1624];
- unsigned char active_map[216];
-
- /* Video streaming */
- struct mutex queue_lock;
- struct vb2_queue vidq;
- enum go7007_parser_state state;
- int parse_length;
- u16 modet_word;
- int seen_frame;
- u32 next_seq;
- struct list_head vidq_active;
- wait_queue_head_t frame_waitq;
- struct go7007_buffer *active_buf;
-
- /* Audio streaming */
- void (*audio_deliver)(struct go7007 *go, u8 *buf, int length);
- void *snd_context;
-
- /* I2C */
- int i2c_adapter_online;
- struct i2c_adapter i2c_adapter;
-
- /* HPI driver */
- struct go7007_hpi_ops *hpi_ops;
- void *hpi_context;
- int interrupt_available;
- wait_queue_head_t interrupt_waitq;
- unsigned short interrupt_value;
- unsigned short interrupt_data;
-};
-
-static inline struct go7007 *to_go7007(struct v4l2_device *v4l2_dev)
-{
- return container_of(v4l2_dev, struct go7007, v4l2_dev);
-}
-
-/* All of these must be called with the hpi_lock mutex held! */
-#define go7007_interface_reset(go) \
- ((go)->hpi_ops->interface_reset(go))
-#define go7007_write_interrupt(go, x, y) \
- ((go)->hpi_ops->write_interrupt)((go), (x), (y))
-#define go7007_stream_start(go) \
- ((go)->hpi_ops->stream_start(go))
-#define go7007_stream_stop(go) \
- ((go)->hpi_ops->stream_stop(go))
-#define go7007_send_firmware(go, x, y) \
- ((go)->hpi_ops->send_firmware)((go), (x), (y))
-#define go7007_write_addr(go, x, y) \
- ((go)->hpi_ops->write_interrupt)((go), (x)|0x8000, (y))
-
-/* go7007-driver.c */
-int go7007_read_addr(struct go7007 *go, u16 addr, u16 *data);
-int go7007_read_interrupt(struct go7007 *go, u16 *value, u16 *data);
-int go7007_boot_encoder(struct go7007 *go, int init_i2c);
-int go7007_reset_encoder(struct go7007 *go);
-int go7007_register_encoder(struct go7007 *go, unsigned num_i2c_devs);
-int go7007_start_encoder(struct go7007 *go);
-void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length);
-struct go7007 *go7007_alloc(const struct go7007_board_info *board,
- struct device *dev);
-void go7007_update_board(struct go7007 *go);
-
-/* go7007-fw.c */
-int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen);
-
-/* go7007-i2c.c */
-int go7007_i2c_init(struct go7007 *go);
-int go7007_i2c_remove(struct go7007 *go);
-
-/* go7007-v4l2.c */
-int go7007_v4l2_init(struct go7007 *go);
-int go7007_v4l2_ctrl_init(struct go7007 *go);
-void go7007_v4l2_remove(struct go7007 *go);
-
-/* snd-go7007.c */
-int go7007_snd_init(struct go7007 *go);
-int go7007_snd_remove(struct go7007 *go);
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
deleted file mode 100644
index 2f62be905cd1..000000000000
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ /dev/null
@@ -1,1349 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/wait.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/mm.h>
-#include <linux/usb.h>
-#include <linux/i2c.h>
-#include <asm/byteorder.h>
-#include <media/saa7115.h>
-#include <media/tuner.h>
-#include <media/uda1342.h>
-
-#include "go7007-priv.h"
-
-static unsigned int assume_endura;
-module_param(assume_endura, int, 0644);
-MODULE_PARM_DESC(assume_endura,
- "when probing fails, hardware is a Pelco Endura");
-
-/* #define GO7007_I2C_DEBUG */ /* for debugging the EZ-USB I2C adapter */
-
-#define HPI_STATUS_ADDR 0xFFF4
-#define INT_PARAM_ADDR 0xFFF6
-#define INT_INDEX_ADDR 0xFFF8
-
-/*
- * Pipes on EZ-USB interface:
- * 0 snd - Control
- * 0 rcv - Control
- * 2 snd - Download firmware (control)
- * 4 rcv - Read Interrupt (interrupt)
- * 6 rcv - Read Video (bulk)
- * 8 rcv - Read Audio (bulk)
- */
-
-#define GO7007_USB_EZUSB (1<<0)
-#define GO7007_USB_EZUSB_I2C (1<<1)
-
-struct go7007_usb_board {
- unsigned int flags;
- struct go7007_board_info main_info;
-};
-
-struct go7007_usb {
- const struct go7007_usb_board *board;
- struct mutex i2c_lock;
- struct usb_device *usbdev;
- struct urb *video_urbs[8];
- struct urb *audio_urbs[8];
- struct urb *intr_urb;
-};
-
-/*********************** Product specification data ***********************/
-
-static const struct go7007_usb_board board_matrix_ii = {
- .flags = GO7007_USB_EZUSB,
- .main_info = {
- .flags = GO7007_BOARD_HAS_AUDIO |
- GO7007_BOARD_USE_ONBOARD_I2C,
- .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
- GO7007_AUDIO_WORD_16,
- .audio_rate = 48000,
- .audio_bclk_div = 8,
- .audio_main_div = 2,
- .hpi_buffer_cap = 7,
- .sensor_flags = GO7007_SENSOR_656 |
- GO7007_SENSOR_VALID_ENABLE |
- GO7007_SENSOR_TV |
- GO7007_SENSOR_SAA7115 |
- GO7007_SENSOR_VBI |
- GO7007_SENSOR_SCALING,
- .num_i2c_devs = 1,
- .i2c_devs = {
- {
- .type = "saa7115",
- .addr = 0x20,
- .is_video = 1,
- },
- },
- .num_inputs = 2,
- .inputs = {
- {
- .video_input = 0,
- .name = "Composite",
- },
- {
- .video_input = 9,
- .name = "S-Video",
- },
- },
- .video_config = SAA7115_IDQ_IS_DEFAULT,
- },
-};
-
-static const struct go7007_usb_board board_matrix_reload = {
- .flags = GO7007_USB_EZUSB,
- .main_info = {
- .flags = GO7007_BOARD_HAS_AUDIO |
- GO7007_BOARD_USE_ONBOARD_I2C,
- .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
- GO7007_AUDIO_I2S_MASTER |
- GO7007_AUDIO_WORD_16,
- .audio_rate = 48000,
- .audio_bclk_div = 8,
- .audio_main_div = 2,
- .hpi_buffer_cap = 7,
- .sensor_flags = GO7007_SENSOR_656 |
- GO7007_SENSOR_TV,
- .num_i2c_devs = 1,
- .i2c_devs = {
- {
- .type = "saa7113",
- .addr = 0x25,
- .is_video = 1,
- },
- },
- .num_inputs = 2,
- .inputs = {
- {
- .video_input = 0,
- .name = "Composite",
- },
- {
- .video_input = 9,
- .name = "S-Video",
- },
- },
- .video_config = SAA7115_IDQ_IS_DEFAULT,
- },
-};
-
-static const struct go7007_usb_board board_star_trek = {
- .flags = GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
- .main_info = {
- .flags = GO7007_BOARD_HAS_AUDIO, /* |
- GO7007_BOARD_HAS_TUNER, */
- .sensor_flags = GO7007_SENSOR_656 |
- GO7007_SENSOR_VALID_ENABLE |
- GO7007_SENSOR_TV |
- GO7007_SENSOR_SAA7115 |
- GO7007_SENSOR_VBI |
- GO7007_SENSOR_SCALING,
- .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
- GO7007_AUDIO_WORD_16,
- .audio_bclk_div = 8,
- .audio_main_div = 2,
- .hpi_buffer_cap = 7,
- .num_i2c_devs = 1,
- .i2c_devs = {
- {
- .type = "saa7115",
- .addr = 0x20,
- .is_video = 1,
- },
- },
- .num_inputs = 2,
- .inputs = {
- /* {
- * .video_input = 3,
- * .audio_index = AUDIO_TUNER,
- * .name = "Tuner",
- * },
- */
- {
- .video_input = 1,
- /* .audio_index = AUDIO_EXTERN, */
- .name = "Composite",
- },
- {
- .video_input = 8,
- /* .audio_index = AUDIO_EXTERN, */
- .name = "S-Video",
- },
- },
- .video_config = SAA7115_IDQ_IS_DEFAULT,
- },
-};
-
-static const struct go7007_usb_board board_px_tv402u = {
- .flags = GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
- .main_info = {
- .flags = GO7007_BOARD_HAS_AUDIO |
- GO7007_BOARD_HAS_TUNER,
- .sensor_flags = GO7007_SENSOR_656 |
- GO7007_SENSOR_VALID_ENABLE |
- GO7007_SENSOR_TV |
- GO7007_SENSOR_SAA7115 |
- GO7007_SENSOR_VBI |
- GO7007_SENSOR_SCALING,
- .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
- GO7007_AUDIO_WORD_16,
- .audio_bclk_div = 8,
- .audio_main_div = 2,
- .hpi_buffer_cap = 7,
- .num_i2c_devs = 5,
- .i2c_devs = {
- {
- .type = "saa7115",
- .addr = 0x20,
- .is_video = 1,
- },
- {
- .type = "uda1342",
- .addr = 0x1a,
- .is_audio = 1,
- },
- {
- .type = "tuner",
- .addr = 0x60,
- },
- {
- .type = "tuner",
- .addr = 0x43,
- },
- {
- .type = "sony-btf-mpx",
- .addr = 0x44,
- },
- },
- .num_inputs = 3,
- .inputs = {
- {
- .video_input = 3,
- .audio_index = 0,
- .name = "Tuner",
- },
- {
- .video_input = 1,
- .audio_index = 1,
- .name = "Composite",
- },
- {
- .video_input = 8,
- .audio_index = 1,
- .name = "S-Video",
- },
- },
- .video_config = SAA7115_IDQ_IS_DEFAULT,
- .num_aud_inputs = 2,
- .aud_inputs = {
- {
- .audio_input = UDA1342_IN2,
- .name = "Tuner",
- },
- {
- .audio_input = UDA1342_IN1,
- .name = "Line In",
- },
- },
- },
-};
-
-static const struct go7007_usb_board board_xmen = {
- .flags = 0,
- .main_info = {
- .flags = GO7007_BOARD_USE_ONBOARD_I2C,
- .hpi_buffer_cap = 0,
- .sensor_flags = GO7007_SENSOR_VREF_POLAR,
- .sensor_width = 320,
- .sensor_height = 240,
- .sensor_framerate = 30030,
- .audio_flags = GO7007_AUDIO_ONE_CHANNEL |
- GO7007_AUDIO_I2S_MODE_3 |
- GO7007_AUDIO_WORD_14 |
- GO7007_AUDIO_I2S_MASTER |
- GO7007_AUDIO_BCLK_POLAR |
- GO7007_AUDIO_OKI_MODE,
- .audio_rate = 8000,
- .audio_bclk_div = 48,
- .audio_main_div = 1,
- .num_i2c_devs = 1,
- .i2c_devs = {
- {
- .type = "ov7640",
- .addr = 0x21,
- },
- },
- .num_inputs = 1,
- .inputs = {
- {
- .name = "Camera",
- },
- },
- },
-};
-
-static const struct go7007_usb_board board_matrix_revolution = {
- .flags = GO7007_USB_EZUSB,
- .main_info = {
- .flags = GO7007_BOARD_HAS_AUDIO |
- GO7007_BOARD_USE_ONBOARD_I2C,
- .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
- GO7007_AUDIO_I2S_MASTER |
- GO7007_AUDIO_WORD_16,
- .audio_rate = 48000,
- .audio_bclk_div = 8,
- .audio_main_div = 2,
- .hpi_buffer_cap = 7,
- .sensor_flags = GO7007_SENSOR_656 |
- GO7007_SENSOR_TV |
- GO7007_SENSOR_VBI,
- .num_i2c_devs = 1,
- .i2c_devs = {
- {
- .type = "tw9903",
- .is_video = 1,
- .addr = 0x44,
- },
- },
- .num_inputs = 2,
- .inputs = {
- {
- .video_input = 2,
- .name = "Composite",
- },
- {
- .video_input = 8,
- .name = "S-Video",
- },
- },
- },
-};
-
-static const struct go7007_usb_board board_lifeview_lr192 = {
- .flags = GO7007_USB_EZUSB,
- .main_info = {
- .flags = GO7007_BOARD_HAS_AUDIO |
- GO7007_BOARD_USE_ONBOARD_I2C,
- .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
- GO7007_AUDIO_WORD_16,
- .audio_rate = 48000,
- .audio_bclk_div = 8,
- .audio_main_div = 2,
- .hpi_buffer_cap = 7,
- .sensor_flags = GO7007_SENSOR_656 |
- GO7007_SENSOR_VALID_ENABLE |
- GO7007_SENSOR_TV |
- GO7007_SENSOR_VBI |
- GO7007_SENSOR_SCALING,
- .num_i2c_devs = 0,
- .num_inputs = 1,
- .inputs = {
- {
- .video_input = 0,
- .name = "Composite",
- },
- },
- },
-};
-
-static const struct go7007_usb_board board_endura = {
- .flags = 0,
- .main_info = {
- .flags = 0,
- .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
- GO7007_AUDIO_I2S_MASTER |
- GO7007_AUDIO_WORD_16,
- .audio_rate = 8000,
- .audio_bclk_div = 48,
- .audio_main_div = 8,
- .hpi_buffer_cap = 0,
- .sensor_flags = GO7007_SENSOR_656 |
- GO7007_SENSOR_TV,
- .sensor_h_offset = 8,
- .num_i2c_devs = 0,
- .num_inputs = 1,
- .inputs = {
- {
- .name = "Camera",
- },
- },
- },
-};
-
-static const struct go7007_usb_board board_adlink_mpg24 = {
- .flags = 0,
- .main_info = {
- .flags = GO7007_BOARD_USE_ONBOARD_I2C,
- .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
- GO7007_AUDIO_I2S_MASTER |
- GO7007_AUDIO_WORD_16,
- .audio_rate = 48000,
- .audio_bclk_div = 8,
- .audio_main_div = 2,
- .hpi_buffer_cap = 0,
- .sensor_flags = GO7007_SENSOR_656 |
- GO7007_SENSOR_TV |
- GO7007_SENSOR_VBI,
- .num_i2c_devs = 1,
- .i2c_devs = {
- {
- .type = "tw2804",
- .addr = 0x00, /* yes, really */
- .flags = I2C_CLIENT_TEN,
- .is_video = 1,
- },
- },
- .num_inputs = 1,
- .inputs = {
- {
- .name = "Composite",
- },
- },
- },
-};
-
-static const struct go7007_usb_board board_sensoray_2250 = {
- .flags = GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
- .main_info = {
- .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
- GO7007_AUDIO_I2S_MASTER |
- GO7007_AUDIO_WORD_16,
- .flags = GO7007_BOARD_HAS_AUDIO,
- .audio_rate = 48000,
- .audio_bclk_div = 8,
- .audio_main_div = 2,
- .hpi_buffer_cap = 7,
- .sensor_flags = GO7007_SENSOR_656 |
- GO7007_SENSOR_TV,
- .num_i2c_devs = 1,
- .i2c_devs = {
- {
- .type = "s2250",
- .addr = 0x43,
- .is_video = 1,
- .is_audio = 1,
- },
- },
- .num_inputs = 2,
- .inputs = {
- {
- .video_input = 0,
- .name = "Composite",
- },
- {
- .video_input = 1,
- .name = "S-Video",
- },
- },
- .num_aud_inputs = 3,
- .aud_inputs = {
- {
- .audio_input = 0,
- .name = "Line In",
- },
- {
- .audio_input = 1,
- .name = "Mic",
- },
- {
- .audio_input = 2,
- .name = "Mic Boost",
- },
- },
- },
-};
-
-static const struct go7007_usb_board board_ads_usbav_709 = {
- .flags = GO7007_USB_EZUSB,
- .main_info = {
- .flags = GO7007_BOARD_HAS_AUDIO |
- GO7007_BOARD_USE_ONBOARD_I2C,
- .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
- GO7007_AUDIO_I2S_MASTER |
- GO7007_AUDIO_WORD_16,
- .audio_rate = 48000,
- .audio_bclk_div = 8,
- .audio_main_div = 2,
- .hpi_buffer_cap = 7,
- .sensor_flags = GO7007_SENSOR_656 |
- GO7007_SENSOR_TV |
- GO7007_SENSOR_VBI,
- .num_i2c_devs = 1,
- .i2c_devs = {
- {
- .type = "tw9906",
- .is_video = 1,
- .addr = 0x44,
- },
- },
- .num_inputs = 2,
- .inputs = {
- {
- .video_input = 0,
- .name = "Composite",
- },
- {
- .video_input = 10,
- .name = "S-Video",
- },
- },
- },
-};
-
-static const struct usb_device_id go7007_usb_id_table[] = {
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
- USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
- .idProduct = 0x7007, /* Product ID of GO7007SB chip */
- .bcdDevice_lo = 0x200, /* Revision number of XMen */
- .bcdDevice_hi = 0x200,
- .bInterfaceClass = 255,
- .bInterfaceSubClass = 0,
- .bInterfaceProtocol = 255,
- .driver_info = (kernel_ulong_t)GO7007_BOARDID_XMEN,
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
- .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
- .idProduct = 0x7007, /* Product ID of GO7007SB chip */
- .bcdDevice_lo = 0x202, /* Revision number of Matrix II */
- .bcdDevice_hi = 0x202,
- .driver_info = (kernel_ulong_t)GO7007_BOARDID_MATRIX_II,
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
- .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
- .idProduct = 0x7007, /* Product ID of GO7007SB chip */
- .bcdDevice_lo = 0x204, /* Revision number of Matrix */
- .bcdDevice_hi = 0x204, /* Reloaded */
- .driver_info = (kernel_ulong_t)GO7007_BOARDID_MATRIX_RELOAD,
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
- USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
- .idProduct = 0x7007, /* Product ID of GO7007SB chip */
- .bcdDevice_lo = 0x205, /* Revision number of XMen-II */
- .bcdDevice_hi = 0x205,
- .bInterfaceClass = 255,
- .bInterfaceSubClass = 0,
- .bInterfaceProtocol = 255,
- .driver_info = (kernel_ulong_t)GO7007_BOARDID_XMEN_II,
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
- .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
- .idProduct = 0x7007, /* Product ID of GO7007SB chip */
- .bcdDevice_lo = 0x208, /* Revision number of Star Trek */
- .bcdDevice_hi = 0x208,
- .driver_info = (kernel_ulong_t)GO7007_BOARDID_STAR_TREK,
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
- USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
- .idProduct = 0x7007, /* Product ID of GO7007SB chip */
- .bcdDevice_lo = 0x209, /* Revision number of XMen-III */
- .bcdDevice_hi = 0x209,
- .bInterfaceClass = 255,
- .bInterfaceSubClass = 0,
- .bInterfaceProtocol = 255,
- .driver_info = (kernel_ulong_t)GO7007_BOARDID_XMEN_III,
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
- .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
- .idProduct = 0x7007, /* Product ID of GO7007SB chip */
- .bcdDevice_lo = 0x210, /* Revision number of Matrix */
- .bcdDevice_hi = 0x210, /* Revolution */
- .driver_info = (kernel_ulong_t)GO7007_BOARDID_MATRIX_REV,
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
- .idVendor = 0x093b, /* Vendor ID of Plextor */
- .idProduct = 0xa102, /* Product ID of M402U */
- .bcdDevice_lo = 0x1, /* revision number of Blueberry */
- .bcdDevice_hi = 0x1,
- .driver_info = (kernel_ulong_t)GO7007_BOARDID_PX_M402U,
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
- .idVendor = 0x093b, /* Vendor ID of Plextor */
- .idProduct = 0xa104, /* Product ID of TV402U */
- .bcdDevice_lo = 0x1,
- .bcdDevice_hi = 0x1,
- .driver_info = (kernel_ulong_t)GO7007_BOARDID_PX_TV402U,
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
- .idVendor = 0x10fd, /* Vendor ID of Anubis Electronics */
- .idProduct = 0xde00, /* Product ID of Lifeview LR192 */
- .bcdDevice_lo = 0x1,
- .bcdDevice_hi = 0x1,
- .driver_info = (kernel_ulong_t)GO7007_BOARDID_LIFEVIEW_LR192,
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
- .idVendor = 0x1943, /* Vendor ID Sensoray */
- .idProduct = 0x2250, /* Product ID of 2250/2251 */
- .bcdDevice_lo = 0x1,
- .bcdDevice_hi = 0x1,
- .driver_info = (kernel_ulong_t)GO7007_BOARDID_SENSORAY_2250,
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
- .idVendor = 0x06e1, /* Vendor ID of ADS Technologies */
- .idProduct = 0x0709, /* Product ID of DVD Xpress DX2 */
- .bcdDevice_lo = 0x204,
- .bcdDevice_hi = 0x204,
- .driver_info = (kernel_ulong_t)GO7007_BOARDID_ADS_USBAV_709,
- },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, go7007_usb_id_table);
-
-/********************* Driver for EZ-USB HPI interface *********************/
-
-static int go7007_usb_vendor_request(struct go7007 *go, int request,
- int value, int index, void *transfer_buffer, int length, int in)
-{
- struct go7007_usb *usb = go->hpi_context;
- int timeout = 5000;
-
- if (in) {
- return usb_control_msg(usb->usbdev,
- usb_rcvctrlpipe(usb->usbdev, 0), request,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
- value, index, transfer_buffer, length, timeout);
- } else {
- return usb_control_msg(usb->usbdev,
- usb_sndctrlpipe(usb->usbdev, 0), request,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index, transfer_buffer, length, timeout);
- }
-}
-
-static int go7007_usb_interface_reset(struct go7007 *go)
-{
- struct go7007_usb *usb = go->hpi_context;
- u16 intr_val, intr_data;
-
- if (go->status == STATUS_SHUTDOWN)
- return -1;
- /* Reset encoder */
- if (go7007_write_interrupt(go, 0x0001, 0x0001) < 0)
- return -1;
- msleep(100);
-
- if (usb->board->flags & GO7007_USB_EZUSB) {
- /* Reset buffer in EZ-USB */
- pr_debug("resetting EZ-USB buffers\n");
- if (go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0 ||
- go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0)
- return -1;
-
- /* Reset encoder again */
- if (go7007_write_interrupt(go, 0x0001, 0x0001) < 0)
- return -1;
- msleep(100);
- }
-
- /* Wait for an interrupt to indicate successful hardware reset */
- if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
- (intr_val & ~0x1) != 0x55aa) {
- dev_err(go->dev, "unable to reset the USB interface\n");
- return -1;
- }
- return 0;
-}
-
-static int go7007_usb_ezusb_write_interrupt(struct go7007 *go,
- int addr, int data)
-{
- struct go7007_usb *usb = go->hpi_context;
- int i, r;
- u16 status_reg = 0;
- int timeout = 500;
-
- pr_debug("WriteInterrupt: %04x %04x\n", addr, data);
-
- for (i = 0; i < 100; ++i) {
- r = usb_control_msg(usb->usbdev,
- usb_rcvctrlpipe(usb->usbdev, 0), 0x14,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
- 0, HPI_STATUS_ADDR, go->usb_buf,
- sizeof(status_reg), timeout);
- if (r < 0)
- break;
- status_reg = le16_to_cpu(*((u16 *)go->usb_buf));
- if (!(status_reg & 0x0010))
- break;
- msleep(10);
- }
- if (r < 0)
- goto write_int_error;
- if (i == 100) {
- dev_err(go->dev, "device is hung, status reg = 0x%04x\n", status_reg);
- return -1;
- }
- r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0), 0x12,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE, data,
- INT_PARAM_ADDR, NULL, 0, timeout);
- if (r < 0)
- goto write_int_error;
- r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0),
- 0x12, USB_TYPE_VENDOR | USB_RECIP_DEVICE, addr,
- INT_INDEX_ADDR, NULL, 0, timeout);
- if (r < 0)
- goto write_int_error;
- return 0;
-
-write_int_error:
- dev_err(go->dev, "error in WriteInterrupt: %d\n", r);
- return r;
-}
-
-static int go7007_usb_onboard_write_interrupt(struct go7007 *go,
- int addr, int data)
-{
- struct go7007_usb *usb = go->hpi_context;
- int r;
- int timeout = 500;
-
- pr_debug("WriteInterrupt: %04x %04x\n", addr, data);
-
- go->usb_buf[0] = data & 0xff;
- go->usb_buf[1] = data >> 8;
- go->usb_buf[2] = addr & 0xff;
- go->usb_buf[3] = addr >> 8;
- go->usb_buf[4] = go->usb_buf[5] = go->usb_buf[6] = go->usb_buf[7] = 0;
- r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 2), 0x00,
- USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, 0x55aa,
- 0xf0f0, go->usb_buf, 8, timeout);
- if (r < 0) {
- dev_err(go->dev, "error in WriteInterrupt: %d\n", r);
- return r;
- }
- return 0;
-}
-
-static void go7007_usb_readinterrupt_complete(struct urb *urb)
-{
- struct go7007 *go = (struct go7007 *)urb->context;
- u16 *regs = (u16 *)urb->transfer_buffer;
- int status = urb->status;
-
- if (status) {
- if (status != -ESHUTDOWN &&
- go->status != STATUS_SHUTDOWN) {
- dev_err(go->dev, "error in read interrupt: %d\n", urb->status);
- } else {
- wake_up(&go->interrupt_waitq);
- return;
- }
- } else if (urb->actual_length != urb->transfer_buffer_length) {
- dev_err(go->dev, "short read in interrupt pipe!\n");
- } else {
- go->interrupt_available = 1;
- go->interrupt_data = __le16_to_cpu(regs[0]);
- go->interrupt_value = __le16_to_cpu(regs[1]);
- pr_debug("ReadInterrupt: %04x %04x\n",
- go->interrupt_value, go->interrupt_data);
- }
-
- wake_up(&go->interrupt_waitq);
-}
-
-static int go7007_usb_read_interrupt(struct go7007 *go)
-{
- struct go7007_usb *usb = go->hpi_context;
- int r;
-
- r = usb_submit_urb(usb->intr_urb, GFP_KERNEL);
- if (r < 0) {
- dev_err(go->dev, "unable to submit interrupt urb: %d\n", r);
- return r;
- }
- return 0;
-}
-
-static void go7007_usb_read_video_pipe_complete(struct urb *urb)
-{
- struct go7007 *go = (struct go7007 *)urb->context;
- int r, status = urb->status;
-
- if (!vb2_is_streaming(&go->vidq)) {
- wake_up_interruptible(&go->frame_waitq);
- return;
- }
- if (status) {
- dev_err(go->dev, "error in video pipe: %d\n", status);
- return;
- }
- if (urb->actual_length != urb->transfer_buffer_length) {
- dev_err(go->dev, "short read in video pipe!\n");
- return;
- }
- go7007_parse_video_stream(go, urb->transfer_buffer, urb->actual_length);
- r = usb_submit_urb(urb, GFP_ATOMIC);
- if (r < 0)
- dev_err(go->dev, "error in video pipe: %d\n", r);
-}
-
-static void go7007_usb_read_audio_pipe_complete(struct urb *urb)
-{
- struct go7007 *go = (struct go7007 *)urb->context;
- int r, status = urb->status;
-
- if (!vb2_is_streaming(&go->vidq))
- return;
- if (status) {
- dev_err(go->dev, "error in audio pipe: %d\n",
- status);
- return;
- }
- if (urb->actual_length != urb->transfer_buffer_length) {
- dev_err(go->dev, "short read in audio pipe!\n");
- return;
- }
- if (go->audio_deliver != NULL)
- go->audio_deliver(go, urb->transfer_buffer, urb->actual_length);
- r = usb_submit_urb(urb, GFP_ATOMIC);
- if (r < 0)
- dev_err(go->dev, "error in audio pipe: %d\n", r);
-}
-
-static int go7007_usb_stream_start(struct go7007 *go)
-{
- struct go7007_usb *usb = go->hpi_context;
- int i, r;
-
- for (i = 0; i < 8; ++i) {
- r = usb_submit_urb(usb->video_urbs[i], GFP_KERNEL);
- if (r < 0) {
- dev_err(go->dev, "error submitting video urb %d: %d\n", i, r);
- goto video_submit_failed;
- }
- }
- if (!go->audio_enabled)
- return 0;
-
- for (i = 0; i < 8; ++i) {
- r = usb_submit_urb(usb->audio_urbs[i], GFP_KERNEL);
- if (r < 0) {
- dev_err(go->dev, "error submitting audio urb %d: %d\n", i, r);
- goto audio_submit_failed;
- }
- }
- return 0;
-
-audio_submit_failed:
- for (i = 0; i < 7; ++i)
- usb_kill_urb(usb->audio_urbs[i]);
-video_submit_failed:
- for (i = 0; i < 8; ++i)
- usb_kill_urb(usb->video_urbs[i]);
- return -1;
-}
-
-static int go7007_usb_stream_stop(struct go7007 *go)
-{
- struct go7007_usb *usb = go->hpi_context;
- int i;
-
- if (go->status == STATUS_SHUTDOWN)
- return 0;
- for (i = 0; i < 8; ++i)
- usb_kill_urb(usb->video_urbs[i]);
- if (go->audio_enabled)
- for (i = 0; i < 8; ++i)
- usb_kill_urb(usb->audio_urbs[i]);
- return 0;
-}
-
-static int go7007_usb_send_firmware(struct go7007 *go, u8 *data, int len)
-{
- struct go7007_usb *usb = go->hpi_context;
- int transferred, pipe;
- int timeout = 500;
-
- pr_debug("DownloadBuffer sending %d bytes\n", len);
-
- if (usb->board->flags & GO7007_USB_EZUSB)
- pipe = usb_sndbulkpipe(usb->usbdev, 2);
- else
- pipe = usb_sndbulkpipe(usb->usbdev, 3);
-
- return usb_bulk_msg(usb->usbdev, pipe, data, len,
- &transferred, timeout);
-}
-
-static void go7007_usb_release(struct go7007 *go)
-{
- struct go7007_usb *usb = go->hpi_context;
- struct urb *vurb, *aurb;
- int i;
-
- if (usb->intr_urb) {
- usb_kill_urb(usb->intr_urb);
- kfree(usb->intr_urb->transfer_buffer);
- usb_free_urb(usb->intr_urb);
- }
-
- /* Free USB-related structs */
- for (i = 0; i < 8; ++i) {
- vurb = usb->video_urbs[i];
- if (vurb) {
- usb_kill_urb(vurb);
- kfree(vurb->transfer_buffer);
- usb_free_urb(vurb);
- }
- aurb = usb->audio_urbs[i];
- if (aurb) {
- usb_kill_urb(aurb);
- kfree(aurb->transfer_buffer);
- usb_free_urb(aurb);
- }
- }
-
- kfree(go->hpi_context);
-}
-
-static struct go7007_hpi_ops go7007_usb_ezusb_hpi_ops = {
- .interface_reset = go7007_usb_interface_reset,
- .write_interrupt = go7007_usb_ezusb_write_interrupt,
- .read_interrupt = go7007_usb_read_interrupt,
- .stream_start = go7007_usb_stream_start,
- .stream_stop = go7007_usb_stream_stop,
- .send_firmware = go7007_usb_send_firmware,
- .release = go7007_usb_release,
-};
-
-static struct go7007_hpi_ops go7007_usb_onboard_hpi_ops = {
- .interface_reset = go7007_usb_interface_reset,
- .write_interrupt = go7007_usb_onboard_write_interrupt,
- .read_interrupt = go7007_usb_read_interrupt,
- .stream_start = go7007_usb_stream_start,
- .stream_stop = go7007_usb_stream_stop,
- .send_firmware = go7007_usb_send_firmware,
- .release = go7007_usb_release,
-};
-
-/********************* Driver for EZ-USB I2C adapter *********************/
-
-static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
- struct i2c_msg msgs[], int num)
-{
- struct go7007 *go = i2c_get_adapdata(adapter);
- struct go7007_usb *usb = go->hpi_context;
- u8 *buf = go->usb_buf;
- int buf_len, i;
- int ret = -EIO;
-
- if (go->status == STATUS_SHUTDOWN)
- return -ENODEV;
-
- mutex_lock(&usb->i2c_lock);
-
- for (i = 0; i < num; ++i) {
- /* The hardware command is "write some bytes then read some
- * bytes", so we try to coalesce a write followed by a read
- * into a single USB transaction */
- if (i + 1 < num && msgs[i].addr == msgs[i + 1].addr &&
- !(msgs[i].flags & I2C_M_RD) &&
- (msgs[i + 1].flags & I2C_M_RD)) {
-#ifdef GO7007_I2C_DEBUG
- pr_debug("i2c write/read %d/%d bytes on %02x\n",
- msgs[i].len, msgs[i + 1].len, msgs[i].addr);
-#endif
- buf[0] = 0x01;
- buf[1] = msgs[i].len + 1;
- buf[2] = msgs[i].addr << 1;
- memcpy(&buf[3], msgs[i].buf, msgs[i].len);
- buf_len = msgs[i].len + 3;
- buf[buf_len++] = msgs[++i].len;
- } else if (msgs[i].flags & I2C_M_RD) {
-#ifdef GO7007_I2C_DEBUG
- pr_debug("i2c read %d bytes on %02x\n",
- msgs[i].len, msgs[i].addr);
-#endif
- buf[0] = 0x01;
- buf[1] = 1;
- buf[2] = msgs[i].addr << 1;
- buf[3] = msgs[i].len;
- buf_len = 4;
- } else {
-#ifdef GO7007_I2C_DEBUG
- pr_debug("i2c write %d bytes on %02x\n",
- msgs[i].len, msgs[i].addr);
-#endif
- buf[0] = 0x00;
- buf[1] = msgs[i].len + 1;
- buf[2] = msgs[i].addr << 1;
- memcpy(&buf[3], msgs[i].buf, msgs[i].len);
- buf_len = msgs[i].len + 3;
- buf[buf_len++] = 0;
- }
- if (go7007_usb_vendor_request(go, 0x24, 0, 0,
- buf, buf_len, 0) < 0)
- goto i2c_done;
- if (msgs[i].flags & I2C_M_RD) {
- memset(buf, 0, msgs[i].len + 1);
- if (go7007_usb_vendor_request(go, 0x25, 0, 0, buf,
- msgs[i].len + 1, 1) < 0)
- goto i2c_done;
- memcpy(msgs[i].buf, buf + 1, msgs[i].len);
- }
- }
- ret = num;
-
-i2c_done:
- mutex_unlock(&usb->i2c_lock);
- return ret;
-}
-
-static u32 go7007_usb_functionality(struct i2c_adapter *adapter)
-{
- /* No errors are reported by the hardware, so we don't bother
- * supporting quick writes to avoid confusing probing */
- return (I2C_FUNC_SMBUS_EMUL) & ~I2C_FUNC_SMBUS_QUICK;
-}
-
-static struct i2c_algorithm go7007_usb_algo = {
- .master_xfer = go7007_usb_i2c_master_xfer,
- .functionality = go7007_usb_functionality,
-};
-
-static struct i2c_adapter go7007_usb_adap_templ = {
- .owner = THIS_MODULE,
- .name = "WIS GO7007SB EZ-USB",
- .algo = &go7007_usb_algo,
-};
-
-/********************* USB add/remove functions *********************/
-
-static int go7007_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct go7007 *go;
- struct go7007_usb *usb;
- const struct go7007_usb_board *board;
- struct usb_device *usbdev = interface_to_usbdev(intf);
- unsigned num_i2c_devs;
- char *name;
- int video_pipe, i, v_urb_len;
-
- pr_debug("probing new GO7007 USB board\n");
-
- switch (id->driver_info) {
- case GO7007_BOARDID_MATRIX_II:
- name = "WIS Matrix II or compatible";
- board = &board_matrix_ii;
- break;
- case GO7007_BOARDID_MATRIX_RELOAD:
- name = "WIS Matrix Reloaded or compatible";
- board = &board_matrix_reload;
- break;
- case GO7007_BOARDID_MATRIX_REV:
- name = "WIS Matrix Revolution or compatible";
- board = &board_matrix_revolution;
- break;
- case GO7007_BOARDID_STAR_TREK:
- name = "WIS Star Trek or compatible";
- board = &board_star_trek;
- break;
- case GO7007_BOARDID_XMEN:
- name = "WIS XMen or compatible";
- board = &board_xmen;
- break;
- case GO7007_BOARDID_XMEN_II:
- name = "WIS XMen II or compatible";
- board = &board_xmen;
- break;
- case GO7007_BOARDID_XMEN_III:
- name = "WIS XMen III or compatible";
- board = &board_xmen;
- break;
- case GO7007_BOARDID_PX_M402U:
- name = "Plextor PX-M402U";
- board = &board_matrix_ii;
- break;
- case GO7007_BOARDID_PX_TV402U:
- name = "Plextor PX-TV402U (unknown tuner)";
- board = &board_px_tv402u;
- break;
- case GO7007_BOARDID_LIFEVIEW_LR192:
- dev_err(&intf->dev, "The Lifeview TV Walker Ultra is not supported. Sorry!\n");
- return -ENODEV;
- name = "Lifeview TV Walker Ultra";
- board = &board_lifeview_lr192;
- break;
- case GO7007_BOARDID_SENSORAY_2250:
- dev_info(&intf->dev, "Sensoray 2250 found\n");
- name = "Sensoray 2250/2251";
- board = &board_sensoray_2250;
- break;
- case GO7007_BOARDID_ADS_USBAV_709:
- name = "ADS Tech DVD Xpress DX2";
- board = &board_ads_usbav_709;
- break;
- default:
- dev_err(&intf->dev, "unknown board ID %d!\n",
- (unsigned int)id->driver_info);
- return -ENODEV;
- }
-
- go = go7007_alloc(&board->main_info, &intf->dev);
- if (go == NULL)
- return -ENOMEM;
-
- usb = kzalloc(sizeof(struct go7007_usb), GFP_KERNEL);
- if (usb == NULL) {
- kfree(go);
- return -ENOMEM;
- }
-
- usb->board = board;
- usb->usbdev = usbdev;
- usb_make_path(usbdev, go->bus_info, sizeof(go->bus_info));
- go->board_id = id->driver_info;
- strncpy(go->name, name, sizeof(go->name));
- if (board->flags & GO7007_USB_EZUSB)
- go->hpi_ops = &go7007_usb_ezusb_hpi_ops;
- else
- go->hpi_ops = &go7007_usb_onboard_hpi_ops;
- go->hpi_context = usb;
-
- /* Allocate the URB and buffer for receiving incoming interrupts */
- usb->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (usb->intr_urb == NULL)
- goto allocfail;
- usb->intr_urb->transfer_buffer = kmalloc(2*sizeof(u16), GFP_KERNEL);
- if (usb->intr_urb->transfer_buffer == NULL)
- goto allocfail;
-
- if (go->board_id == GO7007_BOARDID_SENSORAY_2250)
- usb_fill_bulk_urb(usb->intr_urb, usb->usbdev,
- usb_rcvbulkpipe(usb->usbdev, 4),
- usb->intr_urb->transfer_buffer, 2*sizeof(u16),
- go7007_usb_readinterrupt_complete, go);
- else
- usb_fill_int_urb(usb->intr_urb, usb->usbdev,
- usb_rcvintpipe(usb->usbdev, 4),
- usb->intr_urb->transfer_buffer, 2*sizeof(u16),
- go7007_usb_readinterrupt_complete, go, 8);
- usb_set_intfdata(intf, &go->v4l2_dev);
-
- /* Boot the GO7007 */
- if (go7007_boot_encoder(go, go->board_info->flags &
- GO7007_BOARD_USE_ONBOARD_I2C) < 0)
- goto allocfail;
-
- /* Register the EZ-USB I2C adapter, if we're using it */
- if (board->flags & GO7007_USB_EZUSB_I2C) {
- memcpy(&go->i2c_adapter, &go7007_usb_adap_templ,
- sizeof(go7007_usb_adap_templ));
- mutex_init(&usb->i2c_lock);
- go->i2c_adapter.dev.parent = go->dev;
- i2c_set_adapdata(&go->i2c_adapter, go);
- if (i2c_add_adapter(&go->i2c_adapter) < 0) {
- dev_err(go->dev, "error: i2c_add_adapter failed\n");
- goto allocfail;
- }
- go->i2c_adapter_online = 1;
- }
-
- /* Pelco and Adlink reused the XMen and XMen-III vendor and product
- * IDs for their own incompatible designs. We can detect XMen boards
- * by probing the sensor, but there is no way to probe the sensors on
- * the Pelco and Adlink designs so we default to the Adlink. If it
- * is actually a Pelco, the user must set the assume_endura module
- * parameter. */
- if ((go->board_id == GO7007_BOARDID_XMEN ||
- go->board_id == GO7007_BOARDID_XMEN_III) &&
- go->i2c_adapter_online) {
- union i2c_smbus_data data;
-
- /* Check to see if register 0x0A is 0x76 */
- i2c_smbus_xfer(&go->i2c_adapter, 0x21, I2C_CLIENT_SCCB,
- I2C_SMBUS_READ, 0x0A, I2C_SMBUS_BYTE_DATA, &data);
- if (data.byte != 0x76) {
- if (assume_endura) {
- go->board_id = GO7007_BOARDID_ENDURA;
- usb->board = board = &board_endura;
- go->board_info = &board->main_info;
- strncpy(go->name, "Pelco Endura",
- sizeof(go->name));
- } else {
- u16 channel;
-
- /* read channel number from GPIO[1:0] */
- go7007_read_addr(go, 0x3c81, &channel);
- channel &= 0x3;
- go->board_id = GO7007_BOARDID_ADLINK_MPG24;
- usb->board = board = &board_adlink_mpg24;
- go->board_info = &board->main_info;
- go->channel_number = channel;
- snprintf(go->name, sizeof(go->name),
- "Adlink PCI-MPG24, channel #%d",
- channel);
- }
- go7007_update_board(go);
- }
- }
-
- num_i2c_devs = go->board_info->num_i2c_devs;
-
- /* Probe the tuner model on the TV402U */
- if (go->board_id == GO7007_BOARDID_PX_TV402U) {
- /* Board strapping indicates tuner model */
- if (go7007_usb_vendor_request(go, 0x41, 0, 0, go->usb_buf, 3,
- 1) < 0) {
- dev_err(go->dev, "GPIO read failed!\n");
- goto allocfail;
- }
- switch (go->usb_buf[0] >> 6) {
- case 1:
- go->tuner_type = TUNER_SONY_BTF_PG472Z;
- go->std = V4L2_STD_PAL;
- strncpy(go->name, "Plextor PX-TV402U-EU",
- sizeof(go->name));
- break;
- case 2:
- go->tuner_type = TUNER_SONY_BTF_PK467Z;
- go->std = V4L2_STD_NTSC_M_JP;
- num_i2c_devs -= 2;
- strncpy(go->name, "Plextor PX-TV402U-JP",
- sizeof(go->name));
- break;
- case 3:
- go->tuner_type = TUNER_SONY_BTF_PB463Z;
- num_i2c_devs -= 2;
- strncpy(go->name, "Plextor PX-TV402U-NA",
- sizeof(go->name));
- break;
- default:
- pr_debug("unable to detect tuner type!\n");
- break;
- }
- /* Configure tuner mode selection inputs connected
- * to the EZ-USB GPIO output pins */
- if (go7007_usb_vendor_request(go, 0x40, 0x7f02, 0,
- NULL, 0, 0) < 0) {
- dev_err(go->dev, "GPIO write failed!\n");
- goto allocfail;
- }
- }
-
- /* Print a nasty message if the user attempts to use a USB2.0 device in
- * a USB1.1 port. There will be silent corruption of the stream. */
- if ((board->flags & GO7007_USB_EZUSB) &&
- usbdev->speed != USB_SPEED_HIGH)
- dev_err(go->dev, "*** WARNING *** This device must be connected to a USB 2.0 port! Attempting to capture video through a USB 1.1 port will result in stream corruption, even at low bitrates!\n");
-
- /* Allocate the URBs and buffers for receiving the video stream */
- if (board->flags & GO7007_USB_EZUSB) {
- v_urb_len = 1024;
- video_pipe = usb_rcvbulkpipe(usb->usbdev, 6);
- } else {
- v_urb_len = 512;
- video_pipe = usb_rcvbulkpipe(usb->usbdev, 1);
- }
- for (i = 0; i < 8; ++i) {
- usb->video_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
- if (usb->video_urbs[i] == NULL)
- goto allocfail;
- usb->video_urbs[i]->transfer_buffer =
- kmalloc(v_urb_len, GFP_KERNEL);
- if (usb->video_urbs[i]->transfer_buffer == NULL)
- goto allocfail;
- usb_fill_bulk_urb(usb->video_urbs[i], usb->usbdev, video_pipe,
- usb->video_urbs[i]->transfer_buffer, v_urb_len,
- go7007_usb_read_video_pipe_complete, go);
- }
-
- /* Allocate the URBs and buffers for receiving the audio stream */
- if ((board->flags & GO7007_USB_EZUSB) &&
- (board->flags & GO7007_BOARD_HAS_AUDIO)) {
- for (i = 0; i < 8; ++i) {
- usb->audio_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
- if (usb->audio_urbs[i] == NULL)
- goto allocfail;
- usb->audio_urbs[i]->transfer_buffer = kmalloc(4096,
- GFP_KERNEL);
- if (usb->audio_urbs[i]->transfer_buffer == NULL)
- goto allocfail;
- usb_fill_bulk_urb(usb->audio_urbs[i], usb->usbdev,
- usb_rcvbulkpipe(usb->usbdev, 8),
- usb->audio_urbs[i]->transfer_buffer, 4096,
- go7007_usb_read_audio_pipe_complete, go);
- }
- }
-
- /* Do any final GO7007 initialization, then register the
- * V4L2 and ALSA interfaces */
- if (go7007_register_encoder(go, num_i2c_devs) < 0)
- goto allocfail;
-
- go->status = STATUS_ONLINE;
- return 0;
-
-allocfail:
- go7007_usb_release(go);
- kfree(go);
- return -ENOMEM;
-}
-
-static void go7007_usb_disconnect(struct usb_interface *intf)
-{
- struct go7007 *go = to_go7007(usb_get_intfdata(intf));
-
- mutex_lock(&go->queue_lock);
- mutex_lock(&go->serialize_lock);
-
- if (go->audio_enabled)
- go7007_snd_remove(go);
-
- go->status = STATUS_SHUTDOWN;
- v4l2_device_disconnect(&go->v4l2_dev);
- video_unregister_device(&go->vdev);
- mutex_unlock(&go->serialize_lock);
- mutex_unlock(&go->queue_lock);
-
- v4l2_device_put(&go->v4l2_dev);
-}
-
-static struct usb_driver go7007_usb_driver = {
- .name = "go7007",
- .probe = go7007_usb_probe,
- .disconnect = go7007_usb_disconnect,
- .id_table = go7007_usb_id_table,
-};
-
-module_usb_driver(go7007_usb_driver);
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
deleted file mode 100644
index da7b5493e13e..000000000000
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ /dev/null
@@ -1,1055 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/unistd.h>
-#include <linux/time.h>
-#include <linux/vmalloc.h>
-#include <linux/pagemap.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-#include <linux/uaccess.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-subdev.h>
-#include <media/v4l2-event.h>
-#include <media/videobuf2-vmalloc.h>
-#include <media/saa7115.h>
-
-#include "go7007.h"
-#include "go7007-priv.h"
-
-#define call_all(dev, o, f, args...) \
- v4l2_device_call_until_err(dev, 0, o, f, ##args)
-
-static bool valid_pixelformat(u32 pixelformat)
-{
- switch (pixelformat) {
- case V4L2_PIX_FMT_MJPEG:
- case V4L2_PIX_FMT_MPEG1:
- case V4L2_PIX_FMT_MPEG2:
- case V4L2_PIX_FMT_MPEG4:
- return true;
- default:
- return false;
- }
-}
-
-static u32 get_frame_type_flag(struct go7007_buffer *vb, int format)
-{
- u8 *ptr = vb2_plane_vaddr(&vb->vb, 0);
-
- switch (format) {
- case V4L2_PIX_FMT_MJPEG:
- return V4L2_BUF_FLAG_KEYFRAME;
- case V4L2_PIX_FMT_MPEG4:
- switch ((ptr[vb->frame_offset + 4] >> 6) & 0x3) {
- case 0:
- return V4L2_BUF_FLAG_KEYFRAME;
- case 1:
- return V4L2_BUF_FLAG_PFRAME;
- case 2:
- return V4L2_BUF_FLAG_BFRAME;
- default:
- return 0;
- }
- case V4L2_PIX_FMT_MPEG1:
- case V4L2_PIX_FMT_MPEG2:
- switch ((ptr[vb->frame_offset + 5] >> 3) & 0x7) {
- case 1:
- return V4L2_BUF_FLAG_KEYFRAME;
- case 2:
- return V4L2_BUF_FLAG_PFRAME;
- case 3:
- return V4L2_BUF_FLAG_BFRAME;
- default:
- return 0;
- }
- }
-
- return 0;
-}
-
-static void get_resolution(struct go7007 *go, int *width, int *height)
-{
- switch (go->standard) {
- case GO7007_STD_NTSC:
- *width = 720;
- *height = 480;
- break;
- case GO7007_STD_PAL:
- *width = 720;
- *height = 576;
- break;
- case GO7007_STD_OTHER:
- default:
- *width = go->board_info->sensor_width;
- *height = go->board_info->sensor_height;
- break;
- }
-}
-
-static void set_formatting(struct go7007 *go)
-{
- if (go->format == V4L2_PIX_FMT_MJPEG) {
- go->pali = 0;
- go->aspect_ratio = GO7007_RATIO_1_1;
- go->gop_size = 0;
- go->ipb = 0;
- go->closed_gop = 0;
- go->repeat_seqhead = 0;
- go->seq_header_enable = 0;
- go->gop_header_enable = 0;
- go->dvd_mode = 0;
- return;
- }
-
- switch (go->format) {
- case V4L2_PIX_FMT_MPEG1:
- go->pali = 0;
- break;
- default:
- case V4L2_PIX_FMT_MPEG2:
- go->pali = 0x48;
- break;
- case V4L2_PIX_FMT_MPEG4:
- /* For future reference: this is the list of MPEG4
- * profiles that are available, although they are
- * untested:
- *
- * Profile pali
- * -------------- ----
- * PROFILE_S_L0 0x08
- * PROFILE_S_L1 0x01
- * PROFILE_S_L2 0x02
- * PROFILE_S_L3 0x03
- * PROFILE_ARTS_L1 0x91
- * PROFILE_ARTS_L2 0x92
- * PROFILE_ARTS_L3 0x93
- * PROFILE_ARTS_L4 0x94
- * PROFILE_AS_L0 0xf0
- * PROFILE_AS_L1 0xf1
- * PROFILE_AS_L2 0xf2
- * PROFILE_AS_L3 0xf3
- * PROFILE_AS_L4 0xf4
- * PROFILE_AS_L5 0xf5
- */
- go->pali = 0xf5;
- break;
- }
- go->gop_size = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_size);
- go->closed_gop = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_closure);
- go->ipb = v4l2_ctrl_g_ctrl(go->mpeg_video_b_frames) != 0;
- go->bitrate = v4l2_ctrl_g_ctrl(go->mpeg_video_bitrate);
- go->repeat_seqhead = v4l2_ctrl_g_ctrl(go->mpeg_video_rep_seqheader);
- go->gop_header_enable = 1;
- go->dvd_mode = 0;
- if (go->format == V4L2_PIX_FMT_MPEG2)
- go->dvd_mode =
- go->bitrate == 9800000 &&
- go->gop_size == 15 &&
- go->ipb == 0 &&
- go->repeat_seqhead == 1 &&
- go->closed_gop;
-
- switch (v4l2_ctrl_g_ctrl(go->mpeg_video_aspect_ratio)) {
- default:
- case V4L2_MPEG_VIDEO_ASPECT_1x1:
- go->aspect_ratio = GO7007_RATIO_1_1;
- break;
- case V4L2_MPEG_VIDEO_ASPECT_4x3:
- go->aspect_ratio = GO7007_RATIO_4_3;
- break;
- case V4L2_MPEG_VIDEO_ASPECT_16x9:
- go->aspect_ratio = GO7007_RATIO_16_9;
- break;
- }
-}
-
-static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
-{
- int sensor_height = 0, sensor_width = 0;
- int width, height, i;
-
- if (fmt != NULL && !valid_pixelformat(fmt->fmt.pix.pixelformat))
- return -EINVAL;
-
- get_resolution(go, &sensor_width, &sensor_height);
-
- if (fmt == NULL) {
- width = sensor_width;
- height = sensor_height;
- } else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
- if (fmt->fmt.pix.width > sensor_width)
- width = sensor_width;
- else if (fmt->fmt.pix.width < 144)
- width = 144;
- else
- width = fmt->fmt.pix.width & ~0x0f;
-
- if (fmt->fmt.pix.height > sensor_height)
- height = sensor_height;
- else if (fmt->fmt.pix.height < 96)
- height = 96;
- else
- height = fmt->fmt.pix.height & ~0x0f;
- } else {
- width = fmt->fmt.pix.width;
-
- if (width <= sensor_width / 4) {
- width = sensor_width / 4;
- height = sensor_height / 4;
- } else if (width <= sensor_width / 2) {
- width = sensor_width / 2;
- height = sensor_height / 2;
- } else {
- width = sensor_width;
- height = sensor_height;
- }
- width &= ~0xf;
- height &= ~0xf;
- }
-
- if (fmt != NULL) {
- u32 pixelformat = fmt->fmt.pix.pixelformat;
-
- memset(fmt, 0, sizeof(*fmt));
- fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- fmt->fmt.pix.width = width;
- fmt->fmt.pix.height = height;
- fmt->fmt.pix.pixelformat = pixelformat;
- fmt->fmt.pix.field = V4L2_FIELD_NONE;
- fmt->fmt.pix.bytesperline = 0;
- fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
- fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- }
-
- if (try)
- return 0;
-
- if (fmt)
- go->format = fmt->fmt.pix.pixelformat;
- go->width = width;
- go->height = height;
- go->encoder_h_offset = go->board_info->sensor_h_offset;
- go->encoder_v_offset = go->board_info->sensor_v_offset;
- for (i = 0; i < 4; ++i)
- go->modet[i].enable = 0;
- for (i = 0; i < 1624; ++i)
- go->modet_map[i] = 0;
-
- if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
- struct v4l2_mbus_framefmt mbus_fmt;
-
- mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
- mbus_fmt.width = fmt ? fmt->fmt.pix.width : width;
- mbus_fmt.height = height;
- go->encoder_h_halve = 0;
- go->encoder_v_halve = 0;
- go->encoder_subsample = 0;
- call_all(&go->v4l2_dev, video, s_mbus_fmt, &mbus_fmt);
- } else {
- if (width <= sensor_width / 4) {
- go->encoder_h_halve = 1;
- go->encoder_v_halve = 1;
- go->encoder_subsample = 1;
- } else if (width <= sensor_width / 2) {
- go->encoder_h_halve = 1;
- go->encoder_v_halve = 1;
- go->encoder_subsample = 0;
- } else {
- go->encoder_h_halve = 0;
- go->encoder_v_halve = 0;
- go->encoder_subsample = 0;
- }
- }
- return 0;
-}
-
-#if 0
-static int clip_to_modet_map(struct go7007 *go, int region,
- struct v4l2_clip *clip_list)
-{
- struct v4l2_clip clip, *clip_ptr;
- int x, y, mbnum;
-
- /* Check if coordinates are OK and if any macroblocks are already
- * used by other regions (besides 0) */
- clip_ptr = clip_list;
- while (clip_ptr) {
- if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
- return -EFAULT;
- if (clip.c.left < 0 || (clip.c.left & 0xF) ||
- clip.c.width <= 0 || (clip.c.width & 0xF))
- return -EINVAL;
- if (clip.c.left + clip.c.width > go->width)
- return -EINVAL;
- if (clip.c.top < 0 || (clip.c.top & 0xF) ||
- clip.c.height <= 0 || (clip.c.height & 0xF))
- return -EINVAL;
- if (clip.c.top + clip.c.height > go->height)
- return -EINVAL;
- for (y = 0; y < clip.c.height; y += 16)
- for (x = 0; x < clip.c.width; x += 16) {
- mbnum = (go->width >> 4) *
- ((clip.c.top + y) >> 4) +
- ((clip.c.left + x) >> 4);
- if (go->modet_map[mbnum] != 0 &&
- go->modet_map[mbnum] != region)
- return -EBUSY;
- }
- clip_ptr = clip.next;
- }
-
- /* Clear old region macroblocks */
- for (mbnum = 0; mbnum < 1624; ++mbnum)
- if (go->modet_map[mbnum] == region)
- go->modet_map[mbnum] = 0;
-
- /* Claim macroblocks in this list */
- clip_ptr = clip_list;
- while (clip_ptr) {
- if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
- return -EFAULT;
- for (y = 0; y < clip.c.height; y += 16)
- for (x = 0; x < clip.c.width; x += 16) {
- mbnum = (go->width >> 4) *
- ((clip.c.top + y) >> 4) +
- ((clip.c.left + x) >> 4);
- go->modet_map[mbnum] = region;
- }
- clip_ptr = clip.next;
- }
- return 0;
-}
-#endif
-
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct go7007 *go = video_drvdata(file);
-
- strlcpy(cap->driver, "go7007", sizeof(cap->driver));
- strlcpy(cap->card, go->name, sizeof(cap->card));
- strlcpy(cap->bus_info, go->bus_info, sizeof(cap->bus_info));
-
- cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING;
-
- if (go->board_info->num_aud_inputs)
- cap->device_caps |= V4L2_CAP_AUDIO;
- if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
- cap->device_caps |= V4L2_CAP_TUNER;
- cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *fmt)
-{
- char *desc = NULL;
-
- switch (fmt->index) {
- case 0:
- fmt->pixelformat = V4L2_PIX_FMT_MJPEG;
- desc = "Motion JPEG";
- break;
- case 1:
- fmt->pixelformat = V4L2_PIX_FMT_MPEG1;
- desc = "MPEG-1 ES";
- break;
- case 2:
- fmt->pixelformat = V4L2_PIX_FMT_MPEG2;
- desc = "MPEG-2 ES";
- break;
- case 3:
- fmt->pixelformat = V4L2_PIX_FMT_MPEG4;
- desc = "MPEG-4 ES";
- break;
- default:
- return -EINVAL;
- }
- fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
-
- strncpy(fmt->description, desc, sizeof(fmt->description));
-
- return 0;
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct go7007 *go = video_drvdata(file);
-
- fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- fmt->fmt.pix.width = go->width;
- fmt->fmt.pix.height = go->height;
- fmt->fmt.pix.pixelformat = go->format;
- fmt->fmt.pix.field = V4L2_FIELD_NONE;
- fmt->fmt.pix.bytesperline = 0;
- fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
- fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct go7007 *go = video_drvdata(file);
-
- return set_capture_size(go, fmt, 1);
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *fmt)
-{
- struct go7007 *go = video_drvdata(file);
-
- if (vb2_is_busy(&go->vidq))
- return -EBUSY;
-
- return set_capture_size(go, fmt, 0);
-}
-
-static int go7007_queue_setup(struct vb2_queue *q,
- const struct v4l2_format *fmt,
- unsigned int *num_buffers, unsigned int *num_planes,
- unsigned int sizes[], void *alloc_ctxs[])
-{
- sizes[0] = GO7007_BUF_SIZE;
- *num_planes = 1;
-
- if (*num_buffers < 2)
- *num_buffers = 2;
-
- return 0;
-}
-
-static void go7007_buf_queue(struct vb2_buffer *vb)
-{
- struct vb2_queue *vq = vb->vb2_queue;
- struct go7007 *go = vb2_get_drv_priv(vq);
- struct go7007_buffer *go7007_vb =
- container_of(vb, struct go7007_buffer, vb);
- unsigned long flags;
-
- spin_lock_irqsave(&go->spinlock, flags);
- list_add_tail(&go7007_vb->list, &go->vidq_active);
- spin_unlock_irqrestore(&go->spinlock, flags);
-}
-
-static int go7007_buf_prepare(struct vb2_buffer *vb)
-{
- struct go7007_buffer *go7007_vb =
- container_of(vb, struct go7007_buffer, vb);
-
- go7007_vb->modet_active = 0;
- go7007_vb->frame_offset = 0;
- vb->v4l2_planes[0].bytesused = 0;
- return 0;
-}
-
-static void go7007_buf_finish(struct vb2_buffer *vb)
-{
- struct vb2_queue *vq = vb->vb2_queue;
- struct go7007 *go = vb2_get_drv_priv(vq);
- struct go7007_buffer *go7007_vb =
- container_of(vb, struct go7007_buffer, vb);
- u32 frame_type_flag = get_frame_type_flag(go7007_vb, go->format);
- struct v4l2_buffer *buf = &vb->v4l2_buf;
-
- buf->flags &= ~(V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_BFRAME |
- V4L2_BUF_FLAG_PFRAME);
- buf->flags |= frame_type_flag;
- buf->field = V4L2_FIELD_NONE;
-}
-
-static int go7007_start_streaming(struct vb2_queue *q, unsigned int count)
-{
- struct go7007 *go = vb2_get_drv_priv(q);
- int ret;
-
- set_formatting(go);
- mutex_lock(&go->hw_lock);
- go->next_seq = 0;
- go->active_buf = NULL;
- q->streaming = 1;
- if (go7007_start_encoder(go) < 0)
- ret = -EIO;
- else
- ret = 0;
- mutex_unlock(&go->hw_lock);
- if (ret) {
- q->streaming = 0;
- return ret;
- }
- call_all(&go->v4l2_dev, video, s_stream, 1);
- v4l2_ctrl_grab(go->mpeg_video_gop_size, true);
- v4l2_ctrl_grab(go->mpeg_video_gop_closure, true);
- v4l2_ctrl_grab(go->mpeg_video_bitrate, true);
- v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, true);
- /* Turn on Capture LED */
- if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
- go7007_write_addr(go, 0x3c82, 0x0005);
- return ret;
-}
-
-static void go7007_stop_streaming(struct vb2_queue *q)
-{
- struct go7007 *go = vb2_get_drv_priv(q);
- unsigned long flags;
-
- q->streaming = 0;
- go7007_stream_stop(go);
- mutex_lock(&go->hw_lock);
- go7007_reset_encoder(go);
- mutex_unlock(&go->hw_lock);
- call_all(&go->v4l2_dev, video, s_stream, 0);
-
- spin_lock_irqsave(&go->spinlock, flags);
- INIT_LIST_HEAD(&go->vidq_active);
- spin_unlock_irqrestore(&go->spinlock, flags);
- v4l2_ctrl_grab(go->mpeg_video_gop_size, false);
- v4l2_ctrl_grab(go->mpeg_video_gop_closure, false);
- v4l2_ctrl_grab(go->mpeg_video_bitrate, false);
- v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, false);
- /* Turn on Capture LED */
- if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
- go7007_write_addr(go, 0x3c82, 0x000d);
-}
-
-static struct vb2_ops go7007_video_qops = {
- .queue_setup = go7007_queue_setup,
- .buf_queue = go7007_buf_queue,
- .buf_prepare = go7007_buf_prepare,
- .buf_finish = go7007_buf_finish,
- .start_streaming = go7007_start_streaming,
- .stop_streaming = go7007_stop_streaming,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
-};
-
-static int vidioc_g_parm(struct file *filp, void *priv,
- struct v4l2_streamparm *parm)
-{
- struct go7007 *go = video_drvdata(filp);
- struct v4l2_fract timeperframe = {
- .numerator = 1001 * go->fps_scale,
- .denominator = go->sensor_framerate,
- };
-
- if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- parm->parm.capture.readbuffers = 2;
- parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
- parm->parm.capture.timeperframe = timeperframe;
-
- return 0;
-}
-
-static int vidioc_s_parm(struct file *filp, void *priv,
- struct v4l2_streamparm *parm)
-{
- struct go7007 *go = video_drvdata(filp);
- unsigned int n, d;
-
- if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- n = go->sensor_framerate *
- parm->parm.capture.timeperframe.numerator;
- d = 1001 * parm->parm.capture.timeperframe.denominator;
- if (n != 0 && d != 0 && n > d)
- go->fps_scale = (n + d/2) / d;
- else
- go->fps_scale = 1;
-
- return vidioc_g_parm(filp, priv, parm);
-}
-
-/* VIDIOC_ENUMSTD on go7007 were used for enumerating the supported fps and
- its resolution, when the device is not connected to TV.
- This is were an API abuse, probably used by the lack of specific IOCTL's to
- enumerate it, by the time the driver was written.
-
- However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS
- and VIDIOC_ENUM_FRAMESIZES) were added for this purpose.
-
- The two functions below implement the newer ioctls
-*/
-static int vidioc_enum_framesizes(struct file *filp, void *priv,
- struct v4l2_frmsizeenum *fsize)
-{
- struct go7007 *go = video_drvdata(filp);
- int width, height;
-
- if (fsize->index > 2)
- return -EINVAL;
-
- if (!valid_pixelformat(fsize->pixel_format))
- return -EINVAL;
-
- get_resolution(go, &width, &height);
- fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
- fsize->discrete.width = (width >> fsize->index) & ~0xf;
- fsize->discrete.height = (height >> fsize->index) & ~0xf;
- return 0;
-}
-
-static int vidioc_enum_frameintervals(struct file *filp, void *priv,
- struct v4l2_frmivalenum *fival)
-{
- struct go7007 *go = video_drvdata(filp);
- int width, height;
- int i;
-
- if (fival->index > 4)
- return -EINVAL;
-
- if (!valid_pixelformat(fival->pixel_format))
- return -EINVAL;
-
- if (!(go->board_info->sensor_flags & GO7007_SENSOR_SCALING)) {
- get_resolution(go, &width, &height);
- for (i = 0; i <= 2; i++)
- if (fival->width == ((width >> i) & ~0xf) &&
- fival->height == ((height >> i) & ~0xf))
- break;
- if (i > 2)
- return -EINVAL;
- }
- fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
- fival->discrete.numerator = 1001 * (fival->index + 1);
- fival->discrete.denominator = go->sensor_framerate;
- return 0;
-}
-
-static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
-{
- struct go7007 *go = video_drvdata(file);
-
- *std = go->std;
- return 0;
-}
-
-static int go7007_s_std(struct go7007 *go)
-{
- if (go->std & V4L2_STD_625_50) {
- go->standard = GO7007_STD_PAL;
- go->sensor_framerate = 25025;
- } else {
- go->standard = GO7007_STD_NTSC;
- go->sensor_framerate = 30000;
- }
-
- call_all(&go->v4l2_dev, video, s_std, go->std);
- set_capture_size(go, NULL, 0);
- return 0;
-}
-
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)
-{
- struct go7007 *go = video_drvdata(file);
-
- if (vb2_is_busy(&go->vidq))
- return -EBUSY;
-
- go->std = std;
-
- return go7007_s_std(go);
-}
-
-static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
-{
- struct go7007 *go = video_drvdata(file);
-
- return call_all(&go->v4l2_dev, video, querystd, std);
-}
-
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *inp)
-{
- struct go7007 *go = video_drvdata(file);
-
- if (inp->index >= go->board_info->num_inputs)
- return -EINVAL;
-
- strncpy(inp->name, go->board_info->inputs[inp->index].name,
- sizeof(inp->name));
-
- /* If this board has a tuner, it will be the first input */
- if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
- inp->index == 0)
- inp->type = V4L2_INPUT_TYPE_TUNER;
- else
- inp->type = V4L2_INPUT_TYPE_CAMERA;
-
- if (go->board_info->num_aud_inputs)
- inp->audioset = (1 << go->board_info->num_aud_inputs) - 1;
- else
- inp->audioset = 0;
- inp->tuner = 0;
- if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
- inp->std = video_devdata(file)->tvnorms;
- else
- inp->std = 0;
-
- return 0;
-}
-
-
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
-{
- struct go7007 *go = video_drvdata(file);
-
- *input = go->input;
-
- return 0;
-}
-
-static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
-{
- struct go7007 *go = video_drvdata(file);
-
- if (a->index >= go->board_info->num_aud_inputs)
- return -EINVAL;
- strlcpy(a->name, go->board_info->aud_inputs[a->index].name,
- sizeof(a->name));
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
-{
- struct go7007 *go = video_drvdata(file);
-
- a->index = go->aud_input;
- strlcpy(a->name, go->board_info->aud_inputs[go->aud_input].name,
- sizeof(a->name));
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *fh,
- const struct v4l2_audio *a)
-{
- struct go7007 *go = video_drvdata(file);
-
- if (a->index >= go->board_info->num_aud_inputs)
- return -EINVAL;
- go->aud_input = a->index;
- v4l2_subdev_call(go->sd_audio, audio, s_routing,
- go->board_info->aud_inputs[go->aud_input].audio_input, 0, 0);
- return 0;
-}
-
-static void go7007_s_input(struct go7007 *go)
-{
- unsigned int input = go->input;
-
- v4l2_subdev_call(go->sd_video, video, s_routing,
- go->board_info->inputs[input].video_input, 0,
- go->board_info->video_config);
- if (go->board_info->num_aud_inputs) {
- int aud_input = go->board_info->inputs[input].audio_index;
-
- v4l2_subdev_call(go->sd_audio, audio, s_routing,
- go->board_info->aud_inputs[aud_input].audio_input, 0, 0);
- go->aud_input = aud_input;
- }
-}
-
-static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
-{
- struct go7007 *go = video_drvdata(file);
-
- if (input >= go->board_info->num_inputs)
- return -EINVAL;
- if (vb2_is_busy(&go->vidq))
- return -EBUSY;
-
- go->input = input;
- go7007_s_input(go);
-
- return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *t)
-{
- struct go7007 *go = video_drvdata(file);
-
- if (t->index != 0)
- return -EINVAL;
-
- strlcpy(t->name, "Tuner", sizeof(t->name));
- return call_all(&go->v4l2_dev, tuner, g_tuner, t);
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
- const struct v4l2_tuner *t)
-{
- struct go7007 *go = video_drvdata(file);
-
- if (t->index != 0)
- return -EINVAL;
-
- return call_all(&go->v4l2_dev, tuner, s_tuner, t);
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct go7007 *go = video_drvdata(file);
-
- if (f->tuner)
- return -EINVAL;
-
- return call_all(&go->v4l2_dev, tuner, g_frequency, f);
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
- const struct v4l2_frequency *f)
-{
- struct go7007 *go = video_drvdata(file);
-
- if (f->tuner)
- return -EINVAL;
-
- return call_all(&go->v4l2_dev, tuner, s_frequency, f);
-}
-
-static int vidioc_log_status(struct file *file, void *priv)
-{
- struct go7007 *go = video_drvdata(file);
-
- v4l2_ctrl_log_status(file, priv);
- return call_all(&go->v4l2_dev, core, log_status);
-}
-
-/* FIXME:
- Those ioctls are private, and not needed, since several standard
- extended controls already provide streaming control.
- So, those ioctls should be converted into vidioc_g_ext_ctrls()
- and vidioc_s_ext_ctrls()
- */
-
-#if 0
- case GO7007IOC_S_MD_PARAMS:
- {
- struct go7007_md_params *mdp = arg;
-
- if (mdp->region > 3)
- return -EINVAL;
- if (mdp->trigger > 0) {
- go->modet[mdp->region].pixel_threshold =
- mdp->pixel_threshold >> 1;
- go->modet[mdp->region].motion_threshold =
- mdp->motion_threshold >> 1;
- go->modet[mdp->region].mb_threshold =
- mdp->trigger >> 1;
- go->modet[mdp->region].enable = 1;
- } else
- go->modet[mdp->region].enable = 0;
- /* fall-through */
- }
- case GO7007IOC_S_MD_REGION:
- {
- struct go7007_md_region *region = arg;
-
- if (region->region < 1 || region->region > 3)
- return -EINVAL;
- return clip_to_modet_map(go, region->region, region->clips);
- }
-#endif
-
-static struct v4l2_file_operations go7007_fops = {
- .owner = THIS_MODULE,
- .open = v4l2_fh_open,
- .release = vb2_fop_release,
- .unlocked_ioctl = video_ioctl2,
- .read = vb2_fop_read,
- .mmap = vb2_fop_mmap,
- .poll = vb2_fop_poll,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = vb2_ioctl_reqbufs,
- .vidioc_querybuf = vb2_ioctl_querybuf,
- .vidioc_qbuf = vb2_ioctl_qbuf,
- .vidioc_dqbuf = vb2_ioctl_dqbuf,
- .vidioc_g_std = vidioc_g_std,
- .vidioc_s_std = vidioc_s_std,
- .vidioc_querystd = vidioc_querystd,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_enumaudio = vidioc_enumaudio,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_s_audio = vidioc_s_audio,
- .vidioc_streamon = vb2_ioctl_streamon,
- .vidioc_streamoff = vb2_ioctl_streamoff,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_g_parm = vidioc_g_parm,
- .vidioc_s_parm = vidioc_s_parm,
- .vidioc_enum_framesizes = vidioc_enum_framesizes,
- .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
- .vidioc_log_status = vidioc_log_status,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-static struct video_device go7007_template = {
- .name = "go7007",
- .fops = &go7007_fops,
- .release = video_device_release_empty,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = V4L2_STD_ALL,
-};
-
-int go7007_v4l2_ctrl_init(struct go7007 *go)
-{
- struct v4l2_ctrl_handler *hdl = &go->hdl;
- struct v4l2_ctrl *ctrl;
-
- v4l2_ctrl_handler_init(hdl, 13);
- go->mpeg_video_gop_size = v4l2_ctrl_new_std(hdl, NULL,
- V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, 34, 1, 15);
- go->mpeg_video_gop_closure = v4l2_ctrl_new_std(hdl, NULL,
- V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, 0, 1, 1, 1);
- go->mpeg_video_bitrate = v4l2_ctrl_new_std(hdl, NULL,
- V4L2_CID_MPEG_VIDEO_BITRATE,
- 64000, 10000000, 1, 9800000);
- go->mpeg_video_b_frames = v4l2_ctrl_new_std(hdl, NULL,
- V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 2, 2, 0);
- go->mpeg_video_rep_seqheader = v4l2_ctrl_new_std(hdl, NULL,
- V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, 0, 1, 1, 1);
-
- go->mpeg_video_aspect_ratio = v4l2_ctrl_new_std_menu(hdl, NULL,
- V4L2_CID_MPEG_VIDEO_ASPECT,
- V4L2_MPEG_VIDEO_ASPECT_16x9, 0,
- V4L2_MPEG_VIDEO_ASPECT_1x1);
- ctrl = v4l2_ctrl_new_std(hdl, NULL,
- V4L2_CID_JPEG_ACTIVE_MARKER, 0,
- V4L2_JPEG_ACTIVE_MARKER_DQT |
- V4L2_JPEG_ACTIVE_MARKER_DHT, 0,
- V4L2_JPEG_ACTIVE_MARKER_DQT |
- V4L2_JPEG_ACTIVE_MARKER_DHT);
- if (ctrl)
- ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
- if (hdl->error) {
- int rv = hdl->error;
-
- v4l2_err(&go->v4l2_dev, "Could not register controls\n");
- return rv;
- }
- go->v4l2_dev.ctrl_handler = hdl;
- return 0;
-}
-
-int go7007_v4l2_init(struct go7007 *go)
-{
- struct video_device *vdev = &go->vdev;
- int rv;
-
- mutex_init(&go->serialize_lock);
- mutex_init(&go->queue_lock);
-
- INIT_LIST_HEAD(&go->vidq_active);
- go->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- go->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
- go->vidq.ops = &go7007_video_qops;
- go->vidq.mem_ops = &vb2_vmalloc_memops;
- go->vidq.drv_priv = go;
- go->vidq.buf_struct_size = sizeof(struct go7007_buffer);
- go->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- go->vidq.lock = &go->queue_lock;
- rv = vb2_queue_init(&go->vidq);
- if (rv)
- return rv;
- *vdev = go7007_template;
- vdev->lock = &go->serialize_lock;
- vdev->queue = &go->vidq;
- set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
- video_set_drvdata(vdev, go);
- vdev->v4l2_dev = &go->v4l2_dev;
- if (!v4l2_device_has_op(&go->v4l2_dev, video, querystd))
- v4l2_disable_ioctl(vdev, VIDIOC_QUERYSTD);
- if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) {
- v4l2_disable_ioctl(vdev, VIDIOC_S_FREQUENCY);
- v4l2_disable_ioctl(vdev, VIDIOC_G_FREQUENCY);
- v4l2_disable_ioctl(vdev, VIDIOC_S_TUNER);
- v4l2_disable_ioctl(vdev, VIDIOC_G_TUNER);
- } else {
- struct v4l2_frequency f = {
- .type = V4L2_TUNER_ANALOG_TV,
- .frequency = 980,
- };
-
- call_all(&go->v4l2_dev, tuner, s_frequency, &f);
- }
- if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV)) {
- v4l2_disable_ioctl(vdev, VIDIOC_G_STD);
- v4l2_disable_ioctl(vdev, VIDIOC_S_STD);
- vdev->tvnorms = 0;
- }
- if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING)
- v4l2_disable_ioctl(vdev, VIDIOC_ENUM_FRAMESIZES);
- if (go->board_info->num_aud_inputs == 0) {
- v4l2_disable_ioctl(vdev, VIDIOC_G_AUDIO);
- v4l2_disable_ioctl(vdev, VIDIOC_S_AUDIO);
- v4l2_disable_ioctl(vdev, VIDIOC_ENUMAUDIO);
- }
- /* Setup correct crystal frequency on this board */
- if (go->board_info->sensor_flags & GO7007_SENSOR_SAA7115)
- v4l2_subdev_call(go->sd_video, video, s_crystal_freq,
- SAA7115_FREQ_24_576_MHZ,
- SAA7115_FREQ_FL_APLL | SAA7115_FREQ_FL_UCGC |
- SAA7115_FREQ_FL_DOUBLE_ASCLK);
- go7007_s_input(go);
- if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
- go7007_s_std(go);
- rv = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
- if (rv < 0)
- return rv;
- dev_info(go->dev, "registered device %s [v4l2]\n",
- video_device_node_name(vdev));
-
- return 0;
-}
-
-void go7007_v4l2_remove(struct go7007 *go)
-{
- v4l2_ctrl_handler_free(&go->hdl);
-}
diff --git a/drivers/staging/media/go7007/go7007.h b/drivers/staging/media/go7007/go7007.h
deleted file mode 100644
index 54b989738982..000000000000
--- a/drivers/staging/media/go7007/go7007.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and the associated README documentation file (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-struct go7007_md_params {
- __u16 region;
- __u16 trigger;
- __u16 pixel_threshold;
- __u16 motion_threshold;
- __u32 reserved[8];
-};
-
-struct go7007_md_region {
- __u16 region;
- __u16 flags;
- struct v4l2_clip *clips;
- __u32 reserved[8];
-};
-
-#define GO7007IOC_S_MD_PARAMS _IOWR('V', BASE_VIDIOC_PRIVATE + 6, \
- struct go7007_md_params)
-#define GO7007IOC_G_MD_PARAMS _IOR('V', BASE_VIDIOC_PRIVATE + 7, \
- struct go7007_md_params)
-#define GO7007IOC_S_MD_REGION _IOW('V', BASE_VIDIOC_PRIVATE + 8, \
- struct go7007_md_region)
diff --git a/drivers/staging/media/go7007/go7007.txt b/drivers/staging/media/go7007/go7007.txt
deleted file mode 100644
index c8e5eb09d385..000000000000
--- a/drivers/staging/media/go7007/go7007.txt
+++ /dev/null
@@ -1,478 +0,0 @@
-This is a driver for the WIS GO7007SB multi-format video encoder.
-
-Pete Eberlein <pete@sensoray.com>
-
-The driver was originally released under the GPL and is currently hosted at:
-http://nikosapi.org/wiki/index.php/WIS_Go7007_Linux_driver
-The go7007 firmware can be acquired from the package on the site above.
-
-I've modified the driver to support the following Video4Linux2 MPEG
-controls, with acceptable values:
-
-V4L2_CID_MPEG_STREAM_TYPE V4L2_MPEG_STREAM_TYPE_MPEG2_DVD
- V4L2_MPEG_STREAM_TYPE_MPEG_ELEM
-V4L2_CID_MPEG_VIDEO_ENCODING V4L2_MPEG_VIDEO_ENCODING_MPEG_1
- V4L2_MPEG_VIDEO_ENCODING_MPEG_2
- V4L2_MPEG_VIDEO_ENCODING_MPEG_4
-V4L2_CID_MPEG_VIDEO_ASPECT V4L2_MPEG_VIDEO_ASPECT_1x1
- V4L2_MPEG_VIDEO_ASPECT_4x3
- V4L2_MPEG_VIDEO_ASPECT_16x9
-V4L2_CID_MPEG_VIDEO_GOP_SIZE integer
-V4L2_CID_MPEG_VIDEO_BITRATE 64000 .. 10000000
-
-These should be used instead of the non-standard GO7007 ioctls described
-below.
-
-
-The README files from the orignal package appear below:
-
----------------------------------------------------------------------------
- WIS GO7007SB Public Linux Driver
----------------------------------------------------------------------------
-
-
-*** Please see the file RELEASE-NOTES for important last-minute updates ***
-
-
- 0. OVERVIEW AND LICENSING/DISCLAIMER
-
-
-This driver kit contains Linux drivers for the WIS GO7007SB multi-format
-video encoder. Only kernel version 2.6.x is supported. The video stream
-is available through the Video4Linux2 API and the audio stream is available
-through the ALSA API (or the OSS emulation layer of the ALSA system).
-
-The files in kernel/ and hotplug/ are licensed under the GNU General Public
-License Version 2 from the Free Software Foundation. A copy of the license
-is included in the file COPYING.
-
-The example applications in apps/ and C header files in include/ are
-licensed under a permissive license included in the source files which
-allows copying, modification and redistribution for any purpose without
-attribution.
-
-The firmware files included in the firmware/ directory may be freely
-redistributed only in conjunction with this document; but modification,
-tampering and reverse engineering are prohibited.
-
-MICRONAS USA, INC., MAKES NO WARRANTIES TO ANY PERSON OR ENTITY WITH
-RESPECT TO THE SOFTWARE OR ANY DERIVATIVES THEREOF OR ANY SERVICES OR
-LICENSES AND DISCLAIMS ALL IMPLIED WARRANTIES, INCLUDING WITHOUT LIMITATION
-WARRANTIES OF MERCHANTABILITY, SUPPORT, AND FITNESS FOR A PARTICULAR
-PURPOSE AND NON-INFRINGEMENT.
-
-
- 1. SYSTEM REQUIREMENTS
-
-
-This driver requires Linux kernel 2.6. Kernel 2.4 is not supported. Using
-kernel 2.6.10 or later is recommended, as earlier kernels are known to have
-unstable USB 2.0 support.
-
-A fully built kernel source tree must be available. Typically this will be
-linked from "/lib/modules/<KERNEL VERSION>/build" for convenience. If this
-link does not exist, an extra parameter will need to be passed to the
-`make` command.
-
-All vendor-built kernels should already be configured properly. However,
-for custom-built kernels, the following options need to be enabled in the
-kernel as built-in or modules:
-
- CONFIG_MODULES - Enable loadable module support
- CONFIG_FW_LOADER - Hotplug firmware loading support
- CONFIG_I2C - I2C support
- CONFIG_VIDEO_DEV - Video For Linux
- CONFIG_SOUND - Sound card support
- CONFIG_SND - Advanced Linux Sound Architecture
- CONFIG_USB - Support for Host-side USB
- CONFIG_USB_EHCI_HCD - EHCI HCD (USB 2.0) support
-
-Additionally, to use the example application, the following options need to
-be enabled in the ALSA section:
-
- CONFIG_SND_MIXER_OSS - OSS Mixer API
- CONFIG_SND_PCM_OSS - OSS PCM (digital audio) API
-
-The hotplug scripts, along with the fxload utility, must also be installed.
-These scripts can be obtained from <http://linux-hotplug.sourceforge.net/>.
-Hotplugging is used for loading firmware into the Cypruss EZ-USB chip using
-fxload and for loading firmware into the driver using the firmware agent.
-
-
- 2. COMPILING AND INSTALLING THE DRIVER
-
-
-Most users should be able to compile the driver by simply running:
-
- $ make
-
-in the top-level directory of the driver kit. First the kernel modules
-will be built, followed by the example applications.
-
-If the build system is unable to locate the kernel source tree for the
-currently-running kernel, or if the module should be built for a kernel
-other than the currently-running kernel, an additional parameter will need
-to be passed to make to specify the appropriate kernel source directory:
-
- $ make KERNELSRC=/usr/src/linux-2.6.10-custom3
-
-Once the compile completes, the driver and firmware files should be
-installed by running:
-
- $ make install
-
-The kernel modules will be placed in "/lib/modules/<KERNEL VERSION>/extra"
-and the firmware files will be placed in the appropriate hotplug firmware
-directory, usually /lib/firmware. In addition, USB maps and scripts will
-be placed in /etc/hotplug/usb to enable fxload to initialize the EZ-USB
-control chip when the device is connected.
-
-
- 3. PAL/SECAM TUNER CONFIGURATION (TV402U-EU only)
-
-
-The PAL model of the Plextor ConvertX TV402U may require additional
-configuration to correctly select the appropriate TV frequency band and
-audio subchannel.
-
-Users with a device other than the Plextor ConvertX TV402U-EU should skip
-this section.
-
-The wide variety of PAL TV systems used in Europe requires that additional
-information about the local TV standards be passed to the driver in order
-to properly tune TV channels. The two necessary parameters are (a) the PAL
-TV band, and (b) the audio subchannel format in use.
-
-In many cases, the appropriate TV band selection is passed to the driver
-from applications. However, in some cases, the application only specifies
-that the driver should use PAL but not the specific information about the
-appropriate TV band. To work around this issue, the correct TV band may be
-specified in the "force_band" parameter to the wis-sony-tuner module:
-
- TV band force_band
- ------- ----------
- PAL B/G B
- PAL I I
- PAL D/K D
- SECAM L L
-
-If the "force_band" parameter is specified, the driver will ignore any TV
-band specified by applications and will always use the band provided in the
-module parameter.
-
-The other parameter that can be specified is the audio subchannel format.
-There are several stereo audio carrier systems in use, including NICAM and
-three varieties of A2. To receive audio broadcast on one of these stereo
-carriers, the "force_mpx_mode" parameter must be specified to the
-wis-sony-tuner module.
-
- TV band Audio subcarrier force_mpx_mode
- ------- ---------------- --------------
- PAL B/G Mono (default) 1
- PAL B/G A2 2
- PAL B/G NICAM 3
- PAL I Mono (default) 4
- PAL I NICAM 5
- PAL D/K Mono (default) 6
- PAL D/K A2 (1) 7
- PAL D/K A2 (2) 8
- PAL D/K A2 (3) 9
- PAL D/K NICAM 10
- SECAM L Mono (default) 11
- SECAM L NICAM 12
-
-If the "force_mpx_mode" parameter is not specified, the correct mono-only
-mode will be chosen based on the TV band. However, the tuner will not
-receive stereo audio or bilingual broadcasts correctly.
-
-To pass the "force_band" or "force_mpx_mode" parameters to the
-wis-sony-tuner module, the following line must be added to the modprobe
-configuration file, which varies from one Linux distribution to another.
-
- options wis-sony-tuner force_band=B force_mpx_mode=2
-
-The above example would force the tuner to the PAL B/G TV band and receive
-stereo audio broadcasts on the A2 carrier.
-
-To verify that the configuration has been placed in the correct location,
-execute:
-
- $ modprobe -c | grep wis-sony-tuner
-
-If the configuration line appears, then modprobe will pass the parameters
-correctly the next time the wis-sony-tuner module is loaded into the
-kernel.
-
-
- 4. TESTING THE DRIVER
-
-
-Because few Linux applications are able to correctly capture from
-Video4Linux2 devices with only compressed formats supported, the new driver
-should be tested with the "gorecord" application in the apps/ directory.
-
-First connect a video source to the device, such as a DVD player or VCR.
-This will be captured to a file for testing the driver. If an input source
-is unavailable, a test file can still be captured, but the video will be
-black and the audio will be silent.
-
-This application will auto-detect the V4L2 and ALSA/OSS device names of the
-hardware and will record video and audio to an AVI file for a specified
-number of seconds. For example:
-
- $ apps/gorecord -duration 60 capture.avi
-
-If this application does not successfully record an AVI file, the error
-messages produced by gorecord and recorded in the system log (usually in
-/var/log/messages) should provide information to help resolve the problem.
-
-Supplying no parameters to gorecord will cause it to probe the available
-devices and exit. Use the -help flag for usage information.
-
-
- 5. USING THE DRIVER
-
-
-The V4L2 device implemented by the driver provides a standard compressed
-format API, within the following criteria:
-
- * Applications that only support the original Video4Linux1 API will not
- be able to communicate with this driver at all.
-
- * No raw video modes are supported, so applications like xawtv that
- expect only uncompressed video will not function.
-
- * Supported compression formats are: Motion-JPEG, MPEG1, MPEG2 and MPEG4.
-
- * MPEG video formats are delivered as Video Elementary Streams only.
- Program Stream (PS), Transport Stream (TS) and Packetized Elementary
- Stream (PES) formats are not supported.
-
- * Video parameters such as format and input port may not be changed while
- the encoder is active.
-
- * The audio capture device only functions when the video encoder is
- actively capturing video. Attempts to read from the audio device when
- the encoder is inactive will result in an I/O error.
-
- * The native format of the audio device is 48Khz 2-channel 16-bit
- little-endian PCM, delivered through the ALSA system. No audio
- compression is implemented in the hardware. ALSA may convert to other
- uncompressed formats on the fly.
-
-The include/ directory contains a C header file describing non-standard
-features of the GO7007SB encoder, which are described below:
-
-
- GO7007IOC_S_COMP_PARAMS, GO7007IOC_G_COMP_PARAMS
-
- These ioctls are used to negotiate general compression parameters.
-
- To query the current parameters, call the GO7007IOC_G_COMP_PARAMS ioctl
- with a pointer to a struct go7007_comp_params. If the driver is not
- set to MPEG format, the EINVAL error code will be returned.
-
- To change the current parameters, initialize all fields of a struct
- go7007_comp_params and call the GO7007_IOC_S_COMP_PARAMS ioctl with a
- pointer to this structure. The driver will return the current
- parameters with any necessary changes to conform to the limitations of
- the hardware or current compression mode. Any or all fields can be set
- to zero to request a reasonable default value. If the driver is not
- set to MPEG format, the EINVAL error code will be returned. When I/O
- is in progress, the EBUSY error code will be returned.
-
- Fields in struct go7007_comp_params:
-
- __u32 The maximum number of frames in each
- gop_size Group Of Pictures; i.e. the maximum
- number of frames minus one between
- each key frame.
-
- __u32 The maximum number of sequential
- max_b_frames bidirectionally-predicted frames.
- (B-frames are not yet supported.)
-
- enum go7007_aspect_ratio The aspect ratio to be encoded in the
- aspect_ratio meta-data of the compressed format.
-
- Choices are:
- GO7007_ASPECT_RATIO_1_1
- GO7007_ASPECT_RATIO_4_3_NTSC
- GO7007_ASPECT_RATIO_4_3_PAL
- GO7007_ASPECT_RATIO_16_9_NTSC
- GO7007_ASPECT_RATIO_16_9_PAL
-
- __u32 Bit-wise OR of control flags (below)
- flags
-
- Flags in struct go7007_comp_params:
-
- GO7007_COMP_CLOSED_GOP Only produce self-contained GOPs, used
- to produce streams appropriate for
- random seeking.
-
- GO7007_COMP_OMIT_SEQ_HEADER Omit the stream sequence header.
-
-
- GO7007IOC_S_MPEG_PARAMS, GO7007IOC_G_MPEG_PARAMS
-
- These ioctls are used to negotiate MPEG-specific stream parameters when
- the pixelformat has been set to V4L2_PIX_FMT_MPEG.
-
- To query the current parameters, call the GO7007IOC_G_MPEG_PARAMS ioctl
- with a pointer to a struct go7007_mpeg_params. If the driver is not
- set to MPEG format, the EINVAL error code will be returned.
-
- To change the current parameters, initialize all fields of a struct
- go7007_mpeg_params and call the GO7007_IOC_S_MPEG_PARAMS ioctl with a
- pointer to this structure. The driver will return the current
- parameters with any necessary changes to conform to the limitations of
- the hardware or selected MPEG mode. Any or all fields can be set to
- zero to request a reasonable default value. If the driver is not set
- to MPEG format, the EINVAL error code will be returned. When I/O is in
- progress, the EBUSY error code will be returned.
-
- Fields in struct go7007_mpeg_params:
-
- enum go7007_mpeg_video_standard
- mpeg_video_standard The MPEG video standard in which to
- compress the video.
-
- Choices are:
- GO7007_MPEG_VIDEO_MPEG1
- GO7007_MPEG_VIDEO_MPEG2
- GO7007_MPEG_VIDEO_MPEG4
-
- __u32 Bit-wise OR of control flags (below)
- flags
-
- __u32 The profile and level indication to be
- pali stored in the sequence header. This
- is only used as an indicator to the
- decoder, and does not affect the MPEG
- features used in the video stream.
- Not valid for MPEG1.
-
- Choices for MPEG2 are:
- GO7007_MPEG2_PROFILE_MAIN_MAIN
-
- Choices for MPEG4 are:
- GO7007_MPEG4_PROFILE_S_L0
- GO7007_MPEG4_PROFILE_S_L1
- GO7007_MPEG4_PROFILE_S_L2
- GO7007_MPEG4_PROFILE_S_L3
- GO7007_MPEG4_PROFILE_ARTS_L1
- GO7007_MPEG4_PROFILE_ARTS_L2
- GO7007_MPEG4_PROFILE_ARTS_L3
- GO7007_MPEG4_PROFILE_ARTS_L4
- GO7007_MPEG4_PROFILE_AS_L0
- GO7007_MPEG4_PROFILE_AS_L1
- GO7007_MPEG4_PROFILE_AS_L2
- GO7007_MPEG4_PROFILE_AS_L3
- GO7007_MPEG4_PROFILE_AS_L4
- GO7007_MPEG4_PROFILE_AS_L5
-
- Flags in struct go7007_mpeg_params:
-
- GO7007_MPEG_FORCE_DVD_MODE Force all compression parameters and
- bitrate control settings to comply
- with DVD MPEG2 stream requirements.
- This overrides most compression and
- bitrate settings!
-
- GO7007_MPEG_OMIT_GOP_HEADER Omit the GOP header.
-
- GO7007_MPEG_REPEAT_SEQHEADER Repeat the MPEG sequence header at
- the start of each GOP.
-
-
- GO7007IOC_S_BITRATE, GO7007IOC_G_BITRATE
-
- These ioctls are used to set and query the target bitrate value for the
- compressed video stream. The bitrate may be selected by storing the
- target bits per second in an int and calling GO7007IOC_S_BITRATE with a
- pointer to the int. The bitrate may be queried by calling
- GO7007IOC_G_BITRATE with a pointer to an int where the current bitrate
- will be stored.
-
- Note that this is the primary means of controlling the video quality
- for all compression modes, including V4L2_PIX_FMT_MJPEG. The
- VIDIOC_S_JPEGCOMP ioctl is not supported.
-
-
-----------------------------------------------------------------------------
- Installing the WIS PCI Voyager Driver
----------------------------------------------------------------------------
-
-The WIS PCI Voyager driver requires several patches to the Linux 2.6.11.x
-kernel source tree before compiling the driver. These patches update the
-in-kernel SAA7134 driver to the newest development version and patch bugs
-in the TDA8290/TDA8275 tuner driver.
-
-The following patches must be downloaded from Gerd Knorr's website and
-applied in the order listed:
-
- http://dl.bytesex.org/patches/2.6.11-2/i2c-tuner
- http://dl.bytesex.org/patches/2.6.11-2/i2c-tuner2
- http://dl.bytesex.org/patches/2.6.11-2/v4l2-api-mpeg
- http://dl.bytesex.org/patches/2.6.11-2/saa7134-update
-
-The following patches are included with this SDK and can be applied in any
-order:
-
- patches/2.6.11/saa7134-voyager.diff
- patches/2.6.11/tda8275-newaddr.diff
- patches/2.6.11/tda8290-ntsc.diff
-
-Check to make sure the CONFIG_VIDEO_SAA7134 option is enabled in the kernel
-configuration, and build and install the kernel.
-
-After rebooting into the new kernel, the GO7007 driver can be compiled and
-installed:
-
- $ make SAA7134_BUILD=y
- $ make install
- $ modprobe saa7134-go7007
-
-There will be two V4L video devices associated with the PCI Voyager. The
-first device (most likely /dev/video0) provides access to the raw video
-capture mode of the SAA7133 device and is used to configure the source
-video parameters and tune the TV tuner. This device can be used with xawtv
-or other V4L(2) video software as a standard uncompressed device.
-
-The second device (most likely /dev/video1) provides access to the
-compression functions of the GO7007. It can be tested using the gorecord
-application in the apps/ directory of this SDK:
-
- $ apps/gorecord -vdevice /dev/video1 -noaudio test.avi
-
-Currently the frame resolution is fixed at 720x480 (NTSC) or 720x576 (PAL),
-and the video standard must be specified to both the raw and the compressed
-video devices (xawtv and gorecord, for example).
-
-
---------------------------------------------------------------------------
-RELEASE NOTES FOR WIS GO7007SB LINUX DRIVER
----------------------------------------------------------------------------
-
-Last updated: 5 November 2005
-
- - Release 0.9.7 includes new support for using udev to run fxload. The
- install script should automatically detect whether the old hotplug
- scripts or the new udev rules should be used. To force the use of
- hotplug, run "make install USE_UDEV=n". To force the use of udev, run
- "make install USE_UDEV=y".
-
- - Motion detection is supported but undocumented. Try the `modet` app
- for a demonstration of how to use the facility.
-
- - Using USB2.0 devices such as the TV402U with USB1.1 HCDs or hubs can
- cause buffer overruns and frame drops, even at low framerates, due to
- inconsistency in the bitrate control mechanism.
-
- - On devices with an SAA7115, including the Plextor ConvertX, video height
- values of 96, 128, 160, 192, 256, 320, and 384 do not work in NTSC mode.
- All valid heights up to 512 work correctly in PAL mode.
-
- - The WIS Star Trek and PCI Voyager boards have no support yet for audio
- or the TV tuner.
diff --git a/drivers/staging/media/go7007/s2250-board.c b/drivers/staging/media/go7007/s2250-board.c
deleted file mode 100644
index eaa2b0990a1b..000000000000
--- a/drivers/staging/media/go7007/s2250-board.c
+++ /dev/null
@@ -1,631 +0,0 @@
-/*
- * Copyright (C) 2008 Sensoray Company 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/usb.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-subdev.h>
-#include "go7007-priv.h"
-
-MODULE_DESCRIPTION("Sensoray 2250/2251 i2c v4l2 subdev driver");
-MODULE_LICENSE("GPL v2");
-
-/*
- * Note: this board has two i2c devices: a vpx3226f and a tlv320aic23b.
- * Due to the unusual way these are accessed on this device we do not
- * reuse the i2c drivers, but instead they are implemented in this
- * driver. It would be nice to improve on this, though.
- */
-
-#define TLV320_ADDRESS 0x34
-#define VPX322_ADDR_ANALOGCONTROL1 0x02
-#define VPX322_ADDR_BRIGHTNESS0 0x0127
-#define VPX322_ADDR_BRIGHTNESS1 0x0131
-#define VPX322_ADDR_CONTRAST0 0x0128
-#define VPX322_ADDR_CONTRAST1 0x0132
-#define VPX322_ADDR_HUE 0x00dc
-#define VPX322_ADDR_SAT 0x0030
-
-struct go7007_usb_board {
- unsigned int flags;
- struct go7007_board_info main_info;
-};
-
-struct go7007_usb {
- struct go7007_usb_board *board;
- struct mutex i2c_lock;
- struct usb_device *usbdev;
- struct urb *video_urbs[8];
- struct urb *audio_urbs[8];
- struct urb *intr_urb;
-};
-
-static unsigned char aud_regs[] = {
- 0x1e, 0x00,
- 0x00, 0x17,
- 0x02, 0x17,
- 0x04, 0xf9,
- 0x06, 0xf9,
- 0x08, 0x02,
- 0x0a, 0x00,
- 0x0c, 0x00,
- 0x0a, 0x00,
- 0x0c, 0x00,
- 0x0e, 0x02,
- 0x10, 0x00,
- 0x12, 0x01,
- 0x00, 0x00,
-};
-
-
-static unsigned char vid_regs[] = {
- 0xF2, 0x0f,
- 0xAA, 0x00,
- 0xF8, 0xff,
- 0x00, 0x00,
-};
-
-static u16 vid_regs_fp[] = {
- 0x028, 0x067,
- 0x120, 0x016,
- 0x121, 0xcF2,
- 0x122, 0x0F2,
- 0x123, 0x00c,
- 0x124, 0x2d0,
- 0x125, 0x2e0,
- 0x126, 0x004,
- 0x128, 0x1E0,
- 0x12A, 0x016,
- 0x12B, 0x0F2,
- 0x12C, 0x0F2,
- 0x12D, 0x00c,
- 0x12E, 0x2d0,
- 0x12F, 0x2e0,
- 0x130, 0x004,
- 0x132, 0x1E0,
- 0x140, 0x060,
- 0x153, 0x00C,
- 0x154, 0x200,
- 0x150, 0x801,
- 0x000, 0x000
-};
-
-/* PAL specific values */
-static u16 vid_regs_fp_pal[] = {
- 0x120, 0x017,
- 0x121, 0xd22,
- 0x122, 0x122,
- 0x12A, 0x017,
- 0x12B, 0x122,
- 0x12C, 0x122,
- 0x140, 0x060,
- 0x000, 0x000,
-};
-
-struct s2250 {
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler hdl;
- v4l2_std_id std;
- int input;
- int brightness;
- int contrast;
- int saturation;
- int hue;
- int reg12b_val;
- int audio_input;
- struct i2c_client *audio;
-};
-
-static inline struct s2250 *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct s2250, sd);
-}
-
-/* from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/
-static int go7007_usb_vendor_request(struct go7007 *go, u16 request,
- u16 value, u16 index, void *transfer_buffer, int length, int in)
-{
- struct go7007_usb *usb = go->hpi_context;
- int timeout = 5000;
-
- if (in) {
- return usb_control_msg(usb->usbdev,
- usb_rcvctrlpipe(usb->usbdev, 0), request,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
- value, index, transfer_buffer, length, timeout);
- } else {
- return usb_control_msg(usb->usbdev,
- usb_sndctrlpipe(usb->usbdev, 0), request,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index, transfer_buffer, length, timeout);
- }
-}
-/* end from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/
-
-static int write_reg(struct i2c_client *client, u8 reg, u8 value)
-{
- struct go7007 *go = i2c_get_adapdata(client->adapter);
- struct go7007_usb *usb;
- int rc;
- int dev_addr = client->addr << 1; /* firmware wants 8-bit address */
- u8 *buf;
-
- if (go == NULL)
- return -ENODEV;
-
- if (go->status == STATUS_SHUTDOWN)
- return -EBUSY;
-
- buf = kzalloc(16, GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
-
- usb = go->hpi_context;
- if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
- dev_info(&client->dev, "i2c lock failed\n");
- kfree(buf);
- return -EINTR;
- }
- rc = go7007_usb_vendor_request(go, 0x55, dev_addr,
- (reg<<8 | value),
- buf,
- 16, 1);
-
- mutex_unlock(&usb->i2c_lock);
- kfree(buf);
- return rc;
-}
-
-static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
-{
- struct go7007 *go = i2c_get_adapdata(client->adapter);
- struct go7007_usb *usb;
- int rc;
- u8 *buf;
- struct s2250 *dec = i2c_get_clientdata(client);
-
- if (go == NULL)
- return -ENODEV;
-
- if (go->status == STATUS_SHUTDOWN)
- return -EBUSY;
-
- buf = kzalloc(16, GFP_KERNEL);
-
- if (buf == NULL)
- return -ENOMEM;
-
-
-
- memset(buf, 0xcd, 6);
-
- usb = go->hpi_context;
- if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
- dev_info(&client->dev, "i2c lock failed\n");
- kfree(buf);
- return -EINTR;
- }
- rc = go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1);
- mutex_unlock(&usb->i2c_lock);
- if (rc < 0) {
- kfree(buf);
- return rc;
- }
-
- if (buf[0] == 0) {
- unsigned int subaddr, val_read;
-
- subaddr = (buf[4] << 8) + buf[5];
- val_read = (buf[2] << 8) + buf[3];
- kfree(buf);
- if (val_read != val) {
- dev_info(&client->dev, "invalid fp write %x %x\n",
- val_read, val);
- return -EFAULT;
- }
- if (subaddr != addr) {
- dev_info(&client->dev, "invalid fp write addr %x %x\n",
- subaddr, addr);
- return -EFAULT;
- }
- } else {
- kfree(buf);
- return -EFAULT;
- }
-
- /* save last 12b value */
- if (addr == 0x12b)
- dec->reg12b_val = val;
-
- return 0;
-}
-
-static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val)
-{
- struct go7007 *go = i2c_get_adapdata(client->adapter);
- struct go7007_usb *usb;
- int rc;
- u8 *buf;
-
- if (go == NULL)
- return -ENODEV;
-
- if (go->status == STATUS_SHUTDOWN)
- return -EBUSY;
-
- buf = kzalloc(16, GFP_KERNEL);
-
- if (buf == NULL)
- return -ENOMEM;
-
-
-
- memset(buf, 0xcd, 6);
- usb = go->hpi_context;
- if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
- dev_info(&client->dev, "i2c lock failed\n");
- kfree(buf);
- return -EINTR;
- }
- rc = go7007_usb_vendor_request(go, 0x58, addr, 0, buf, 16, 1);
- mutex_unlock(&usb->i2c_lock);
- if (rc < 0) {
- kfree(buf);
- return rc;
- }
-
- *val = (buf[0] << 8) | buf[1];
- kfree(buf);
-
- return 0;
-}
-
-
-static int write_regs(struct i2c_client *client, u8 *regs)
-{
- int i;
-
- for (i = 0; !((regs[i] == 0x00) && (regs[i+1] == 0x00)); i += 2) {
- if (write_reg(client, regs[i], regs[i+1]) < 0) {
- dev_info(&client->dev, "failed\n");
- return -1;
- }
- }
- return 0;
-}
-
-static int write_regs_fp(struct i2c_client *client, u16 *regs)
-{
- int i;
-
- for (i = 0; !((regs[i] == 0x00) && (regs[i+1] == 0x00)); i += 2) {
- if (write_reg_fp(client, regs[i], regs[i+1]) < 0) {
- dev_info(&client->dev, "failed fp\n");
- return -1;
- }
- }
- return 0;
-}
-
-
-/* ------------------------------------------------------------------------- */
-
-static int s2250_s_video_routing(struct v4l2_subdev *sd, u32 input, u32 output,
- u32 config)
-{
- struct s2250 *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int vidsys;
-
- vidsys = (state->std == V4L2_STD_NTSC) ? 0x01 : 0x00;
- if (input == 0) {
- /* composite */
- write_reg_fp(client, 0x20, 0x020 | vidsys);
- write_reg_fp(client, 0x21, 0x662);
- write_reg_fp(client, 0x140, 0x060);
- } else if (input == 1) {
- /* S-Video */
- write_reg_fp(client, 0x20, 0x040 | vidsys);
- write_reg_fp(client, 0x21, 0x666);
- write_reg_fp(client, 0x140, 0x060);
- } else {
- return -EINVAL;
- }
- state->input = input;
- return 0;
-}
-
-static int s2250_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
-{
- struct s2250 *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u16 vidsource;
-
- vidsource = (state->input == 1) ? 0x040 : 0x020;
- if (norm & V4L2_STD_625_50) {
- write_regs_fp(client, vid_regs_fp);
- write_regs_fp(client, vid_regs_fp_pal);
- write_reg_fp(client, 0x20, vidsource);
- } else {
- write_regs_fp(client, vid_regs_fp);
- write_reg_fp(client, 0x20, vidsource | 1);
- }
- state->std = norm;
- return 0;
-}
-
-static int s2250_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct s2250 *state = container_of(ctrl->handler, struct s2250, hdl);
- struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
- u16 oldvalue;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
- write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
- ctrl->val | (oldvalue & ~0xff));
- read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
- write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
- ctrl->val | (oldvalue & ~0xff));
- write_reg_fp(client, 0x140, 0x60);
- break;
- case V4L2_CID_CONTRAST:
- read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
- write_reg_fp(client, VPX322_ADDR_CONTRAST0,
- ctrl->val | (oldvalue & ~0x3f));
- read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
- write_reg_fp(client, VPX322_ADDR_CONTRAST1,
- ctrl->val | (oldvalue & ~0x3f));
- write_reg_fp(client, 0x140, 0x60);
- break;
- case V4L2_CID_SATURATION:
- write_reg_fp(client, VPX322_ADDR_SAT, ctrl->val);
- break;
- case V4L2_CID_HUE:
- write_reg_fp(client, VPX322_ADDR_HUE, ctrl->val);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int s2250_s_mbus_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *fmt)
-{
- struct s2250 *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (fmt->height < 640) {
- write_reg_fp(client, 0x12b, state->reg12b_val | 0x400);
- write_reg_fp(client, 0x140, 0x060);
- } else {
- write_reg_fp(client, 0x12b, state->reg12b_val & ~0x400);
- write_reg_fp(client, 0x140, 0x060);
- }
- return 0;
-}
-
-static int s2250_s_audio_routing(struct v4l2_subdev *sd, u32 input, u32 output,
- u32 config)
-{
- struct s2250 *state = to_state(sd);
-
- switch (input) {
- case 0:
- write_reg(state->audio, 0x08, 0x02); /* Line In */
- break;
- case 1:
- write_reg(state->audio, 0x08, 0x04); /* Mic */
- break;
- case 2:
- write_reg(state->audio, 0x08, 0x05); /* Mic Boost */
- break;
- default:
- return -EINVAL;
- }
- state->audio_input = input;
- return 0;
-}
-
-
-static int s2250_log_status(struct v4l2_subdev *sd)
-{
- struct s2250 *state = to_state(sd);
-
- v4l2_info(sd, "Standard: %s\n", state->std == V4L2_STD_NTSC ? "NTSC" :
- state->std == V4L2_STD_PAL ? "PAL" :
- state->std == V4L2_STD_SECAM ? "SECAM" :
- "unknown");
- v4l2_info(sd, "Input: %s\n", state->input == 0 ? "Composite" :
- state->input == 1 ? "S-video" :
- "error");
- v4l2_info(sd, "Audio input: %s\n", state->audio_input == 0 ? "Line In" :
- state->audio_input == 1 ? "Mic" :
- state->audio_input == 2 ? "Mic Boost" :
- "error");
- return v4l2_ctrl_subdev_log_status(sd);
-}
-
-/* --------------------------------------------------------------------------*/
-
-static const struct v4l2_ctrl_ops s2250_ctrl_ops = {
- .s_ctrl = s2250_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops s2250_core_ops = {
- .log_status = s2250_log_status,
-};
-
-static const struct v4l2_subdev_audio_ops s2250_audio_ops = {
- .s_routing = s2250_s_audio_routing,
-};
-
-static const struct v4l2_subdev_video_ops s2250_video_ops = {
- .s_std = s2250_s_std,
- .s_routing = s2250_s_video_routing,
- .s_mbus_fmt = s2250_s_mbus_fmt,
-};
-
-static const struct v4l2_subdev_ops s2250_ops = {
- .core = &s2250_core_ops,
- .audio = &s2250_audio_ops,
- .video = &s2250_video_ops,
-};
-
-/* --------------------------------------------------------------------------*/
-
-static int s2250_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct i2c_client *audio;
- struct i2c_adapter *adapter = client->adapter;
- struct s2250 *state;
- struct v4l2_subdev *sd;
- u8 *data;
- struct go7007 *go = i2c_get_adapdata(adapter);
- struct go7007_usb *usb = go->hpi_context;
-
- audio = i2c_new_dummy(adapter, TLV320_ADDRESS >> 1);
- if (audio == NULL)
- return -ENOMEM;
-
- state = kzalloc(sizeof(struct s2250), GFP_KERNEL);
- if (state == NULL) {
- i2c_unregister_device(audio);
- return -ENOMEM;
- }
-
- sd = &state->sd;
- v4l2_i2c_subdev_init(sd, client, &s2250_ops);
-
- v4l2_info(sd, "initializing %s at address 0x%x on %s\n",
- "Sensoray 2250/2251", client->addr, client->adapter->name);
-
- v4l2_ctrl_handler_init(&state->hdl, 4);
- v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
- V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
- v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 0x3f, 1, 0x32);
- v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
- V4L2_CID_SATURATION, 0, 4094, 1, 2070);
- v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
- V4L2_CID_HUE, -512, 511, 1, 0);
- sd->ctrl_handler = &state->hdl;
- if (state->hdl.error) {
- int err = state->hdl.error;
-
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- return err;
- }
-
- state->std = V4L2_STD_NTSC;
- state->brightness = 50;
- state->contrast = 50;
- state->saturation = 50;
- state->hue = 0;
- state->audio = audio;
-
- /* initialize the audio */
- if (write_regs(audio, aud_regs) < 0) {
- dev_err(&client->dev, "error initializing audio\n");
- goto fail;
- }
-
- if (write_regs(client, vid_regs) < 0) {
- dev_err(&client->dev, "error initializing decoder\n");
- goto fail;
- }
- if (write_regs_fp(client, vid_regs_fp) < 0) {
- dev_err(&client->dev, "error initializing decoder\n");
- goto fail;
- }
- /* set default channel */
- /* composite */
- write_reg_fp(client, 0x20, 0x020 | 1);
- write_reg_fp(client, 0x21, 0x662);
- write_reg_fp(client, 0x140, 0x060);
-
- /* set default audio input */
- state->audio_input = 0;
- write_reg(client, 0x08, 0x02); /* Line In */
-
- if (mutex_lock_interruptible(&usb->i2c_lock) == 0) {
- data = kzalloc(16, GFP_KERNEL);
- if (data != NULL) {
- int rc;
- rc = go7007_usb_vendor_request(go, 0x41, 0, 0,
- data, 16, 1);
- if (rc > 0) {
- u8 mask;
- data[0] = 0;
- mask = 1<<5;
- data[0] &= ~mask;
- data[1] |= mask;
- go7007_usb_vendor_request(go, 0x40, 0,
- (data[1]<<8)
- + data[1],
- data, 16, 0);
- }
- kfree(data);
- }
- mutex_unlock(&usb->i2c_lock);
- }
-
- v4l2_info(sd, "initialized successfully\n");
- return 0;
-
-fail:
- i2c_unregister_device(audio);
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- return -EIO;
-}
-
-static int s2250_remove(struct i2c_client *client)
-{
- struct s2250 *state = to_state(i2c_get_clientdata(client));
-
- v4l2_device_unregister_subdev(&state->sd);
- v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- return 0;
-}
-
-static const struct i2c_device_id s2250_id[] = {
- { "s2250", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, s2250_id);
-
-static struct i2c_driver s2250_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "s2250",
- },
- .probe = s2250_probe,
- .remove = s2250_remove,
- .id_table = s2250_id,
-};
-
-module_i2c_driver(s2250_driver);
diff --git a/drivers/staging/media/go7007/saa7134-go7007.c b/drivers/staging/media/go7007/saa7134-go7007.c
deleted file mode 100644
index e40f7fbfc0a5..000000000000
--- a/drivers/staging/media/go7007/saa7134-go7007.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/wait.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/mm.h>
-#include <linux/usb.h>
-#include <linux/i2c.h>
-#include <asm/byteorder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-
-#include "saa7134.h"
-#include "saa7134-reg.h"
-#include "go7007.h"
-#include "go7007-priv.h"
-
-/*#define GO7007_HPI_DEBUG*/
-
-enum hpi_address {
- HPI_ADDR_VIDEO_BUFFER = 0xe4,
- HPI_ADDR_INIT_BUFFER = 0xea,
- HPI_ADDR_INTR_RET_VALUE = 0xee,
- HPI_ADDR_INTR_RET_DATA = 0xec,
- HPI_ADDR_INTR_STATUS = 0xf4,
- HPI_ADDR_INTR_WR_PARAM = 0xf6,
- HPI_ADDR_INTR_WR_INDEX = 0xf8,
-};
-
-enum gpio_command {
- GPIO_COMMAND_RESET = 0x00, /* 000b */
- GPIO_COMMAND_REQ1 = 0x04, /* 001b */
- GPIO_COMMAND_WRITE = 0x20, /* 010b */
- GPIO_COMMAND_REQ2 = 0x24, /* 011b */
- GPIO_COMMAND_READ = 0x80, /* 100b */
- GPIO_COMMAND_VIDEO = 0x84, /* 101b */
- GPIO_COMMAND_IDLE = 0xA0, /* 110b */
- GPIO_COMMAND_ADDR = 0xA4, /* 111b */
-};
-
-struct saa7134_go7007 {
- struct v4l2_subdev sd;
- struct saa7134_dev *dev;
- u8 *top;
- u8 *bottom;
- dma_addr_t top_dma;
- dma_addr_t bottom_dma;
-};
-
-static inline struct saa7134_go7007 *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct saa7134_go7007, sd);
-}
-
-static const struct go7007_board_info board_voyager = {
- .flags = 0,
- .sensor_flags = GO7007_SENSOR_656 |
- GO7007_SENSOR_VALID_ENABLE |
- GO7007_SENSOR_TV |
- GO7007_SENSOR_VBI,
- .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
- GO7007_AUDIO_WORD_16,
- .audio_rate = 48000,
- .audio_bclk_div = 8,
- .audio_main_div = 2,
- .hpi_buffer_cap = 7,
- .num_inputs = 1,
- .inputs = {
- {
- .name = "SAA7134",
- },
- },
-};
-
-/********************* Driver for GPIO HPI interface *********************/
-
-static int gpio_write(struct saa7134_dev *dev, u8 addr, u16 data)
-{
- saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
-
- /* Write HPI address */
- saa_writeb(SAA7134_GPIO_GPSTATUS0, addr);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-
- /* Write low byte */
- saa_writeb(SAA7134_GPIO_GPSTATUS0, data & 0xff);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-
- /* Write high byte */
- saa_writeb(SAA7134_GPIO_GPSTATUS0, data >> 8);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-
- return 0;
-}
-
-static int gpio_read(struct saa7134_dev *dev, u8 addr, u16 *data)
-{
- saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
-
- /* Write HPI address */
- saa_writeb(SAA7134_GPIO_GPSTATUS0, addr);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-
- saa_writeb(SAA7134_GPIO_GPMODE0, 0x00);
-
- /* Read low byte */
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ);
- saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- *data = saa_readb(SAA7134_GPIO_GPSTATUS0);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-
- /* Read high byte */
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ);
- saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- *data |= saa_readb(SAA7134_GPIO_GPSTATUS0) << 8;
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-
- return 0;
-}
-
-static int saa7134_go7007_interface_reset(struct go7007 *go)
-{
- struct saa7134_go7007 *saa = go->hpi_context;
- struct saa7134_dev *dev = saa->dev;
- u32 status;
- u16 intr_val, intr_data;
- int count = 20;
-
- saa_clearb(SAA7134_TS_PARALLEL, 0x80); /* Disable TS interface */
- saa_writeb(SAA7134_GPIO_GPMODE2, 0xa4);
- saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
-
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_RESET);
- msleep(1);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2);
- msleep(10);
-
- saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
-
- status = saa_readb(SAA7134_GPIO_GPSTATUS2);
- /*printk(KERN_DEBUG "status is %s\n", status & 0x40 ? "OK" : "not OK"); */
-
- /* enter command mode...(?) */
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2);
-
- do {
- saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- status = saa_readb(SAA7134_GPIO_GPSTATUS2);
- /*printk(KERN_INFO "gpio is %08x\n", saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2)); */
- } while (--count > 0);
-
- /* Wait for an interrupt to indicate successful hardware reset */
- if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
- (intr_val & ~0x1) != 0x55aa) {
- printk(KERN_ERR
- "saa7134-go7007: unable to reset the GO7007\n");
- return -1;
- }
- return 0;
-}
-
-static int saa7134_go7007_write_interrupt(struct go7007 *go, int addr, int data)
-{
- struct saa7134_go7007 *saa = go->hpi_context;
- struct saa7134_dev *dev = saa->dev;
- int i;
- u16 status_reg;
-
-#ifdef GO7007_HPI_DEBUG
- printk(KERN_DEBUG
- "saa7134-go7007: WriteInterrupt: %04x %04x\n", addr, data);
-#endif
-
- for (i = 0; i < 100; ++i) {
- gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
- if (!(status_reg & 0x0010))
- break;
- msleep(10);
- }
- if (i == 100) {
- printk(KERN_ERR
- "saa7134-go7007: device is hung, status reg = 0x%04x\n",
- status_reg);
- return -1;
- }
- gpio_write(dev, HPI_ADDR_INTR_WR_PARAM, data);
- gpio_write(dev, HPI_ADDR_INTR_WR_INDEX, addr);
-
- return 0;
-}
-
-static int saa7134_go7007_read_interrupt(struct go7007 *go)
-{
- struct saa7134_go7007 *saa = go->hpi_context;
- struct saa7134_dev *dev = saa->dev;
-
- /* XXX we need to wait if there is no interrupt available */
- go->interrupt_available = 1;
- gpio_read(dev, HPI_ADDR_INTR_RET_VALUE, &go->interrupt_value);
- gpio_read(dev, HPI_ADDR_INTR_RET_DATA, &go->interrupt_data);
-#ifdef GO7007_HPI_DEBUG
- printk(KERN_DEBUG "saa7134-go7007: ReadInterrupt: %04x %04x\n",
- go->interrupt_value, go->interrupt_data);
-#endif
- return 0;
-}
-
-static void saa7134_go7007_irq_ts_done(struct saa7134_dev *dev,
- unsigned long status)
-{
- struct go7007 *go = video_get_drvdata(dev->empress_dev);
- struct saa7134_go7007 *saa = go->hpi_context;
-
- if (!vb2_is_streaming(&go->vidq))
- return;
- if (0 != (status & 0x000f0000))
- printk(KERN_DEBUG "saa7134-go7007: irq: lost %ld\n",
- (status >> 16) & 0x0f);
- if (status & 0x100000) {
- dma_sync_single_for_cpu(&dev->pci->dev,
- saa->bottom_dma, PAGE_SIZE, DMA_FROM_DEVICE);
- go7007_parse_video_stream(go, saa->bottom, PAGE_SIZE);
- saa_writel(SAA7134_RS_BA2(5), cpu_to_le32(saa->bottom_dma));
- } else {
- dma_sync_single_for_cpu(&dev->pci->dev,
- saa->top_dma, PAGE_SIZE, DMA_FROM_DEVICE);
- go7007_parse_video_stream(go, saa->top, PAGE_SIZE);
- saa_writel(SAA7134_RS_BA1(5), cpu_to_le32(saa->top_dma));
- }
-}
-
-static int saa7134_go7007_stream_start(struct go7007 *go)
-{
- struct saa7134_go7007 *saa = go->hpi_context;
- struct saa7134_dev *dev = saa->dev;
-
- saa->top_dma = dma_map_page(&dev->pci->dev, virt_to_page(saa->top),
- 0, PAGE_SIZE, DMA_FROM_DEVICE);
- if (dma_mapping_error(&dev->pci->dev, saa->top_dma))
- return -ENOMEM;
- saa->bottom_dma = dma_map_page(&dev->pci->dev,
- virt_to_page(saa->bottom),
- 0, PAGE_SIZE, DMA_FROM_DEVICE);
- if (dma_mapping_error(&dev->pci->dev, saa->bottom_dma)) {
- dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
- DMA_FROM_DEVICE);
- return -ENOMEM;
- }
-
- saa_writel(SAA7134_VIDEO_PORT_CTRL0 >> 2, 0xA300B000);
- saa_writel(SAA7134_VIDEO_PORT_CTRL4 >> 2, 0x40000200);
-
- /* Set HPI interface for video */
- saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
- saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_VIDEO_BUFFER);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
- saa_writeb(SAA7134_GPIO_GPMODE0, 0x00);
-
- /* Enable TS interface */
- saa_writeb(SAA7134_TS_PARALLEL, 0xe6);
-
- /* Reset TS interface */
- saa_setb(SAA7134_TS_SERIAL1, 0x01);
- saa_clearb(SAA7134_TS_SERIAL1, 0x01);
-
- /* Set up transfer block size */
- saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 128 - 1);
- saa_writeb(SAA7134_TS_DMA0, (PAGE_SIZE >> 7) - 1);
- saa_writeb(SAA7134_TS_DMA1, 0);
- saa_writeb(SAA7134_TS_DMA2, 0);
-
- /* Enable video streaming mode */
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_VIDEO);
-
- saa_writel(SAA7134_RS_BA1(5), cpu_to_le32(saa->top_dma));
- saa_writel(SAA7134_RS_BA2(5), cpu_to_le32(saa->bottom_dma));
- saa_writel(SAA7134_RS_PITCH(5), 128);
- saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_MAX);
-
- /* Enable TS FIFO */
- saa_setl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5);
-
- /* Enable DMA IRQ */
- saa_setl(SAA7134_IRQ1,
- SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0);
-
- return 0;
-}
-
-static int saa7134_go7007_stream_stop(struct go7007 *go)
-{
- struct saa7134_go7007 *saa = go->hpi_context;
- struct saa7134_dev *dev;
-
- if (!saa)
- return -EINVAL;
- dev = saa->dev;
- if (!dev)
- return -EINVAL;
-
- /* Shut down TS FIFO */
- saa_clearl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5);
-
- /* Disable DMA IRQ */
- saa_clearl(SAA7134_IRQ1,
- SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0);
-
- /* Disable TS interface */
- saa_clearb(SAA7134_TS_PARALLEL, 0x80);
-
- dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
- DMA_FROM_DEVICE);
- dma_unmap_page(&dev->pci->dev, saa->bottom_dma, PAGE_SIZE,
- DMA_FROM_DEVICE);
-
- return 0;
-}
-
-static int saa7134_go7007_send_firmware(struct go7007 *go, u8 *data, int len)
-{
- struct saa7134_go7007 *saa = go->hpi_context;
- struct saa7134_dev *dev = saa->dev;
- u16 status_reg;
- int i;
-
-#ifdef GO7007_HPI_DEBUG
- printk(KERN_DEBUG "saa7134-go7007: DownloadBuffer "
- "sending %d bytes\n", len);
-#endif
-
- while (len > 0) {
- i = len > 64 ? 64 : len;
- saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
- saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_INIT_BUFFER);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
- while (i-- > 0) {
- saa_writeb(SAA7134_GPIO_GPSTATUS0, *data);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
- ++data;
- --len;
- }
- for (i = 0; i < 100; ++i) {
- gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
- if (!(status_reg & 0x0002))
- break;
- }
- if (i == 100) {
- printk(KERN_ERR "saa7134-go7007: device is hung, "
- "status reg = 0x%04x\n", status_reg);
- return -1;
- }
- }
- return 0;
-}
-
-static struct go7007_hpi_ops saa7134_go7007_hpi_ops = {
- .interface_reset = saa7134_go7007_interface_reset,
- .write_interrupt = saa7134_go7007_write_interrupt,
- .read_interrupt = saa7134_go7007_read_interrupt,
- .stream_start = saa7134_go7007_stream_start,
- .stream_stop = saa7134_go7007_stream_stop,
- .send_firmware = saa7134_go7007_send_firmware,
-};
-MODULE_FIRMWARE("go7007/go7007tv.bin");
-
-/* --------------------------------------------------------------------------*/
-
-static int saa7134_go7007_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
-{
- struct saa7134_go7007 *saa = to_state(sd);
- struct saa7134_dev *dev = saa->dev;
-
- return saa7134_s_std_internal(dev, NULL, norm);
-}
-
-static int saa7134_go7007_queryctrl(struct v4l2_subdev *sd,
- struct v4l2_queryctrl *query)
-{
- return saa7134_queryctrl(NULL, NULL, query);
-}
-static int saa7134_go7007_s_ctrl(struct v4l2_subdev *sd,
- struct v4l2_control *ctrl)
-{
- struct saa7134_go7007 *saa = to_state(sd);
- struct saa7134_dev *dev = saa->dev;
- return saa7134_s_ctrl_internal(dev, NULL, ctrl);
-}
-
-static int saa7134_go7007_g_ctrl(struct v4l2_subdev *sd,
- struct v4l2_control *ctrl)
-{
- struct saa7134_go7007 *saa = to_state(sd);
- struct saa7134_dev *dev = saa->dev;
- return saa7134_g_ctrl_internal(dev, NULL, ctrl);
-}
-
-/* --------------------------------------------------------------------------*/
-
-static const struct v4l2_subdev_core_ops saa7134_go7007_core_ops = {
- .g_ctrl = saa7134_go7007_g_ctrl,
- .s_ctrl = saa7134_go7007_s_ctrl,
- .queryctrl = saa7134_go7007_queryctrl,
-};
-
-static const struct v4l2_subdev_video_ops saa7134_go7007_video_ops = {
- .s_std = saa7134_go7007_s_std,
-};
-
-static const struct v4l2_subdev_ops saa7134_go7007_sd_ops = {
- .core = &saa7134_go7007_core_ops,
- .video = &saa7134_go7007_video_ops,
-};
-
-/* --------------------------------------------------------------------------*/
-
-
-/********************* Add/remove functions *********************/
-
-static int saa7134_go7007_init(struct saa7134_dev *dev)
-{
- struct go7007 *go;
- struct saa7134_go7007 *saa;
- struct v4l2_subdev *sd;
-
- printk(KERN_DEBUG "saa7134-go7007: probing new SAA713X board\n");
-
- go = go7007_alloc(&board_voyager, &dev->pci->dev);
- if (go == NULL)
- return -ENOMEM;
-
- saa = kzalloc(sizeof(struct saa7134_go7007), GFP_KERNEL);
- if (saa == NULL) {
- kfree(go);
- return -ENOMEM;
- }
-
- go->board_id = GO7007_BOARDID_PCI_VOYAGER;
- snprintf(go->bus_info, sizeof(go->bus_info), "PCI:%s", pci_name(dev->pci));
- strlcpy(go->name, saa7134_boards[dev->board].name, sizeof(go->name));
- go->hpi_ops = &saa7134_go7007_hpi_ops;
- go->hpi_context = saa;
- saa->dev = dev;
-
- /* Init the subdevice interface */
- sd = &saa->sd;
- v4l2_subdev_init(sd, &saa7134_go7007_sd_ops);
- v4l2_set_subdevdata(sd, saa);
- strncpy(sd->name, "saa7134-go7007", sizeof(sd->name));
-
- /* Allocate a couple pages for receiving the compressed stream */
- saa->top = (u8 *)get_zeroed_page(GFP_KERNEL);
- if (!saa->top)
- goto allocfail;
- saa->bottom = (u8 *)get_zeroed_page(GFP_KERNEL);
- if (!saa->bottom)
- goto allocfail;
-
- /* Boot the GO7007 */
- if (go7007_boot_encoder(go, go->board_info->flags &
- GO7007_BOARD_USE_ONBOARD_I2C) < 0)
- goto allocfail;
-
- /* Do any final GO7007 initialization, then register the
- * V4L2 and ALSA interfaces */
- if (go7007_register_encoder(go, go->board_info->num_i2c_devs) < 0)
- goto allocfail;
-
- /* Register the subdevice interface with the go7007 device */
- if (v4l2_device_register_subdev(&go->v4l2_dev, sd) < 0)
- printk(KERN_INFO "saa7134-go7007: register subdev failed\n");
-
- dev->empress_dev = &go->vdev;
-
- go->status = STATUS_ONLINE;
- return 0;
-
-allocfail:
- if (saa->top)
- free_page((unsigned long)saa->top);
- if (saa->bottom)
- free_page((unsigned long)saa->bottom);
- kfree(saa);
- kfree(go);
- return -ENOMEM;
-}
-
-static int saa7134_go7007_fini(struct saa7134_dev *dev)
-{
- struct go7007 *go;
- struct saa7134_go7007 *saa;
-
- if (NULL == dev->empress_dev)
- return 0;
-
- go = video_get_drvdata(dev->empress_dev);
- if (go->audio_enabled)
- go7007_snd_remove(go);
-
- saa = go->hpi_context;
- go->status = STATUS_SHUTDOWN;
- free_page((unsigned long)saa->top);
- free_page((unsigned long)saa->bottom);
- v4l2_device_unregister_subdev(&saa->sd);
- kfree(saa);
- video_unregister_device(&go->vdev);
-
- v4l2_device_put(&go->v4l2_dev);
- dev->empress_dev = NULL;
-
- return 0;
-}
-
-static struct saa7134_mpeg_ops saa7134_go7007_ops = {
- .type = SAA7134_MPEG_GO7007,
- .init = saa7134_go7007_init,
- .fini = saa7134_go7007_fini,
- .irq_ts_done = saa7134_go7007_irq_ts_done,
-};
-
-static int __init saa7134_go7007_mod_init(void)
-{
- return saa7134_ts_register(&saa7134_go7007_ops);
-}
-
-static void __exit saa7134_go7007_mod_cleanup(void)
-{
- saa7134_ts_unregister(&saa7134_go7007_ops);
-}
-
-module_init(saa7134_go7007_mod_init);
-module_exit(saa7134_go7007_mod_cleanup);
-
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/media/go7007/snd-go7007.c b/drivers/staging/media/go7007/snd-go7007.c
deleted file mode 100644
index 9eb2a20ae40a..000000000000
--- a/drivers/staging/media/go7007/snd-go7007.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/vmalloc.h>
-#include <linux/time.h>
-#include <linux/mm.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-#include <linux/uaccess.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-
-#include "go7007-priv.h"
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-module_param_array(index, int, NULL, 0444);
-module_param_array(id, charp, NULL, 0444);
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for the go7007 audio driver");
-MODULE_PARM_DESC(id, "ID string for the go7007 audio driver");
-MODULE_PARM_DESC(enable, "Enable for the go7007 audio driver");
-
-struct go7007_snd {
- struct snd_card *card;
- struct snd_pcm *pcm;
- struct snd_pcm_substream *substream;
- spinlock_t lock;
- int w_idx;
- int hw_ptr;
- int avail;
- int capturing;
-};
-
-static struct snd_pcm_hardware go7007_snd_capture_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 4096,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 32,
-};
-
-static void parse_audio_stream_data(struct go7007 *go, u8 *buf, int length)
-{
- struct go7007_snd *gosnd = go->snd_context;
- struct snd_pcm_runtime *runtime = gosnd->substream->runtime;
- int frames = bytes_to_frames(runtime, length);
-
- spin_lock(&gosnd->lock);
- gosnd->hw_ptr += frames;
- if (gosnd->hw_ptr >= runtime->buffer_size)
- gosnd->hw_ptr -= runtime->buffer_size;
- gosnd->avail += frames;
- spin_unlock(&gosnd->lock);
- if (gosnd->w_idx + length > runtime->dma_bytes) {
- int cpy = runtime->dma_bytes - gosnd->w_idx;
-
- memcpy(runtime->dma_area + gosnd->w_idx, buf, cpy);
- length -= cpy;
- buf += cpy;
- gosnd->w_idx = 0;
- }
- memcpy(runtime->dma_area + gosnd->w_idx, buf, length);
- gosnd->w_idx += length;
- spin_lock(&gosnd->lock);
- if (gosnd->avail < runtime->period_size) {
- spin_unlock(&gosnd->lock);
- return;
- }
- gosnd->avail -= runtime->period_size;
- spin_unlock(&gosnd->lock);
- if (gosnd->capturing)
- snd_pcm_period_elapsed(gosnd->substream);
-}
-
-static int go7007_snd_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct go7007 *go = snd_pcm_substream_chip(substream);
- unsigned int bytes;
-
- bytes = params_buffer_bytes(hw_params);
- if (substream->runtime->dma_bytes > 0)
- vfree(substream->runtime->dma_area);
- substream->runtime->dma_bytes = 0;
- substream->runtime->dma_area = vmalloc(bytes);
- if (substream->runtime->dma_area == NULL)
- return -ENOMEM;
- substream->runtime->dma_bytes = bytes;
- go->audio_deliver = parse_audio_stream_data;
- return 0;
-}
-
-static int go7007_snd_hw_free(struct snd_pcm_substream *substream)
-{
- struct go7007 *go = snd_pcm_substream_chip(substream);
-
- go->audio_deliver = NULL;
- if (substream->runtime->dma_bytes > 0)
- vfree(substream->runtime->dma_area);
- substream->runtime->dma_bytes = 0;
- return 0;
-}
-
-static int go7007_snd_capture_open(struct snd_pcm_substream *substream)
-{
- struct go7007 *go = snd_pcm_substream_chip(substream);
- struct go7007_snd *gosnd = go->snd_context;
- unsigned long flags;
- int r;
-
- spin_lock_irqsave(&gosnd->lock, flags);
- if (gosnd->substream == NULL) {
- gosnd->substream = substream;
- substream->runtime->hw = go7007_snd_capture_hw;
- r = 0;
- } else
- r = -EBUSY;
- spin_unlock_irqrestore(&gosnd->lock, flags);
- return r;
-}
-
-static int go7007_snd_capture_close(struct snd_pcm_substream *substream)
-{
- struct go7007 *go = snd_pcm_substream_chip(substream);
- struct go7007_snd *gosnd = go->snd_context;
-
- gosnd->substream = NULL;
- return 0;
-}
-
-static int go7007_snd_pcm_prepare(struct snd_pcm_substream *substream)
-{
- return 0;
-}
-
-static int go7007_snd_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct go7007 *go = snd_pcm_substream_chip(substream);
- struct go7007_snd *gosnd = go->snd_context;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- /* Just set a flag to indicate we should signal ALSA when
- * sound comes in */
- gosnd->capturing = 1;
- return 0;
- case SNDRV_PCM_TRIGGER_STOP:
- gosnd->hw_ptr = gosnd->w_idx = gosnd->avail = 0;
- gosnd->capturing = 0;
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-static snd_pcm_uframes_t go7007_snd_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct go7007 *go = snd_pcm_substream_chip(substream);
- struct go7007_snd *gosnd = go->snd_context;
-
- return gosnd->hw_ptr;
-}
-
-static struct page *go7007_snd_pcm_page(struct snd_pcm_substream *substream,
- unsigned long offset)
-{
- return vmalloc_to_page(substream->runtime->dma_area + offset);
-}
-
-static struct snd_pcm_ops go7007_snd_capture_ops = {
- .open = go7007_snd_capture_open,
- .close = go7007_snd_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = go7007_snd_hw_params,
- .hw_free = go7007_snd_hw_free,
- .prepare = go7007_snd_pcm_prepare,
- .trigger = go7007_snd_pcm_trigger,
- .pointer = go7007_snd_pcm_pointer,
- .page = go7007_snd_pcm_page,
-};
-
-static int go7007_snd_free(struct snd_device *device)
-{
- struct go7007 *go = device->device_data;
-
- kfree(go->snd_context);
- go->snd_context = NULL;
- return 0;
-}
-
-static struct snd_device_ops go7007_snd_device_ops = {
- .dev_free = go7007_snd_free,
-};
-
-int go7007_snd_init(struct go7007 *go)
-{
- static int dev;
- struct go7007_snd *gosnd;
- int ret = 0;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
- gosnd = kmalloc(sizeof(struct go7007_snd), GFP_KERNEL);
- if (gosnd == NULL)
- return -ENOMEM;
- spin_lock_init(&gosnd->lock);
- gosnd->hw_ptr = gosnd->w_idx = gosnd->avail = 0;
- gosnd->capturing = 0;
- ret = snd_card_new(go->dev, index[dev], id[dev], THIS_MODULE, 0,
- &gosnd->card);
- if (ret < 0) {
- kfree(gosnd);
- return ret;
- }
- ret = snd_device_new(gosnd->card, SNDRV_DEV_LOWLEVEL, go,
- &go7007_snd_device_ops);
- if (ret < 0) {
- kfree(gosnd);
- return ret;
- }
- ret = snd_pcm_new(gosnd->card, "go7007", 0, 0, 1, &gosnd->pcm);
- if (ret < 0) {
- snd_card_free(gosnd->card);
- kfree(gosnd);
- return ret;
- }
- strlcpy(gosnd->card->driver, "go7007", sizeof(gosnd->card->driver));
- strlcpy(gosnd->card->shortname, go->name, sizeof(gosnd->card->driver));
- strlcpy(gosnd->card->longname, gosnd->card->shortname,
- sizeof(gosnd->card->longname));
-
- gosnd->pcm->private_data = go;
- snd_pcm_set_ops(gosnd->pcm, SNDRV_PCM_STREAM_CAPTURE,
- &go7007_snd_capture_ops);
-
- ret = snd_card_register(gosnd->card);
- if (ret < 0) {
- snd_card_free(gosnd->card);
- kfree(gosnd);
- return ret;
- }
-
- gosnd->substream = NULL;
- go->snd_context = gosnd;
- v4l2_device_get(&go->v4l2_dev);
- ++dev;
-
- return 0;
-}
-EXPORT_SYMBOL(go7007_snd_init);
-
-int go7007_snd_remove(struct go7007 *go)
-{
- struct go7007_snd *gosnd = go->snd_context;
-
- snd_card_disconnect(gosnd->card);
- snd_card_free_when_closed(gosnd->card);
- v4l2_device_put(&go->v4l2_dev);
- return 0;
-}
-EXPORT_SYMBOL(go7007_snd_remove);
-
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/media/lirc/lirc_igorplugusb.c b/drivers/staging/media/lirc/lirc_igorplugusb.c
index 44b0d0766084..431d1e86ebf9 100644
--- a/drivers/staging/media/lirc/lirc_igorplugusb.c
+++ b/drivers/staging/media/lirc/lirc_igorplugusb.c
@@ -209,12 +209,6 @@ static int unregister_from_lirc(struct igorplug *ir)
struct lirc_driver *d;
int devnum;
- if (!ir) {
- dev_err(&ir->usbdev->dev,
- "%s: called with NULL device struct!\n", __func__);
- return -EINVAL;
- }
-
devnum = ir->devnum;
d = ir->d;
diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c
index a5b62eec5e21..96c76b33770b 100644
--- a/drivers/staging/media/lirc/lirc_imon.c
+++ b/drivers/staging/media/lirc/lirc_imon.c
@@ -189,6 +189,7 @@ MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes(default: no)");
static void free_imon_context(struct imon_context *context)
{
struct device *dev = context->driver->dev;
+
usb_free_urb(context->tx_urb);
usb_free_urb(context->rx_urb);
lirc_buffer_free(context->driver->rbuf);
@@ -481,8 +482,6 @@ static void usb_tx_callback(struct urb *urb)
/* notify waiters that write has finished */
atomic_set(&context->tx.busy, 0);
complete(&context->tx.finished);
-
- return;
}
/**
@@ -547,7 +546,6 @@ static void ir_close(void *data)
}
mutex_unlock(&context->ctx_lock);
- return;
}
/**
@@ -572,7 +570,6 @@ static void submit_data(struct imon_context *context)
lirc_buffer_write(context->driver->rbuf, buf);
wake_up(&context->driver->rbuf->wait_poll);
- return;
}
static inline int tv2int(const struct timeval *a, const struct timeval *b)
@@ -656,6 +653,7 @@ static void imon_incoming_packet(struct imon_context *context,
mask = 0x80;
for (bit = 0; bit < 8; ++bit) {
int curr_bit = !(buf[octet] & mask);
+
if (curr_bit != context->rx.prev_bit) {
if (context->rx.count) {
submit_data(context);
@@ -707,8 +705,6 @@ static void usb_rx_callback(struct urb *urb)
}
usb_submit_urb(context->rx_urb, GFP_ATOMIC);
-
- return;
}
/**
@@ -775,6 +771,7 @@ static int imon_probe(struct usb_interface *interface,
struct usb_endpoint_descriptor *ep;
int ep_dir;
int ep_type;
+
ep = &iface_desc->endpoint[i].desc;
ep_dir = ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK;
ep_type = ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
diff --git a/drivers/staging/media/lirc/lirc_parallel.c b/drivers/staging/media/lirc/lirc_parallel.c
index 1394f020e46b..672858a089f3 100644
--- a/drivers/staging/media/lirc/lirc_parallel.c
+++ b/drivers/staging/media/lirc/lirc_parallel.c
@@ -169,23 +169,22 @@ static unsigned int init_lirc_timer(void)
newtimer = (1000000*count)/timeelapsed;
pr_info("%u Hz timer detected\n", newtimer);
return newtimer;
- } else {
- newtimer = (1000000*count)/timeelapsed;
- if (abs(newtimer - default_timer) > default_timer/10) {
- /* bad timer */
- pr_notice("bad timer: %u Hz\n", newtimer);
- pr_notice("using default timer: %u Hz\n",
- default_timer);
- return default_timer;
- } else {
- pr_info("%u Hz timer detected\n", newtimer);
- return newtimer; /* use detected value */
- }
}
- } else {
- pr_notice("no timer detected\n");
- return 0;
+ newtimer = (1000000*count)/timeelapsed;
+ if (abs(newtimer - default_timer) > default_timer/10) {
+ /* bad timer */
+ pr_notice("bad timer: %u Hz\n", newtimer);
+ pr_notice("using default timer: %u Hz\n",
+ default_timer);
+ return default_timer;
+ } else {
+ pr_info("%u Hz timer detected\n", newtimer);
+ return newtimer; /* use detected value */
+ }
}
+
+ pr_notice("no timer detected\n");
+ return 0;
}
static int lirc_claim(void)
@@ -661,7 +660,8 @@ static int __init lirc_parallel_init(void)
goto exit_device_put;
}
ppdevice = parport_register_device(pport, LIRC_DRIVER_NAME,
- pf, kf, lirc_lirc_irq_handler, 0, NULL);
+ pf, kf, lirc_lirc_irq_handler, 0,
+ NULL);
parport_put_port(pport);
if (ppdevice == NULL) {
pr_notice("parport_register_device() failed\n");
diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
index efe561cd0935..bae0d467093e 100644
--- a/drivers/staging/media/lirc/lirc_serial.c
+++ b/drivers/staging/media/lirc/lirc_serial.c
@@ -782,7 +782,7 @@ static int lirc_serial_probe(struct platform_device *dev)
{
int i, nlow, nhigh, result;
- result = request_irq(irq, lirc_irq_handler,
+ result = devm_request_irq(&dev->dev, irq, lirc_irq_handler,
(share_irq ? IRQF_SHARED : 0),
LIRC_DRIVER_NAME, (void *)&hardware);
if (result < 0) {
@@ -800,22 +800,22 @@ static int lirc_serial_probe(struct platform_device *dev)
* for the NSLU2 it's done in boot code.
*/
if (((iommap != 0)
- && (request_mem_region(iommap, 8 << ioshift,
- LIRC_DRIVER_NAME) == NULL))
+ && (devm_request_mem_region(&dev->dev, iommap, 8 << ioshift,
+ LIRC_DRIVER_NAME) == NULL))
|| ((iommap == 0)
- && (request_region(io, 8, LIRC_DRIVER_NAME) == NULL))) {
+ && (devm_request_region(&dev->dev, io, 8,
+ LIRC_DRIVER_NAME) == NULL))) {
dev_err(&dev->dev, "port %04x already in use\n", io);
dev_warn(&dev->dev, "use 'setserial /dev/ttySX uart none'\n");
dev_warn(&dev->dev,
"or compile the serial port driver as module and\n");
dev_warn(&dev->dev, "make sure this module is loaded first\n");
- result = -EBUSY;
- goto exit_free_irq;
+ return -EBUSY;
}
result = hardware_init_port();
if (result < 0)
- goto exit_release_region;
+ return result;
/* Initialize pulse/space widths */
init_timing_params(duty_cycle, freq);
@@ -847,28 +847,6 @@ static int lirc_serial_probe(struct platform_device *dev)
dprintk("Interrupt %d, port %04x obtained\n", irq, io);
return 0;
-
-exit_release_region:
- if (iommap != 0)
- release_mem_region(iommap, 8 << ioshift);
- else
- release_region(io, 8);
-exit_free_irq:
- free_irq(irq, (void *)&hardware);
-
- return result;
-}
-
-static int lirc_serial_remove(struct platform_device *dev)
-{
- free_irq(irq, (void *)&hardware);
-
- if (iommap != 0)
- release_mem_region(iommap, 8 << ioshift);
- else
- release_region(io, 8);
-
- return 0;
}
static int set_use_inc(void *data)
@@ -1081,7 +1059,6 @@ static int lirc_serial_resume(struct platform_device *dev)
static struct platform_driver lirc_serial_driver = {
.probe = lirc_serial_probe,
- .remove = lirc_serial_remove,
.suspend = lirc_serial_suspend,
.resume = lirc_serial_resume,
.driver = {
diff --git a/drivers/staging/media/msi3101/Kconfig b/drivers/staging/media/msi3101/Kconfig
deleted file mode 100644
index de0b3bba3873..000000000000
--- a/drivers/staging/media/msi3101/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-config USB_MSI3101
- tristate "Mirics MSi3101 SDR Dongle"
- depends on USB && VIDEO_DEV && VIDEO_V4L2 && SPI
- select VIDEOBUF2_CORE
- select VIDEOBUF2_VMALLOC
- select MEDIA_TUNER_MSI001
-
-config MEDIA_TUNER_MSI001
- tristate "Mirics MSi001"
- depends on VIDEO_V4L2 && SPI
diff --git a/drivers/staging/media/msi3101/Makefile b/drivers/staging/media/msi3101/Makefile
deleted file mode 100644
index daf4f58d9a56..000000000000
--- a/drivers/staging/media/msi3101/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_USB_MSI3101) += sdr-msi3101.o
-obj-$(CONFIG_MEDIA_TUNER_MSI001) += msi001.o
diff --git a/drivers/staging/media/msi3101/msi001.c b/drivers/staging/media/msi3101/msi001.c
deleted file mode 100644
index bd0b93cb6c53..000000000000
--- a/drivers/staging/media/msi3101/msi001.c
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * Mirics MSi001 silicon tuner driver
- *
- * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
- * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
- *
- * 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.
- */
-
-#include <linux/module.h>
-#include <linux/gcd.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ctrls.h>
-
-static const struct v4l2_frequency_band bands[] = {
- {
- .type = V4L2_TUNER_RF,
- .index = 0,
- .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
- .rangelow = 49000000,
- .rangehigh = 263000000,
- }, {
- .type = V4L2_TUNER_RF,
- .index = 1,
- .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
- .rangelow = 390000000,
- .rangehigh = 960000000,
- },
-};
-
-struct msi001 {
- struct spi_device *spi;
- struct v4l2_subdev sd;
-
- /* Controls */
- struct v4l2_ctrl_handler hdl;
- struct v4l2_ctrl *bandwidth_auto;
- struct v4l2_ctrl *bandwidth;
- struct v4l2_ctrl *lna_gain;
- struct v4l2_ctrl *mixer_gain;
- struct v4l2_ctrl *if_gain;
-
- unsigned int f_tuner;
-};
-
-static inline struct msi001 *sd_to_msi001(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct msi001, sd);
-}
-
-static int msi001_wreg(struct msi001 *s, u32 data)
-{
- /* Register format: 4 bits addr + 20 bits value */
- return spi_write(s->spi, &data, 3);
-};
-
-static int msi001_set_gain(struct msi001 *s, int lna_gain, int mixer_gain,
- int if_gain)
-{
- int ret;
- u32 reg;
- dev_dbg(&s->spi->dev, "%s: lna=%d mixer=%d if=%d\n", __func__,
- lna_gain, mixer_gain, if_gain);
-
- reg = 1 << 0;
- reg |= (59 - if_gain) << 4;
- reg |= 0 << 10;
- reg |= (1 - mixer_gain) << 12;
- reg |= (1 - lna_gain) << 13;
- reg |= 4 << 14;
- reg |= 0 << 17;
- ret = msi001_wreg(s, reg);
- if (ret)
- goto err;
-
- return 0;
-err:
- dev_dbg(&s->spi->dev, "%s: failed %d\n", __func__, ret);
- return ret;
-};
-
-static int msi001_set_tuner(struct msi001 *s)
-{
- int ret, i;
- unsigned int n, m, thresh, frac, vco_step, tmp, f_if1;
- u32 reg;
- u64 f_vco, tmp64;
- u8 mode, filter_mode, lo_div;
- static const struct {
- u32 rf;
- u8 mode;
- u8 lo_div;
- } band_lut[] = {
- { 50000000, 0xe1, 16}, /* AM_MODE2, antenna 2 */
- {108000000, 0x42, 32}, /* VHF_MODE */
- {330000000, 0x44, 16}, /* B3_MODE */
- {960000000, 0x48, 4}, /* B45_MODE */
- { ~0U, 0x50, 2}, /* BL_MODE */
- };
- static const struct {
- u32 freq;
- u8 filter_mode;
- } if_freq_lut[] = {
- { 0, 0x03}, /* Zero IF */
- { 450000, 0x02}, /* 450 kHz IF */
- {1620000, 0x01}, /* 1.62 MHz IF */
- {2048000, 0x00}, /* 2.048 MHz IF */
- };
- static const struct {
- u32 freq;
- u8 val;
- } bandwidth_lut[] = {
- { 200000, 0x00}, /* 200 kHz */
- { 300000, 0x01}, /* 300 kHz */
- { 600000, 0x02}, /* 600 kHz */
- {1536000, 0x03}, /* 1.536 MHz */
- {5000000, 0x04}, /* 5 MHz */
- {6000000, 0x05}, /* 6 MHz */
- {7000000, 0x06}, /* 7 MHz */
- {8000000, 0x07}, /* 8 MHz */
- };
-
- unsigned int f_rf = s->f_tuner;
-
- /*
- * bandwidth (Hz)
- * 200000, 300000, 600000, 1536000, 5000000, 6000000, 7000000, 8000000
- */
- unsigned int bandwidth;
-
- /*
- * intermediate frequency (Hz)
- * 0, 450000, 1620000, 2048000
- */
- unsigned int f_if = 0;
- #define F_REF 24000000
- #define R_REF 4
- #define F_OUT_STEP 1
-
- dev_dbg(&s->spi->dev,
- "%s: f_rf=%d f_if=%d\n",
- __func__, f_rf, f_if);
-
- for (i = 0; i < ARRAY_SIZE(band_lut); i++) {
- if (f_rf <= band_lut[i].rf) {
- mode = band_lut[i].mode;
- lo_div = band_lut[i].lo_div;
- break;
- }
- }
-
- if (i == ARRAY_SIZE(band_lut)) {
- ret = -EINVAL;
- goto err;
- }
-
- /* AM_MODE is upconverted */
- if ((mode >> 0) & 0x1)
- f_if1 = 5 * F_REF;
- else
- f_if1 = 0;
-
- for (i = 0; i < ARRAY_SIZE(if_freq_lut); i++) {
- if (f_if == if_freq_lut[i].freq) {
- filter_mode = if_freq_lut[i].filter_mode;
- break;
- }
- }
-
- if (i == ARRAY_SIZE(if_freq_lut)) {
- ret = -EINVAL;
- goto err;
- }
-
- /* filters */
- bandwidth = s->bandwidth->val;
- bandwidth = clamp(bandwidth, 200000U, 8000000U);
-
- for (i = 0; i < ARRAY_SIZE(bandwidth_lut); i++) {
- if (bandwidth <= bandwidth_lut[i].freq) {
- bandwidth = bandwidth_lut[i].val;
- break;
- }
- }
-
- if (i == ARRAY_SIZE(bandwidth_lut)) {
- ret = -EINVAL;
- goto err;
- }
-
- s->bandwidth->val = bandwidth_lut[i].freq;
-
- dev_dbg(&s->spi->dev, "%s: bandwidth selected=%d\n",
- __func__, bandwidth_lut[i].freq);
-
- f_vco = (u64) (f_rf + f_if + f_if1) * lo_div;
- tmp64 = f_vco;
- m = do_div(tmp64, F_REF * R_REF);
- n = (unsigned int) tmp64;
-
- vco_step = F_OUT_STEP * lo_div;
- thresh = (F_REF * R_REF) / vco_step;
- frac = 1ul * thresh * m / (F_REF * R_REF);
-
- /* Find out greatest common divisor and divide to smaller. */
- tmp = gcd(thresh, frac);
- thresh /= tmp;
- frac /= tmp;
-
- /* Force divide to reg max. Resolution will be reduced. */
- tmp = DIV_ROUND_UP(thresh, 4095);
- thresh = DIV_ROUND_CLOSEST(thresh, tmp);
- frac = DIV_ROUND_CLOSEST(frac, tmp);
-
- /* calc real RF set */
- tmp = 1ul * F_REF * R_REF * n;
- tmp += 1ul * F_REF * R_REF * frac / thresh;
- tmp /= lo_div;
-
- dev_dbg(&s->spi->dev,
- "%s: rf=%u:%u n=%d thresh=%d frac=%d\n",
- __func__, f_rf, tmp, n, thresh, frac);
-
- ret = msi001_wreg(s, 0x00000e);
- if (ret)
- goto err;
-
- ret = msi001_wreg(s, 0x000003);
- if (ret)
- goto err;
-
- reg = 0 << 0;
- reg |= mode << 4;
- reg |= filter_mode << 12;
- reg |= bandwidth << 14;
- reg |= 0x02 << 17;
- reg |= 0x00 << 20;
- ret = msi001_wreg(s, reg);
- if (ret)
- goto err;
-
- reg = 5 << 0;
- reg |= thresh << 4;
- reg |= 1 << 19;
- reg |= 1 << 21;
- ret = msi001_wreg(s, reg);
- if (ret)
- goto err;
-
- reg = 2 << 0;
- reg |= frac << 4;
- reg |= n << 16;
- ret = msi001_wreg(s, reg);
- if (ret)
- goto err;
-
- ret = msi001_set_gain(s, s->lna_gain->cur.val, s->mixer_gain->cur.val,
- s->if_gain->cur.val);
- if (ret)
- goto err;
-
- reg = 6 << 0;
- reg |= 63 << 4;
- reg |= 4095 << 10;
- ret = msi001_wreg(s, reg);
- if (ret)
- goto err;
-
- return 0;
-err:
- dev_dbg(&s->spi->dev, "%s: failed %d\n", __func__, ret);
- return ret;
-};
-
-static int msi001_s_power(struct v4l2_subdev *sd, int on)
-{
- struct msi001 *s = sd_to_msi001(sd);
- int ret;
- dev_dbg(&s->spi->dev, "%s: on=%d\n", __func__, on);
-
- if (on)
- ret = 0;
- else
- ret = msi001_wreg(s, 0x000000);
-
- return ret;
-}
-
-static const struct v4l2_subdev_core_ops msi001_core_ops = {
- .s_power = msi001_s_power,
-};
-
-static int msi001_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v)
-{
- struct msi001 *s = sd_to_msi001(sd);
- dev_dbg(&s->spi->dev, "%s: index=%d\n", __func__, v->index);
-
- strlcpy(v->name, "Mirics MSi001", sizeof(v->name));
- v->type = V4L2_TUNER_RF;
- v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
- v->rangelow = 49000000;
- v->rangehigh = 960000000;
-
- return 0;
-}
-
-static int msi001_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *v)
-{
- struct msi001 *s = sd_to_msi001(sd);
- dev_dbg(&s->spi->dev, "%s: index=%d\n", __func__, v->index);
- return 0;
-}
-
-static int msi001_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
-{
- struct msi001 *s = sd_to_msi001(sd);
- dev_dbg(&s->spi->dev, "%s: tuner=%d\n", __func__, f->tuner);
- f->frequency = s->f_tuner;
- return 0;
-}
-
-static int msi001_s_frequency(struct v4l2_subdev *sd,
- const struct v4l2_frequency *f)
-{
- struct msi001 *s = sd_to_msi001(sd);
- unsigned int band;
- dev_dbg(&s->spi->dev, "%s: tuner=%d type=%d frequency=%u\n",
- __func__, f->tuner, f->type, f->frequency);
-
- if (f->frequency < ((bands[0].rangehigh + bands[1].rangelow) / 2))
- band = 0;
- else
- band = 1;
- s->f_tuner = clamp_t(unsigned int, f->frequency,
- bands[band].rangelow, bands[band].rangehigh);
-
- return msi001_set_tuner(s);
-}
-
-static int msi001_enum_freq_bands(struct v4l2_subdev *sd,
- struct v4l2_frequency_band *band)
-{
- struct msi001 *s = sd_to_msi001(sd);
- dev_dbg(&s->spi->dev, "%s: tuner=%d type=%d index=%d\n",
- __func__, band->tuner, band->type, band->index);
-
- if (band->index >= ARRAY_SIZE(bands))
- return -EINVAL;
-
- band->capability = bands[band->index].capability;
- band->rangelow = bands[band->index].rangelow;
- band->rangehigh = bands[band->index].rangehigh;
-
- return 0;
-}
-
-static const struct v4l2_subdev_tuner_ops msi001_tuner_ops = {
- .g_tuner = msi001_g_tuner,
- .s_tuner = msi001_s_tuner,
- .g_frequency = msi001_g_frequency,
- .s_frequency = msi001_s_frequency,
- .enum_freq_bands = msi001_enum_freq_bands,
-};
-
-static const struct v4l2_subdev_ops msi001_ops = {
- .core = &msi001_core_ops,
- .tuner = &msi001_tuner_ops,
-};
-
-static int msi001_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct msi001 *s = container_of(ctrl->handler, struct msi001, hdl);
-
- int ret;
- dev_dbg(&s->spi->dev,
- "%s: id=%d name=%s val=%d min=%d max=%d step=%d\n",
- __func__, ctrl->id, ctrl->name, ctrl->val,
- ctrl->minimum, ctrl->maximum, ctrl->step);
-
- switch (ctrl->id) {
- case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO:
- case V4L2_CID_RF_TUNER_BANDWIDTH:
- ret = msi001_set_tuner(s);
- break;
- case V4L2_CID_RF_TUNER_LNA_GAIN:
- ret = msi001_set_gain(s, s->lna_gain->val,
- s->mixer_gain->cur.val, s->if_gain->cur.val);
- break;
- case V4L2_CID_RF_TUNER_MIXER_GAIN:
- ret = msi001_set_gain(s, s->lna_gain->cur.val,
- s->mixer_gain->val, s->if_gain->cur.val);
- break;
- case V4L2_CID_RF_TUNER_IF_GAIN:
- ret = msi001_set_gain(s, s->lna_gain->cur.val,
- s->mixer_gain->cur.val, s->if_gain->val);
- break;
- default:
- dev_dbg(&s->spi->dev, "%s: unkown control %d\n",
- __func__, ctrl->id);
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static const struct v4l2_ctrl_ops msi001_ctrl_ops = {
- .s_ctrl = msi001_s_ctrl,
-};
-
-static int msi001_probe(struct spi_device *spi)
-{
- struct msi001 *s;
- int ret;
- dev_dbg(&spi->dev, "%s:\n", __func__);
-
- s = kzalloc(sizeof(struct msi001), GFP_KERNEL);
- if (s == NULL) {
- ret = -ENOMEM;
- dev_dbg(&spi->dev, "Could not allocate memory for msi001\n");
- goto err_kfree;
- }
-
- s->spi = spi;
- s->f_tuner = bands[0].rangelow;
- v4l2_spi_subdev_init(&s->sd, spi, &msi001_ops);
-
- /* Register controls */
- v4l2_ctrl_handler_init(&s->hdl, 5);
- s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, &msi001_ctrl_ops,
- V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1);
- s->bandwidth = v4l2_ctrl_new_std(&s->hdl, &msi001_ctrl_ops,
- V4L2_CID_RF_TUNER_BANDWIDTH, 200000, 8000000, 1, 200000);
- v4l2_ctrl_auto_cluster(2, &s->bandwidth_auto, 0, false);
- s->lna_gain = v4l2_ctrl_new_std(&s->hdl, &msi001_ctrl_ops,
- V4L2_CID_RF_TUNER_LNA_GAIN, 0, 1, 1, 1);
- s->mixer_gain = v4l2_ctrl_new_std(&s->hdl, &msi001_ctrl_ops,
- V4L2_CID_RF_TUNER_MIXER_GAIN, 0, 1, 1, 1);
- s->if_gain = v4l2_ctrl_new_std(&s->hdl, &msi001_ctrl_ops,
- V4L2_CID_RF_TUNER_IF_GAIN, 0, 59, 1, 0);
- if (s->hdl.error) {
- ret = s->hdl.error;
- dev_err(&s->spi->dev, "Could not initialize controls\n");
- /* control init failed, free handler */
- goto err_ctrl_handler_free;
- }
-
- s->sd.ctrl_handler = &s->hdl;
- return 0;
-
-err_ctrl_handler_free:
- v4l2_ctrl_handler_free(&s->hdl);
-err_kfree:
- kfree(s);
- return ret;
-}
-
-static int msi001_remove(struct spi_device *spi)
-{
- struct v4l2_subdev *sd = spi_get_drvdata(spi);
- struct msi001 *s = sd_to_msi001(sd);
- dev_dbg(&spi->dev, "%s:\n", __func__);
-
- /*
- * Registered by v4l2_spi_new_subdev() from master driver, but we must
- * unregister it from here. Weird.
- */
- v4l2_device_unregister_subdev(&s->sd);
- v4l2_ctrl_handler_free(&s->hdl);
- kfree(s);
- return 0;
-}
-
-static const struct spi_device_id msi001_id[] = {
- {"msi001", 0},
- {}
-};
-MODULE_DEVICE_TABLE(spi, msi001_id);
-
-static struct spi_driver msi001_driver = {
- .driver = {
- .name = "msi001",
- .owner = THIS_MODULE,
- },
- .probe = msi001_probe,
- .remove = msi001_remove,
- .id_table = msi001_id,
-};
-module_spi_driver(msi001_driver);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Mirics MSi001");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c
deleted file mode 100644
index 08d0d096b881..000000000000
--- a/drivers/staging/media/msi3101/sdr-msi3101.c
+++ /dev/null
@@ -1,1518 +0,0 @@
-/*
- * Mirics MSi3101 SDR Dongle driver
- *
- * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * That driver is somehow based of pwc driver:
- * (C) 1999-2004 Nemosoft Unv.
- * (C) 2004-2006 Luc Saillard (luc@saillard.org)
- * (C) 2011 Hans de Goede <hdegoede@redhat.com>
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <asm/div64.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-event.h>
-#include <linux/usb.h>
-#include <media/videobuf2-vmalloc.h>
-#include <linux/spi/spi.h>
-
-/*
- * iConfiguration 0
- * bInterfaceNumber 0
- * bAlternateSetting 1
- * bNumEndpoints 1
- * bEndpointAddress 0x81 EP 1 IN
- * bmAttributes 1
- * Transfer Type Isochronous
- * wMaxPacketSize 0x1400 3x 1024 bytes
- * bInterval 1
- */
-#define MAX_ISO_BUFS (8)
-#define ISO_FRAMES_PER_DESC (8)
-#define ISO_MAX_FRAME_SIZE (3 * 1024)
-#define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE)
-#define MAX_ISOC_ERRORS 20
-
-/* TODO: These should be moved to V4L2 API */
-#define V4L2_PIX_FMT_SDR_S8 v4l2_fourcc('D', 'S', '0', '8') /* signed 8-bit */
-#define V4L2_PIX_FMT_SDR_S12 v4l2_fourcc('D', 'S', '1', '2') /* signed 12-bit */
-#define V4L2_PIX_FMT_SDR_S14 v4l2_fourcc('D', 'S', '1', '4') /* signed 14-bit */
-#define V4L2_PIX_FMT_SDR_MSI2500_384 v4l2_fourcc('M', '3', '8', '4') /* Mirics MSi2500 format 384 */
-
-static const struct v4l2_frequency_band bands[] = {
- {
- .tuner = 0,
- .type = V4L2_TUNER_ADC,
- .index = 0,
- .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
- .rangelow = 1200000,
- .rangehigh = 15000000,
- },
-};
-
-/* stream formats */
-struct msi3101_format {
- char *name;
- u32 pixelformat;
-};
-
-/* format descriptions for capture and preview */
-static struct msi3101_format formats[] = {
- {
- .name = "IQ U8",
- .pixelformat = V4L2_SDR_FMT_CU8,
- }, {
- .name = "IQ U16LE",
- .pixelformat = V4L2_SDR_FMT_CU16LE,
-#if 0
- }, {
- .name = "8-bit signed",
- .pixelformat = V4L2_PIX_FMT_SDR_S8,
- }, {
- .name = "10+2-bit signed",
- .pixelformat = V4L2_PIX_FMT_SDR_MSI2500_384,
- }, {
- .name = "12-bit signed",
- .pixelformat = V4L2_PIX_FMT_SDR_S12,
- }, {
- .name = "14-bit signed",
- .pixelformat = V4L2_PIX_FMT_SDR_S14,
-#endif
- },
-};
-
-static const unsigned int NUM_FORMATS = ARRAY_SIZE(formats);
-
-/* intermediate buffers with raw data from the USB device */
-struct msi3101_frame_buf {
- struct vb2_buffer vb; /* common v4l buffer stuff -- must be first */
- struct list_head list;
-};
-
-struct msi3101_state {
- struct video_device vdev;
- struct v4l2_device v4l2_dev;
- struct v4l2_subdev *v4l2_subdev;
- struct spi_master *master;
-
- /* videobuf2 queue and queued buffers list */
- struct vb2_queue vb_queue;
- struct list_head queued_bufs;
- spinlock_t queued_bufs_lock; /* Protects queued_bufs */
-
- /* Note if taking both locks v4l2_lock must always be locked first! */
- struct mutex v4l2_lock; /* Protects everything else */
- struct mutex vb_queue_lock; /* Protects vb_queue and capt_file */
-
- /* Pointer to our usb_device, will be NULL after unplug */
- struct usb_device *udev; /* Both mutexes most be hold when setting! */
-
- unsigned int f_adc;
- u32 pixelformat;
-
- unsigned int isoc_errors; /* number of contiguous ISOC errors */
- unsigned int vb_full; /* vb is full and packets dropped */
-
- struct urb *urbs[MAX_ISO_BUFS];
- int (*convert_stream)(struct msi3101_state *s, u8 *dst, u8 *src,
- unsigned int src_len);
-
- /* Controls */
- struct v4l2_ctrl_handler hdl;
-
- u32 next_sample; /* for track lost packets */
- u32 sample; /* for sample rate calc */
- unsigned long jiffies_next;
- unsigned int sample_ctrl_bit[4];
-};
-
-/* Private functions */
-static struct msi3101_frame_buf *msi3101_get_next_fill_buf(
- struct msi3101_state *s)
-{
- unsigned long flags = 0;
- struct msi3101_frame_buf *buf = NULL;
-
- spin_lock_irqsave(&s->queued_bufs_lock, flags);
- if (list_empty(&s->queued_bufs))
- goto leave;
-
- buf = list_entry(s->queued_bufs.next, struct msi3101_frame_buf, list);
- list_del(&buf->list);
-leave:
- spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
- return buf;
-}
-
-/*
- * +===========================================================================
- * | 00-1023 | USB packet type '504'
- * +===========================================================================
- * | 00- 03 | sequence number of first sample in that USB packet
- * +---------------------------------------------------------------------------
- * | 04- 15 | garbage
- * +---------------------------------------------------------------------------
- * | 16-1023 | samples
- * +---------------------------------------------------------------------------
- * signed 8-bit sample
- * 504 * 2 = 1008 samples
- */
-static int msi3101_convert_stream_504(struct msi3101_state *s, u8 *dst,
- u8 *src, unsigned int src_len)
-{
- int i, i_max, dst_len = 0;
- u32 sample_num[3];
-
- /* There could be 1-3 1024 bytes URB frames */
- i_max = src_len / 1024;
-
- for (i = 0; i < i_max; i++) {
- sample_num[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0;
- if (i == 0 && s->next_sample != sample_num[0]) {
- dev_dbg_ratelimited(&s->udev->dev,
- "%d samples lost, %d %08x:%08x\n",
- sample_num[0] - s->next_sample,
- src_len, s->next_sample, sample_num[0]);
- }
-
- /*
- * Dump all unknown 'garbage' data - maybe we will discover
- * someday if there is something rational...
- */
- dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
-
- /* 504 x I+Q samples */
- src += 16;
- memcpy(dst, src, 1008);
- src += 1008;
- dst += 1008;
- dst_len += 1008;
- }
-
- /* calculate samping rate and output it in 10 seconds intervals */
- if ((s->jiffies_next + msecs_to_jiffies(10000)) <= jiffies) {
- unsigned long jiffies_now = jiffies;
- unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next);
- unsigned int samples = sample_num[i_max - 1] - s->sample;
- s->jiffies_next = jiffies_now;
- s->sample = sample_num[i_max - 1];
- dev_dbg(&s->udev->dev,
- "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
- src_len, samples, msecs,
- samples * 1000UL / msecs);
- }
-
- /* next sample (sample = sample + i * 504) */
- s->next_sample = sample_num[i_max - 1] + 504;
-
- return dst_len;
-}
-
-static int msi3101_convert_stream_504_u8(struct msi3101_state *s, u8 *dst,
- u8 *src, unsigned int src_len)
-{
- int i, j, i_max, dst_len = 0;
- u32 sample_num[3];
- s8 *s8src;
- u8 *u8dst;
-
- /* There could be 1-3 1024 bytes URB frames */
- i_max = src_len / 1024;
- u8dst = (u8 *) dst;
-
- for (i = 0; i < i_max; i++) {
- sample_num[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0;
- if (i == 0 && s->next_sample != sample_num[0]) {
- dev_dbg_ratelimited(&s->udev->dev,
- "%d samples lost, %d %08x:%08x\n",
- sample_num[0] - s->next_sample,
- src_len, s->next_sample, sample_num[0]);
- }
-
- /*
- * Dump all unknown 'garbage' data - maybe we will discover
- * someday if there is something rational...
- */
- dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
-
- /* 504 x I+Q samples */
- src += 16;
-
- s8src = (s8 *) src;
- for (j = 0; j < 1008; j++)
- *u8dst++ = *s8src++ + 128;
-
- src += 1008;
- dst += 1008;
- dst_len += 1008;
- }
-
- /* calculate samping rate and output it in 10 seconds intervals */
- if (unlikely(time_is_before_jiffies(s->jiffies_next))) {
-#define MSECS 10000UL
- unsigned int samples = sample_num[i_max - 1] - s->sample;
- s->jiffies_next = jiffies + msecs_to_jiffies(MSECS);
- s->sample = sample_num[i_max - 1];
- dev_dbg(&s->udev->dev,
- "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
- src_len, samples, MSECS,
- samples * 1000UL / MSECS);
- }
-
- /* next sample (sample = sample + i * 504) */
- s->next_sample = sample_num[i_max - 1] + 504;
-
- return dst_len;
-}
-
-/*
- * +===========================================================================
- * | 00-1023 | USB packet type '384'
- * +===========================================================================
- * | 00- 03 | sequence number of first sample in that USB packet
- * +---------------------------------------------------------------------------
- * | 04- 15 | garbage
- * +---------------------------------------------------------------------------
- * | 16- 175 | samples
- * +---------------------------------------------------------------------------
- * | 176- 179 | control bits for previous samples
- * +---------------------------------------------------------------------------
- * | 180- 339 | samples
- * +---------------------------------------------------------------------------
- * | 340- 343 | control bits for previous samples
- * +---------------------------------------------------------------------------
- * | 344- 503 | samples
- * +---------------------------------------------------------------------------
- * | 504- 507 | control bits for previous samples
- * +---------------------------------------------------------------------------
- * | 508- 667 | samples
- * +---------------------------------------------------------------------------
- * | 668- 671 | control bits for previous samples
- * +---------------------------------------------------------------------------
- * | 672- 831 | samples
- * +---------------------------------------------------------------------------
- * | 832- 835 | control bits for previous samples
- * +---------------------------------------------------------------------------
- * | 836- 995 | samples
- * +---------------------------------------------------------------------------
- * | 996- 999 | control bits for previous samples
- * +---------------------------------------------------------------------------
- * | 1000-1023 | garbage
- * +---------------------------------------------------------------------------
- *
- * Bytes 4 - 7 could have some meaning?
- *
- * Control bits for previous samples is 32-bit field, containing 16 x 2-bit
- * numbers. This results one 2-bit number for 8 samples. It is likely used for
- * for bit shifting sample by given bits, increasing actual sampling resolution.
- * Number 2 (0b10) was never seen.
- *
- * 6 * 16 * 2 * 4 = 768 samples. 768 * 4 = 3072 bytes
- */
-static int msi3101_convert_stream_384(struct msi3101_state *s, u8 *dst,
- u8 *src, unsigned int src_len)
-{
- int i, i_max, dst_len = 0;
- u32 sample_num[3];
-
- /* There could be 1-3 1024 bytes URB frames */
- i_max = src_len / 1024;
- for (i = 0; i < i_max; i++) {
- sample_num[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0;
- if (i == 0 && s->next_sample != sample_num[0]) {
- dev_dbg_ratelimited(&s->udev->dev,
- "%d samples lost, %d %08x:%08x\n",
- sample_num[0] - s->next_sample,
- src_len, s->next_sample, sample_num[0]);
- }
-
- /*
- * Dump all unknown 'garbage' data - maybe we will discover
- * someday if there is something rational...
- */
- dev_dbg_ratelimited(&s->udev->dev,
- "%*ph %*ph\n", 12, &src[4], 24, &src[1000]);
-
- /* 384 x I+Q samples */
- src += 16;
- memcpy(dst, src, 984);
- src += 984 + 24;
- dst += 984;
- dst_len += 984;
- }
-
- /* calculate samping rate and output it in 10 seconds intervals */
- if ((s->jiffies_next + msecs_to_jiffies(10000)) <= jiffies) {
- unsigned long jiffies_now = jiffies;
- unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next);
- unsigned int samples = sample_num[i_max - 1] - s->sample;
- s->jiffies_next = jiffies_now;
- s->sample = sample_num[i_max - 1];
- dev_dbg(&s->udev->dev,
- "slen=%d samples=%u msecs=%lu sampling rate=%lu bits=%d.%d.%d.%d\n",
- src_len, samples, msecs,
- samples * 1000UL / msecs,
- s->sample_ctrl_bit[0], s->sample_ctrl_bit[1],
- s->sample_ctrl_bit[2], s->sample_ctrl_bit[3]);
- }
-
- /* next sample (sample = sample + i * 384) */
- s->next_sample = sample_num[i_max - 1] + 384;
-
- return dst_len;
-}
-
-/*
- * +===========================================================================
- * | 00-1023 | USB packet type '336'
- * +===========================================================================
- * | 00- 03 | sequence number of first sample in that USB packet
- * +---------------------------------------------------------------------------
- * | 04- 15 | garbage
- * +---------------------------------------------------------------------------
- * | 16-1023 | samples
- * +---------------------------------------------------------------------------
- * signed 12-bit sample
- */
-static int msi3101_convert_stream_336(struct msi3101_state *s, u8 *dst,
- u8 *src, unsigned int src_len)
-{
- int i, i_max, dst_len = 0;
- u32 sample_num[3];
-
- /* There could be 1-3 1024 bytes URB frames */
- i_max = src_len / 1024;
-
- for (i = 0; i < i_max; i++) {
- sample_num[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0;
- if (i == 0 && s->next_sample != sample_num[0]) {
- dev_dbg_ratelimited(&s->udev->dev,
- "%d samples lost, %d %08x:%08x\n",
- sample_num[0] - s->next_sample,
- src_len, s->next_sample, sample_num[0]);
- }
-
- /*
- * Dump all unknown 'garbage' data - maybe we will discover
- * someday if there is something rational...
- */
- dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
-
- /* 336 x I+Q samples */
- src += 16;
- memcpy(dst, src, 1008);
- src += 1008;
- dst += 1008;
- dst_len += 1008;
- }
-
- /* calculate samping rate and output it in 10 seconds intervals */
- if ((s->jiffies_next + msecs_to_jiffies(10000)) <= jiffies) {
- unsigned long jiffies_now = jiffies;
- unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next);
- unsigned int samples = sample_num[i_max - 1] - s->sample;
- s->jiffies_next = jiffies_now;
- s->sample = sample_num[i_max - 1];
- dev_dbg(&s->udev->dev,
- "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
- src_len, samples, msecs,
- samples * 1000UL / msecs);
- }
-
- /* next sample (sample = sample + i * 336) */
- s->next_sample = sample_num[i_max - 1] + 336;
-
- return dst_len;
-}
-
-/*
- * +===========================================================================
- * | 00-1023 | USB packet type '252'
- * +===========================================================================
- * | 00- 03 | sequence number of first sample in that USB packet
- * +---------------------------------------------------------------------------
- * | 04- 15 | garbage
- * +---------------------------------------------------------------------------
- * | 16-1023 | samples
- * +---------------------------------------------------------------------------
- * signed 14-bit sample
- */
-static int msi3101_convert_stream_252(struct msi3101_state *s, u8 *dst,
- u8 *src, unsigned int src_len)
-{
- int i, i_max, dst_len = 0;
- u32 sample_num[3];
-
- /* There could be 1-3 1024 bytes URB frames */
- i_max = src_len / 1024;
-
- for (i = 0; i < i_max; i++) {
- sample_num[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0;
- if (i == 0 && s->next_sample != sample_num[0]) {
- dev_dbg_ratelimited(&s->udev->dev,
- "%d samples lost, %d %08x:%08x\n",
- sample_num[0] - s->next_sample,
- src_len, s->next_sample, sample_num[0]);
- }
-
- /*
- * Dump all unknown 'garbage' data - maybe we will discover
- * someday if there is something rational...
- */
- dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
-
- /* 252 x I+Q samples */
- src += 16;
- memcpy(dst, src, 1008);
- src += 1008;
- dst += 1008;
- dst_len += 1008;
- }
-
- /* calculate samping rate and output it in 10 seconds intervals */
- if ((s->jiffies_next + msecs_to_jiffies(10000)) <= jiffies) {
- unsigned long jiffies_now = jiffies;
- unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next);
- unsigned int samples = sample_num[i_max - 1] - s->sample;
- s->jiffies_next = jiffies_now;
- s->sample = sample_num[i_max - 1];
- dev_dbg(&s->udev->dev,
- "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
- src_len, samples, msecs,
- samples * 1000UL / msecs);
- }
-
- /* next sample (sample = sample + i * 252) */
- s->next_sample = sample_num[i_max - 1] + 252;
-
- return dst_len;
-}
-
-static int msi3101_convert_stream_252_u16(struct msi3101_state *s, u8 *dst,
- u8 *src, unsigned int src_len)
-{
- int i, j, i_max, dst_len = 0;
- u32 sample_num[3];
- u16 *u16dst = (u16 *) dst;
- struct {signed int x:14;} se;
-
- /* There could be 1-3 1024 bytes URB frames */
- i_max = src_len / 1024;
-
- for (i = 0; i < i_max; i++) {
- sample_num[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0;
- if (i == 0 && s->next_sample != sample_num[0]) {
- dev_dbg_ratelimited(&s->udev->dev,
- "%d samples lost, %d %08x:%08x\n",
- sample_num[0] - s->next_sample,
- src_len, s->next_sample, sample_num[0]);
- }
-
- /*
- * Dump all unknown 'garbage' data - maybe we will discover
- * someday if there is something rational...
- */
- dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
-
- /* 252 x I+Q samples */
- src += 16;
-
- for (j = 0; j < 1008; j += 4) {
- unsigned int usample[2];
- int ssample[2];
-
- usample[0] = src[j + 0] >> 0 | src[j + 1] << 8;
- usample[1] = src[j + 2] >> 0 | src[j + 3] << 8;
-
- /* sign extension from 14-bit to signed int */
- ssample[0] = se.x = usample[0];
- ssample[1] = se.x = usample[1];
-
- /* from signed to unsigned */
- usample[0] = ssample[0] + 8192;
- usample[1] = ssample[1] + 8192;
-
- /* from 14-bit to 16-bit */
- *u16dst++ = (usample[0] << 2) | (usample[0] >> 12);
- *u16dst++ = (usample[1] << 2) | (usample[1] >> 12);
- }
-
- src += 1008;
- dst += 1008;
- dst_len += 1008;
- }
-
- /* calculate samping rate and output it in 10 seconds intervals */
- if (unlikely(time_is_before_jiffies(s->jiffies_next))) {
-#define MSECS 10000UL
- unsigned int samples = sample_num[i_max - 1] - s->sample;
- s->jiffies_next = jiffies + msecs_to_jiffies(MSECS);
- s->sample = sample_num[i_max - 1];
- dev_dbg(&s->udev->dev,
- "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
- src_len, samples, MSECS,
- samples * 1000UL / MSECS);
- }
-
- /* next sample (sample = sample + i * 252) */
- s->next_sample = sample_num[i_max - 1] + 252;
-
- return dst_len;
-}
-
-/*
- * This gets called for the Isochronous pipe (stream). This is done in interrupt
- * time, so it has to be fast, not crash, and not stall. Neat.
- */
-static void msi3101_isoc_handler(struct urb *urb)
-{
- struct msi3101_state *s = (struct msi3101_state *)urb->context;
- int i, flen, fstatus;
- unsigned char *iso_buf = NULL;
- struct msi3101_frame_buf *fbuf;
-
- if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN)) {
- dev_dbg(&s->udev->dev, "URB (%p) unlinked %ssynchronuously\n",
- urb, urb->status == -ENOENT ? "" : "a");
- return;
- }
-
- if (unlikely(urb->status != 0)) {
- dev_dbg(&s->udev->dev,
- "msi3101_isoc_handler() called with status %d\n",
- urb->status);
- /* Give up after a number of contiguous errors */
- if (++s->isoc_errors > MAX_ISOC_ERRORS)
- dev_dbg(&s->udev->dev,
- "Too many ISOC errors, bailing out\n");
- goto handler_end;
- } else {
- /* Reset ISOC error counter. We did get here, after all. */
- s->isoc_errors = 0;
- }
-
- /* Compact data */
- for (i = 0; i < urb->number_of_packets; i++) {
- void *ptr;
-
- /* Check frame error */
- fstatus = urb->iso_frame_desc[i].status;
- if (unlikely(fstatus)) {
- dev_dbg_ratelimited(&s->udev->dev,
- "frame=%d/%d has error %d skipping\n",
- i, urb->number_of_packets, fstatus);
- continue;
- }
-
- /* Check if that frame contains data */
- flen = urb->iso_frame_desc[i].actual_length;
- if (unlikely(flen == 0))
- continue;
-
- iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
-
- /* Get free framebuffer */
- fbuf = msi3101_get_next_fill_buf(s);
- if (unlikely(fbuf == NULL)) {
- s->vb_full++;
- dev_dbg_ratelimited(&s->udev->dev,
- "videobuf is full, %d packets dropped\n",
- s->vb_full);
- continue;
- }
-
- /* fill framebuffer */
- ptr = vb2_plane_vaddr(&fbuf->vb, 0);
- flen = s->convert_stream(s, ptr, iso_buf, flen);
- vb2_set_plane_payload(&fbuf->vb, 0, flen);
- vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE);
- }
-
-handler_end:
- i = usb_submit_urb(urb, GFP_ATOMIC);
- if (unlikely(i != 0))
- dev_dbg(&s->udev->dev,
- "Error (%d) re-submitting urb in msi3101_isoc_handler\n",
- i);
-}
-
-static void msi3101_iso_stop(struct msi3101_state *s)
-{
- int i;
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- /* Unlinking ISOC buffers one by one */
- for (i = 0; i < MAX_ISO_BUFS; i++) {
- if (s->urbs[i]) {
- dev_dbg(&s->udev->dev, "Unlinking URB %p\n",
- s->urbs[i]);
- usb_kill_urb(s->urbs[i]);
- }
- }
-}
-
-static void msi3101_iso_free(struct msi3101_state *s)
-{
- int i;
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- /* Freeing ISOC buffers one by one */
- for (i = 0; i < MAX_ISO_BUFS; i++) {
- if (s->urbs[i]) {
- dev_dbg(&s->udev->dev, "Freeing URB\n");
- if (s->urbs[i]->transfer_buffer) {
- usb_free_coherent(s->udev,
- s->urbs[i]->transfer_buffer_length,
- s->urbs[i]->transfer_buffer,
- s->urbs[i]->transfer_dma);
- }
- usb_free_urb(s->urbs[i]);
- s->urbs[i] = NULL;
- }
- }
-}
-
-/* Both v4l2_lock and vb_queue_lock should be locked when calling this */
-static void msi3101_isoc_cleanup(struct msi3101_state *s)
-{
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- msi3101_iso_stop(s);
- msi3101_iso_free(s);
-}
-
-/* Both v4l2_lock and vb_queue_lock should be locked when calling this */
-static int msi3101_isoc_init(struct msi3101_state *s)
-{
- struct usb_device *udev;
- struct urb *urb;
- int i, j, ret;
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- s->isoc_errors = 0;
- udev = s->udev;
-
- ret = usb_set_interface(s->udev, 0, 1);
- if (ret)
- return ret;
-
- /* Allocate and init Isochronuous urbs */
- for (i = 0; i < MAX_ISO_BUFS; i++) {
- urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL);
- if (urb == NULL) {
- dev_err(&s->udev->dev,
- "Failed to allocate urb %d\n", i);
- msi3101_isoc_cleanup(s);
- return -ENOMEM;
- }
- s->urbs[i] = urb;
- dev_dbg(&s->udev->dev, "Allocated URB at 0x%p\n", urb);
-
- urb->interval = 1;
- urb->dev = udev;
- urb->pipe = usb_rcvisocpipe(udev, 0x81);
- urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
- urb->transfer_buffer = usb_alloc_coherent(udev, ISO_BUFFER_SIZE,
- GFP_KERNEL, &urb->transfer_dma);
- if (urb->transfer_buffer == NULL) {
- dev_err(&s->udev->dev,
- "Failed to allocate urb buffer %d\n",
- i);
- msi3101_isoc_cleanup(s);
- return -ENOMEM;
- }
- urb->transfer_buffer_length = ISO_BUFFER_SIZE;
- urb->complete = msi3101_isoc_handler;
- urb->context = s;
- urb->start_frame = 0;
- urb->number_of_packets = ISO_FRAMES_PER_DESC;
- for (j = 0; j < ISO_FRAMES_PER_DESC; j++) {
- urb->iso_frame_desc[j].offset = j * ISO_MAX_FRAME_SIZE;
- urb->iso_frame_desc[j].length = ISO_MAX_FRAME_SIZE;
- }
- }
-
- /* link */
- for (i = 0; i < MAX_ISO_BUFS; i++) {
- ret = usb_submit_urb(s->urbs[i], GFP_KERNEL);
- if (ret) {
- dev_err(&s->udev->dev,
- "isoc_init() submit_urb %d failed with error %d\n",
- i, ret);
- msi3101_isoc_cleanup(s);
- return ret;
- }
- dev_dbg(&s->udev->dev, "URB 0x%p submitted.\n", s->urbs[i]);
- }
-
- /* All is done... */
- return 0;
-}
-
-/* Must be called with vb_queue_lock hold */
-static void msi3101_cleanup_queued_bufs(struct msi3101_state *s)
-{
- unsigned long flags = 0;
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- spin_lock_irqsave(&s->queued_bufs_lock, flags);
- while (!list_empty(&s->queued_bufs)) {
- struct msi3101_frame_buf *buf;
-
- buf = list_entry(s->queued_bufs.next, struct msi3101_frame_buf,
- list);
- list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
- }
- spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
-}
-
-/* The user yanked out the cable... */
-static void msi3101_disconnect(struct usb_interface *intf)
-{
- struct v4l2_device *v = usb_get_intfdata(intf);
- struct msi3101_state *s =
- container_of(v, struct msi3101_state, v4l2_dev);
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- mutex_lock(&s->vb_queue_lock);
- mutex_lock(&s->v4l2_lock);
- /* No need to keep the urbs around after disconnection */
- s->udev = NULL;
- v4l2_device_disconnect(&s->v4l2_dev);
- video_unregister_device(&s->vdev);
- spi_unregister_master(s->master);
- mutex_unlock(&s->v4l2_lock);
- mutex_unlock(&s->vb_queue_lock);
-
- v4l2_device_put(&s->v4l2_dev);
-}
-
-static int msi3101_querycap(struct file *file, void *fh,
- struct v4l2_capability *cap)
-{
- struct msi3101_state *s = video_drvdata(file);
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
- strlcpy(cap->card, s->vdev.name, sizeof(cap->card));
- usb_make_path(s->udev, cap->bus_info, sizeof(cap->bus_info));
- cap->device_caps = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_STREAMING |
- V4L2_CAP_READWRITE | V4L2_CAP_TUNER;
- cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
- return 0;
-}
-
-/* Videobuf2 operations */
-static int msi3101_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt, unsigned int *nbuffers,
- unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
-{
- struct msi3101_state *s = vb2_get_drv_priv(vq);
- dev_dbg(&s->udev->dev, "%s: *nbuffers=%d\n", __func__, *nbuffers);
-
- /* Absolute min and max number of buffers available for mmap() */
- *nbuffers = clamp_t(unsigned int, *nbuffers, 8, 32);
- *nplanes = 1;
- /*
- * 3, wMaxPacketSize 3x 1024 bytes
- * 504, max IQ sample pairs per 1024 frame
- * 2, two samples, I and Q
- * 2, 16-bit is enough for single sample
- */
- sizes[0] = PAGE_ALIGN(3 * 504 * 2 * 2);
- dev_dbg(&s->udev->dev, "%s: nbuffers=%d sizes[0]=%d\n",
- __func__, *nbuffers, sizes[0]);
- return 0;
-}
-
-static void msi3101_buf_queue(struct vb2_buffer *vb)
-{
- struct msi3101_state *s = vb2_get_drv_priv(vb->vb2_queue);
- struct msi3101_frame_buf *buf =
- container_of(vb, struct msi3101_frame_buf, vb);
- unsigned long flags = 0;
-
- /* Check the device has not disconnected between prep and queuing */
- if (unlikely(!s->udev)) {
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
- return;
- }
-
- spin_lock_irqsave(&s->queued_bufs_lock, flags);
- list_add_tail(&buf->list, &s->queued_bufs);
- spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
-}
-
-#define CMD_WREG 0x41
-#define CMD_START_STREAMING 0x43
-#define CMD_STOP_STREAMING 0x45
-#define CMD_READ_UNKNOW 0x48
-
-#define msi3101_dbg_usb_control_msg(udev, r, t, v, _i, b, l) { \
- char *direction; \
- if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
- direction = ">>>"; \
- else \
- direction = "<<<"; \
- dev_dbg(&udev->dev, "%s: %02x %02x %02x %02x %02x %02x %02x %02x " \
- "%s %*ph\n", __func__, t, r, v & 0xff, v >> 8, \
- _i & 0xff, _i >> 8, l & 0xff, l >> 8, direction, l, b); \
-}
-
-static int msi3101_ctrl_msg(struct msi3101_state *s, u8 cmd, u32 data)
-{
- int ret;
- u8 request = cmd;
- u8 requesttype = USB_DIR_OUT | USB_TYPE_VENDOR;
- u16 value = (data >> 0) & 0xffff;
- u16 index = (data >> 16) & 0xffff;
-
- msi3101_dbg_usb_control_msg(s->udev,
- request, requesttype, value, index, NULL, 0);
-
- ret = usb_control_msg(s->udev, usb_sndctrlpipe(s->udev, 0),
- request, requesttype, value, index, NULL, 0, 2000);
-
- if (ret)
- dev_err(&s->udev->dev, "%s: failed %d, cmd %02x, data %04x\n",
- __func__, ret, cmd, data);
-
- return ret;
-};
-
-#define F_REF 24000000
-#define DIV_R_IN 2
-static int msi3101_set_usb_adc(struct msi3101_state *s)
-{
- int ret, div_n, div_m, div_r_out, f_sr, f_vco, fract;
- u32 reg3, reg4, reg7;
- struct v4l2_ctrl *bandwidth_auto;
- struct v4l2_ctrl *bandwidth;
-
- f_sr = s->f_adc;
-
- /* set tuner, subdev, filters according to sampling rate */
- bandwidth_auto = v4l2_ctrl_find(&s->hdl, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO);
- if (v4l2_ctrl_g_ctrl(bandwidth_auto)) {
- bandwidth = v4l2_ctrl_find(&s->hdl, V4L2_CID_RF_TUNER_BANDWIDTH);
- v4l2_ctrl_s_ctrl(bandwidth, s->f_adc);
- }
-
- /* select stream format */
- switch (s->pixelformat) {
- case V4L2_SDR_FMT_CU8:
- s->convert_stream = msi3101_convert_stream_504_u8;
- reg7 = 0x000c9407;
- break;
- case V4L2_SDR_FMT_CU16LE:
- s->convert_stream = msi3101_convert_stream_252_u16;
- reg7 = 0x00009407;
- break;
- case V4L2_PIX_FMT_SDR_S8:
- s->convert_stream = msi3101_convert_stream_504;
- reg7 = 0x000c9407;
- break;
- case V4L2_PIX_FMT_SDR_MSI2500_384:
- s->convert_stream = msi3101_convert_stream_384;
- reg7 = 0x0000a507;
- break;
- case V4L2_PIX_FMT_SDR_S12:
- s->convert_stream = msi3101_convert_stream_336;
- reg7 = 0x00008507;
- break;
- case V4L2_PIX_FMT_SDR_S14:
- s->convert_stream = msi3101_convert_stream_252;
- reg7 = 0x00009407;
- break;
- default:
- s->convert_stream = msi3101_convert_stream_504_u8;
- reg7 = 0x000c9407;
- break;
- }
-
- /*
- * Synthesizer config is just a educated guess...
- *
- * [7:0] 0x03, register address
- * [8] 1, power control
- * [9] ?, power control
- * [12:10] output divider
- * [13] 0 ?
- * [14] 0 ?
- * [15] fractional MSB, bit 20
- * [16:19] N
- * [23:20] ?
- * [24:31] 0x01
- *
- * output divider
- * val div
- * 0 - (invalid)
- * 1 4
- * 2 6
- * 3 8
- * 4 10
- * 5 12
- * 6 14
- * 7 16
- *
- * VCO 202000000 - 720000000++
- */
- reg3 = 0x01000303;
- reg4 = 0x00000004;
-
- /* XXX: Filters? AGC? */
- if (f_sr < 6000000)
- reg3 |= 0x1 << 20;
- else if (f_sr < 7000000)
- reg3 |= 0x5 << 20;
- else if (f_sr < 8500000)
- reg3 |= 0x9 << 20;
- else
- reg3 |= 0xd << 20;
-
- for (div_r_out = 4; div_r_out < 16; div_r_out += 2) {
- f_vco = f_sr * div_r_out * 12;
- dev_dbg(&s->udev->dev, "%s: div_r_out=%d f_vco=%d\n",
- __func__, div_r_out, f_vco);
- if (f_vco >= 202000000)
- break;
- }
-
- div_n = f_vco / (F_REF * DIV_R_IN);
- div_m = f_vco % (F_REF * DIV_R_IN);
- fract = 0x200000ul * div_m / (F_REF * DIV_R_IN);
-
- reg3 |= div_n << 16;
- reg3 |= (div_r_out / 2 - 1) << 10;
- reg3 |= ((fract >> 20) & 0x000001) << 15; /* [20] */
- reg4 |= ((fract >> 0) & 0x0fffff) << 8; /* [19:0] */
-
- dev_dbg(&s->udev->dev,
- "%s: f_sr=%d f_vco=%d div_n=%d div_m=%d div_r_out=%d reg3=%08x reg4=%08x\n",
- __func__, f_sr, f_vco, div_n, div_m, div_r_out, reg3, reg4);
-
- ret = msi3101_ctrl_msg(s, CMD_WREG, 0x00608008);
- if (ret)
- goto err;
-
- ret = msi3101_ctrl_msg(s, CMD_WREG, 0x00000c05);
- if (ret)
- goto err;
-
- ret = msi3101_ctrl_msg(s, CMD_WREG, 0x00020000);
- if (ret)
- goto err;
-
- ret = msi3101_ctrl_msg(s, CMD_WREG, 0x00480102);
- if (ret)
- goto err;
-
- ret = msi3101_ctrl_msg(s, CMD_WREG, 0x00f38008);
- if (ret)
- goto err;
-
- ret = msi3101_ctrl_msg(s, CMD_WREG, reg7);
- if (ret)
- goto err;
-
- ret = msi3101_ctrl_msg(s, CMD_WREG, reg4);
- if (ret)
- goto err;
-
- ret = msi3101_ctrl_msg(s, CMD_WREG, reg3);
- if (ret)
- goto err;
-err:
- return ret;
-};
-
-static int msi3101_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
- struct msi3101_state *s = vb2_get_drv_priv(vq);
- int ret;
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- if (!s->udev)
- return -ENODEV;
-
- if (mutex_lock_interruptible(&s->v4l2_lock))
- return -ERESTARTSYS;
-
- /* wake-up tuner */
- v4l2_subdev_call(s->v4l2_subdev, core, s_power, 1);
-
- ret = msi3101_set_usb_adc(s);
-
- ret = msi3101_isoc_init(s);
- if (ret)
- msi3101_cleanup_queued_bufs(s);
-
- ret = msi3101_ctrl_msg(s, CMD_START_STREAMING, 0);
-
- mutex_unlock(&s->v4l2_lock);
-
- return ret;
-}
-
-static void msi3101_stop_streaming(struct vb2_queue *vq)
-{
- struct msi3101_state *s = vb2_get_drv_priv(vq);
-
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- mutex_lock(&s->v4l2_lock);
-
- if (s->udev)
- msi3101_isoc_cleanup(s);
-
- msi3101_cleanup_queued_bufs(s);
-
- /* according to tests, at least 700us delay is required */
- msleep(20);
- if (!msi3101_ctrl_msg(s, CMD_STOP_STREAMING, 0)) {
- /* sleep USB IF / ADC */
- msi3101_ctrl_msg(s, CMD_WREG, 0x01000003);
- }
-
- /* sleep tuner */
- v4l2_subdev_call(s->v4l2_subdev, core, s_power, 0);
-
- mutex_unlock(&s->v4l2_lock);
-}
-
-static struct vb2_ops msi3101_vb2_ops = {
- .queue_setup = msi3101_queue_setup,
- .buf_queue = msi3101_buf_queue,
- .start_streaming = msi3101_start_streaming,
- .stop_streaming = msi3101_stop_streaming,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
-};
-
-static int msi3101_enum_fmt_sdr_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct msi3101_state *s = video_drvdata(file);
- dev_dbg(&s->udev->dev, "%s: index=%d\n", __func__, f->index);
-
- if (f->index >= NUM_FORMATS)
- return -EINVAL;
-
- strlcpy(f->description, formats[f->index].name, sizeof(f->description));
- f->pixelformat = formats[f->index].pixelformat;
-
- return 0;
-}
-
-static int msi3101_g_fmt_sdr_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct msi3101_state *s = video_drvdata(file);
- dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
- (char *)&s->pixelformat);
-
- memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
- f->fmt.sdr.pixelformat = s->pixelformat;
-
- return 0;
-}
-
-static int msi3101_s_fmt_sdr_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct msi3101_state *s = video_drvdata(file);
- struct vb2_queue *q = &s->vb_queue;
- int i;
- dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
- (char *)&f->fmt.sdr.pixelformat);
-
- if (vb2_is_busy(q))
- return -EBUSY;
-
- memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
- for (i = 0; i < NUM_FORMATS; i++) {
- if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
- s->pixelformat = f->fmt.sdr.pixelformat;
- return 0;
- }
- }
-
- f->fmt.sdr.pixelformat = formats[0].pixelformat;
- s->pixelformat = formats[0].pixelformat;
-
- return 0;
-}
-
-static int msi3101_try_fmt_sdr_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct msi3101_state *s = video_drvdata(file);
- int i;
- dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
- (char *)&f->fmt.sdr.pixelformat);
-
- memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
- for (i = 0; i < NUM_FORMATS; i++) {
- if (formats[i].pixelformat == f->fmt.sdr.pixelformat)
- return 0;
- }
-
- f->fmt.sdr.pixelformat = formats[0].pixelformat;
-
- return 0;
-}
-
-static int msi3101_s_tuner(struct file *file, void *priv,
- const struct v4l2_tuner *v)
-{
- struct msi3101_state *s = video_drvdata(file);
- int ret;
- dev_dbg(&s->udev->dev, "%s: index=%d\n", __func__, v->index);
-
- if (v->index == 0)
- ret = 0;
- else if (v->index == 1)
- ret = v4l2_subdev_call(s->v4l2_subdev, tuner, s_tuner, v);
- else
- ret = -EINVAL;
-
- return ret;
-}
-
-static int msi3101_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
-{
- struct msi3101_state *s = video_drvdata(file);
- int ret;
- dev_dbg(&s->udev->dev, "%s: index=%d\n", __func__, v->index);
-
- if (v->index == 0) {
- strlcpy(v->name, "Mirics MSi2500", sizeof(v->name));
- v->type = V4L2_TUNER_ADC;
- v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
- v->rangelow = 1200000;
- v->rangehigh = 15000000;
- ret = 0;
- } else if (v->index == 1) {
- ret = v4l2_subdev_call(s->v4l2_subdev, tuner, g_tuner, v);
- } else {
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int msi3101_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct msi3101_state *s = video_drvdata(file);
- int ret = 0;
- dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d\n",
- __func__, f->tuner, f->type);
-
- if (f->tuner == 0) {
- f->frequency = s->f_adc;
- ret = 0;
- } else if (f->tuner == 1) {
- f->type = V4L2_TUNER_RF;
- ret = v4l2_subdev_call(s->v4l2_subdev, tuner, g_frequency, f);
- } else {
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int msi3101_s_frequency(struct file *file, void *priv,
- const struct v4l2_frequency *f)
-{
- struct msi3101_state *s = video_drvdata(file);
- int ret;
- dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d frequency=%u\n",
- __func__, f->tuner, f->type, f->frequency);
-
- if (f->tuner == 0) {
- s->f_adc = clamp_t(unsigned int, f->frequency,
- bands[0].rangelow,
- bands[0].rangehigh);
- dev_dbg(&s->udev->dev, "%s: ADC frequency=%u Hz\n",
- __func__, s->f_adc);
- ret = msi3101_set_usb_adc(s);
- } else if (f->tuner == 1) {
- ret = v4l2_subdev_call(s->v4l2_subdev, tuner, s_frequency, f);
- } else {
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int msi3101_enum_freq_bands(struct file *file, void *priv,
- struct v4l2_frequency_band *band)
-{
- struct msi3101_state *s = video_drvdata(file);
- int ret;
- dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d index=%d\n",
- __func__, band->tuner, band->type, band->index);
-
- if (band->tuner == 0) {
- if (band->index >= ARRAY_SIZE(bands)) {
- ret = -EINVAL;
- } else {
- *band = bands[band->index];
- ret = 0;
- }
- } else if (band->tuner == 1) {
- ret = v4l2_subdev_call(s->v4l2_subdev, tuner,
- enum_freq_bands, band);
- } else {
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static const struct v4l2_ioctl_ops msi3101_ioctl_ops = {
- .vidioc_querycap = msi3101_querycap,
-
- .vidioc_enum_fmt_sdr_cap = msi3101_enum_fmt_sdr_cap,
- .vidioc_g_fmt_sdr_cap = msi3101_g_fmt_sdr_cap,
- .vidioc_s_fmt_sdr_cap = msi3101_s_fmt_sdr_cap,
- .vidioc_try_fmt_sdr_cap = msi3101_try_fmt_sdr_cap,
-
- .vidioc_reqbufs = vb2_ioctl_reqbufs,
- .vidioc_create_bufs = vb2_ioctl_create_bufs,
- .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
- .vidioc_querybuf = vb2_ioctl_querybuf,
- .vidioc_qbuf = vb2_ioctl_qbuf,
- .vidioc_dqbuf = vb2_ioctl_dqbuf,
-
- .vidioc_streamon = vb2_ioctl_streamon,
- .vidioc_streamoff = vb2_ioctl_streamoff,
-
- .vidioc_g_tuner = msi3101_g_tuner,
- .vidioc_s_tuner = msi3101_s_tuner,
-
- .vidioc_g_frequency = msi3101_g_frequency,
- .vidioc_s_frequency = msi3101_s_frequency,
- .vidioc_enum_freq_bands = msi3101_enum_freq_bands,
-
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
- .vidioc_log_status = v4l2_ctrl_log_status,
-};
-
-static const struct v4l2_file_operations msi3101_fops = {
- .owner = THIS_MODULE,
- .open = v4l2_fh_open,
- .release = vb2_fop_release,
- .read = vb2_fop_read,
- .poll = vb2_fop_poll,
- .mmap = vb2_fop_mmap,
- .unlocked_ioctl = video_ioctl2,
-};
-
-static struct video_device msi3101_template = {
- .name = "Mirics MSi3101 SDR Dongle",
- .release = video_device_release_empty,
- .fops = &msi3101_fops,
- .ioctl_ops = &msi3101_ioctl_ops,
-};
-
-static void msi3101_video_release(struct v4l2_device *v)
-{
- struct msi3101_state *s =
- container_of(v, struct msi3101_state, v4l2_dev);
-
- v4l2_ctrl_handler_free(&s->hdl);
- v4l2_device_unregister(&s->v4l2_dev);
- kfree(s);
-}
-
-static int msi3101_transfer_one_message(struct spi_master *master,
- struct spi_message *m)
-{
- struct msi3101_state *s = spi_master_get_devdata(master);
- struct spi_transfer *t;
- int ret = 0;
- u32 data;
-
- list_for_each_entry(t, &m->transfers, transfer_list) {
- dev_dbg(&s->udev->dev, "%s: msg=%*ph\n",
- __func__, t->len, t->tx_buf);
- data = 0x09; /* reg 9 is SPI adapter */
- data |= ((u8 *)t->tx_buf)[0] << 8;
- data |= ((u8 *)t->tx_buf)[1] << 16;
- data |= ((u8 *)t->tx_buf)[2] << 24;
- ret = msi3101_ctrl_msg(s, CMD_WREG, data);
- }
-
- m->status = ret;
- spi_finalize_current_message(master);
- return ret;
-}
-
-static int msi3101_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev(intf);
- struct msi3101_state *s = NULL;
- struct v4l2_subdev *sd;
- struct spi_master *master;
- int ret;
- static struct spi_board_info board_info = {
- .modalias = "msi001",
- .bus_num = 0,
- .chip_select = 0,
- .max_speed_hz = 12000000,
- };
-
- s = kzalloc(sizeof(struct msi3101_state), GFP_KERNEL);
- if (s == NULL) {
- pr_err("Could not allocate memory for msi3101_state\n");
- return -ENOMEM;
- }
-
- mutex_init(&s->v4l2_lock);
- mutex_init(&s->vb_queue_lock);
- spin_lock_init(&s->queued_bufs_lock);
- INIT_LIST_HEAD(&s->queued_bufs);
- s->udev = udev;
- s->f_adc = bands[0].rangelow;
- s->pixelformat = V4L2_SDR_FMT_CU8;
-
- /* Init videobuf2 queue structure */
- s->vb_queue.type = V4L2_BUF_TYPE_SDR_CAPTURE;
- s->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
- s->vb_queue.drv_priv = s;
- s->vb_queue.buf_struct_size = sizeof(struct msi3101_frame_buf);
- s->vb_queue.ops = &msi3101_vb2_ops;
- s->vb_queue.mem_ops = &vb2_vmalloc_memops;
- s->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- ret = vb2_queue_init(&s->vb_queue);
- if (ret) {
- dev_err(&s->udev->dev, "Could not initialize vb2 queue\n");
- goto err_free_mem;
- }
-
- /* Init video_device structure */
- s->vdev = msi3101_template;
- s->vdev.queue = &s->vb_queue;
- s->vdev.queue->lock = &s->vb_queue_lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev.flags);
- video_set_drvdata(&s->vdev, s);
-
- /* Register the v4l2_device structure */
- s->v4l2_dev.release = msi3101_video_release;
- ret = v4l2_device_register(&intf->dev, &s->v4l2_dev);
- if (ret) {
- dev_err(&s->udev->dev,
- "Failed to register v4l2-device (%d)\n", ret);
- goto err_free_mem;
- }
-
- /* SPI master adapter */
- master = spi_alloc_master(&s->udev->dev, 0);
- if (master == NULL) {
- ret = -ENOMEM;
- goto err_unregister_v4l2_dev;
- }
-
- s->master = master;
- master->bus_num = 0;
- master->num_chipselect = 1;
- master->transfer_one_message = msi3101_transfer_one_message;
- spi_master_set_devdata(master, s);
- ret = spi_register_master(master);
- if (ret) {
- spi_master_put(master);
- goto err_unregister_v4l2_dev;
- }
-
- /* load v4l2 subdevice */
- sd = v4l2_spi_new_subdev(&s->v4l2_dev, master, &board_info);
- s->v4l2_subdev = sd;
- if (sd == NULL) {
- dev_err(&s->udev->dev, "cannot get v4l2 subdevice\n");
- ret = -ENODEV;
- goto err_unregister_master;
- }
-
- /* Register controls */
- v4l2_ctrl_handler_init(&s->hdl, 0);
- if (s->hdl.error) {
- ret = s->hdl.error;
- dev_err(&s->udev->dev, "Could not initialize controls\n");
- goto err_free_controls;
- }
-
- /* currently all controls are from subdev */
- v4l2_ctrl_add_handler(&s->hdl, sd->ctrl_handler, NULL);
-
- s->v4l2_dev.ctrl_handler = &s->hdl;
- s->vdev.v4l2_dev = &s->v4l2_dev;
- s->vdev.lock = &s->v4l2_lock;
-
- ret = video_register_device(&s->vdev, VFL_TYPE_SDR, -1);
- if (ret) {
- dev_err(&s->udev->dev,
- "Failed to register as video device (%d)\n",
- ret);
- goto err_unregister_v4l2_dev;
- }
- dev_info(&s->udev->dev, "Registered as %s\n",
- video_device_node_name(&s->vdev));
-
- return 0;
-
-err_free_controls:
- v4l2_ctrl_handler_free(&s->hdl);
-err_unregister_master:
- spi_unregister_master(s->master);
-err_unregister_v4l2_dev:
- v4l2_device_unregister(&s->v4l2_dev);
-err_free_mem:
- kfree(s);
- return ret;
-}
-
-/* USB device ID list */
-static struct usb_device_id msi3101_id_table[] = {
- { USB_DEVICE(0x1df7, 0x2500) }, /* Mirics MSi3101 SDR Dongle */
- { USB_DEVICE(0x2040, 0xd300) }, /* Hauppauge WinTV 133559 LF */
- { }
-};
-MODULE_DEVICE_TABLE(usb, msi3101_id_table);
-
-/* USB subsystem interface */
-static struct usb_driver msi3101_driver = {
- .name = KBUILD_MODNAME,
- .probe = msi3101_probe,
- .disconnect = msi3101_disconnect,
- .id_table = msi3101_id_table,
-};
-
-module_usb_driver(msi3101_driver);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Mirics MSi3101 SDR Dongle");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index 2e422dde074e..d548371db65a 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -1003,33 +1003,18 @@ static void iss_disable_clocks(struct iss_device *iss)
clk_disable(iss->iss_fck);
}
-static void iss_put_clocks(struct iss_device *iss)
-{
- if (iss->iss_fck) {
- clk_put(iss->iss_fck);
- iss->iss_fck = NULL;
- }
-
- if (iss->iss_ctrlclk) {
- clk_put(iss->iss_ctrlclk);
- iss->iss_ctrlclk = NULL;
- }
-}
-
static int iss_get_clocks(struct iss_device *iss)
{
- iss->iss_fck = clk_get(iss->dev, "iss_fck");
+ iss->iss_fck = devm_clk_get(iss->dev, "iss_fck");
if (IS_ERR(iss->iss_fck)) {
dev_err(iss->dev, "Unable to get iss_fck clock info\n");
- iss_put_clocks(iss);
return PTR_ERR(iss->iss_fck);
}
- iss->iss_ctrlclk = clk_get(iss->dev, "iss_ctrlclk");
+ iss->iss_ctrlclk = devm_clk_get(iss->dev, "iss_ctrlclk");
if (IS_ERR(iss->iss_ctrlclk)) {
dev_err(iss->dev, "Unable to get iss_ctrlclk clock info\n");
- iss_put_clocks(iss);
- return PTR_ERR(iss->iss_fck);
+ return PTR_ERR(iss->iss_ctrlclk);
}
return 0;
@@ -1104,29 +1089,11 @@ static int iss_map_mem_resource(struct platform_device *pdev,
{
struct resource *mem;
- /* request the mem region for the camera registers */
-
mem = platform_get_resource(pdev, IORESOURCE_MEM, res);
- if (!mem) {
- dev_err(iss->dev, "no mem resource?\n");
- return -ENODEV;
- }
- if (!request_mem_region(mem->start, resource_size(mem), pdev->name)) {
- dev_err(iss->dev,
- "cannot reserve camera register I/O region\n");
- return -ENODEV;
- }
- iss->res[res] = mem;
+ iss->regs[res] = devm_ioremap_resource(iss->dev, mem);
- /* map the region */
- iss->regs[res] = ioremap_nocache(mem->start, resource_size(mem));
- if (!iss->regs[res]) {
- dev_err(iss->dev, "cannot map camera register I/O region\n");
- return -ENODEV;
- }
-
- return 0;
+ return PTR_ERR_OR_ZERO(iss->regs[res]);
}
static void iss_unregister_entities(struct iss_device *iss)
@@ -1389,7 +1356,7 @@ static int iss_probe(struct platform_device *pdev)
if (pdata == NULL)
return -EINVAL;
- iss = kzalloc(sizeof(*iss), GFP_KERNEL);
+ iss = devm_kzalloc(&pdev->dev, sizeof(*iss), GFP_KERNEL);
if (!iss) {
dev_err(&pdev->dev, "Could not allocate memory\n");
return -ENOMEM;
@@ -1456,7 +1423,8 @@ static int iss_probe(struct platform_device *pdev)
goto error_iss;
}
- if (request_irq(iss->irq_num, iss_isr, IRQF_SHARED, "OMAP4 ISS", iss)) {
+ if (devm_request_irq(iss->dev, iss->irq_num, iss_isr, IRQF_SHARED,
+ "OMAP4 ISS", iss)) {
dev_err(iss->dev, "Unable to request IRQ\n");
ret = -EINVAL;
goto error_iss;
@@ -1465,7 +1433,7 @@ static int iss_probe(struct platform_device *pdev)
/* Entities */
ret = iss_initialize_modules(iss);
if (ret < 0)
- goto error_irq;
+ goto error_iss;
ret = iss_register_entities(iss);
if (ret < 0)
@@ -1477,29 +1445,12 @@ static int iss_probe(struct platform_device *pdev)
error_modules:
iss_cleanup_modules(iss);
-error_irq:
- free_irq(iss->irq_num, iss);
error_iss:
omap4iss_put(iss);
error:
- iss_put_clocks(iss);
-
- for (i = 0; i < OMAP4_ISS_MEM_LAST; i++) {
- if (iss->regs[i]) {
- iounmap(iss->regs[i]);
- iss->regs[i] = NULL;
- }
-
- if (iss->res[i]) {
- release_mem_region(iss->res[i]->start,
- resource_size(iss->res[i]));
- iss->res[i] = NULL;
- }
- }
platform_set_drvdata(pdev, NULL);
mutex_destroy(&iss->iss_mutex);
- kfree(iss);
return ret;
}
@@ -1507,29 +1458,10 @@ error:
static int iss_remove(struct platform_device *pdev)
{
struct iss_device *iss = platform_get_drvdata(pdev);
- unsigned int i;
iss_unregister_entities(iss);
iss_cleanup_modules(iss);
- free_irq(iss->irq_num, iss);
- iss_put_clocks(iss);
-
- for (i = 0; i < OMAP4_ISS_MEM_LAST; i++) {
- if (iss->regs[i]) {
- iounmap(iss->regs[i]);
- iss->regs[i] = NULL;
- }
-
- if (iss->res[i]) {
- release_mem_region(iss->res[i]->start,
- resource_size(iss->res[i]));
- iss->res[i] = NULL;
- }
- }
-
- kfree(iss);
-
return 0;
}
diff --git a/drivers/staging/media/omap4iss/iss.h b/drivers/staging/media/omap4iss/iss.h
index 05cd9bf3b41f..734cfeeb0314 100644
--- a/drivers/staging/media/omap4iss/iss.h
+++ b/drivers/staging/media/omap4iss/iss.h
@@ -97,7 +97,7 @@ struct iss_device {
u64 raw_dmamask;
struct mutex iss_mutex; /* For handling ref_count field */
- bool crashed;
+ unsigned int crashed;
int has_context;
int ref_count;
diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c
index bf8a65726107..9ae4871928d8 100644
--- a/drivers/staging/media/omap4iss/iss_csi2.c
+++ b/drivers/staging/media/omap4iss/iss_csi2.c
@@ -317,7 +317,7 @@ static void csi2_ctx_enable(struct iss_csi2_device *csi2, u8 ctxnum, u8 enable)
static void csi2_ctx_config(struct iss_csi2_device *csi2,
struct iss_csi2_ctx_cfg *ctx)
{
- u32 reg;
+ u32 reg = 0;
/* Set up CSI2_CTx_CTRL1 */
if (ctx->eof_enabled)
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
index cbf455d66f73..943b5b09c632 100644
--- a/drivers/staging/media/omap4iss/iss_video.c
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -25,6 +25,9 @@
#include "iss_video.h"
#include "iss.h"
+static unsigned debug;
+module_param(debug, uint, 0644);
+MODULE_PARM_DESC(debug, "activates debug info");
/* -----------------------------------------------------------------------------
* Helper functions
@@ -328,15 +331,6 @@ static int iss_video_buf_prepare(struct vb2_buffer *vb)
if (vb2_plane_size(vb, 0) < size)
return -ENOBUFS;
- /* Refuse to prepare the buffer is the video node has registered an
- * error. We don't need to take any lock here as the operation is
- * inherently racy. The authoritative check will be performed in the
- * queue handler, which can't return an error, this check is just a best
- * effort to notify userspace as early as possible.
- */
- if (unlikely(video->error))
- return -EIO;
-
addr = vb2_dma_contig_plane_dma_addr(vb, 0);
if (!IS_ALIGNED(addr, 32)) {
dev_dbg(video->iss->dev,
@@ -360,6 +354,11 @@ static void iss_video_buf_queue(struct vb2_buffer *vb)
spin_lock_irqsave(&video->qlock, flags);
+ /* Mark the buffer is faulty and give it back to the queue immediately
+ * if the video node has registered an error. vb2 will perform the same
+ * check when preparing the buffer, but that is inherently racy, so we
+ * need to handle the race condition with an authoritative check here.
+ */
if (unlikely(video->error)) {
vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
spin_unlock_irqrestore(&video->qlock, flags);
@@ -510,6 +509,7 @@ void omap4iss_video_cancel_stream(struct iss_video *video)
vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
}
+ vb2_queue_error(video->queue);
video->error = true;
spin_unlock_irqrestore(&video->qlock, flags);
@@ -895,7 +895,6 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
video->queue = &vfh->queue;
INIT_LIST_HEAD(&video->dmaqueue);
- spin_lock_init(&video->qlock);
video->error = false;
atomic_set(&pipe->frame_number, -1);
@@ -1044,6 +1043,8 @@ static int iss_video_open(struct file *file)
if (handle == NULL)
return -ENOMEM;
+ video->video.debug = debug;
+
v4l2_fh_init(&handle->vfh, &video->video);
v4l2_fh_add(&handle->vfh);
@@ -1175,6 +1176,7 @@ int omap4iss_video_init(struct iss_video *video, const char *name)
if (ret < 0)
return ret;
+ spin_lock_init(&video->qlock);
mutex_init(&video->mutex);
atomic_set(&video->active, 0);
diff --git a/drivers/staging/media/rtl2832u_sdr/Kconfig b/drivers/staging/media/rtl2832u_sdr/Kconfig
deleted file mode 100644
index 3ede5fe8f0a5..000000000000
--- a/drivers/staging/media/rtl2832u_sdr/Kconfig
+++ /dev/null
@@ -1,7 +0,0 @@
-config DVB_RTL2832_SDR
- tristate "Realtek RTL2832 SDR"
- depends on USB && DVB_CORE && I2C && VIDEO_V4L2 && DVB_USB_RTL28XXU
- select DVB_RTL2832
- select VIDEOBUF2_VMALLOC
- default m if !MEDIA_SUBDRV_AUTOSELECT
-
diff --git a/drivers/staging/media/rtl2832u_sdr/Makefile b/drivers/staging/media/rtl2832u_sdr/Makefile
deleted file mode 100644
index 7e00a0df4631..000000000000
--- a/drivers/staging/media/rtl2832u_sdr/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o
-
-ccflags-y += -Idrivers/media/dvb-core
-ccflags-y += -Idrivers/media/dvb-frontends
-ccflags-y += -Idrivers/media/tuners
-ccflags-y += -Idrivers/media/usb/dvb-usb-v2
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
deleted file mode 100644
index 093df6b6ae35..000000000000
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
+++ /dev/null
@@ -1,1497 +0,0 @@
-/*
- * Realtek RTL2832U SDR driver
- *
- * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * GNU Radio plugin "gr-kernel" for device usage will be on:
- * http://git.linuxtv.org/anttip/gr-kernel.git
- *
- */
-
-#include "dvb_frontend.h"
-#include "rtl2832_sdr.h"
-#include "dvb_usb.h"
-
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-event.h>
-#include <media/videobuf2-vmalloc.h>
-
-#include <linux/jiffies.h>
-#include <linux/math64.h>
-
-#define MAX_BULK_BUFS (10)
-#define BULK_BUFFER_SIZE (128 * 512)
-
-static const struct v4l2_frequency_band bands_adc[] = {
- {
- .tuner = 0,
- .type = V4L2_TUNER_ADC,
- .index = 0,
- .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
- .rangelow = 300000,
- .rangehigh = 300000,
- },
- {
- .tuner = 0,
- .type = V4L2_TUNER_ADC,
- .index = 1,
- .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
- .rangelow = 900001,
- .rangehigh = 2800000,
- },
- {
- .tuner = 0,
- .type = V4L2_TUNER_ADC,
- .index = 2,
- .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
- .rangelow = 3200000,
- .rangehigh = 3200000,
- },
-};
-
-static const struct v4l2_frequency_band bands_fm[] = {
- {
- .tuner = 1,
- .type = V4L2_TUNER_RF,
- .index = 0,
- .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
- .rangelow = 50000000,
- .rangehigh = 2000000000,
- },
-};
-
-/* stream formats */
-struct rtl2832_sdr_format {
- char *name;
- u32 pixelformat;
-};
-
-static struct rtl2832_sdr_format formats[] = {
- {
- .name = "IQ U8",
- .pixelformat = V4L2_SDR_FMT_CU8,
- }, {
- .name = "IQ U16LE (emulated)",
- .pixelformat = V4L2_SDR_FMT_CU16LE,
- },
-};
-
-static const unsigned int NUM_FORMATS = ARRAY_SIZE(formats);
-
-/* intermediate buffers with raw data from the USB device */
-struct rtl2832_sdr_frame_buf {
- struct vb2_buffer vb; /* common v4l buffer stuff -- must be first */
- struct list_head list;
-};
-
-struct rtl2832_sdr_state {
-#define POWER_ON (1 << 1)
-#define URB_BUF (1 << 2)
- unsigned long flags;
-
- const struct rtl2832_config *cfg;
- struct dvb_frontend *fe;
- struct dvb_usb_device *d;
- struct i2c_adapter *i2c;
- u8 bank;
-
- struct video_device vdev;
- struct v4l2_device v4l2_dev;
-
- /* videobuf2 queue and queued buffers list */
- struct vb2_queue vb_queue;
- struct list_head queued_bufs;
- spinlock_t queued_bufs_lock; /* Protects queued_bufs */
- unsigned sequence; /* buffer sequence counter */
-
- /* Note if taking both locks v4l2_lock must always be locked first! */
- struct mutex v4l2_lock; /* Protects everything else */
- struct mutex vb_queue_lock; /* Protects vb_queue and capt_file */
-
- /* Pointer to our usb_device, will be NULL after unplug */
- struct usb_device *udev; /* Both mutexes most be hold when setting! */
-
- unsigned int vb_full; /* vb is full and packets dropped */
-
- struct urb *urb_list[MAX_BULK_BUFS];
- int buf_num;
- unsigned long buf_size;
- u8 *buf_list[MAX_BULK_BUFS];
- dma_addr_t dma_addr[MAX_BULK_BUFS];
- int urbs_initialized;
- int urbs_submitted;
-
- unsigned int f_adc, f_tuner;
- u32 pixelformat;
-
- /* Controls */
- struct v4l2_ctrl_handler hdl;
- struct v4l2_ctrl *bandwidth_auto;
- struct v4l2_ctrl *bandwidth;
-
- /* for sample rate calc */
- unsigned int sample;
- unsigned int sample_measured;
- unsigned long jiffies_next;
-};
-
-/* write multiple hardware registers */
-static int rtl2832_sdr_wr(struct rtl2832_sdr_state *s, u8 reg, const u8 *val,
- int len)
-{
- int ret;
-#define MAX_WR_LEN 24
-#define MAX_WR_XFER_LEN (MAX_WR_LEN + 1)
- u8 buf[MAX_WR_XFER_LEN];
- struct i2c_msg msg[1] = {
- {
- .addr = s->cfg->i2c_addr,
- .flags = 0,
- .len = 1 + len,
- .buf = buf,
- }
- };
-
- if (WARN_ON(len > MAX_WR_LEN))
- return -EINVAL;
-
- buf[0] = reg;
- memcpy(&buf[1], val, len);
-
- ret = i2c_transfer(s->i2c, msg, 1);
- if (ret == 1) {
- ret = 0;
- } else {
- dev_err(&s->i2c->dev,
- "%s: I2C wr failed=%d reg=%02x len=%d\n",
- KBUILD_MODNAME, ret, reg, len);
- ret = -EREMOTEIO;
- }
- return ret;
-}
-
-/* read multiple hardware registers */
-static int rtl2832_sdr_rd(struct rtl2832_sdr_state *s, u8 reg, u8 *val, int len)
-{
- int ret;
- struct i2c_msg msg[2] = {
- {
- .addr = s->cfg->i2c_addr,
- .flags = 0,
- .len = 1,
- .buf = &reg,
- }, {
- .addr = s->cfg->i2c_addr,
- .flags = I2C_M_RD,
- .len = len,
- .buf = val,
- }
- };
-
- ret = i2c_transfer(s->i2c, msg, 2);
- if (ret == 2) {
- ret = 0;
- } else {
- dev_err(&s->i2c->dev,
- "%s: I2C rd failed=%d reg=%02x len=%d\n",
- KBUILD_MODNAME, ret, reg, len);
- ret = -EREMOTEIO;
- }
- return ret;
-}
-
-/* write multiple registers */
-static int rtl2832_sdr_wr_regs(struct rtl2832_sdr_state *s, u16 reg,
- const u8 *val, int len)
-{
- int ret;
- u8 reg2 = (reg >> 0) & 0xff;
- u8 bank = (reg >> 8) & 0xff;
-
- /* switch bank if needed */
- if (bank != s->bank) {
- ret = rtl2832_sdr_wr(s, 0x00, &bank, 1);
- if (ret)
- return ret;
-
- s->bank = bank;
- }
-
- return rtl2832_sdr_wr(s, reg2, val, len);
-}
-
-/* read multiple registers */
-static int rtl2832_sdr_rd_regs(struct rtl2832_sdr_state *s, u16 reg, u8 *val,
- int len)
-{
- int ret;
- u8 reg2 = (reg >> 0) & 0xff;
- u8 bank = (reg >> 8) & 0xff;
-
- /* switch bank if needed */
- if (bank != s->bank) {
- ret = rtl2832_sdr_wr(s, 0x00, &bank, 1);
- if (ret)
- return ret;
-
- s->bank = bank;
- }
-
- return rtl2832_sdr_rd(s, reg2, val, len);
-}
-
-/* write single register */
-static int rtl2832_sdr_wr_reg(struct rtl2832_sdr_state *s, u16 reg, u8 val)
-{
- return rtl2832_sdr_wr_regs(s, reg, &val, 1);
-}
-
-#if 0
-/* read single register */
-static int rtl2832_sdr_rd_reg(struct rtl2832_sdr_state *s, u16 reg, u8 *val)
-{
- return rtl2832_sdr_rd_regs(s, reg, val, 1);
-}
-#endif
-
-/* write single register with mask */
-static int rtl2832_sdr_wr_reg_mask(struct rtl2832_sdr_state *s, u16 reg,
- u8 val, u8 mask)
-{
- int ret;
- u8 tmp;
-
- /* no need for read if whole reg is written */
- if (mask != 0xff) {
- ret = rtl2832_sdr_rd_regs(s, reg, &tmp, 1);
- if (ret)
- return ret;
-
- val &= mask;
- tmp &= ~mask;
- val |= tmp;
- }
-
- return rtl2832_sdr_wr_regs(s, reg, &val, 1);
-}
-
-#if 0
-/* read single register with mask */
-static int rtl2832_sdr_rd_reg_mask(struct rtl2832_sdr_state *s, u16 reg,
- u8 *val, u8 mask)
-{
- int ret, i;
- u8 tmp;
-
- ret = rtl2832_sdr_rd_regs(s, reg, &tmp, 1);
- if (ret)
- return ret;
-
- tmp &= mask;
-
- /* find position of the first bit */
- for (i = 0; i < 8; i++) {
- if ((mask >> i) & 0x01)
- break;
- }
- *val = tmp >> i;
-
- return 0;
-}
-#endif
-
-/* Private functions */
-static struct rtl2832_sdr_frame_buf *rtl2832_sdr_get_next_fill_buf(
- struct rtl2832_sdr_state *s)
-{
- unsigned long flags = 0;
- struct rtl2832_sdr_frame_buf *buf = NULL;
-
- spin_lock_irqsave(&s->queued_bufs_lock, flags);
- if (list_empty(&s->queued_bufs))
- goto leave;
-
- buf = list_entry(s->queued_bufs.next,
- struct rtl2832_sdr_frame_buf, list);
- list_del(&buf->list);
-leave:
- spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
- return buf;
-}
-
-static unsigned int rtl2832_sdr_convert_stream(struct rtl2832_sdr_state *s,
- void *dst, const u8 *src, unsigned int src_len)
-{
- unsigned int dst_len;
-
- if (s->pixelformat == V4L2_SDR_FMT_CU8) {
- /* native stream, no need to convert */
- memcpy(dst, src, src_len);
- dst_len = src_len;
- } else if (s->pixelformat == V4L2_SDR_FMT_CU16LE) {
- /* convert u8 to u16 */
- unsigned int i;
- u16 *u16dst = dst;
- for (i = 0; i < src_len; i++)
- *u16dst++ = (src[i] << 8) | (src[i] >> 0);
- dst_len = 2 * src_len;
- } else {
- dst_len = 0;
- }
-
- /* calculate samping rate and output it in 10 seconds intervals */
- if (unlikely(time_is_before_jiffies(s->jiffies_next))) {
-#define MSECS 10000UL
- unsigned int samples = s->sample - s->sample_measured;
- s->jiffies_next = jiffies + msecs_to_jiffies(MSECS);
- s->sample_measured = s->sample;
- dev_dbg(&s->udev->dev,
- "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
- src_len, samples, MSECS,
- samples * 1000UL / MSECS);
- }
-
- /* total number of I+Q pairs */
- s->sample += src_len / 2;
-
- return dst_len;
-}
-
-/*
- * This gets called for the bulk stream pipe. This is done in interrupt
- * time, so it has to be fast, not crash, and not stall. Neat.
- */
-static void rtl2832_sdr_urb_complete(struct urb *urb)
-{
- struct rtl2832_sdr_state *s = urb->context;
- struct rtl2832_sdr_frame_buf *fbuf;
-
- dev_dbg_ratelimited(&s->udev->dev,
- "%s: status=%d length=%d/%d errors=%d\n",
- __func__, urb->status, urb->actual_length,
- urb->transfer_buffer_length, urb->error_count);
-
- switch (urb->status) {
- case 0: /* success */
- case -ETIMEDOUT: /* NAK */
- break;
- case -ECONNRESET: /* kill */
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- default: /* error */
- dev_err_ratelimited(&s->udev->dev, "urb failed=%d\n",
- urb->status);
- break;
- }
-
- if (likely(urb->actual_length > 0)) {
- void *ptr;
- unsigned int len;
- /* get free framebuffer */
- fbuf = rtl2832_sdr_get_next_fill_buf(s);
- if (unlikely(fbuf == NULL)) {
- s->vb_full++;
- dev_notice_ratelimited(&s->udev->dev,
- "videobuf is full, %d packets dropped\n",
- s->vb_full);
- goto skip;
- }
-
- /* fill framebuffer */
- ptr = vb2_plane_vaddr(&fbuf->vb, 0);
- len = rtl2832_sdr_convert_stream(s, ptr, urb->transfer_buffer,
- urb->actual_length);
- vb2_set_plane_payload(&fbuf->vb, 0, len);
- v4l2_get_timestamp(&fbuf->vb.v4l2_buf.timestamp);
- fbuf->vb.v4l2_buf.sequence = s->sequence++;
- vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE);
- }
-skip:
- usb_submit_urb(urb, GFP_ATOMIC);
-}
-
-static int rtl2832_sdr_kill_urbs(struct rtl2832_sdr_state *s)
-{
- int i;
-
- for (i = s->urbs_submitted - 1; i >= 0; i--) {
- dev_dbg(&s->udev->dev, "%s: kill urb=%d\n", __func__, i);
- /* stop the URB */
- usb_kill_urb(s->urb_list[i]);
- }
- s->urbs_submitted = 0;
-
- return 0;
-}
-
-static int rtl2832_sdr_submit_urbs(struct rtl2832_sdr_state *s)
-{
- int i, ret;
-
- for (i = 0; i < s->urbs_initialized; i++) {
- dev_dbg(&s->udev->dev, "%s: submit urb=%d\n", __func__, i);
- ret = usb_submit_urb(s->urb_list[i], GFP_ATOMIC);
- if (ret) {
- dev_err(&s->udev->dev,
- "Could not submit urb no. %d - get them all back\n",
- i);
- rtl2832_sdr_kill_urbs(s);
- return ret;
- }
- s->urbs_submitted++;
- }
-
- return 0;
-}
-
-static int rtl2832_sdr_free_stream_bufs(struct rtl2832_sdr_state *s)
-{
- if (s->flags & USB_STATE_URB_BUF) {
- while (s->buf_num) {
- s->buf_num--;
- dev_dbg(&s->udev->dev, "%s: free buf=%d\n",
- __func__, s->buf_num);
- usb_free_coherent(s->udev, s->buf_size,
- s->buf_list[s->buf_num],
- s->dma_addr[s->buf_num]);
- }
- }
- s->flags &= ~USB_STATE_URB_BUF;
-
- return 0;
-}
-
-static int rtl2832_sdr_alloc_stream_bufs(struct rtl2832_sdr_state *s)
-{
- s->buf_num = 0;
- s->buf_size = BULK_BUFFER_SIZE;
-
- dev_dbg(&s->udev->dev,
- "%s: all in all I will use %u bytes for streaming\n",
- __func__, MAX_BULK_BUFS * BULK_BUFFER_SIZE);
-
- for (s->buf_num = 0; s->buf_num < MAX_BULK_BUFS; s->buf_num++) {
- s->buf_list[s->buf_num] = usb_alloc_coherent(s->udev,
- BULK_BUFFER_SIZE, GFP_ATOMIC,
- &s->dma_addr[s->buf_num]);
- if (!s->buf_list[s->buf_num]) {
- dev_dbg(&s->udev->dev, "%s: alloc buf=%d failed\n",
- __func__, s->buf_num);
- rtl2832_sdr_free_stream_bufs(s);
- return -ENOMEM;
- }
-
- dev_dbg(&s->udev->dev, "%s: alloc buf=%d %p (dma %llu)\n",
- __func__, s->buf_num,
- s->buf_list[s->buf_num],
- (long long)s->dma_addr[s->buf_num]);
- s->flags |= USB_STATE_URB_BUF;
- }
-
- return 0;
-}
-
-static int rtl2832_sdr_free_urbs(struct rtl2832_sdr_state *s)
-{
- int i;
-
- rtl2832_sdr_kill_urbs(s);
-
- for (i = s->urbs_initialized - 1; i >= 0; i--) {
- if (s->urb_list[i]) {
- dev_dbg(&s->udev->dev, "%s: free urb=%d\n",
- __func__, i);
- /* free the URBs */
- usb_free_urb(s->urb_list[i]);
- }
- }
- s->urbs_initialized = 0;
-
- return 0;
-}
-
-static int rtl2832_sdr_alloc_urbs(struct rtl2832_sdr_state *s)
-{
- int i, j;
-
- /* allocate the URBs */
- for (i = 0; i < MAX_BULK_BUFS; i++) {
- dev_dbg(&s->udev->dev, "%s: alloc urb=%d\n", __func__, i);
- s->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
- if (!s->urb_list[i]) {
- dev_dbg(&s->udev->dev, "%s: failed\n", __func__);
- for (j = 0; j < i; j++)
- usb_free_urb(s->urb_list[j]);
- return -ENOMEM;
- }
- usb_fill_bulk_urb(s->urb_list[i],
- s->udev,
- usb_rcvbulkpipe(s->udev, 0x81),
- s->buf_list[i],
- BULK_BUFFER_SIZE,
- rtl2832_sdr_urb_complete, s);
-
- s->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
- s->urb_list[i]->transfer_dma = s->dma_addr[i];
- s->urbs_initialized++;
- }
-
- return 0;
-}
-
-/* Must be called with vb_queue_lock hold */
-static void rtl2832_sdr_cleanup_queued_bufs(struct rtl2832_sdr_state *s)
-{
- unsigned long flags = 0;
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- spin_lock_irqsave(&s->queued_bufs_lock, flags);
- while (!list_empty(&s->queued_bufs)) {
- struct rtl2832_sdr_frame_buf *buf;
- buf = list_entry(s->queued_bufs.next,
- struct rtl2832_sdr_frame_buf, list);
- list_del(&buf->list);
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
- }
- spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
-}
-
-/* The user yanked out the cable... */
-static void rtl2832_sdr_release_sec(struct dvb_frontend *fe)
-{
- struct rtl2832_sdr_state *s = fe->sec_priv;
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- mutex_lock(&s->vb_queue_lock);
- mutex_lock(&s->v4l2_lock);
- /* No need to keep the urbs around after disconnection */
- s->udev = NULL;
-
- v4l2_device_disconnect(&s->v4l2_dev);
- video_unregister_device(&s->vdev);
- mutex_unlock(&s->v4l2_lock);
- mutex_unlock(&s->vb_queue_lock);
-
- v4l2_device_put(&s->v4l2_dev);
-
- fe->sec_priv = NULL;
-}
-
-static int rtl2832_sdr_querycap(struct file *file, void *fh,
- struct v4l2_capability *cap)
-{
- struct rtl2832_sdr_state *s = video_drvdata(file);
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
- strlcpy(cap->card, s->vdev.name, sizeof(cap->card));
- usb_make_path(s->udev, cap->bus_info, sizeof(cap->bus_info));
- cap->device_caps = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_STREAMING |
- V4L2_CAP_READWRITE | V4L2_CAP_TUNER;
- cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
- return 0;
-}
-
-/* Videobuf2 operations */
-static int rtl2832_sdr_queue_setup(struct vb2_queue *vq,
- const struct v4l2_format *fmt, unsigned int *nbuffers,
- unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
-{
- struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
- dev_dbg(&s->udev->dev, "%s: *nbuffers=%d\n", __func__, *nbuffers);
-
- /* Need at least 8 buffers */
- if (vq->num_buffers + *nbuffers < 8)
- *nbuffers = 8 - vq->num_buffers;
- *nplanes = 1;
- /* 2 = max 16-bit sample returned */
- sizes[0] = PAGE_ALIGN(BULK_BUFFER_SIZE * 2);
- dev_dbg(&s->udev->dev, "%s: nbuffers=%d sizes[0]=%d\n",
- __func__, *nbuffers, sizes[0]);
- return 0;
-}
-
-static int rtl2832_sdr_buf_prepare(struct vb2_buffer *vb)
-{
- struct rtl2832_sdr_state *s = vb2_get_drv_priv(vb->vb2_queue);
-
- /* Don't allow queing new buffers after device disconnection */
- if (!s->udev)
- return -ENODEV;
-
- return 0;
-}
-
-static void rtl2832_sdr_buf_queue(struct vb2_buffer *vb)
-{
- struct rtl2832_sdr_state *s = vb2_get_drv_priv(vb->vb2_queue);
- struct rtl2832_sdr_frame_buf *buf =
- container_of(vb, struct rtl2832_sdr_frame_buf, vb);
- unsigned long flags = 0;
-
- /* Check the device has not disconnected between prep and queuing */
- if (!s->udev) {
- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
- return;
- }
-
- spin_lock_irqsave(&s->queued_bufs_lock, flags);
- list_add_tail(&buf->list, &s->queued_bufs);
- spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
-}
-
-static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
-{
- struct dvb_frontend *fe = s->fe;
- int ret;
- unsigned int f_sr, f_if;
- u8 buf[4], u8tmp1, u8tmp2;
- u64 u64tmp;
- u32 u32tmp;
- dev_dbg(&s->udev->dev, "%s: f_adc=%u\n", __func__, s->f_adc);
-
- if (!test_bit(POWER_ON, &s->flags))
- return 0;
-
- if (s->f_adc == 0)
- return 0;
-
- f_sr = s->f_adc;
-
- ret = rtl2832_sdr_wr_regs(s, 0x13e, "\x00\x00", 2);
- if (ret)
- goto err;
-
- ret = rtl2832_sdr_wr_regs(s, 0x115, "\x00\x00\x00\x00", 4);
- if (ret)
- goto err;
-
- /* get IF from tuner */
- if (fe->ops.tuner_ops.get_if_frequency)
- ret = fe->ops.tuner_ops.get_if_frequency(fe, &f_if);
- else
- ret = -EINVAL;
-
- if (ret)
- goto err;
-
- /* program IF */
- u64tmp = f_if % s->cfg->xtal;
- u64tmp *= 0x400000;
- u64tmp = div_u64(u64tmp, s->cfg->xtal);
- u64tmp = -u64tmp;
- u32tmp = u64tmp & 0x3fffff;
-
- dev_dbg(&s->udev->dev, "%s: f_if=%u if_ctl=%08x\n",
- __func__, f_if, u32tmp);
-
- buf[0] = (u32tmp >> 16) & 0xff;
- buf[1] = (u32tmp >> 8) & 0xff;
- buf[2] = (u32tmp >> 0) & 0xff;
-
- ret = rtl2832_sdr_wr_regs(s, 0x119, buf, 3);
- if (ret)
- goto err;
-
- /* BB / IF mode */
- /* POR: 0x1b1=0x1f, 0x008=0x0d, 0x006=0x80 */
- if (f_if) {
- u8tmp1 = 0x1a; /* disable Zero-IF */
- u8tmp2 = 0x8d; /* enable ADC I */
- } else {
- u8tmp1 = 0x1b; /* enable Zero-IF, DC, IQ */
- u8tmp2 = 0xcd; /* enable ADC I, ADC Q */
- }
-
- ret = rtl2832_sdr_wr_reg(s, 0x1b1, u8tmp1);
- if (ret)
- goto err;
-
- ret = rtl2832_sdr_wr_reg(s, 0x008, u8tmp2);
- if (ret)
- goto err;
-
- ret = rtl2832_sdr_wr_reg(s, 0x006, 0x80);
- if (ret)
- goto err;
-
- /* program sampling rate (resampling down) */
- u32tmp = div_u64(s->cfg->xtal * 0x400000ULL, f_sr * 4U);
- u32tmp <<= 2;
- buf[0] = (u32tmp >> 24) & 0xff;
- buf[1] = (u32tmp >> 16) & 0xff;
- buf[2] = (u32tmp >> 8) & 0xff;
- buf[3] = (u32tmp >> 0) & 0xff;
- ret = rtl2832_sdr_wr_regs(s, 0x19f, buf, 4);
- if (ret)
- goto err;
-
- /* low-pass filter */
- ret = rtl2832_sdr_wr_regs(s, 0x11c,
- "\xca\xdc\xd7\xd8\xe0\xf2\x0e\x35\x06\x50\x9c\x0d\x71\x11\x14\x71\x74\x19\x41\xa5",
- 20);
- if (ret)
- goto err;
-
- ret = rtl2832_sdr_wr_regs(s, 0x017, "\x11\x10", 2);
- if (ret)
- goto err;
-
- /* mode */
- ret = rtl2832_sdr_wr_regs(s, 0x019, "\x05", 1);
- if (ret)
- goto err;
-
- ret = rtl2832_sdr_wr_regs(s, 0x01a, "\x1b\x16\x0d\x06\x01\xff", 6);
- if (ret)
- goto err;
-
- /* FSM */
- ret = rtl2832_sdr_wr_regs(s, 0x192, "\x00\xf0\x0f", 3);
- if (ret)
- goto err;
-
- /* PID filter */
- ret = rtl2832_sdr_wr_regs(s, 0x061, "\x60", 1);
- if (ret)
- goto err;
-
- /* used RF tuner based settings */
- switch (s->cfg->tuner) {
- case RTL2832_TUNER_E4000:
- ret = rtl2832_sdr_wr_regs(s, 0x112, "\x5a", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x102, "\x40", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x103, "\x5a", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1c7, "\x30", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x104, "\xd0", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x105, "\xbe", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1c8, "\x18", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x106, "\x35", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1c9, "\x21", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1ca, "\x21", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1cb, "\x00", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x107, "\x40", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1cd, "\x10", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1ce, "\x10", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x108, "\x80", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x109, "\x7f", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x10a, "\x80", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x10b, "\x7f", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x011, "\xd4", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1e5, "\xf0", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1d9, "\x00", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1db, "\x00", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1dd, "\x14", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1de, "\xec", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1d8, "\x0c", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1e6, "\x02", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1d7, "\x09", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x00d, "\x83", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x010, "\x49", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x00d, "\x87", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x00d, "\x85", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x013, "\x02", 1);
- break;
- case RTL2832_TUNER_FC0012:
- case RTL2832_TUNER_FC0013:
- ret = rtl2832_sdr_wr_regs(s, 0x112, "\x5a", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x102, "\x40", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x103, "\x5a", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1c7, "\x2c", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x104, "\xcc", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x105, "\xbe", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1c8, "\x16", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x106, "\x35", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1c9, "\x21", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1ca, "\x21", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1cb, "\x00", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x107, "\x40", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1cd, "\x10", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1ce, "\x10", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x108, "\x80", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x109, "\x7f", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x10a, "\x80", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x10b, "\x7f", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x011, "\xe9\xbf", 2);
- ret = rtl2832_sdr_wr_regs(s, 0x1e5, "\xf0", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1d9, "\x00", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1db, "\x00", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1dd, "\x11", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1de, "\xef", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1d8, "\x0c", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1e6, "\x02", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1d7, "\x09", 1);
- break;
- case RTL2832_TUNER_R820T:
- ret = rtl2832_sdr_wr_regs(s, 0x112, "\x5a", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x102, "\x40", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x115, "\x01", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x103, "\x80", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1c7, "\x24", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x104, "\xcc", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x105, "\xbe", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1c8, "\x14", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x106, "\x35", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1c9, "\x21", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1ca, "\x21", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1cb, "\x00", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x107, "\x40", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1cd, "\x10", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1ce, "\x10", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x108, "\x80", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x109, "\x7f", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x10a, "\x80", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x10b, "\x7f", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x011, "\xf4", 1);
- break;
- default:
- dev_notice(&s->udev->dev, "Unsupported tuner\n");
- }
-
- /* software reset */
- ret = rtl2832_sdr_wr_reg_mask(s, 0x101, 0x04, 0x04);
- if (ret)
- goto err;
-
- ret = rtl2832_sdr_wr_reg_mask(s, 0x101, 0x00, 0x04);
- if (ret)
- goto err;
-err:
- return ret;
-};
-
-static void rtl2832_sdr_unset_adc(struct rtl2832_sdr_state *s)
-{
- int ret;
-
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- /* PID filter */
- ret = rtl2832_sdr_wr_regs(s, 0x061, "\xe0", 1);
- if (ret)
- goto err;
-
- /* mode */
- ret = rtl2832_sdr_wr_regs(s, 0x019, "\x20", 1);
- if (ret)
- goto err;
-
- ret = rtl2832_sdr_wr_regs(s, 0x017, "\x11\x10", 2);
- if (ret)
- goto err;
-
- /* FSM */
- ret = rtl2832_sdr_wr_regs(s, 0x192, "\x00\x0f\xff", 3);
- if (ret)
- goto err;
-
- ret = rtl2832_sdr_wr_regs(s, 0x13e, "\x40\x00", 2);
- if (ret)
- goto err;
-
- ret = rtl2832_sdr_wr_regs(s, 0x115, "\x06\x3f\xce\xcc", 4);
- if (ret)
- goto err;
-err:
- return;
-};
-
-static int rtl2832_sdr_set_tuner_freq(struct rtl2832_sdr_state *s)
-{
- struct dvb_frontend *fe = s->fe;
- struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- struct v4l2_ctrl *bandwidth_auto;
- struct v4l2_ctrl *bandwidth;
-
- /*
- * tuner RF (Hz)
- */
- if (s->f_tuner == 0)
- return 0;
-
- /*
- * bandwidth (Hz)
- */
- bandwidth_auto = v4l2_ctrl_find(&s->hdl, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO);
- bandwidth = v4l2_ctrl_find(&s->hdl, V4L2_CID_RF_TUNER_BANDWIDTH);
- if (v4l2_ctrl_g_ctrl(bandwidth_auto)) {
- c->bandwidth_hz = s->f_adc;
- v4l2_ctrl_s_ctrl(bandwidth, s->f_adc);
- } else {
- c->bandwidth_hz = v4l2_ctrl_g_ctrl(bandwidth);
- }
-
- c->frequency = s->f_tuner;
- c->delivery_system = SYS_DVBT;
-
- dev_dbg(&s->udev->dev, "%s: frequency=%u bandwidth=%d\n",
- __func__, c->frequency, c->bandwidth_hz);
-
- if (!test_bit(POWER_ON, &s->flags))
- return 0;
-
- if (fe->ops.tuner_ops.set_params)
- fe->ops.tuner_ops.set_params(fe);
-
- return 0;
-};
-
-static int rtl2832_sdr_set_tuner(struct rtl2832_sdr_state *s)
-{
- struct dvb_frontend *fe = s->fe;
-
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- if (fe->ops.tuner_ops.init)
- fe->ops.tuner_ops.init(fe);
-
- return 0;
-};
-
-static void rtl2832_sdr_unset_tuner(struct rtl2832_sdr_state *s)
-{
- struct dvb_frontend *fe = s->fe;
-
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- if (fe->ops.tuner_ops.sleep)
- fe->ops.tuner_ops.sleep(fe);
-
- return;
-};
-
-static int rtl2832_sdr_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
- struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
- int ret;
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- if (!s->udev)
- return -ENODEV;
-
- if (mutex_lock_interruptible(&s->v4l2_lock))
- return -ERESTARTSYS;
-
- if (s->d->props->power_ctrl)
- s->d->props->power_ctrl(s->d, 1);
-
- set_bit(POWER_ON, &s->flags);
-
- ret = rtl2832_sdr_set_tuner(s);
- if (ret)
- goto err;
-
- ret = rtl2832_sdr_set_tuner_freq(s);
- if (ret)
- goto err;
-
- ret = rtl2832_sdr_set_adc(s);
- if (ret)
- goto err;
-
- ret = rtl2832_sdr_alloc_stream_bufs(s);
- if (ret)
- goto err;
-
- ret = rtl2832_sdr_alloc_urbs(s);
- if (ret)
- goto err;
-
- s->sequence = 0;
-
- ret = rtl2832_sdr_submit_urbs(s);
- if (ret)
- goto err;
-
-err:
- mutex_unlock(&s->v4l2_lock);
-
- return ret;
-}
-
-static void rtl2832_sdr_stop_streaming(struct vb2_queue *vq)
-{
- struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- mutex_lock(&s->v4l2_lock);
-
- rtl2832_sdr_kill_urbs(s);
- rtl2832_sdr_free_urbs(s);
- rtl2832_sdr_free_stream_bufs(s);
- rtl2832_sdr_cleanup_queued_bufs(s);
- rtl2832_sdr_unset_adc(s);
- rtl2832_sdr_unset_tuner(s);
-
- clear_bit(POWER_ON, &s->flags);
-
- if (s->d->props->power_ctrl)
- s->d->props->power_ctrl(s->d, 0);
-
- mutex_unlock(&s->v4l2_lock);
-}
-
-static struct vb2_ops rtl2832_sdr_vb2_ops = {
- .queue_setup = rtl2832_sdr_queue_setup,
- .buf_prepare = rtl2832_sdr_buf_prepare,
- .buf_queue = rtl2832_sdr_buf_queue,
- .start_streaming = rtl2832_sdr_start_streaming,
- .stop_streaming = rtl2832_sdr_stop_streaming,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
-};
-
-static int rtl2832_sdr_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *v)
-{
- struct rtl2832_sdr_state *s = video_drvdata(file);
- dev_dbg(&s->udev->dev, "%s: index=%d type=%d\n",
- __func__, v->index, v->type);
-
- if (v->index == 0) {
- strlcpy(v->name, "ADC: Realtek RTL2832", sizeof(v->name));
- v->type = V4L2_TUNER_ADC;
- v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
- v->rangelow = 300000;
- v->rangehigh = 3200000;
- } else if (v->index == 1) {
- strlcpy(v->name, "RF: <unknown>", sizeof(v->name));
- v->type = V4L2_TUNER_RF;
- v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
- v->rangelow = 50000000;
- v->rangehigh = 2000000000;
- } else {
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int rtl2832_sdr_s_tuner(struct file *file, void *priv,
- const struct v4l2_tuner *v)
-{
- struct rtl2832_sdr_state *s = video_drvdata(file);
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- if (v->index > 1)
- return -EINVAL;
- return 0;
-}
-
-static int rtl2832_sdr_enum_freq_bands(struct file *file, void *priv,
- struct v4l2_frequency_band *band)
-{
- struct rtl2832_sdr_state *s = video_drvdata(file);
- dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d index=%d\n",
- __func__, band->tuner, band->type, band->index);
-
- if (band->tuner == 0) {
- if (band->index >= ARRAY_SIZE(bands_adc))
- return -EINVAL;
-
- *band = bands_adc[band->index];
- } else if (band->tuner == 1) {
- if (band->index >= ARRAY_SIZE(bands_fm))
- return -EINVAL;
-
- *band = bands_fm[band->index];
- } else {
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int rtl2832_sdr_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct rtl2832_sdr_state *s = video_drvdata(file);
- int ret = 0;
- dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d\n",
- __func__, f->tuner, f->type);
-
- if (f->tuner == 0) {
- f->frequency = s->f_adc;
- f->type = V4L2_TUNER_ADC;
- } else if (f->tuner == 1) {
- f->frequency = s->f_tuner;
- f->type = V4L2_TUNER_RF;
- } else {
- return -EINVAL;
- }
-
- return ret;
-}
-
-static int rtl2832_sdr_s_frequency(struct file *file, void *priv,
- const struct v4l2_frequency *f)
-{
- struct rtl2832_sdr_state *s = video_drvdata(file);
- int ret, band;
-
- dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d frequency=%u\n",
- __func__, f->tuner, f->type, f->frequency);
-
- /* ADC band midpoints */
- #define BAND_ADC_0 ((bands_adc[0].rangehigh + bands_adc[1].rangelow) / 2)
- #define BAND_ADC_1 ((bands_adc[1].rangehigh + bands_adc[2].rangelow) / 2)
-
- if (f->tuner == 0 && f->type == V4L2_TUNER_ADC) {
- if (f->frequency < BAND_ADC_0)
- band = 0;
- else if (f->frequency < BAND_ADC_1)
- band = 1;
- else
- band = 2;
-
- s->f_adc = clamp_t(unsigned int, f->frequency,
- bands_adc[band].rangelow,
- bands_adc[band].rangehigh);
-
- dev_dbg(&s->udev->dev, "%s: ADC frequency=%u Hz\n",
- __func__, s->f_adc);
- ret = rtl2832_sdr_set_adc(s);
- } else if (f->tuner == 1) {
- s->f_tuner = clamp_t(unsigned int, f->frequency,
- bands_fm[0].rangelow,
- bands_fm[0].rangehigh);
- dev_dbg(&s->udev->dev, "%s: RF frequency=%u Hz\n",
- __func__, f->frequency);
-
- ret = rtl2832_sdr_set_tuner_freq(s);
- } else {
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int rtl2832_sdr_enum_fmt_sdr_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct rtl2832_sdr_state *s = video_drvdata(file);
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- if (f->index >= NUM_FORMATS)
- return -EINVAL;
-
- strlcpy(f->description, formats[f->index].name, sizeof(f->description));
- f->pixelformat = formats[f->index].pixelformat;
-
- return 0;
-}
-
-static int rtl2832_sdr_g_fmt_sdr_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct rtl2832_sdr_state *s = video_drvdata(file);
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- f->fmt.sdr.pixelformat = s->pixelformat;
- memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
-
- return 0;
-}
-
-static int rtl2832_sdr_s_fmt_sdr_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct rtl2832_sdr_state *s = video_drvdata(file);
- struct vb2_queue *q = &s->vb_queue;
- int i;
- dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
- (char *)&f->fmt.sdr.pixelformat);
-
- if (vb2_is_busy(q))
- return -EBUSY;
-
- memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
- for (i = 0; i < NUM_FORMATS; i++) {
- if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
- s->pixelformat = f->fmt.sdr.pixelformat;
- return 0;
- }
- }
-
- f->fmt.sdr.pixelformat = formats[0].pixelformat;
- s->pixelformat = formats[0].pixelformat;
-
- return 0;
-}
-
-static int rtl2832_sdr_try_fmt_sdr_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct rtl2832_sdr_state *s = video_drvdata(file);
- int i;
- dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
- (char *)&f->fmt.sdr.pixelformat);
-
- memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
- for (i = 0; i < NUM_FORMATS; i++) {
- if (formats[i].pixelformat == f->fmt.sdr.pixelformat)
- return 0;
- }
-
- f->fmt.sdr.pixelformat = formats[0].pixelformat;
-
- return 0;
-}
-
-static const struct v4l2_ioctl_ops rtl2832_sdr_ioctl_ops = {
- .vidioc_querycap = rtl2832_sdr_querycap,
-
- .vidioc_enum_fmt_sdr_cap = rtl2832_sdr_enum_fmt_sdr_cap,
- .vidioc_g_fmt_sdr_cap = rtl2832_sdr_g_fmt_sdr_cap,
- .vidioc_s_fmt_sdr_cap = rtl2832_sdr_s_fmt_sdr_cap,
- .vidioc_try_fmt_sdr_cap = rtl2832_sdr_try_fmt_sdr_cap,
-
- .vidioc_reqbufs = vb2_ioctl_reqbufs,
- .vidioc_create_bufs = vb2_ioctl_create_bufs,
- .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
- .vidioc_querybuf = vb2_ioctl_querybuf,
- .vidioc_qbuf = vb2_ioctl_qbuf,
- .vidioc_dqbuf = vb2_ioctl_dqbuf,
-
- .vidioc_streamon = vb2_ioctl_streamon,
- .vidioc_streamoff = vb2_ioctl_streamoff,
-
- .vidioc_g_tuner = rtl2832_sdr_g_tuner,
- .vidioc_s_tuner = rtl2832_sdr_s_tuner,
-
- .vidioc_enum_freq_bands = rtl2832_sdr_enum_freq_bands,
- .vidioc_g_frequency = rtl2832_sdr_g_frequency,
- .vidioc_s_frequency = rtl2832_sdr_s_frequency,
-
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
- .vidioc_log_status = v4l2_ctrl_log_status,
-};
-
-static const struct v4l2_file_operations rtl2832_sdr_fops = {
- .owner = THIS_MODULE,
- .open = v4l2_fh_open,
- .release = vb2_fop_release,
- .read = vb2_fop_read,
- .poll = vb2_fop_poll,
- .mmap = vb2_fop_mmap,
- .unlocked_ioctl = video_ioctl2,
-};
-
-static struct video_device rtl2832_sdr_template = {
- .name = "Realtek RTL2832 SDR",
- .release = video_device_release_empty,
- .fops = &rtl2832_sdr_fops,
- .ioctl_ops = &rtl2832_sdr_ioctl_ops,
-};
-
-static int rtl2832_sdr_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct rtl2832_sdr_state *s =
- container_of(ctrl->handler, struct rtl2832_sdr_state,
- hdl);
- struct dvb_frontend *fe = s->fe;
- struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- int ret;
- dev_dbg(&s->udev->dev,
- "%s: id=%d name=%s val=%d min=%d max=%d step=%d\n",
- __func__, ctrl->id, ctrl->name, ctrl->val,
- ctrl->minimum, ctrl->maximum, ctrl->step);
-
- switch (ctrl->id) {
- case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO:
- case V4L2_CID_RF_TUNER_BANDWIDTH:
- /* TODO: these controls should be moved to tuner drivers */
- if (s->bandwidth_auto->val) {
- /* Round towards the closest legal value */
- s32 val = s->f_adc + s->bandwidth->step / 2;
- u32 offset;
- val = clamp(val, s->bandwidth->minimum, s->bandwidth->maximum);
- offset = val - s->bandwidth->minimum;
- offset = s->bandwidth->step * (offset / s->bandwidth->step);
- s->bandwidth->val = s->bandwidth->minimum + offset;
- }
-
- c->bandwidth_hz = s->bandwidth->val;
-
- if (!test_bit(POWER_ON, &s->flags))
- return 0;
-
- if (fe->ops.tuner_ops.set_params)
- ret = fe->ops.tuner_ops.set_params(fe);
- else
- ret = 0;
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static const struct v4l2_ctrl_ops rtl2832_sdr_ctrl_ops = {
- .s_ctrl = rtl2832_sdr_s_ctrl,
-};
-
-static void rtl2832_sdr_video_release(struct v4l2_device *v)
-{
- struct rtl2832_sdr_state *s =
- container_of(v, struct rtl2832_sdr_state, v4l2_dev);
-
- v4l2_ctrl_handler_free(&s->hdl);
- v4l2_device_unregister(&s->v4l2_dev);
- kfree(s);
-}
-
-struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c, const struct rtl2832_config *cfg,
- struct v4l2_subdev *sd)
-{
- int ret;
- struct rtl2832_sdr_state *s;
- const struct v4l2_ctrl_ops *ops = &rtl2832_sdr_ctrl_ops;
- struct dvb_usb_device *d = i2c_get_adapdata(i2c);
-
- s = kzalloc(sizeof(struct rtl2832_sdr_state), GFP_KERNEL);
- if (s == NULL) {
- dev_err(&d->udev->dev,
- "Could not allocate memory for rtl2832_sdr_state\n");
- return NULL;
- }
-
- /* setup the state */
- s->fe = fe;
- s->d = d;
- s->udev = d->udev;
- s->i2c = i2c;
- s->cfg = cfg;
- s->f_adc = bands_adc[0].rangelow;
- s->f_tuner = bands_fm[0].rangelow;
- s->pixelformat = V4L2_SDR_FMT_CU8;
-
- mutex_init(&s->v4l2_lock);
- mutex_init(&s->vb_queue_lock);
- spin_lock_init(&s->queued_bufs_lock);
- INIT_LIST_HEAD(&s->queued_bufs);
-
- /* Init videobuf2 queue structure */
- s->vb_queue.type = V4L2_BUF_TYPE_SDR_CAPTURE;
- s->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
- s->vb_queue.drv_priv = s;
- s->vb_queue.buf_struct_size = sizeof(struct rtl2832_sdr_frame_buf);
- s->vb_queue.ops = &rtl2832_sdr_vb2_ops;
- s->vb_queue.mem_ops = &vb2_vmalloc_memops;
- s->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- ret = vb2_queue_init(&s->vb_queue);
- if (ret) {
- dev_err(&s->udev->dev, "Could not initialize vb2 queue\n");
- goto err_free_mem;
- }
-
- /* Register controls */
- switch (s->cfg->tuner) {
- case RTL2832_TUNER_E4000:
- v4l2_ctrl_handler_init(&s->hdl, 9);
- if (sd)
- v4l2_ctrl_add_handler(&s->hdl, sd->ctrl_handler, NULL);
- break;
- case RTL2832_TUNER_R820T:
- v4l2_ctrl_handler_init(&s->hdl, 2);
- s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1);
- s->bandwidth = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH, 0, 8000000, 100000, 0);
- v4l2_ctrl_auto_cluster(2, &s->bandwidth_auto, 0, false);
- break;
- case RTL2832_TUNER_FC0012:
- case RTL2832_TUNER_FC0013:
- v4l2_ctrl_handler_init(&s->hdl, 2);
- s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1);
- s->bandwidth = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH, 6000000, 8000000, 1000000, 6000000);
- v4l2_ctrl_auto_cluster(2, &s->bandwidth_auto, 0, false);
- break;
- default:
- v4l2_ctrl_handler_init(&s->hdl, 0);
- dev_notice(&s->udev->dev, "%s: Unsupported tuner\n",
- KBUILD_MODNAME);
- goto err_free_controls;
- }
-
- if (s->hdl.error) {
- ret = s->hdl.error;
- dev_err(&s->udev->dev, "Could not initialize controls\n");
- goto err_free_controls;
- }
-
- /* Init video_device structure */
- s->vdev = rtl2832_sdr_template;
- s->vdev.queue = &s->vb_queue;
- s->vdev.queue->lock = &s->vb_queue_lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev.flags);
- video_set_drvdata(&s->vdev, s);
-
- /* Register the v4l2_device structure */
- s->v4l2_dev.release = rtl2832_sdr_video_release;
- ret = v4l2_device_register(&s->udev->dev, &s->v4l2_dev);
- if (ret) {
- dev_err(&s->udev->dev,
- "Failed to register v4l2-device (%d)\n", ret);
- goto err_free_controls;
- }
-
- s->v4l2_dev.ctrl_handler = &s->hdl;
- s->vdev.v4l2_dev = &s->v4l2_dev;
- s->vdev.lock = &s->v4l2_lock;
- s->vdev.vfl_dir = VFL_DIR_RX;
-
- ret = video_register_device(&s->vdev, VFL_TYPE_SDR, -1);
- if (ret) {
- dev_err(&s->udev->dev,
- "Failed to register as video device (%d)\n",
- ret);
- goto err_unregister_v4l2_dev;
- }
- dev_info(&s->udev->dev, "Registered as %s\n",
- video_device_node_name(&s->vdev));
-
- fe->sec_priv = s;
- fe->ops.release_sec = rtl2832_sdr_release_sec;
-
- dev_info(&s->i2c->dev, "%s: Realtek RTL2832 SDR attached\n",
- KBUILD_MODNAME);
- return fe;
-
-err_unregister_v4l2_dev:
- v4l2_device_unregister(&s->v4l2_dev);
-err_free_controls:
- v4l2_ctrl_handler_free(&s->hdl);
-err_free_mem:
- kfree(s);
- return NULL;
-}
-EXPORT_SYMBOL(rtl2832_sdr_attach);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Realtek RTL2832 SDR driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h
deleted file mode 100644
index b865fadf184f..000000000000
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Realtek RTL2832U SDR driver
- *
- * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * GNU Radio plugin "gr-kernel" for device usage will be on:
- * http://git.linuxtv.org/anttip/gr-kernel.git
- *
- * TODO:
- * Help is very highly welcome for these + all the others you could imagine:
- * - move controls to V4L2 API
- * - use libv4l2 for stream format conversions
- * - gr-kernel: switch to v4l2_mmap (current read eats a lot of cpu)
- * - SDRSharp support
- */
-
-#ifndef RTL2832_SDR_H
-#define RTL2832_SDR_H
-
-#include <linux/kconfig.h>
-#include <media/v4l2-subdev.h>
-
-/* for config struct */
-#include "rtl2832.h"
-
-#if IS_ENABLED(CONFIG_DVB_RTL2832_SDR)
-extern struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c, const struct rtl2832_config *cfg,
- struct v4l2_subdev *sd);
-#else
-static inline struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c, const struct rtl2832_config *cfg,
- struct v4l2_subdev *sd)
-{
- dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__);
- return NULL;
-}
-#endif
-
-#endif /* RTL2832_SDR_H */
diff --git a/drivers/staging/media/sn9c102/Kconfig b/drivers/staging/media/sn9c102/Kconfig
deleted file mode 100644
index 10f586befce3..000000000000
--- a/drivers/staging/media/sn9c102/Kconfig
+++ /dev/null
@@ -1,17 +0,0 @@
-config USB_SN9C102
- tristate "USB SN9C1xx PC Camera Controller support (DEPRECATED)"
- depends on VIDEO_V4L2 && MEDIA_USB_SUPPORT && USB
- ---help---
- This driver is DEPRECATED, please use the gspca sonixb and
- sonixj modules instead.
-
- Say Y here if you want support for cameras based on SONiX SN9C101,
- SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers.
-
- See <file:drivers/staging/media/sn9c102/sn9c102.txt> for more info.
-
- If you have webcams that are only supported by this driver and not by
- the gspca driver, then contact the linux-media mailinglist.
-
- To compile this driver as a module, choose M here: the
- module will be called sn9c102.
diff --git a/drivers/staging/media/sn9c102/Makefile b/drivers/staging/media/sn9c102/Makefile
deleted file mode 100644
index 7ecd5a90c7c9..000000000000
--- a/drivers/staging/media/sn9c102/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-sn9c102-objs := sn9c102_core.o \
- sn9c102_hv7131d.o \
- sn9c102_hv7131r.o \
- sn9c102_mi0343.o \
- sn9c102_mi0360.o \
- sn9c102_mt9v111.o \
- sn9c102_ov7630.o \
- sn9c102_ov7660.o \
- sn9c102_pas106b.o \
- sn9c102_pas202bcb.o \
- sn9c102_tas5110c1b.o \
- sn9c102_tas5110d.o \
- sn9c102_tas5130d1b.o
-
-obj-$(CONFIG_USB_SN9C102) += sn9c102.o
diff --git a/drivers/staging/media/sn9c102/sn9c102.h b/drivers/staging/media/sn9c102/sn9c102.h
deleted file mode 100644
index 37ca7225fcf7..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/***************************************************************************
- * V4L2 driver for SN9C1xx PC Camera Controllers *
- * *
- * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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 _SN9C102_H_
-#define _SN9C102_H_
-
-#include <linux/usb.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-device.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/types.h>
-#include <linux/param.h>
-#include <linux/rwsem.h>
-#include <linux/mutex.h>
-#include <linux/string.h>
-#include <linux/stddef.h>
-#include <linux/kref.h>
-
-#include "sn9c102_config.h"
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-enum sn9c102_frame_state {
- F_UNUSED,
- F_QUEUED,
- F_GRABBING,
- F_DONE,
- F_ERROR,
-};
-
-struct sn9c102_frame_t {
- void *bufmem;
- struct v4l2_buffer buf;
- enum sn9c102_frame_state state;
- struct list_head frame;
- unsigned long vma_use_count;
-};
-
-enum sn9c102_dev_state {
- DEV_INITIALIZED = 0x01,
- DEV_DISCONNECTED = 0x02,
- DEV_MISCONFIGURED = 0x04,
-};
-
-enum sn9c102_io_method {
- IO_NONE,
- IO_READ,
- IO_MMAP,
-};
-
-enum sn9c102_stream_state {
- STREAM_OFF,
- STREAM_INTERRUPT,
- STREAM_ON,
-};
-
-typedef char sn9c102_sof_header_t[62];
-
-struct sn9c102_sof_t {
- sn9c102_sof_header_t header;
- u16 bytesread;
-};
-
-struct sn9c102_sysfs_attr {
- u16 reg, i2c_reg;
- sn9c102_sof_header_t frame_header;
-};
-
-struct sn9c102_module_param {
- u8 force_munmap;
- u16 frame_timeout;
-};
-
-static DEFINE_MUTEX(sn9c102_sysfs_lock);
-static DECLARE_RWSEM(sn9c102_dev_lock);
-
-struct sn9c102_device {
- struct video_device *v4ldev;
-
- struct v4l2_device v4l2_dev;
-
- enum sn9c102_bridge bridge;
- struct sn9c102_sensor sensor;
-
- struct usb_device *usbdev;
- struct urb *urb[SN9C102_URBS];
- void *transfer_buffer[SN9C102_URBS];
- u8 *control_buffer;
-
- struct sn9c102_frame_t *frame_current, frame[SN9C102_MAX_FRAMES];
- struct list_head inqueue, outqueue;
- u32 frame_count, nbuffers, nreadbuffers;
-
- enum sn9c102_io_method io;
- enum sn9c102_stream_state stream;
-
- struct v4l2_jpegcompression compression;
-
- struct sn9c102_sysfs_attr sysfs;
- struct sn9c102_sof_t sof;
- u16 reg[384];
-
- struct sn9c102_module_param module_param;
-
- struct kref kref;
- enum sn9c102_dev_state state;
- u8 users;
-
- struct completion probe;
- struct mutex open_mutex, fileop_mutex;
- spinlock_t queue_lock;
- wait_queue_head_t wait_open, wait_frame, wait_stream;
-};
-
-/*****************************************************************************/
-
-struct sn9c102_device*
-sn9c102_match_id(struct sn9c102_device *cam, const struct usb_device_id *id)
-{
- return usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id) ? cam : NULL;
-}
-
-
-void
-sn9c102_attach_sensor(struct sn9c102_device *cam,
- const struct sn9c102_sensor *sensor)
-{
- memcpy(&cam->sensor, sensor, sizeof(struct sn9c102_sensor));
-}
-
-
-enum sn9c102_bridge
-sn9c102_get_bridge(struct sn9c102_device *cam)
-{
- return cam->bridge;
-}
-
-
-struct sn9c102_sensor *sn9c102_get_sensor(struct sn9c102_device *cam)
-{
- return &cam->sensor;
-}
-
-/*****************************************************************************/
-
-#undef DBG
-#undef KDBG
-#ifdef SN9C102_DEBUG
-# define DBG(level, fmt, args...) \
-do { \
- if (debug >= (level)) { \
- if ((level) == 1) \
- dev_err(&cam->usbdev->dev, fmt "\n", ## args); \
- else if ((level) == 2) \
- dev_info(&cam->usbdev->dev, fmt "\n", ## args); \
- else if ((level) >= 3) \
- dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
- __func__, __LINE__ , ## args); \
- } \
-} while (0)
-# define V4LDBG(level, name, cmd) \
-do { \
- if (debug >= (level)) \
- v4l_printk_ioctl(name, cmd); \
-} while (0)
-# define KDBG(level, fmt, args...) \
-do { \
- if (debug >= (level)) { \
- if ((level) == 1 || (level) == 2) \
- pr_info("sn9c102: " fmt "\n", ## args); \
- else if ((level) == 3) \
- pr_debug("sn9c102: [%s:%d] " fmt "\n", \
- __func__, __LINE__ , ## args); \
- } \
-} while (0)
-#else
-# define DBG(level, fmt, args...) do { ; } while (0)
-# define V4LDBG(level, name, cmd) do { ; } while (0)
-# define KDBG(level, fmt, args...) do { ; } while (0)
-#endif
-
-#undef PDBG
-#define PDBG(fmt, args...) \
-dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __func__, \
- __LINE__ , ## args)
-
-#undef PDBGG
-#define PDBGG(fmt, args...) do { ; } while (0) /* placeholder */
-
-#endif /* _SN9C102_H_ */
diff --git a/drivers/staging/media/sn9c102/sn9c102.txt b/drivers/staging/media/sn9c102/sn9c102.txt
deleted file mode 100644
index b4f67040403a..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102.txt
+++ /dev/null
@@ -1,592 +0,0 @@
-
- SN9C1xx PC Camera Controllers
- Driver for Linux
- =============================
-
- - Documentation -
-
-
-Index
-=====
-1. Copyright
-2. Disclaimer
-3. License
-4. Overview and features
-5. Module dependencies
-6. Module loading
-7. Module parameters
-8. Optional device control through "sysfs"
-9. Supported devices
-10. Notes for V4L2 application developers
-11. Video frame formats
-12. Contact information
-13. Credits
-
-
-1. Copyright
-============
-Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it>
-
-
-2. Disclaimer
-=============
-SONiX is a trademark of SONiX Technology Company Limited, inc.
-This software is not sponsored or developed by SONiX.
-
-
-3. License
-==========
-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.
-
-
-4. Overview and features
-========================
-This driver attempts to support the video interface of the devices assembling
-the SONiX SN9C101, SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers
-("SN9C1xx" from now on).
-
-The driver relies on the Video4Linux2 and USB core modules. It has been
-designed to run properly on SMP systems as well.
-
-The latest version of the SN9C1xx driver can be found at the following URL:
-http://www.linux-projects.org/
-
-Some of the features of the driver are:
-
-- full compliance with the Video4Linux2 API (see also "Notes for V4L2
- application developers" paragraph);
-- available mmap or read/poll methods for video streaming through isochronous
- data transfers;
-- automatic detection of image sensor;
-- support for built-in microphone interface;
-- support for any window resolutions and optional panning within the maximum
- pixel area of image sensor;
-- image downscaling with arbitrary scaling factors from 1, 2 and 4 in both
- directions (see "Notes for V4L2 application developers" paragraph);
-- two different video formats for uncompressed or compressed data in low or
- high compression quality (see also "Notes for V4L2 application developers"
- and "Video frame formats" paragraphs);
-- full support for the capabilities of many of the possible image sensors that
- can be connected to the SN9C1xx bridges, including, for instance, red, green,
- blue and global gain adjustments and exposure (see "Supported devices"
- paragraph for details);
-- use of default color settings for sunlight conditions;
-- dynamic I/O interface for both SN9C1xx and image sensor control and
- monitoring (see "Optional device control through 'sysfs'" paragraph);
-- dynamic driver control thanks to various module parameters (see "Module
- parameters" paragraph);
-- up to 64 cameras can be handled at the same time; they can be connected and
- disconnected from the host many times without turning off the computer, if
- the system supports hotplugging;
-- no known bugs.
-
-
-5. Module dependencies
-======================
-For it to work properly, the driver needs kernel support for Video4Linux and
-USB.
-
-The following options of the kernel configuration file must be enabled and
-corresponding modules must be compiled:
-
- # Multimedia devices
- #
- CONFIG_VIDEO_DEV=m
-
-To enable advanced debugging functionality on the device through /sysfs:
-
- # Multimedia devices
- #
- CONFIG_VIDEO_ADV_DEBUG=y
-
- # USB support
- #
- CONFIG_USB=m
-
-In addition, depending on the hardware being used, the modules below are
-necessary:
-
- # USB Host Controller Drivers
- #
- CONFIG_USB_EHCI_HCD=m
- CONFIG_USB_UHCI_HCD=m
- CONFIG_USB_OHCI_HCD=m
-
-The SN9C103, SN9c105 and SN9C120 controllers also provide a built-in microphone
-interface. It is supported by the USB Audio driver thanks to the ALSA API:
-
- # Sound
- #
- CONFIG_SOUND=y
-
- # Advanced Linux Sound Architecture
- #
- CONFIG_SND=m
-
- # USB devices
- #
- CONFIG_SND_USB_AUDIO=m
-
-And finally:
-
- # USB Multimedia devices
- #
- CONFIG_USB_SN9C102=m
-
-
-6. Module loading
-=================
-To use the driver, it is necessary to load the "sn9c102" module into memory
-after every other module required: "videodev", "v4l2_common", "compat_ioctl32",
-"usbcore" and, depending on the USB host controller you have, "ehci-hcd",
-"uhci-hcd" or "ohci-hcd".
-
-Loading can be done as shown below:
-
- [root@localhost home]# modprobe sn9c102
-
-Note that the module is called "sn9c102" for historic reasons, although it
-does not just support the SN9C102.
-
-At this point all the devices supported by the driver and connected to the USB
-ports should be recognized. You can invoke "dmesg" to analyze kernel messages
-and verify that the loading process has gone well:
-
- [user@localhost home]$ dmesg
-
-or, to isolate all the kernel messages generated by the driver:
-
- [user@localhost home]$ dmesg | grep sn9c102
-
-
-7. Module parameters
-====================
-Module parameters are listed below:
--------------------------------------------------------------------------------
-Name: video_nr
-Type: short array (min = 0, max = 64)
-Syntax: <-1|n[,...]>
-Description: Specify V4L2 minor mode number:
- -1 = use next available
- n = use minor number n
- You can specify up to 64 cameras this way.
- For example:
- video_nr=-1,2,-1 would assign minor number 2 to the second
- recognized camera and use auto for the first one and for every
- other camera.
-Default: -1
--------------------------------------------------------------------------------
-Name: force_munmap
-Type: bool array (min = 0, max = 64)
-Syntax: <0|1[,...]>
-Description: Force the application to unmap previously mapped buffer memory
- before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not
- all the applications support this feature. This parameter is
- specific for each detected camera.
- 0 = do not force memory unmapping
- 1 = force memory unmapping (save memory)
-Default: 0
--------------------------------------------------------------------------------
-Name: frame_timeout
-Type: uint array (min = 0, max = 64)
-Syntax: <0|n[,...]>
-Description: Timeout for a video frame in seconds before returning an I/O
- error; 0 for infinity. This parameter is specific for each
- detected camera and can be changed at runtime thanks to the
- /sys filesystem interface.
-Default: 2
--------------------------------------------------------------------------------
-Name: debug
-Type: ushort
-Syntax: <n>
-Description: Debugging information level, from 0 to 3:
- 0 = none (use carefully)
- 1 = critical errors
- 2 = significant information
- 3 = more verbose messages
- Level 3 is useful for testing only. It also shows some more
- information about the hardware being detected.
- This parameter can be changed at runtime thanks to the /sys
- filesystem interface.
-Default: 2
--------------------------------------------------------------------------------
-
-
-8. Optional device control through "sysfs" [1]
-==========================================
-If the kernel has been compiled with the CONFIG_VIDEO_ADV_DEBUG option enabled,
-it is possible to read and write both the SN9C1xx and the image sensor
-registers by using the "sysfs" filesystem interface.
-
-Every time a supported device is recognized, a write-only file named "green" is
-created in the /sys/class/video4linux/videoX directory. You can set the green
-channel's gain by writing the desired value to it. The value may range from 0
-to 15 for the SN9C101 or SN9C102 bridges, from 0 to 127 for the SN9C103,
-SN9C105 and SN9C120 bridges.
-Similarly, only for the SN9C103, SN9C105 and SN9C120 controllers, blue and red
-gain control files are available in the same directory, for which accepted
-values may range from 0 to 127.
-
-There are other four entries in the directory above for each registered camera:
-"reg", "val", "i2c_reg" and "i2c_val". The first two files control the
-SN9C1xx bridge, while the other two control the sensor chip. "reg" and
-"i2c_reg" hold the values of the current register index where the following
-reading/writing operations are addressed at through "val" and "i2c_val". Their
-use is not intended for end-users. Note that "i2c_reg" and "i2c_val" will not
-be created if the sensor does not actually support the standard I2C protocol or
-its registers are not 8-bit long. Also, remember that you must be logged in as
-root before writing to them.
-
-As an example, suppose we were to want to read the value contained in the
-register number 1 of the sensor register table - which is usually the product
-identifier - of the camera registered as "/dev/video0":
-
- [root@localhost #] cd /sys/class/video4linux/video0
- [root@localhost #] echo 1 > i2c_reg
- [root@localhost #] cat i2c_val
-
-Note that "cat" will fail if sensor registers cannot be read.
-
-Now let's set the green gain's register of the SN9C101 or SN9C102 chips to 2:
-
- [root@localhost #] echo 0x11 > reg
- [root@localhost #] echo 2 > val
-
-Note that the SN9C1xx always returns 0 when some of its registers are read.
-To avoid race conditions, all the I/O accesses to the above files are
-serialized.
-The sysfs interface also provides the "frame_header" entry, which exports the
-frame header of the most recent requested and captured video frame. The header
-is always 18-bytes long and is appended to every video frame by the SN9C1xx
-controllers. As an example, this additional information can be used by the user
-application for implementing auto-exposure features via software.
-
-The following table describes the frame header exported by the SN9C101 and
-SN9C102:
-
-Byte # Value or bits Description
------- ------------- -----------
-0x00 0xFF Frame synchronisation pattern
-0x01 0xFF Frame synchronisation pattern
-0x02 0x00 Frame synchronisation pattern
-0x03 0xC4 Frame synchronisation pattern
-0x04 0xC4 Frame synchronisation pattern
-0x05 0x96 Frame synchronisation pattern
-0x06 [3:0] Read channel gain control = (1+R_GAIN/8)
- [7:4] Blue channel gain control = (1+B_GAIN/8)
-0x07 [ 0 ] Compression mode. 0=No compression, 1=Compression enabled
- [2:1] Maximum scale factor for compression
- [ 3 ] 1 = USB fifo(2K bytes) is full
- [ 4 ] 1 = Digital gain is finish
- [ 5 ] 1 = Exposure is finish
- [7:6] Frame index
-0x08 [7:0] Y sum inside Auto-Exposure area (low-byte)
-0x09 [7:0] Y sum inside Auto-Exposure area (high-byte)
- where Y sum = (R/4 + 5G/16 + B/8) / 32
-0x0A [7:0] Y sum outside Auto-Exposure area (low-byte)
-0x0B [7:0] Y sum outside Auto-Exposure area (high-byte)
- where Y sum = (R/4 + 5G/16 + B/8) / 128
-0x0C 0xXX Not used
-0x0D 0xXX Not used
-0x0E 0xXX Not used
-0x0F 0xXX Not used
-0x10 0xXX Not used
-0x11 0xXX Not used
-
-The following table describes the frame header exported by the SN9C103:
-
-Byte # Value or bits Description
------- ------------- -----------
-0x00 0xFF Frame synchronisation pattern
-0x01 0xFF Frame synchronisation pattern
-0x02 0x00 Frame synchronisation pattern
-0x03 0xC4 Frame synchronisation pattern
-0x04 0xC4 Frame synchronisation pattern
-0x05 0x96 Frame synchronisation pattern
-0x06 [6:0] Read channel gain control = (1/2+R_GAIN/64)
-0x07 [6:0] Blue channel gain control = (1/2+B_GAIN/64)
- [7:4]
-0x08 [ 0 ] Compression mode. 0=No compression, 1=Compression enabled
- [2:1] Maximum scale factor for compression
- [ 3 ] 1 = USB fifo(2K bytes) is full
- [ 4 ] 1 = Digital gain is finish
- [ 5 ] 1 = Exposure is finish
- [7:6] Frame index
-0x09 [7:0] Y sum inside Auto-Exposure area (low-byte)
-0x0A [7:0] Y sum inside Auto-Exposure area (high-byte)
- where Y sum = (R/4 + 5G/16 + B/8) / 32
-0x0B [7:0] Y sum outside Auto-Exposure area (low-byte)
-0x0C [7:0] Y sum outside Auto-Exposure area (high-byte)
- where Y sum = (R/4 + 5G/16 + B/8) / 128
-0x0D [1:0] Audio frame number
- [ 2 ] 1 = Audio is recording
-0x0E [7:0] Audio summation (low-byte)
-0x0F [7:0] Audio summation (high-byte)
-0x10 [7:0] Audio sample count
-0x11 [7:0] Audio peak data in audio frame
-
-The AE area (sx, sy, ex, ey) in the active window can be set by programming the
-registers 0x1c, 0x1d, 0x1e and 0x1f of the SN9C1xx controllers, where one unit
-corresponds to 32 pixels.
-
-[1] The frame headers exported by the SN9C105 and SN9C120 are not described.
-
-
-9. Supported devices
-====================
-None of the names of the companies as well as their products will be mentioned
-here. They have never collaborated with the author, so no advertising.
-
-From the point of view of a driver, what unambiguously identify a device are
-its vendor and product USB identifiers. Below is a list of known identifiers of
-devices assembling the SN9C1xx PC camera controllers:
-
-Vendor ID Product ID
---------- ----------
-0x0458 0x7025
-0x045e 0x00f5
-0x045e 0x00f7
-0x0471 0x0327
-0x0471 0x0328
-0x0c45 0x6001
-0x0c45 0x6005
-0x0c45 0x6007
-0x0c45 0x6009
-0x0c45 0x600d
-0x0c45 0x6011
-0x0c45 0x6019
-0x0c45 0x6024
-0x0c45 0x6025
-0x0c45 0x6028
-0x0c45 0x6029
-0x0c45 0x602a
-0x0c45 0x602b
-0x0c45 0x602c
-0x0c45 0x602d
-0x0c45 0x602e
-0x0c45 0x6030
-0x0c45 0x603f
-0x0c45 0x6080
-0x0c45 0x6082
-0x0c45 0x6083
-0x0c45 0x6088
-0x0c45 0x608a
-0x0c45 0x608b
-0x0c45 0x608c
-0x0c45 0x608e
-0x0c45 0x608f
-0x0c45 0x60a0
-0x0c45 0x60a2
-0x0c45 0x60a3
-0x0c45 0x60a8
-0x0c45 0x60aa
-0x0c45 0x60ab
-0x0c45 0x60ac
-0x0c45 0x60ae
-0x0c45 0x60af
-0x0c45 0x60b0
-0x0c45 0x60b2
-0x0c45 0x60b3
-0x0c45 0x60b8
-0x0c45 0x60ba
-0x0c45 0x60bb
-0x0c45 0x60bc
-0x0c45 0x60be
-0x0c45 0x60c0
-0x0c45 0x60c2
-0x0c45 0x60c8
-0x0c45 0x60cc
-0x0c45 0x60ea
-0x0c45 0x60ec
-0x0c45 0x60ef
-0x0c45 0x60fa
-0x0c45 0x60fb
-0x0c45 0x60fc
-0x0c45 0x60fe
-0x0c45 0x6102
-0x0c45 0x6108
-0x0c45 0x610f
-0x0c45 0x6130
-0x0c45 0x6138
-0x0c45 0x613a
-0x0c45 0x613b
-0x0c45 0x613c
-0x0c45 0x613e
-
-The list above does not imply that all those devices work with this driver: up
-until now only the ones that assemble the following pairs of SN9C1xx bridges
-and image sensors are supported; kernel messages will always tell you whether
-this is the case (see "Module loading" paragraph):
-
-Image sensor / SN9C1xx bridge | SN9C10[12] SN9C103 SN9C105 SN9C120
--------------------------------------------------------------------------------
-HV7131D Hynix Semiconductor | Yes No No No
-HV7131R Hynix Semiconductor | No Yes Yes Yes
-MI-0343 Micron Technology | Yes No No No
-MI-0360 Micron Technology | No Yes Yes Yes
-OV7630 OmniVision Technologies | Yes Yes Yes Yes
-OV7660 OmniVision Technologies | No No Yes Yes
-PAS106B PixArt Imaging | Yes No No No
-PAS202B PixArt Imaging | Yes Yes No No
-TAS5110C1B Taiwan Advanced Sensor | Yes No No No
-TAS5110D Taiwan Advanced Sensor | Yes No No No
-TAS5130D1B Taiwan Advanced Sensor | Yes No No No
-
-"Yes" means that the pair is supported by the driver, while "No" means that the
-pair does not exist or is not supported by the driver.
-
-Only some of the available control settings of each image sensor are supported
-through the V4L2 interface.
-
-Donations of new models for further testing and support would be much
-appreciated. Non-available hardware will not be supported by the author of this
-driver.
-
-
-10. Notes for V4L2 application developers
-=========================================
-This driver follows the V4L2 API specifications. In particular, it enforces two
-rules:
-
-- exactly one I/O method, either "mmap" or "read", is associated with each
-file descriptor. Once it is selected, the application must close and reopen the
-device to switch to the other I/O method;
-
-- although it is not mandatory, previously mapped buffer memory should always
-be unmapped before calling any "VIDIOC_S_CROP" or "VIDIOC_S_FMT" ioctl's.
-The same number of buffers as before will be allocated again to match the size
-of the new video frames, so you have to map the buffers again before any I/O
-attempts on them.
-
-Consistently with the hardware limits, this driver also supports image
-downscaling with arbitrary scaling factors from 1, 2 and 4 in both directions.
-However, the V4L2 API specifications don't correctly define how the scaling
-factor can be chosen arbitrarily by the "negotiation" of the "source" and
-"target" rectangles. To work around this flaw, we have added the convention
-that, during the negotiation, whenever the "VIDIOC_S_CROP" ioctl is issued, the
-scaling factor is restored to 1.
-
-This driver supports two different video formats: the first one is the "8-bit
-Sequential Bayer" format and can be used to obtain uncompressed video data
-from the device through the current I/O method, while the second one provides
-either "raw" compressed video data (without frame headers not related to the
-compressed data) or standard JPEG (with frame headers). The compression quality
-may vary from 0 to 1 and can be selected or queried thanks to the
-VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2 ioctl's. For maximum flexibility,
-both the default active video format and the default compression quality
-depend on how the image sensor being used is initialized.
-
-
-11. Video frame formats [1]
-=======================
-The SN9C1xx PC Camera Controllers can send images in two possible video
-formats over the USB: either native "Sequential RGB Bayer" or compressed.
-The compression is used to achieve high frame rates. With regard to the
-SN9C101, SN9C102 and SN9C103, the compression is based on the Huffman encoding
-algorithm described below, while with regard to the SN9C105 and SN9C120 the
-compression is based on the JPEG standard.
-The current video format may be selected or queried from the user application
-by calling the VIDIOC_S_FMT or VIDIOC_G_FMT ioctl's, as described in the V4L2
-API specifications.
-
-The name "Sequential Bayer" indicates the organization of the red, green and
-blue pixels in one video frame. Each pixel is associated with a 8-bit long
-value and is disposed in memory according to the pattern shown below:
-
-B[0] G[1] B[2] G[3] ... B[m-2] G[m-1]
-G[m] R[m+1] G[m+2] R[m+2] ... G[2m-2] R[2m-1]
-...
-... B[(n-1)(m-2)] G[(n-1)(m-1)]
-... G[n(m-2)] R[n(m-1)]
-
-The above matrix also represents the sequential or progressive read-out mode of
-the (n, m) Bayer color filter array used in many CCD or CMOS image sensors.
-
-The Huffman compressed video frame consists of a bitstream that encodes for
-every R, G, or B pixel the difference between the value of the pixel itself and
-some reference pixel value. Pixels are organised in the Bayer pattern and the
-Bayer sub-pixels are tracked individually and alternatingly. For example, in
-the first line values for the B and G1 pixels are alternatingly encoded, while
-in the second line values for the G2 and R pixels are alternatingly encoded.
-
-The pixel reference value is calculated as follows:
-- the 4 top left pixels are encoded in raw uncompressed 8-bit format;
-- the value in the top two rows is the value of the pixel left of the current
- pixel;
-- the value in the left column is the value of the pixel above the current
- pixel;
-- for all other pixels, the reference value is the average of the value of the
- pixel on the left and the value of the pixel above the current pixel;
-- there is one code in the bitstream that specifies the value of a pixel
- directly (in 4-bit resolution);
-- pixel values need to be clamped inside the range [0..255] for proper
- decoding.
-
-The algorithm purely describes the conversion from compressed Bayer code used
-in the SN9C101, SN9C102 and SN9C103 chips to uncompressed Bayer. Additional
-steps are required to convert this to a color image (i.e. a color interpolation
-algorithm).
-
-The following Huffman codes have been found:
-0: +0 (relative to reference pixel value)
-100: +4
-101: -4?
-1110xxxx: set absolute value to xxxx.0000
-1101: +11
-1111: -11
-11001: +20
-110000: -20
-110001: ??? - these codes are apparently not used
-
-[1] The Huffman compression algorithm has been reverse-engineered and
- documented by Bertrik Sikken.
-
-
-12. Contact information
-=======================
-The author may be contacted by e-mail at <luca.risolia@studio.unibo.it>.
-
-GPG/PGP encrypted e-mail's are accepted. The GPG key ID of the author is
-'FCE635A4'; the public 1024-bit key should be available at any keyserver;
-the fingerprint is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'.
-
-
-13. Credits
-===========
-Many thanks to following persons for their contribute (listed in alphabetical
-order):
-
-- David Anderson for the donation of a webcam;
-- Luca Capello for the donation of a webcam;
-- Philippe Coval for having helped testing the PAS202BCA image sensor;
-- Joao Rodrigo Fuzaro, Joao Limirio, Claudio Filho and Caio Begotti for the
- donation of a webcam;
-- Dennis Heitmann for the donation of a webcam;
-- Jon Hollstrom for the donation of a webcam;
-- Nick McGill for the donation of a webcam;
-- Carlos Eduardo Medaglia Dyonisio, who added the support for the PAS202BCB
- image sensor;
-- Stefano Mozzi, who donated 45 EU;
-- Andrew Pearce for the donation of a webcam;
-- John Pullan for the donation of a webcam;
-- Bertrik Sikken, who reverse-engineered and documented the Huffman compression
- algorithm used in the SN9C101, SN9C102 and SN9C103 controllers and
- implemented the first decoder;
-- Ronny Standke for the donation of a webcam;
-- Mizuno Takafumi for the donation of a webcam;
-- an "anonymous" donator (who didn't want his name to be revealed) for the
- donation of a webcam.
-- an anonymous donator for the donation of four webcams and two boards with ten
- image sensors.
diff --git a/drivers/staging/media/sn9c102/sn9c102_config.h b/drivers/staging/media/sn9c102/sn9c102_config.h
deleted file mode 100644
index 0f4e0378b071..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_config.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/***************************************************************************
- * Global parameters for the V4L2 driver for SN9C1xx PC Camera Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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 _SN9C102_CONFIG_H_
-#define _SN9C102_CONFIG_H_
-
-#include <linux/types.h>
-#include <linux/jiffies.h>
-
-#define SN9C102_DEBUG
-#define SN9C102_DEBUG_LEVEL 2
-#define SN9C102_MAX_DEVICES 64
-#define SN9C102_PRESERVE_IMGSCALE 0
-#define SN9C102_FORCE_MUNMAP 0
-#define SN9C102_MAX_FRAMES 32
-#define SN9C102_URBS 2
-#define SN9C102_ISO_PACKETS 7
-#define SN9C102_ALTERNATE_SETTING 8
-#define SN9C102_URB_TIMEOUT msecs_to_jiffies(2 * SN9C102_ISO_PACKETS)
-#define SN9C102_CTRL_TIMEOUT 300
-#define SN9C102_FRAME_TIMEOUT 0
-
-/*****************************************************************************/
-
-static const u8 SN9C102_Y_QTABLE0[64] = {
- 8, 5, 5, 8, 12, 20, 25, 30,
- 6, 6, 7, 9, 13, 29, 30, 27,
- 7, 6, 8, 12, 20, 28, 34, 28,
- 7, 8, 11, 14, 25, 43, 40, 31,
- 9, 11, 18, 28, 34, 54, 51, 38,
- 12, 17, 27, 32, 40, 52, 56, 46,
- 24, 32, 39, 43, 51, 60, 60, 50,
- 36, 46, 47, 49, 56, 50, 51, 49
-};
-
-static const u8 SN9C102_UV_QTABLE0[64] = {
- 8, 9, 12, 23, 49, 49, 49, 49,
- 9, 10, 13, 33, 49, 49, 49, 49,
- 12, 13, 28, 49, 49, 49, 49, 49,
- 23, 33, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49
-};
-
-static const u8 SN9C102_Y_QTABLE1[64] = {
- 16, 11, 10, 16, 24, 40, 51, 61,
- 12, 12, 14, 19, 26, 58, 60, 55,
- 14, 13, 16, 24, 40, 57, 69, 56,
- 14, 17, 22, 29, 51, 87, 80, 62,
- 18, 22, 37, 56, 68, 109, 103, 77,
- 24, 35, 55, 64, 81, 104, 113, 92,
- 49, 64, 78, 87, 103, 121, 120, 101,
- 72, 92, 95, 98, 112, 100, 103, 99
-};
-
-static const u8 SN9C102_UV_QTABLE1[64] = {
- 17, 18, 24, 47, 99, 99, 99, 99,
- 18, 21, 26, 66, 99, 99, 99, 99,
- 24, 26, 56, 99, 99, 99, 99, 99,
- 47, 66, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99
-};
-
-#endif /* _SN9C102_CONFIG_H_ */
diff --git a/drivers/staging/media/sn9c102/sn9c102_core.c b/drivers/staging/media/sn9c102/sn9c102_core.c
deleted file mode 100644
index 98b30579b0ac..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_core.c
+++ /dev/null
@@ -1,3465 +0,0 @@
-/***************************************************************************
- * V4L2 driver for SN9C1xx PC Camera Controllers *
- * *
- * Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-#include <linux/fs.h>
-#include <linux/delay.h>
-#include <linux/compiler.h>
-#include <linux/ioctl.h>
-#include <linux/poll.h>
-#include <linux/stat.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <linux/version.h>
-#include <linux/page-flags.h>
-#include <asm/byteorder.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-#include "sn9c102.h"
-
-/*****************************************************************************/
-
-#define SN9C102_MODULE_NAME "V4L2 driver for SN9C1xx PC Camera Controllers"
-#define SN9C102_MODULE_ALIAS "sn9c1xx"
-#define SN9C102_MODULE_AUTHOR "(C) 2004-2007 Luca Risolia"
-#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
-#define SN9C102_MODULE_LICENSE "GPL"
-#define SN9C102_MODULE_VERSION "1:1.48"
-
-/*****************************************************************************/
-
-MODULE_DEVICE_TABLE(usb, sn9c102_id_table);
-
-MODULE_AUTHOR(SN9C102_MODULE_AUTHOR " " SN9C102_AUTHOR_EMAIL);
-MODULE_DESCRIPTION(SN9C102_MODULE_NAME);
-MODULE_ALIAS(SN9C102_MODULE_ALIAS);
-MODULE_VERSION(SN9C102_MODULE_VERSION);
-MODULE_LICENSE(SN9C102_MODULE_LICENSE);
-
-static short video_nr[] = {[0 ... SN9C102_MAX_DEVICES-1] = -1};
-module_param_array(video_nr, short, NULL, 0444);
-MODULE_PARM_DESC(video_nr,
- " <-1|n[,...]>"
- "\nSpecify V4L2 minor mode number."
- "\n-1 = use next available (default)"
- "\n n = use minor number n (integer >= 0)"
- "\nYou can specify up to "__MODULE_STRING(SN9C102_MAX_DEVICES)
- " cameras this way."
- "\nFor example:"
- "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
- "\nthe second camera and use auto for the first"
- "\none and for every other camera."
- "\n");
-
-static bool force_munmap[] = {[0 ... SN9C102_MAX_DEVICES-1] =
- SN9C102_FORCE_MUNMAP};
-module_param_array(force_munmap, bool, NULL, 0444);
-MODULE_PARM_DESC(force_munmap,
- " <0|1[,...]>"
- "\nForce the application to unmap previously"
- "\nmapped buffer memory before calling any VIDIOC_S_CROP or"
- "\nVIDIOC_S_FMT ioctl's. Not all the applications support"
- "\nthis feature. This parameter is specific for each"
- "\ndetected camera."
- "\n0 = do not force memory unmapping"
- "\n1 = force memory unmapping (save memory)"
- "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
- "\n");
-
-static unsigned int frame_timeout[] = {[0 ... SN9C102_MAX_DEVICES-1] =
- SN9C102_FRAME_TIMEOUT};
-module_param_array(frame_timeout, uint, NULL, 0644);
-MODULE_PARM_DESC(frame_timeout,
- " <0|n[,...]>"
- "\nTimeout for a video frame in seconds before"
- "\nreturning an I/O error; 0 for infinity."
- "\nThis parameter is specific for each detected camera."
- "\nDefault value is "__MODULE_STRING(SN9C102_FRAME_TIMEOUT)"."
- "\n");
-
-#ifdef SN9C102_DEBUG
-static unsigned short debug = SN9C102_DEBUG_LEVEL;
-module_param(debug, ushort, 0644);
-MODULE_PARM_DESC(debug,
- " <n>"
- "\nDebugging information level, from 0 to 3:"
- "\n0 = none (use carefully)"
- "\n1 = critical errors"
- "\n2 = significant informations"
- "\n3 = more verbose messages"
- "\nLevel 3 is useful for testing only."
- "\nDefault value is "__MODULE_STRING(SN9C102_DEBUG_LEVEL)"."
- "\n");
-#endif
-
-/*
- Add the probe entries to this table. Be sure to add the entry in the right
- place, since, on failure, the next probing routine is called according to
- the order of the list below, from top to bottom.
-*/
-static int (*sn9c102_sensor_table[])(struct sn9c102_device *) = {
- &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */
- &sn9c102_probe_hv7131r, /* strong detection based on SENSOR ids */
- &sn9c102_probe_mi0343, /* strong detection based on SENSOR ids */
- &sn9c102_probe_mi0360, /* strong detection based on SENSOR ids */
- &sn9c102_probe_mt9v111, /* strong detection based on SENSOR ids */
- &sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */
- &sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */
- &sn9c102_probe_ov7630, /* strong detection based on SENSOR ids */
- &sn9c102_probe_ov7660, /* strong detection based on SENSOR ids */
- &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */
- &sn9c102_probe_tas5110d, /* detection based on USB pid/vid */
- &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */
-};
-
-/*****************************************************************************/
-
-static u32
-sn9c102_request_buffers(struct sn9c102_device *cam, u32 count,
- enum sn9c102_io_method io)
-{
- struct v4l2_pix_format *p = &(cam->sensor.pix_format);
- struct v4l2_rect *r = &(cam->sensor.cropcap.bounds);
- size_t imagesize = cam->module_param.force_munmap || io == IO_READ ?
- (p->width * p->height * p->priv) / 8 :
- (r->width * r->height * p->priv) / 8;
- void *buff = NULL;
- u32 i;
-
- if (count > SN9C102_MAX_FRAMES)
- count = SN9C102_MAX_FRAMES;
-
- if (cam->bridge == BRIDGE_SN9C105 || cam->bridge == BRIDGE_SN9C120)
- imagesize += 589 + 2; /* length of JPEG header + EOI marker */
-
- cam->nbuffers = count;
- while (cam->nbuffers > 0) {
- buff = vmalloc_32_user(cam->nbuffers * PAGE_ALIGN(imagesize));
- if (buff)
- break;
- cam->nbuffers--;
- }
-
- for (i = 0; i < cam->nbuffers; i++) {
- cam->frame[i].bufmem = buff + i*PAGE_ALIGN(imagesize);
- cam->frame[i].buf.index = i;
- cam->frame[i].buf.m.offset = i*PAGE_ALIGN(imagesize);
- cam->frame[i].buf.length = imagesize;
- cam->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- cam->frame[i].buf.sequence = 0;
- cam->frame[i].buf.field = V4L2_FIELD_NONE;
- cam->frame[i].buf.memory = V4L2_MEMORY_MMAP;
- cam->frame[i].buf.flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- }
-
- return cam->nbuffers;
-}
-
-
-static void sn9c102_release_buffers(struct sn9c102_device *cam)
-{
- if (cam->nbuffers) {
- vfree(cam->frame[0].bufmem);
- cam->nbuffers = 0;
- }
- cam->frame_current = NULL;
-}
-
-
-static void sn9c102_empty_framequeues(struct sn9c102_device *cam)
-{
- u32 i;
-
- INIT_LIST_HEAD(&cam->inqueue);
- INIT_LIST_HEAD(&cam->outqueue);
-
- for (i = 0; i < SN9C102_MAX_FRAMES; i++) {
- cam->frame[i].state = F_UNUSED;
- cam->frame[i].buf.bytesused = 0;
- }
-}
-
-
-static void sn9c102_requeue_outqueue(struct sn9c102_device *cam)
-{
- struct sn9c102_frame_t *i;
-
- list_for_each_entry(i, &cam->outqueue, frame) {
- i->state = F_QUEUED;
- list_add(&i->frame, &cam->inqueue);
- }
-
- INIT_LIST_HEAD(&cam->outqueue);
-}
-
-
-static void sn9c102_queue_unusedframes(struct sn9c102_device *cam)
-{
- unsigned long lock_flags;
- u32 i;
-
- for (i = 0; i < cam->nbuffers; i++)
- if (cam->frame[i].state == F_UNUSED) {
- cam->frame[i].state = F_QUEUED;
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- list_add_tail(&cam->frame[i].frame, &cam->inqueue);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
- }
-}
-
-/*****************************************************************************/
-
-/*
- Write a sequence of count value/register pairs. Returns -1 after the first
- failed write, or 0 for no errors.
-*/
-int sn9c102_write_regs(struct sn9c102_device *cam, const u8 valreg[][2],
- int count)
-{
- struct usb_device *udev = cam->usbdev;
- u8 *buff = cam->control_buffer;
- int i, res;
-
- for (i = 0; i < count; i++) {
- u8 index = valreg[i][1];
-
- /*
- index is a u8, so it must be <256 and can't be out of range.
- If we put in a check anyway, gcc annoys us with a warning
- hat our check is useless. People get all uppity when they
- see warnings in the kernel compile.
- */
-
- *buff = valreg[i][0];
-
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08,
- 0x41, index, 0, buff, 1,
- SN9C102_CTRL_TIMEOUT);
-
- if (res < 0) {
- DBG(3, "Failed to write a register (value 0x%02X, "
- "index 0x%02X, error %d)", *buff, index, res);
- return -1;
- }
-
- cam->reg[index] = *buff;
- }
-
- return 0;
-}
-
-
-int sn9c102_write_reg(struct sn9c102_device *cam, u8 value, u16 index)
-{
- struct usb_device *udev = cam->usbdev;
- u8 *buff = cam->control_buffer;
- int res;
-
- if (index >= ARRAY_SIZE(cam->reg))
- return -1;
-
- *buff = value;
-
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
- index, 0, buff, 1, SN9C102_CTRL_TIMEOUT);
- if (res < 0) {
- DBG(3, "Failed to write a register (value 0x%02X, index "
- "0x%02X, error %d)", value, index, res);
- return -1;
- }
-
- cam->reg[index] = value;
-
- return 0;
-}
-
-
-/* NOTE: with the SN9C10[123] reading some registers always returns 0 */
-int sn9c102_read_reg(struct sn9c102_device *cam, u16 index)
-{
- struct usb_device *udev = cam->usbdev;
- u8 *buff = cam->control_buffer;
- int res;
-
- res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
- index, 0, buff, 1, SN9C102_CTRL_TIMEOUT);
- if (res < 0)
- DBG(3, "Failed to read a register (index 0x%02X, error %d)",
- index, res);
-
- return (res >= 0) ? (int)(*buff) : -1;
-}
-
-
-int sn9c102_pread_reg(struct sn9c102_device *cam, u16 index)
-{
- if (index >= ARRAY_SIZE(cam->reg))
- return -1;
-
- return cam->reg[index];
-}
-
-
-static int
-sn9c102_i2c_wait(struct sn9c102_device *cam,
- const struct sn9c102_sensor *sensor)
-{
- int i, r;
-
- for (i = 1; i <= 5; i++) {
- r = sn9c102_read_reg(cam, 0x08);
- if (r < 0)
- return -EIO;
- if (r & 0x04)
- return 0;
- if (sensor->frequency & SN9C102_I2C_400KHZ)
- udelay(5*16);
- else
- udelay(16*16);
- }
- return -EBUSY;
-}
-
-
-static int
-sn9c102_i2c_detect_read_error(struct sn9c102_device *cam,
- const struct sn9c102_sensor *sensor)
-{
- int r , err = 0;
-
- r = sn9c102_read_reg(cam, 0x08);
- if (r < 0)
- err += r;
-
- if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) {
- if (!(r & 0x08))
- err += -1;
- } else {
- if (r & 0x08)
- err += -1;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int
-sn9c102_i2c_detect_write_error(struct sn9c102_device *cam,
- const struct sn9c102_sensor *sensor)
-{
- int r;
-
- r = sn9c102_read_reg(cam, 0x08);
- return (r < 0 || (r >= 0 && (r & 0x08))) ? -EIO : 0;
-}
-
-
-int
-sn9c102_i2c_try_raw_read(struct sn9c102_device *cam,
- const struct sn9c102_sensor *sensor, u8 data0,
- u8 data1, u8 n, u8 buffer[])
-{
- struct usb_device *udev = cam->usbdev;
- u8 *data = cam->control_buffer;
- int i = 0, err = 0, res;
-
- /* Write cycle */
- data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
- ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) | 0x10;
- data[1] = data0; /* I2C slave id */
- data[2] = data1; /* address */
- data[7] = 0x10;
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
- 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
- if (res < 0)
- err += res;
-
- err += sn9c102_i2c_wait(cam, sensor);
-
- /* Read cycle - n bytes */
- data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
- ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) |
- (n << 4) | 0x02;
- data[1] = data0;
- data[7] = 0x10;
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
- 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
- if (res < 0)
- err += res;
-
- err += sn9c102_i2c_wait(cam, sensor);
-
- /* The first read byte will be placed in data[4] */
- res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
- 0x0a, 0, data, 5, SN9C102_CTRL_TIMEOUT);
- if (res < 0)
- err += res;
-
- err += sn9c102_i2c_detect_read_error(cam, sensor);
-
- PDBGG("I2C read: address 0x%02X, first read byte: 0x%02X", data1,
- data[4]);
-
- if (err) {
- DBG(3, "I2C read failed for %s image sensor", sensor->name);
- return -1;
- }
-
- if (buffer)
- for (i = 0; i < n && i < 5; i++)
- buffer[n-i-1] = data[4-i];
-
- return (int)data[4];
-}
-
-
-int
-sn9c102_i2c_try_raw_write(struct sn9c102_device *cam,
- const struct sn9c102_sensor *sensor, u8 n, u8 data0,
- u8 data1, u8 data2, u8 data3, u8 data4, u8 data5)
-{
- struct usb_device *udev = cam->usbdev;
- u8 *data = cam->control_buffer;
- int err = 0, res;
-
- /* Write cycle. It usually is address + value */
- data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
- ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0)
- | ((n - 1) << 4);
- data[1] = data0;
- data[2] = data1;
- data[3] = data2;
- data[4] = data3;
- data[5] = data4;
- data[6] = data5;
- data[7] = 0x17;
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
- 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
- if (res < 0)
- err += res;
-
- err += sn9c102_i2c_wait(cam, sensor);
- err += sn9c102_i2c_detect_write_error(cam, sensor);
-
- if (err)
- DBG(3, "I2C write failed for %s image sensor", sensor->name);
-
- PDBGG("I2C raw write: %u bytes, data0 = 0x%02X, data1 = 0x%02X, "
- "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X",
- n, data0, data1, data2, data3, data4, data5);
-
- return err ? -1 : 0;
-}
-
-
-int
-sn9c102_i2c_try_read(struct sn9c102_device *cam,
- const struct sn9c102_sensor *sensor, u8 address)
-{
- return sn9c102_i2c_try_raw_read(cam, sensor, sensor->i2c_slave_id,
- address, 1, NULL);
-}
-
-
-static int sn9c102_i2c_try_write(struct sn9c102_device *cam,
- const struct sn9c102_sensor *sensor,
- u8 address, u8 value)
-{
- return sn9c102_i2c_try_raw_write(cam, sensor, 3,
- sensor->i2c_slave_id, address,
- value, 0, 0, 0);
-}
-
-
-int sn9c102_i2c_read(struct sn9c102_device *cam, u8 address)
-{
- return sn9c102_i2c_try_read(cam, &cam->sensor, address);
-}
-
-
-int sn9c102_i2c_write(struct sn9c102_device *cam, u8 address, u8 value)
-{
- return sn9c102_i2c_try_write(cam, &cam->sensor, address, value);
-}
-
-/*****************************************************************************/
-
-static size_t sn9c102_sof_length(struct sn9c102_device *cam)
-{
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- return 12;
- case BRIDGE_SN9C103:
- return 18;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- return 62;
- }
-
- return 0;
-}
-
-
-static void*
-sn9c102_find_sof_header(struct sn9c102_device *cam, void *mem, size_t len)
-{
- static const char marker[6] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
- const char *m = mem;
- size_t soflen = 0, i, j;
-
- soflen = sn9c102_sof_length(cam);
-
- for (i = 0; i < len; i++) {
- size_t b;
-
- /* Read the variable part of the header */
- if (unlikely(cam->sof.bytesread >= sizeof(marker))) {
- cam->sof.header[cam->sof.bytesread] = *(m+i);
- if (++cam->sof.bytesread == soflen) {
- cam->sof.bytesread = 0;
- return mem + i;
- }
- continue;
- }
-
- /* Search for the SOF marker (fixed part) in the header */
- for (j = 0, b = cam->sof.bytesread; j+b < sizeof(marker); j++) {
- if (unlikely(i+j == len))
- return NULL;
- if (*(m+i+j) == marker[cam->sof.bytesread]) {
- cam->sof.header[cam->sof.bytesread] = *(m+i+j);
- if (++cam->sof.bytesread == sizeof(marker)) {
- PDBGG("Bytes to analyze: %zd. SOF "
- "starts at byte #%zd", len, i);
- i += j+1;
- break;
- }
- } else {
- cam->sof.bytesread = 0;
- break;
- }
- }
- }
-
- return NULL;
-}
-
-
-static void*
-sn9c102_find_eof_header(struct sn9c102_device *cam, void *mem, size_t len)
-{
- static const u8 eof_header[4][4] = {
- {0x00, 0x00, 0x00, 0x00},
- {0x40, 0x00, 0x00, 0x00},
- {0x80, 0x00, 0x00, 0x00},
- {0xc0, 0x00, 0x00, 0x00},
- };
- size_t i, j;
-
- /* The EOF header does not exist in compressed data */
- if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X ||
- cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
- return NULL;
-
- /*
- The EOF header might cross the packet boundary, but this is not a
- problem, since the end of a frame is determined by checking its size
- in the first place.
- */
- for (i = 0; (len >= 4) && (i <= len - 4); i++)
- for (j = 0; j < ARRAY_SIZE(eof_header); j++)
- if (!memcmp(mem + i, eof_header[j], 4))
- return mem + i;
-
- return NULL;
-}
-
-
-static void
-sn9c102_write_jpegheader(struct sn9c102_device *cam, struct sn9c102_frame_t *f)
-{
- static const u8 jpeg_header[589] = {
- 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x06, 0x04, 0x05,
- 0x06, 0x05, 0x04, 0x06, 0x06, 0x05, 0x06, 0x07, 0x07, 0x06,
- 0x08, 0x0a, 0x10, 0x0a, 0x0a, 0x09, 0x09, 0x0a, 0x14, 0x0e,
- 0x0f, 0x0c, 0x10, 0x17, 0x14, 0x18, 0x18, 0x17, 0x14, 0x16,
- 0x16, 0x1a, 0x1d, 0x25, 0x1f, 0x1a, 0x1b, 0x23, 0x1c, 0x16,
- 0x16, 0x20, 0x2c, 0x20, 0x23, 0x26, 0x27, 0x29, 0x2a, 0x29,
- 0x19, 0x1f, 0x2d, 0x30, 0x2d, 0x28, 0x30, 0x25, 0x28, 0x29,
- 0x28, 0x01, 0x07, 0x07, 0x07, 0x0a, 0x08, 0x0a, 0x13, 0x0a,
- 0x0a, 0x13, 0x28, 0x1a, 0x16, 0x1a, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xff, 0xc4, 0x01, 0xa2,
- 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
- 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01,
- 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
- 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x10, 0x00,
- 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04,
- 0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04,
- 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
- 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23,
- 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62,
- 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25,
- 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38,
- 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
- 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64,
- 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76,
- 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
- 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
- 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,
- 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2,
- 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3,
- 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3,
- 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3,
- 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x11, 0x00, 0x02,
- 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04,
- 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
- 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
- 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1,
- 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1,
- 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19,
- 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
- 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
- 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64,
- 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76,
- 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
- 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
- 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
- 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
- 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3,
- 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4,
- 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc0, 0x00, 0x11,
- 0x08, 0x01, 0xe0, 0x02, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02,
- 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03,
- 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
- };
- u8 *pos = f->bufmem;
-
- memcpy(pos, jpeg_header, sizeof(jpeg_header));
- *(pos + 6) = 0x00;
- *(pos + 7 + 64) = 0x01;
- if (cam->compression.quality == 0) {
- memcpy(pos + 7, SN9C102_Y_QTABLE0, 64);
- memcpy(pos + 8 + 64, SN9C102_UV_QTABLE0, 64);
- } else if (cam->compression.quality == 1) {
- memcpy(pos + 7, SN9C102_Y_QTABLE1, 64);
- memcpy(pos + 8 + 64, SN9C102_UV_QTABLE1, 64);
- }
- *(pos + 564) = cam->sensor.pix_format.width & 0xFF;
- *(pos + 563) = (cam->sensor.pix_format.width >> 8) & 0xFF;
- *(pos + 562) = cam->sensor.pix_format.height & 0xFF;
- *(pos + 561) = (cam->sensor.pix_format.height >> 8) & 0xFF;
- *(pos + 567) = 0x21;
-
- f->buf.bytesused += sizeof(jpeg_header);
-}
-
-
-static void sn9c102_urb_complete(struct urb *urb)
-{
- struct sn9c102_device *cam = urb->context;
- struct sn9c102_frame_t **f;
- size_t imagesize, soflen;
- u8 i;
- int err = 0;
-
- if (urb->status == -ENOENT)
- return;
-
- f = &cam->frame_current;
-
- if (cam->stream == STREAM_INTERRUPT) {
- cam->stream = STREAM_OFF;
- if ((*f))
- (*f)->state = F_QUEUED;
- cam->sof.bytesread = 0;
- DBG(3, "Stream interrupted by application");
- wake_up(&cam->wait_stream);
- }
-
- if (cam->state & DEV_DISCONNECTED)
- return;
-
- if (cam->state & DEV_MISCONFIGURED) {
- wake_up_interruptible(&cam->wait_frame);
- return;
- }
-
- if (cam->stream == STREAM_OFF || list_empty(&cam->inqueue))
- goto resubmit_urb;
-
- if (!(*f))
- (*f) = list_entry(cam->inqueue.next, struct sn9c102_frame_t,
- frame);
-
- imagesize = (cam->sensor.pix_format.width *
- cam->sensor.pix_format.height *
- cam->sensor.pix_format.priv) / 8;
- if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
- imagesize += 589; /* length of jpeg header */
- soflen = sn9c102_sof_length(cam);
-
- for (i = 0; i < urb->number_of_packets; i++) {
- unsigned int img, len, status;
- void *pos, *sof, *eof;
-
- len = urb->iso_frame_desc[i].actual_length;
- status = urb->iso_frame_desc[i].status;
- pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
-
- if (status) {
- DBG(3, "Error in isochronous frame");
- (*f)->state = F_ERROR;
- cam->sof.bytesread = 0;
- continue;
- }
-
- PDBGG("Isochrnous frame: length %u, #%u i", len, i);
-
-redo:
- sof = sn9c102_find_sof_header(cam, pos, len);
- if (likely(!sof)) {
- eof = sn9c102_find_eof_header(cam, pos, len);
- if ((*f)->state == F_GRABBING) {
-end_of_frame:
- img = len;
-
- if (eof)
- img = (eof > pos) ? eof - pos - 1 : 0;
-
- if ((*f)->buf.bytesused + img > imagesize) {
- u32 b;
- b = (*f)->buf.bytesused + img -
- imagesize;
- img = imagesize - (*f)->buf.bytesused;
- PDBGG("Expected EOF not found: video "
- "frame cut");
- if (eof)
- DBG(3, "Exceeded limit: +%u "
- "bytes", (unsigned)(b));
- }
-
- memcpy((*f)->bufmem + (*f)->buf.bytesused, pos,
- img);
-
- if ((*f)->buf.bytesused == 0)
- v4l2_get_timestamp(
- &(*f)->buf.timestamp);
-
- (*f)->buf.bytesused += img;
-
- if ((*f)->buf.bytesused == imagesize ||
- ((cam->sensor.pix_format.pixelformat ==
- V4L2_PIX_FMT_SN9C10X ||
- cam->sensor.pix_format.pixelformat ==
- V4L2_PIX_FMT_JPEG) && eof)) {
- u32 b;
-
- b = (*f)->buf.bytesused;
- (*f)->state = F_DONE;
- (*f)->buf.sequence = ++cam->frame_count;
-
- spin_lock(&cam->queue_lock);
- list_move_tail(&(*f)->frame,
- &cam->outqueue);
- if (!list_empty(&cam->inqueue))
- (*f) = list_entry(
- cam->inqueue.next,
- struct sn9c102_frame_t,
- frame);
- else
- (*f) = NULL;
- spin_unlock(&cam->queue_lock);
-
- memcpy(cam->sysfs.frame_header,
- cam->sof.header, soflen);
-
- DBG(3, "Video frame captured: %lu "
- "bytes", (unsigned long)(b));
-
- if (!(*f))
- goto resubmit_urb;
-
- } else if (eof) {
- (*f)->state = F_ERROR;
- DBG(3, "Not expected EOF after %lu "
- "bytes of image data",
- (unsigned long)
- ((*f)->buf.bytesused));
- }
-
- if (sof) /* (1) */
- goto start_of_frame;
-
- } else if (eof) {
- DBG(3, "EOF without SOF");
- continue;
-
- } else {
- PDBGG("Ignoring pointless isochronous frame");
- continue;
- }
-
- } else if ((*f)->state == F_QUEUED || (*f)->state == F_ERROR) {
-start_of_frame:
- (*f)->state = F_GRABBING;
- (*f)->buf.bytesused = 0;
- len -= (sof - pos);
- pos = sof;
- if (cam->sensor.pix_format.pixelformat ==
- V4L2_PIX_FMT_JPEG)
- sn9c102_write_jpegheader(cam, (*f));
- DBG(3, "SOF detected: new video frame");
- if (len)
- goto redo;
-
- } else if ((*f)->state == F_GRABBING) {
- eof = sn9c102_find_eof_header(cam, pos, len);
- if (eof && eof < sof)
- goto end_of_frame; /* (1) */
- else {
- if (cam->sensor.pix_format.pixelformat ==
- V4L2_PIX_FMT_SN9C10X ||
- cam->sensor.pix_format.pixelformat ==
- V4L2_PIX_FMT_JPEG) {
- if (sof - pos >= soflen) {
- eof = sof - soflen;
- } else { /* remove header */
- eof = pos;
- (*f)->buf.bytesused -=
- (soflen - (sof - pos));
- }
- goto end_of_frame;
- } else {
- DBG(3, "SOF before expected EOF after "
- "%lu bytes of image data",
- (unsigned long)
- ((*f)->buf.bytesused));
- goto start_of_frame;
- }
- }
- }
- }
-
-resubmit_urb:
- urb->dev = cam->usbdev;
- err = usb_submit_urb(urb, GFP_ATOMIC);
- if (err < 0 && err != -EPERM) {
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "usb_submit_urb() failed");
- }
-
- wake_up_interruptible(&cam->wait_frame);
-}
-
-
-static int sn9c102_start_transfer(struct sn9c102_device *cam)
-{
- struct usb_device *udev = cam->usbdev;
- struct urb *urb;
- struct usb_host_interface *altsetting = usb_altnum_to_altsetting(
- usb_ifnum_to_if(udev, 0),
- SN9C102_ALTERNATE_SETTING);
- const unsigned int psz = le16_to_cpu(altsetting->
- endpoint[0].desc.wMaxPacketSize);
- s8 i, j;
- int err = 0;
-
- for (i = 0; i < SN9C102_URBS; i++) {
- cam->transfer_buffer[i] = kzalloc(SN9C102_ISO_PACKETS * psz,
- GFP_KERNEL);
- if (!cam->transfer_buffer[i]) {
- err = -ENOMEM;
- DBG(1, "Not enough memory");
- goto free_buffers;
- }
- }
-
- for (i = 0; i < SN9C102_URBS; i++) {
- urb = usb_alloc_urb(SN9C102_ISO_PACKETS, GFP_KERNEL);
- cam->urb[i] = urb;
- if (!urb) {
- err = -ENOMEM;
- DBG(1, "usb_alloc_urb() failed");
- goto free_urbs;
- }
- urb->dev = udev;
- urb->context = cam;
- urb->pipe = usb_rcvisocpipe(udev, 1);
- urb->transfer_flags = URB_ISO_ASAP;
- urb->number_of_packets = SN9C102_ISO_PACKETS;
- urb->complete = sn9c102_urb_complete;
- urb->transfer_buffer = cam->transfer_buffer[i];
- urb->transfer_buffer_length = psz * SN9C102_ISO_PACKETS;
- urb->interval = 1;
- for (j = 0; j < SN9C102_ISO_PACKETS; j++) {
- urb->iso_frame_desc[j].offset = psz * j;
- urb->iso_frame_desc[j].length = psz;
- }
- }
-
- /* Enable video */
- if (!(cam->reg[0x01] & 0x04)) {
- err = sn9c102_write_reg(cam, cam->reg[0x01] | 0x04, 0x01);
- if (err) {
- err = -EIO;
- DBG(1, "I/O hardware error");
- goto free_urbs;
- }
- }
-
- err = usb_set_interface(udev, 0, SN9C102_ALTERNATE_SETTING);
- if (err) {
- DBG(1, "usb_set_interface() failed");
- goto free_urbs;
- }
-
- cam->frame_current = NULL;
- cam->sof.bytesread = 0;
-
- for (i = 0; i < SN9C102_URBS; i++) {
- err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
- if (err) {
- for (j = i-1; j >= 0; j--)
- usb_kill_urb(cam->urb[j]);
- DBG(1, "usb_submit_urb() failed, error %d", err);
- goto free_urbs;
- }
- }
-
- return 0;
-
-free_urbs:
- for (i = 0; (i < SN9C102_URBS) && cam->urb[i]; i++)
- usb_free_urb(cam->urb[i]);
-
-free_buffers:
- for (i = 0; (i < SN9C102_URBS) && cam->transfer_buffer[i]; i++)
- kfree(cam->transfer_buffer[i]);
-
- return err;
-}
-
-
-static int sn9c102_stop_transfer(struct sn9c102_device *cam)
-{
- struct usb_device *udev = cam->usbdev;
- s8 i;
- int err = 0;
-
- if (cam->state & DEV_DISCONNECTED)
- return 0;
-
- for (i = SN9C102_URBS-1; i >= 0; i--) {
- usb_kill_urb(cam->urb[i]);
- usb_free_urb(cam->urb[i]);
- kfree(cam->transfer_buffer[i]);
- }
-
- err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */
- if (err)
- DBG(3, "usb_set_interface() failed");
-
- return err;
-}
-
-
-static int sn9c102_stream_interrupt(struct sn9c102_device *cam)
-{
- cam->stream = STREAM_INTERRUPT;
- wait_event_timeout(cam->wait_stream,
- (cam->stream == STREAM_OFF) ||
- (cam->state & DEV_DISCONNECTED),
- SN9C102_URB_TIMEOUT);
- if (cam->state & DEV_DISCONNECTED)
- return -ENODEV;
- else if (cam->stream != STREAM_OFF) {
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "URB timeout reached. The camera is misconfigured. "
- "To use it, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -EIO;
- }
-
- return 0;
-}
-
-/*****************************************************************************/
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static u16 sn9c102_strtou16(const char *buff, size_t len, ssize_t *count)
-{
- char str[7];
- char *endp;
- unsigned long val;
-
- if (len < 6) {
- strncpy(str, buff, len);
- str[len] = '\0';
- } else {
- strncpy(str, buff, 6);
- str[6] = '\0';
- }
-
- val = simple_strtoul(str, &endp, 0);
-
- *count = 0;
- if (val <= 0xffff)
- *count = (ssize_t)(endp - str);
- if ((*count) && (len == *count+1) && (buff[*count] == '\n'))
- *count += 1;
-
- return (u16)val;
-}
-
-/*
- NOTE 1: being inside one of the following methods implies that the v4l
- device exists for sure (see kobjects and reference counters)
- NOTE 2: buffers are PAGE_SIZE long
-*/
-
-static ssize_t sn9c102_show_reg(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct sn9c102_device *cam;
- ssize_t count;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- count = sprintf(buf, "%u\n", cam->sysfs.reg);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t
-sn9c102_store_reg(struct device *cd, struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct sn9c102_device *cam;
- u16 index;
- ssize_t count;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- index = sn9c102_strtou16(buf, len, &count);
- if (index >= ARRAY_SIZE(cam->reg) || !count) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EINVAL;
- }
-
- cam->sysfs.reg = index;
-
- DBG(2, "Moved SN9C1XX register index to 0x%02X", cam->sysfs.reg);
- DBG(3, "Written bytes: %zd", count);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t sn9c102_show_val(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct sn9c102_device *cam;
- ssize_t count;
- int val;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- val = sn9c102_read_reg(cam, cam->sysfs.reg);
- if (val < 0) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EIO;
- }
-
- count = sprintf(buf, "%d\n", val);
-
- DBG(3, "Read bytes: %zd, value: %d", count, val);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t
-sn9c102_store_val(struct device *cd, struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct sn9c102_device *cam;
- u16 value;
- ssize_t count;
- int err;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- value = sn9c102_strtou16(buf, len, &count);
- if (!count) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EINVAL;
- }
-
- err = sn9c102_write_reg(cam, value, cam->sysfs.reg);
- if (err) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EIO;
- }
-
- DBG(2, "Written SN9C1XX reg. 0x%02X, val. 0x%02X",
- cam->sysfs.reg, value);
- DBG(3, "Written bytes: %zd", count);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t sn9c102_show_i2c_reg(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct sn9c102_device *cam;
- ssize_t count;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg);
-
- DBG(3, "Read bytes: %zd", count);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t
-sn9c102_store_i2c_reg(struct device *cd, struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct sn9c102_device *cam;
- u16 index;
- ssize_t count;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- index = sn9c102_strtou16(buf, len, &count);
- if (!count) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EINVAL;
- }
-
- cam->sysfs.i2c_reg = index;
-
- DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg);
- DBG(3, "Written bytes: %zd", count);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t sn9c102_show_i2c_val(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct sn9c102_device *cam;
- ssize_t count;
- int val;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- if (!(cam->sensor.sysfs_ops & SN9C102_I2C_READ)) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENOSYS;
- }
-
- val = sn9c102_i2c_read(cam, cam->sysfs.i2c_reg);
- if (val < 0) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EIO;
- }
-
- count = sprintf(buf, "%d\n", val);
-
- DBG(3, "Read bytes: %zd, value: %d", count, val);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t
-sn9c102_store_i2c_val(struct device *cd, struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct sn9c102_device *cam;
- u16 value;
- ssize_t count;
- int err;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- if (!(cam->sensor.sysfs_ops & SN9C102_I2C_WRITE)) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENOSYS;
- }
-
- value = sn9c102_strtou16(buf, len, &count);
- if (!count) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EINVAL;
- }
-
- err = sn9c102_i2c_write(cam, cam->sysfs.i2c_reg, value);
- if (err) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EIO;
- }
-
- DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X",
- cam->sysfs.i2c_reg, value);
- DBG(3, "Written bytes: %zd", count);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t
-sn9c102_store_green(struct device *cd, struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct sn9c102_device *cam;
- enum sn9c102_bridge bridge;
- ssize_t res = 0;
- u16 value;
- ssize_t count;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- bridge = cam->bridge;
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- value = sn9c102_strtou16(buf, len, &count);
- if (!count)
- return -EINVAL;
-
- switch (bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- if (value > 0x0f)
- return -EINVAL;
- res = sn9c102_store_reg(cd, attr, "0x11", 4);
- if (res >= 0)
- res = sn9c102_store_val(cd, attr, buf, len);
- break;
- case BRIDGE_SN9C103:
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (value > 0x7f)
- return -EINVAL;
- res = sn9c102_store_reg(cd, attr, "0x07", 4);
- if (res >= 0)
- res = sn9c102_store_val(cd, attr, buf, len);
- break;
- }
-
- return res;
-}
-
-
-static ssize_t
-sn9c102_store_blue(struct device *cd, struct device_attribute *attr,
- const char *buf, size_t len)
-{
- ssize_t res = 0;
- u16 value;
- ssize_t count;
-
- value = sn9c102_strtou16(buf, len, &count);
- if (!count || value > 0x7f)
- return -EINVAL;
-
- res = sn9c102_store_reg(cd, attr, "0x06", 4);
- if (res >= 0)
- res = sn9c102_store_val(cd, attr, buf, len);
-
- return res;
-}
-
-
-static ssize_t
-sn9c102_store_red(struct device *cd, struct device_attribute *attr,
- const char *buf, size_t len)
-{
- ssize_t res = 0;
- u16 value;
- ssize_t count;
-
- value = sn9c102_strtou16(buf, len, &count);
- if (!count || value > 0x7f)
- return -EINVAL;
- res = sn9c102_store_reg(cd, attr, "0x05", 4);
- if (res >= 0)
- res = sn9c102_store_val(cd, attr, buf, len);
-
- return res;
-}
-
-
-static ssize_t sn9c102_show_frame_header(struct device *cd,
- struct device_attribute *attr,
- char *buf)
-{
- struct sn9c102_device *cam;
- ssize_t count;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam)
- return -ENODEV;
-
- count = sizeof(cam->sysfs.frame_header);
- memcpy(buf, cam->sysfs.frame_header, count);
-
- DBG(3, "Frame header, read bytes: %zd", count);
-
- return count;
-}
-
-
-static DEVICE_ATTR(reg, S_IRUGO | S_IWUSR, sn9c102_show_reg, sn9c102_store_reg);
-static DEVICE_ATTR(val, S_IRUGO | S_IWUSR, sn9c102_show_val, sn9c102_store_val);
-static DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR,
- sn9c102_show_i2c_reg, sn9c102_store_i2c_reg);
-static DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
- sn9c102_show_i2c_val, sn9c102_store_i2c_val);
-static DEVICE_ATTR(green, S_IWUSR, NULL, sn9c102_store_green);
-static DEVICE_ATTR(blue, S_IWUSR, NULL, sn9c102_store_blue);
-static DEVICE_ATTR(red, S_IWUSR, NULL, sn9c102_store_red);
-static DEVICE_ATTR(frame_header, S_IRUGO, sn9c102_show_frame_header, NULL);
-
-
-static int sn9c102_create_sysfs(struct sn9c102_device *cam)
-{
- struct device *dev = &(cam->v4ldev->dev);
- int err = 0;
-
- err = device_create_file(dev, &dev_attr_reg);
- if (err)
- goto err_out;
- err = device_create_file(dev, &dev_attr_val);
- if (err)
- goto err_reg;
- err = device_create_file(dev, &dev_attr_frame_header);
- if (err)
- goto err_val;
-
- if (cam->sensor.sysfs_ops) {
- err = device_create_file(dev, &dev_attr_i2c_reg);
- if (err)
- goto err_frame_header;
- err = device_create_file(dev, &dev_attr_i2c_val);
- if (err)
- goto err_i2c_reg;
- }
-
- if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) {
- err = device_create_file(dev, &dev_attr_green);
- if (err)
- goto err_i2c_val;
- } else {
- err = device_create_file(dev, &dev_attr_blue);
- if (err)
- goto err_i2c_val;
- err = device_create_file(dev, &dev_attr_red);
- if (err)
- goto err_blue;
- }
-
- return 0;
-
-err_blue:
- device_remove_file(dev, &dev_attr_blue);
-err_i2c_val:
- if (cam->sensor.sysfs_ops)
- device_remove_file(dev, &dev_attr_i2c_val);
-err_i2c_reg:
- if (cam->sensor.sysfs_ops)
- device_remove_file(dev, &dev_attr_i2c_reg);
-err_frame_header:
- device_remove_file(dev, &dev_attr_frame_header);
-err_val:
- device_remove_file(dev, &dev_attr_val);
-err_reg:
- device_remove_file(dev, &dev_attr_reg);
-err_out:
- return err;
-}
-#endif /* CONFIG_VIDEO_ADV_DEBUG */
-
-/*****************************************************************************/
-
-static int
-sn9c102_set_pix_format(struct sn9c102_device *cam, struct v4l2_pix_format *pix)
-{
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X ||
- pix->pixelformat == V4L2_PIX_FMT_JPEG) {
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x80,
- 0x18);
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- err += sn9c102_write_reg(cam, cam->reg[0x18] & 0x7f,
- 0x18);
- break;
- }
- } else {
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- err += sn9c102_write_reg(cam, cam->reg[0x18] & 0x7f,
- 0x18);
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x80,
- 0x18);
- break;
- }
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int
-sn9c102_set_compression(struct sn9c102_device *cam,
- struct v4l2_jpegcompression *compression)
-{
- int i, err = 0;
-
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- if (compression->quality == 0)
- err += sn9c102_write_reg(cam, cam->reg[0x17] | 0x01,
- 0x17);
- else if (compression->quality == 1)
- err += sn9c102_write_reg(cam, cam->reg[0x17] & 0xfe,
- 0x17);
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (compression->quality == 0) {
- for (i = 0; i <= 63; i++) {
- err += sn9c102_write_reg(cam,
- SN9C102_Y_QTABLE1[i],
- 0x100 + i);
- err += sn9c102_write_reg(cam,
- SN9C102_UV_QTABLE1[i],
- 0x140 + i);
- }
- err += sn9c102_write_reg(cam, cam->reg[0x18] & 0xbf,
- 0x18);
- } else if (compression->quality == 1) {
- for (i = 0; i <= 63; i++) {
- err += sn9c102_write_reg(cam,
- SN9C102_Y_QTABLE1[i],
- 0x100 + i);
- err += sn9c102_write_reg(cam,
- SN9C102_UV_QTABLE1[i],
- 0x140 + i);
- }
- err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x40,
- 0x18);
- }
- break;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int sn9c102_set_scale(struct sn9c102_device *cam, u8 scale)
-{
- u8 r = 0;
- int err = 0;
-
- if (scale == 1)
- r = cam->reg[0x18] & 0xcf;
- else if (scale == 2) {
- r = cam->reg[0x18] & 0xcf;
- r |= 0x10;
- } else if (scale == 4)
- r = cam->reg[0x18] | 0x20;
-
- err += sn9c102_write_reg(cam, r, 0x18);
- if (err)
- return -EIO;
-
- PDBGG("Scaling factor: %u", scale);
-
- return 0;
-}
-
-
-static int sn9c102_set_crop(struct sn9c102_device *cam, struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = &cam->sensor;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left),
- v_start = (u8)(rect->top - s->cropcap.bounds.top),
- h_size = (u8)(rect->width / 16),
- v_size = (u8)(rect->height / 16);
- int err = 0;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
- err += sn9c102_write_reg(cam, h_size, 0x15);
- err += sn9c102_write_reg(cam, v_size, 0x16);
- if (err)
- return -EIO;
-
- PDBGG("h_start, v_start, h_size, v_size, ho_size, vo_size "
- "%u %u %u %u", h_start, v_start, h_size, v_size);
-
- return 0;
-}
-
-
-static int sn9c102_init(struct sn9c102_device *cam)
-{
- struct sn9c102_sensor *s = &cam->sensor;
- struct v4l2_control ctrl;
- struct v4l2_queryctrl *qctrl;
- struct v4l2_rect *rect;
- u8 i = 0;
- int err = 0;
-
- if (!(cam->state & DEV_INITIALIZED)) {
- mutex_init(&cam->open_mutex);
- init_waitqueue_head(&cam->wait_open);
- qctrl = s->qctrl;
- rect = &(s->cropcap.defrect);
- } else { /* use current values */
- qctrl = s->_qctrl;
- rect = &(s->_rect);
- }
-
- err += sn9c102_set_scale(cam, rect->width / s->pix_format.width);
- err += sn9c102_set_crop(cam, rect);
- if (err)
- return err;
-
- if (s->init) {
- err = s->init(cam);
- if (err) {
- DBG(3, "Sensor initialization failed");
- return err;
- }
- }
-
- if (!(cam->state & DEV_INITIALIZED))
- if (cam->bridge == BRIDGE_SN9C101 ||
- cam->bridge == BRIDGE_SN9C102 ||
- cam->bridge == BRIDGE_SN9C103) {
- if (s->pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
- s->pix_format.pixelformat = V4L2_PIX_FMT_SBGGR8;
- cam->compression.quality = cam->reg[0x17] & 0x01 ?
- 0 : 1;
- } else {
- if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
- s->pix_format.pixelformat = V4L2_PIX_FMT_JPEG;
- cam->compression.quality = cam->reg[0x18] & 0x40 ?
- 0 : 1;
- err += sn9c102_set_compression(cam, &cam->compression);
- }
- else
- err += sn9c102_set_compression(cam, &cam->compression);
- err += sn9c102_set_pix_format(cam, &s->pix_format);
- if (s->set_pix_format)
- err += s->set_pix_format(cam, &s->pix_format);
- if (err)
- return err;
-
- if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X ||
- s->pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
- DBG(3, "Compressed video format is active, quality %d",
- cam->compression.quality);
- else
- DBG(3, "Uncompressed video format is active");
-
- if (s->set_crop) {
- err = s->set_crop(cam, rect);
- if (err) {
- DBG(3, "set_crop() failed");
- return err;
- }
- }
-
- if (s->set_ctrl) {
- for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
- if (s->qctrl[i].id != 0 &&
- !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) {
- ctrl.id = s->qctrl[i].id;
- ctrl.value = qctrl[i].default_value;
- err = s->set_ctrl(cam, &ctrl);
- if (err) {
- DBG(3, "Set %s control failed",
- s->qctrl[i].name);
- return err;
- }
- DBG(3, "Image sensor supports '%s' control",
- s->qctrl[i].name);
- }
- }
-
- if (!(cam->state & DEV_INITIALIZED)) {
- mutex_init(&cam->fileop_mutex);
- spin_lock_init(&cam->queue_lock);
- init_waitqueue_head(&cam->wait_frame);
- init_waitqueue_head(&cam->wait_stream);
- cam->nreadbuffers = 2;
- memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl));
- memcpy(&(s->_rect), &(s->cropcap.defrect),
- sizeof(struct v4l2_rect));
- cam->state |= DEV_INITIALIZED;
- }
-
- DBG(2, "Initialization succeeded");
- return 0;
-}
-
-/*****************************************************************************/
-
-static void sn9c102_release_resources(struct kref *kref)
-{
- struct sn9c102_device *cam;
-
- mutex_lock(&sn9c102_sysfs_lock);
-
- cam = container_of(kref, struct sn9c102_device, kref);
-
- DBG(2, "V4L2 device %s deregistered",
- video_device_node_name(cam->v4ldev));
- video_set_drvdata(cam->v4ldev, NULL);
- video_unregister_device(cam->v4ldev);
- v4l2_device_unregister(&cam->v4l2_dev);
- usb_put_dev(cam->usbdev);
- kfree(cam->control_buffer);
- kfree(cam);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
-}
-
-
-static int sn9c102_open(struct file *filp)
-{
- struct sn9c102_device *cam;
- int err = 0;
-
- /*
- A read_trylock() in open() is the only safe way to prevent race
- conditions with disconnect(), one close() and multiple (not
- necessarily simultaneous) attempts to open(). For example, it
- prevents from waiting for a second access, while the device
- structure is being deallocated, after a possible disconnect() and
- during a following close() holding the write lock: given that, after
- this deallocation, no access will be possible anymore, using the
- non-trylock version would have let open() gain the access to the
- device structure improperly.
- For this reason the lock must also not be per-device.
- */
- if (!down_read_trylock(&sn9c102_dev_lock))
- return -ERESTARTSYS;
-
- cam = video_drvdata(filp);
-
- if (wait_for_completion_interruptible(&cam->probe)) {
- up_read(&sn9c102_dev_lock);
- return -ERESTARTSYS;
- }
-
- kref_get(&cam->kref);
-
- /*
- Make sure to isolate all the simultaneous opens.
- */
- if (mutex_lock_interruptible(&cam->open_mutex)) {
- kref_put(&cam->kref, sn9c102_release_resources);
- up_read(&sn9c102_dev_lock);
- return -ERESTARTSYS;
- }
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- err = -ENODEV;
- goto out;
- }
-
- if (cam->users) {
- DBG(2, "Device %s is already in use",
- video_device_node_name(cam->v4ldev));
- DBG(3, "Simultaneous opens are not supported");
- /*
- open() must follow the open flags and should block
- eventually while the device is in use.
- */
- if ((filp->f_flags & O_NONBLOCK) ||
- (filp->f_flags & O_NDELAY)) {
- err = -EWOULDBLOCK;
- goto out;
- }
- DBG(2, "A blocking open() has been requested. Wait for the "
- "device to be released...");
- up_read(&sn9c102_dev_lock);
- /*
- We will not release the "open_mutex" lock, so that only one
- process can be in the wait queue below. This way the process
- will be sleeping while holding the lock, without losing its
- priority after any wake_up().
- */
- err = wait_event_interruptible_exclusive(cam->wait_open,
- (cam->state & DEV_DISCONNECTED)
- || !cam->users);
- down_read(&sn9c102_dev_lock);
- if (err)
- goto out;
- if (cam->state & DEV_DISCONNECTED) {
- err = -ENODEV;
- goto out;
- }
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- err = sn9c102_init(cam);
- if (err) {
- DBG(1, "Initialization failed again. "
- "I will retry on next open().");
- goto out;
- }
- cam->state &= ~DEV_MISCONFIGURED;
- }
-
- err = sn9c102_start_transfer(cam);
- if (err)
- goto out;
-
- filp->private_data = cam;
- cam->users++;
- cam->io = IO_NONE;
- cam->stream = STREAM_OFF;
- cam->nbuffers = 0;
- cam->frame_count = 0;
- sn9c102_empty_framequeues(cam);
-
- DBG(3, "Video device %s is open", video_device_node_name(cam->v4ldev));
-
-out:
- mutex_unlock(&cam->open_mutex);
- if (err)
- kref_put(&cam->kref, sn9c102_release_resources);
-
- up_read(&sn9c102_dev_lock);
- return err;
-}
-
-
-static int sn9c102_release(struct file *filp)
-{
- struct sn9c102_device *cam;
-
- down_write(&sn9c102_dev_lock);
-
- cam = video_drvdata(filp);
-
- sn9c102_stop_transfer(cam);
- sn9c102_release_buffers(cam);
- cam->users--;
- wake_up_interruptible_nr(&cam->wait_open, 1);
-
- DBG(3, "Video device %s closed", video_device_node_name(cam->v4ldev));
-
- kref_put(&cam->kref, sn9c102_release_resources);
-
- up_write(&sn9c102_dev_lock);
-
- return 0;
-}
-
-
-static ssize_t
-sn9c102_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
-{
- struct sn9c102_device *cam = video_drvdata(filp);
- struct sn9c102_frame_t *f, *i;
- unsigned long lock_flags;
- long timeout;
- int err = 0;
-
- if (mutex_lock_interruptible(&cam->fileop_mutex))
- return -ERESTARTSYS;
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- DBG(1, "The camera is misconfigured. Close and open it "
- "again.");
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
-
- if (cam->io == IO_MMAP) {
- DBG(3, "Close and open the device again to choose "
- "the read method");
- mutex_unlock(&cam->fileop_mutex);
- return -EBUSY;
- }
-
- if (cam->io == IO_NONE) {
- if (!sn9c102_request_buffers(cam, cam->nreadbuffers, IO_READ)) {
- DBG(1, "read() failed, not enough memory");
- mutex_unlock(&cam->fileop_mutex);
- return -ENOMEM;
- }
- cam->io = IO_READ;
- cam->stream = STREAM_ON;
- }
-
- if (list_empty(&cam->inqueue)) {
- if (!list_empty(&cam->outqueue))
- sn9c102_empty_framequeues(cam);
- sn9c102_queue_unusedframes(cam);
- }
-
- if (!count) {
- mutex_unlock(&cam->fileop_mutex);
- return 0;
- }
-
- if (list_empty(&cam->outqueue)) {
- if (filp->f_flags & O_NONBLOCK) {
- mutex_unlock(&cam->fileop_mutex);
- return -EAGAIN;
- }
- if (!cam->module_param.frame_timeout) {
- err = wait_event_interruptible
- (cam->wait_frame,
- (!list_empty(&cam->outqueue)) ||
- (cam->state & DEV_DISCONNECTED) ||
- (cam->state & DEV_MISCONFIGURED));
- if (err) {
- mutex_unlock(&cam->fileop_mutex);
- return err;
- }
- } else {
- timeout = wait_event_interruptible_timeout
- (cam->wait_frame,
- (!list_empty(&cam->outqueue)) ||
- (cam->state & DEV_DISCONNECTED) ||
- (cam->state & DEV_MISCONFIGURED),
- msecs_to_jiffies(
- cam->module_param.frame_timeout * 1000
- )
- );
- if (timeout < 0) {
- mutex_unlock(&cam->fileop_mutex);
- return timeout;
- } else if (timeout == 0 &&
- !(cam->state & DEV_DISCONNECTED)) {
- DBG(1, "Video frame timeout elapsed");
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
- }
- if (cam->state & DEV_DISCONNECTED) {
- mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
- if (cam->state & DEV_MISCONFIGURED) {
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
- }
-
- f = list_entry(cam->outqueue.prev, struct sn9c102_frame_t, frame);
-
- if (count > f->buf.bytesused)
- count = f->buf.bytesused;
-
- if (copy_to_user(buf, f->bufmem, count)) {
- err = -EFAULT;
- goto exit;
- }
- *f_pos += count;
-
-exit:
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- list_for_each_entry(i, &cam->outqueue, frame)
- i->state = F_UNUSED;
- INIT_LIST_HEAD(&cam->outqueue);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
-
- sn9c102_queue_unusedframes(cam);
-
- PDBGG("Frame #%lu, bytes read: %zu",
- (unsigned long)f->buf.index, count);
-
- mutex_unlock(&cam->fileop_mutex);
-
- return count;
-}
-
-
-static unsigned int sn9c102_poll(struct file *filp, poll_table *wait)
-{
- struct sn9c102_device *cam = video_drvdata(filp);
- struct sn9c102_frame_t *f;
- unsigned long lock_flags;
- unsigned int mask = 0;
-
- if (mutex_lock_interruptible(&cam->fileop_mutex))
- return POLLERR;
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- goto error;
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- DBG(1, "The camera is misconfigured. Close and open it "
- "again.");
- goto error;
- }
-
- if (cam->io == IO_NONE) {
- if (!sn9c102_request_buffers(cam, cam->nreadbuffers,
- IO_READ)) {
- DBG(1, "poll() failed, not enough memory");
- goto error;
- }
- cam->io = IO_READ;
- cam->stream = STREAM_ON;
- }
-
- if (cam->io == IO_READ) {
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- list_for_each_entry(f, &cam->outqueue, frame)
- f->state = F_UNUSED;
- INIT_LIST_HEAD(&cam->outqueue);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
- sn9c102_queue_unusedframes(cam);
- }
-
- poll_wait(filp, &cam->wait_frame, wait);
-
- if (!list_empty(&cam->outqueue))
- mask |= POLLIN | POLLRDNORM;
-
- mutex_unlock(&cam->fileop_mutex);
-
- return mask;
-
-error:
- mutex_unlock(&cam->fileop_mutex);
- return POLLERR;
-}
-
-
-static void sn9c102_vm_open(struct vm_area_struct *vma)
-{
- struct sn9c102_frame_t *f = vma->vm_private_data;
- f->vma_use_count++;
-}
-
-
-static void sn9c102_vm_close(struct vm_area_struct *vma)
-{
- /* NOTE: buffers are not freed here */
- struct sn9c102_frame_t *f = vma->vm_private_data;
- f->vma_use_count--;
-}
-
-
-static const struct vm_operations_struct sn9c102_vm_ops = {
- .open = sn9c102_vm_open,
- .close = sn9c102_vm_close,
-};
-
-
-static int sn9c102_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- struct sn9c102_device *cam = video_drvdata(filp);
- unsigned long size = vma->vm_end - vma->vm_start,
- start = vma->vm_start;
- void *pos;
- u32 i;
-
- if (mutex_lock_interruptible(&cam->fileop_mutex))
- return -ERESTARTSYS;
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- DBG(1, "The camera is misconfigured. Close and open it "
- "again.");
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
-
- if (!(vma->vm_flags & (VM_WRITE | VM_READ))) {
- mutex_unlock(&cam->fileop_mutex);
- return -EACCES;
- }
-
- if (cam->io != IO_MMAP ||
- size != PAGE_ALIGN(cam->frame[0].buf.length)) {
- mutex_unlock(&cam->fileop_mutex);
- return -EINVAL;
- }
-
- for (i = 0; i < cam->nbuffers; i++) {
- if ((cam->frame[i].buf.m.offset>>PAGE_SHIFT) == vma->vm_pgoff)
- break;
- }
- if (i == cam->nbuffers) {
- mutex_unlock(&cam->fileop_mutex);
- return -EINVAL;
- }
-
- vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
-
- pos = cam->frame[i].bufmem;
- while (size > 0) { /* size is page-aligned */
- if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
- mutex_unlock(&cam->fileop_mutex);
- return -EAGAIN;
- }
- start += PAGE_SIZE;
- pos += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
-
- vma->vm_ops = &sn9c102_vm_ops;
- vma->vm_private_data = &cam->frame[i];
- sn9c102_vm_open(vma);
-
- mutex_unlock(&cam->fileop_mutex);
-
- return 0;
-}
-
-/*****************************************************************************/
-
-static int
-sn9c102_vidioc_querycap(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_capability cap = {
- .driver = "sn9c102",
- .version = LINUX_VERSION_CODE,
- .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING,
- };
-
- strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
- if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
- strlcpy(cap.bus_info, dev_name(&cam->usbdev->dev),
- sizeof(cap.bus_info));
-
- if (copy_to_user(arg, &cap, sizeof(cap)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_enuminput(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_input i;
-
- if (copy_from_user(&i, arg, sizeof(i)))
- return -EFAULT;
-
- if (i.index)
- return -EINVAL;
-
- memset(&i, 0, sizeof(i));
- strcpy(i.name, "Camera");
- i.type = V4L2_INPUT_TYPE_CAMERA;
- i.capabilities = V4L2_IN_CAP_STD;
-
- if (copy_to_user(arg, &i, sizeof(i)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_g_input(struct sn9c102_device *cam, void __user *arg)
-{
- int index = 0;
-
- if (copy_to_user(arg, &index, sizeof(index)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_s_input(struct sn9c102_device *cam, void __user *arg)
-{
- int index;
-
- if (copy_from_user(&index, arg, sizeof(index)))
- return -EFAULT;
-
- if (index != 0)
- return -EINVAL;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_query_ctrl(struct sn9c102_device *cam, void __user *arg)
-{
- struct sn9c102_sensor *s = &cam->sensor;
- struct v4l2_queryctrl qc;
- u8 i;
-
- if (copy_from_user(&qc, arg, sizeof(qc)))
- return -EFAULT;
-
- for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
- if (qc.id && qc.id == s->qctrl[i].id) {
- memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
- if (copy_to_user(arg, &qc, sizeof(qc)))
- return -EFAULT;
- return 0;
- }
-
- return -EINVAL;
-}
-
-
-static int
-sn9c102_vidioc_g_ctrl(struct sn9c102_device *cam, void __user *arg)
-{
- struct sn9c102_sensor *s = &cam->sensor;
- struct v4l2_control ctrl;
- int err = 0;
- u8 i;
-
- if (!s->get_ctrl && !s->set_ctrl)
- return -EINVAL;
-
- if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
- return -EFAULT;
-
- if (!s->get_ctrl) {
- for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
- if (ctrl.id && ctrl.id == s->qctrl[i].id) {
- ctrl.value = s->_qctrl[i].default_value;
- goto exit;
- }
- return -EINVAL;
- } else
- err = s->get_ctrl(cam, &ctrl);
-
-exit:
- if (copy_to_user(arg, &ctrl, sizeof(ctrl)))
- return -EFAULT;
-
- PDBGG("VIDIOC_G_CTRL: id %lu, value %lu",
- (unsigned long)ctrl.id, (unsigned long)ctrl.value);
-
- return err;
-}
-
-
-static int
-sn9c102_vidioc_s_ctrl(struct sn9c102_device *cam, void __user *arg)
-{
- struct sn9c102_sensor *s = &cam->sensor;
- struct v4l2_control ctrl;
- u8 i;
- int err = 0;
-
- if (!s->set_ctrl)
- return -EINVAL;
-
- if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
- return -EFAULT;
-
- for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) {
- if (ctrl.id == s->qctrl[i].id) {
- if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)
- return -EINVAL;
- if (ctrl.value < s->qctrl[i].minimum ||
- ctrl.value > s->qctrl[i].maximum)
- return -ERANGE;
- ctrl.value -= ctrl.value % s->qctrl[i].step;
- break;
- }
- }
- if (i == ARRAY_SIZE(s->qctrl))
- return -EINVAL;
- err = s->set_ctrl(cam, &ctrl);
- if (err)
- return err;
-
- s->_qctrl[i].default_value = ctrl.value;
-
- PDBGG("VIDIOC_S_CTRL: id %lu, value %lu",
- (unsigned long)ctrl.id, (unsigned long)ctrl.value);
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_cropcap(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_cropcap *cc = &(cam->sensor.cropcap);
-
- cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- cc->pixelaspect.numerator = 1;
- cc->pixelaspect.denominator = 1;
-
- if (copy_to_user(arg, cc, sizeof(*cc)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_g_crop(struct sn9c102_device *cam, void __user *arg)
-{
- struct sn9c102_sensor *s = &cam->sensor;
- struct v4l2_crop crop = {
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
- };
-
- memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
-
- if (copy_to_user(arg, &crop, sizeof(crop)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_s_crop(struct sn9c102_device *cam, void __user *arg)
-{
- struct sn9c102_sensor *s = &cam->sensor;
- struct v4l2_crop crop;
- struct v4l2_rect *rect;
- struct v4l2_rect *bounds = &(s->cropcap.bounds);
- struct v4l2_pix_format *pix_format = &(s->pix_format);
- u8 scale;
- const enum sn9c102_stream_state stream = cam->stream;
- const u32 nbuffers = cam->nbuffers;
- u32 i;
- int err = 0;
-
- if (copy_from_user(&crop, arg, sizeof(crop)))
- return -EFAULT;
-
- rect = &(crop.c);
-
- if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (cam->module_param.force_munmap)
- for (i = 0; i < cam->nbuffers; i++)
- if (cam->frame[i].vma_use_count) {
- DBG(3, "VIDIOC_S_CROP failed. "
- "Unmap the buffers first.");
- return -EBUSY;
- }
-
- /* Preserve R,G or B origin */
- rect->left = (s->_rect.left & 1L) ? rect->left | 1L : rect->left & ~1L;
- rect->top = (s->_rect.top & 1L) ? rect->top | 1L : rect->top & ~1L;
-
- if (rect->width < 16)
- rect->width = 16;
- if (rect->height < 16)
- rect->height = 16;
- if (rect->width > bounds->width)
- rect->width = bounds->width;
- if (rect->height > bounds->height)
- rect->height = bounds->height;
- if (rect->left < bounds->left)
- rect->left = bounds->left;
- if (rect->top < bounds->top)
- rect->top = bounds->top;
- if (rect->left + rect->width > bounds->left + bounds->width)
- rect->left = bounds->left+bounds->width - rect->width;
- if (rect->top + rect->height > bounds->top + bounds->height)
- rect->top = bounds->top+bounds->height - rect->height;
-
- rect->width &= ~15L;
- rect->height &= ~15L;
-
- if (SN9C102_PRESERVE_IMGSCALE) {
- /* Calculate the actual scaling factor */
- u32 a, b;
- a = rect->width * rect->height;
- b = pix_format->width * pix_format->height;
- scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
- } else
- scale = 1;
-
- if (cam->stream == STREAM_ON) {
- err = sn9c102_stream_interrupt(cam);
- if (err)
- return err;
- }
-
- if (copy_to_user(arg, &crop, sizeof(crop))) {
- cam->stream = stream;
- return -EFAULT;
- }
-
- if (cam->module_param.force_munmap || cam->io == IO_READ)
- sn9c102_release_buffers(cam);
-
- err = sn9c102_set_crop(cam, rect);
- if (s->set_crop)
- err += s->set_crop(cam, rect);
- err += sn9c102_set_scale(cam, scale);
-
- if (err) { /* atomic, no rollback in ioctl() */
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -EIO;
- }
-
- s->pix_format.width = rect->width/scale;
- s->pix_format.height = rect->height/scale;
- memcpy(&(s->_rect), rect, sizeof(*rect));
-
- if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
- nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -ENOMEM;
- }
-
- if (cam->io == IO_READ)
- sn9c102_empty_framequeues(cam);
- else if (cam->module_param.force_munmap)
- sn9c102_requeue_outqueue(cam);
-
- cam->stream = stream;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_enum_framesizes(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_frmsizeenum frmsize;
-
- if (copy_from_user(&frmsize, arg, sizeof(frmsize)))
- return -EFAULT;
-
- if (frmsize.index != 0)
- return -EINVAL;
-
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- if (frmsize.pixel_format != V4L2_PIX_FMT_SN9C10X &&
- frmsize.pixel_format != V4L2_PIX_FMT_SBGGR8)
- return -EINVAL;
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (frmsize.pixel_format != V4L2_PIX_FMT_JPEG &&
- frmsize.pixel_format != V4L2_PIX_FMT_SBGGR8)
- return -EINVAL;
- break;
- }
-
- frmsize.type = V4L2_FRMSIZE_TYPE_STEPWISE;
- frmsize.stepwise.min_width = frmsize.stepwise.step_width = 16;
- frmsize.stepwise.min_height = frmsize.stepwise.step_height = 16;
- frmsize.stepwise.max_width = cam->sensor.cropcap.bounds.width;
- frmsize.stepwise.max_height = cam->sensor.cropcap.bounds.height;
- memset(&frmsize.reserved, 0, sizeof(frmsize.reserved));
-
- if (copy_to_user(arg, &frmsize, sizeof(frmsize)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_enum_fmt(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_fmtdesc fmtd;
-
- if (copy_from_user(&fmtd, arg, sizeof(fmtd)))
- return -EFAULT;
-
- if (fmtd.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (fmtd.index == 0) {
- strcpy(fmtd.description, "bayer rgb");
- fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8;
- } else if (fmtd.index == 1) {
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- strcpy(fmtd.description, "compressed");
- fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X;
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- strcpy(fmtd.description, "JPEG");
- fmtd.pixelformat = V4L2_PIX_FMT_JPEG;
- break;
- }
- fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
- } else
- return -EINVAL;
-
- fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
-
- if (copy_to_user(arg, &fmtd, sizeof(fmtd)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_g_fmt(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_format format;
- struct v4l2_pix_format *pfmt = &(cam->sensor.pix_format);
-
- if (copy_from_user(&format, arg, sizeof(format)))
- return -EFAULT;
-
- if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- pfmt->colorspace = (pfmt->pixelformat == V4L2_PIX_FMT_JPEG) ?
- V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB;
- pfmt->bytesperline = (pfmt->pixelformat == V4L2_PIX_FMT_SN9C10X ||
- pfmt->pixelformat == V4L2_PIX_FMT_JPEG)
- ? 0 : (pfmt->width * pfmt->priv) / 8;
- pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
- pfmt->field = V4L2_FIELD_NONE;
- memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
-
- if (copy_to_user(arg, &format, sizeof(format)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_try_s_fmt(struct sn9c102_device *cam, unsigned int cmd,
- void __user *arg)
-{
- struct sn9c102_sensor *s = &cam->sensor;
- struct v4l2_format format;
- struct v4l2_pix_format *pix;
- struct v4l2_pix_format *pfmt = &(s->pix_format);
- struct v4l2_rect *bounds = &(s->cropcap.bounds);
- struct v4l2_rect rect;
- u8 scale;
- const enum sn9c102_stream_state stream = cam->stream;
- const u32 nbuffers = cam->nbuffers;
- u32 i;
- int err = 0;
-
- if (copy_from_user(&format, arg, sizeof(format)))
- return -EFAULT;
-
- pix = &(format.fmt.pix);
-
- if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- memcpy(&rect, &(s->_rect), sizeof(rect));
-
- { /* calculate the actual scaling factor */
- u32 a, b;
- a = rect.width * rect.height;
- b = pix->width * pix->height;
- scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
- }
-
- rect.width = scale * pix->width;
- rect.height = scale * pix->height;
-
- if (rect.width < 16)
- rect.width = 16;
- if (rect.height < 16)
- rect.height = 16;
- if (rect.width > bounds->left + bounds->width - rect.left)
- rect.width = bounds->left + bounds->width - rect.left;
- if (rect.height > bounds->top + bounds->height - rect.top)
- rect.height = bounds->top + bounds->height - rect.top;
-
- rect.width &= ~15L;
- rect.height &= ~15L;
-
- { /* adjust the scaling factor */
- u32 a, b;
- a = rect.width * rect.height;
- b = pix->width * pix->height;
- scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
- }
-
- pix->width = rect.width / scale;
- pix->height = rect.height / scale;
-
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X &&
- pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
- pix->pixelformat = pfmt->pixelformat;
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (pix->pixelformat != V4L2_PIX_FMT_JPEG &&
- pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
- pix->pixelformat = pfmt->pixelformat;
- break;
- }
- pix->priv = pfmt->priv; /* bpp */
- pix->colorspace = (pix->pixelformat == V4L2_PIX_FMT_JPEG) ?
- V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB;
- pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X ||
- pix->pixelformat == V4L2_PIX_FMT_JPEG)
- ? 0 : (pix->width * pix->priv) / 8;
- pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
- pix->field = V4L2_FIELD_NONE;
-
- if (cmd == VIDIOC_TRY_FMT) {
- if (copy_to_user(arg, &format, sizeof(format)))
- return -EFAULT;
- return 0;
- }
-
- if (cam->module_param.force_munmap)
- for (i = 0; i < cam->nbuffers; i++)
- if (cam->frame[i].vma_use_count) {
- DBG(3, "VIDIOC_S_FMT failed. Unmap the "
- "buffers first.");
- return -EBUSY;
- }
-
- if (cam->stream == STREAM_ON) {
- err = sn9c102_stream_interrupt(cam);
- if (err)
- return err;
- }
-
- if (copy_to_user(arg, &format, sizeof(format))) {
- cam->stream = stream;
- return -EFAULT;
- }
-
- if (cam->module_param.force_munmap || cam->io == IO_READ)
- sn9c102_release_buffers(cam);
-
- err += sn9c102_set_pix_format(cam, pix);
- err += sn9c102_set_crop(cam, &rect);
- if (s->set_pix_format)
- err += s->set_pix_format(cam, pix);
- if (s->set_crop)
- err += s->set_crop(cam, &rect);
- err += sn9c102_set_scale(cam, scale);
-
- if (err) { /* atomic, no rollback in ioctl() */
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -EIO;
- }
-
- memcpy(pfmt, pix, sizeof(*pix));
- memcpy(&(s->_rect), &rect, sizeof(rect));
-
- if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
- nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -ENOMEM;
- }
-
- if (cam->io == IO_READ)
- sn9c102_empty_framequeues(cam);
- else if (cam->module_param.force_munmap)
- sn9c102_requeue_outqueue(cam);
-
- cam->stream = stream;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_g_jpegcomp(struct sn9c102_device *cam, void __user *arg)
-{
- if (copy_to_user(arg, &cam->compression, sizeof(cam->compression)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_s_jpegcomp(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_jpegcompression jc;
- const enum sn9c102_stream_state stream = cam->stream;
- int err = 0;
-
- if (copy_from_user(&jc, arg, sizeof(jc)))
- return -EFAULT;
-
- if (jc.quality != 0 && jc.quality != 1)
- return -EINVAL;
-
- if (cam->stream == STREAM_ON) {
- err = sn9c102_stream_interrupt(cam);
- if (err)
- return err;
- }
-
- err += sn9c102_set_compression(cam, &jc);
- if (err) { /* atomic, no rollback in ioctl() */
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware problems. "
- "To use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -EIO;
- }
-
- cam->compression.quality = jc.quality;
-
- cam->stream = stream;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_reqbufs(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_requestbuffers rb;
- u32 i;
- int err;
-
- if (copy_from_user(&rb, arg, sizeof(rb)))
- return -EFAULT;
-
- if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- rb.memory != V4L2_MEMORY_MMAP)
- return -EINVAL;
-
- if (cam->io == IO_READ) {
- DBG(3, "Close and open the device again to choose the mmap "
- "I/O method");
- return -EBUSY;
- }
-
- for (i = 0; i < cam->nbuffers; i++)
- if (cam->frame[i].vma_use_count) {
- DBG(3, "VIDIOC_REQBUFS failed. Previous buffers are "
- "still mapped.");
- return -EBUSY;
- }
-
- if (cam->stream == STREAM_ON) {
- err = sn9c102_stream_interrupt(cam);
- if (err)
- return err;
- }
-
- sn9c102_empty_framequeues(cam);
-
- sn9c102_release_buffers(cam);
- if (rb.count)
- rb.count = sn9c102_request_buffers(cam, rb.count, IO_MMAP);
-
- if (copy_to_user(arg, &rb, sizeof(rb))) {
- sn9c102_release_buffers(cam);
- cam->io = IO_NONE;
- return -EFAULT;
- }
-
- cam->io = rb.count ? IO_MMAP : IO_NONE;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_querybuf(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_buffer b;
-
- if (copy_from_user(&b, arg, sizeof(b)))
- return -EFAULT;
-
- if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- b.index >= cam->nbuffers || cam->io != IO_MMAP)
- return -EINVAL;
-
- b = cam->frame[b.index].buf;
-
- if (cam->frame[b.index].vma_use_count)
- b.flags |= V4L2_BUF_FLAG_MAPPED;
-
- if (cam->frame[b.index].state == F_DONE)
- b.flags |= V4L2_BUF_FLAG_DONE;
- else if (cam->frame[b.index].state != F_UNUSED)
- b.flags |= V4L2_BUF_FLAG_QUEUED;
-
- if (copy_to_user(arg, &b, sizeof(b)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_qbuf(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_buffer b;
- unsigned long lock_flags;
-
- if (copy_from_user(&b, arg, sizeof(b)))
- return -EFAULT;
-
- if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- b.index >= cam->nbuffers || cam->io != IO_MMAP)
- return -EINVAL;
-
- if (cam->frame[b.index].state != F_UNUSED)
- return -EINVAL;
-
- cam->frame[b.index].state = F_QUEUED;
-
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
-
- PDBGG("Frame #%lu queued", (unsigned long)b.index);
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_dqbuf(struct sn9c102_device *cam, struct file *filp,
- void __user *arg)
-{
- struct v4l2_buffer b;
- struct sn9c102_frame_t *f;
- unsigned long lock_flags;
- long timeout;
- int err = 0;
-
- if (copy_from_user(&b, arg, sizeof(b)))
- return -EFAULT;
-
- if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
- return -EINVAL;
-
- if (list_empty(&cam->outqueue)) {
- if (cam->stream == STREAM_OFF)
- return -EINVAL;
- if (filp->f_flags & O_NONBLOCK)
- return -EAGAIN;
- if (!cam->module_param.frame_timeout) {
- err = wait_event_interruptible
- (cam->wait_frame,
- (!list_empty(&cam->outqueue)) ||
- (cam->state & DEV_DISCONNECTED) ||
- (cam->state & DEV_MISCONFIGURED));
- if (err)
- return err;
- } else {
- timeout = wait_event_interruptible_timeout
- (cam->wait_frame,
- (!list_empty(&cam->outqueue)) ||
- (cam->state & DEV_DISCONNECTED) ||
- (cam->state & DEV_MISCONFIGURED),
- cam->module_param.frame_timeout *
- 1000 * msecs_to_jiffies(1));
- if (timeout < 0)
- return timeout;
- else if (timeout == 0 &&
- !(cam->state & DEV_DISCONNECTED)) {
- DBG(1, "Video frame timeout elapsed");
- return -EIO;
- }
- }
- if (cam->state & DEV_DISCONNECTED)
- return -ENODEV;
- if (cam->state & DEV_MISCONFIGURED)
- return -EIO;
- }
-
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- f = list_entry(cam->outqueue.next, struct sn9c102_frame_t, frame);
- list_del(cam->outqueue.next);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
-
- f->state = F_UNUSED;
-
- b = f->buf;
- if (f->vma_use_count)
- b.flags |= V4L2_BUF_FLAG_MAPPED;
-
- if (copy_to_user(arg, &b, sizeof(b)))
- return -EFAULT;
-
- PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index);
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_streamon(struct sn9c102_device *cam, void __user *arg)
-{
- int type;
-
- if (copy_from_user(&type, arg, sizeof(type)))
- return -EFAULT;
-
- if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
- return -EINVAL;
-
- cam->stream = STREAM_ON;
-
- DBG(3, "Stream on");
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_streamoff(struct sn9c102_device *cam, void __user *arg)
-{
- int type, err;
-
- if (copy_from_user(&type, arg, sizeof(type)))
- return -EFAULT;
-
- if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
- return -EINVAL;
-
- if (cam->stream == STREAM_ON) {
- err = sn9c102_stream_interrupt(cam);
- if (err)
- return err;
- }
-
- sn9c102_empty_framequeues(cam);
-
- DBG(3, "Stream off");
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_g_parm(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_streamparm sp;
-
- if (copy_from_user(&sp, arg, sizeof(sp)))
- return -EFAULT;
-
- if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- sp.parm.capture.extendedmode = 0;
- sp.parm.capture.readbuffers = cam->nreadbuffers;
-
- if (copy_to_user(arg, &sp, sizeof(sp)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_s_parm(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_streamparm sp;
-
- if (copy_from_user(&sp, arg, sizeof(sp)))
- return -EFAULT;
-
- if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- sp.parm.capture.extendedmode = 0;
-
- if (sp.parm.capture.readbuffers == 0)
- sp.parm.capture.readbuffers = cam->nreadbuffers;
-
- if (sp.parm.capture.readbuffers > SN9C102_MAX_FRAMES)
- sp.parm.capture.readbuffers = SN9C102_MAX_FRAMES;
-
- if (copy_to_user(arg, &sp, sizeof(sp)))
- return -EFAULT;
-
- cam->nreadbuffers = sp.parm.capture.readbuffers;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_enumaudio(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_audio audio;
-
- if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
- return -EINVAL;
-
- if (copy_from_user(&audio, arg, sizeof(audio)))
- return -EFAULT;
-
- if (audio.index != 0)
- return -EINVAL;
-
- strcpy(audio.name, "Microphone");
- audio.capability = 0;
- audio.mode = 0;
-
- if (copy_to_user(arg, &audio, sizeof(audio)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_g_audio(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_audio audio;
-
- if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
- return -EINVAL;
-
- if (copy_from_user(&audio, arg, sizeof(audio)))
- return -EFAULT;
-
- memset(&audio, 0, sizeof(audio));
- strcpy(audio.name, "Microphone");
-
- if (copy_to_user(arg, &audio, sizeof(audio)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_s_audio(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_audio audio;
-
- if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
- return -EINVAL;
-
- if (copy_from_user(&audio, arg, sizeof(audio)))
- return -EFAULT;
-
- if (audio.index != 0)
- return -EINVAL;
-
- return 0;
-}
-
-
-static long sn9c102_ioctl_v4l2(struct file *filp,
- unsigned int cmd, void __user *arg)
-{
- struct sn9c102_device *cam = video_drvdata(filp);
-
- switch (cmd) {
-
- case VIDIOC_QUERYCAP:
- return sn9c102_vidioc_querycap(cam, arg);
-
- case VIDIOC_ENUMINPUT:
- return sn9c102_vidioc_enuminput(cam, arg);
-
- case VIDIOC_G_INPUT:
- return sn9c102_vidioc_g_input(cam, arg);
-
- case VIDIOC_S_INPUT:
- return sn9c102_vidioc_s_input(cam, arg);
-
- case VIDIOC_QUERYCTRL:
- return sn9c102_vidioc_query_ctrl(cam, arg);
-
- case VIDIOC_G_CTRL:
- return sn9c102_vidioc_g_ctrl(cam, arg);
-
- case VIDIOC_S_CTRL:
- return sn9c102_vidioc_s_ctrl(cam, arg);
-
- case VIDIOC_CROPCAP:
- return sn9c102_vidioc_cropcap(cam, arg);
-
- case VIDIOC_G_CROP:
- return sn9c102_vidioc_g_crop(cam, arg);
-
- case VIDIOC_S_CROP:
- return sn9c102_vidioc_s_crop(cam, arg);
-
- case VIDIOC_ENUM_FRAMESIZES:
- return sn9c102_vidioc_enum_framesizes(cam, arg);
-
- case VIDIOC_ENUM_FMT:
- return sn9c102_vidioc_enum_fmt(cam, arg);
-
- case VIDIOC_G_FMT:
- return sn9c102_vidioc_g_fmt(cam, arg);
-
- case VIDIOC_TRY_FMT:
- case VIDIOC_S_FMT:
- return sn9c102_vidioc_try_s_fmt(cam, cmd, arg);
-
- case VIDIOC_G_JPEGCOMP:
- return sn9c102_vidioc_g_jpegcomp(cam, arg);
-
- case VIDIOC_S_JPEGCOMP:
- return sn9c102_vidioc_s_jpegcomp(cam, arg);
-
- case VIDIOC_REQBUFS:
- return sn9c102_vidioc_reqbufs(cam, arg);
-
- case VIDIOC_QUERYBUF:
- return sn9c102_vidioc_querybuf(cam, arg);
-
- case VIDIOC_QBUF:
- return sn9c102_vidioc_qbuf(cam, arg);
-
- case VIDIOC_DQBUF:
- return sn9c102_vidioc_dqbuf(cam, filp, arg);
-
- case VIDIOC_STREAMON:
- return sn9c102_vidioc_streamon(cam, arg);
-
- case VIDIOC_STREAMOFF:
- return sn9c102_vidioc_streamoff(cam, arg);
-
- case VIDIOC_G_PARM:
- return sn9c102_vidioc_g_parm(cam, arg);
-
- case VIDIOC_S_PARM:
- return sn9c102_vidioc_s_parm(cam, arg);
-
- case VIDIOC_ENUMAUDIO:
- return sn9c102_vidioc_enumaudio(cam, arg);
-
- case VIDIOC_G_AUDIO:
- return sn9c102_vidioc_g_audio(cam, arg);
-
- case VIDIOC_S_AUDIO:
- return sn9c102_vidioc_s_audio(cam, arg);
-
- default:
- return -ENOTTY;
-
- }
-}
-
-
-static long sn9c102_ioctl(struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- struct sn9c102_device *cam = video_drvdata(filp);
- int err = 0;
-
- if (mutex_lock_interruptible(&cam->fileop_mutex))
- return -ERESTARTSYS;
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- DBG(1, "The camera is misconfigured. Close and open it "
- "again.");
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
-
- V4LDBG(3, "sn9c102", cmd);
-
- err = sn9c102_ioctl_v4l2(filp, cmd, (void __user *)arg);
-
- mutex_unlock(&cam->fileop_mutex);
-
- return err;
-}
-
-/*****************************************************************************/
-
-static const struct v4l2_file_operations sn9c102_fops = {
- .owner = THIS_MODULE,
- .open = sn9c102_open,
- .release = sn9c102_release,
- .unlocked_ioctl = sn9c102_ioctl,
- .read = sn9c102_read,
- .poll = sn9c102_poll,
- .mmap = sn9c102_mmap,
-};
-
-/*****************************************************************************/
-
-/* It exists a single interface only. We do not need to validate anything. */
-static int
-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;
- unsigned int i;
- int err = 0, r;
-
- cam = kzalloc(sizeof(struct sn9c102_device), GFP_KERNEL);
- if (!cam)
- return -ENOMEM;
-
- cam->usbdev = udev;
-
- /* register v4l2_device early so it can be used for printks */
- if (v4l2_device_register(&intf->dev, &cam->v4l2_dev)) {
- dev_err(&intf->dev, "v4l2_device_register failed\n");
- err = -ENOMEM;
- goto fail;
- }
-
- cam->control_buffer = kzalloc(8, GFP_KERNEL);
- if (!cam->control_buffer) {
- DBG(1, "kzalloc() failed");
- err = -ENOMEM;
- goto fail;
- }
-
- cam->v4ldev = video_device_alloc();
- if (!cam->v4ldev) {
- DBG(1, "video_device_alloc() failed");
- err = -ENOMEM;
- goto fail;
- }
-
- r = sn9c102_read_reg(cam, 0x00);
- if (r < 0 || (r != 0x10 && r != 0x11 && r != 0x12)) {
- DBG(1, "Sorry, this is not a SN9C1xx-based camera "
- "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
- err = -ENODEV;
- goto fail;
- }
-
- cam->bridge = id->driver_info;
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- DBG(2, "SN9C10[12] PC Camera Controller detected "
- "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
- break;
- case BRIDGE_SN9C103:
- DBG(2, "SN9C103 PC Camera Controller detected "
- "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
- break;
- case BRIDGE_SN9C105:
- DBG(2, "SN9C105 PC Camera Controller detected "
- "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
- break;
- case BRIDGE_SN9C120:
- DBG(2, "SN9C120 PC Camera Controller detected "
- "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
- break;
- }
-
- for (i = 0; i < ARRAY_SIZE(sn9c102_sensor_table); i++) {
- err = sn9c102_sensor_table[i](cam);
- if (!err)
- break;
- }
-
- if (!err) {
- DBG(2, "%s image sensor detected", cam->sensor.name);
- DBG(3, "Support for %s maintained by %s",
- cam->sensor.name, cam->sensor.maintainer);
- } else {
- DBG(1, "No supported image sensor detected for this bridge");
- err = -ENODEV;
- goto fail;
- }
-
- if (!(cam->bridge & cam->sensor.supported_bridge)) {
- DBG(1, "Bridge not supported");
- err = -ENODEV;
- goto fail;
- }
-
- if (sn9c102_init(cam)) {
- DBG(1, "Initialization failed. I will retry on open().");
- cam->state |= DEV_MISCONFIGURED;
- }
-
- strcpy(cam->v4ldev->name, "SN9C1xx PC Camera");
- cam->v4ldev->fops = &sn9c102_fops;
- cam->v4ldev->release = video_device_release;
- cam->v4ldev->v4l2_dev = &cam->v4l2_dev;
-
- init_completion(&cam->probe);
-
- err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
- video_nr[dev_nr]);
- if (err) {
- DBG(1, "V4L2 device registration failed");
- if (err == -ENFILE && video_nr[dev_nr] == -1)
- DBG(1, "Free /dev/videoX node not found");
- video_nr[dev_nr] = -1;
- dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
- complete_all(&cam->probe);
- goto fail;
- }
-
- DBG(2, "V4L2 device registered as %s",
- video_device_node_name(cam->v4ldev));
-
- video_set_drvdata(cam->v4ldev, cam);
- cam->module_param.force_munmap = force_munmap[dev_nr];
- cam->module_param.frame_timeout = frame_timeout[dev_nr];
-
- dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- err = sn9c102_create_sysfs(cam);
- if (!err)
- DBG(2, "Optional device control through 'sysfs' "
- "interface ready");
- else
- DBG(2, "Failed to create optional 'sysfs' interface for "
- "device controlling. Error #%d", err);
-#else
- DBG(2, "Optional device control through 'sysfs' interface disabled");
- DBG(3, "Compile the kernel with the 'CONFIG_VIDEO_ADV_DEBUG' "
- "configuration option to enable it.");
-#endif
-
- usb_set_intfdata(intf, cam);
- kref_init(&cam->kref);
- usb_get_dev(cam->usbdev);
-
- complete_all(&cam->probe);
-
- return 0;
-
-fail:
- if (cam) {
- kfree(cam->control_buffer);
- if (cam->v4ldev)
- video_device_release(cam->v4ldev);
- v4l2_device_unregister(&cam->v4l2_dev);
- kfree(cam);
- }
- return err;
-}
-
-
-static void sn9c102_usb_disconnect(struct usb_interface *intf)
-{
- struct sn9c102_device *cam;
-
- down_write(&sn9c102_dev_lock);
-
- cam = usb_get_intfdata(intf);
-
- DBG(2, "Disconnecting %s...", cam->v4ldev->name);
-
- if (cam->users) {
- DBG(2, "Device %s is open! Deregistration and memory "
- "deallocation are deferred.",
- video_device_node_name(cam->v4ldev));
- cam->state |= DEV_MISCONFIGURED;
- sn9c102_stop_transfer(cam);
- cam->state |= DEV_DISCONNECTED;
- wake_up_interruptible(&cam->wait_frame);
- wake_up(&cam->wait_stream);
- } else
- cam->state |= DEV_DISCONNECTED;
-
- wake_up_interruptible_all(&cam->wait_open);
-
- v4l2_device_disconnect(&cam->v4l2_dev);
-
- kref_put(&cam->kref, sn9c102_release_resources);
-
- up_write(&sn9c102_dev_lock);
-}
-
-
-static struct usb_driver sn9c102_usb_driver = {
- .name = "sn9c102",
- .id_table = sn9c102_id_table,
- .probe = sn9c102_usb_probe,
- .disconnect = sn9c102_usb_disconnect,
-};
-
-module_usb_driver(sn9c102_usb_driver);
diff --git a/drivers/staging/media/sn9c102/sn9c102_devtable.h b/drivers/staging/media/sn9c102/sn9c102_devtable.h
deleted file mode 100644
index b187a8a304eb..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_devtable.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/***************************************************************************
- * Table of device identifiers of the SN9C1xx PC Camera Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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 _SN9C102_DEVTABLE_H_
-#define _SN9C102_DEVTABLE_H_
-
-#include <linux/usb.h>
-
-struct sn9c102_device;
-
-/*
- Each SN9C1xx camera has proper PID/VID identifiers.
- SN9C103, SN9C105, SN9C120 support multiple interfaces, but we only have to
- handle the video class interface.
-*/
-#define SN9C102_USB_DEVICE(vend, prod, bridge) \
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
- USB_DEVICE_ID_MATCH_INT_CLASS, \
- .idVendor = (vend), \
- .idProduct = (prod), \
- .bInterfaceClass = 0xff, \
- .driver_info = (bridge)
-
-static const struct usb_device_id sn9c102_id_table[] = {
- /* SN9C101 and SN9C102 */
-#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
- { SN9C102_USB_DEVICE(0x0c45, 0x6001, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6005, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6007, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), }, OV6650 */
- { SN9C102_USB_DEVICE(0x0c45, 0x6019, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6024, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6025, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6028, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6029, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), },
-#endif
- { SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), }, /* not in sonixb */
-#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
- { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */
- { SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), },
-#endif
- { SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), }, /* not in sonixb */
- /* SN9C103 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6080, BRIDGE_SN9C103), }, non existent ? */
- { SN9C102_USB_DEVICE(0x0c45, 0x6082, BRIDGE_SN9C103), }, /* not in sonixb */
-#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6083, BRIDGE_SN9C103), }, HY7131D/E */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6088, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x608a, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x608b, BRIDGE_SN9C103), }, non existent ? */
- { SN9C102_USB_DEVICE(0x0c45, 0x608c, BRIDGE_SN9C103), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x608e, BRIDGE_SN9C103), }, CISVF10 */
- { SN9C102_USB_DEVICE(0x0c45, 0x608f, BRIDGE_SN9C103), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60a0, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60a2, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60a3, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60a8, BRIDGE_SN9C103), }, PAS106 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60aa, BRIDGE_SN9C103), }, TAS5130 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ab, BRIDGE_SN9C103), }, TAS5110, non existent */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ac, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ae, BRIDGE_SN9C103), }, non existent ? */
- { SN9C102_USB_DEVICE(0x0c45, 0x60af, BRIDGE_SN9C103), },
- { SN9C102_USB_DEVICE(0x0c45, 0x60b0, BRIDGE_SN9C103), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60b2, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60b3, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60b8, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ba, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60bb, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60bc, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60be, BRIDGE_SN9C103), }, non existent ? */
-#endif
- /* SN9C105 */
-#if !defined CONFIG_USB_GSPCA_SONIXJ && !defined CONFIG_USB_GSPCA_SONIXJ_MODULE
- { SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), },
- { SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), },
- { SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), },
- { SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), },
- { SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60c2, BRIDGE_SN9C105), }, PO1030 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60c8, BRIDGE_SN9C105), }, OM6801 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60cc, BRIDGE_SN9C105), }, HV7131GP */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ea, BRIDGE_SN9C105), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ec, BRIDGE_SN9C105), }, MO4000 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ef, BRIDGE_SN9C105), }, ICM105C */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60fa, BRIDGE_SN9C105), }, OV7648 */
- { SN9C102_USB_DEVICE(0x0c45, 0x60fb, BRIDGE_SN9C105), },
- { SN9C102_USB_DEVICE(0x0c45, 0x60fc, BRIDGE_SN9C105), },
- { SN9C102_USB_DEVICE(0x0c45, 0x60fe, BRIDGE_SN9C105), },
- /* SN9C120 */
- { SN9C102_USB_DEVICE(0x0458, 0x7025, BRIDGE_SN9C120), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6102, BRIDGE_SN9C120), }, po2030 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), }, om6801 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), }, S5K53BEB */
- { SN9C102_USB_DEVICE(0x0c45, 0x6130, BRIDGE_SN9C120), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6138, BRIDGE_SN9C120), }, MO8000 */
- { SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), },
- { SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), },
- { SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), },
- { SN9C102_USB_DEVICE(0x0c45, 0x613e, BRIDGE_SN9C120), },
-#endif
- { }
-};
-
-/*
- Probing functions: on success, you must attach the sensor to the camera
- by calling sn9c102_attach_sensor().
- To enable the I2C communication, you might need to perform a really basic
- initialization of the SN9C1XX chip.
- Functions must return 0 on success, the appropriate error otherwise.
-*/
-extern int sn9c102_probe_hv7131d(struct sn9c102_device *cam);
-extern int sn9c102_probe_hv7131r(struct sn9c102_device *cam);
-extern int sn9c102_probe_mi0343(struct sn9c102_device *cam);
-extern int sn9c102_probe_mi0360(struct sn9c102_device *cam);
-extern int sn9c102_probe_mt9v111(struct sn9c102_device *cam);
-extern int sn9c102_probe_ov7630(struct sn9c102_device *cam);
-extern int sn9c102_probe_ov7660(struct sn9c102_device *cam);
-extern int sn9c102_probe_pas106b(struct sn9c102_device *cam);
-extern int sn9c102_probe_pas202bcb(struct sn9c102_device *cam);
-extern int sn9c102_probe_tas5110c1b(struct sn9c102_device *cam);
-extern int sn9c102_probe_tas5110d(struct sn9c102_device *cam);
-extern int sn9c102_probe_tas5130d1b(struct sn9c102_device *cam);
-
-#endif /* _SN9C102_DEVTABLE_H_ */
diff --git a/drivers/staging/media/sn9c102/sn9c102_hv7131d.c b/drivers/staging/media/sn9c102/sn9c102_hv7131d.c
deleted file mode 100644
index f1d94f0190c6..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_hv7131d.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/***************************************************************************
- * Plug-in for HV7131D image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int hv7131d_init(struct sn9c102_device *cam)
-{
- int err;
-
- err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
- {0x00, 0x14}, {0x60, 0x17},
- {0x0e, 0x18}, {0xf2, 0x19});
-
- err += sn9c102_i2c_write(cam, 0x01, 0x04);
- err += sn9c102_i2c_write(cam, 0x02, 0x00);
- err += sn9c102_i2c_write(cam, 0x28, 0x00);
-
- return err;
-}
-
-
-static int hv7131d_get_ctrl(struct sn9c102_device *cam,
- struct v4l2_control *ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- {
- int r1 = sn9c102_i2c_read(cam, 0x26),
- r2 = sn9c102_i2c_read(cam, 0x27);
- if (r1 < 0 || r2 < 0)
- return -EIO;
- ctrl->value = (r1 << 8) | (r2 & 0xff);
- }
- return 0;
- case V4L2_CID_RED_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x31);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = 0x3f - (ctrl->value & 0x3f);
- return 0;
- case V4L2_CID_BLUE_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x33);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = 0x3f - (ctrl->value & 0x3f);
- return 0;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x32);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = 0x3f - (ctrl->value & 0x3f);
- return 0;
- case SN9C102_V4L2_CID_RESET_LEVEL:
- ctrl->value = sn9c102_i2c_read(cam, 0x30);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x3f;
- return 0;
- case SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE:
- ctrl->value = sn9c102_i2c_read(cam, 0x34);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x07;
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-
-static int hv7131d_set_ctrl(struct sn9c102_device *cam,
- const struct v4l2_control *ctrl)
-{
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_write(cam, 0x26, ctrl->value >> 8);
- err += sn9c102_i2c_write(cam, 0x27, ctrl->value & 0xff);
- break;
- case V4L2_CID_RED_BALANCE:
- err += sn9c102_i2c_write(cam, 0x31, 0x3f - ctrl->value);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_i2c_write(cam, 0x33, 0x3f - ctrl->value);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_i2c_write(cam, 0x32, 0x3f - ctrl->value);
- break;
- case SN9C102_V4L2_CID_RESET_LEVEL:
- err += sn9c102_i2c_write(cam, 0x30, ctrl->value);
- break;
- case SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE:
- err += sn9c102_i2c_write(cam, 0x34, ctrl->value);
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int hv7131d_set_crop(struct sn9c102_device *cam,
- const struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 2,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 2;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static int hv7131d_set_pix_format(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix)
-{
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
- err += sn9c102_write_reg(cam, 0x42, 0x19);
- else
- err += sn9c102_write_reg(cam, 0xf2, 0x19);
-
- return err;
-}
-
-
-static const struct sn9c102_sensor hv7131d = {
- .name = "HV7131D",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
- .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x11,
- .init = &hv7131d_init,
- .qctrl = {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x0250,
- .maximum = 0xffff,
- .step = 0x0001,
- .default_value = 0x0250,
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x20,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x1e,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_RESET_LEVEL,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "reset level",
- .minimum = 0x19,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x30,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "pixel bias voltage",
- .minimum = 0x00,
- .maximum = 0x07,
- .step = 0x01,
- .default_value = 0x02,
- .flags = 0,
- },
- },
- .get_ctrl = &hv7131d_get_ctrl,
- .set_ctrl = &hv7131d_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &hv7131d_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &hv7131d_set_pix_format
-};
-
-
-int sn9c102_probe_hv7131d(struct sn9c102_device *cam)
-{
- int r0 = 0, r1 = 0, err;
-
- err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
- {0x28, 0x17});
-
- r0 = sn9c102_i2c_try_read(cam, &hv7131d, 0x00);
- r1 = sn9c102_i2c_try_read(cam, &hv7131d, 0x01);
- if (err || r0 < 0 || r1 < 0)
- return -EIO;
-
- if ((r0 != 0x00 && r0 != 0x01) || r1 != 0x04)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &hv7131d);
-
- return 0;
-}
diff --git a/drivers/staging/media/sn9c102/sn9c102_hv7131r.c b/drivers/staging/media/sn9c102/sn9c102_hv7131r.c
deleted file mode 100644
index 51b24e000e88..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_hv7131r.c
+++ /dev/null
@@ -1,369 +0,0 @@
-/***************************************************************************
- * Plug-in for HV7131R image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int hv7131r_init(struct sn9c102_device *cam)
-{
- int err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C103:
- err = sn9c102_write_const_regs(cam, {0x00, 0x03}, {0x1a, 0x04},
- {0x20, 0x05}, {0x20, 0x06},
- {0x03, 0x10}, {0x00, 0x14},
- {0x60, 0x17}, {0x0a, 0x18},
- {0xf0, 0x19}, {0x1d, 0x1a},
- {0x10, 0x1b}, {0x02, 0x1c},
- {0x03, 0x1d}, {0x0f, 0x1e},
- {0x0c, 0x1f}, {0x00, 0x20},
- {0x10, 0x21}, {0x20, 0x22},
- {0x30, 0x23}, {0x40, 0x24},
- {0x50, 0x25}, {0x60, 0x26},
- {0x70, 0x27}, {0x80, 0x28},
- {0x90, 0x29}, {0xa0, 0x2a},
- {0xb0, 0x2b}, {0xc0, 0x2c},
- {0xd0, 0x2d}, {0xe0, 0x2e},
- {0xf0, 0x2f}, {0xff, 0x30});
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02},
- {0x00, 0x03}, {0x1a, 0x04},
- {0x44, 0x05}, {0x3e, 0x06},
- {0x1a, 0x07}, {0x03, 0x10},
- {0x08, 0x14}, {0xa3, 0x17},
- {0x4b, 0x18}, {0x00, 0x19},
- {0x1d, 0x1a}, {0x10, 0x1b},
- {0x02, 0x1c}, {0x03, 0x1d},
- {0x0f, 0x1e}, {0x0c, 0x1f},
- {0x00, 0x20}, {0x29, 0x21},
- {0x40, 0x22}, {0x54, 0x23},
- {0x66, 0x24}, {0x76, 0x25},
- {0x85, 0x26}, {0x94, 0x27},
- {0xa1, 0x28}, {0xae, 0x29},
- {0xbb, 0x2a}, {0xc7, 0x2b},
- {0xd3, 0x2c}, {0xde, 0x2d},
- {0xea, 0x2e}, {0xf4, 0x2f},
- {0xff, 0x30}, {0x00, 0x3F},
- {0xC7, 0x40}, {0x01, 0x41},
- {0x44, 0x42}, {0x00, 0x43},
- {0x44, 0x44}, {0x00, 0x45},
- {0x44, 0x46}, {0x00, 0x47},
- {0xC7, 0x48}, {0x01, 0x49},
- {0xC7, 0x4A}, {0x01, 0x4B},
- {0xC7, 0x4C}, {0x01, 0x4D},
- {0x44, 0x4E}, {0x00, 0x4F},
- {0x44, 0x50}, {0x00, 0x51},
- {0x44, 0x52}, {0x00, 0x53},
- {0xC7, 0x54}, {0x01, 0x55},
- {0xC7, 0x56}, {0x01, 0x57},
- {0xC7, 0x58}, {0x01, 0x59},
- {0x44, 0x5A}, {0x00, 0x5B},
- {0x44, 0x5C}, {0x00, 0x5D},
- {0x44, 0x5E}, {0x00, 0x5F},
- {0xC7, 0x60}, {0x01, 0x61},
- {0xC7, 0x62}, {0x01, 0x63},
- {0xC7, 0x64}, {0x01, 0x65},
- {0x44, 0x66}, {0x00, 0x67},
- {0x44, 0x68}, {0x00, 0x69},
- {0x44, 0x6A}, {0x00, 0x6B},
- {0xC7, 0x6C}, {0x01, 0x6D},
- {0xC7, 0x6E}, {0x01, 0x6F},
- {0xC7, 0x70}, {0x01, 0x71},
- {0x44, 0x72}, {0x00, 0x73},
- {0x44, 0x74}, {0x00, 0x75},
- {0x44, 0x76}, {0x00, 0x77},
- {0xC7, 0x78}, {0x01, 0x79},
- {0xC7, 0x7A}, {0x01, 0x7B},
- {0xC7, 0x7C}, {0x01, 0x7D},
- {0x44, 0x7E}, {0x00, 0x7F},
- {0x14, 0x84}, {0x00, 0x85},
- {0x27, 0x86}, {0x00, 0x87},
- {0x07, 0x88}, {0x00, 0x89},
- {0xEC, 0x8A}, {0x0f, 0x8B},
- {0xD8, 0x8C}, {0x0f, 0x8D},
- {0x3D, 0x8E}, {0x00, 0x8F},
- {0x3D, 0x90}, {0x00, 0x91},
- {0xCD, 0x92}, {0x0f, 0x93},
- {0xf7, 0x94}, {0x0f, 0x95},
- {0x0C, 0x96}, {0x00, 0x97},
- {0x00, 0x98}, {0x66, 0x99},
- {0x05, 0x9A}, {0x00, 0x9B},
- {0x04, 0x9C}, {0x00, 0x9D},
- {0x08, 0x9E}, {0x00, 0x9F},
- {0x2D, 0xC0}, {0x2D, 0xC1},
- {0x3A, 0xC2}, {0x05, 0xC3},
- {0x04, 0xC4}, {0x3F, 0xC5},
- {0x00, 0xC6}, {0x00, 0xC7},
- {0x50, 0xC8}, {0x3C, 0xC9},
- {0x28, 0xCA}, {0xD8, 0xCB},
- {0x14, 0xCC}, {0xEC, 0xCD},
- {0x32, 0xCE}, {0xDD, 0xCF},
- {0x32, 0xD0}, {0xDD, 0xD1},
- {0x6A, 0xD2}, {0x50, 0xD3},
- {0x00, 0xD4}, {0x00, 0xD5},
- {0x00, 0xD6});
- break;
- default:
- break;
- }
-
- err += sn9c102_i2c_write(cam, 0x20, 0x00);
- err += sn9c102_i2c_write(cam, 0x21, 0xd6);
- err += sn9c102_i2c_write(cam, 0x25, 0x06);
-
- return err;
-}
-
-
-static int hv7131r_get_ctrl(struct sn9c102_device *cam,
- struct v4l2_control *ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- ctrl->value = sn9c102_i2c_read(cam, 0x30);
- if (ctrl->value < 0)
- return -EIO;
- return 0;
- case V4L2_CID_RED_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x31);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = ctrl->value & 0x3f;
- return 0;
- case V4L2_CID_BLUE_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x33);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = ctrl->value & 0x3f;
- return 0;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x32);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = ctrl->value & 0x3f;
- return 0;
- case V4L2_CID_BLACK_LEVEL:
- ctrl->value = sn9c102_i2c_read(cam, 0x01);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = (ctrl->value & 0x08) ? 1 : 0;
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-
-static int hv7131r_set_ctrl(struct sn9c102_device *cam,
- const struct v4l2_control *ctrl)
-{
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_write(cam, 0x30, ctrl->value);
- break;
- case V4L2_CID_RED_BALANCE:
- err += sn9c102_i2c_write(cam, 0x31, ctrl->value);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_i2c_write(cam, 0x33, ctrl->value);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_i2c_write(cam, 0x32, ctrl->value);
- break;
- case V4L2_CID_BLACK_LEVEL:
- {
- int r = sn9c102_i2c_read(cam, 0x01);
-
- if (r < 0)
- return -EIO;
- err += sn9c102_i2c_write(cam, 0x01,
- (ctrl->value<<3) | (r&0xf7));
- }
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int hv7131r_set_crop(struct sn9c102_device *cam,
- const struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static int hv7131r_set_pix_format(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix)
-{
- int err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C103:
- if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
- err += sn9c102_write_reg(cam, 0xa0, 0x19);
- err += sn9c102_i2c_write(cam, 0x01, 0x04);
- } else {
- err += sn9c102_write_reg(cam, 0x30, 0x19);
- err += sn9c102_i2c_write(cam, 0x01, 0x04);
- }
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
- err += sn9c102_write_reg(cam, 0xa5, 0x17);
- err += sn9c102_i2c_write(cam, 0x01, 0x24);
- } else {
- err += sn9c102_write_reg(cam, 0xa3, 0x17);
- err += sn9c102_i2c_write(cam, 0x01, 0x04);
- }
- break;
- default:
- break;
- }
-
- return err;
-}
-
-
-static const struct sn9c102_sensor hv7131r = {
- .name = "HV7131R",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
- .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x11,
- .init = &hv7131r_init,
- .qctrl = {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x01,
- .default_value = 0x40,
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x08,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x1a,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x2f,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLACK_LEVEL,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "auto black level compensation",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- },
- .get_ctrl = &hv7131r_get_ctrl,
- .set_ctrl = &hv7131r_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &hv7131r_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &hv7131r_set_pix_format
-};
-
-
-int sn9c102_probe_hv7131r(struct sn9c102_device *cam)
-{
- int devid, err;
-
- err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x44, 0x02},
- {0x34, 0x01}, {0x20, 0x17},
- {0x34, 0x01}, {0x46, 0x01});
-
- devid = sn9c102_i2c_try_read(cam, &hv7131r, 0x00);
- if (err || devid < 0)
- return -EIO;
-
- if (devid != 0x02)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &hv7131r);
-
- return 0;
-}
diff --git a/drivers/staging/media/sn9c102/sn9c102_mi0343.c b/drivers/staging/media/sn9c102/sn9c102_mi0343.c
deleted file mode 100644
index b20fdb6541d3..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_mi0343.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/***************************************************************************
- * Plug-in for MI-0343 image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int mi0343_init(struct sn9c102_device *cam)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
-
- err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
- {0x0a, 0x14}, {0x40, 0x01},
- {0x20, 0x17}, {0x07, 0x18},
- {0xa0, 0x19});
-
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
- 0x00, 0x01, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x03,
- 0x01, 0xe1, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x04,
- 0x02, 0x81, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x05,
- 0x00, 0x17, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x06,
- 0x00, 0x11, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x62,
- 0x04, 0x9a, 0, 0);
-
- return err;
-}
-
-
-static int mi0343_get_ctrl(struct sn9c102_device *cam,
- struct v4l2_control *ctrl)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- u8 data[2];
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[0];
- return 0;
- case V4L2_CID_GAIN:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2,
- data) < 0)
- return -EIO;
- break;
- case V4L2_CID_HFLIP:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1] & 0x20 ? 1 : 0;
- return 0;
- case V4L2_CID_VFLIP:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1] & 0x80 ? 1 : 0;
- return 0;
- case V4L2_CID_RED_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2,
- data) < 0)
- return -EIO;
- break;
- case V4L2_CID_BLUE_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2,
- data) < 0)
- return -EIO;
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2,
- data) < 0)
- return -EIO;
- break;
- default:
- return -EINVAL;
- }
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- case V4L2_CID_RED_BALANCE:
- case V4L2_CID_BLUE_BALANCE:
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- ctrl->value = data[1] | (data[0] << 8);
- if (ctrl->value >= 0x10 && ctrl->value <= 0x3f)
- ctrl->value -= 0x10;
- else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f)
- ctrl->value -= 0x60;
- else if (ctrl->value >= 0xe0 && ctrl->value <= 0xff)
- ctrl->value -= 0xe0;
- }
-
- return 0;
-}
-
-
-static int mi0343_set_ctrl(struct sn9c102_device *cam,
- const struct v4l2_control *ctrl)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- u16 reg = 0;
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- case V4L2_CID_RED_BALANCE:
- case V4L2_CID_BLUE_BALANCE:
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if (ctrl->value <= (0x3f-0x10))
- reg = 0x10 + ctrl->value;
- else if (ctrl->value <= ((0x3f-0x10) + (0x7f-0x60)))
- reg = 0x60 + (ctrl->value - (0x3f-0x10));
- else
- reg = 0xe0 + (ctrl->value - (0x3f-0x10) - (0x7f-0x60));
- break;
- }
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x09, ctrl->value, 0x00,
- 0, 0);
- break;
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x35, reg >> 8, reg & 0xff,
- 0, 0);
- break;
- case V4L2_CID_HFLIP:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x20, ctrl->value ? 0x40:0x00,
- ctrl->value ? 0x20:0x00,
- 0, 0);
- break;
- case V4L2_CID_VFLIP:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x20, ctrl->value ? 0x80:0x00,
- ctrl->value ? 0x80:0x00,
- 0, 0);
- break;
- case V4L2_CID_RED_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2d, reg >> 8, reg & 0xff,
- 0, 0);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2c, reg >> 8, reg & 0xff,
- 0, 0);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2b, reg >> 8, reg & 0xff,
- 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2e, reg >> 8, reg & 0xff,
- 0, 0);
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int mi0343_set_crop(struct sn9c102_device *cam,
- const struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 2;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static int mi0343_set_pix_format(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) {
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x0a, 0x00, 0x03, 0, 0);
- err += sn9c102_write_reg(cam, 0x20, 0x19);
- } else {
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x0a, 0x00, 0x05, 0, 0);
- err += sn9c102_write_reg(cam, 0xa0, 0x19);
- }
-
- return err;
-}
-
-
-static const struct sn9c102_sensor mi0343 = {
- .name = "MI-0343",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x5d,
- .init = &mi0343_init,
- .qctrl = {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0x0f,
- .step = 0x01,
- .default_value = 0x06,
- .flags = 0,
- },
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),/*0x6d*/
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- },
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = ((0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0)),
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- },
- .get_ctrl = &mi0343_get_ctrl,
- .set_ctrl = &mi0343_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &mi0343_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &mi0343_set_pix_format
-};
-
-
-int sn9c102_probe_mi0343(struct sn9c102_device *cam)
-{
- u8 data[2];
-
- if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
- {0x28, 0x17}))
- return -EIO;
-
- if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00,
- 2, data) < 0)
- return -EIO;
-
- if (data[1] != 0x42 || data[0] != 0xe3)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &mi0343);
-
- return 0;
-}
diff --git a/drivers/staging/media/sn9c102/sn9c102_mi0360.c b/drivers/staging/media/sn9c102/sn9c102_mi0360.c
deleted file mode 100644
index 5f21d1b43e32..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_mi0360.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/***************************************************************************
- * Plug-in for MI-0360 image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int mi0360_init(struct sn9c102_device *cam)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C103:
- err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
- {0x0a, 0x14}, {0x40, 0x01},
- {0x20, 0x17}, {0x07, 0x18},
- {0xa0, 0x19}, {0x02, 0x1c},
- {0x03, 0x1d}, {0x0f, 0x1e},
- {0x0c, 0x1f}, {0x00, 0x20},
- {0x10, 0x21}, {0x20, 0x22},
- {0x30, 0x23}, {0x40, 0x24},
- {0x50, 0x25}, {0x60, 0x26},
- {0x70, 0x27}, {0x80, 0x28},
- {0x90, 0x29}, {0xa0, 0x2a},
- {0xb0, 0x2b}, {0xc0, 0x2c},
- {0xd0, 0x2d}, {0xe0, 0x2e},
- {0xf0, 0x2f}, {0xff, 0x30});
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02},
- {0x00, 0x03}, {0x1a, 0x04},
- {0x50, 0x05}, {0x20, 0x06},
- {0x10, 0x07}, {0x03, 0x10},
- {0x08, 0x14}, {0xa2, 0x17},
- {0x47, 0x18}, {0x00, 0x19},
- {0x1d, 0x1a}, {0x10, 0x1b},
- {0x02, 0x1c}, {0x03, 0x1d},
- {0x0f, 0x1e}, {0x0c, 0x1f},
- {0x00, 0x20}, {0x29, 0x21},
- {0x40, 0x22}, {0x54, 0x23},
- {0x66, 0x24}, {0x76, 0x25},
- {0x85, 0x26}, {0x94, 0x27},
- {0xa1, 0x28}, {0xae, 0x29},
- {0xbb, 0x2a}, {0xc7, 0x2b},
- {0xd3, 0x2c}, {0xde, 0x2d},
- {0xea, 0x2e}, {0xf4, 0x2f},
- {0xff, 0x30}, {0x00, 0x3F},
- {0xC7, 0x40}, {0x01, 0x41},
- {0x44, 0x42}, {0x00, 0x43},
- {0x44, 0x44}, {0x00, 0x45},
- {0x44, 0x46}, {0x00, 0x47},
- {0xC7, 0x48}, {0x01, 0x49},
- {0xC7, 0x4A}, {0x01, 0x4B},
- {0xC7, 0x4C}, {0x01, 0x4D},
- {0x44, 0x4E}, {0x00, 0x4F},
- {0x44, 0x50}, {0x00, 0x51},
- {0x44, 0x52}, {0x00, 0x53},
- {0xC7, 0x54}, {0x01, 0x55},
- {0xC7, 0x56}, {0x01, 0x57},
- {0xC7, 0x58}, {0x01, 0x59},
- {0x44, 0x5A}, {0x00, 0x5B},
- {0x44, 0x5C}, {0x00, 0x5D},
- {0x44, 0x5E}, {0x00, 0x5F},
- {0xC7, 0x60}, {0x01, 0x61},
- {0xC7, 0x62}, {0x01, 0x63},
- {0xC7, 0x64}, {0x01, 0x65},
- {0x44, 0x66}, {0x00, 0x67},
- {0x44, 0x68}, {0x00, 0x69},
- {0x44, 0x6A}, {0x00, 0x6B},
- {0xC7, 0x6C}, {0x01, 0x6D},
- {0xC7, 0x6E}, {0x01, 0x6F},
- {0xC7, 0x70}, {0x01, 0x71},
- {0x44, 0x72}, {0x00, 0x73},
- {0x44, 0x74}, {0x00, 0x75},
- {0x44, 0x76}, {0x00, 0x77},
- {0xC7, 0x78}, {0x01, 0x79},
- {0xC7, 0x7A}, {0x01, 0x7B},
- {0xC7, 0x7C}, {0x01, 0x7D},
- {0x44, 0x7E}, {0x00, 0x7F},
- {0x14, 0x84}, {0x00, 0x85},
- {0x27, 0x86}, {0x00, 0x87},
- {0x07, 0x88}, {0x00, 0x89},
- {0xEC, 0x8A}, {0x0f, 0x8B},
- {0xD8, 0x8C}, {0x0f, 0x8D},
- {0x3D, 0x8E}, {0x00, 0x8F},
- {0x3D, 0x90}, {0x00, 0x91},
- {0xCD, 0x92}, {0x0f, 0x93},
- {0xf7, 0x94}, {0x0f, 0x95},
- {0x0C, 0x96}, {0x00, 0x97},
- {0x00, 0x98}, {0x66, 0x99},
- {0x05, 0x9A}, {0x00, 0x9B},
- {0x04, 0x9C}, {0x00, 0x9D},
- {0x08, 0x9E}, {0x00, 0x9F},
- {0x2D, 0xC0}, {0x2D, 0xC1},
- {0x3A, 0xC2}, {0x05, 0xC3},
- {0x04, 0xC4}, {0x3F, 0xC5},
- {0x00, 0xC6}, {0x00, 0xC7},
- {0x50, 0xC8}, {0x3C, 0xC9},
- {0x28, 0xCA}, {0xD8, 0xCB},
- {0x14, 0xCC}, {0xEC, 0xCD},
- {0x32, 0xCE}, {0xDD, 0xCF},
- {0x32, 0xD0}, {0xDD, 0xD1},
- {0x6A, 0xD2}, {0x50, 0xD3},
- {0x00, 0xD4}, {0x00, 0xD5},
- {0x00, 0xD6});
- break;
- default:
- break;
- }
-
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
- 0x00, 0x01, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x03,
- 0x01, 0xe1, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x04,
- 0x02, 0x81, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x05,
- 0x00, 0x17, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x06,
- 0x00, 0x11, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x62,
- 0x04, 0x9a, 0, 0);
-
- return err;
-}
-
-
-static int mi0360_get_ctrl(struct sn9c102_device *cam,
- struct v4l2_control *ctrl)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- u8 data[2];
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[0];
- return 0;
- case V4L2_CID_GAIN:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1];
- return 0;
- case V4L2_CID_RED_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1];
- return 0;
- case V4L2_CID_BLUE_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1];
- return 0;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1];
- return 0;
- case V4L2_CID_HFLIP:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1] & 0x20 ? 1 : 0;
- return 0;
- case V4L2_CID_VFLIP:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1] & 0x80 ? 1 : 0;
- return 0;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-
-static int mi0360_set_ctrl(struct sn9c102_device *cam,
- const struct v4l2_control *ctrl)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x09, ctrl->value, 0x00,
- 0, 0);
- break;
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x35, 0x03, ctrl->value,
- 0, 0);
- break;
- case V4L2_CID_RED_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2c, 0x03, ctrl->value,
- 0, 0);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2d, 0x03, ctrl->value,
- 0, 0);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2b, 0x03, ctrl->value,
- 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2e, 0x03, ctrl->value,
- 0, 0);
- break;
- case V4L2_CID_HFLIP:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x20, ctrl->value ? 0x40:0x00,
- ctrl->value ? 0x20:0x00,
- 0, 0);
- break;
- case V4L2_CID_VFLIP:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x20, ctrl->value ? 0x80:0x00,
- ctrl->value ? 0x80:0x00,
- 0, 0);
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int mi0360_set_crop(struct sn9c102_device *cam,
- const struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = 0, v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C103:
- h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0;
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1;
- break;
- default:
- break;
- }
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static int mi0360_set_pix_format(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x0a, 0x00, 0x05, 0, 0);
- err += sn9c102_write_reg(cam, 0x60, 0x19);
- if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 ||
- sn9c102_get_bridge(cam) == BRIDGE_SN9C120)
- err += sn9c102_write_reg(cam, 0xa6, 0x17);
- } else {
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x0a, 0x00, 0x02, 0, 0);
- err += sn9c102_write_reg(cam, 0x20, 0x19);
- if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 ||
- sn9c102_get_bridge(cam) == BRIDGE_SN9C120)
- err += sn9c102_write_reg(cam, 0xa2, 0x17);
- }
-
- return err;
-}
-
-
-static const struct sn9c102_sensor mi0360 = {
- .name = "MI-0360",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x5d,
- .init = &mi0360_init,
- .qctrl = {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0x0f,
- .step = 0x01,
- .default_value = 0x05,
- .flags = 0,
- },
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x25,
- .flags = 0,
- },
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- },
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x0f,
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x32,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x25,
- .flags = 0,
- },
- },
- .get_ctrl = &mi0360_get_ctrl,
- .set_ctrl = &mi0360_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &mi0360_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &mi0360_set_pix_format
-};
-
-
-int sn9c102_probe_mi0360(struct sn9c102_device *cam)
-{
-
- u8 data[2];
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C103:
- if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
- {0x28, 0x17}))
- return -EIO;
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
- {0x01, 0x01}, {0x00, 0x01},
- {0x28, 0x17}))
- return -EIO;
- break;
- default:
- break;
- }
-
- if (sn9c102_i2c_try_raw_read(cam, &mi0360, mi0360.i2c_slave_id, 0x00,
- 2, data) < 0)
- return -EIO;
-
- if (data[0] != 0x82 || data[1] != 0x43)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &mi0360);
-
- return 0;
-}
diff --git a/drivers/staging/media/sn9c102/sn9c102_mt9v111.c b/drivers/staging/media/sn9c102/sn9c102_mt9v111.c
deleted file mode 100644
index 95986eb492e4..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_mt9v111.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/***************************************************************************
- * Plug-in for MT9V111 image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int mt9v111_init(struct sn9c102_device *cam)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
-
- err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02},
- {0x00, 0x03}, {0x1a, 0x04},
- {0x1f, 0x05}, {0x20, 0x06},
- {0x1f, 0x07}, {0x81, 0x08},
- {0x5c, 0x09}, {0x00, 0x0a},
- {0x00, 0x0b}, {0x00, 0x0c},
- {0x00, 0x0d}, {0x00, 0x0e},
- {0x00, 0x0f}, {0x03, 0x10},
- {0x00, 0x11}, {0x00, 0x12},
- {0x02, 0x13}, {0x14, 0x14},
- {0x28, 0x15}, {0x1e, 0x16},
- {0xe2, 0x17}, {0x06, 0x18},
- {0x00, 0x19}, {0x00, 0x1a},
- {0x00, 0x1b}, {0x08, 0x20},
- {0x39, 0x21}, {0x51, 0x22},
- {0x63, 0x23}, {0x73, 0x24},
- {0x82, 0x25}, {0x8f, 0x26},
- {0x9b, 0x27}, {0xa7, 0x28},
- {0xb1, 0x29}, {0xbc, 0x2a},
- {0xc6, 0x2b}, {0xcf, 0x2c},
- {0xd8, 0x2d}, {0xe1, 0x2e},
- {0xea, 0x2f}, {0xf2, 0x30},
- {0x13, 0x84}, {0x00, 0x85},
- {0x25, 0x86}, {0x00, 0x87},
- {0x07, 0x88}, {0x00, 0x89},
- {0xee, 0x8a}, {0x0f, 0x8b},
- {0xe5, 0x8c}, {0x0f, 0x8d},
- {0x2e, 0x8e}, {0x00, 0x8f},
- {0x30, 0x90}, {0x00, 0x91},
- {0xd4, 0x92}, {0x0f, 0x93},
- {0xfc, 0x94}, {0x0f, 0x95},
- {0x14, 0x96}, {0x00, 0x97},
- {0x00, 0x98}, {0x60, 0x99},
- {0x07, 0x9a}, {0x40, 0x9b},
- {0x20, 0x9c}, {0x00, 0x9d},
- {0x00, 0x9e}, {0x00, 0x9f},
- {0x2d, 0xc0}, {0x2d, 0xc1},
- {0x3a, 0xc2}, {0x05, 0xc3},
- {0x04, 0xc4}, {0x3f, 0xc5},
- {0x00, 0xc6}, {0x00, 0xc7},
- {0x50, 0xc8}, {0x3c, 0xc9},
- {0x28, 0xca}, {0xd8, 0xcb},
- {0x14, 0xcc}, {0xec, 0xcd},
- {0x32, 0xce}, {0xdd, 0xcf},
- {0x2d, 0xd0}, {0xdd, 0xd1},
- {0x6a, 0xd2}, {0x50, 0xd3},
- {0x60, 0xd4}, {0x00, 0xd5},
- {0x00, 0xd6});
-
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x01,
- 0x00, 0x01, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
- 0x00, 0x01, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x08,
- 0x04, 0x80, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x01,
- 0x00, 0x04, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x08,
- 0x00, 0x08, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x02,
- 0x00, 0x16, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x03,
- 0x01, 0xe7, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x04,
- 0x02, 0x87, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x06,
- 0x00, 0x40, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x05,
- 0x00, 0x09, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x07,
- 0x30, 0x02, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0c,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x12,
- 0x00, 0xb0, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x13,
- 0x00, 0x7c, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x1e,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x20,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x20,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x01,
- 0x00, 0x04, 0, 0);
-
- return err;
-}
-
-static int mt9v111_get_ctrl(struct sn9c102_device *cam,
- struct v4l2_control *ctrl)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- u8 data[2];
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_VFLIP:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1] & 0x80 ? 1 : 0;
- return 0;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-static int mt9v111_set_ctrl(struct sn9c102_device *cam,
- const struct v4l2_control *ctrl)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_VFLIP:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x20,
- ctrl->value ? 0x80 : 0x00,
- ctrl->value ? 0x80 : 0x00, 0,
- 0);
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-static int mt9v111_set_crop(struct sn9c102_device *cam,
- const struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 v_start = (u8) (rect->top - s->cropcap.bounds.top) + 2;
-
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-static int mt9v111_set_pix_format(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix)
-{
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
- err += sn9c102_write_reg(cam, 0xb4, 0x17);
- } else {
- err += sn9c102_write_reg(cam, 0xe2, 0x17);
- }
-
- return err;
-}
-
-
-static const struct sn9c102_sensor mt9v111 = {
- .name = "MT9V111",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C105 | BRIDGE_SN9C120,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x5c,
- .init = &mt9v111_init,
- .qctrl = {
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- },
- },
- .get_ctrl = &mt9v111_get_ctrl,
- .set_ctrl = &mt9v111_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &mt9v111_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &mt9v111_set_pix_format
-};
-
-
-int sn9c102_probe_mt9v111(struct sn9c102_device *cam)
-{
- u8 data[2];
- int err = 0;
-
- err += sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
- {0x29, 0x01}, {0x42, 0x17},
- {0x62, 0x17}, {0x08, 0x01});
- err += sn9c102_i2c_try_raw_write(cam, &mt9v111, 4,
- mt9v111.i2c_slave_id, 0x01, 0x00,
- 0x04, 0, 0);
- if (err || sn9c102_i2c_try_raw_read(cam, &mt9v111,
- mt9v111.i2c_slave_id, 0x36, 2,
- data) < 0)
- return -EIO;
-
- if (data[0] != 0x82 || data[1] != 0x3a)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &mt9v111);
-
- return 0;
-}
diff --git a/drivers/staging/media/sn9c102/sn9c102_ov7630.c b/drivers/staging/media/sn9c102/sn9c102_ov7630.c
deleted file mode 100644
index 9ec304dc4705..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_ov7630.c
+++ /dev/null
@@ -1,634 +0,0 @@
-/***************************************************************************
- * Plug-in for OV7630 image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2006-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int ov7630_init(struct sn9c102_device *cam)
-{
- int err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- err = sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17},
- {0x0f, 0x18}, {0x50, 0x19});
-
- err += sn9c102_i2c_write(cam, 0x12, 0x8d);
- err += sn9c102_i2c_write(cam, 0x12, 0x0d);
- err += sn9c102_i2c_write(cam, 0x11, 0x00);
- err += sn9c102_i2c_write(cam, 0x15, 0x35);
- err += sn9c102_i2c_write(cam, 0x16, 0x03);
- err += sn9c102_i2c_write(cam, 0x17, 0x1c);
- err += sn9c102_i2c_write(cam, 0x18, 0xbd);
- err += sn9c102_i2c_write(cam, 0x19, 0x06);
- err += sn9c102_i2c_write(cam, 0x1a, 0xf6);
- err += sn9c102_i2c_write(cam, 0x1b, 0x04);
- err += sn9c102_i2c_write(cam, 0x20, 0x44);
- err += sn9c102_i2c_write(cam, 0x23, 0xee);
- err += sn9c102_i2c_write(cam, 0x26, 0xa0);
- err += sn9c102_i2c_write(cam, 0x27, 0x9a);
- err += sn9c102_i2c_write(cam, 0x28, 0x20);
- err += sn9c102_i2c_write(cam, 0x29, 0x30);
- err += sn9c102_i2c_write(cam, 0x2f, 0x3d);
- err += sn9c102_i2c_write(cam, 0x30, 0x24);
- err += sn9c102_i2c_write(cam, 0x32, 0x86);
- err += sn9c102_i2c_write(cam, 0x60, 0xa9);
- err += sn9c102_i2c_write(cam, 0x61, 0x42);
- err += sn9c102_i2c_write(cam, 0x65, 0x00);
- err += sn9c102_i2c_write(cam, 0x69, 0x38);
- err += sn9c102_i2c_write(cam, 0x6f, 0x88);
- err += sn9c102_i2c_write(cam, 0x70, 0x0b);
- err += sn9c102_i2c_write(cam, 0x71, 0x00);
- err += sn9c102_i2c_write(cam, 0x74, 0x21);
- err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
- break;
- case BRIDGE_SN9C103:
- err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03},
- {0x1a, 0x04}, {0x20, 0x05},
- {0x20, 0x06}, {0x20, 0x07},
- {0x03, 0x10}, {0x0a, 0x14},
- {0x60, 0x17}, {0x0f, 0x18},
- {0x50, 0x19}, {0x1d, 0x1a},
- {0x10, 0x1b}, {0x02, 0x1c},
- {0x03, 0x1d}, {0x0f, 0x1e},
- {0x0c, 0x1f}, {0x00, 0x20},
- {0x10, 0x21}, {0x20, 0x22},
- {0x30, 0x23}, {0x40, 0x24},
- {0x50, 0x25}, {0x60, 0x26},
- {0x70, 0x27}, {0x80, 0x28},
- {0x90, 0x29}, {0xa0, 0x2a},
- {0xb0, 0x2b}, {0xc0, 0x2c},
- {0xd0, 0x2d}, {0xe0, 0x2e},
- {0xf0, 0x2f}, {0xff, 0x30});
-
- err += sn9c102_i2c_write(cam, 0x12, 0x8d);
- err += sn9c102_i2c_write(cam, 0x12, 0x0d);
- err += sn9c102_i2c_write(cam, 0x15, 0x34);
- err += sn9c102_i2c_write(cam, 0x11, 0x01);
- err += sn9c102_i2c_write(cam, 0x1b, 0x04);
- err += sn9c102_i2c_write(cam, 0x20, 0x44);
- err += sn9c102_i2c_write(cam, 0x23, 0xee);
- err += sn9c102_i2c_write(cam, 0x26, 0xa0);
- err += sn9c102_i2c_write(cam, 0x27, 0x9a);
- err += sn9c102_i2c_write(cam, 0x28, 0x20);
- err += sn9c102_i2c_write(cam, 0x29, 0x30);
- err += sn9c102_i2c_write(cam, 0x2f, 0x3d);
- err += sn9c102_i2c_write(cam, 0x30, 0x24);
- err += sn9c102_i2c_write(cam, 0x32, 0x86);
- err += sn9c102_i2c_write(cam, 0x60, 0xa9);
- err += sn9c102_i2c_write(cam, 0x61, 0x42);
- err += sn9c102_i2c_write(cam, 0x65, 0x00);
- err += sn9c102_i2c_write(cam, 0x69, 0x38);
- err += sn9c102_i2c_write(cam, 0x6f, 0x88);
- err += sn9c102_i2c_write(cam, 0x70, 0x0b);
- err += sn9c102_i2c_write(cam, 0x71, 0x00);
- err += sn9c102_i2c_write(cam, 0x74, 0x21);
- err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- err = sn9c102_write_const_regs(cam, {0x40, 0x02}, {0x00, 0x03},
- {0x1a, 0x04}, {0x03, 0x10},
- {0x0a, 0x14}, {0xe2, 0x17},
- {0x0b, 0x18}, {0x00, 0x19},
- {0x1d, 0x1a}, {0x10, 0x1b},
- {0x02, 0x1c}, {0x03, 0x1d},
- {0x0f, 0x1e}, {0x0c, 0x1f},
- {0x00, 0x20}, {0x24, 0x21},
- {0x3b, 0x22}, {0x47, 0x23},
- {0x60, 0x24}, {0x71, 0x25},
- {0x80, 0x26}, {0x8f, 0x27},
- {0x9d, 0x28}, {0xaa, 0x29},
- {0xb8, 0x2a}, {0xc4, 0x2b},
- {0xd1, 0x2c}, {0xdd, 0x2d},
- {0xe8, 0x2e}, {0xf4, 0x2f},
- {0xff, 0x30}, {0x00, 0x3f},
- {0xc7, 0x40}, {0x01, 0x41},
- {0x44, 0x42}, {0x00, 0x43},
- {0x44, 0x44}, {0x00, 0x45},
- {0x44, 0x46}, {0x00, 0x47},
- {0xc7, 0x48}, {0x01, 0x49},
- {0xc7, 0x4a}, {0x01, 0x4b},
- {0xc7, 0x4c}, {0x01, 0x4d},
- {0x44, 0x4e}, {0x00, 0x4f},
- {0x44, 0x50}, {0x00, 0x51},
- {0x44, 0x52}, {0x00, 0x53},
- {0xc7, 0x54}, {0x01, 0x55},
- {0xc7, 0x56}, {0x01, 0x57},
- {0xc7, 0x58}, {0x01, 0x59},
- {0x44, 0x5a}, {0x00, 0x5b},
- {0x44, 0x5c}, {0x00, 0x5d},
- {0x44, 0x5e}, {0x00, 0x5f},
- {0xc7, 0x60}, {0x01, 0x61},
- {0xc7, 0x62}, {0x01, 0x63},
- {0xc7, 0x64}, {0x01, 0x65},
- {0x44, 0x66}, {0x00, 0x67},
- {0x44, 0x68}, {0x00, 0x69},
- {0x44, 0x6a}, {0x00, 0x6b},
- {0xc7, 0x6c}, {0x01, 0x6d},
- {0xc7, 0x6e}, {0x01, 0x6f},
- {0xc7, 0x70}, {0x01, 0x71},
- {0x44, 0x72}, {0x00, 0x73},
- {0x44, 0x74}, {0x00, 0x75},
- {0x44, 0x76}, {0x00, 0x77},
- {0xc7, 0x78}, {0x01, 0x79},
- {0xc7, 0x7a}, {0x01, 0x7b},
- {0xc7, 0x7c}, {0x01, 0x7d},
- {0x44, 0x7e}, {0x00, 0x7f},
- {0x17, 0x84}, {0x00, 0x85},
- {0x2e, 0x86}, {0x00, 0x87},
- {0x09, 0x88}, {0x00, 0x89},
- {0xe8, 0x8a}, {0x0f, 0x8b},
- {0xda, 0x8c}, {0x0f, 0x8d},
- {0x40, 0x8e}, {0x00, 0x8f},
- {0x37, 0x90}, {0x00, 0x91},
- {0xcf, 0x92}, {0x0f, 0x93},
- {0xfa, 0x94}, {0x0f, 0x95},
- {0x00, 0x96}, {0x00, 0x97},
- {0x00, 0x98}, {0x66, 0x99},
- {0x00, 0x9a}, {0x40, 0x9b},
- {0x20, 0x9c}, {0x00, 0x9d},
- {0x00, 0x9e}, {0x00, 0x9f},
- {0x2d, 0xc0}, {0x2d, 0xc1},
- {0x3a, 0xc2}, {0x00, 0xc3},
- {0x04, 0xc4}, {0x3f, 0xc5},
- {0x00, 0xc6}, {0x00, 0xc7},
- {0x50, 0xc8}, {0x3c, 0xc9},
- {0x28, 0xca}, {0xd8, 0xcb},
- {0x14, 0xcc}, {0xec, 0xcd},
- {0x32, 0xce}, {0xdd, 0xcf},
- {0x32, 0xd0}, {0xdd, 0xd1},
- {0x6a, 0xd2}, {0x50, 0xd3},
- {0x60, 0xd4}, {0x00, 0xd5},
- {0x00, 0xd6});
-
- err += sn9c102_i2c_write(cam, 0x12, 0x80);
- err += sn9c102_i2c_write(cam, 0x12, 0x48);
- err += sn9c102_i2c_write(cam, 0x01, 0x80);
- err += sn9c102_i2c_write(cam, 0x02, 0x80);
- err += sn9c102_i2c_write(cam, 0x03, 0x80);
- err += sn9c102_i2c_write(cam, 0x04, 0x10);
- err += sn9c102_i2c_write(cam, 0x05, 0x20);
- err += sn9c102_i2c_write(cam, 0x06, 0x80);
- err += sn9c102_i2c_write(cam, 0x11, 0x00);
- err += sn9c102_i2c_write(cam, 0x0c, 0x20);
- err += sn9c102_i2c_write(cam, 0x0d, 0x20);
- err += sn9c102_i2c_write(cam, 0x15, 0x80);
- err += sn9c102_i2c_write(cam, 0x16, 0x03);
- err += sn9c102_i2c_write(cam, 0x17, 0x1b);
- err += sn9c102_i2c_write(cam, 0x18, 0xbd);
- err += sn9c102_i2c_write(cam, 0x19, 0x05);
- err += sn9c102_i2c_write(cam, 0x1a, 0xf6);
- err += sn9c102_i2c_write(cam, 0x1b, 0x04);
- err += sn9c102_i2c_write(cam, 0x21, 0x1b);
- err += sn9c102_i2c_write(cam, 0x22, 0x00);
- err += sn9c102_i2c_write(cam, 0x23, 0xde);
- err += sn9c102_i2c_write(cam, 0x24, 0x10);
- err += sn9c102_i2c_write(cam, 0x25, 0x8a);
- err += sn9c102_i2c_write(cam, 0x26, 0xa0);
- err += sn9c102_i2c_write(cam, 0x27, 0xca);
- err += sn9c102_i2c_write(cam, 0x28, 0xa2);
- err += sn9c102_i2c_write(cam, 0x29, 0x74);
- err += sn9c102_i2c_write(cam, 0x2a, 0x88);
- err += sn9c102_i2c_write(cam, 0x2b, 0x34);
- err += sn9c102_i2c_write(cam, 0x2c, 0x88);
- err += sn9c102_i2c_write(cam, 0x2e, 0x00);
- err += sn9c102_i2c_write(cam, 0x2f, 0x00);
- err += sn9c102_i2c_write(cam, 0x30, 0x00);
- err += sn9c102_i2c_write(cam, 0x32, 0xc2);
- err += sn9c102_i2c_write(cam, 0x33, 0x08);
- err += sn9c102_i2c_write(cam, 0x4c, 0x40);
- err += sn9c102_i2c_write(cam, 0x4d, 0xf3);
- err += sn9c102_i2c_write(cam, 0x60, 0x05);
- err += sn9c102_i2c_write(cam, 0x61, 0x40);
- err += sn9c102_i2c_write(cam, 0x62, 0x12);
- err += sn9c102_i2c_write(cam, 0x63, 0x57);
- err += sn9c102_i2c_write(cam, 0x64, 0x73);
- err += sn9c102_i2c_write(cam, 0x65, 0x00);
- err += sn9c102_i2c_write(cam, 0x66, 0x55);
- err += sn9c102_i2c_write(cam, 0x67, 0x01);
- err += sn9c102_i2c_write(cam, 0x68, 0xac);
- err += sn9c102_i2c_write(cam, 0x69, 0x38);
- err += sn9c102_i2c_write(cam, 0x6f, 0x1f);
- err += sn9c102_i2c_write(cam, 0x70, 0x01);
- err += sn9c102_i2c_write(cam, 0x71, 0x00);
- err += sn9c102_i2c_write(cam, 0x72, 0x10);
- err += sn9c102_i2c_write(cam, 0x73, 0x50);
- err += sn9c102_i2c_write(cam, 0x74, 0x20);
- err += sn9c102_i2c_write(cam, 0x76, 0x01);
- err += sn9c102_i2c_write(cam, 0x77, 0xf3);
- err += sn9c102_i2c_write(cam, 0x78, 0x90);
- err += sn9c102_i2c_write(cam, 0x79, 0x98);
- err += sn9c102_i2c_write(cam, 0x7a, 0x98);
- err += sn9c102_i2c_write(cam, 0x7b, 0x00);
- err += sn9c102_i2c_write(cam, 0x7c, 0x38);
- err += sn9c102_i2c_write(cam, 0x7d, 0xff);
- break;
- default:
- break;
- }
-
- return err;
-}
-
-
-static int ov7630_get_ctrl(struct sn9c102_device *cam,
- struct v4l2_control *ctrl)
-{
- enum sn9c102_bridge bridge = sn9c102_get_bridge(cam);
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- ctrl->value = sn9c102_i2c_read(cam, 0x10);
- if (ctrl->value < 0)
- return -EIO;
- break;
- case V4L2_CID_RED_BALANCE:
- if (bridge == BRIDGE_SN9C105 || bridge == BRIDGE_SN9C120)
- ctrl->value = sn9c102_pread_reg(cam, 0x05);
- else
- ctrl->value = sn9c102_pread_reg(cam, 0x07);
- break;
- case V4L2_CID_BLUE_BALANCE:
- ctrl->value = sn9c102_pread_reg(cam, 0x06);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if (bridge == BRIDGE_SN9C105 || bridge == BRIDGE_SN9C120)
- ctrl->value = sn9c102_pread_reg(cam, 0x07);
- else
- ctrl->value = sn9c102_pread_reg(cam, 0x05);
- break;
- break;
- case V4L2_CID_GAIN:
- ctrl->value = sn9c102_i2c_read(cam, 0x00);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x3f;
- break;
- case V4L2_CID_DO_WHITE_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x0c);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x3f;
- break;
- case V4L2_CID_WHITENESS:
- ctrl->value = sn9c102_i2c_read(cam, 0x0d);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x3f;
- break;
- case V4L2_CID_AUTOGAIN:
- ctrl->value = sn9c102_i2c_read(cam, 0x13);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x01;
- break;
- case V4L2_CID_VFLIP:
- ctrl->value = sn9c102_i2c_read(cam, 0x75);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = (ctrl->value & 0x80) ? 1 : 0;
- break;
- case SN9C102_V4L2_CID_GAMMA:
- ctrl->value = sn9c102_i2c_read(cam, 0x14);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = (ctrl->value & 0x02) ? 1 : 0;
- break;
- case SN9C102_V4L2_CID_BAND_FILTER:
- ctrl->value = sn9c102_i2c_read(cam, 0x2d);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = (ctrl->value & 0x02) ? 1 : 0;
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int ov7630_set_ctrl(struct sn9c102_device *cam,
- const struct v4l2_control *ctrl)
-{
- enum sn9c102_bridge bridge = sn9c102_get_bridge(cam);
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_write(cam, 0x10, ctrl->value);
- break;
- case V4L2_CID_RED_BALANCE:
- if (bridge == BRIDGE_SN9C105 || bridge == BRIDGE_SN9C120)
- err += sn9c102_write_reg(cam, ctrl->value, 0x05);
- else
- err += sn9c102_write_reg(cam, ctrl->value, 0x07);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_write_reg(cam, ctrl->value, 0x06);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if (bridge == BRIDGE_SN9C105 || bridge == BRIDGE_SN9C120)
- err += sn9c102_write_reg(cam, ctrl->value, 0x07);
- else
- err += sn9c102_write_reg(cam, ctrl->value, 0x05);
- break;
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_write(cam, 0x00, ctrl->value);
- break;
- case V4L2_CID_DO_WHITE_BALANCE:
- err += sn9c102_i2c_write(cam, 0x0c, ctrl->value);
- break;
- case V4L2_CID_WHITENESS:
- err += sn9c102_i2c_write(cam, 0x0d, ctrl->value);
- break;
- case V4L2_CID_AUTOGAIN:
- err += sn9c102_i2c_write(cam, 0x13, ctrl->value |
- (ctrl->value << 1));
- break;
- case V4L2_CID_VFLIP:
- err += sn9c102_i2c_write(cam, 0x75, 0x0e | (ctrl->value << 7));
- break;
- case SN9C102_V4L2_CID_GAMMA:
- err += sn9c102_i2c_write(cam, 0x14, ctrl->value << 2);
- break;
- case SN9C102_V4L2_CID_BAND_FILTER:
- err += sn9c102_i2c_write(cam, 0x2d, ctrl->value << 2);
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int ov7630_set_crop(struct sn9c102_device *cam,
- const struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = 0, v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1;
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4;
- break;
- default:
- break;
- }
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static int ov7630_set_pix_format(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix)
-{
- int err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8)
- err += sn9c102_write_reg(cam, 0x50, 0x19);
- else
- err += sn9c102_write_reg(cam, 0x20, 0x19);
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
- err += sn9c102_write_reg(cam, 0xe5, 0x17);
- err += sn9c102_i2c_write(cam, 0x11, 0x04);
- } else {
- err += sn9c102_write_reg(cam, 0xe2, 0x17);
- err += sn9c102_i2c_write(cam, 0x11, 0x02);
- }
- break;
- default:
- break;
- }
-
- return err;
-}
-
-
-static const struct sn9c102_sensor ov7630 = {
- .name = "OV7630",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103 |
- BRIDGE_SN9C105 | BRIDGE_SN9C120,
- .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x21,
- .init = &ov7630_init,
- .qctrl = {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x14,
- .flags = 0,
- },
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x01,
- .default_value = 0x60,
- .flags = 0,
- },
- {
- .id = V4L2_CID_WHITENESS,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "white balance background: red",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x20,
- .flags = 0,
- },
- {
- .id = V4L2_CID_DO_WHITE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "white balance background: blue",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x20,
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x20,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x20,
- .flags = 0,
- },
- {
- .id = V4L2_CID_AUTOGAIN,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "auto adjust",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical flip",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x01,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x20,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_BAND_FILTER,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "band filter",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GAMMA,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "rgb gamma",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- },
- .get_ctrl = &ov7630_get_ctrl,
- .set_ctrl = &ov7630_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &ov7630_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SN9C10X,
- .priv = 8,
- },
- .set_pix_format = &ov7630_set_pix_format
-};
-
-
-int sn9c102_probe_ov7630(struct sn9c102_device *cam)
-{
- int pid, ver, err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
- {0x28, 0x17});
- break;
- case BRIDGE_SN9C103: /* do _not_ change anything! */
- err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x42, 0x01},
- {0x28, 0x17}, {0x44, 0x02});
- pid = sn9c102_i2c_try_read(cam, &ov7630, 0x0a);
- if (err || pid < 0) /* try a different initialization */
- err += sn9c102_write_const_regs(cam, {0x01, 0x01},
- {0x00, 0x01});
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- err = sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
- {0x29, 0x01}, {0x74, 0x02},
- {0x0e, 0x01}, {0x44, 0x01});
- break;
- default:
- break;
- }
-
- pid = sn9c102_i2c_try_read(cam, &ov7630, 0x0a);
- ver = sn9c102_i2c_try_read(cam, &ov7630, 0x0b);
- if (err || pid < 0 || ver < 0)
- return -EIO;
- if (pid != 0x76 || ver != 0x31)
- return -ENODEV;
- sn9c102_attach_sensor(cam, &ov7630);
-
- return 0;
-}
diff --git a/drivers/staging/media/sn9c102/sn9c102_ov7660.c b/drivers/staging/media/sn9c102/sn9c102_ov7660.c
deleted file mode 100644
index ac07805d122e..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_ov7660.c
+++ /dev/null
@@ -1,546 +0,0 @@
-/***************************************************************************
- * Plug-in for OV7660 image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published