2019-05-27 08:55:06 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2008-04-12 09:58:09 -03:00
/*
* Main USB camera driver
*
2011-03-14 05:33:01 -03:00
* Copyright ( C ) 2008 - 2011 Jean - François Moine < http : //moinejf.free.fr>
2008-04-12 09:58:09 -03:00
*
2010-01-28 06:39:49 -03:00
* Camera button input handling by Márton Németh
* Copyright ( C ) 2009 - 2010 Márton Németh < nm127 @ freemail . hu >
2008-04-12 09:58:09 -03:00
*/
2011-08-21 19:56:57 -03:00
# define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2011-09-23 05:17:10 -03:00
# define GSPCA_VERSION "2.14.0"
2008-04-12 09:58:09 -03:00
# include <linux/init.h>
# include <linux/fs.h>
# include <linux/vmalloc.h>
# include <linux/sched.h>
# include <linux/slab.h>
# include <linux/mm.h>
# include <linux/string.h>
# include <linux/pagemap.h>
2008-07-01 10:03:42 -03:00
# include <linux/io.h>
2008-04-12 09:58:09 -03:00
# include <asm/page.h>
2008-07-01 10:03:42 -03:00
# include <linux/uaccess.h>
2010-03-07 06:56:56 -03:00
# include <linux/ktime.h>
2008-07-20 08:12:02 -03:00
# include <media/v4l2-ioctl.h>
2012-05-06 09:28:17 -03:00
# include <media/v4l2-ctrls.h>
2012-05-06 09:28:19 -03:00
# include <media/v4l2-fh.h>
2012-05-06 09:28:20 -03:00
# include <media/v4l2-event.h>
2008-04-12 09:58:09 -03:00
# include "gspca.h"
2013-01-24 19:28:59 -03:00
# if IS_ENABLED(CONFIG_INPUT)
2010-01-28 06:39:49 -03:00
# include <linux/input.h>
# include <linux/usb/input.h>
2010-02-18 15:02:51 -03:00
# endif
2010-01-28 06:39:49 -03:00
2008-06-12 10:58:58 -03:00
/* global values */
2009-01-17 04:46:38 -03:00
# define DEF_NURBS 3 /* default number of URBs */
# if DEF_NURBS > MAX_NURBS
# error "DEF_NURBS too big"
# endif
2008-06-12 10:58:58 -03:00
2010-04-02 06:59:13 -03:00
MODULE_AUTHOR ( " Jean-François Moine <http://moinejf.free.fr> " ) ;
2008-04-12 09:58:09 -03:00
MODULE_DESCRIPTION ( " GSPCA USB Camera Driver " ) ;
MODULE_LICENSE ( " GPL " ) ;
2011-09-23 05:17:10 -03:00
MODULE_VERSION ( GSPCA_VERSION ) ;
2008-04-12 09:58:09 -03:00
2013-02-04 13:17:55 -03:00
int gspca_debug ;
2008-04-12 09:58:09 -03:00
EXPORT_SYMBOL ( gspca_debug ) ;
2013-02-04 13:17:55 -03:00
static void PDEBUG_MODE ( struct gspca_dev * gspca_dev , int debug , char * txt ,
__u32 pixfmt , int w , int h )
2008-04-12 09:58:09 -03:00
{
if ( ( pixfmt > > 24 ) > = ' 0 ' & & ( pixfmt > > 24 ) < = ' z ' ) {
2017-09-22 15:20:33 -04:00
gspca_dbg ( gspca_dev , debug , " %s %c%c%c%c %dx%d \n " ,
txt ,
pixfmt & 0xff ,
( pixfmt > > 8 ) & 0xff ,
( pixfmt > > 16 ) & 0xff ,
pixfmt > > 24 ,
w , h ) ;
2008-04-12 09:58:09 -03:00
} else {
2017-09-22 15:20:33 -04:00
gspca_dbg ( gspca_dev , debug , " %s 0x%08x %dx%d \n " ,
txt ,
pixfmt ,
w , h ) ;
2008-04-12 09:58:09 -03:00
}
}
2009-11-07 15:30:50 -03:00
/* specific memory types - !! should be different from V4L2_MEMORY_xxx */
2008-06-12 10:58:58 -03:00
# define GSPCA_MEMORY_NO 0 /* V4L2_MEMORY_xxx starts from 1 */
# define GSPCA_MEMORY_READ 7
2010-01-28 06:39:49 -03:00
/*
* Input and interrupt endpoint handling functions
*/
2013-01-24 19:28:59 -03:00
# if IS_ENABLED(CONFIG_INPUT)
2010-01-28 06:39:49 -03:00
static void int_irq ( struct urb * urb )
{
struct gspca_dev * gspca_dev = ( struct gspca_dev * ) urb - > context ;
int ret ;
ret = urb - > status ;
switch ( ret ) {
case 0 :
if ( gspca_dev - > sd_desc - > int_pkt_scan ( gspca_dev ,
urb - > transfer_buffer , urb - > actual_length ) < 0 ) {
2017-09-22 14:33:35 -04:00
gspca_err ( gspca_dev , " Unknown packet received \n " ) ;
2010-01-28 06:39:49 -03:00
}
break ;
case - ENOENT :
case - ECONNRESET :
case - ENODEV :
case - ESHUTDOWN :
/* Stop is requested either by software or hardware is gone,
* keep the ret value non - zero and don ' t resubmit later .
*/
break ;
default :
2017-09-22 14:33:35 -04:00
gspca_err ( gspca_dev , " URB error %i, resubmitting \n " ,
urb - > status ) ;
2010-01-28 06:39:49 -03:00
urb - > status = 0 ;
ret = 0 ;
}
if ( ret = = 0 ) {
ret = usb_submit_urb ( urb , GFP_ATOMIC ) ;
if ( ret < 0 )
2011-08-21 19:56:57 -03:00
pr_err ( " Resubmit URB failed with error %i \n " , ret ) ;
2010-01-28 06:39:49 -03:00
}
}
static int gspca_input_connect ( struct gspca_dev * dev )
{
struct input_dev * input_dev ;
int err = 0 ;
dev - > input_dev = NULL ;
2010-02-19 04:28:39 -03:00
if ( dev - > sd_desc - > int_pkt_scan | | dev - > sd_desc - > other_input ) {
2010-01-28 06:39:49 -03:00
input_dev = input_allocate_device ( ) ;
if ( ! input_dev )
return - ENOMEM ;
usb_make_path ( dev - > dev , dev - > phys , sizeof ( dev - > phys ) ) ;
strlcat ( dev - > phys , " /input0 " , sizeof ( dev - > phys ) ) ;
input_dev - > name = dev - > sd_desc - > name ;
input_dev - > phys = dev - > phys ;
usb_to_input_id ( dev - > dev , & input_dev - > id ) ;
input_dev - > evbit [ 0 ] = BIT_MASK ( EV_KEY ) ;
input_dev - > keybit [ BIT_WORD ( KEY_CAMERA ) ] = BIT_MASK ( KEY_CAMERA ) ;
input_dev - > dev . parent = & dev - > dev - > dev ;
err = input_register_device ( input_dev ) ;
if ( err ) {
2011-08-21 19:56:57 -03:00
pr_err ( " Input device registration failed with error %i \n " ,
err ) ;
2010-01-28 06:39:49 -03:00
input_dev - > dev . parent = NULL ;
input_free_device ( input_dev ) ;
} else {
dev - > input_dev = input_dev ;
}
2010-02-19 04:41:40 -03:00
}
2010-01-28 06:39:49 -03:00
return err ;
}
static int alloc_and_submit_int_urb ( struct gspca_dev * gspca_dev ,
struct usb_endpoint_descriptor * ep )
{
unsigned int buffer_len ;
int interval ;
struct urb * urb ;
struct usb_device * dev ;
void * buffer = NULL ;
int ret = - EINVAL ;
2010-04-29 06:01:53 -03:00
buffer_len = le16_to_cpu ( ep - > wMaxPacketSize ) ;
2010-01-28 06:39:49 -03:00
interval = ep - > bInterval ;
2017-09-22 15:20:33 -04:00
gspca_dbg ( gspca_dev , D_CONF , " found int in endpoint: 0x%x, buffer_len=%u, interval=%u \n " ,
ep - > bEndpointAddress , buffer_len , interval ) ;
2010-01-28 06:39:49 -03:00
dev = gspca_dev - > dev ;
urb = usb_alloc_urb ( 0 , GFP_KERNEL ) ;
if ( ! urb ) {
ret = - ENOMEM ;
goto error ;
}
2010-05-20 21:26:12 -07:00
buffer = usb_alloc_coherent ( dev , buffer_len ,
2010-01-28 06:39:49 -03:00
GFP_KERNEL , & urb - > transfer_dma ) ;
if ( ! buffer ) {
ret = - ENOMEM ;
goto error_buffer ;
}
usb_fill_int_urb ( urb , dev ,
usb_rcvintpipe ( dev , ep - > bEndpointAddress ) ,
buffer , buffer_len ,
int_irq , ( void * ) gspca_dev , interval ) ;
2010-09-03 06:57:19 -03:00
urb - > transfer_flags | = URB_NO_TRANSFER_DMA_MAP ;
2010-01-28 06:39:49 -03:00
ret = usb_submit_urb ( urb , GFP_KERNEL ) ;
if ( ret < 0 ) {
2017-09-22 14:33:35 -04:00
gspca_err ( gspca_dev , " submit int URB failed with error %i \n " ,
ret ) ;
2010-01-28 06:39:49 -03:00
goto error_submit ;
}
2010-10-26 05:16:32 -03:00
gspca_dev - > int_urb = urb ;
2010-01-28 06:39:49 -03:00
return ret ;
error_submit :
2010-04-12 13:17:25 +02:00
usb_free_coherent ( dev ,
urb - > transfer_buffer_length ,
urb - > transfer_buffer ,
urb - > transfer_dma ) ;
2010-01-28 06:39:49 -03:00
error_buffer :
usb_free_urb ( urb ) ;
error :
return ret ;
}
2010-02-19 04:41:40 -03:00
static void gspca_input_create_urb ( struct gspca_dev * gspca_dev )
2010-01-28 06:39:49 -03:00
{
struct usb_interface * intf ;
struct usb_host_interface * intf_desc ;
struct usb_endpoint_descriptor * ep ;
int i ;
if ( gspca_dev - > sd_desc - > int_pkt_scan ) {
intf = usb_ifnum_to_if ( gspca_dev - > dev , gspca_dev - > iface ) ;
intf_desc = intf - > cur_altsetting ;
for ( i = 0 ; i < intf_desc - > desc . bNumEndpoints ; i + + ) {
ep = & intf_desc - > endpoint [ i ] . desc ;
if ( usb_endpoint_dir_in ( ep ) & &
usb_endpoint_xfer_int ( ep ) ) {
2010-02-19 04:41:40 -03:00
alloc_and_submit_int_urb ( gspca_dev , ep ) ;
2010-01-28 06:39:49 -03:00
break ;
}
}
}
}
static void gspca_input_destroy_urb ( struct gspca_dev * gspca_dev )
{
struct urb * urb ;
urb = gspca_dev - > int_urb ;
if ( urb ) {
gspca_dev - > int_urb = NULL ;
usb_kill_urb ( urb ) ;
2010-04-12 13:17:25 +02:00
usb_free_coherent ( gspca_dev - > dev ,
urb - > transfer_buffer_length ,
urb - > transfer_buffer ,
urb - > transfer_dma ) ;
2010-01-28 06:39:49 -03:00
usb_free_urb ( urb ) ;
}
}
2010-03-30 14:32:04 -03:00
# else
static inline void gspca_input_destroy_urb ( struct gspca_dev * gspca_dev )
{
}
static inline void gspca_input_create_urb ( struct gspca_dev * gspca_dev )
{
}
static inline int gspca_input_connect ( struct gspca_dev * dev )
{
return 0 ;
}
2010-01-28 06:39:49 -03:00
# endif
2008-04-12 09:58:09 -03:00
/*
2008-06-12 10:58:58 -03:00
* fill a video frame from an URB and resubmit
2008-04-12 09:58:09 -03:00
*/
2008-06-12 10:58:58 -03:00
static void fill_frame ( struct gspca_dev * gspca_dev ,
struct urb * urb )
2008-04-12 09:58:09 -03:00
{
2009-01-13 06:07:59 -03:00
u8 * data ; /* address of data in the iso message */
2008-09-20 05:44:21 -03:00
int i , len , st ;
2008-04-12 09:58:09 -03:00
cam_pkt_op pkt_scan ;
2008-06-30 15:50:11 -03:00
if ( urb - > status ! = 0 ) {
2009-02-12 08:05:45 -03:00
if ( urb - > status = = - ESHUTDOWN )
return ; /* disconnection */
2008-09-03 17:12:13 -03:00
# ifdef CONFIG_PM
2009-10-24 15:02:14 -03:00
if ( gspca_dev - > frozen )
return ;
2008-09-03 17:12:13 -03:00
# endif
2017-09-22 14:33:35 -04:00
gspca_err ( gspca_dev , " urb status: %d \n " , urb - > status ) ;
2009-11-13 07:15:08 -03:00
urb - > status = 0 ;
2009-10-23 06:56:06 -03:00
goto resubmit ;
2008-06-30 15:50:11 -03:00
}
2008-04-12 09:58:09 -03:00
pkt_scan = gspca_dev - > sd_desc - > pkt_scan ;
for ( i = 0 ; i < urb - > number_of_packets ; i + + ) {
2010-12-27 12:00:03 -03:00
len = urb - > iso_frame_desc [ i ] . actual_length ;
2008-04-12 09:58:09 -03:00
/* check the packet status and length */
st = urb - > iso_frame_desc [ i ] . status ;
if ( st ) {
2019-02-28 10:28:34 -05:00
gspca_dbg ( gspca_dev , D_PACK , " ISOC data error: [%d] len=%d, status=%d \n " ,
2011-08-21 19:56:57 -03:00
i , len , st ) ;
2008-04-12 09:58:09 -03:00
gspca_dev - > last_packet_type = DISCARD_PACKET ;
continue ;
}
2010-12-25 13:22:21 -03:00
if ( len = = 0 ) {
if ( gspca_dev - > empty_packet = = 0 )
gspca_dev - > empty_packet = 1 ;
continue ;
}
2008-04-12 09:58:09 -03:00
/* let the packet be analyzed by the subdriver */
2017-09-22 15:20:33 -04:00
gspca_dbg ( gspca_dev , D_PACK , " packet [%d] o:%d l:%d \n " ,
i , urb - > iso_frame_desc [ i ] . offset , len ) ;
2009-01-13 06:07:59 -03:00
data = ( u8 * ) urb - > transfer_buffer
2008-04-12 09:58:09 -03:00
+ urb - > iso_frame_desc [ i ] . offset ;
2009-11-13 09:21:03 -03:00
pkt_scan ( gspca_dev , data , len ) ;
2008-04-12 09:58:09 -03:00
}
2009-10-23 06:56:06 -03:00
resubmit :
2019-02-26 07:54:22 -05:00
if ( ! gspca_dev - > streaming )
return ;
2008-04-12 09:58:09 -03:00
/* resubmit the URB */
st = usb_submit_urb ( urb , GFP_ATOMIC ) ;
if ( st < 0 )
2011-08-21 19:56:57 -03:00
pr_err ( " usb_submit_urb() ret %d \n " , st ) ;
2008-04-12 09:58:09 -03:00
}
2008-06-12 10:58:58 -03:00
/*
* ISOC message interrupt from the USB device
*
2008-07-08 06:58:15 -03:00
* Analyse each packet and call the subdriver for copy to the frame buffer .
2008-06-12 10:58:58 -03:00
*/
2009-01-13 06:07:59 -03:00
static void isoc_irq ( struct urb * urb )
2008-06-12 10:58:58 -03:00
{
struct gspca_dev * gspca_dev = ( struct gspca_dev * ) urb - > context ;
2017-09-22 15:20:33 -04:00
gspca_dbg ( gspca_dev , D_PACK , " isoc irq \n " ) ;
2019-02-26 07:54:22 -05:00
if ( ! gspca_dev - > streaming )
2008-06-12 10:58:58 -03:00
return ;
fill_frame ( gspca_dev , urb ) ;
}
2008-09-04 07:01:50 -03:00
/*
* bulk message interrupt from the USB device
*/
2009-01-13 06:07:59 -03:00
static void bulk_irq ( struct urb * urb )
2008-09-04 07:01:50 -03:00
{
struct gspca_dev * gspca_dev = ( struct gspca_dev * ) urb - > context ;
2008-11-14 07:53:32 -03:00
int st ;
2008-09-04 07:01:50 -03:00
2017-09-22 15:20:33 -04:00
gspca_dbg ( gspca_dev , D_PACK , " bulk irq \n " ) ;
2019-02-26 07:54:22 -05:00
if ( ! gspca_dev - > streaming )
2008-09-04 07:01:50 -03:00
return ;
2008-11-18 04:19:52 -03:00
switch ( urb - > status ) {
case 0 :
break ;
2009-02-12 08:05:45 -03:00
case - ESHUTDOWN :
return ; /* disconnection */
2008-11-18 04:19:52 -03:00
default :
2008-09-04 07:01:50 -03:00
# ifdef CONFIG_PM
2009-10-24 15:02:14 -03:00
if ( gspca_dev - > frozen )
return ;
2008-09-04 07:01:50 -03:00
# endif
2017-09-22 14:33:35 -04:00
gspca_err ( gspca_dev , " urb status: %d \n " , urb - > status ) ;
2009-11-13 07:15:08 -03:00
urb - > status = 0 ;
2009-10-23 06:56:06 -03:00
goto resubmit ;
2008-09-04 07:01:50 -03:00
}
2017-09-22 15:20:33 -04:00
gspca_dbg ( gspca_dev , D_PACK , " packet l:%d \n " , urb - > actual_length ) ;
2009-11-13 08:16:02 -03:00
gspca_dev - > sd_desc - > pkt_scan ( gspca_dev ,
urb - > transfer_buffer ,
urb - > actual_length ) ;
2008-11-14 07:53:32 -03:00
2009-10-23 06:56:06 -03:00
resubmit :
2019-02-26 07:54:22 -05:00
if ( ! gspca_dev - > streaming )
return ;
2008-11-14 07:53:32 -03:00
/* resubmit the URB */
if ( gspca_dev - > cam . bulk_nurbs ! = 0 ) {
st = usb_submit_urb ( urb , GFP_ATOMIC ) ;
if ( st < 0 )
2011-08-21 19:56:57 -03:00
pr_err ( " usb_submit_urb() ret %d \n " , st ) ;
2008-11-14 07:53:32 -03:00
}
2008-09-04 07:01:50 -03:00
}
2008-04-12 09:58:09 -03:00
/*
* add data to the current frame
*
2008-07-08 06:58:15 -03:00
* This function is called by the subdrivers at interrupt level .
*
2008-04-12 09:58:09 -03:00
* To build a frame , these ones must add
* - one FIRST_PACKET
* - 0 or many INTER_PACKETs
* - one LAST_PACKET
* DISCARD_PACKET invalidates the whole frame .
*/
2009-11-13 09:21:03 -03:00
void gspca_frame_add ( struct gspca_dev * gspca_dev ,
enum gspca_packet_type packet_type ,
const u8 * data ,
int len )
2008-04-12 09:58:09 -03:00
{
2018-05-12 10:44:00 -04:00
struct gspca_buffer * buf ;
unsigned long flags ;
2008-04-12 09:58:09 -03:00
2017-09-22 15:20:33 -04:00
gspca_dbg ( gspca_dev , D_PACK , " add t:%d l:%d \n " , packet_type , len ) ;
2009-11-13 08:16:02 -03:00
2018-05-12 10:44:00 -04:00
spin_lock_irqsave ( & gspca_dev - > qlock , flags ) ;
buf = list_first_entry_or_null ( & gspca_dev - > buf_list ,
typeof ( * buf ) , list ) ;
spin_unlock_irqrestore ( & gspca_dev - > qlock , flags ) ;
2010-07-06 04:32:27 -03:00
2018-05-12 10:44:00 -04:00
if ( packet_type = = FIRST_PACKET ) {
/* if there is no queued buffer, discard the whole frame */
if ( ! buf ) {
2010-07-06 04:32:27 -03:00
gspca_dev - > last_packet_type = DISCARD_PACKET ;
2010-10-16 13:59:13 -03:00
gspca_dev - > sequence + + ;
2010-07-06 04:32:27 -03:00
return ;
}
2018-05-12 10:44:00 -04:00
gspca_dev - > image = vb2_plane_vaddr ( & buf - > vb . vb2_buf , 0 ) ;
2010-06-27 03:08:19 -03:00
gspca_dev - > image_len = 0 ;
2010-07-29 02:46:02 -03:00
} else {
switch ( gspca_dev - > last_packet_type ) {
case DISCARD_PACKET :
2011-06-05 03:44:43 -03:00
if ( packet_type = = LAST_PACKET ) {
2010-07-29 02:46:02 -03:00
gspca_dev - > last_packet_type = packet_type ;
2011-06-05 03:44:43 -03:00
gspca_dev - > image = NULL ;
gspca_dev - > image_len = 0 ;
}
2010-07-29 02:46:02 -03:00
return ;
case LAST_PACKET :
return ;
}
2008-06-12 10:58:58 -03:00
}
2008-04-12 09:58:09 -03:00
2008-06-12 10:58:58 -03:00
/* append the packet to the frame buffer */
2008-04-12 09:58:09 -03:00
if ( len > 0 ) {
2018-11-20 05:13:04 -05:00
if ( gspca_dev - > image_len + len > PAGE_ALIGN ( gspca_dev - > pixfmt . sizeimage ) ) {
2017-09-22 14:33:35 -04:00
gspca_err ( gspca_dev , " frame overflow %d > %d \n " ,
gspca_dev - > image_len + len ,
2018-11-20 05:13:04 -05:00
PAGE_ALIGN ( gspca_dev - > pixfmt . sizeimage ) ) ;
2008-04-12 09:58:09 -03:00
packet_type = DISCARD_PACKET ;
} else {
2010-07-29 02:46:02 -03:00
/* !! image is NULL only when last pkt is LAST or DISCARD
if ( gspca_dev - > image = = NULL ) {
2011-08-21 19:56:57 -03:00
pr_err ( " gspca_frame_add() image == NULL \n " ) ;
2010-07-29 02:46:02 -03:00
return ;
}
*/
2010-06-27 03:08:19 -03:00
memcpy ( gspca_dev - > image + gspca_dev - > image_len ,
data , len ) ;
gspca_dev - > image_len + = len ;
2008-04-12 09:58:09 -03:00
}
}
gspca_dev - > last_packet_type = packet_type ;
2010-07-06 04:32:27 -03:00
/* if last packet, invalidate packet concatenation until
* next first packet , wake up the application and advance
* in the queue */
2008-04-12 09:58:09 -03:00
if ( packet_type = = LAST_PACKET ) {
2018-05-12 10:44:00 -04:00
spin_lock_irqsave ( & gspca_dev - > qlock , flags ) ;
list_del ( & buf - > list ) ;
spin_unlock_irqrestore ( & gspca_dev - > qlock , flags ) ;
buf - > vb . vb2_buf . timestamp = ktime_get_ns ( ) ;
vb2_set_plane_payload ( & buf - > vb . vb2_buf , 0 ,
gspca_dev - > image_len ) ;
buf - > vb . sequence = gspca_dev - > sequence + + ;
buf - > vb . field = V4L2_FIELD_NONE ;
2017-09-22 15:20:33 -04:00
gspca_dbg ( gspca_dev , D_FRAM , " frame complete len:%d \n " ,
2018-05-12 10:44:00 -04:00
gspca_dev - > image_len ) ;
vb2_buffer_done ( & buf - > vb . vb2_buf , VB2_BUF_STATE_DONE ) ;
2010-07-06 04:32:27 -03:00
gspca_dev - > image = NULL ;
gspca_dev - > image_len = 0 ;
2008-04-12 09:58:09 -03:00
}
}
EXPORT_SYMBOL ( gspca_frame_add ) ;
2008-06-12 10:58:58 -03:00
static void destroy_urbs ( struct gspca_dev * gspca_dev )
2008-04-12 09:58:09 -03:00
{
struct urb * urb ;
unsigned int i ;
2017-09-22 15:20:33 -04:00
gspca_dbg ( gspca_dev , D_STREAM , " kill transfer \n " ) ;
2018-05-23 16:13:48 -04:00
/* Killing all URBs guarantee that no URB completion
* handler is running . Therefore , there shouldn ' t
* be anyone trying to access gspca_dev - > urb [ i ]
*/
for ( i = 0 ; i < MAX_NURBS ; i + + )
usb_kill_urb ( gspca_dev - > urb [ i ] ) ;
gspca_dbg ( gspca_dev , D_STREAM , " releasing urbs \n " ) ;
2008-10-13 15:52:46 -03:00
for ( i = 0 ; i < MAX_NURBS ; i + + ) {
2008-05-04 06:46:21 -03:00
urb = gspca_dev - > urb [ i ] ;
2018-05-23 16:13:48 -04:00
if ( ! urb )
continue ;
2008-05-04 06:46:21 -03:00
gspca_dev - > urb [ i ] = NULL ;
2013-03-20 11:30:46 -03:00
usb_free_coherent ( gspca_dev - > dev ,
urb - > transfer_buffer_length ,
urb - > transfer_buffer ,
urb - > transfer_dma ) ;
2008-04-12 09:58:09 -03:00
usb_free_urb ( urb ) ;
}
}
2010-04-09 06:11:36 -03:00
static int gspca_set_alt0 ( struct gspca_dev * gspca_dev )
{
int ret ;
if ( gspca_dev - > alt = = 0 )
return 0 ;
ret = usb_set_interface ( gspca_dev - > dev , gspca_dev - > iface , 0 ) ;
if ( ret < 0 )
2011-08-21 19:56:57 -03:00
pr_err ( " set alt 0 err %d \n " , ret ) ;
2010-04-09 06:11:36 -03:00
return ret ;
}
2008-04-12 09:58:09 -03:00
/*
2014-06-25 06:27:56 -03:00
* look for an input transfer endpoint in an alternate setting .
*
* If xfer_ep is invalid , return the first valid ep found , otherwise
* look for exactly the ep with address equal to xfer_ep .
2008-04-12 09:58:09 -03:00
*/
2008-09-04 07:01:50 -03:00
static struct usb_host_endpoint * alt_xfer ( struct usb_host_interface * alt ,
2014-06-25 06:27:56 -03:00
int xfer , int xfer_ep )
2008-04-12 09:58:09 -03:00
{
struct usb_host_endpoint * ep ;
int i , attr ;
for ( i = 0 ; i < alt - > desc . bNumEndpoints ; i + + ) {
ep = & alt - > endpoint [ i ] ;
2008-12-31 08:13:46 -03:00
attr = ep - > desc . bmAttributes & USB_ENDPOINT_XFERTYPE_MASK ;
2009-04-21 13:57:31 -03:00
if ( attr = = xfer
2011-03-21 16:58:56 -03:00
& & ep - > desc . wMaxPacketSize ! = 0
2014-06-25 06:27:56 -03:00
& & usb_endpoint_dir_in ( & ep - > desc )
& & ( xfer_ep < 0 | | ep - > desc . bEndpointAddress = = xfer_ep ) )
2008-12-31 08:13:46 -03:00
return ep ;
2008-04-12 09:58:09 -03:00
}
return NULL ;
}
2011-08-10 07:38:48 -03:00
/* compute the minimum bandwidth for the current transfer */
static u32 which_bandwidth ( struct gspca_dev * gspca_dev )
{
u32 bandwidth ;
2012-01-04 13:44:02 -03:00
/* get the (max) image size */
2013-08-30 17:54:23 -03:00
bandwidth = gspca_dev - > pixfmt . sizeimage ;
2011-08-10 07:38:48 -03:00
2012-01-04 13:44:02 -03:00
/* if the image is compressed, estimate its mean size */
2012-01-01 16:35:01 -03:00
if ( ! gspca_dev - > cam . needs_full_bandwidth & &
2013-08-30 17:54:23 -03:00
bandwidth < gspca_dev - > pixfmt . width *
gspca_dev - > pixfmt . height )
2012-01-04 13:44:02 -03:00
bandwidth = bandwidth * 3 / 8 ; /* 0.375 */
2011-08-10 07:38:48 -03:00
/* estimate the frame rate */
if ( gspca_dev - > sd_desc - > get_streamparm ) {
struct v4l2_streamparm parm ;
gspca_dev - > sd_desc - > get_streamparm ( gspca_dev , & parm ) ;
bandwidth * = parm . parm . capture . timeperframe . denominator ;
2011-12-30 09:13:07 -03:00
bandwidth / = parm . parm . capture . timeperframe . numerator ;
2011-08-10 07:38:48 -03:00
} else {
2012-01-04 13:44:02 -03:00
/* don't hope more than 15 fps with USB 1.1 and
* image resolution > = 640 x480 */
2013-08-30 17:54:23 -03:00
if ( gspca_dev - > pixfmt . width > = 640
2012-01-04 13:44:02 -03:00
& & gspca_dev - > dev - > speed = = USB_SPEED_FULL )
bandwidth * = 15 ; /* 15 fps */
else
bandwidth * = 30 ; /* 30 fps */
2011-08-10 07:38:48 -03:00
}
2017-09-22 15:20:33 -04:00
gspca_dbg ( gspca_dev , D_STREAM , " min bandwidth: %d \n " , bandwidth ) ;
2011-08-10 07:38:48 -03:00
return bandwidth ;
}
/* endpoint table */
# define MAX_ALT 16
struct ep_tb_s {
u32 alt ;
u32 bandwidth ;
} ;
2008-04-12 09:58:09 -03:00
/*
2011-08-10 07:38:48 -03:00
* build the table of the endpoints
* and compute the minimum bandwidth for the image transfer
2008-04-12 09:58:09 -03:00
*/
2011-12-30 07:58:10 -03:00
static int build_isoc_ep_tb ( struct gspca_dev * gspca_dev ,
2011-08-10 07:38:48 -03:00
struct usb_interface * intf ,
struct ep_tb_s * ep_tb )
2008-04-12 09:58:09 -03:00
{
struct usb_host_endpoint * ep ;
2011-08-10 07:38:48 -03:00
int i , j , nbalt , psize , found ;
u32 bandwidth , last_bw ;
2008-04-12 09:58:09 -03:00
2011-08-10 07:38:48 -03:00
nbalt = intf - > num_altsetting ;
if ( nbalt > MAX_ALT )
nbalt = MAX_ALT ; /* fixme: should warn */
/* build the endpoint table */
i = 0 ;
last_bw = 0 ;
for ( ; ; ) {
ep_tb - > bandwidth = 2000 * 2000 * 120 ;
found = 0 ;
for ( j = 0 ; j < nbalt ; j + + ) {
2011-12-30 07:58:10 -03:00
ep = alt_xfer ( & intf - > altsetting [ j ] ,
2014-06-25 06:27:56 -03:00
USB_ENDPOINT_XFER_ISOC ,
gspca_dev - > xfer_ep ) ;
2011-08-10 07:38:48 -03:00
if ( ep = = NULL )
continue ;
2011-12-30 08:20:50 -03:00
if ( ep - > desc . bInterval = = 0 ) {
pr_err ( " alt %d iso endp with 0 interval \n " , j ) ;
continue ;
}
2011-08-10 07:38:48 -03:00
psize = le16_to_cpu ( ep - > desc . wMaxPacketSize ) ;
2011-12-30 07:58:10 -03:00
psize = ( psize & 0x07ff ) * ( 1 + ( ( psize > > 11 ) & 3 ) ) ;
2011-12-30 08:20:50 -03:00
bandwidth = psize * 1000 ;
2011-08-10 07:38:48 -03:00
if ( gspca_dev - > dev - > speed = = USB_SPEED_HIGH
2016-05-02 08:22:26 -03:00
| | gspca_dev - > dev - > speed > = USB_SPEED_SUPER )
2011-08-10 07:38:48 -03:00
bandwidth * = 8 ;
2011-12-30 08:20:50 -03:00
bandwidth / = 1 < < ( ep - > desc . bInterval - 1 ) ;
2011-08-10 07:38:48 -03:00
if ( bandwidth < = last_bw )
continue ;
if ( bandwidth < ep_tb - > bandwidth ) {
ep_tb - > bandwidth = bandwidth ;
ep_tb - > alt = j ;
found = 1 ;
}
2008-09-29 05:57:32 -03:00
}
2011-08-10 07:38:48 -03:00
if ( ! found )
break ;
2017-09-22 15:20:33 -04:00
gspca_dbg ( gspca_dev , D_STREAM , " alt %d bandwidth %d \n " ,
ep_tb - > alt , ep_tb - > bandwidth ) ;
2011-08-10 07:38:48 -03:00
last_bw = ep_tb - > bandwidth ;
i + + ;
ep_tb + + ;
}
2011-12-30 18:26:53 -03:00
/*
* If the camera :
* has a usb audio class interface ( a built in usb mic ) ; and
* is a usb 1 full speed device ; and
* uses the max full speed iso bandwidth ; and
* and has more than 1 alt setting
* then skip the highest alt setting to spare bandwidth for the mic
*/
if ( gspca_dev - > audio & &
gspca_dev - > dev - > speed = = USB_SPEED_FULL & &
last_bw > = 1000000 & &
i > 1 ) {
2017-09-22 15:20:33 -04:00
gspca_dbg ( gspca_dev , D_STREAM , " dev has usb audio, skipping highest alt \n " ) ;
2011-12-30 18:26:53 -03:00
i - - ;
ep_tb - - ;
}
2011-08-10 07:38:48 -03:00
/* get the requested bandwidth and start at the highest atlsetting */
bandwidth = which_bandwidth ( gspca_dev ) ;
ep_tb - - ;
while ( i > 1 ) {
ep_tb - - ;
if ( ep_tb - > bandwidth < bandwidth )
break ;
i - - ;
2008-04-12 09:58:09 -03:00
}
2011-08-10 07:38:48 -03:00
return i ;
2008-04-12 09:58:09 -03:00
}
/*
2008-09-04 07:01:50 -03:00
* create the URBs for image transfer
2008-04-12 09:58:09 -03:00
*/
static int create_urbs ( struct gspca_dev * gspca_dev ,
struct usb_host_endpoint * ep )
{
struct urb * urb ;
2008-06-12 10:58:58 -03:00
int n , nurbs , i , psize , npkt , bsize ;
2008-04-12 09:58:09 -03:00
/* calculate the packet size and the number of packets */
psize = le16_to_cpu ( ep - > desc . wMaxPacketSize ) ;
2008-06-12 10:58:58 -03:00
2009-04-21 13:45:56 -03:00
if ( ! gspca_dev - > cam . bulk ) { /* isoc */
2008-09-29 05:57:32 -03:00
/* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
2009-06-30 07:07:01 -03:00
if ( gspca_dev - > pkt_size = = 0 )
psize = ( psize & 0x07ff ) * ( 1 + ( ( psize > > 11 ) & 3 ) ) ;
else
psize = gspca_dev - > pkt_size ;
2009-04-25 13:29:01 -03:00
npkt = gspca_dev - > cam . npkt ;
if ( npkt = = 0 )
npkt = 32 ; /* default value */
2008-09-04 07:01:50 -03:00
bsize = psize * npkt ;
2017-09-22 15:20:33 -04:00
gspca_dbg ( gspca_dev , D_STREAM ,
" isoc %d pkts size %d = bsize:%d \n " ,
npkt , psize , bsize ) ;
2008-09-08 03:22:42 -03:00
nurbs = DEF_NURBS ;
2008-09-29 05:57:32 -03:00
} else { /* bulk */
2008-09-04 07:01:50 -03:00
npkt = 0 ;
2008-11-14 07:53:32 -03:00
bsize = gspca_dev - > cam . bulk_size ;
2008-09-29 05:57:32 -03:00
if ( bsize = = 0 )
bsize = psize ;
2017-09-22 15:20:33 -04:00
gspca_dbg ( gspca_dev , D_STREAM , " bulk bsize:%d \n " , bsize ) ;
2008-11-14 07:53:32 -03:00
if ( gspca_dev - > cam . bulk_nurbs ! = 0 )
nurbs = gspca_dev - > cam . bulk_nurbs ;
else
nurbs = 1 ;
2008-09-04 07:01:50 -03:00
}
2008-06-12 10:58:58 -03:00
for ( n = 0 ; n < nurbs ; n + + ) {
2008-04-12 09:58:09 -03:00
urb = usb_alloc_urb ( npkt , GFP_KERNEL ) ;
2016-08-11 18:03:52 -03:00
if ( ! urb )
2008-04-12 09:58:09 -03:00
return - ENOMEM ;
2009-12-15 05:16:04 -03:00
gspca_dev - > urb [ n ] = urb ;
2010-04-12 13:17:25 +02:00
urb - > transfer_buffer = usb_alloc_coherent ( gspca_dev - > dev ,
2008-04-12 09:58:09 -03:00
bsize ,
GFP_KERNEL ,
& urb - > transfer_dma ) ;
2008-05-04 06:46:21 -03:00
if ( urb - > transfer_buffer = = NULL ) {
2011-08-21 19:56:57 -03:00
pr_err ( " usb_alloc_coherent failed \n " ) ;
2008-04-12 09:58:09 -03:00
return - ENOMEM ;
}
urb - > dev = gspca_dev - > dev ;
urb - > context = gspca_dev ;
urb - > transfer_buffer_length = bsize ;
2008-09-04 07:01:50 -03:00
if ( npkt ! = 0 ) { /* ISOC */
urb - > pipe = usb_rcvisocpipe ( gspca_dev - > dev ,
ep - > desc . bEndpointAddress ) ;
2008-09-28 07:43:00 -03:00
urb - > transfer_flags = URB_ISO_ASAP
| URB_NO_TRANSFER_DMA_MAP ;
2012-01-01 13:34:58 -03:00
urb - > interval = 1 < < ( ep - > desc . bInterval - 1 ) ;
2008-09-04 07:01:50 -03:00
urb - > complete = isoc_irq ;
urb - > number_of_packets = npkt ;
for ( i = 0 ; i < npkt ; i + + ) {
urb - > iso_frame_desc [ i ] . length = psize ;
urb - > iso_frame_desc [ i ] . offset = psize * i ;
}
} else { /* bulk */
urb - > pipe = usb_rcvbulkpipe ( gspca_dev - > dev ,
2010-10-29 07:57:03 -03:00
ep - > desc . bEndpointAddress ) ;
2008-09-28 07:43:00 -03:00
urb - > transfer_flags = URB_NO_TRANSFER_DMA_MAP ;
2008-09-04 07:01:50 -03:00
urb - > complete = bulk_irq ;
2008-04-12 09:58:09 -03:00
}
}
return 0 ;
}
2018-05-12 10:44:00 -04:00
/* Note: both the queue and the usb locks should be held when calling this */
static void gspca_stream_off ( struct gspca_dev * gspca_dev )
{
gspca_dev - > streaming = false ;
gspca_dev - > usb_err = 0 ;
if ( gspca_dev - > sd_desc - > stopN )
gspca_dev - > sd_desc - > stopN ( gspca_dev ) ;
destroy_urbs ( gspca_dev ) ;
gspca_input_destroy_urb ( gspca_dev ) ;
gspca_set_alt0 ( gspca_dev ) ;
if ( gspca_dev - > present )
gspca_input_create_urb ( gspca_dev ) ;
if ( gspca_dev - > sd_desc - > stop0 )
gspca_dev - > sd_desc - > stop0 ( gspca_dev ) ;
gspca_dbg ( gspca_dev , D_STREAM , " stream off OK \n " ) ;
}
2008-04-12 09:58:09 -03:00
/*
* start the USB transfer
*/
static int gspca_init_transfer ( struct gspca_dev * gspca_dev )
{
2011-08-10 07:38:48 -03:00
struct usb_interface * intf ;
2008-04-12 09:58:09 -03:00
struct usb_host_endpoint * ep ;
2009-12-15 05:16:04 -03:00
struct urb * urb ;
2011-08-10 07:38:48 -03:00
struct ep_tb_s ep_tb [ MAX_ALT ] ;
int n , ret , xfer , alt , alt_idx ;
2008-04-12 09:58:09 -03:00
2010-07-06 04:32:27 -03:00
/* reset the streaming variables */
gspca_dev - > image = NULL ;
gspca_dev - > image_len = 0 ;
gspca_dev - > last_packet_type = DISCARD_PACKET ;
2010-01-13 15:34:27 -03:00
gspca_dev - > usb_err = 0 ;
2011-08-10 07:38:48 -03:00
/* do the specific subdriver stuff before endpoint selection */
[media] gspca: Fix bulk mode cameras no longer working (regression fix)
The new iso bandwidth calculation code accidentally has broken support
for bulk mode cameras. This has broken the following drivers:
finepix, jeilinj, ovfx2, ov534, ov534_9, se401, sq905, sq905c, sq930x,
stv0680, vicam.
Thix patch fixes this. Fix tested with: se401, sq905, sq905c, stv0680 &
vicam cams.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2011-12-29 16:43:12 -03:00
intf = usb_ifnum_to_if ( gspca_dev - > dev , gspca_dev - > iface ) ;
gspca_dev - > alt = gspca_dev - > cam . bulk ? intf - > num_altsetting : 0 ;
2009-06-30 07:07:01 -03:00
if ( gspca_dev - > sd_desc - > isoc_init ) {
ret = gspca_dev - > sd_desc - > isoc_init ( gspca_dev ) ;
if ( ret < 0 )
2012-05-06 09:28:27 -03:00
return ret ;
2009-06-30 07:07:01 -03:00
}
2011-08-10 07:38:48 -03:00
xfer = gspca_dev - > cam . bulk ? USB_ENDPOINT_XFER_BULK
: USB_ENDPOINT_XFER_ISOC ;
2010-10-26 05:15:46 -03:00
2011-12-30 07:58:10 -03:00
/* if bulk or the subdriver forced an altsetting, get the endpoint */
2011-08-10 07:38:48 -03:00
if ( gspca_dev - > alt ! = 0 ) {
gspca_dev - > alt - - ; /* (previous version compatibility) */
2014-06-25 06:27:56 -03:00
ep = alt_xfer ( & intf - > altsetting [ gspca_dev - > alt ] , xfer ,
gspca_dev - > xfer_ep ) ;
2011-08-10 07:38:48 -03:00
if ( ep = = NULL ) {
pr_err ( " bad altsetting %d \n " , gspca_dev - > alt ) ;
2012-05-06 09:28:27 -03:00
return - EIO ;
2011-08-10 07:38:48 -03:00
}
ep_tb [ 0 ] . alt = gspca_dev - > alt ;
alt_idx = 1 ;
} else {
2014-06-04 09:03:39 -03:00
/* else, compute the minimum bandwidth
* and build the endpoint table */
2011-12-30 07:58:10 -03:00
alt_idx = build_isoc_ep_tb ( gspca_dev , intf , ep_tb ) ;
2011-08-10 07:38:48 -03:00
if ( alt_idx < = 0 ) {
pr_err ( " no transfer endpoint found \n " ) ;
2012-05-06 09:28:27 -03:00
return - EIO ;
2011-08-10 07:38:48 -03:00
}
2009-06-30 07:07:01 -03:00
}
2011-08-10 07:38:48 -03:00
/* set the highest alternate setting and
* loop until urb submit succeeds */
gspca_input_destroy_urb ( gspca_dev ) ;
gspca_dev - > alt = ep_tb [ - - alt_idx ] . alt ;
alt = - 1 ;
2008-04-12 09:58:09 -03:00
for ( ; ; ) {
2011-08-10 07:38:48 -03:00
if ( alt ! = gspca_dev - > alt ) {
alt = gspca_dev - > alt ;
2011-11-30 05:54:16 -03:00
if ( intf - > num_altsetting > 1 ) {
2011-08-10 07:38:48 -03:00
ret = usb_set_interface ( gspca_dev - > dev ,
gspca_dev - > iface ,
alt ) ;
if ( ret < 0 ) {
2011-08-10 07:40:47 -03:00
if ( ret = = - ENOSPC )
goto retry ; /*fixme: ugly*/
2011-08-10 07:38:48 -03:00
pr_err ( " set alt %d err %d \n " , alt , ret ) ;
goto out ;
}
}
}
2009-12-15 05:23:04 -03:00
if ( ! gspca_dev - > cam . no_urb_create ) {
2017-09-22 15:20:33 -04:00
gspca_dbg ( gspca_dev , D_STREAM , " init transfer alt %d \n " ,
alt ) ;
2011-08-10 07:38:48 -03:00
ret = create_urbs ( gspca_dev ,
2014-06-25 06:27:56 -03:00
alt_xfer ( & intf - > altsetting [ alt ] , xfer ,
gspca_dev - > xfer_ep ) ) ;
2009-12-15 05:23:04 -03:00
if ( ret < 0 ) {
destroy_urbs ( gspca_dev ) ;
goto out ;
}
2009-12-15 05:16:04 -03:00
}
2008-04-12 09:58:09 -03:00
2008-10-22 14:51:56 -03:00
/* clear the bulk endpoint */
2009-04-21 13:45:56 -03:00
if ( gspca_dev - > cam . bulk )
2008-10-22 14:51:56 -03:00
usb_clear_halt ( gspca_dev - > dev ,
2008-12-31 08:13:46 -03:00
gspca_dev - > urb [ 0 ] - > pipe ) ;
2008-10-22 14:51:56 -03:00
2008-04-12 09:58:09 -03:00
/* start the cam */
2008-09-20 06:39:08 -03:00
ret = gspca_dev - > sd_desc - > start ( gspca_dev ) ;
if ( ret < 0 ) {
destroy_urbs ( gspca_dev ) ;
goto out ;
}
2012-06-15 05:24:26 -03:00
v4l2_ctrl_handler_setup ( gspca_dev - > vdev . ctrl_handler ) ;
2018-05-12 10:44:00 -04:00
gspca_dev - > streaming = true ;
2008-04-12 09:58:09 -03:00
2008-11-14 07:53:32 -03:00
/* some bulk transfers are started by the subdriver */
2009-04-21 13:45:56 -03:00
if ( gspca_dev - > cam . bulk & & gspca_dev - > cam . bulk_nurbs = = 0 )
2008-09-08 03:22:42 -03:00
break ;
2008-04-12 09:58:09 -03:00
/* submit the URBs */
2009-12-15 05:16:04 -03:00
for ( n = 0 ; n < MAX_NURBS ; n + + ) {
urb = gspca_dev - > urb [ n ] ;
if ( urb = = NULL )
break ;
ret = usb_submit_urb ( urb , GFP_KERNEL ) ;
2009-06-30 07:07:01 -03:00
if ( ret < 0 )
break ;
2008-04-12 09:58:09 -03:00
}
if ( ret > = 0 )
2011-08-10 07:38:48 -03:00
break ; /* transfer is started */
/* something when wrong
* stop the webcam and free the transfer resources */
2010-04-09 06:11:36 -03:00
gspca_stream_off ( gspca_dev ) ;
2009-11-10 14:49:43 -03:00
if ( ret ! = - ENOSPC ) {
2011-08-21 19:56:57 -03:00
pr_err ( " usb_submit_urb alt %d err %d \n " ,
gspca_dev - > alt , ret ) ;
2009-06-30 07:07:01 -03:00
goto out ;
2009-11-10 14:49:43 -03:00
}
2009-06-30 07:07:01 -03:00
/* the bandwidth is not wide enough
2011-03-30 22:57:33 -03:00
* negotiate or try a lower alternate setting */
2011-08-10 07:40:47 -03:00
retry :
2017-09-22 14:33:35 -04:00
gspca_err ( gspca_dev , " alt %d - bandwidth not wide enough, trying again \n " ,
alt ) ;
2009-06-30 07:07:01 -03:00
msleep ( 20 ) ; /* wait for kill complete */
if ( gspca_dev - > sd_desc - > isoc_nego ) {
ret = gspca_dev - > sd_desc - > isoc_nego ( gspca_dev ) ;
if ( ret < 0 )
goto out ;
} else {
2011-08-10 07:38:48 -03:00
if ( alt_idx < = 0 ) {
pr_err ( " no transfer endpoint found \n " ) ;
2009-06-30 07:07:01 -03:00
ret = - EIO ;
goto out ;
}
2011-12-31 11:32:03 -02:00
gspca_dev - > alt = ep_tb [ - - alt_idx ] . alt ;
2009-06-30 07:07:01 -03:00
}
2008-04-12 09:58:09 -03:00
}
out :
2010-10-26 05:15:46 -03:00
gspca_input_create_urb ( gspca_dev ) ;
2008-04-12 09:58:09 -03:00
return ret ;
}
2008-06-12 10:58:58 -03:00
static void gspca_set_default_mode ( struct gspca_dev * gspca_dev )
2008-04-12 09:58:09 -03:00
{
int i ;
i = gspca_dev - > cam . nmodes - 1 ; /* take the highest mode */
gspca_dev - > curr_mode = i ;
2013-08-30 17:54:23 -03:00
gspca_dev - > pixfmt = gspca_dev - > cam . cam_mode [ i ] ;
2010-10-02 04:12:25 -03:00
2012-05-06 09:28:17 -03:00
/* does nothing if ctrl_handler == NULL */
v4l2_ctrl_handler_setup ( gspca_dev - > vdev . ctrl_handler ) ;
2008-04-12 09:58:09 -03:00
}
2016-03-09 13:03:18 -03:00
static int wxh_to_mode ( struct gspca_dev * gspca_dev ,
2018-12-14 11:40:25 -05:00
int width , int height , u32 pixelformat )
2016-03-09 13:03:18 -03:00
{
int i ;
for ( i = 0 ; i < gspca_dev - > cam . nmodes ; i + + ) {
if ( width = = gspca_dev - > cam . cam_mode [ i ] . width
2018-12-14 11:40:25 -05:00
& & height = = gspca_dev - > cam . cam_mode [ i ] . height
& & pixelformat = = gspca_dev - > cam . cam_mode [ i ] . pixelformat )
2016-03-09 13:03:18 -03:00
return i ;
}
return - EINVAL ;
}
2016-03-09 13:03:17 -03:00
static int wxh_to_nearest_mode ( struct gspca_dev * gspca_dev ,
2018-12-14 11:40:26 -05:00
int width , int height , u32 pixelformat )
2008-04-12 09:58:09 -03:00
{
int i ;
2020-06-28 11:24:47 +02:00
for ( i = gspca_dev - > cam . nmodes ; - - i > = 0 ; ) {
2018-12-14 11:40:26 -05:00
if ( width > = gspca_dev - > cam . cam_mode [ i ] . width
& & height > = gspca_dev - > cam . cam_mode [ i ] . height
& & pixelformat = = gspca_dev - > cam . cam_mode [ i ] . pixelformat )
return i ;
}
2008-06-12 10:58:58 -03:00
for ( i = gspca_dev - > cam . nmodes ; - - i > 0 ; ) {
if ( width > = gspca_dev - > cam . cam_mode [ i ] . width
& & height > = gspca_dev - > cam . cam_mode [ i ] . height )
2008-04-12 09:58:09 -03:00
break ;
}
return i ;
}
/*
* search a mode with the right pixel format
*/
static int gspca_get_mode ( struct gspca_dev * gspca_dev ,
int mode ,
int pixfmt )
{
int modeU , modeD ;
modeU = modeD = mode ;
while ( ( modeU < gspca_dev - > cam . nmodes ) | | modeD > = 0 ) {
if ( - - modeD > = 0 ) {
2008-07-05 11:49:20 -03:00
if ( gspca_dev - > cam . cam_mode [ modeD ] . pixelformat
= = pixfmt )
2008-04-12 09:58:09 -03:00
return modeD ;
}
if ( + + modeU < gspca_dev - > cam . nmodes ) {
2008-07-05 11:49:20 -03:00
if ( gspca_dev - > cam . cam_mode [ modeU ] . pixelformat
= = pixfmt )
2008-04-12 09:58:09 -03:00
return modeU ;
}
}
return - EINVAL ;
}
2009-07-19 05:29:20 -03:00
# ifdef CONFIG_VIDEO_ADV_DEBUG
2013-05-29 06:59:42 -03:00
static int vidioc_g_chip_info ( struct file * file , void * priv ,
struct v4l2_dbg_chip_info * chip )
2009-07-19 05:29:20 -03:00
{
2012-05-06 09:28:18 -03:00
struct gspca_dev * gspca_dev = video_drvdata ( file ) ;
2009-07-19 05:29:20 -03:00
2009-12-02 07:14:33 -03:00
gspca_dev - > usb_err = 0 ;
2013-05-29 06:59:42 -03:00
if ( gspca_dev - > sd_desc - > get_chip_info )
return gspca_dev - > sd_desc - > get_chip_info ( gspca_dev , chip ) ;
return chip - > match . addr ? - EINVAL : 0 ;
2009-07-19 05:29:20 -03:00
}
2013-05-29 06:59:42 -03:00
static int vidioc_g_register ( struct file * file , void * priv ,
struct v4l2_dbg_register * reg )
2009-07-19 05:29:20 -03:00
{
2012-05-06 09:28:18 -03:00
struct gspca_dev * gspca_dev = video_drvdata ( file ) ;
2009-07-19 05:29:20 -03:00
2009-12-02 07:14:33 -03:00
gspca_dev - > usb_err = 0 ;
2013-05-29 06:59:42 -03:00
return gspca_dev - > sd_desc - > get_register ( gspca_dev , reg ) ;
2009-07-19 05:29:20 -03:00
}
2013-05-29 06:59:42 -03:00
static int vidioc_s_register ( struct file * file , void * priv ,
const struct v4l2_dbg_register * reg )
2009-07-19 05:29:20 -03:00
{
2012-05-06 09:28:18 -03:00
struct gspca_dev * gspca_dev = video_drvdata ( file ) ;
2009-07-19 05:29:20 -03:00
2009-12-02 07:14:33 -03:00
gspca_dev - > usb_err = 0 ;
2013-05-29 06:59:42 -03:00
return gspca_dev - > sd_desc - > set_register ( gspca_dev , reg ) ;
2009-07-19 05:29:20 -03:00
}
2013-05-29 06:59:42 -03:00
# endif
2009-07-19 05:29:20 -03:00
2008-07-01 04:06:22 -03:00
static int vidioc_enum_fmt_vid_cap ( struct file * file , void * priv ,
2008-04-12 09:58:09 -03:00
struct v4l2_fmtdesc * fmtdesc )
{
2012-05-06 09:28:18 -03:00
struct gspca_dev * gspca_dev = video_drvdata ( file ) ;
2008-06-30 15:50:11 -03:00
int i , j , index ;
2008-04-12 09:58:09 -03:00
__u32 fmt_tb [ 8 ] ;
/* give an index to each format */
index = 0 ;
for ( i = gspca_dev - > cam . nmodes ; - - i > = 0 ; ) {
2008-07-05 11:49:20 -03:00
fmt_tb [ index ] = gspca_dev - > cam . cam_mode [ i ] . pixelformat ;
2008-04-12 09:58:09 -03:00
j = 0 ;
for ( ; ; ) {
if ( fmt_tb [ j ] = = fmt_tb [ index ] )
break ;
j + + ;
}
if ( j = = index ) {
if ( fmtdesc - > index = = index )
break ; /* new format */
index + + ;
2008-11-12 23:18:21 -03:00
if ( index > = ARRAY_SIZE ( fmt_tb ) )
2008-04-12 09:58:09 -03:00
return - EINVAL ;
}
}
if ( i < 0 )
return - EINVAL ; /* no more format */
fmtdesc - > pixelformat = fmt_tb [ index ] ;
return 0 ;
}
2019-06-26 05:58:02 -04:00
static int vidioc_g_fmt_vid_cap ( struct file * file , void * _priv ,
struct v4l2_format * fmt )
2008-04-12 09:58:09 -03:00
{
2012-05-06 09:28:18 -03:00
struct gspca_dev * gspca_dev = video_drvdata ( file ) ;
2019-06-26 05:58:02 -04:00
u32 priv = fmt - > fmt . pix . priv ;
2008-04-12 09:58:09 -03:00
2013-08-30 17:54:23 -03:00
fmt - > fmt . pix = gspca_dev - > pixfmt ;
2019-06-26 05:58:02 -04:00
/* some drivers use priv internally, so keep the original value */
fmt - > fmt . pix . priv = priv ;
2008-04-12 09:58:09 -03:00
return 0 ;
}
2008-07-01 04:06:22 -03:00
static int try_fmt_vid_cap ( struct gspca_dev * gspca_dev ,
2008-04-12 09:58:09 -03:00
struct v4l2_format * fmt )
{
2008-07-04 17:55:18 -03:00
int w , h , mode , mode2 ;
2008-04-12 09:58:09 -03:00
2008-05-04 06:46:21 -03:00
w = fmt - > fmt . pix . width ;
h = fmt - > fmt . pix . height ;
2008-06-12 10:58:58 -03:00
2013-02-04 13:17:55 -03:00
PDEBUG_MODE ( gspca_dev , D_CONF , " try fmt cap " ,
fmt - > fmt . pix . pixelformat , w , h ) ;
2016-03-09 13:03:17 -03:00
/* search the nearest mode for width and height */
2018-12-14 11:40:26 -05:00
mode = wxh_to_nearest_mode ( gspca_dev , w , h , fmt - > fmt . pix . pixelformat ) ;
2008-04-12 09:58:09 -03:00
/* OK if right palette */
2008-07-05 11:49:20 -03:00
if ( gspca_dev - > cam . cam_mode [ mode ] . pixelformat
! = fmt - > fmt . pix . pixelformat ) {
2008-04-12 09:58:09 -03:00
/* else, search the closest mode with the same pixel format */
mode2 = gspca_get_mode ( gspca_dev , mode ,
fmt - > fmt . pix . pixelformat ) ;
2008-07-05 11:49:20 -03:00
if ( mode2 > = 0 )
2008-04-12 09:58:09 -03:00
mode = mode2 ;
}
2012-05-23 17:17:12 -03:00
fmt - > fmt . pix = gspca_dev - > cam . cam_mode [ mode ] ;
2013-08-30 17:54:24 -03:00
if ( gspca_dev - > sd_desc - > try_fmt ) {
/* pass original resolution to subdriver try_fmt */
fmt - > fmt . pix . width = w ;
fmt - > fmt . pix . height = h ;
gspca_dev - > sd_desc - > try_fmt ( gspca_dev , fmt ) ;
}
2008-04-12 09:58:09 -03:00
return mode ; /* used when s_fmt */
}
2019-06-26 05:58:02 -04:00
static int vidioc_try_fmt_vid_cap ( struct file * file , void * _priv ,
struct v4l2_format * fmt )
2008-04-12 09:58:09 -03:00
{
2012-05-06 09:28:18 -03:00
struct gspca_dev * gspca_dev = video_drvdata ( file ) ;
2019-06-26 05:58:02 -04:00
u32 priv = fmt - > fmt . pix . priv ;
2008-04-12 09:58:09 -03:00
2018-05-12 10:44:00 -04:00
if ( try_fmt_vid_cap ( gspca_dev , fmt ) < 0 )
return - EINVAL ;
2019-06-26 05:58:02 -04:00
/* some drivers use priv internally, so keep the original value */
fmt - > fmt . pix . priv = priv ;
2008-04-12 09:58:09 -03:00
return 0 ;
}
2019-06-26 05:58:02 -04:00
static int vidioc_s_fmt_vid_cap ( struct file * file , void * _priv ,
struct v4l2_format * fmt )
2008-04-12 09:58:09 -03:00
{
2012-05-06 09:28:18 -03:00
struct gspca_dev * gspca_dev = video_drvdata ( file ) ;
2019-06-26 05:58:02 -04:00
u32 priv = fmt - > fmt . pix . priv ;
2018-05-12 10:44:00 -04:00
int mode ;
2008-06-12 10:58:58 -03:00
2018-05-12 10:44:00 -04:00
if ( vb2_is_busy ( & gspca_dev - > queue ) )
return - EBUSY ;
2008-04-12 09:58:09 -03:00
2018-05-12 10:44:00 -04:00
mode = try_fmt_vid_cap ( gspca_dev , fmt ) ;
if ( mode < 0 )
return - EINVAL ;
2008-06-12 10:58:58 -03:00
2018-05-12 10:44:00 -04:00
gspca_dev - > curr_mode = mode ;
2013-08-30 17:54:24 -03:00
if ( gspca_dev - > sd_desc - > try_fmt )
/* subdriver try_fmt can modify format parameters */
gspca_dev - > pixfmt = fmt - > fmt . pix ;
else
2018-05-12 10:44:00 -04:00
gspca_dev - > pixfmt = gspca_dev - > cam . cam_mode [ mode ] ;
2019-06-26 05:58:02 -04:00
/* some drivers use priv internally, so keep the original value */
fmt - > fmt . pix . priv = priv ;
2018-05-12 10:44:00 -04:00
return 0 ;
2008-04-12 09:58:09 -03:00
}
2009-05-25 15:04:22 -03:00
static int vidioc_enum_framesizes ( struct file * file , void * priv ,
struct v4l2_frmsizeenum * fsize )
{
2012-05-06 09:28:18 -03:00
struct gspca_dev * gspca_dev = video_drvdata ( file ) ;
2009-05-25 15:04:22 -03:00
int i ;
__u32 index = 0 ;
2013-08-30 17:54:24 -03:00
if ( gspca_dev - > sd_desc - > enum_framesizes )
return gspca_dev - > sd_desc - > enum_framesizes ( gspca_dev , fsize ) ;
2009-05-25 15:04:22 -03:00
for ( i = 0 ; i < gspca_dev - > cam . nmodes ; i + + ) {
if ( fsize - > pixel_format ! =
gspca_dev - > cam . cam_mode [ i ] . pixelformat )
continue ;
if ( fsize - > index = = index ) {
fsize - > type = V4L2_FRMSIZE_TYPE_DISCRETE ;
fsize - > discrete . width =
gspca_dev - > cam . cam_mode [ i ] . width ;
fsize - > discrete . height =
gspca_dev - > cam . cam_mode [ i ] . height ;
return 0 ;
}
index + + ;
}
return - EINVAL ;
}
2009-12-02 06:18:46 -03:00
static int vidioc_enum_frameintervals ( struct file * filp , void * priv ,
struct v4l2_frmivalenum * fival )
{
2012-05-06 09:28:18 -03:00
struct gspca_dev * gspca_dev = video_drvdata ( filp ) ;
2016-03-09 13:03:18 -03:00
int mode ;
2009-12-02 06:18:46 -03:00
__u32 i ;
2018-12-14 11:40:25 -05:00
mode = wxh_to_mode ( gspca_dev , fival - > width , fival - > height ,
fival - > pixel_format ) ;
2016-03-09 13:03:18 -03:00
if ( mode < 0 )
return - EINVAL ;
2009-12-02 06:18:46 -03:00
if ( gspca_dev - > cam . mode_framerates = = NULL | |
gspca_dev - > cam . mode_framerates [ mode ] . nrates = = 0 )
return - EINVAL ;
if ( fival - > pixel_format ! =
gspca_dev - > cam . cam_mode [ mode ] . pixelformat )
return - EINVAL ;
for ( i = 0 ; i < gspca_dev - > cam . mode_framerates [ mode ] . nrates ; i + + ) {
if ( fival - > index = = i ) {
2016-03-09 13:03:16 -03:00
fival - > type = V4L2_FRMIVAL_TYPE_DISCRETE ;
2009-12-02 06:18:46 -03:00
fival - > discrete . numerator = 1 ;
fival - > discrete . denominator =
gspca_dev - > cam . mode_framerates [ mode ] . rates [ i ] ;
return 0 ;
}
}
return - EINVAL ;
}
2012-05-06 09:28:27 -03:00
static void gspca_release ( struct v4l2_device * v4l2_device )
2008-09-28 08:12:22 -03:00
{
2012-05-06 09:28:27 -03:00
struct gspca_dev * gspca_dev =
container_of ( v4l2_device , struct gspca_dev , v4l2_dev ) ;
2008-09-28 08:12:22 -03:00
2012-05-06 09:28:17 -03:00
v4l2_ctrl_handler_free ( gspca_dev - > vdev . ctrl_handler ) ;
2012-05-06 09:28:19 -03:00
v4l2_device_unregister ( & gspca_dev - > v4l2_dev ) ;
2008-09-28 08:12:22 -03:00
kfree ( gspca_dev - > usb_buf ) ;
kfree ( gspca_dev ) ;
}
2008-04-12 09:58:09 -03:00
static int vidioc_querycap ( struct file * file , void * priv ,
struct v4l2_capability * cap )
{
2012-05-06 09:28:18 -03:00
struct gspca_dev * gspca_dev = video_drvdata ( file ) ;
2008-04-12 09:58:09 -03:00
2018-09-10 08:19:14 -04:00
strscpy ( ( char * ) cap - > driver , gspca_dev - > sd_desc - > name ,
sizeof ( cap - > driver ) ) ;
2008-07-23 03:24:06 -03:00
if ( gspca_dev - > dev - > product ! = NULL ) {
2018-09-10 08:19:14 -04:00
strscpy ( ( char * ) cap - > card , gspca_dev - > dev - > product ,
sizeof ( cap - > card ) ) ;
2008-07-23 03:24:06 -03:00
} else {
2010-12-28 06:55:01 -03:00
snprintf ( ( char * ) cap - > card , sizeof cap - > card ,
2008-07-23 03:24:06 -03:00
" USB Camera (%04x:%04x) " ,
le16_to_cpu ( gspca_dev - > dev - > descriptor . idVendor ) ,
le16_to_cpu ( gspca_dev - > dev - > descriptor . idProduct ) ) ;
}
2010-12-28 06:55:01 -03:00
usb_make_path ( gspca_dev - > dev , ( char * ) cap - > bus_info ,
sizeof ( cap - > bus_info ) ) ;
2012-05-06 09:28:27 -03:00
return 0 ;
2008-04-12 09:58:09 -03:00
}
static int vidioc_enum_input ( struct file * file , void * priv ,
struct v4l2_input * input )
{
2012-05-06 09:28:18 -03:00
struct gspca_dev * gspca_dev = video_drvdata ( file ) ;
2008-04-12 09:58:09 -03:00
if ( input - > index ! = 0 )
return - EINVAL ;
input - > type = V4L2_INPUT_TYPE_CAMERA ;
2009-03-29 19:17:10 -03:00
input - > status = gspca_dev - > cam . input_flags ;
2018-09-10 08:19:14 -04:00
strscpy ( input - > name , gspca_dev - > sd_desc - > name ,
2008-04-12 09:58:09 -03:00
sizeof input - > name ) ;
return 0 ;
}
static int vidioc_g_input ( struct file * file , void * priv , unsigned int * i )
{
* i = 0 ;
return 0 ;
}
static int vidioc_s_input ( struct file * file , void * priv , unsigned int i )
{
if ( i > 0 )
return - EINVAL ;
return 0 ;
}
static int vidioc_g_jpegcomp ( struct file * file , void * priv ,
struct v4l2_jpegcompression * jpegcomp )
{
2012-05-06 09:28:18 -03:00
struct gspca_dev * gspca_dev = video_drvdata ( file ) ;
2008-04-12 09:58:09 -03:00
2009-12-02 07:14:33 -03:00
gspca_dev - > usb_err = 0 ;
2012-05-06 09:28:27 -03:00
return gspca_dev - > sd_desc - > get_jcomp ( gspca_dev , jpegcomp ) ;
2008-04-12 09:58:09 -03:00
}
static int vidioc_s_jpegcomp ( struct file * file , void * priv ,
2012-09-17 05:05:25 -03:00
const struct v4l2_jpegcompression * jpegcomp )
2008-04-12 09:58:09 -03:00
{
2012-05-06 09:28:18 -03:00
struct gspca_dev * gspca_dev = video_drvdata ( file ) ;
2008-04-12 09:58:09 -03:00
2009-12-02 07:14:33 -03:00
gspca_dev - > usb_err = 0 ;
2012-05-06 09:28:27 -03:00
return gspca_dev - > sd_desc - > set_jcomp ( gspca_dev , jpegcomp ) ;
2008-04-12 09:58:09 -03:00
}
static int vidioc_g_parm ( struct file * filp , void * priv ,
struct v4l2_streamparm * parm )
{
2012-05-06 09:28:18 -03:00
struct gspca_dev * gspca_dev = video_drvdata ( filp ) ;
2008-04-12 09:58:09 -03:00
2018-05-12 10:44:01 -04:00
parm - > parm . capture . readbuffers = gspca_dev - > queue . min_buffers_needed ;
2008-12-10 06:02:42 -03:00
2018-05-12 10:44:01 -04:00
if ( ! gspca_dev - > sd_desc - > get_streamparm )
return 0 ;
parm - > parm . capture . capability = V4L2_CAP_TIMEPERFRAME ;
gspca_dev - > usb_err = 0 ;
gspca_dev - > sd_desc - > get_streamparm ( gspca_dev , parm ) ;
return gspca_dev - > usb_err ;
2008-04-12 09:58:09 -03:00
}
static int vidioc_s_parm ( struct file * filp , void * priv ,
struct v4l2_streamparm * parm )
{
2012-05-06 09:28:18 -03:00
struct gspca_dev * gspca_dev = video_drvdata ( filp ) ;
2008-04-12 09:58:09 -03:00
2018-05-12 10:44:01 -04:00
parm - > parm . capture . readbuffers = gspca_dev - > queue . min_buffers_needed ;
2008-12-10 06:02:42 -03:00
2018-05-12 10:44:01 -04:00
if ( ! gspca_dev - > sd_desc - > set_streamparm ) {
parm - > parm . capture . capability = 0 ;
return 0 ;
2008-12-10 06:02:42 -03:00
}
2018-05-12 10:44:01 -04:00
parm - > parm . capture . capability = V4L2_CAP_TIMEPERFRAME ;
gspca_dev - > usb_err = 0 ;
gspca_dev - > sd_desc - > set_streamparm ( gspca_dev , parm ) ;
return gspca_dev - > usb_err ;
2008-04-12 09:58:09 -03:00
}
2018-05-12 10:44:00 -04:00
static int gspca_queue_setup ( struct vb2_queue * vq ,
unsigned int * nbuffers , unsigned int * nplanes ,
unsigned int sizes [ ] , struct device * alloc_devs [ ] )
2010-12-30 19:54:33 -03:00
{
2018-05-12 10:44:00 -04:00
struct gspca_dev * gspca_dev = vb2_get_drv_priv ( vq ) ;
2018-11-20 05:13:04 -05:00
unsigned int size = PAGE_ALIGN ( gspca_dev - > pixfmt . sizeimage ) ;
2010-12-30 19:54:33 -03:00
2018-05-12 10:44:00 -04:00
if ( * nplanes )
2018-11-20 05:13:04 -05:00
return sizes [ 0 ] < size ? - EINVAL : 0 ;
2018-05-12 10:44:00 -04:00
* nplanes = 1 ;
2018-11-20 05:13:04 -05:00
sizes [ 0 ] = size ;
2018-05-12 10:44:00 -04:00
return 0 ;
2010-12-30 19:54:33 -03:00
}
2018-05-12 10:44:00 -04:00
static int gspca_buffer_prepare ( struct vb2_buffer * vb )
2010-12-30 19:54:33 -03:00
{
2018-05-12 10:44:00 -04:00
struct gspca_dev * gspca_dev = vb2_get_drv_priv ( vb - > vb2_queue ) ;
2018-11-20 05:13:04 -05:00
unsigned long size = PAGE_ALIGN ( gspca_dev - > pixfmt . sizeimage ) ;
2010-12-30 19:54:33 -03:00
2018-05-12 10:44:00 -04:00
if ( vb2_plane_size ( vb , 0 ) < size ) {
gspca_err ( gspca_dev , " buffer too small (%lu < %lu) \n " ,
vb2_plane_size ( vb , 0 ) , size ) ;
return - EINVAL ;
}
return 0 ;
2010-12-30 19:54:33 -03:00
}
2018-05-12 10:44:00 -04:00
static void gspca_buffer_finish ( struct vb2_buffer * vb )
2008-04-12 09:58:09 -03:00
{
2018-05-12 10:44:00 -04:00
struct gspca_dev * gspca_dev = vb2_get_drv_priv ( vb - > vb2_queue ) ;
2010-12-30 19:54:33 -03:00
2018-05-12 10:44:00 -04:00
if ( ! gspca_dev - > sd_desc - > dq_callback )
return ;
2012-05-06 09:28:27 -03:00
2018-05-12 10:44:00 -04:00
gspca_dev - > usb_err = 0 ;
if ( gspca_dev - > present )
gspca_dev - > sd_desc - > dq_callback ( gspca_dev ) ;
2008-04-12 09:58:09 -03:00
}
2018-05-12 10:44:00 -04:00
static void gspca_buffer_queue ( struct vb2_buffer * vb )
2008-04-12 09:58:09 -03:00
{
2018-05-12 10:44:00 -04:00
struct gspca_dev * gspca_dev = vb2_get_drv_priv ( vb - > vb2_queue ) ;
struct gspca_buffer * buf = to_gspca_buffer ( vb ) ;
unsigned long flags ;
2008-04-12 09:58:09 -03:00
2018-05-12 10:44:00 -04:00
spin_lock_irqsave ( & gspca_dev - > qlock , flags ) ;
list_add_tail ( & buf - > list , & gspca_dev - > buf_list ) ;
spin_unlock_irqrestore ( & gspca_dev - > qlock , flags ) ;
2008-04-12 09:58:09 -03:00
}
2018-05-12 10:44:00 -04:00
static void gspca_return_all_buffers ( struct gspca_dev * gspca_dev ,
enum vb2_buffer_state state )
2008-04-12 09:58:09 -03:00
{
2018-05-12 10:44:00 -04:00
struct gspca_buffer * buf , * node ;
unsigned long flags ;
2012-05-06 09:28:27 -03:00
2018-05-12 10:44:00 -04:00
spin_lock_irqsave ( & gspca_dev - > qlock , flags ) ;
list_for_each_entry_safe ( buf , node , & gspca_dev - > buf_list , list ) {
vb2_buffer_done ( & buf - > vb . vb2_buf , state ) ;
list_del ( & buf - > list ) ;
2008-06-12 10:58:58 -03:00
}
2018-05-12 10:44:00 -04:00
spin_unlock_irqrestore ( & gspca_dev - > qlock , flags ) ;
2008-06-12 10:58:58 -03:00
}
2018-05-12 10:44:00 -04:00
static int gspca_start_streaming ( struct vb2_queue * vq , unsigned int count )
2008-06-12 10:58:58 -03:00
{
2018-05-12 10:44:00 -04:00
struct gspca_dev * gspca_dev = vb2_get_drv_priv ( vq ) ;
int ret ;
2012-05-07 08:19:42 -03:00
2018-05-12 10:44:00 -04:00
gspca_dev - > sequence = 0 ;
2012-05-07 08:19:42 -03:00
2018-05-12 10:44:00 -04:00
ret = gspca_init_transfer ( gspca_dev ) ;
if ( ret )
gspca_return_all_buffers ( gspca_dev , VB2_BUF_STATE_QUEUED ) ;
2008-06-12 10:58:58 -03:00
return ret ;
}
2018-05-12 10:44:00 -04:00
static void gspca_stop_streaming ( struct vb2_queue * vq )
2008-06-12 10:58:58 -03:00
{
2018-05-12 10:44:00 -04:00
struct gspca_dev * gspca_dev = vb2_get_drv_priv ( vq ) ;
2008-04-12 09:58:09 -03:00
2018-05-12 10:44:00 -04:00
gspca_stream_off ( gspca_dev ) ;
2008-04-12 09:58:09 -03:00
2018-05-12 10:44:00 -04:00
/* Release all active buffers */
gspca_return_all_buffers ( gspca_dev , VB2_BUF_STATE_ERROR ) ;
2008-04-12 09:58:09 -03:00
}
2018-05-12 10:44:00 -04:00
static const struct vb2_ops gspca_qops = {
. queue_setup = gspca_queue_setup ,
. buf_prepare = gspca_buffer_prepare ,
. buf_finish = gspca_buffer_finish ,
. buf_queue = gspca_buffer_queue ,
. start_streaming = gspca_start_streaming ,
. stop_streaming = gspca_stop_streaming ,
. wait_prepare = vb2_ops_wait_prepare ,
. wait_finish = vb2_ops_wait_finish ,
} ;
2017-06-29 02:55:23 -04:00
static const struct v4l2_file_operations dev_fops = {
2008-04-12 09:58:09 -03:00
. owner = THIS_MODULE ,
2018-05-12 10:44:00 -04:00
. open = v4l2_fh_open ,
. release = vb2_fop_release ,
2008-12-30 06:58:20 -03:00
. unlocked_ioctl = video_ioctl2 ,
2018-05-12 10:44:00 -04:00
. read = vb2_fop_read ,
. mmap = vb2_fop_mmap ,
. poll = vb2_fop_poll ,
2008-04-12 09:58:09 -03:00
} ;
2008-07-21 02:57:38 -03:00
static const struct v4l2_ioctl_ops dev_ioctl_ops = {
2008-04-12 09:58:09 -03:00
. vidioc_querycap = vidioc_querycap ,
2008-07-01 04:06:22 -03:00
. vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap ,
. vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap ,
. vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap ,
. vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap ,
2008-04-12 09:58:09 -03:00
. vidioc_enum_input = vidioc_enum_input ,
. vidioc_g_input = vidioc_g_input ,
. vidioc_s_input = vidioc_s_input ,
. vidioc_g_jpegcomp = vidioc_g_jpegcomp ,
. vidioc_s_jpegcomp = vidioc_s_jpegcomp ,
. vidioc_g_parm = vidioc_g_parm ,
. vidioc_s_parm = vidioc_s_parm ,
2009-05-25 15:04:22 -03:00
. vidioc_enum_framesizes = vidioc_enum_framesizes ,
2009-12-02 06:18:46 -03:00
. vidioc_enum_frameintervals = vidioc_enum_frameintervals ,
2018-05-12 10:44:00 -04:00
. vidioc_reqbufs = vb2_ioctl_reqbufs ,
. vidioc_create_bufs = vb2_ioctl_create_bufs ,
. vidioc_querybuf = vb2_ioctl_querybuf ,
. vidioc_qbuf = vb2_ioctl_qbuf ,
. vidioc_dqbuf = vb2_ioctl_dqbuf ,
. vidioc_expbuf = vb2_ioctl_expbuf ,
. vidioc_streamon = vb2_ioctl_streamon ,
. vidioc_streamoff = vb2_ioctl_streamoff ,
2009-07-19 05:29:20 -03:00
# ifdef CONFIG_VIDEO_ADV_DEBUG
2013-05-29 06:59:42 -03:00
. vidioc_g_chip_info = vidioc_g_chip_info ,
2009-07-19 05:29:20 -03:00
. vidioc_g_register = vidioc_g_register ,
. vidioc_s_register = vidioc_s_register ,
# endif
2012-05-06 09:28:20 -03:00
. vidioc_subscribe_event = v4l2_ctrl_subscribe_event ,
. vidioc_unsubscribe_event = v4l2_event_unsubscribe ,
2008-04-12 09:58:09 -03:00
} ;
2011-03-14 05:33:01 -03:00
static const struct video_device gspca_template = {
2008-07-21 02:57:38 -03:00
. name = " gspca main driver " ,
. fops = & dev_fops ,
. ioctl_ops = & dev_ioctl_ops ,
2012-05-06 09:28:27 -03:00
. release = video_device_release_empty , /* We use v4l2_dev.release */
2008-07-21 02:57:38 -03:00
} ;
2008-04-12 09:58:09 -03:00
/*
* probe and create a new gspca device
*
* This function must be called by the sub - driver when it is
* called for probing a new device .
*/
2010-06-05 07:47:36 -03:00
int gspca_dev_probe2 ( struct usb_interface * intf ,
2008-04-12 09:58:09 -03:00
const struct usb_device_id * id ,
const struct sd_desc * sd_desc ,
2008-06-12 10:58:58 -03:00
int dev_size ,
struct module * module )
2008-04-12 09:58:09 -03:00
{
struct gspca_dev * gspca_dev ;
struct usb_device * dev = interface_to_usbdev ( intf ) ;
2018-05-12 10:44:00 -04:00
struct vb2_queue * q ;
2008-04-12 09:58:09 -03:00
int ret ;
2011-09-23 05:25:28 -03:00
pr_info ( " %s- " GSPCA_VERSION " probing %04x:%04x \n " ,
sd_desc - > name , id - > idVendor , id - > idProduct ) ;
2008-04-12 09:58:09 -03:00
/* create the device */
if ( dev_size < sizeof * gspca_dev )
dev_size = sizeof * gspca_dev ;
gspca_dev = kzalloc ( dev_size , GFP_KERNEL ) ;
2008-10-03 08:46:50 -03:00
if ( ! gspca_dev ) {
2011-08-21 19:56:57 -03:00
pr_err ( " couldn't kzalloc gspca struct \n " ) ;
2008-10-03 08:46:50 -03:00
return - ENOMEM ;
2008-04-12 09:58:09 -03:00
}
2019-11-12 10:22:24 +01:00
gspca_dev - > usb_buf = kzalloc ( USB_BUF_SZ , GFP_KERNEL ) ;
2008-09-03 17:12:19 -03:00
if ( ! gspca_dev - > usb_buf ) {
2011-08-21 19:56:57 -03:00
pr_err ( " out of memory \n " ) ;
2008-10-03 08:46:50 -03:00
ret = - ENOMEM ;
2008-09-03 17:12:19 -03:00
goto out ;
}
2008-04-12 09:58:09 -03:00
gspca_dev - > dev = dev ;
2010-06-05 07:47:36 -03:00
gspca_dev - > iface = intf - > cur_altsetting - > desc . bInterfaceNumber ;
2014-06-25 06:27:56 -03:00
gspca_dev - > xfer_ep = - 1 ;
2010-07-14 06:30:18 -03:00
/* check if any audio device */
2012-01-01 17:20:14 -03:00
if ( dev - > actconfig - > desc . bNumInterfaces ! = 1 ) {
2010-07-14 06:30:18 -03:00
int i ;
struct usb_interface * intf2 ;
2012-01-01 17:20:14 -03:00
for ( i = 0 ; i < dev - > actconfig - > desc . bNumInterfaces ; i + + ) {
intf2 = dev - > actconfig - > interface [ i ] ;
2010-07-14 06:30:18 -03:00
if ( intf2 ! = NULL
& & intf2 - > altsetting ! = NULL
& & intf2 - > altsetting - > desc . bInterfaceClass = =
USB_CLASS_AUDIO ) {
gspca_dev - > audio = 1 ;
break ;
}
}
}
2012-05-06 09:28:27 -03:00
gspca_dev - > v4l2_dev . release = gspca_release ;
2012-05-06 09:28:19 -03:00
ret = v4l2_device_register ( & intf - > dev , & gspca_dev - > v4l2_dev ) ;
if ( ret )
goto out ;
2018-05-12 10:44:00 -04:00
gspca_dev - > present = true ;
2008-04-12 09:58:09 -03:00
gspca_dev - > sd_desc = sd_desc ;
2008-10-23 07:29:51 -03:00
gspca_dev - > empty_packet = - 1 ; /* don't check the empty packets */
2012-05-06 09:28:17 -03:00
gspca_dev - > vdev = gspca_template ;
2012-05-06 09:28:19 -03:00
gspca_dev - > vdev . v4l2_dev = & gspca_dev - > v4l2_dev ;
2019-06-04 07:19:53 -04:00
gspca_dev - > vdev . device_caps = V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_STREAMING | V4L2_CAP_READWRITE ;
2012-05-06 09:28:18 -03:00
video_set_drvdata ( & gspca_dev - > vdev , gspca_dev ) ;
2012-05-06 09:28:17 -03:00
gspca_dev - > module = module ;
mutex_init ( & gspca_dev - > usb_lock ) ;
2012-05-06 09:28:27 -03:00
gspca_dev - > vdev . lock = & gspca_dev - > usb_lock ;
2012-05-06 09:28:17 -03:00
init_waitqueue_head ( & gspca_dev - > wq ) ;
2008-04-12 09:58:09 -03:00
2018-05-12 10:44:00 -04:00
/* Initialize the vb2 queue */
q = & gspca_dev - > queue ;
q - > type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
q - > io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ ;
q - > drv_priv = gspca_dev ;
q - > buf_struct_size = sizeof ( struct gspca_buffer ) ;
q - > ops = & gspca_qops ;
q - > mem_ops = & vb2_vmalloc_memops ;
q - > timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC ;
q - > min_buffers_needed = 2 ;
q - > lock = & gspca_dev - > usb_lock ;
ret = vb2_queue_init ( q ) ;
if ( ret )
goto out ;
gspca_dev - > vdev . queue = q ;
INIT_LIST_HEAD ( & gspca_dev - > buf_list ) ;
spin_lock_init ( & gspca_dev - > qlock ) ;
2008-09-03 17:12:16 -03:00
/* configure the subdriver and initialize the USB device */
2008-11-22 04:27:34 -03:00
ret = sd_desc - > config ( gspca_dev , id ) ;
2008-09-03 17:12:16 -03:00
if ( ret < 0 )
goto out ;
2008-11-22 04:27:34 -03:00
ret = sd_desc - > init ( gspca_dev ) ;
2012-05-06 09:28:17 -03:00
if ( ret < 0 )
goto out ;
if ( sd_desc - > init_controls )
ret = sd_desc - > init_controls ( gspca_dev ) ;
2008-04-12 09:58:09 -03:00
if ( ret < 0 )
goto out ;
gspca_set_default_mode ( gspca_dev ) ;
2010-02-19 04:41:40 -03:00
ret = gspca_input_connect ( gspca_dev ) ;
if ( ret )
goto out ;
2012-05-23 17:17:12 -03:00
# ifdef CONFIG_VIDEO_ADV_DEBUG
2013-05-29 06:59:42 -03:00
if ( ! gspca_dev - > sd_desc - > get_register )
2012-05-23 17:17:12 -03:00
v4l2_disable_ioctl ( & gspca_dev - > vdev , VIDIOC_DBG_G_REGISTER ) ;
2013-05-29 06:59:42 -03:00
if ( ! gspca_dev - > sd_desc - > set_register )
2012-05-23 17:17:12 -03:00
v4l2_disable_ioctl ( & gspca_dev - > vdev , VIDIOC_DBG_S_REGISTER ) ;
# endif
if ( ! gspca_dev - > sd_desc - > get_jcomp )
v4l2_disable_ioctl ( & gspca_dev - > vdev , VIDIOC_G_JPEGCOMP ) ;
if ( ! gspca_dev - > sd_desc - > set_jcomp )
v4l2_disable_ioctl ( & gspca_dev - > vdev , VIDIOC_S_JPEGCOMP ) ;
2012-05-06 09:28:27 -03:00
2008-04-12 09:58:09 -03:00
/* init video stuff */
2008-11-19 06:37:53 -03:00
ret = video_register_device ( & gspca_dev - > vdev ,
2020-02-03 12:41:14 +01:00
VFL_TYPE_VIDEO ,
2009-01-13 06:07:59 -03:00
- 1 ) ;
2008-04-12 09:58:09 -03:00
if ( ret < 0 ) {
2011-08-21 19:56:57 -03:00
pr_err ( " video_register_device err %d \n " , ret ) ;
2008-04-12 09:58:09 -03:00
goto out ;
}
usb_set_intfdata ( intf , gspca_dev ) ;
2017-09-22 15:20:33 -04:00
gspca_dbg ( gspca_dev , D_PROBE , " %s created \n " ,
video_device_node_name ( & gspca_dev - > vdev ) ) ;
2010-01-28 06:39:49 -03:00
2010-02-19 04:41:40 -03:00
gspca_input_create_urb ( gspca_dev ) ;
2010-01-28 06:39:49 -03:00
2008-04-12 09:58:09 -03:00
return 0 ;
out :
2013-01-24 19:28:59 -03:00
# if IS_ENABLED(CONFIG_INPUT)
2010-02-19 04:41:40 -03:00
if ( gspca_dev - > input_dev )
input_unregister_device ( gspca_dev - > input_dev ) ;
2010-02-19 05:11:09 -03:00
# endif
2012-05-06 09:28:17 -03:00
v4l2_ctrl_handler_free ( gspca_dev - > vdev . ctrl_handler ) ;
2008-11-19 06:37:53 -03:00
kfree ( gspca_dev - > usb_buf ) ;
kfree ( gspca_dev ) ;
2008-04-12 09:58:09 -03:00
return ret ;
}
2010-06-05 07:47:36 -03:00
EXPORT_SYMBOL ( gspca_dev_probe2 ) ;
/* same function as the previous one, but check the interface */
int gspca_dev_probe ( struct usb_interface * intf ,
const struct usb_device_id * id ,
const struct sd_desc * sd_desc ,
int dev_size ,
struct module * module )
{
struct usb_device * dev = interface_to_usbdev ( intf ) ;
/* we don't handle multi-config cameras */
if ( dev - > descriptor . bNumConfigurations ! = 1 ) {
2011-08-21 19:56:57 -03:00
pr_err ( " %04x:%04x too many config \n " ,
id - > idVendor , id - > idProduct ) ;
2010-06-05 07:47:36 -03:00
return - ENODEV ;
}
/* the USB video interface must be the first one */
2012-01-01 17:20:14 -03:00
if ( dev - > actconfig - > desc . bNumInterfaces ! = 1
2010-07-14 06:26:54 -03:00
& & intf - > cur_altsetting - > desc . bInterfaceNumber ! = 0 )
2010-06-05 07:47:36 -03:00
return - ENODEV ;
return gspca_dev_probe2 ( intf , id , sd_desc , dev_size , module ) ;
}
2008-04-12 09:58:09 -03:00
EXPORT_SYMBOL ( gspca_dev_probe ) ;
/*
* USB disconnection
*
* This function must be called by the sub - driver
* when the device disconnects , after the specific resources are freed .
*/
void gspca_disconnect ( struct usb_interface * intf )
{
2008-05-04 06:46:21 -03:00
struct gspca_dev * gspca_dev = usb_get_intfdata ( intf ) ;
2013-01-24 19:28:59 -03:00
# if IS_ENABLED(CONFIG_INPUT)
2010-01-28 06:39:49 -03:00
struct input_dev * input_dev ;
2010-02-18 15:02:51 -03:00
# endif
2008-04-12 09:58:09 -03:00
2017-09-22 15:20:33 -04:00
gspca_dbg ( gspca_dev , D_PROBE , " %s disconnect \n " ,
video_device_node_name ( & gspca_dev - > vdev ) ) ;
2012-05-06 09:28:27 -03:00
2009-02-04 15:33:21 -03:00
mutex_lock ( & gspca_dev - > usb_lock ) ;
2018-05-12 10:44:00 -04:00
gspca_dev - > present = false ;
2019-02-28 10:28:34 -05:00
destroy_urbs ( gspca_dev ) ;
gspca_input_destroy_urb ( gspca_dev ) ;
2010-12-30 13:11:21 -03:00
2018-05-12 10:44:00 -04:00
vb2_queue_error ( & gspca_dev - > queue ) ;
2009-02-12 08:05:45 -03:00
2013-01-24 19:28:59 -03:00
# if IS_ENABLED(CONFIG_INPUT)
2010-01-28 06:39:49 -03:00
input_dev = gspca_dev - > input_dev ;
if ( input_dev ) {
gspca_dev - > input_dev = NULL ;
input_unregister_device ( input_dev ) ;
}
2010-02-18 15:02:51 -03:00
# endif
2010-01-28 06:39:49 -03:00
2012-05-06 09:28:19 -03:00
v4l2_device_disconnect ( & gspca_dev - > v4l2_dev ) ;
2012-05-06 09:28:27 -03:00
video_unregister_device ( & gspca_dev - > vdev ) ;
2009-02-12 08:05:45 -03:00
2012-05-06 09:28:27 -03:00
mutex_unlock ( & gspca_dev - > usb_lock ) ;
2008-09-28 08:12:22 -03:00
2011-03-30 22:57:33 -03:00
/* (this will call gspca_release() immediately or on last close) */
2012-05-06 09:28:27 -03:00
v4l2_device_put ( & gspca_dev - > v4l2_dev ) ;
2008-04-12 09:58:09 -03:00
}
EXPORT_SYMBOL ( gspca_disconnect ) ;
2008-09-03 16:48:10 -03:00
# ifdef CONFIG_PM
int gspca_suspend ( struct usb_interface * intf , pm_message_t message )
{
struct gspca_dev * gspca_dev = usb_get_intfdata ( intf ) ;
2012-09-09 08:04:05 -03:00
gspca_input_destroy_urb ( gspca_dev ) ;
2018-05-12 10:44:00 -04:00
if ( ! vb2_start_streaming_called ( & gspca_dev - > queue ) )
2008-09-03 16:48:10 -03:00
return 0 ;
2012-09-09 08:04:05 -03:00
2012-05-06 09:28:27 -03:00
mutex_lock ( & gspca_dev - > usb_lock ) ;
2008-09-03 16:48:10 -03:00
gspca_dev - > frozen = 1 ; /* avoid urb error messages */
2012-05-09 12:11:12 -03:00
gspca_dev - > usb_err = 0 ;
2008-09-03 17:12:16 -03:00
if ( gspca_dev - > sd_desc - > stopN )
gspca_dev - > sd_desc - > stopN ( gspca_dev ) ;
2008-09-03 16:48:10 -03:00
destroy_urbs ( gspca_dev ) ;
gspca_set_alt0 ( gspca_dev ) ;
2012-05-06 09:28:27 -03:00
if ( gspca_dev - > sd_desc - > stop0 )
2008-09-03 17:12:16 -03:00
gspca_dev - > sd_desc - > stop0 ( gspca_dev ) ;
2012-05-06 09:28:27 -03:00
mutex_unlock ( & gspca_dev - > usb_lock ) ;
2012-09-09 08:04:05 -03:00
2008-09-03 16:48:10 -03:00
return 0 ;
}
EXPORT_SYMBOL ( gspca_suspend ) ;
int gspca_resume ( struct usb_interface * intf )
{
struct gspca_dev * gspca_dev = usb_get_intfdata ( intf ) ;
2012-05-06 09:28:22 -03:00
int streaming , ret = 0 ;
2008-09-03 16:48:10 -03:00
2012-05-06 09:28:27 -03:00
mutex_lock ( & gspca_dev - > usb_lock ) ;
2008-09-03 16:48:10 -03:00
gspca_dev - > frozen = 0 ;
2012-05-09 12:11:12 -03:00
gspca_dev - > usb_err = 0 ;
2008-09-03 17:12:16 -03:00
gspca_dev - > sd_desc - > init ( gspca_dev ) ;
2012-05-06 09:28:17 -03:00
/*
* Most subdrivers send all ctrl values on sd_start and thus
* only write to the device registers on s_ctrl when streaming - >
* Clear streaming to avoid setting all ctrls twice .
*/
2018-05-12 10:44:00 -04:00
streaming = vb2_start_streaming_called ( & gspca_dev - > queue ) ;
2012-05-06 09:28:27 -03:00
if ( streaming )
2012-05-06 09:28:22 -03:00
ret = gspca_init_transfer ( gspca_dev ) ;
2012-09-09 08:04:05 -03:00
else
gspca_input_create_urb ( gspca_dev ) ;
2012-05-06 09:28:27 -03:00
mutex_unlock ( & gspca_dev - > usb_lock ) ;
2012-09-09 08:04:05 -03:00
2012-05-06 09:28:22 -03:00
return ret ;
2008-09-03 16:48:10 -03:00
}
EXPORT_SYMBOL ( gspca_resume ) ;
# endif
2008-07-10 10:40:53 -03:00
2008-04-12 09:58:09 -03:00
/* -- module insert / remove -- */
static int __init gspca_init ( void )
{
2011-09-23 05:17:10 -03:00
pr_info ( " v " GSPCA_VERSION " registered \n " ) ;
2008-04-12 09:58:09 -03:00
return 0 ;
}
static void __exit gspca_exit ( void )
{
}
module_init ( gspca_init ) ;
module_exit ( gspca_exit ) ;
module_param_named ( debug , gspca_debug , int , 0644 ) ;
MODULE_PARM_DESC ( debug ,
2013-02-04 13:17:55 -03:00
" 1:probe 2:config 3:stream 4:frame 5:packet 6:usbi 7:usbo " ) ;