diff options
Diffstat (limited to 'drivers/media/video/pvrusb2')
46 files changed, 0 insertions, 15875 deletions
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig deleted file mode 100644 index 25e412ecad2c..000000000000 --- a/drivers/media/video/pvrusb2/Kconfig +++ /dev/null @@ -1,65 +0,0 @@ -config VIDEO_PVRUSB2 - tristate "Hauppauge WinTV-PVR USB2 support" - depends on VIDEO_V4L2 && I2C - select VIDEO_TUNER - select VIDEO_TVEEPROM - select VIDEO_CX2341X - select VIDEO_SAA711X - select VIDEO_CX25840 - select VIDEO_MSP3400 - select VIDEO_WM8775 - select VIDEO_CS53L32A - ---help--- - This is a video4linux driver for Conexant 23416 based - usb2 personal video recorder devices. - - To compile this driver as a module, choose M here: the - module will be called pvrusb2 - -config VIDEO_PVRUSB2_SYSFS - bool "pvrusb2 sysfs support (EXPERIMENTAL)" - default y - depends on VIDEO_PVRUSB2 && SYSFS && EXPERIMENTAL - ---help--- - This option enables the operation of a sysfs based - interface for query and control of the pvrusb2 driver. - - This is not generally needed for v4l applications, - although certain applications are optimized to take - advantage of this feature. - - If you are in doubt, say Y. - - Note: This feature is experimental and subject to change. - -config VIDEO_PVRUSB2_DVB - bool "pvrusb2 ATSC/DVB support (EXPERIMENTAL)" - default y - depends on VIDEO_PVRUSB2 && DVB_CORE && EXPERIMENTAL - select DVB_LGDT330X if !DVB_FE_CUSTOMISE - select DVB_S5H1409 if !DVB_FE_CUSTOMISE - select DVB_S5H1411 if !DVB_FE_CUSTOMISE - select DVB_TDA10048 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE - ---help--- - - This option enables a DVB interface for the pvrusb2 driver. - If your device does not support digital television, this - feature will have no affect on the driver's operation. - - If you are in doubt, say Y. - -config VIDEO_PVRUSB2_DEBUGIFC - bool "pvrusb2 debug interface" - depends on VIDEO_PVRUSB2_SYSFS - ---help--- - This option enables the inclusion of a debug interface - in the pvrusb2 driver, hosted through sysfs. - - You do not need to select this option unless you plan - on debugging the driver or performing a manual firmware - extraction. - - If you are in doubt, say N. diff --git a/drivers/media/video/pvrusb2/Makefile b/drivers/media/video/pvrusb2/Makefile deleted file mode 100644 index bc716db797e3..000000000000 --- a/drivers/media/video/pvrusb2/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o -obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o -obj-pvrusb2-dvb-$(CONFIG_VIDEO_PVRUSB2_DVB) := pvrusb2-dvb.o - -pvrusb2-objs := pvrusb2-i2c-core.o \ - pvrusb2-audio.o \ - pvrusb2-encoder.o pvrusb2-video-v4l.o \ - pvrusb2-eeprom.o \ - pvrusb2-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \ - pvrusb2-ctrl.o pvrusb2-std.o pvrusb2-devattr.o \ - pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \ - pvrusb2-cx2584x-v4l.o pvrusb2-wm8775.o \ - pvrusb2-cs53l32a.o \ - $(obj-pvrusb2-dvb-y) \ - $(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y) - -obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o - -ccflags-y += -Idrivers/media/video -ccflags-y += -Idrivers/media/tuners -ccflags-y += -Idrivers/media/dvb-core -ccflags-y += -Idrivers/media/dvb-frontends diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c deleted file mode 100644 index cc06d5e4adcc..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-audio.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 "pvrusb2-audio.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include <linux/videodev2.h> -#include <media/msp3400.h> -#include <media/v4l2-common.h> - - -struct routing_scheme { - const int *def; - unsigned int cnt; -}; - -static const int routing_scheme0[] = { - [PVR2_CVAL_INPUT_TV] = MSP_INPUT_DEFAULT, - [PVR2_CVAL_INPUT_RADIO] = MSP_INPUT(MSP_IN_SCART2, - MSP_IN_TUNER1, - MSP_DSP_IN_SCART, - MSP_DSP_IN_SCART), - [PVR2_CVAL_INPUT_COMPOSITE] = MSP_INPUT(MSP_IN_SCART1, - MSP_IN_TUNER1, - MSP_DSP_IN_SCART, - MSP_DSP_IN_SCART), - [PVR2_CVAL_INPUT_SVIDEO] = MSP_INPUT(MSP_IN_SCART1, - MSP_IN_TUNER1, - MSP_DSP_IN_SCART, - MSP_DSP_IN_SCART), -}; - -static const struct routing_scheme routing_def0 = { - .def = routing_scheme0, - .cnt = ARRAY_SIZE(routing_scheme0), -}; - -static const struct routing_scheme *routing_schemes[] = { - [PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0, -}; - -void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) -{ - if (hdw->input_dirty || hdw->force_dirty) { - const struct routing_scheme *sp; - unsigned int sid = hdw->hdw_desc->signal_routing_scheme; - u32 input; - - pvr2_trace(PVR2_TRACE_CHIPS, "subdev msp3400 v4l2 set_stereo"); - sp = (sid < ARRAY_SIZE(routing_schemes)) ? - routing_schemes[sid] : NULL; - - if ((sp != NULL) && - (hdw->input_val >= 0) && - (hdw->input_val < sp->cnt)) { - input = sp->def[hdw->input_val]; - } else { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "*** WARNING *** subdev msp3400 set_input:" - " Invalid routing scheme (%u)" - " and/or input (%d)", - sid, hdw->input_val); - return; - } - sd->ops->audio->s_routing(sd, input, - MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0); - } -} - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.h b/drivers/media/video/pvrusb2/pvrusb2-audio.h deleted file mode 100644 index e3e63d750891..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-audio.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ - -#ifndef __PVRUSB2_AUDIO_H -#define __PVRUSB2_AUDIO_H - -#include "pvrusb2-hdw-internal.h" -void pvr2_msp3400_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *); -#endif /* __PVRUSB2_AUDIO_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.c b/drivers/media/video/pvrusb2/pvrusb2-context.c deleted file mode 100644 index 7c19ff72e6b3..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-context.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 "pvrusb2-context.h" -#include "pvrusb2-io.h" -#include "pvrusb2-ioread.h" -#include "pvrusb2-hdw.h" -#include "pvrusb2-debug.h" -#include <linux/wait.h> -#include <linux/kthread.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/slab.h> - -static struct pvr2_context *pvr2_context_exist_first; -static struct pvr2_context *pvr2_context_exist_last; -static struct pvr2_context *pvr2_context_notify_first; -static struct pvr2_context *pvr2_context_notify_last; -static DEFINE_MUTEX(pvr2_context_mutex); -static DECLARE_WAIT_QUEUE_HEAD(pvr2_context_sync_data); -static DECLARE_WAIT_QUEUE_HEAD(pvr2_context_cleanup_data); -static int pvr2_context_cleanup_flag; -static int pvr2_context_cleaned_flag; -static struct task_struct *pvr2_context_thread_ptr; - - -static void pvr2_context_set_notify(struct pvr2_context *mp, int fl) -{ - int signal_flag = 0; - mutex_lock(&pvr2_context_mutex); - if (fl) { - if (!mp->notify_flag) { - signal_flag = (pvr2_context_notify_first == NULL); - mp->notify_prev = pvr2_context_notify_last; - mp->notify_next = NULL; - pvr2_context_notify_last = mp; - if (mp->notify_prev) { - mp->notify_prev->notify_next = mp; - } else { - pvr2_context_notify_first = mp; - } - mp->notify_flag = !0; - } - } else { - if (mp->notify_flag) { - mp->notify_flag = 0; - if (mp->notify_next) { - mp->notify_next->notify_prev = mp->notify_prev; - } else { - pvr2_context_notify_last = mp->notify_prev; - } - if (mp->notify_prev) { - mp->notify_prev->notify_next = mp->notify_next; - } else { - pvr2_context_notify_first = mp->notify_next; - } - } - } - mutex_unlock(&pvr2_context_mutex); - if (signal_flag) wake_up(&pvr2_context_sync_data); -} - - -static void pvr2_context_destroy(struct pvr2_context *mp) -{ - pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context %p (destroy)",mp); - if (mp->hdw) pvr2_hdw_destroy(mp->hdw); - pvr2_context_set_notify(mp, 0); - mutex_lock(&pvr2_context_mutex); - if (mp->exist_next) { - mp->exist_next->exist_prev = mp->exist_prev; - } else { - pvr2_context_exist_last = mp->exist_prev; - } - if (mp->exist_prev) { - mp->exist_prev->exist_next = mp->exist_next; - } else { - pvr2_context_exist_first = mp->exist_next; - } - if (!pvr2_context_exist_first) { - /* Trigger wakeup on control thread in case it is waiting - for an exit condition. */ - wake_up(&pvr2_context_sync_data); - } - mutex_unlock(&pvr2_context_mutex); - kfree(mp); -} - - -static void pvr2_context_notify(struct pvr2_context *mp) -{ - pvr2_context_set_notify(mp,!0); -} - - -static void pvr2_context_check(struct pvr2_context *mp) -{ - struct pvr2_channel *ch1, *ch2; - pvr2_trace(PVR2_TRACE_CTXT, - "pvr2_context %p (notify)", mp); - if (!mp->initialized_flag && !mp->disconnect_flag) { - mp->initialized_flag = !0; - pvr2_trace(PVR2_TRACE_CTXT, - "pvr2_context %p (initialize)", mp); - /* Finish hardware initialization */ - if (pvr2_hdw_initialize(mp->hdw, - (void (*)(void *))pvr2_context_notify, - mp)) { - mp->video_stream.stream = - pvr2_hdw_get_video_stream(mp->hdw); - /* Trigger interface initialization. By doing this - here initialization runs in our own safe and - cozy thread context. */ - if (mp->setup_func) mp->setup_func(mp); - } else { - pvr2_trace(PVR2_TRACE_CTXT, - "pvr2_context %p (thread skipping setup)", - mp); - /* Even though initialization did not succeed, - we're still going to continue anyway. We need - to do this in order to await the expected - disconnect (which we will detect in the normal - course of operation). */ - } - } - - for (ch1 = mp->mc_first; ch1; ch1 = ch2) { - ch2 = ch1->mc_next; - if (ch1->check_func) ch1->check_func(ch1); - } - - if (mp->disconnect_flag && !mp->mc_first) { - /* Go away... */ - pvr2_context_destroy(mp); - return; - } -} - - -static int pvr2_context_shutok(void) -{ - return pvr2_context_cleanup_flag && (pvr2_context_exist_first == NULL); -} - - -static int pvr2_context_thread_func(void *foo) -{ - struct pvr2_context *mp; - - pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context thread start"); - - do { - while ((mp = pvr2_context_notify_first) != NULL) { - pvr2_context_set_notify(mp, 0); - pvr2_context_check(mp); - } - wait_event_interruptible( - pvr2_context_sync_data, - ((pvr2_context_notify_first != NULL) || - pvr2_context_shutok())); - } while (!pvr2_context_shutok()); - - pvr2_context_cleaned_flag = !0; - wake_up(&pvr2_context_cleanup_data); - - pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context thread cleaned up"); - - wait_event_interruptible( - pvr2_context_sync_data, - kthread_should_stop()); - - pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context thread end"); - - return 0; -} - - -int pvr2_context_global_init(void) -{ - pvr2_context_thread_ptr = kthread_run(pvr2_context_thread_func, - NULL, - "pvrusb2-context"); - return (pvr2_context_thread_ptr ? 0 : -ENOMEM); -} - - -void pvr2_context_global_done(void) -{ - pvr2_context_cleanup_flag = !0; - wake_up(&pvr2_context_sync_data); - wait_event_interruptible( - pvr2_context_cleanup_data, - pvr2_context_cleaned_flag); - kthread_stop(pvr2_context_thread_ptr); -} - - -struct pvr2_context *pvr2_context_create( - struct usb_interface *intf, - const struct usb_device_id *devid, - void (*setup_func)(struct pvr2_context *)) -{ - struct pvr2_context *mp = NULL; - mp = kzalloc(sizeof(*mp),GFP_KERNEL); - if (!mp) goto done; - pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context %p (create)",mp); - mp->setup_func = setup_func; - mutex_init(&mp->mutex); - mutex_lock(&pvr2_context_mutex); - mp->exist_prev = pvr2_context_exist_last; - mp->exist_next = NULL; - pvr2_context_exist_last = mp; - if (mp->exist_prev) { - mp->exist_prev->exist_next = mp; - } else { - pvr2_context_exist_first = mp; - } - mutex_unlock(&pvr2_context_mutex); - mp->hdw = pvr2_hdw_create(intf,devid); - if (!mp->hdw) { - pvr2_context_destroy(mp); - mp = NULL; - goto done; - } - pvr2_context_set_notify(mp, !0); - done: - return mp; -} - - -static void pvr2_context_reset_input_limits(struct pvr2_context *mp) -{ - unsigned int tmsk,mmsk; - struct pvr2_channel *cp; - struct pvr2_hdw *hdw = mp->hdw; - mmsk = pvr2_hdw_get_input_available(hdw); - tmsk = mmsk; - for (cp = mp->mc_first; cp; cp = cp->mc_next) { - if (!cp->input_mask) continue; - tmsk &= cp->input_mask; - } - pvr2_hdw_set_input_allowed(hdw,mmsk,tmsk); - pvr2_hdw_commit_ctl(hdw); -} - - -static void pvr2_context_enter(struct pvr2_context *mp) -{ - mutex_lock(&mp->mutex); -} - - -static void pvr2_context_exit(struct pvr2_context *mp) -{ - int destroy_flag = 0; - if (!(mp->mc_first || !mp->disconnect_flag)) { - destroy_flag = !0; - } - mutex_unlock(&mp->mutex); - if (destroy_flag) pvr2_context_notify(mp); -} - - -void pvr2_context_disconnect(struct pvr2_context *mp) -{ - pvr2_hdw_disconnect(mp->hdw); - mp->disconnect_flag = !0; - pvr2_context_notify(mp); -} - - -void pvr2_channel_init(struct pvr2_channel *cp,struct pvr2_context *mp) -{ - pvr2_context_enter(mp); - cp->hdw = mp->hdw; - cp->mc_head = mp; - cp->mc_next = NULL; - cp->mc_prev = mp->mc_last; - if (mp->mc_last) { - mp->mc_last->mc_next = cp; - } else { - mp->mc_first = cp; - } - mp->mc_last = cp; - pvr2_context_exit(mp); -} - - -static void pvr2_channel_disclaim_stream(struct pvr2_channel *cp) -{ - if (!cp->stream) return; - pvr2_stream_kill(cp->stream->stream); - cp->stream->user = NULL; - cp->stream = NULL; -} - - -void pvr2_channel_done(struct pvr2_channel *cp) -{ - struct pvr2_context *mp = cp->mc_head; - pvr2_context_enter(mp); - cp->input_mask = 0; - pvr2_channel_disclaim_stream(cp); - pvr2_context_reset_input_limits(mp); - if (cp->mc_next) { - cp->mc_next->mc_prev = cp->mc_prev; - } else { - mp->mc_last = cp->mc_prev; - } - if (cp->mc_prev) { - cp->mc_prev->mc_next = cp->mc_next; - } else { - mp->mc_first = cp->mc_next; - } - cp->hdw = NULL; - pvr2_context_exit(mp); -} - - -int pvr2_channel_limit_inputs(struct pvr2_channel *cp,unsigned int cmsk) -{ - unsigned int tmsk,mmsk; - int ret = 0; - struct pvr2_channel *p2; - struct pvr2_hdw *hdw = cp->hdw; - - mmsk = pvr2_hdw_get_input_available(hdw); - cmsk &= mmsk; - if (cmsk == cp->input_mask) { - /* No change; nothing to do */ - return 0; - } - - pvr2_context_enter(cp->mc_head); - do { - if (!cmsk) { - cp->input_mask = 0; - pvr2_context_reset_input_limits(cp->mc_head); - break; - } - tmsk = mmsk; - for (p2 = cp->mc_head->mc_first; p2; p2 = p2->mc_next) { - if (p2 == cp) continue; - if (!p2->input_mask) continue; - tmsk &= p2->input_mask; - } - if (!(tmsk & cmsk)) { - ret = -EPERM; - break; - } - tmsk &= cmsk; - if ((ret = pvr2_hdw_set_input_allowed(hdw,mmsk,tmsk)) != 0) { - /* Internal failure changing allowed list; probably - should not happen, but react if it does. */ - break; - } - cp->input_mask = cmsk; - pvr2_hdw_commit_ctl(hdw); - } while (0); - pvr2_context_exit(cp->mc_head); - return ret; -} - - -unsigned int pvr2_channel_get_limited_inputs(struct pvr2_channel *cp) -{ - return cp->input_mask; -} - - -int pvr2_channel_claim_stream(struct pvr2_channel *cp, - struct pvr2_context_stream *sp) -{ - int code = 0; - pvr2_context_enter(cp->mc_head); do { - if (sp == cp->stream) break; - if (sp && sp->user) { - code = -EBUSY; - break; - } - pvr2_channel_disclaim_stream(cp); - if (!sp) break; - sp->user = cp; - cp->stream = sp; - } while (0); pvr2_context_exit(cp->mc_head); - return code; -} - - -// This is the marker for the real beginning of a legitimate mpeg2 stream. -static char stream_sync_key[] = { - 0x00, 0x00, 0x01, 0xba, -}; - -struct pvr2_ioread *pvr2_channel_create_mpeg_stream( - struct pvr2_context_stream *sp) -{ - struct pvr2_ioread *cp; - cp = pvr2_ioread_create(); - if (!cp) return NULL; - pvr2_ioread_setup(cp,sp->stream); - pvr2_ioread_set_sync_key(cp,stream_sync_key,sizeof(stream_sync_key)); - return cp; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.h b/drivers/media/video/pvrusb2/pvrusb2-context.h deleted file mode 100644 index d657e53bbfa3..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-context.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ -#ifndef __PVRUSB2_CONTEXT_H -#define __PVRUSB2_CONTEXT_H - -#include <linux/mutex.h> -#include <linux/usb.h> -#include <linux/workqueue.h> - -struct pvr2_hdw; /* hardware interface - defined elsewhere */ -struct pvr2_stream; /* stream interface - defined elsewhere */ - -struct pvr2_context; /* All central state */ -struct pvr2_channel; /* One I/O pathway to a user */ -struct pvr2_context_stream; /* Wrapper for a stream */ -struct pvr2_ioread; /* Low level stream structure */ - -struct pvr2_context_stream { - struct pvr2_channel *user; - struct pvr2_stream *stream; -}; - -struct pvr2_context { - struct pvr2_channel *mc_first; - struct pvr2_channel *mc_last; - struct pvr2_context *exist_next; - struct pvr2_context *exist_prev; - struct pvr2_context *notify_next; - struct pvr2_context *notify_prev; - struct pvr2_hdw *hdw; - struct pvr2_context_stream video_stream; - struct mutex mutex; - int notify_flag; - int initialized_flag; - int disconnect_flag; - - /* Called after pvr2_context initialization is complete */ - void (*setup_func)(struct pvr2_context *); - -}; - -struct pvr2_channel { - struct pvr2_context *mc_head; - struct pvr2_channel *mc_next; - struct pvr2_channel *mc_prev; - struct pvr2_context_stream *stream; - struct pvr2_hdw *hdw; - unsigned int input_mask; - void (*check_func)(struct pvr2_channel *); -}; - -struct pvr2_context *pvr2_context_create(struct usb_interface *intf, - const struct usb_device_id *devid, - void (*setup_func)(struct pvr2_context *)); -void pvr2_context_disconnect(struct pvr2_context *); - -void pvr2_channel_init(struct pvr2_channel *,struct pvr2_context *); -void pvr2_channel_done(struct pvr2_channel *); -int pvr2_channel_limit_inputs(struct pvr2_channel *,unsigned int); -unsigned int pvr2_channel_get_limited_inputs(struct pvr2_channel *); -int pvr2_channel_claim_stream(struct pvr2_channel *, - struct pvr2_context_stream *); -struct pvr2_ioread *pvr2_channel_create_mpeg_stream( - struct pvr2_context_stream *); - -int pvr2_context_global_init(void); -void pvr2_context_global_done(void); - -#endif /* __PVRUSB2_CONTEXT_H */ -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c deleted file mode 100644 index 88320900dbd4..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 source file is specifically designed to interface with the - v4l-dvb cs53l32a module. - -*/ - -#include "pvrusb2-cs53l32a.h" - - -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include <linux/videodev2.h> -#include <media/v4l2-common.h> -#include <linux/errno.h> - -struct routing_scheme { - const int *def; - unsigned int cnt; -}; - - -static const int routing_scheme1[] = { - [PVR2_CVAL_INPUT_TV] = 2, /* 1 or 2 seems to work here */ - [PVR2_CVAL_INPUT_RADIO] = 2, - [PVR2_CVAL_INPUT_COMPOSITE] = 0, - [PVR2_CVAL_INPUT_SVIDEO] = 0, -}; - -static const struct routing_scheme routing_def1 = { - .def = routing_scheme1, - .cnt = ARRAY_SIZE(routing_scheme1), -}; - -static const struct routing_scheme *routing_schemes[] = { - [PVR2_ROUTING_SCHEME_ONAIR] = &routing_def1, -}; - - -void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) -{ - if (hdw->input_dirty || hdw->force_dirty) { - const struct routing_scheme *sp; - unsigned int sid = hdw->hdw_desc->signal_routing_scheme; - u32 input; - pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)", - hdw->input_val); - sp = (sid < ARRAY_SIZE(routing_schemes)) ? - routing_schemes[sid] : NULL; - if ((sp == NULL) || - (hdw->input_val < 0) || - (hdw->input_val >= sp->cnt)) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "*** WARNING *** subdev v4l2 set_input:" - " Invalid routing scheme (%u)" - " and/or input (%d)", - sid, hdw->input_val); - return; - } - input = sp->def[hdw->input_val]; - sd->ops->audio->s_routing(sd, input, 0, 0); - } -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h deleted file mode 100644 index 53ba548b72a7..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ - -#ifndef __PVRUSB2_CS53L32A_H -#define __PVRUSB2_CS53L32A_H - -/* - - This module connects the pvrusb2 driver to the I2C chip level - driver which handles device video processing. This interface is - used internally by the driver; higher level code should only - interact through the interface provided by pvrusb2-hdw.h. - -*/ - - -#include "pvrusb2-hdw-internal.h" -void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *); - -#endif /* __PVRUSB2_AUDIO_CS53L32A_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c deleted file mode 100644 index 7d5a7139a45a..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c +++ /dev/null @@ -1,609 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 "pvrusb2-ctrl.h" -#include "pvrusb2-hdw-internal.h" -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/mutex.h> - - -static int pvr2_ctrl_range_check(struct pvr2_ctrl *cptr,int val) -{ - if (cptr->info->check_value) { - if (!cptr->info->check_value(cptr,val)) return -ERANGE; - } else if (cptr->info->type == pvr2_ctl_enum) { - if (val < 0) return -ERANGE; - if (val >= cptr->info->def.type_enum.count) return -ERANGE; - } else { - int lim; - lim = cptr->info->def.type_int.min_value; - if (cptr->info->get_min_value) { - cptr->info->get_min_value(cptr,&lim); - } - if (val < lim) return -ERANGE; - lim = cptr->info->def.type_int.max_value; - if (cptr->info->get_max_value) { - cptr->info->get_max_value(cptr,&lim); - } - if (val > lim) return -ERANGE; - } - return 0; -} - - -/* Set the given control. */ -int pvr2_ctrl_set_value(struct pvr2_ctrl *cptr,int val) -{ - return pvr2_ctrl_set_mask_value(cptr,~0,val); -} - - -/* Set/clear specific bits of the given control. */ -int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val) -{ - int ret = 0; - if (!cptr) return -EINVAL; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->set_value) { - if (cptr->info->type == pvr2_ctl_bitmask) { - mask &= cptr->info->def.type_bitmask.valid_bits; - } else if ((cptr->info->type == pvr2_ctl_int)|| - (cptr->info->type == pvr2_ctl_enum)) { - ret = pvr2_ctrl_range_check(cptr,val); - if (ret < 0) break; - } else if (cptr->info->type != pvr2_ctl_bool) { - break; - } - ret = cptr->info->set_value(cptr,mask,val); - } else { - ret = -EPERM; - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Get the current value of the given control. */ -int pvr2_ctrl_get_value(struct pvr2_ctrl *cptr,int *valptr) -{ - int ret = 0; - if (!cptr) return -EINVAL; - LOCK_TAKE(cptr->hdw->big_lock); do { - ret = cptr->info->get_value(cptr,valptr); - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Retrieve control's type */ -enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *cptr) -{ - if (!cptr) return pvr2_ctl_int; - return cptr->info->type; -} - - -/* Retrieve control's maximum value (int type) */ -int pvr2_ctrl_get_max(struct pvr2_ctrl *cptr) -{ - int ret = 0; - if (!cptr) return 0; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->get_max_value) { - cptr->info->get_max_value(cptr,&ret); - } else if (cptr->info->type == pvr2_ctl_int) { - ret = cptr->info->def.type_int.max_value; - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Retrieve control's minimum value (int type) */ -int pvr2_ctrl_get_min(struct pvr2_ctrl *cptr) -{ - int ret = 0; - if (!cptr) return 0; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->get_min_value) { - cptr->info->get_min_value(cptr,&ret); - } else if (cptr->info->type == pvr2_ctl_int) { - ret = cptr->info->def.type_int.min_value; - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Retrieve control's default value (any type) */ -int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr, int *valptr) -{ - int ret = 0; - if (!cptr) return -EINVAL; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->get_def_value) { - ret = cptr->info->get_def_value(cptr, valptr); - } else { - *valptr = cptr->info->default_value; - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Retrieve control's enumeration count (enum only) */ -int pvr2_ctrl_get_cnt(struct pvr2_ctrl *cptr) -{ - int ret = 0; - if (!cptr) return 0; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->type == pvr2_ctl_enum) { - ret = cptr->info->def.type_enum.count; - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Retrieve control's valid mask bits (bit mask only) */ -int pvr2_ctrl_get_mask(struct pvr2_ctrl *cptr) -{ - int ret = 0; - if (!cptr) return 0; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->type == pvr2_ctl_bitmask) { - ret = cptr->info->def.type_bitmask.valid_bits; - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Retrieve the control's name */ -const char *pvr2_ctrl_get_name(struct pvr2_ctrl *cptr) -{ - if (!cptr) return NULL; - return cptr->info->name; -} - - -/* Retrieve the control's desc */ -const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *cptr) -{ - if (!cptr) return NULL; - return cptr->info->desc; -} - - -/* Retrieve a control enumeration or bit mask value */ -int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val, - char *bptr,unsigned int bmax, - unsigned int *blen) -{ - int ret = -EINVAL; - if (!cptr) return 0; - *blen = 0; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->type == pvr2_ctl_enum) { - const char * const *names; - names = cptr->info->def.type_enum.value_names; - if (pvr2_ctrl_range_check(cptr,val) == 0) { - if (names[val]) { - *blen = scnprintf( - bptr,bmax,"%s", - names[val]); - } else { - *blen = 0; - } - ret = 0; - } - } else if (cptr->info->type == pvr2_ctl_bitmask) { - const char **names; - unsigned int idx; - int msk; - names = cptr->info->def.type_bitmask.bit_names; - val &= cptr->info->def.type_bitmask.valid_bits; - for (idx = 0, msk = 1; val; idx++, msk <<= 1) { - if (val & msk) { - *blen = scnprintf(bptr,bmax,"%s", - names[idx]); - ret = 0; - break; - } - } - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Return V4L ID for this control or zero if none */ -int pvr2_ctrl_get_v4lid(struct pvr2_ctrl *cptr) -{ - if (!cptr) return 0; - return cptr->info->v4l_id; -} - - -unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *cptr) -{ - unsigned int flags = 0; - - if (cptr->info->get_v4lflags) { - flags = cptr->info->get_v4lflags(cptr); - } - - if (cptr->info->set_value) { - flags &= ~V4L2_CTRL_FLAG_READ_ONLY; - } else { - flags |= V4L2_CTRL_FLAG_READ_ONLY; - } - - return flags; -} - - -/* Return true if control is writable */ -int pvr2_ctrl_is_writable(struct pvr2_ctrl *cptr) -{ - if (!cptr) return 0; - return cptr->info->set_value != NULL; -} - - -/* Return true if control has custom symbolic representation */ -int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *cptr) -{ - if (!cptr) return 0; - if (!cptr->info->val_to_sym) return 0; - if (!cptr->info->sym_to_val) return 0; - return !0; -} - - -/* Convert a given mask/val to a custom symbolic value */ -int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *cptr, - int mask,int val, - char *buf,unsigned int maxlen, - unsigned int *len) -{ - if (!cptr) return -EINVAL; - if (!cptr->info->val_to_sym) return -EINVAL; - return cptr->info->val_to_sym(cptr,mask,val,buf,maxlen,len); -} - - -/* Convert a symbolic value to a mask/value pair */ -int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *cptr, - const char *buf,unsigned int len, - int *maskptr,int *valptr) -{ - if (!cptr) return -EINVAL; - if (!cptr->info->sym_to_val) return -EINVAL; - return cptr->info->sym_to_val(cptr,buf,len,maskptr,valptr); -} - - -static unsigned int gen_bitmask_string(int msk,int val,int msk_only, - const char **names, - char *ptr,unsigned int len) -{ - unsigned int idx; - long sm,um; - int spcFl; - unsigned int uc,cnt; - const char *idStr; - - spcFl = 0; - uc = 0; - um = 0; - for (idx = 0, sm = 1; msk; idx++, sm <<= 1) { - if (sm & msk) { - msk &= ~sm; - idStr = names[idx]; - if (idStr) { - cnt = scnprintf(ptr,len,"%s%s%s", - (spcFl ? " " : ""), - (msk_only ? "" : - ((val & sm) ? "+" : "-")), - idStr); - ptr += cnt; len -= cnt; uc += cnt; - spcFl = !0; - } else { - um |= sm; - } - } - } - if (um) { - if (msk_only) { - cnt = scnprintf(ptr,len,"%s0x%lx", - (spcFl ? " " : ""), - um); - ptr += cnt; len -= cnt; uc += cnt; - spcFl = !0; - } else if (um & val) { - cnt = scnprintf(ptr,len,"%s+0x%lx", - (spcFl ? " " : ""), - um & val); - ptr += cnt; len -= cnt; uc += cnt; - spcFl = !0; - } else if (um & ~val) { - cnt = scnprintf(ptr,len,"%s+0x%lx", - (spcFl ? " " : ""), - um & ~val); - ptr += cnt; len -= cnt; uc += cnt; - spcFl = !0; - } - } - return uc; -} - - -static const char *boolNames[] = { - "false", - "true", - "no", - "yes", -}; - - -static int parse_token(const char *ptr,unsigned int len, - int *valptr, - const char * const *names, unsigned int namecnt) -{ - char buf[33]; - unsigned int slen; - unsigned int idx; - int negfl; - char *p2; - *valptr = 0; - if (!names) namecnt = 0; - for (idx = 0; idx < namecnt; idx++) { - if (!names[idx]) continue; - slen = strlen(names[idx]); - if (slen != len) continue; - if (memcmp(names[idx],ptr,slen)) continue; - *valptr = idx; - return 0; - } - negfl = 0; - if ((*ptr == '-') || (*ptr == '+')) { - negfl = (*ptr == '-'); - ptr++; len--; - } - if (len >= sizeof(buf)) return -EINVAL; - memcpy(buf,ptr,len); - buf[len] = 0; - *valptr = simple_strtol(buf,&p2,0); - if (negfl) *valptr = -(*valptr); - if (*p2) return -EINVAL; - return 1; -} - - -static int parse_mtoken(const char *ptr,unsigned int len, - int *valptr, - const char **names,int valid_bits) -{ - char buf[33]; - unsigned int slen; - unsigned int idx; - char *p2; - int msk; - *valptr = 0; - for (idx = 0, msk = 1; valid_bits; idx++, msk <<= 1) { - if (!(msk & valid_bits)) continue; - valid_bits &= ~msk; - if (!names[idx]) continue; - slen = strlen(names[idx]); - if (slen != len) continue; - if (memcmp(names[idx],ptr,slen)) continue; - *valptr = msk; - return 0; - } - if (len >= sizeof(buf)) return -EINVAL; - memcpy(buf,ptr,len); - buf[len] = 0; - *valptr = simple_strtol(buf,&p2,0); - if (*p2) return -EINVAL; - return 0; -} - - -static int parse_tlist(const char *ptr,unsigned int len, - int *maskptr,int *valptr, - const char **names,int valid_bits) -{ - unsigned int cnt; - int mask,val,kv,mode,ret; - mask = 0; - val = 0; - ret = 0; - while (len) { - cnt = 0; - while ((cnt < len) && - ((ptr[cnt] <= 32) || - (ptr[cnt] >= 127))) cnt++; - ptr += cnt; - len -= cnt; - mode = 0; - if ((*ptr == '-') || (*ptr == '+')) { - mode = (*ptr == '-') ? -1 : 1; - ptr++; - len--; - } - cnt = 0; - while (cnt < len) { - if (ptr[cnt] <= 32) break; - if (ptr[cnt] >= 127) break; - cnt++; - } - if (!cnt) break; - if (parse_mtoken(ptr,cnt,&kv,names,valid_bits)) { - ret = -EINVAL; - break; - } - ptr += cnt; - len -= cnt; - switch (mode) { - case 0: - mask = valid_bits; - val |= kv; - break; - case -1: - mask |= kv; - val &= ~kv; - break; - case 1: - mask |= kv; - val |= kv; - break; - default: - break; - } - } - *maskptr = mask; - *valptr = val; - return ret; -} - - -/* Convert a symbolic value to a mask/value pair */ -int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, - const char *ptr,unsigned int len, - int *maskptr,int *valptr) -{ - int ret = -EINVAL; - unsigned int cnt; - - *maskptr = 0; - *valptr = 0; - - cnt = 0; - while ((cnt < len) && ((ptr[cnt] <= 32) || (ptr[cnt] >= 127))) cnt++; - len -= cnt; ptr += cnt; - cnt = 0; - while ((cnt < len) && ((ptr[len-(cnt+1)] <= 32) || - (ptr[len-(cnt+1)] >= 127))) cnt++; - len -= cnt; - - if (!len) return -EINVAL; - - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->type == pvr2_ctl_int) { - ret = parse_token(ptr,len,valptr,NULL,0); - if (ret >= 0) { - ret = pvr2_ctrl_range_check(cptr,*valptr); - } - *maskptr = ~0; - } else if (cptr->info->type == pvr2_ctl_bool) { - ret = parse_token(ptr,len,valptr,boolNames, - ARRAY_SIZE(boolNames)); - if (ret == 1) { - *valptr = *valptr ? !0 : 0; - } else if (ret == 0) { - *valptr = (*valptr & 1) ? !0 : 0; - } - *maskptr = 1; - } else if (cptr->info->type == pvr2_ctl_enum) { - ret = parse_token( - ptr,len,valptr, - cptr->info->def.type_enum.value_names, - cptr->info->def.type_enum.count); - if (ret >= 0) { - ret = pvr2_ctrl_range_check(cptr,*valptr); - } - *maskptr = ~0; - } else if (cptr->info->type == pvr2_ctl_bitmask) { - ret = parse_tlist( - ptr,len,maskptr,valptr, - cptr->info->def.type_bitmask.bit_names, - cptr->info->def.type_bitmask.valid_bits); - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Convert a given mask/val to a symbolic value */ -int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *cptr, - int mask,int val, - char *buf,unsigned int maxlen, - unsigned int *len) -{ - int ret = -EINVAL; - - *len = 0; - if (cptr->info->type == pvr2_ctl_int) { - *len = scnprintf(buf,maxlen,"%d",val); - ret = 0; - } else if (cptr->info->type == pvr2_ctl_bool) { - *len = scnprintf(buf,maxlen,"%s",val ? "true" : "false"); - ret = 0; - } else if (cptr->info->type == pvr2_ctl_enum) { - const char * const *names; - names = cptr->info->def.type_enum.value_names; - if ((val >= 0) && - (val < cptr->info->def.type_enum.count)) { - if (names[val]) { - *len = scnprintf( - buf,maxlen,"%s", - names[val]); - } else { - *len = 0; - } - ret = 0; - } - } else if (cptr->info->type == pvr2_ctl_bitmask) { - *len = gen_bitmask_string( - val & mask & cptr->info->def.type_bitmask.valid_bits, - ~0,!0, - cptr->info->def.type_bitmask.bit_names, - buf,maxlen); - } - return ret; -} - - -/* Convert a given mask/val to a symbolic value */ -int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *cptr, - int mask,int val, - char *buf,unsigned int maxlen, - unsigned int *len) -{ - int ret; - LOCK_TAKE(cptr->hdw->big_lock); do { - ret = pvr2_ctrl_value_to_sym_internal(cptr,mask,val, - buf,maxlen,len); - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.h b/drivers/media/video/pvrusb2/pvrusb2-ctrl.h deleted file mode 100644 index 794ff90121c7..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ -#ifndef __PVRUSB2_CTRL_H -#define __PVRUSB2_CTRL_H - -struct pvr2_ctrl; - -enum pvr2_ctl_type { - pvr2_ctl_int = 0, - pvr2_ctl_enum = 1, - pvr2_ctl_bitmask = 2, - pvr2_ctl_bool = 3, -}; - - -/* Set the given control. */ -int pvr2_ctrl_set_value(struct pvr2_ctrl *,int val); - -/* Set/clear specific bits of the given control. */ -int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *,int mask,int val); - -/* Get the current value of the given control. */ -int pvr2_ctrl_get_value(struct pvr2_ctrl *,int *valptr); - -/* Retrieve control's type */ -enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *); - -/* Retrieve control's maximum value (int type) */ -int pvr2_ctrl_get_max(struct pvr2_ctrl *); - -/* Retrieve control's minimum value (int type) */ -int pvr2_ctrl_get_min(struct pvr2_ctrl *); - -/* Retrieve control's default value (any type) */ -int pvr2_ctrl_get_def(struct pvr2_ctrl *, int *valptr); - -/* Retrieve control's enumeration count (enum only) */ -int pvr2_ctrl_get_cnt(struct pvr2_ctrl *); - -/* Retrieve control's valid mask bits (bit mask only) */ -int pvr2_ctrl_get_mask(struct pvr2_ctrl *); - -/* Retrieve the control's name */ -const char *pvr2_ctrl_get_name(struct pvr2_ctrl *); - -/* Retrieve the control's desc */ -const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *); - -/* Retrieve a control enumeration or bit mask value */ -int pvr2_ctrl_get_valname(struct pvr2_ctrl *,int,char *,unsigned int, - unsigned int *); - -/* Return true if control is writable */ -int pvr2_ctrl_is_writable(struct pvr2_ctrl *); - -/* Return V4L flags value for control (or zero if there is no v4l control - actually under this control) */ -unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *); - -/* Return V4L ID for this control or zero if none */ -int pvr2_ctrl_get_v4lid(struct pvr2_ctrl *); - -/* Return true if control has custom symbolic representation */ -int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *); - -/* Convert a given mask/val to a custom symbolic value */ -int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *, - int mask,int val, - char *buf,unsigned int maxlen, - unsigned int *len); - -/* Convert a symbolic value to a mask/value pair */ -int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *, - const char *buf,unsigned int len, - int *maskptr,int *valptr); - -/* Convert a given mask/val to a symbolic value */ -int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *, - int mask,int val, - char *buf,unsigned int maxlen, - unsigned int *len); - -/* Convert a symbolic value to a mask/value pair */ -int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *, - const char *buf,unsigned int len, - int *maskptr,int *valptr); - -/* Convert a given mask/val to a symbolic value - must already be - inside of critical region. */ -int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *, - int mask,int val, - char *buf,unsigned int maxlen, - unsigned int *len); - -#endif /* __PVRUSB2_CTRL_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c deleted file mode 100644 index c514d0b9ffdc..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 source file is specifically designed to interface with the - cx2584x, in kernels 2.6.16 or newer. - -*/ - -#include "pvrusb2-cx2584x-v4l.h" -#include "pvrusb2-video-v4l.h" - - -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include <media/cx25840.h> -#include <linux/videodev2.h> -#include <media/v4l2-common.h> -#include <linux/errno.h> - - -struct routing_scheme_item { - int vid; - int aud; -}; - -struct routing_scheme { - const struct routing_scheme_item *def; - unsigned int cnt; -}; - -static const struct routing_scheme_item routing_scheme0[] = { - [PVR2_CVAL_INPUT_TV] = { - .vid = CX25840_COMPOSITE7, - .aud = CX25840_AUDIO8, - }, - [PVR2_CVAL_INPUT_RADIO] = { /* Treat the same as composite */ - .vid = CX25840_COMPOSITE3, - .aud = CX25840_AUDIO_SERIAL, - }, - [PVR2_CVAL_INPUT_COMPOSITE] = { - .vid = CX25840_COMPOSITE3, - .aud = CX25840_AUDIO_SERIAL, - }, - [PVR2_CVAL_INPUT_SVIDEO] = { - .vid = CX25840_SVIDEO1, - .aud = CX25840_AUDIO_SERIAL, - }, -}; - -static const struct routing_scheme routing_def0 = { - .def = routing_scheme0, - .cnt = ARRAY_SIZE(routing_scheme0), -}; - -/* Specific to gotview device */ -static const struct routing_scheme_item routing_schemegv[] = { - [PVR2_CVAL_INPUT_TV] = { - .vid = CX25840_COMPOSITE2, - .aud = CX25840_AUDIO5, - }, - [PVR2_CVAL_INPUT_RADIO] = { - /* line-in is used for radio and composite. A GPIO is - used to switch between the two choices. */ - .vid = CX25840_COMPOSITE1, - .aud = CX25840_AUDIO_SERIAL, - }, - [PVR2_CVAL_INPUT_COMPOSITE] = { - .vid = CX25840_COMPOSITE1, - .aud = CX25840_AUDIO_SERIAL, - }, - [PVR2_CVAL_INPUT_SVIDEO] = { - .vid = (CX25840_SVIDEO_LUMA3|CX25840_SVIDEO_CHROMA4), - .aud = CX25840_AUDIO_SERIAL, - }, -}; - -static const struct routing_scheme routing_defgv = { - .def = routing_schemegv, - .cnt = ARRAY_SIZE(routing_schemegv), -}; - -/* Specific to grabster av400 device */ -static const struct routing_scheme_item routing_schemeav400[] = { - [PVR2_CVAL_INPUT_COMPOSITE] = { - .vid = CX25840_COMPOSITE1, - .aud = CX25840_AUDIO_SERIAL, - }, - [PVR2_CVAL_INPUT_SVIDEO] = { - .vid = (CX25840_SVIDEO_LUMA2|CX25840_SVIDEO_CHROMA4), - .aud = CX25840_AUDIO_SERIAL, - }, -}; - -static const struct routing_scheme routing_defav400 = { - .def = routing_schemeav400, - .cnt = ARRAY_SIZE(routing_schemeav400), -}; - -static const struct routing_scheme *routing_schemes[] = { - [PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0, - [PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv, - [PVR2_ROUTING_SCHEME_AV400] = &routing_defav400, -}; - -void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) -{ - pvr2_trace(PVR2_TRACE_CHIPS, "subdev cx2584x update..."); - if (hdw->input_dirty || hdw->force_dirty) { - enum cx25840_video_input vid_input; - enum cx25840_audio_input aud_input; - const struct routing_scheme *sp; - unsigned int sid = hdw->hdw_desc->signal_routing_scheme; - - sp = (sid < ARRAY_SIZE(routing_schemes)) ? - routing_schemes[sid] : NULL; - if ((sp == NULL) || - (hdw->input_val < 0) || - (hdw->input_val >= sp->cnt)) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "*** WARNING *** subdev cx2584x set_input:" - " Invalid routing scheme (%u)" - " and/or input (%d)", - sid, hdw->input_val); - return; - } - vid_input = sp->def[hdw->input_val].vid; - aud_input = sp->def[hdw->input_val].aud; - pvr2_trace(PVR2_TRACE_CHIPS, - "subdev cx2584x set_input vid=0x%x aud=0x%x", - vid_input, aud_input); - sd->ops->video->s_routing(sd, (u32)vid_input, 0, 0); - sd->ops->audio->s_routing(sd, (u32)aud_input, 0, 0); - } -} - - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h deleted file mode 100644 index e35c2322a08c..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ - -#ifndef __PVRUSB2_CX2584X_V4L_H -#define __PVRUSB2_CX2584X_V4L_H - -/* - - This module connects the pvrusb2 driver to the I2C chip level - driver which handles combined device audio & video processing. - This interface is used internally by the driver; higher level code - should only interact through the interface provided by - pvrusb2-hdw.h. - -*/ - - - -#include "pvrusb2-hdw-internal.h" - -void pvr2_cx25840_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd); - - -#endif /* __PVRUSB2_CX2584X_V4L_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-debug.h b/drivers/media/video/pvrusb2/pvrusb2-debug.h deleted file mode 100644 index be79249f8628..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-debug.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ -#ifndef __PVRUSB2_DEBUG_H -#define __PVRUSB2_DEBUG_H - -extern int pvrusb2_debug; - -#define pvr2_trace(msk, fmt, arg...) do {if(msk & pvrusb2_debug) printk(KERN_INFO "pvrusb2: " fmt "\n", ##arg); } while (0) - -/* These are listed in *rough* order of decreasing usefulness and - increasing noise level. */ -#define PVR2_TRACE_INFO (1 << 0) /* Normal messages */ -#define PVR2_TRACE_ERROR_LEGS (1 << 1) /* error messages */ -#define PVR2_TRACE_TOLERANCE (1 << 2) /* track tolerance-affected errors */ -#define PVR2_TRACE_TRAP (1 << 3) /* Trap & report app misbehavior */ -#define PVR2_TRACE_STD (1 << 4) /* Log video standard stuff */ -#define PVR2_TRACE_INIT (1 << 5) /* misc initialization steps */ -#define PVR2_TRACE_START_STOP (1 << 6) /* Streaming start / stop */ -#define PVR2_TRACE_CTL (1 << 7) /* commit of control changes */ -#define PVR2_TRACE_STATE (1 << 8) /* Device state changes */ -#define PVR2_TRACE_STBITS (1 << 9) /* Individual bit state changes */ -#define PVR2_TRACE_EEPROM (1 << 10) /* eeprom parsing / report */ -#define PVR2_TRACE_STRUCT (1 << 11) /* internal struct creation */ -#define PVR2_TRACE_OPEN_CLOSE (1 << 12) /* application open / close */ -#define PVR2_TRACE_CTXT (1 << 13) /* Main context tracking */ -#define PVR2_TRACE_SYSFS (1 << 14) /* Sysfs driven I/O */ -#define PVR2_TRACE_FIRMWARE (1 << 15) /* firmware upload actions */ -#define PVR2_TRACE_CHIPS (1 << 16) /* chip broadcast operation */ -#define PVR2_TRACE_I2C (1 << 17) /* I2C related stuff */ -#define PVR2_TRACE_I2C_CMD (1 << 18) /* Software commands to I2C modules */ -#define PVR2_TRACE_I2C_CORE (1 << 19) /* I2C core debugging */ -#define PVR2_TRACE_I2C_TRAF (1 << 20) /* I2C traffic through the adapter */ -#define PVR2_TRACE_V4LIOCTL (1 << 21) /* v4l ioctl details */ -#define PVR2_TRACE_ENCODER (1 << 22) /* mpeg2 encoder operation */ -#define PVR2_TRACE_BUF_POOL (1 << 23) /* Track buffer pool management */ -#define PVR2_TRACE_BUF_FLOW (1 << 24) /* Track buffer flow in system */ -#define PVR2_TRACE_DATA_FLOW (1 << 25) /* Track data flow */ -#define PVR2_TRACE_DEBUGIFC (1 << 26) /* Debug interface actions */ -#define PVR2_TRACE_GPIO (1 << 27) /* GPIO state bit changes */ -#define PVR2_TRACE_DVB_FEED (1 << 28) /* DVB transport feed debug */ - - -#endif /* __PVRUSB2_HDW_INTERNAL_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c deleted file mode 100644 index 4279ebb811a1..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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/string.h> -#include "pvrusb2-debugifc.h" -#include "pvrusb2-hdw.h" -#include "pvrusb2-debug.h" - -struct debugifc_mask_item { - const char *name; - unsigned long msk; -}; - - -static unsigned int debugifc_count_whitespace(const char *buf, - unsigned int count) -{ - unsigned int scnt; - char ch; - - for (scnt = 0; scnt < count; scnt++) { - ch = buf[scnt]; - if (ch == ' ') continue; - if (ch == '\t') continue; - if (ch == '\n') continue; - break; - } - return scnt; -} - - -static unsigned int debugifc_count_nonwhitespace(const char *buf, - unsigned int count) -{ - unsigned int scnt; - char ch; - - for (scnt = 0; scnt < count; scnt++) { - ch = buf[scnt]; - if (ch == ' ') break; - if (ch == '\t') break; - if (ch == '\n') break; - } - return scnt; -} - - -static unsigned int debugifc_isolate_word(const char *buf,unsigned int count, - const char **wstrPtr, - unsigned int *wlenPtr) -{ - const char *wptr; - unsigned int consume_cnt = 0; - unsigned int wlen; - unsigned int scnt; - - wptr = NULL; - wlen = 0; - scnt = debugifc_count_whitespace(buf,count); - consume_cnt += scnt; count -= scnt; buf += scnt; - if (!count) goto done; - - scnt = debugifc_count_nonwhitespace(buf,count); - if (!scnt) goto done; - wptr = buf; - wlen = scnt; - consume_cnt += scnt; count -= scnt; buf += scnt; - - done: - *wstrPtr = wptr; - *wlenPtr = wlen; - return consume_cnt; -} - - -static int debugifc_parse_unsigned_number(const char *buf,unsigned int count, - u32 *num_ptr) -{ - u32 result = 0; - int radix = 10; - if ((count >= 2) && (buf[0] == '0') && - ((buf[1] == 'x') || (buf[1] == 'X'))) { - radix = 16; - count -= 2; - buf += 2; - } else if ((count >= 1) && (buf[0] == '0')) { - radix = 8; - } - - while (count--) { - int val = hex_to_bin(*buf++); - if (val < 0 || val >= radix) - return -EINVAL; - result *= radix; - result += val; - } - *num_ptr = result; - return 0; -} - - -static int debugifc_match_keyword(const char *buf,unsigned int count, - const char *keyword) -{ - unsigned int kl; - if (!keyword) return 0; - kl = strlen(keyword); - if (kl != count) return 0; - return !memcmp(buf,keyword,kl); -} - - -int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt) -{ - int bcnt = 0; - int ccnt; - ccnt = scnprintf(buf, acnt, "Driver hardware description: %s\n", - pvr2_hdw_get_desc(hdw)); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = scnprintf(buf,acnt,"Driver state info:\n"); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = pvr2_hdw_state_report(hdw,buf,acnt); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - - return bcnt; -} - - -int pvr2_debugifc_print_status(struct pvr2_hdw *hdw, - char *buf,unsigned int acnt) -{ - int bcnt = 0; - int ccnt; - int ret; - u32 gpio_dir,gpio_in,gpio_out; - struct pvr2_stream_stats stats; - struct pvr2_stream *sp; - - ret = pvr2_hdw_is_hsm(hdw); - ccnt = scnprintf(buf,acnt,"USB link speed: %s\n", - (ret < 0 ? "FAIL" : (ret ? "high" : "full"))); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - - gpio_dir = 0; gpio_in = 0; gpio_out = 0; - pvr2_hdw_gpio_get_dir(hdw,&gpio_dir); - pvr2_hdw_gpio_get_out(hdw,&gpio_out); - pvr2_hdw_gpio_get_in(hdw,&gpio_in); - ccnt = scnprintf(buf,acnt,"GPIO state: dir=0x%x in=0x%x out=0x%x\n", - gpio_dir,gpio_in,gpio_out); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - - ccnt = scnprintf(buf,acnt,"Streaming is %s\n", - pvr2_hdw_get_streaming(hdw) ? "on" : "off"); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - - - sp = pvr2_hdw_get_video_stream(hdw); - if (sp) { - pvr2_stream_get_stats(sp, &stats, 0); - ccnt = scnprintf( - buf,acnt, - "Bytes streamed=%u" - " URBs: queued=%u idle=%u ready=%u" - " processed=%u failed=%u\n", - stats.bytes_processed, - stats.buffers_in_queue, - stats.buffers_in_idle, - stats.buffers_in_ready, - stats.buffers_processed, - stats.buffers_failed); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - } - - return bcnt; -} - - -static int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf, - unsigned int count) -{ - const char *wptr; - unsigned int wlen; - unsigned int scnt; - - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (!scnt) return 0; - count -= scnt; buf += scnt; - if (!wptr) return 0; - - pvr2_trace(PVR2_TRACE_DEBUGIFC,"debugifc cmd: \"%.*s\"",wlen,wptr); - if (debugifc_match_keyword(wptr,wlen,"reset")) { - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (!scnt) return -EINVAL; - count -= scnt; buf += scnt; - if (!wptr) return -EINVAL; - if (debugifc_match_keyword(wptr,wlen,"cpu")) { - pvr2_hdw_cpureset_assert(hdw,!0); - pvr2_hdw_cpureset_assert(hdw,0); - return 0; - } else if (debugifc_match_keyword(wptr,wlen,"bus")) { - pvr2_hdw_device_reset(hdw); - } else if (debugifc_match_keyword(wptr,wlen,"soft")) { - return pvr2_hdw_cmd_powerup(hdw); - } else if (debugifc_match_keyword(wptr,wlen,"deep")) { - return pvr2_hdw_cmd_deep_reset(hdw); - } else if (debugifc_match_keyword(wptr,wlen,"firmware")) { - return pvr2_upload_firmware2(hdw); - } else if (debugifc_match_keyword(wptr,wlen,"decoder")) { - return pvr2_hdw_cmd_decoder_reset(hdw); - } else if (debugifc_match_keyword(wptr,wlen,"worker")) { - return pvr2_hdw_untrip(hdw); - } else if (debugifc_match_keyword(wptr,wlen,"usbstats")) { - pvr2_stream_get_stats(pvr2_hdw_get_video_stream(hdw), - NULL, !0); - return 0; - } - return -EINVAL; - } else if (debugifc_match_keyword(wptr,wlen,"cpufw")) { - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (!scnt) return -EINVAL; - count -= scnt; buf += scnt; - if (!wptr) return -EINVAL; - if (debugifc_match_keyword(wptr,wlen,"fetch")) { - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (scnt && wptr) { - count -= scnt; buf += scnt; - if (debugifc_match_keyword(wptr, wlen, - "prom")) { - pvr2_hdw_cpufw_set_enabled(hdw, 2, !0); - } else if (debugifc_match_keyword(wptr, wlen, - "ram8k")) { - pvr2_hdw_cpufw_set_enabled(hdw, 0, !0); - } else if (debugifc_match_keyword(wptr, wlen, - "ram16k")) { - pvr2_hdw_cpufw_set_enabled(hdw, 1, !0); - } else { - return -EINVAL; - } - } - pvr2_hdw_cpufw_set_enabled(hdw,0,!0); - return 0; - } else if (debugifc_match_keyword(wptr,wlen,"done")) { - pvr2_hdw_cpufw_set_enabled(hdw,0,0); - return 0; - } else { - return -EINVAL; - } - } else if (debugifc_match_keyword(wptr,wlen,"gpio")) { - int dir_fl = 0; - int ret; - u32 msk,val; - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (!scnt) return -EINVAL; - count -= scnt; buf += scnt; - if (!wptr) return -EINVAL; - if (debugifc_match_keyword(wptr,wlen,"dir")) { - dir_fl = !0; - } else if (!debugifc_match_keyword(wptr,wlen,"out")) { - return -EINVAL; - } - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (!scnt) return -EINVAL; - count -= scnt; buf += scnt; - if (!wptr) return -EINVAL; - ret = debugifc_parse_unsigned_number(wptr,wlen,&msk); - if (ret) return ret; - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (wptr) { - ret = debugifc_parse_unsigned_number(wptr,wlen,&val); - if (ret) return ret; - } else { - val = msk; - msk = 0xffffffff; - } - if (dir_fl) { - ret = pvr2_hdw_gpio_chg_dir(hdw,msk,val); - } else { - ret = pvr2_hdw_gpio_chg_out(hdw,msk,val); - } - return ret; - } - pvr2_trace(PVR2_TRACE_DEBUGIFC, - "debugifc failed to recognize cmd: \"%.*s\"",wlen,wptr); - return -EINVAL; -} - - -int pvr2_debugifc_docmd(struct pvr2_hdw *hdw,const char *buf, - unsigned int count) -{ - unsigned int bcnt = 0; - int ret; - - while (count) { - for (bcnt = 0; bcnt < count; bcnt++) { - if (buf[bcnt] == '\n') break; - } - - ret = pvr2_debugifc_do1cmd(hdw,buf,bcnt); - if (ret < 0) return ret; - if (bcnt < count) bcnt++; - buf += bcnt; - count -= bcnt; - } - - return 0; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.h b/drivers/media/video/pvrusb2/pvrusb2-debugifc.h deleted file mode 100644 index 2f8d46761cd0..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ -#ifndef __PVRUSB2_DEBUGIFC_H -#define __PVRUSB2_DEBUGIFC_H - -struct pvr2_hdw; - -/* Print general status of driver. This will also trigger a probe of - the USB link. Unlike print_info(), this one synchronizes with the - driver so the information should be self-consistent (but it will - hang if the driver is wedged). */ -int pvr2_debugifc_print_info(struct pvr2_hdw *, - char *buf_ptr, unsigned int buf_size); - -/* Non-intrusively print some useful debugging info from inside the - driver. This should work even if the driver appears to be - wedged. */ -int pvr2_debugifc_print_status(struct pvr2_hdw *, - char *buf_ptr,unsigned int buf_size); - -/* Parse a string command into a driver action. */ -int pvr2_debugifc_docmd(struct pvr2_hdw *, - const char *buf_ptr,unsigned int buf_size); - -#endif /* __PVRUSB2_DEBUGIFC_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c deleted file mode 100644 index adc501d3c287..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c +++ /dev/null @@ -1,576 +0,0 @@ -/* - * - * - * Copyright (C) 2007 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 source file should encompass ALL per-device type information for the -driver. To define a new device, add elements to the pvr2_device_table and -pvr2_device_desc structures. - -*/ - -#include "pvrusb2-devattr.h" -#include <linux/usb.h> -#include <linux/module.h> -/* This is needed in order to pull in tuner type ids... */ -#include <linux/i2c.h> -#include <media/tuner.h> -#ifdef CONFIG_VIDEO_PVRUSB2_DVB -#include "pvrusb2-hdw-internal.h" -#include "lgdt330x.h" -#include "s5h1409.h" -#include "s5h1411.h" -#include "tda10048.h" -#include "tda18271.h" -#include "tda8290.h" -#include "tuner-simple.h" -#endif - - -/*------------------------------------------------------------------------*/ -/* Hauppauge PVR-USB2 Model 29xxx */ - -static const struct pvr2_device_client_desc pvr2_cli_29xxx[] = { - { .module_id = PVR2_CLIENT_ID_SAA7115 }, - { .module_id = PVR2_CLIENT_ID_MSP3400 }, - { .module_id = PVR2_CLIENT_ID_TUNER }, - { .module_id = PVR2_CLIENT_ID_DEMOD }, -}; - -#define PVR2_FIRMWARE_29xxx "v4l-pvrusb2-29xxx-01.fw" -static const char *pvr2_fw1_names_29xxx[] = { - PVR2_FIRMWARE_29xxx, -}; - -static const struct pvr2_device_desc pvr2_device_29xxx = { - .description = "WinTV PVR USB2 Model 29xxx", - .shortname = "29xxx", - .client_table.lst = pvr2_cli_29xxx, - .client_table.cnt = ARRAY_SIZE(pvr2_cli_29xxx), - .fx2_firmware.lst = pvr2_fw1_names_29xxx, - .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_29xxx), - .flag_has_hauppauge_rom = !0, - .flag_has_analogtuner = !0, - .flag_has_fmradio = !0, - .flag_has_composite = !0, - .flag_has_svideo = !0, - .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, - .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, - .ir_scheme = PVR2_IR_SCHEME_29XXX, -}; - - - -/*------------------------------------------------------------------------*/ -/* Hauppauge PVR-USB2 Model 24xxx */ - -static const struct pvr2_device_client_desc pvr2_cli_24xxx[] = { - { .module_id = PVR2_CLIENT_ID_CX25840 }, - { .module_id = PVR2_CLIENT_ID_TUNER }, - { .module_id = PVR2_CLIENT_ID_WM8775 }, - { .module_id = PVR2_CLIENT_ID_DEMOD }, -}; - -#define PVR2_FIRMWARE_24xxx "v4l-pvrusb2-24xxx-01.fw" -static const char *pvr2_fw1_names_24xxx[] = { - PVR2_FIRMWARE_24xxx, -}; - -static const struct pvr2_device_desc pvr2_device_24xxx = { - .description = "WinTV PVR USB2 Model 24xxx", - .shortname = "24xxx", - .client_table.lst = pvr2_cli_24xxx, - .client_table.cnt = ARRAY_SIZE(pvr2_cli_24xxx), - .fx2_firmware.lst = pvr2_fw1_names_24xxx, - .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_24xxx), - .flag_has_cx25840 = !0, - .flag_has_wm8775 = !0, - .flag_has_hauppauge_rom = !0, - .flag_has_analogtuner = !0, - .flag_has_fmradio = !0, - .flag_has_composite = !0, - .flag_has_svideo = !0, - .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, - .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, - .ir_scheme = PVR2_IR_SCHEME_24XXX, -}; - - - -/*------------------------------------------------------------------------*/ -/* GOTVIEW USB2.0 DVD2 */ - -static const struct pvr2_device_client_desc pvr2_cli_gotview_2[] = { - { .module_id = PVR2_CLIENT_ID_CX25840 }, - { .module_id = PVR2_CLIENT_ID_TUNER }, - { .module_id = PVR2_CLIENT_ID_DEMOD }, -}; - -static const struct pvr2_device_desc pvr2_device_gotview_2 = { - .description = "Gotview USB 2.0 DVD 2", - .shortname = "gv2", - .client_table.lst = pvr2_cli_gotview_2, - .client_table.cnt = ARRAY_SIZE(pvr2_cli_gotview_2), - .flag_has_cx25840 = !0, - .default_tuner_type = TUNER_PHILIPS_FM1216ME_MK3, - .flag_has_analogtuner = !0, - .flag_has_fmradio = !0, - .flag_has_composite = !0, - .flag_has_svideo = !0, - .signal_routing_scheme = PVR2_ROUTING_SCHEME_GOTVIEW, -}; - - - -/*------------------------------------------------------------------------*/ -/* GOTVIEW USB2.0 DVD Deluxe */ - -/* (same module list as gotview_2) */ - -static const struct pvr2_device_desc pvr2_device_gotview_2d = { - .description = "Gotview USB 2.0 DVD Deluxe", - .shortname = "gv2d", - .client_table.lst = pvr2_cli_gotview_2, - .client_table.cnt = ARRAY_SIZE(pvr2_cli_gotview_2), - .flag_has_cx25840 = !0, - .default_tuner_type = TUNER_PHILIPS_FM1216ME_MK3, - .flag_has_analogtuner = !0, - .flag_has_composite = !0, - .flag_has_svideo = !0, - .signal_routing_scheme = PVR2_ROUTING_SCHEME_GOTVIEW, -}; - - - -/*------------------------------------------------------------------------*/ -/* Terratec Grabster AV400 */ - -static const struct pvr2_device_client_desc pvr2_cli_av400[] = { - { .module_id = PVR2_CLIENT_ID_CX25840 }, -}; - -static const struct pvr2_device_desc pvr2_device_av400 = { - .description = "Terratec Grabster AV400", - .shortname = "av400", - .flag_is_experimental = 1, - .client_table.lst = pvr2_cli_av400, - .client_table.cnt = ARRAY_SIZE(pvr2_cli_av400), - .flag_has_cx25840 = !0, - .flag_has_analogtuner = 0, - .flag_has_composite = !0, - .flag_has_svideo = !0, - .signal_routing_scheme = PVR2_ROUTING_SCHEME_AV400, -}; - - - -/*------------------------------------------------------------------------*/ -/* OnAir Creator */ - -#ifdef CONFIG_VIDEO_PVRUSB2_DVB -static struct lgdt330x_config pvr2_lgdt3303_config = { - .demod_address = 0x0e, - .demod_chip = LGDT3303, - .clock_polarity_flip = 1, -}; - -static int pvr2_lgdt3303_attach(struct pvr2_dvb_adapter *adap) -{ - adap->fe = dvb_attach(lgdt330x_attach, &pvr2_lgdt3303_config, - &adap->channel.hdw->i2c_adap); - if (adap->fe) - return 0; - - return -EIO; -} - -static int pvr2_lgh06xf_attach(struct pvr2_dvb_adapter *adap) -{ - dvb_attach(simple_tuner_attach, adap->fe, - &adap->channel.hdw->i2c_adap, 0x61, - TUNER_LG_TDVS_H06XF); - - return 0; -} - -static const struct pvr2_dvb_props pvr2_onair_creator_fe_props = { - .frontend_attach = pvr2_lgdt3303_attach, - .tuner_attach = pvr2_lgh06xf_attach, -}; -#endif - -static const struct pvr2_device_client_desc pvr2_cli_onair_creator[] = { - { .module_id = PVR2_CLIENT_ID_SAA7115 }, - { .module_id = PVR2_CLIENT_ID_CS53L32A }, - { .module_id = PVR2_CLIENT_ID_TUNER }, -}; - -static const struct pvr2_device_desc pvr2_device_onair_creator = { - .description = "OnAir Creator Hybrid USB tuner", - .shortname = "oac", - .client_table.lst = pvr2_cli_onair_creator, - .client_table.cnt = ARRAY_SIZE(pvr2_cli_onair_creator), - .default_tuner_type = TUNER_LG_TDVS_H06XF, - .flag_has_analogtuner = !0, - .flag_has_composite = !0, - .flag_has_svideo = !0, - .flag_digital_requires_cx23416 = !0, - .signal_routing_scheme = PVR2_ROUTING_SCHEME_ONAIR, - .digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR, - .default_std_mask = V4L2_STD_NTSC_M, -#ifdef CONFIG_VIDEO_PVRUSB2_DVB - .dvb_props = &pvr2_onair_creator_fe_props, -#endif -}; - - - -/*------------------------------------------------------------------------*/ -/* OnAir USB 2.0 */ - -#ifdef CONFIG_VIDEO_PVRUSB2_DVB -static struct lgdt330x_config pvr2_lgdt3302_config = { - .demod_address = 0x0e, - .demod_chip = LGDT3302, -}; - -static int pvr2_lgdt3302_attach(struct pvr2_dvb_adapter *adap) -{ - adap->fe = dvb_attach(lgdt330x_attach, &pvr2_lgdt3302_config, - &adap->channel.hdw->i2c_adap); - if (adap->fe) - return 0; - - return -EIO; -} - -static int pvr2_fcv1236d_attach(struct pvr2_dvb_adapter *adap) -{ - dvb_attach(simple_tuner_attach, adap->fe, - &adap->channel.hdw->i2c_adap, 0x61, - TUNER_PHILIPS_FCV1236D); - - return 0; -} - -static const struct pvr2_dvb_props pvr2_onair_usb2_fe_props = { - .frontend_attach = pvr2_lgdt3302_attach, - .tuner_attach = pvr2_fcv1236d_attach, -}; -#endif - -static const struct pvr2_device_client_desc pvr2_cli_onair_usb2[] = { - { .module_id = PVR2_CLIENT_ID_SAA7115 }, - { .module_id = PVR2_CLIENT_ID_CS53L32A }, - { .module_id = PVR2_CLIENT_ID_TUNER }, -}; - -static const struct pvr2_device_desc pvr2_device_onair_usb2 = { - .description = "OnAir USB2 Hybrid USB tuner", - .shortname = "oa2", - .client_table.lst = pvr2_cli_onair_usb2, - .client_table.cnt = ARRAY_SIZE(pvr2_cli_onair_usb2), - .default_tuner_type = TUNER_PHILIPS_FCV1236D, - .flag_has_analogtuner = !0, - .flag_has_composite = !0, - .flag_has_svideo = !0, - .flag_digital_requires_cx23416 = !0, - .signal_routing_scheme = PVR2_ROUTING_SCHEME_ONAIR, - .digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR, - .default_std_mask = V4L2_STD_NTSC_M, -#ifdef CONFIG_VIDEO_PVRUSB2_DVB - .dvb_props = &pvr2_onair_usb2_fe_props, -#endif -}; - - - -/*------------------------------------------------------------------------*/ -/* Hauppauge PVR-USB2 Model 73xxx */ - -#ifdef CONFIG_VIDEO_PVRUSB2_DVB -static struct tda10048_config hauppauge_tda10048_config = { - .demod_address = 0x10 >> 1, - .output_mode = TDA10048_PARALLEL_OUTPUT, - .fwbulkwritelen = TDA10048_BULKWRITE_50, - .inversion = TDA10048_INVERSION_ON, - .dtv6_if_freq_khz = TDA10048_IF_3300, - .dtv7_if_freq_khz = TDA10048_IF_3800, - .dtv8_if_freq_khz = TDA10048_IF_4300, - .clk_freq_khz = TDA10048_CLK_16000, - .disable_gate_access = 1, -}; - -static struct tda829x_config tda829x_no_probe = { - .probe_tuner = TDA829X_DONT_PROBE, -}; - -static struct tda18271_std_map hauppauge_tda18271_dvbt_std_map = { - .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4, - .if_lvl = 1, .rfagc_top = 0x37, }, - .dvbt_7 = { .if_freq = 3800, .agc_mode = 3, .std = 5, - .if_lvl = 1, .rfagc_top = 0x37, }, - .dvbt_8 = { .if_freq = 4300, .agc_mode = 3, .std = 6, - .if_lvl = 1, .rfagc_top = 0x37, }, -}; - -static struct tda18271_config hauppauge_tda18271_dvb_config = { - .std_map = &hauppauge_tda18271_dvbt_std_map, - .gate = TDA18271_GATE_ANALOG, - .output_opt = TDA18271_OUTPUT_LT_OFF, -}; - -static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap) -{ - adap->fe = dvb_attach(tda10048_attach, &hauppauge_tda10048_config, - &adap->channel.hdw->i2c_adap); - if (adap->fe) - return 0; - - return -EIO; -} - -static int pvr2_73xxx_tda18271_8295_attach(struct pvr2_dvb_adapter *adap) -{ - dvb_attach(tda829x_attach, adap->fe, - &adap->channel.hdw->i2c_adap, 0x42, - &tda829x_no_probe); - dvb_attach(tda18271_attach, adap->fe, 0x60, - &adap->channel.hdw->i2c_adap, - &hauppauge_tda18271_dvb_config); - - return 0; -} - -static const struct pvr2_dvb_props pvr2_73xxx_dvb_props = { - .frontend_attach = pvr2_tda10048_attach, - .tuner_attach = pvr2_73xxx_tda18271_8295_attach, -}; -#endif - -static const struct pvr2_device_client_desc pvr2_cli_73xxx[] = { - { .module_id = PVR2_CLIENT_ID_CX25840 }, - { .module_id = PVR2_CLIENT_ID_TUNER, - .i2c_address_list = "\x42"}, -}; - -#define PVR2_FIRMWARE_73xxx "v4l-pvrusb2-73xxx-01.fw" -static const char *pvr2_fw1_names_73xxx[] = { - PVR2_FIRMWARE_73xxx, -}; - -static const struct pvr2_device_desc pvr2_device_73xxx = { - .description = "WinTV HVR-1900 Model 73xxx", - .shortname = "73xxx", - .client_table.lst = pvr2_cli_73xxx, - .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx), - .fx2_firmware.lst = pvr2_fw1_names_73xxx, - .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_73xxx), - .flag_has_cx25840 = !0, - .flag_has_hauppauge_rom = !0, - .flag_has_analogtuner = !0, - .flag_has_composite = !0, - .flag_has_svideo = !0, - .flag_fx2_16kb = !0, - .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, - .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, - .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, - .ir_scheme = PVR2_IR_SCHEME_ZILOG, -#ifdef CONFIG_VIDEO_PVRUSB2_DVB - .dvb_props = &pvr2_73xxx_dvb_props, -#endif -}; - - - -/*------------------------------------------------------------------------*/ -/* Hauppauge PVR-USB2 Model 75xxx */ - -#ifdef CONFIG_VIDEO_PVRUSB2_DVB -static struct s5h1409_config pvr2_s5h1409_config = { - .demod_address = 0x32 >> 1, - .output_mode = S5H1409_PARALLEL_OUTPUT, - .gpio = S5H1409_GPIO_OFF, - .qam_if = 4000, - .inversion = S5H1409_INVERSION_ON, - .status_mode = S5H1409_DEMODLOCKING, -}; - -static struct s5h1411_config pvr2_s5h1411_config = { - .output_mode = S5H1411_PARALLEL_OUTPUT, - .gpio = S5H1411_GPIO_OFF, - .vsb_if = S5H1411_IF_44000, - .qam_if = S5H1411_IF_4000, - .inversion = S5H1411_INVERSION_ON, - .status_mode = S5H1411_DEMODLOCKING, -}; - -static struct tda18271_std_map hauppauge_tda18271_std_map = { - .atsc_6 = { .if_freq = 5380, .agc_mode = 3, .std = 3, - .if_lvl = 6, .rfagc_top = 0x37, }, - .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0, - .if_lvl = 6, .rfagc_top = 0x37, }, -}; - -static struct tda18271_config hauppauge_tda18271_config = { - .std_map = &hauppauge_tda18271_std_map, - .gate = TDA18271_GATE_ANALOG, - .output_opt = TDA18271_OUTPUT_LT_OFF, -}; - -static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap) -{ - adap->fe = dvb_attach(s5h1409_attach, &pvr2_s5h1409_config, - &adap->channel.hdw->i2c_adap); - if (adap->fe) - return 0; - - return -EIO; -} - -static int pvr2_s5h1411_attach(struct pvr2_dvb_adapter *adap) -{ - adap->fe = dvb_attach(s5h1411_attach, &pvr2_s5h1411_config, - &adap->channel.hdw->i2c_adap); - if (adap->fe) - return 0; - - return -EIO; -} - -static int pvr2_tda18271_8295_attach(struct pvr2_dvb_adapter *adap) -{ - dvb_attach(tda829x_attach, adap->fe, - &adap->channel.hdw->i2c_adap, 0x42, - &tda829x_no_probe); - dvb_attach(tda18271_attach, adap->fe, 0x60, - &adap->channel.hdw->i2c_adap, - &hauppauge_tda18271_config); - - return 0; -} - -static const struct pvr2_dvb_props pvr2_750xx_dvb_props = { - .frontend_attach = pvr2_s5h1409_attach, - .tuner_attach = pvr2_tda18271_8295_attach, -}; - -static const struct pvr2_dvb_props pvr2_751xx_dvb_props = { - .frontend_attach = pvr2_s5h1411_attach, - .tuner_attach = pvr2_tda18271_8295_attach, -}; -#endif - -#define PVR2_FIRMWARE_75xxx "v4l-pvrusb2-73xxx-01.fw" -static const char *pvr2_fw1_names_75xxx[] = { - PVR2_FIRMWARE_75xxx, -}; - -static const struct pvr2_device_desc pvr2_device_750xx = { - .description = "WinTV HVR-1950 Model 750xx", - .shortname = "750xx", - .client_table.lst = pvr2_cli_73xxx, - .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx), - .fx2_firmware.lst = pvr2_fw1_names_75xxx, - .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_75xxx), - .flag_has_cx25840 = !0, - .flag_has_hauppauge_rom = !0, - .flag_has_analogtuner = !0, - .flag_has_composite = !0, - .flag_has_svideo = !0, - .flag_fx2_16kb = !0, - .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, - .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, - .default_std_mask = V4L2_STD_NTSC_M, - .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, - .ir_scheme = PVR2_IR_SCHEME_ZILOG, -#ifdef CONFIG_VIDEO_PVRUSB2_DVB - .dvb_props = &pvr2_750xx_dvb_props, -#endif -}; - -static const struct pvr2_device_desc pvr2_device_751xx = { - .description = "WinTV HVR-1950 Model 751xx", - .shortname = "751xx", - .client_table.lst = pvr2_cli_73xxx, - .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx), - .fx2_firmware.lst = pvr2_fw1_names_75xxx, - .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_75xxx), - .flag_has_cx25840 = !0, - .flag_has_hauppauge_rom = !0, - .flag_has_analogtuner = !0, - .flag_has_composite = !0, - .flag_has_svideo = !0, - .flag_fx2_16kb = !0, - .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, - .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, - .default_std_mask = V4L2_STD_NTSC_M, - .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, - .ir_scheme = PVR2_IR_SCHEME_ZILOG, -#ifdef CONFIG_VIDEO_PVRUSB2_DVB - .dvb_props = &pvr2_751xx_dvb_props, -#endif -}; - - - -/*------------------------------------------------------------------------*/ - -struct usb_device_id pvr2_device_table[] = { - { USB_DEVICE(0x2040, 0x2900), - .driver_info = (kernel_ulong_t)&pvr2_device_29xxx}, - { USB_DEVICE(0x2040, 0x2950), /* Logically identical to 2900 */ - .driver_info = (kernel_ulong_t)&pvr2_device_29xxx}, - { USB_DEVICE(0x2040, 0x2400), - .driver_info = (kernel_ulong_t)&pvr2_device_24xxx}, - { USB_DEVICE(0x1164, 0x0622), - .driver_info = (kernel_ulong_t)&pvr2_device_gotview_2}, - { USB_DEVICE(0x1164, 0x0602), - .driver_info = (kernel_ulong_t)&pvr2_device_gotview_2d}, - { USB_DEVICE(0x11ba, 0x1003), - .driver_info = (kernel_ulong_t)&pvr2_device_onair_creator}, - { USB_DEVICE(0x11ba, 0x1001), - .driver_info = (kernel_ulong_t)&pvr2_device_onair_usb2}, - { USB_DEVICE(0x2040, 0x7300), - .driver_info = (kernel_ulong_t)&pvr2_device_73xxx}, - { USB_DEVICE(0x2040, 0x7500), - .driver_info = (kernel_ulong_t)&pvr2_device_750xx}, - { USB_DEVICE(0x2040, 0x7501), - .driver_info = (kernel_ulong_t)&pvr2_device_751xx}, - { USB_DEVICE(0x0ccd, 0x0039), - .driver_info = (kernel_ulong_t)&pvr2_device_av400}, - { } -}; - -MODULE_DEVICE_TABLE(usb, pvr2_device_table); -MODULE_FIRMWARE(PVR2_FIRMWARE_29xxx); -MODULE_FIRMWARE(PVR2_FIRMWARE_24xxx); -MODULE_FIRMWARE(PVR2_FIRMWARE_73xxx); -MODULE_FIRMWARE(PVR2_FIRMWARE_75xxx); - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h deleted file mode 100644 index 273c8d4b3853..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ -#ifndef __PVRUSB2_DEVATTR_H -#define __PVRUSB2_DEVATTR_H - -#include <linux/mod_devicetable.h> -#include <linux/videodev2.h> -#ifdef CONFIG_VIDEO_PVRUSB2_DVB -#include "pvrusb2-dvb.h" -#endif - -/* - - This header defines structures used to describe attributes of a device. - -*/ - - -#define PVR2_CLIENT_ID_NULL 0 -#define PVR2_CLIENT_ID_MSP3400 1 -#define PVR2_CLIENT_ID_CX25840 2 -#define PVR2_CLIENT_ID_SAA7115 3 -#define PVR2_CLIENT_ID_TUNER 4 -#define PVR2_CLIENT_ID_CS53L32A 5 -#define PVR2_CLIENT_ID_WM8775 6 -#define PVR2_CLIENT_ID_DEMOD 7 - -struct pvr2_device_client_desc { - /* One ovr PVR2_CLIENT_ID_xxxx */ - unsigned char module_id; - - /* Null-terminated array of I2C addresses to try in order - initialize the module. It's safe to make this null terminated - since we're never going to encounter an i2c device with an - address of zero. If this is a null pointer or zero-length, - then no I2C addresses have been specified, in which case we'll - try some compiled in defaults for now. */ - unsigned char *i2c_address_list; -}; - -struct pvr2_device_client_table { - const struct pvr2_device_client_desc *lst; - unsigned char cnt; -}; - - -struct pvr2_string_table { - const char **lst; - unsigned int cnt; -}; - -#define PVR2_ROUTING_SCHEME_HAUPPAUGE 0 -#define PVR2_ROUTING_SCHEME_GOTVIEW 1 -#define PVR2_ROUTING_SCHEME_ONAIR 2 -#define PVR2_ROUTING_SCHEME_AV400 3 - -#define PVR2_DIGITAL_SCHEME_NONE 0 -#define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1 -#define PVR2_DIGITAL_SCHEME_ONAIR 2 - -#define PVR2_LED_SCHEME_NONE 0 -#define PVR2_LED_SCHEME_HAUPPAUGE 1 - -#define PVR2_IR_SCHEME_NONE 0 -#define PVR2_IR_SCHEME_24XXX 1 /* FX2-controlled IR */ -#define PVR2_IR_SCHEME_ZILOG 2 /* HVR-1950 style (must be taken out of reset) */ -#define PVR2_IR_SCHEME_24XXX_MCE 3 /* 24xxx MCE device */ -#define PVR2_IR_SCHEME_29XXX 4 /* Original 29xxx device */ - -/* This describes a particular hardware type (except for the USB device ID - which must live in a separate structure due to environmental - constraints). See the top of pvrusb2-hdw.c for where this is - instantiated. */ -struct pvr2_device_desc { - /* Single line text description of hardware */ - const char *description; - - /* Single token identifier for hardware */ - const char *shortname; - - /* List of additional client modules we need to load */ - struct pvr2_string_table client_modules; - - /* List of defined client modules we need to load */ - struct pvr2_device_client_table client_table; - - /* List of FX2 firmware file names we should search; if empty then - FX2 firmware check / load is skipped and we assume the device - was initialized from internal ROM. */ - struct pvr2_string_table fx2_firmware; - -#ifdef CONFIG_VIDEO_PVRUSB2_DVB - /* callback functions to handle attachment of digital tuner & demod */ - const struct pvr2_dvb_props *dvb_props; - -#endif - /* Initial standard bits to use for this device, if not zero. - Anything set here is also implied as an available standard. - Note: This is ignored if overridden on the module load line via - the video_std module option. */ - v4l2_std_id default_std_mask; - - /* V4L tuner type ID to use with this device (only used if the - driver could not discover the type any other way). */ - int default_tuner_type; - - /* Signal routing scheme used by device, contains one of - PVR2_ROUTING_SCHEME_XXX. Schemes have to be defined as we - encounter them. This is an arbitrary integer scheme id; its - meaning is contained entirely within the driver and is - interpreted by logic which must send commands to the chip-level - drivers (search for things which touch this field). */ - unsigned char signal_routing_scheme; - - /* Indicates scheme for controlling device's LED (if any). The - driver will turn on the LED when streaming is underway. This - contains one of PVR2_LED_SCHEME_XXX. */ - unsigned char led_scheme; - - /* Control scheme to use if there is a digital tuner. This - contains one of PVR2_DIGITAL_SCHEME_XXX. This is an arbitrary - integer scheme id; its meaning is contained entirely within the - driver and is interpreted by logic which must control the - streaming pathway (search for things which touch this field). */ - unsigned char digital_control_scheme; - - /* If set, we don't bother trying to load cx23416 firmware. */ - unsigned int flag_skip_cx23416_firmware:1; - - /* If set, the encoder must be healthy in order for digital mode to - work (otherwise we assume that digital streaming will work even - if we fail to locate firmware for the encoder). If the device - doesn't support digital streaming then this flag has no - effect. */ - unsigned int flag_digital_requires_cx23416:1; - - /* Device has a hauppauge eeprom which we can interrogate. */ - unsigned int flag_has_hauppauge_rom:1; - - /* Device does not require a powerup command to be issued. */ - unsigned int flag_no_powerup:1; - - /* Device has a cx25840 - this enables special additional logic to - handle it. */ - unsigned int flag_has_cx25840:1; - - /* Device has a wm8775 - this enables special additional logic to - ensure that it is found. */ - unsigned int flag_has_wm8775:1; - - /* Indicate IR scheme of hardware. If not set, then it is assumed - that IR can work without any help from the driver. */ - unsigned int ir_scheme:3; - - /* These bits define which kinds of sources the device can handle. - Note: Digital tuner presence is inferred by the - digital_control_scheme enumeration. */ - unsigned int flag_has_fmradio:1; /* Has FM radio receiver */ - unsigned int flag_has_analogtuner:1; /* Has analog tuner */ - unsigned int flag_has_composite:1; /* Has composite input */ - unsigned int flag_has_svideo:1; /* Has s-video input */ - unsigned int flag_fx2_16kb:1; /* 16KB FX2 firmware OK here */ - - /* If this driver is considered experimental, i.e. not all aspects - are working correctly and/or it is untested, mark that fact - with this flag. */ - unsigned int flag_is_experimental:1; -}; - -extern struct usb_device_id pvr2_device_table[]; - -#endif /* __PVRUSB2_HDW_INTERNAL_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.c b/drivers/media/video/pvrusb2/pvrusb2-dvb.c deleted file mode 100644 index 8c95793433e7..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-dvb.c +++ /dev/null @@ -1,435 +0,0 @@ -/* - * pvrusb2-dvb.c - linux-dvb api interface to the pvrusb2 driver. - * - * Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org> - * - * 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 - * - * 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/kthread.h> -#include <linux/freezer.h> -#include <linux/slab.h> -#include <linux/mm.h> -#include "dvbdev.h" -#include "pvrusb2-debug.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-hdw.h" -#include "pvrusb2-io.h" -#include "pvrusb2-dvb.h" - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static int pvr2_dvb_feed_func(struct pvr2_dvb_adapter *adap) -{ - int ret; - unsigned int count; - struct pvr2_buffer *bp; - struct pvr2_stream *stream; - - pvr2_trace(PVR2_TRACE_DVB_FEED, "dvb feed thread started"); - set_freezable(); - - stream = adap->channel.stream->stream; - - for (;;) { - if (kthread_should_stop()) break; - - /* Not sure about this... */ - try_to_freeze(); - - bp = pvr2_stream_get_ready_buffer(stream); - if (bp != NULL) { - count = pvr2_buffer_get_count(bp); - if (count) { - dvb_dmx_swfilter( - &adap->demux, - adap->buffer_storage[ - pvr2_buffer_get_id(bp)], - count); - } else { - ret = pvr2_buffer_get_status(bp); - if (ret < 0) break; - } - ret = pvr2_buffer_queue(bp); - if (ret < 0) break; - - /* Since we know we did something to a buffer, - just go back and try again. No point in - blocking unless we really ran out of - buffers to process. */ - continue; - } - - - /* Wait until more buffers become available or we're - told not to wait any longer. */ - ret = wait_event_interruptible( - adap->buffer_wait_data, - (pvr2_stream_get_ready_count(stream) > 0) || - kthread_should_stop()); - if (ret < 0) break; - } - - /* If we get here and ret is < 0, then an error has occurred. - Probably would be a good idea to communicate that to DVB core... */ - - pvr2_trace(PVR2_TRACE_DVB_FEED, "dvb feed thread stopped"); - - return 0; -} - -static int pvr2_dvb_feed_thread(void *data) -{ - int stat = pvr2_dvb_feed_func(data); - /* from videobuf-dvb.c: */ - while (!kthread_should_stop()) { - set_current_state(TASK_INTERRUPTIBLE); - schedule(); - } - return stat; -} - -static void pvr2_dvb_notify(struct pvr2_dvb_adapter *adap) -{ - wake_up(&adap->buffer_wait_data); -} - -static void pvr2_dvb_stream_end(struct pvr2_dvb_adapter *adap) -{ - unsigned int idx; - struct pvr2_stream *stream; - - if (adap->thread) { - kthread_stop(adap->thread); - adap->thread = NULL; - } - - if (adap->channel.stream) { - stream = adap->channel.stream->stream; - } else { - stream = NULL; - } - if (stream) { - pvr2_hdw_set_streaming(adap->channel.hdw, 0); - pvr2_stream_set_callback(stream, NULL, NULL); - pvr2_stream_kill(stream); - pvr2_stream_set_buffer_count(stream, 0); - pvr2_channel_claim_stream(&adap->channel, NULL); - } - - if (adap->stream_run) { - for (idx = 0; idx < PVR2_DVB_BUFFER_COUNT; idx++) { - if (!(adap->buffer_storage[idx])) continue; - kfree(adap->buffer_storage[idx]); - adap->buffer_storage[idx] = NULL; - } - adap->stream_run = 0; - } -} - -static int pvr2_dvb_stream_do_start(struct pvr2_dvb_adapter *adap) -{ - struct pvr2_context *pvr = adap->channel.mc_head; - unsigned int idx; - int ret; - struct pvr2_buffer *bp; - struct pvr2_stream *stream = NULL; - - if (adap->stream_run) return -EIO; - - ret = pvr2_channel_claim_stream(&adap->channel, &pvr->video_stream); - /* somebody else already has the stream */ - if (ret < 0) return ret; - - stream = adap->channel.stream->stream; - - for (idx = 0; idx < PVR2_DVB_BUFFER_COUNT; idx++) { - adap->buffer_storage[idx] = kmalloc(PVR2_DVB_BUFFER_SIZE, - GFP_KERNEL); - if (!(adap->buffer_storage[idx])) return -ENOMEM; - } - - pvr2_stream_set_callback(pvr->video_stream.stream, - (pvr2_stream_callback) pvr2_dvb_notify, adap); - - ret = pvr2_stream_set_buffer_count(stream, PVR2_DVB_BUFFER_COUNT); - if (ret < 0) return ret; - - for (idx = 0; idx < PVR2_DVB_BUFFER_COUNT; idx++) { - bp = pvr2_stream_get_buffer(stream, idx); - pvr2_buffer_set_buffer(bp, - adap->buffer_storage[idx], - PVR2_DVB_BUFFER_SIZE); - } - - ret = pvr2_hdw_set_streaming(adap->channel.hdw, 1); - if (ret < 0) return ret; - - while ((bp = pvr2_stream_get_idle_buffer(stream)) != NULL) { - ret = pvr2_buffer_queue(bp); - if (ret < 0) return ret; - } - - adap->thread = kthread_run(pvr2_dvb_feed_thread, adap, "pvrusb2-dvb"); - - if (IS_ERR(adap->thread)) { - ret = PTR_ERR(adap->thread); - adap->thread = NULL; - return ret; - } - - adap->stream_run = !0; - - return 0; -} - -static int pvr2_dvb_stream_start(struct pvr2_dvb_adapter *adap) -{ - int ret = pvr2_dvb_stream_do_start(adap); - if (ret < 0) pvr2_dvb_stream_end(adap); - return ret; -} - -static int pvr2_dvb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) -{ - struct pvr2_dvb_adapter *adap = dvbdmxfeed->demux->priv; - int ret = 0; - - if (adap == NULL) return -ENODEV; - - mutex_lock(&adap->lock); - do { - if (onoff) { - if (!adap->feedcount) { - pvr2_trace(PVR2_TRACE_DVB_FEED, - "start feeding demux"); - ret = pvr2_dvb_stream_start(adap); - if (ret < 0) break; - } - (adap->feedcount)++; - } else if (adap->feedcount > 0) { - (adap->feedcount)--; - if (!adap->feedcount) { - pvr2_trace(PVR2_TRACE_DVB_FEED, - "stop feeding demux"); - pvr2_dvb_stream_end(adap); - } - } - } while (0); - mutex_unlock(&adap->lock); - - return ret; -} - -static int pvr2_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - pvr2_trace(PVR2_TRACE_DVB_FEED, "start pid: 0x%04x", dvbdmxfeed->pid); - return pvr2_dvb_ctrl_feed(dvbdmxfeed, 1); -} - -static int pvr2_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - pvr2_trace(PVR2_TRACE_DVB_FEED, "stop pid: 0x%04x", dvbdmxfeed->pid); - return pvr2_dvb_ctrl_feed(dvbdmxfeed, 0); -} - -static int pvr2_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) -{ - struct pvr2_dvb_adapter *adap = fe->dvb->priv; - return pvr2_channel_limit_inputs( - &adap->channel, - (acquire ? (1 << PVR2_CVAL_INPUT_DTV) : 0)); -} - -static int pvr2_dvb_adapter_init(struct pvr2_dvb_adapter *adap) -{ - int ret; - - ret = dvb_register_adapter(&adap->dvb_adap, "pvrusb2-dvb", - THIS_MODULE/*&hdw->usb_dev->owner*/, - &adap->channel.hdw->usb_dev->dev, - adapter_nr); - if (ret < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "dvb_register_adapter failed: error %d", ret); - goto err; - } - adap->dvb_adap.priv = adap; - - adap->demux.dmx.capabilities = DMX_TS_FILTERING | - DMX_SECTION_FILTERING | - DMX_MEMORY_BASED_FILTERING; - adap->demux.priv = adap; - adap->demux.filternum = 256; - adap->demux.feednum = 256; - adap->demux.start_feed = pvr2_dvb_start_feed; - adap->demux.stop_feed = pvr2_dvb_stop_feed; - adap->demux.write_to_decoder = NULL; - - ret = dvb_dmx_init(&adap->demux); - if (ret < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "dvb_dmx_init failed: error %d", ret); - goto err_dmx; - } - - adap->dmxdev.filternum = adap->demux.filternum; - adap->dmxdev.demux = &adap->demux.dmx; - adap->dmxdev.capabilities = 0; - - ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap); - if (ret < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "dvb_dmxdev_init failed: error %d", ret); - goto err_dmx_dev; - } - - dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx); - - return 0; - -err_dmx_dev: - dvb_dmx_release(&adap->demux); -err_dmx: - dvb_unregister_adapter(&adap->dvb_adap); -err: - return ret; -} - -static int pvr2_dvb_adapter_exit(struct pvr2_dvb_adapter *adap) -{ - pvr2_trace(PVR2_TRACE_INFO, "unregistering DVB devices"); - dvb_net_release(&adap->dvb_net); - adap->demux.dmx.close(&adap->demux.dmx); - dvb_dmxdev_release(&adap->dmxdev); - dvb_dmx_release(&adap->demux); - dvb_unregister_adapter(&adap->dvb_adap); - return 0; -} - -static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap) -{ - struct pvr2_hdw *hdw = adap->channel.hdw; - const struct pvr2_dvb_props *dvb_props = hdw->hdw_desc->dvb_props; - int ret = 0; - - if (dvb_props == NULL) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, "fe_props not defined!"); - return -EINVAL; - } - - ret = pvr2_channel_limit_inputs( - &adap->channel, - (1 << PVR2_CVAL_INPUT_DTV)); - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "failed to grab control of dtv input (code=%d)", - ret); - return ret; - } - - if (dvb_props->frontend_attach == NULL) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "frontend_attach not defined!"); - ret = -EINVAL; - goto done; - } - - if ((dvb_props->frontend_attach(adap) == 0) && (adap->fe)) { - - if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "frontend registration failed!"); - dvb_frontend_detach(adap->fe); - adap->fe = NULL; - ret = -ENODEV; - goto done; - } - - if (dvb_props->tuner_attach) - dvb_props->tuner_attach(adap); - - if (adap->fe->ops.analog_ops.standby) - adap->fe->ops.analog_ops.standby(adap->fe); - - /* Ensure all frontends negotiate bus access */ - adap->fe->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl; - - } else { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "no frontend was attached!"); - ret = -ENODEV; - return ret; - } - - done: - pvr2_channel_limit_inputs(&adap->channel, 0); - return ret; -} - -static int pvr2_dvb_frontend_exit(struct pvr2_dvb_adapter *adap) -{ - if (adap->fe != NULL) { - dvb_unregister_frontend(adap->fe); - dvb_frontend_detach(adap->fe); - } - return 0; -} - -static void pvr2_dvb_destroy(struct pvr2_dvb_adapter *adap) -{ - pvr2_dvb_stream_end(adap); - pvr2_dvb_frontend_exit(adap); - pvr2_dvb_adapter_exit(adap); - pvr2_channel_done(&adap->channel); - kfree(adap); -} - -static void pvr2_dvb_internal_check(struct pvr2_channel *chp) -{ - struct pvr2_dvb_adapter *adap; - adap = container_of(chp, struct pvr2_dvb_adapter, channel); - if (!adap->channel.mc_head->disconnect_flag) return; - pvr2_dvb_destroy(adap); -} - -struct pvr2_dvb_adapter *pvr2_dvb_create(struct pvr2_context *pvr) -{ - int ret = 0; - struct pvr2_dvb_adapter *adap; - if (!pvr->hdw->hdw_desc->dvb_props) { - /* Device lacks a digital interface so don't set up - the DVB side of the driver either. For now. */ - return NULL; - } - adap = kzalloc(sizeof(*adap), GFP_KERNEL); - if (!adap) return adap; - pvr2_channel_init(&adap->channel, pvr); - adap->channel.check_func = pvr2_dvb_internal_check; - init_waitqueue_head(&adap->buffer_wait_data); - mutex_init(&adap->lock); - ret = pvr2_dvb_adapter_init(adap); - if (ret < 0) goto fail1; - ret = pvr2_dvb_frontend_init(adap); - if (ret < 0) goto fail2; - return adap; - -fail2: - pvr2_dvb_adapter_exit(adap); -fail1: - pvr2_channel_done(&adap->channel); - return NULL; -} - diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.h b/drivers/media/video/pvrusb2/pvrusb2-dvb.h deleted file mode 100644 index 884ff916a352..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-dvb.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __PVRUSB2_DVB_H__ -#define __PVRUSB2_DVB_H__ - -#include "dvb_frontend.h" -#include "dvb_demux.h" -#include "dvb_net.h" -#include "dmxdev.h" -#include "pvrusb2-context.h" - -#define PVR2_DVB_BUFFER_COUNT 32 -#define PVR2_DVB_BUFFER_SIZE PAGE_ALIGN(0x4000) - -struct pvr2_dvb_adapter { - struct pvr2_channel channel; - - struct dvb_adapter dvb_adap; - struct dmxdev dmxdev; - struct dvb_demux demux; - struct dvb_net dvb_net; - struct dvb_frontend *fe; - - int feedcount; - int max_feed_count; - - struct task_struct *thread; - struct mutex lock; - - unsigned int stream_run:1; - - wait_queue_head_t buffer_wait_data; - char *buffer_storage[PVR2_DVB_BUFFER_COUNT]; -}; - -struct pvr2_dvb_props { - int (*frontend_attach) (struct pvr2_dvb_adapter *); - int (*tuner_attach) (struct pvr2_dvb_adapter *); -}; - -struct pvr2_dvb_adapter *pvr2_dvb_create(struct pvr2_context *pvr); - -#endif /* __PVRUSB2_DVB_H__ */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-eeprom.c b/drivers/media/video/pvrusb2/pvrusb2-eeprom.c deleted file mode 100644 index 9515f3a68f8f..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-eeprom.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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/slab.h> -#include "pvrusb2-eeprom.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" - -#define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__) - - - -/* - - Read and analyze data in the eeprom. Use tveeprom to figure out - the packet structure, since this is another Hauppauge device and - internally it has a family resemblance to ivtv-type devices - -*/ - -#include <media/tveeprom.h> - -/* We seem to only be interested in the last 128 bytes of the EEPROM */ -#define EEPROM_SIZE 128 - -/* Grab EEPROM contents, needed for direct method. */ -static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw) -{ - struct i2c_msg msg[2]; - u8 *eeprom; - u8 iadd[2]; - u8 addr; - u16 eepromSize; - unsigned int offs; - int ret; - int mode16 = 0; - unsigned pcnt,tcnt; - eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL); - if (!eeprom) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to allocate memory" - " required to read eeprom"); - return NULL; - } - - trace_eeprom("Value for eeprom addr from controller was 0x%x", - hdw->eeprom_addr); - addr = hdw->eeprom_addr; - /* Seems that if the high bit is set, then the *real* eeprom - address is shifted right now bit position (noticed this in - newer PVR USB2 hardware) */ - if (addr & 0x80) addr >>= 1; - - /* FX2 documentation states that a 16bit-addressed eeprom is - expected if the I2C address is an odd number (yeah, this is - strange but it's what they do) */ - mode16 = (addr & 1); - eepromSize = (mode16 ? 4096 : 256); - trace_eeprom("Examining %d byte eeprom at location 0x%x" - " using %d bit addressing",eepromSize,addr, - mode16 ? 16 : 8); - - msg[0].addr = addr; - msg[0].flags = 0; - msg[0].len = mode16 ? 2 : 1; - msg[0].buf = iadd; - msg[1].addr = addr; - msg[1].flags = I2C_M_RD; - - /* We have to do the actual eeprom data fetch ourselves, because - (1) we're only fetching part of the eeprom, and (2) if we were - getting the whole thing our I2C driver can't grab it in one - pass - which is what tveeprom is otherwise going to attempt */ - memset(eeprom,0,EEPROM_SIZE); - for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) { - pcnt = 16; - if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt; - offs = tcnt + (eepromSize - EEPROM_SIZE); - if (mode16) { - iadd[0] = offs >> 8; - iadd[1] = offs; - } else { - iadd[0] = offs; - } - msg[1].len = pcnt; - msg[1].buf = eeprom+tcnt; - if ((ret = i2c_transfer(&hdw->i2c_adap, - msg,ARRAY_SIZE(msg))) != 2) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "eeprom fetch set offs err=%d",ret); - kfree(eeprom); - return NULL; - } - } - return eeprom; -} - - -/* Directly call eeprom analysis function within tveeprom. */ -int pvr2_eeprom_analyze(struct pvr2_hdw *hdw) -{ - u8 *eeprom; - struct tveeprom tvdata; - - memset(&tvdata,0,sizeof(tvdata)); - - eeprom = pvr2_eeprom_fetch(hdw); - if (!eeprom) return -EINVAL; - - { - struct i2c_client fake_client; - /* Newer version expects a useless client interface */ - fake_client.addr = hdw->eeprom_addr; - fake_client.adapter = &hdw->i2c_adap; - tveeprom_hauppauge_analog(&fake_client,&tvdata,eeprom); - } - - trace_eeprom("eeprom assumed v4l tveeprom module"); - trace_eeprom("eeprom direct call results:"); - trace_eeprom("has_radio=%d",tvdata.has_radio); - trace_eeprom("tuner_type=%d",tvdata.tuner_type); - trace_eeprom("tuner_formats=0x%x",tvdata.tuner_formats); - trace_eeprom("audio_processor=%d",tvdata.audio_processor); - trace_eeprom("model=%d",tvdata.model); - trace_eeprom("revision=%d",tvdata.revision); - trace_eeprom("serial_number=%d",tvdata.serial_number); - trace_eeprom("rev_str=%s",tvdata.rev_str); - hdw->tuner_type = tvdata.tuner_type; - hdw->tuner_updated = !0; - hdw->serial_number = tvdata.serial_number; - hdw->std_mask_eeprom = tvdata.tuner_formats; - - kfree(eeprom); - - return 0; -} - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-eeprom.h b/drivers/media/video/pvrusb2/pvrusb2-eeprom.h deleted file mode 100644 index cca3216f94cc..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-eeprom.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ - -#ifndef __PVRUSB2_EEPROM_H -#define __PVRUSB2_EEPROM_H - -struct pvr2_hdw; - -int pvr2_eeprom_analyze(struct pvr2_hdw *); - -#endif /* __PVRUSB2_EEPROM_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c deleted file mode 100644 index e046fdaec5ae..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ /dev/null @@ -1,552 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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/device.h> // for linux/firmware.h -#include <linux/firmware.h> -#include "pvrusb2-util.h" -#include "pvrusb2-encoder.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include "pvrusb2-fx2-cmd.h" - - - -/* Firmware mailbox flags - definitions found from ivtv */ -#define IVTV_MBOX_FIRMWARE_DONE 0x00000004 -#define IVTV_MBOX_DRIVER_DONE 0x00000002 -#define IVTV_MBOX_DRIVER_BUSY 0x00000001 - -#define MBOX_BASE 0x44 - - -static int pvr2_encoder_write_words(struct pvr2_hdw *hdw, - unsigned int offs, - const u32 *data, unsigned int dlen) -{ - unsigned int idx,addr; - unsigned int bAddr; - int ret; - unsigned int chunkCnt; - - /* - - Format: First byte must be 0x01. Remaining 32 bit words are - spread out into chunks of 7 bytes each, with the first 4 bytes - being the data word (little endian), and the next 3 bytes - being the address where that data word is to be written (big - endian). Repeat request for additional words, with offset - adjusted accordingly. - - */ - while (dlen) { - chunkCnt = 8; - if (chunkCnt > dlen) chunkCnt = dlen; - memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer)); - bAddr = 0; - hdw->cmd_buffer[bAddr++] = FX2CMD_MEM_WRITE_DWORD; - for (idx = 0; idx < chunkCnt; idx++) { - addr = idx + offs; - hdw->cmd_buffer[bAddr+6] = (addr & 0xffu); - hdw->cmd_buffer[bAddr+5] = ((addr>>8) & 0xffu); - hdw->cmd_buffer[bAddr+4] = ((addr>>16) & 0xffu); - PVR2_DECOMPOSE_LE(hdw->cmd_buffer, bAddr,data[idx]); - bAddr += 7; - } - ret = pvr2_send_request(hdw, - hdw->cmd_buffer,1+(chunkCnt*7), - NULL,0); - if (ret) return ret; - data += chunkCnt; - dlen -= chunkCnt; - offs += chunkCnt; - } - - return 0; -} - - -static int pvr2_encoder_read_words(struct pvr2_hdw *hdw, - unsigned int offs, - u32 *data, unsigned int dlen) -{ - unsigned int idx; - int ret; - unsigned int chunkCnt; - - /* - - Format: First byte must be 0x02 (status check) or 0x28 (read - back block of 32 bit words). Next 6 bytes must be zero, - followed by a single byte of MBOX_BASE+offset for portion to - be read. Returned data is packed set of 32 bits words that - were read. - - */ - - while (dlen) { - chunkCnt = 16; - if (chunkCnt > dlen) chunkCnt = dlen; - if (chunkCnt < 16) chunkCnt = 1; - hdw->cmd_buffer[0] = - ((chunkCnt == 1) ? - FX2CMD_MEM_READ_DWORD : FX2CMD_MEM_READ_64BYTES); - hdw->cmd_buffer[1] = 0; - hdw->cmd_buffer[2] = 0; - hdw->cmd_buffer[3] = 0; - hdw->cmd_buffer[4] = 0; - hdw->cmd_buffer[5] = ((offs>>16) & 0xffu); - hdw->cmd_buffer[6] = ((offs>>8) & 0xffu); - hdw->cmd_buffer[7] = (offs & 0xffu); - ret = pvr2_send_request(hdw, - hdw->cmd_buffer,8, - hdw->cmd_buffer, - (chunkCnt == 1 ? 4 : 16 * 4)); - if (ret) return ret; - - for (idx = 0; idx < chunkCnt; idx++) { - data[idx] = PVR2_COMPOSE_LE(hdw->cmd_buffer,idx*4); - } - data += chunkCnt; - dlen -= chunkCnt; - offs += chunkCnt; - } - - return 0; -} - - -/* This prototype is set up to be compatible with the - cx2341x_mbox_func prototype in cx2341x.h, which should be in - kernels 2.6.18 or later. We do this so that we can enable - cx2341x.ko to write to our encoder (by handing it a pointer to this - function). For earlier kernels this doesn't really matter. */ -static int pvr2_encoder_cmd(void *ctxt, - u32 cmd, - int arg_cnt_send, - int arg_cnt_recv, - u32 *argp) -{ - unsigned int poll_count; - unsigned int try_count = 0; - int retry_flag; - int ret = 0; - unsigned int idx; - /* These sizes look to be limited by the FX2 firmware implementation */ - u32 wrData[16]; - u32 rdData[16]; - struct pvr2_hdw *hdw = (struct pvr2_hdw *)ctxt; - - - /* - - The encoder seems to speak entirely using blocks 32 bit words. - In ivtv driver terms, this is a mailbox at MBOX_BASE which we - populate with data and watch what the hardware does with it. - The first word is a set of flags used to control the - transaction, the second word is the command to execute, the - third byte is zero (ivtv driver suggests that this is some - kind of return value), and the fourth byte is a specified - timeout (windows driver always uses 0x00060000 except for one - case when it is zero). All successive words are the argument - words for the command. - - First, write out the entire set of words, with the first word - being zero. - - Next, write out just the first word again, but set it to - IVTV_MBOX_DRIVER_DONE | IVTV_DRIVER_BUSY this time (which - probably means "go"). - - Next, read back the return count words. Check the first word, - which should have IVTV_MBOX_FIRMWARE_DONE set. If however - that bit is not set, then the command isn't done so repeat the - read until it is set. - - Finally, write out just the first word again, but set it to - 0x0 this time (which probably means "idle"). - - */ - - if (arg_cnt_send > (ARRAY_SIZE(wrData) - 4)) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Failed to write cx23416 command" - " - too many input arguments" - " (was given %u limit %lu)", - arg_cnt_send, (long unsigned) ARRAY_SIZE(wrData) - 4); - return -EINVAL; - } - - if (arg_cnt_recv > (ARRAY_SIZE(rdData) - 4)) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Failed to write cx23416 command" - " - too many return arguments" - " (was given %u limit %lu)", - arg_cnt_recv, (long unsigned) ARRAY_SIZE(rdData) - 4); - return -EINVAL; - } - - - LOCK_TAKE(hdw->ctl_lock); do { - - if (!hdw->state_encoder_ok) { - ret = -EIO; - break; - } - - retry_flag = 0; - try_count++; - ret = 0; - wrData[0] = 0; - wrData[1] = cmd; - wrData[2] = 0; - wrData[3] = 0x00060000; - for (idx = 0; idx < arg_cnt_send; idx++) { - wrData[idx+4] = argp[idx]; - } - for (; idx < ARRAY_SIZE(wrData) - 4; idx++) { - wrData[idx+4] = 0; - } - - ret = pvr2_encoder_write_words(hdw,MBOX_BASE,wrData,idx); - if (ret) break; - wrData[0] = IVTV_MBOX_DRIVER_DONE|IVTV_MBOX_DRIVER_BUSY; - ret = pvr2_encoder_write_words(hdw,MBOX_BASE,wrData,1); - if (ret) break; - poll_count = 0; - while (1) { - poll_count++; - ret = pvr2_encoder_read_words(hdw,MBOX_BASE,rdData, - arg_cnt_recv+4); - if (ret) { - break; - } - if (rdData[0] & IVTV_MBOX_FIRMWARE_DONE) { - break; - } - if (rdData[0] && (poll_count < 1000)) continue; - if (!rdData[0]) { - retry_flag = !0; - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Encoder timed out waiting for us" - "; arranging to retry"); - } else { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "***WARNING*** device's encoder" - " appears to be stuck" - " (status=0x%08x)",rdData[0]); - } - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Encoder command: 0x%02x",cmd); - for (idx = 4; idx < arg_cnt_send; idx++) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Encoder arg%d: 0x%08x", - idx-3,wrData[idx]); - } - ret = -EBUSY; - break; - } - if (retry_flag) { - if (try_count < 20) continue; - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Too many retries..."); - ret = -EBUSY; - } - if (ret) { - del_timer_sync(&hdw->encoder_run_timer); - hdw->state_encoder_ok = 0; - pvr2_trace(PVR2_TRACE_STBITS, - "State bit %s <-- %s", - "state_encoder_ok", - (hdw->state_encoder_ok ? "true" : "false")); - if (hdw->state_encoder_runok) { - hdw->state_encoder_runok = 0; - pvr2_trace(PVR2_TRACE_STBITS, - "State bit %s <-- %s", - "state_encoder_runok", - (hdw->state_encoder_runok ? - "true" : "false")); - } - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Giving up on command." - " This is normally recovered via a firmware" - " reload and re-initialization; concern" - " is only warranted if this happens repeatedly" - " and rapidly."); - break; - } - wrData[0] = 0x7; - for (idx = 0; idx < arg_cnt_recv; idx++) { - argp[idx] = rdData[idx+4]; - } - - wrData[0] = 0x0; - ret = pvr2_encoder_write_words(hdw,MBOX_BASE,wrData,1); - if (ret) break; - - } while(0); LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - - -static int pvr2_encoder_vcmd(struct pvr2_hdw *hdw, int cmd, - int args, ...) -{ - va_list vl; - unsigned int idx; - u32 data[12]; - - if (args > ARRAY_SIZE(data)) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Failed to write cx23416 command" - " - too many arguments" - " (was given %u limit %lu)", - args, (long unsigned) ARRAY_SIZE(data)); - return -EINVAL; - } - - va_start(vl, args); - for (idx = 0; idx < args; idx++) { - data[idx] = va_arg(vl, u32); - } - va_end(vl); - - return pvr2_encoder_cmd(hdw,cmd,args,0,data); -} - - -/* This implements some extra setup for the encoder that seems to be - specific to the PVR USB2 hardware. */ -static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw) -{ - int ret = 0; - int encMisc3Arg = 0; - -#if 0 - /* This inexplicable bit happens in the Hauppauge windows - driver (for both 24xxx and 29xxx devices). However I - currently see no difference in behavior with or without - this stuff. Leave this here as a note of its existence, - but don't use it. */ - LOCK_TAKE(hdw->ctl_lock); do { - u32 dat[1]; - dat[0] = 0x80000640; - pvr2_encoder_write_words(hdw,0x01fe,dat,1); - pvr2_encoder_write_words(hdw,0x023e,dat,1); - } while(0); LOCK_GIVE(hdw->ctl_lock); -#endif - - /* Mike Isely <isely@pobox.com> 26-Jan-2006 The windows driver - sends the following list of ENC_MISC commands (for both - 24xxx and 29xxx devices). Meanings are not entirely clear, - however without the ENC_MISC(3,1) command then we risk - random perpetual video corruption whenever the video input - breaks up for a moment (like when switching channels). */ - - -#if 0 - /* This ENC_MISC(5,0) command seems to hurt 29xxx sync - performance on channel changes, but is not a problem on - 24xxx devices. */ - ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 5,0,0,0); -#endif - - /* This ENC_MISC(3,encMisc3Arg) command is critical - without - it there will eventually be video corruption. Also, the - saa7115 case is strange - the Windows driver is passing 1 - regardless of device type but if we have 1 for saa7115 - devices the video turns sluggish. */ - if (hdw->hdw_desc->flag_has_cx25840) { - encMisc3Arg = 1; - } else { - encMisc3Arg = 0; - } - ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 3, - encMisc3Arg,0,0); - - ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 8,0,0,0); - -#if 0 - /* This ENC_MISC(4,1) command is poisonous, so it is commented - out. But I'm leaving it here anyway to document its - existence in the Windows driver. The effect of this - command is that apps displaying the stream become sluggish - with stuttering video. */ - ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 4,1,0,0); -#endif - - ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 0,3,0,0); - ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4,15,0,0,0); - - /* prevent the PTSs from slowly drifting away in the generated - MPEG stream */ - ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC, 2, 4, 1); - - return ret; -} - -int pvr2_encoder_adjust(struct pvr2_hdw *hdw) -{ - int ret; - ret = cx2341x_update(hdw,pvr2_encoder_cmd, - (hdw->enc_cur_valid ? &hdw->enc_cur_state : NULL), - &hdw->enc_ctl_state); - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Error from cx2341x module code=%d",ret); - } else { - memcpy(&hdw->enc_cur_state,&hdw->enc_ctl_state, - sizeof(struct cx2341x_mpeg_params)); - hdw->enc_cur_valid = !0; - } - return ret; -} - - -int pvr2_encoder_configure(struct pvr2_hdw *hdw) -{ - int ret; - int val; - pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure" - " (cx2341x module)"); - hdw->enc_ctl_state.port = CX2341X_PORT_STREAMING; - hdw->enc_ctl_state.width = hdw->res_hor_val; - hdw->enc_ctl_state.height = hdw->res_ver_val; - hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur & V4L2_STD_525_60) ? - 0 : 1); - - ret = 0; - - ret |= pvr2_encoder_prep_config(hdw); - - /* saa7115: 0xf0 */ - val = 0xf0; - if (hdw->hdw_desc->flag_has_cx25840) { - /* ivtv cx25840: 0x140 */ - val = 0x140; - } - - if (!ret) ret = pvr2_encoder_vcmd( - hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, - val, val); - - /* setup firmware to notify us about some events (don't know why...) */ - if (!ret) ret = pvr2_encoder_vcmd( - hdw,CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, - 0, 0, 0x10000000, 0xffffffff); - - if (!ret) ret = pvr2_encoder_vcmd( - hdw,CX2341X_ENC_SET_VBI_LINE, 5, - 0xffffffff,0,0,0,0); - - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to configure cx23416"); - return ret; - } - - ret = pvr2_encoder_adjust(hdw); - if (ret) return ret; - - ret = pvr2_encoder_vcmd( - hdw, CX2341X_ENC_INITIALIZE_INPUT, 0); - - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to initialize cx23416 video input"); - return ret; - } - - return 0; -} - - -int pvr2_encoder_start(struct pvr2_hdw *hdw) -{ - int status; - - /* unmask some interrupts */ - pvr2_write_register(hdw, 0x0048, 0xbfffffff); - - pvr2_encoder_vcmd(hdw,CX2341X_ENC_MUTE_VIDEO,1, - hdw->input_val == PVR2_CVAL_INPUT_RADIO ? 1 : 0); - - switch (hdw->active_stream_type) { - case pvr2_config_vbi: - status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2, - 0x01,0x14); - break; - case pvr2_config_mpeg: - status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2, - 0,0x13); - break; - default: /* Unhandled cases for now */ - status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2, - 0,0x13); - break; - } - return status; -} - -int pvr2_encoder_stop(struct pvr2_hdw *hdw) -{ - int status; - - /* mask all interrupts */ - pvr2_write_register(hdw, 0x0048, 0xffffffff); - - switch (hdw->active_stream_type) { - case pvr2_config_vbi: - status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3, - 0x01,0x01,0x14); - break; - case pvr2_config_mpeg: - status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3, - 0x01,0,0x13); - break; - default: /* Unhandled cases for now */ - status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3, - 0x01,0,0x13); - break; - } - - return status; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.h b/drivers/media/video/pvrusb2/pvrusb2-encoder.h deleted file mode 100644 index 232fefbcd1ac..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-encoder.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ - -#ifndef __PVRUSB2_ENCODER_H -#define __PVRUSB2_ENCODER_H - -struct pvr2_hdw; - -int pvr2_encoder_adjust(struct pvr2_hdw *); -int pvr2_encoder_configure(struct pvr2_hdw *); -int pvr2_encoder_start(struct pvr2_hdw *); -int pvr2_encoder_stop(struct pvr2_hdw *); - -#endif /* __PVRUSB2_ENCODER_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h b/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h deleted file mode 100644 index 614755ea2ea3..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * - * - * Copyright (C) 2007 Michael Krufky <mkrufky@linuxtv.org> - * - * 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 - * - * 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 - * - */ - -#ifndef _PVRUSB2_FX2_CMD_H_ -#define _PVRUSB2_FX2_CMD_H_ - -#define FX2CMD_MEM_WRITE_DWORD 0x01u -#define FX2CMD_MEM_READ_DWORD 0x02u - -#define FX2CMD_HCW_ZILOG_RESET 0x10u /* 1=reset 0=release */ - -#define FX2CMD_MEM_READ_64BYTES 0x28u - -#define FX2CMD_REG_WRITE 0x04u -#define FX2CMD_REG_READ 0x05u -#define FX2CMD_MEMSEL 0x06u - -#define FX2CMD_I2C_WRITE 0x08u -#define FX2CMD_I2C_READ 0x09u - -#define FX2CMD_GET_USB_SPEED 0x0bu - -#define FX2CMD_STREAMING_ON 0x36u -#define FX2CMD_STREAMING_OFF 0x37u - -#define FX2CMD_FWPOST1 0x52u - -#define FX2CMD_POWER_OFF 0xdcu -#define FX2CMD_POWER_ON 0xdeu - -#define FX2CMD_DEEP_RESET 0xddu - -#define FX2CMD_GET_EEPROM_ADDR 0xebu -#define FX2CMD_GET_IR_CODE 0xecu - -#define FX2CMD_HCW_DEMOD_RESETIN 0xf0u -#define FX2CMD_HCW_DTV_STREAMING_ON 0xf1u -#define FX2CMD_HCW_DTV_STREAMING_OFF 0xf2u - -#define FX2CMD_ONAIR_DTV_STREAMING_ON 0xa0u -#define FX2CMD_ONAIR_DTV_STREAMING_OFF 0xa1u -#define FX2CMD_ONAIR_DTV_POWER_ON 0xa2u -#define FX2CMD_ONAIR_DTV_POWER_OFF 0xa3u - -#endif /* _PVRUSB2_FX2_CMD_H_ */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h deleted file mode 100644 index 036952f2a3cb..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ /dev/null @@ -1,406 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ -#ifndef __PVRUSB2_HDW_INTERNAL_H -#define __PVRUSB2_HDW_INTERNAL_H - -/* - - This header sets up all the internal structures and definitions needed to - track and coordinate the driver's interaction with the hardware. ONLY - source files which actually implement part of that whole circus should be - including this header. Higher levels, like the external layers to the - various public APIs (V4L, sysfs, etc) should NOT ever include this - private, internal header. This means that pvrusb2-hdw, pvrusb2-encoder, - etc will include this, but pvrusb2-v4l should not. - -*/ - -#include <linux/videodev2.h> -#include <linux/i2c.h> -#include <linux/workqueue.h> -#include <linux/mutex.h> -#include "pvrusb2-hdw.h" -#include "pvrusb2-io.h" -#include <media/v4l2-device.h> -#include <media/cx2341x.h> -#include <media/ir-kbd-i2c.h> -#include "pvrusb2-devattr.h" - -/* Legal values for PVR2_CID_HSM */ -#define PVR2_CVAL_HSM_FAIL 0 -#define PVR2_CVAL_HSM_FULL 1 -#define PVR2_CVAL_HSM_HIGH 2 - -#define PVR2_VID_ENDPOINT 0x84 -#define PVR2_UNK_ENDPOINT 0x86 /* maybe raw yuv ? */ -#define PVR2_VBI_ENDPOINT 0x88 - -#define PVR2_CTL_BUFFSIZE 64 - -#define FREQTABLE_SIZE 500 - -#define LOCK_TAKE(x) do { mutex_lock(&x##_mutex); x##_held = !0; } while (0) -#define LOCK_GIVE(x) do { x##_held = 0; mutex_unlock(&x##_mutex); } while (0) - -typedef int (*pvr2_ctlf_is_dirty)(struct pvr2_ctrl *); -typedef void (*pvr2_ctlf_clear_dirty)(struct pvr2_ctrl *); -typedef int (*pvr2_ctlf_check_value)(struct pvr2_ctrl *,int); -typedef int (*pvr2_ctlf_get_value)(struct pvr2_ctrl *,int *); -typedef int (*pvr2_ctlf_set_value)(struct pvr2_ctrl *,int msk,int val); -typedef int (*pvr2_ctlf_val_to_sym)(struct pvr2_ctrl *,int msk,int val, - char *,unsigned int,unsigned int *); -typedef int (*pvr2_ctlf_sym_to_val)(struct pvr2_ctrl *, - const char *,unsigned int, - int *mskp,int *valp); -typedef unsigned int (*pvr2_ctlf_get_v4lflags)(struct pvr2_ctrl *); - -/* This structure describes a specific control. A table of these is set up - in pvrusb2-hdw.c. */ -struct pvr2_ctl_info { - /* Control's name suitable for use as an identifier */ - const char *name; - - /* Short description of control */ - const char *desc; - - /* Control's implementation */ - pvr2_ctlf_get_value get_value; /* Get its value */ - pvr2_ctlf_get_value get_def_value; /* Get its default value */ - pvr2_ctlf_get_value get_min_value; /* Get minimum allowed value */ - pvr2_ctlf_get_value get_max_value; /* Get maximum allowed value */ - pvr2_ctlf_set_value set_value; /* Set its value */ - pvr2_ctlf_check_value check_value; /* Check that value is valid */ - pvr2_ctlf_val_to_sym val_to_sym; /* Custom convert value->symbol */ - pvr2_ctlf_sym_to_val sym_to_val; /* Custom convert symbol->value */ - pvr2_ctlf_is_dirty is_dirty; /* Return true if dirty */ - pvr2_ctlf_clear_dirty clear_dirty; /* Clear dirty state */ - pvr2_ctlf_get_v4lflags get_v4lflags;/* Retrieve v4l flags */ - - /* Control's type (int, enum, bitmask) */ - enum pvr2_ctl_type type; - - /* Associated V4L control ID, if any */ - int v4l_id; - - /* Associated driver internal ID, if any */ - int internal_id; - - /* Don't implicitly initialize this control's value */ - int skip_init; - - /* Starting value for this control */ - int default_value; - - /* Type-specific control information */ - union { - struct { /* Integer control */ - long min_value; /* lower limit */ - long max_value; /* upper limit */ - } type_int; - struct { /* enumerated control */ - unsigned int count; /* enum value count */ - const char * const *value_names; /* symbol names */ - } type_enum; - struct { /* bitmask control */ - unsigned int valid_bits; /* bits in use */ - const char **bit_names; /* symbol name/bit */ - } type_bitmask; - } def; -}; - - -/* Same as pvr2_ctl_info, but includes storage for the control description */ -#define PVR2_CTLD_INFO_DESC_SIZE 32 -struct pvr2_ctld_info { - struct pvr2_ctl_info info; - char desc[PVR2_CTLD_INFO_DESC_SIZE]; -}; - -struct pvr2_ctrl { - const struct pvr2_ctl_info *info; - struct pvr2_hdw *hdw; -}; - - - -/* Disposition of firmware1 loading situation */ -#define FW1_STATE_UNKNOWN 0 -#define FW1_STATE_MISSING 1 -#define FW1_STATE_FAILED 2 -#define FW1_STATE_RELOAD 3 -#define FW1_STATE_OK 4 - -/* What state the device is in if it is a hybrid */ -#define PVR2_PATHWAY_UNKNOWN 0 -#define PVR2_PATHWAY_ANALOG 1 -#define PVR2_PATHWAY_DIGITAL 2 - -typedef int (*pvr2_i2c_func)(struct pvr2_hdw *,u8,u8 *,u16,u8 *, u16); -#define PVR2_I2C_FUNC_CNT 128 - -/* This structure contains all state data directly needed to - manipulate the hardware (as opposed to complying with a kernel - interface) */ -struct pvr2_hdw { - /* Underlying USB device handle */ - struct usb_device *usb_dev; - struct usb_interface *usb_intf; - - /* Our handle into the v4l2 sub-device architecture */ - struct v4l2_device v4l2_dev; - /* Device description, anything that must adjust behavior based on - device specific info will use information held here. */ - const struct pvr2_device_desc *hdw_desc; - - /* Kernel worker thread handling */ - struct workqueue_struct *workqueue; - struct work_struct workpoll; /* Update driver state */ - - /* Video spigot */ - struct pvr2_stream *vid_stream; - - /* Mutex for all hardware state control */ - struct mutex big_lock_mutex; - int big_lock_held; /* For debugging */ - - /* This is a simple string which identifies the instance of this - driver. It is unique within the set of existing devices, but - there is no attempt to keep the name consistent with the same - physical device each time. */ - char name[32]; - - /* This is a simple string which identifies the physical device - instance itself - if possible. (If not possible, then it is - based on the specific driver instance, similar to name above.) - The idea here is that userspace might hopefully be able to use - this recognize specific tuners. It will encode a serial number, - if available. */ - char identifier[32]; - - /* I2C stuff */ - struct i2c_adapter i2c_adap; - struct i2c_algorithm i2c_algo; - pvr2_i2c_func i2c_func[PVR2_I2C_FUNC_CNT]; - int i2c_cx25840_hack_state; - int i2c_linked; - - /* IR related */ - unsigned int ir_scheme_active; /* IR scheme as seen from the outside */ - struct IR_i2c_init_data ir_init_data; /* params passed to IR modules */ - - /* Frequency table */ - unsigned int freqTable[FREQTABLE_SIZE]; - unsigned int freqProgSlot; - - /* Stuff for handling low level control interaction with device */ - struct mutex ctl_lock_mutex; - int ctl_lock_held; /* For debugging */ - struct urb *ctl_write_urb; - struct urb *ctl_read_urb; - unsigned char *ctl_write_buffer; - unsigned char *ctl_read_buffer; - int ctl_write_pend_flag; - int ctl_read_pend_flag; - int ctl_timeout_flag; - struct completion ctl_done; - unsigned char cmd_buffer[PVR2_CTL_BUFFSIZE]; - int cmd_debug_state; // Low level command debugging info - unsigned char cmd_debug_code; // - unsigned int cmd_debug_write_len; // - unsigned int cmd_debug_read_len; // - - /* Bits of state that describe what is going on with various parts - of the driver. */ - int state_pathway_ok; /* Pathway config is ok */ - int state_encoder_ok; /* Encoder is operational */ - int state_encoder_run; /* Encoder is running */ - int state_encoder_config; /* Encoder is configured */ - int state_encoder_waitok; /* Encoder pre-wait done */ - int state_encoder_runok; /* Encoder has run for >= .25 sec */ - int state_decoder_run; /* Decoder is running */ - int state_decoder_ready; /* Decoder is stabilized & streamable */ - int state_usbstream_run; /* FX2 is streaming */ - int state_decoder_quiescent; /* Decoder idle for minimal interval */ - int state_pipeline_config; /* Pipeline is configured */ - int state_pipeline_req; /* Somebody wants to stream */ - int state_pipeline_pause; /* Pipeline must be paused */ - int state_pipeline_idle; /* Pipeline not running */ - - /* This is the master state of the driver. It is the combined - result of other bits of state. Examining this will indicate the - overall state of the driver. Values here are one of - PVR2_STATE_xxxx */ - unsigned int master_state; - - /* True if device led is currently on */ - int led_on; - - /* True if states must be re-evaluated */ - int state_stale; - - void (*state_func)(void *); - void *state_data; - - /* Timer for measuring required decoder settling time before we're - allowed to fire it up again. */ - struct timer_list quiescent_timer; - - /* Timer for measuring decoder stabilization time, which is the - amount of time we need to let the decoder run before we can - trust its output (otherwise the encoder might see garbage and - then fail to start correctly). */ - struct timer_list decoder_stabilization_timer; - - /* Timer for measuring encoder pre-wait time */ - struct timer_list encoder_wait_timer; - - /* Timer for measuring encoder minimum run time */ - struct timer_list encoder_run_timer; - - /* Place to block while waiting for state changes */ - wait_queue_head_t state_wait_data; - - - int force_dirty; /* consider all controls dirty if true */ - int flag_ok; /* device in known good state */ - int flag_modulefail; /* true if at least one module failed to load */ - int flag_disconnected; /* flag_ok == 0 due to disconnect */ - int flag_init_ok; /* true if structure is fully initialized */ - int fw1_state; /* current situation with fw1 */ - int pathway_state; /* one of PVR2_PATHWAY_xxx */ - int flag_decoder_missed;/* We've noticed missing decoder */ - int flag_tripped; /* Indicates overall failure to start */ - - unsigned int decoder_client_id; - - // CPU firmware info (used to help find / save firmware data) - char *fw_buffer; - unsigned int fw_size; - int fw_cpu_flag; /* True if we are dealing with the CPU */ - - /* Tuner / frequency control stuff */ - unsigned int tuner_type; - int tuner_updated; - unsigned int freqValTelevision; /* Current freq for tv mode */ - unsigned int freqValRadio; /* Current freq for radio mode */ - unsigned int freqSlotTelevision; /* Current slot for tv mode */ - unsigned int freqSlotRadio; /* Current slot for radio mode */ - unsigned int freqSelector; /* 0=radio 1=television */ - int freqDirty; - - /* Current tuner info - this information is polled from the I2C bus */ - struct v4l2_tuner tuner_signal_info; - int tuner_signal_stale; - - /* Cropping capability info */ - struct v4l2_cropcap cropcap_info; - int cropcap_stale; - - /* Video standard handling */ - v4l2_std_id std_mask_eeprom; // Hardware supported selections - v4l2_std_id std_mask_avail; // Which standards we may select from - v4l2_std_id std_mask_cur; // Currently selected standard(s) - int std_enum_cur; // selected standard enumeration value - int std_dirty; // True if std_mask_cur has changed - struct pvr2_ctl_info std_info_enum; - struct pvr2_ctl_info std_info_avail; - struct pvr2_ctl_info std_info_cur; - struct pvr2_ctl_info std_info_detect; - - // Generated string names, one per actual V4L2 standard - const char *std_mask_ptrs[32]; - char std_mask_names[32][16]; - - int unit_number; /* ID for driver instance */ - unsigned long serial_number; /* ID for hardware itself */ - - char bus_info[32]; /* Bus location info */ - - /* Minor numbers used by v4l logic (yes, this is a hack, as there - should be no v4l junk here). Probably a better way to do this. */ - int v4l_minor_number_video; - int v4l_minor_number_vbi; - int v4l_minor_number_radio; - - /* Bit mask of PVR2_CVAL_INPUT choices which are valid for the hardware */ - unsigned int input_avail_mask; - /* Bit mask of PVR2_CVAL_INPUT choices which are currently allowed */ - unsigned int input_allowed_mask; - - /* Location of eeprom or a negative number if none */ - int eeprom_addr; - - enum pvr2_config active_stream_type; - enum pvr2_config desired_stream_type; - - /* Control state needed for cx2341x module */ - struct cx2341x_mpeg_params enc_cur_state; - struct cx2341x_mpeg_params enc_ctl_state; - /* True if an encoder attribute has changed */ - int enc_stale; - /* True if an unsafe encoder attribute has changed */ - int enc_unsafe_stale; - /* True if enc_cur_state is valid */ - int enc_cur_valid; - - /* Control state */ -#define VCREATE_DATA(lab) int lab##_val; int lab##_dirty - VCREATE_DATA(brightness); - VCREATE_DATA(contrast); - VCREATE_DATA(saturation); - VCREATE_DATA(hue); - VCREATE_DATA(volume); - VCREATE_DATA(balance); - VCREATE_DATA(bass); - VCREATE_DATA(treble); - VCREATE_DATA(mute); - VCREATE_DATA(cropl); - VCREATE_DATA(cropt); - VCREATE_DATA(cropw); - VCREATE_DATA(croph); - VCREATE_DATA(input); - VCREATE_DATA(audiomode); - VCREATE_DATA(res_hor); - VCREATE_DATA(res_ver); - VCREATE_DATA(srate); -#undef VCREATE_DATA - - struct pvr2_ctld_info *mpeg_ctrl_info; - - struct pvr2_ctrl *controls; - unsigned int control_cnt; -}; - -/* This function gets the current frequency */ -unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *); - -void pvr2_hdw_status_poll(struct pvr2_hdw *); - -#endif /* __PVRUSB2_HDW_INTERNAL_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c deleted file mode 100644 index fb828ba1dbbe..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ /dev/null @@ -1,5202 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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/errno.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/firmware.h> -#include <linux/videodev2.h> -#include <media/v4l2-common.h> -#include <media/tuner.h> -#include "pvrusb2.h" -#include "pvrusb2-std.h" -#include "pvrusb2-util.h" -#include "pvrusb2-hdw.h" -#include "pvrusb2-i2c-core.h" -#include "pvrusb2-eeprom.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-encoder.h" -#include "pvrusb2-debug.h" -#include "pvrusb2-fx2-cmd.h" -#include "pvrusb2-wm8775.h" -#include "pvrusb2-video-v4l.h" -#include "pvrusb2-cx2584x-v4l.h" -#include "pvrusb2-cs53l32a.h" -#include "pvrusb2-audio.h" - -#define TV_MIN_FREQ 55250000L -#define TV_MAX_FREQ 850000000L - -/* This defines a minimum interval that the decoder must remain quiet - before we are allowed to start it running. */ -#define TIME_MSEC_DECODER_WAIT 50 - -/* This defines a minimum interval that the decoder must be allowed to run - before we can safely begin using its streaming output. */ -#define TIME_MSEC_DECODER_STABILIZATION_WAIT 300 - -/* This defines a minimum interval that the encoder must remain quiet - before we are allowed to configure it. */ -#define TIME_MSEC_ENCODER_WAIT 50 - -/* This defines the minimum interval that the encoder must successfully run - before we consider that the encoder has run at least once since its - firmware has been loaded. This measurement is in important for cases - where we can't do something until we know that the encoder has been run - at least once. */ -#define TIME_MSEC_ENCODER_OK 250 - -static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL}; -static DEFINE_MUTEX(pvr2_unit_mtx); - -static int ctlchg; -static int procreload; -static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 }; -static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 }; -static int video_std[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 }; -static int init_pause_msec; - -module_param(ctlchg, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value"); -module_param(init_pause_msec, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(init_pause_msec, "hardware initialization settling delay"); -module_param(procreload, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(procreload, - "Attempt init failure recovery with firmware reload"); -module_param_array(tuner, int, NULL, 0444); -MODULE_PARM_DESC(tuner,"specify installed tuner type"); -module_param_array(video_std, int, NULL, 0444); -MODULE_PARM_DESC(video_std,"specify initial video standard"); -module_param_array(tolerance, int, NULL, 0444); -MODULE_PARM_DESC(tolerance,"specify stream error tolerance"); - -/* US Broadcast channel 3 (61.25 MHz), to help with testing */ -static int default_tv_freq = 61250000L; -/* 104.3 MHz, a usable FM station for my area */ -static int default_radio_freq = 104300000L; - -module_param_named(tv_freq, default_tv_freq, int, 0444); -MODULE_PARM_DESC(tv_freq, "specify initial television frequency"); -module_param_named(radio_freq, default_radio_freq, int, 0444); -MODULE_PARM_DESC(radio_freq, "specify initial radio frequency"); - -#define PVR2_CTL_WRITE_ENDPOINT 0x01 -#define PVR2_CTL_READ_ENDPOINT 0x81 - -#define PVR2_GPIO_IN 0x9008 -#define PVR2_GPIO_OUT 0x900c -#define PVR2_GPIO_DIR 0x9020 - -#define trace_firmware(...) pvr2_trace(PVR2_TRACE_FIRMWARE,__VA_ARGS__) - -#define PVR2_FIRMWARE_ENDPOINT 0x02 - -/* size of a firmware chunk */ -#define FIRMWARE_CHUNK_SIZE 0x2000 - -typedef void (*pvr2_subdev_update_func)(struct pvr2_hdw *, - struct v4l2_subdev *); - -static const pvr2_subdev_update_func pvr2_module_update_functions[] = { - [PVR2_CLIENT_ID_WM8775] = pvr2_wm8775_subdev_update, - [PVR2_CLIENT_ID_SAA7115] = pvr2_saa7115_subdev_update, - [PVR2_CLIENT_ID_MSP3400] = pvr2_msp3400_subdev_update, - [PVR2_CLIENT_ID_CX25840] = pvr2_cx25840_subdev_update, - [PVR2_CLIENT_ID_CS53L32A] = pvr2_cs53l32a_subdev_update, -}; - -static const char *module_names[] = { - [PVR2_CLIENT_ID_MSP3400] = "msp3400", - [PVR2_CLIENT_ID_CX25840] = "cx25840", - [PVR2_CLIENT_ID_SAA7115] = "saa7115", - [PVR2_CLIENT_ID_TUNER] = "tuner", - [PVR2_CLIENT_ID_DEMOD] = "tuner", - [PVR2_CLIENT_ID_CS53L32A] = "cs53l32a", - [PVR2_CLIENT_ID_WM8775] = "wm8775", -}; - - -static const unsigned char *module_i2c_addresses[] = { - [PVR2_CLIENT_ID_TUNER] = "\x60\x61\x62\x63", - [PVR2_CLIENT_ID_DEMOD] = "\x43", - [PVR2_CLIENT_ID_MSP3400] = "\x40", - [PVR2_CLIENT_ID_SAA7115] = "\x21", - [PVR2_CLIENT_ID_WM8775] = "\x1b", - [PVR2_CLIENT_ID_CX25840] = "\x44", - [PVR2_CLIENT_ID_CS53L32A] = "\x11", -}; - - -static const char *ir_scheme_names[] = { - [PVR2_IR_SCHEME_NONE] = "none", - [PVR2_IR_SCHEME_29XXX] = "29xxx", - [PVR2_IR_SCHEME_24XXX] = "24xxx (29xxx emulation)", - [PVR2_IR_SCHEME_24XXX_MCE] = "24xxx (MCE device)", - [PVR2_IR_SCHEME_ZILOG] = "Zilog", -}; - - -/* Define the list of additional controls we'll dynamically construct based - on query of the cx2341x module. */ -struct pvr2_mpeg_ids { - const char *strid; - int id; -}; -static const struct pvr2_mpeg_ids mpeg_ids[] = { - { - .strid = "audio_layer", - .id = V4L2_CID_MPEG_AUDIO_ENCODING, - },{ - .strid = "audio_bitrate", - .id = V4L2_CID_MPEG_AUDIO_L2_BITRATE, - },{ - /* Already using audio_mode elsewhere :-( */ - .strid = "mpeg_audio_mode", - .id = V4L2_CID_MPEG_AUDIO_MODE, - },{ - .strid = "mpeg_audio_mode_extension", - .id = V4L2_CID_MPEG_AUDIO_MODE_EXTENSION, - },{ - .strid = "audio_emphasis", - .id = V4L2_CID_MPEG_AUDIO_EMPHASIS, - },{ - .strid = "audio_crc", - .id = V4L2_CID_MPEG_AUDIO_CRC, - },{ - .strid = "video_aspect", - .id = V4L2_CID_MPEG_VIDEO_ASPECT, - },{ - .strid = "video_b_frames", - .id = V4L2_CID_MPEG_VIDEO_B_FRAMES, - },{ - .strid = "video_gop_size", - .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE, - },{ - .strid = "video_gop_closure", - .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, - },{ - .strid = "video_bitrate_mode", - .id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE, - },{ - .strid = "video_bitrate", - .id = V4L2_CID_MPEG_VIDEO_BITRATE, - },{ - .strid = "video_bitrate_peak", - .id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, - },{ - .strid = "video_temporal_decimation", - .id = V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION, - },{ - .strid = "stream_type", - .id = V4L2_CID_MPEG_STREAM_TYPE, - },{ - .strid = "video_spatial_filter_mode", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE, - },{ - .strid = "video_spatial_filter", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER, - },{ - .strid = "video_luma_spatial_filter_type", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE, - },{ - .strid = "video_chroma_spatial_filter_type", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE, - },{ - .strid = "video_temporal_filter_mode", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE, - },{ - .strid = "video_temporal_filter", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER, - },{ - .strid = "video_median_filter_type", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE, - },{ - .strid = "video_luma_median_filter_top", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP, - },{ - .strid = "video_luma_median_filter_bottom", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM, - },{ - .strid = "video_chroma_median_filter_top", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP, - },{ - .strid = "video_chroma_median_filter_bottom", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM, - } -}; -#define MPEGDEF_COUNT ARRAY_SIZE(mpeg_ids) - - -static const char *control_values_srate[] = { - [V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100] = "44.1 kHz", - [V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000] = "48 kHz", - [V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000] = "32 kHz", -}; - - - -static const char *control_values_input[] = { - [PVR2_CVAL_INPUT_TV] = "television", /*xawtv needs this name*/ - [PVR2_CVAL_INPUT_DTV] = "dtv", - [PVR2_CVAL_INPUT_RADIO] = "radio", - [PVR2_CVAL_INPUT_SVIDEO] = "s-video", - [PVR2_CVAL_INPUT_COMPOSITE] = "composite", -}; - - -static const char *control_values_audiomode[] = { - [V4L2_TUNER_MODE_MONO] = "Mono", - [V4L2_TUNER_MODE_STEREO] = "Stereo", - [V4L2_TUNER_MODE_LANG1] = "Lang1", - [V4L2_TUNER_MODE_LANG2] = "Lang2", - [V4L2_TUNER_MODE_LANG1_LANG2] = "Lang1+Lang2", -}; - - -static const char *control_values_hsm[] = { - [PVR2_CVAL_HSM_FAIL] = "Fail", - [PVR2_CVAL_HSM_HIGH] = "High", - [PVR2_CVAL_HSM_FULL] = "Full", -}; - - -static const char *pvr2_state_names[] = { - [PVR2_STATE_NONE] = "none", - [PVR2_STATE_DEAD] = "dead", - [PVR2_STATE_COLD] = "cold", - [PVR2_STATE_WARM] = "warm", - [PVR2_STATE_ERROR] = "error", - [PVR2_STATE_READY] = "ready", - [PVR2_STATE_RUN] = "run", -}; - - -struct pvr2_fx2cmd_descdef { - unsigned char id; - unsigned char *desc; -}; - -static const struct pvr2_fx2cmd_descdef pvr2_fx2cmd_desc[] = { - {FX2CMD_MEM_WRITE_DWORD, "write encoder dword"}, - {FX2CMD_MEM_READ_DWORD, "read encoder dword"}, - {FX2CMD_HCW_ZILOG_RESET, "zilog IR reset control"}, - {FX2CMD_MEM_READ_64BYTES, "read encoder 64bytes"}, - {FX2CMD_REG_WRITE, "write encoder register"}, - {FX2CMD_REG_READ, "read encoder register"}, - {FX2CMD_MEMSEL, "encoder memsel"}, - {FX2CMD_I2C_WRITE, "i2c write"}, - {FX2CMD_I2C_READ, "i2c read"}, - {FX2CMD_GET_USB_SPEED, "get USB speed"}, - {FX2CMD_STREAMING_ON, "stream on"}, - {FX2CMD_STREAMING_OFF, "stream off"}, - {FX2CMD_FWPOST1, "fwpost1"}, - {FX2CMD_POWER_OFF, "power off"}, - {FX2CMD_POWER_ON, "power on"}, - {FX2CMD_DEEP_RESET, "deep reset"}, - {FX2CMD_GET_EEPROM_ADDR, "get rom addr"}, - {FX2CMD_GET_IR_CODE, "get IR code"}, - {FX2CMD_HCW_DEMOD_RESETIN, "hcw demod resetin"}, - {FX2CMD_HCW_DTV_STREAMING_ON, "hcw dtv stream on"}, - {FX2CMD_HCW_DTV_STREAMING_OFF, "hcw dtv stream off"}, - {FX2CMD_ONAIR_DTV_STREAMING_ON, "onair dtv stream on"}, - {FX2CMD_ONAIR_DTV_STREAMING_OFF, "onair dtv stream off"}, - {FX2CMD_ONAIR_DTV_POWER_ON, "onair dtv power on"}, - {FX2CMD_ONAIR_DTV_POWER_OFF, "onair dtv power off"}, -}; - - -static int pvr2_hdw_set_input(struct pvr2_hdw *hdw,int v); -static void pvr2_hdw_state_sched(struct pvr2_hdw *); -static int pvr2_hdw_state_eval(struct pvr2_hdw *); -static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long); -static void pvr2_hdw_worker_poll(struct work_struct *work); -static int pvr2_hdw_wait(struct pvr2_hdw *,int state); -static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *); -static void pvr2_hdw_state_log_state(struct pvr2_hdw *); -static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl); -static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw); -static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw); -static void pvr2_hdw_quiescent_timeout(unsigned long); -static void pvr2_hdw_decoder_stabilization_timeout(unsigned long); -static void pvr2_hdw_encoder_wait_timeout(unsigned long); -static void pvr2_hdw_encoder_run_timeout(unsigned long); -static int pvr2_issue_simple_cmd(struct pvr2_hdw *,u32); -static int pvr2_send_request_ex(struct pvr2_hdw *hdw, - unsigned int timeout,int probe_fl, - void *write_data,unsigned int write_len, - void *read_data,unsigned int read_len); -static int pvr2_hdw_check_cropcap(struct pvr2_hdw *hdw); -static v4l2_std_id pvr2_hdw_get_detected_std(struct pvr2_hdw *hdw); - -static void trace_stbit(const char *name,int val) -{ - pvr2_trace(PVR2_TRACE_STBITS, - "State bit %s <-- %s", - name,(val ? "true" : "false")); -} - -static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp) -{ - struct pvr2_hdw *hdw = cptr->hdw; - if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) { - *vp = hdw->freqTable[hdw->freqProgSlot-1]; - } else { - *vp = 0; - } - return 0; -} - -static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v) -{ - struct pvr2_hdw *hdw = cptr->hdw; - unsigned int slotId = hdw->freqProgSlot; - if ((slotId > 0) && (slotId <= FREQTABLE_SIZE)) { - hdw->freqTable[slotId-1] = v; - /* Handle side effects correctly - if we're tuned to this - slot, then forgot the slot id relation since the stored - frequency has been changed. */ - if (hdw->freqSelector) { - if (hdw->freqSlotRadio == slotId) { - hdw->freqSlotRadio = 0; - } - } else { - if (hdw->freqSlotTelevision == slotId) { - hdw->freqSlotTelevision = 0; - } - } - } - return 0; -} - -static int ctrl_channelprog_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->freqProgSlot; - return 0; -} - -static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v) -{ - struct pvr2_hdw *hdw = cptr->hdw; - if ((v >= 0) && (v <= FREQTABLE_SIZE)) { - hdw->freqProgSlot = v; - } - return 0; -} - -static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp) -{ - struct pvr2_hdw *hdw = cptr->hdw; - *vp = hdw->freqSelector ? hdw->freqSlotRadio : hdw->freqSlotTelevision; - return 0; -} - -static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int slotId) -{ - unsigned freq = 0; - struct pvr2_hdw *hdw = cptr->hdw; - if ((slotId < 0) || (slotId > FREQTABLE_SIZE)) return 0; - if (slotId > 0) { - freq = hdw->freqTable[slotId-1]; - if (!freq) return 0; - pvr2_hdw_set_cur_freq(hdw,freq); - } - if (hdw->freqSelector) { - hdw->freqSlotRadio = slotId; - } else { - hdw->freqSlotTelevision = slotId; - } - return 0; -} - -static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = pvr2_hdw_get_cur_freq(cptr->hdw); - return 0; -} - -static int ctrl_freq_is_dirty(struct pvr2_ctrl *cptr) -{ - return cptr->hdw->freqDirty != 0; -} - -static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr) -{ - cptr->hdw->freqDirty = 0; -} - -static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v) -{ - pvr2_hdw_set_cur_freq(cptr->hdw,v); - return 0; -} - -static int ctrl_cropl_min_get(struct pvr2_ctrl *cptr, int *left) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *left = cap->bounds.left; - return 0; -} - -static int ctrl_cropl_max_get(struct pvr2_ctrl *cptr, int *left) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *left = cap->bounds.left; - if (cap->bounds.width > cptr->hdw->cropw_val) { - *left += cap->bounds.width - cptr->hdw->cropw_val; - } - return 0; -} - -static int ctrl_cropt_min_get(struct pvr2_ctrl *cptr, int *top) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *top = cap->bounds.top; - return 0; -} - -static int ctrl_cropt_max_get(struct pvr2_ctrl *cptr, int *top) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *top = cap->bounds.top; - if (cap->bounds.height > cptr->hdw->croph_val) { - *top += cap->bounds.height - cptr->hdw->croph_val; - } - return 0; -} - -static int ctrl_cropw_max_get(struct pvr2_ctrl *cptr, int *width) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat, bleftend, cleft; - - stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - bleftend = cap->bounds.left+cap->bounds.width; - cleft = cptr->hdw->cropl_val; - - *width = cleft < bleftend ? bleftend-cleft : 0; - return 0; -} - -static int ctrl_croph_max_get(struct pvr2_ctrl *cptr, int *height) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat, btopend, ctop; - - stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - btopend = cap->bounds.top+cap->bounds.height; - ctop = cptr->hdw->cropt_val; - - *height = ctop < btopend ? btopend-ctop : 0; - return 0; -} - -static int ctrl_get_cropcapbl(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->bounds.left; - return 0; -} - -static int ctrl_get_cropcapbt(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->bounds.top; - return 0; -} - -static int ctrl_get_cropcapbw(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->bounds.width; - return 0; -} - -static int ctrl_get_cropcapbh(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->bounds.height; - return 0; -} - -static int ctrl_get_cropcapdl(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->defrect.left; - return 0; -} - -static int ctrl_get_cropcapdt(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->defrect.top; - return 0; -} - -static int ctrl_get_cropcapdw(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->defrect.width; - return 0; -} - -static int ctrl_get_cropcapdh(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->defrect.height; - return 0; -} - -static int ctrl_get_cropcappan(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->pixelaspect.numerator; - return 0; -} - -static int ctrl_get_cropcappad(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->pixelaspect.denominator; - return 0; -} - -static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp) -{ - /* Actual maximum depends on the video standard in effect. */ - if (cptr->hdw->std_mask_cur & V4L2_STD_525_60) { - *vp = 480; - } else { - *vp = 576; - } - return 0; -} - -static int ctrl_vres_min_get(struct pvr2_ctrl *cptr,int *vp) -{ - /* Actual minimum depends on device digitizer type. */ - if (cptr->hdw->hdw_desc->flag_has_cx25840) { - *vp = 75; - } else { - *vp = 17; - } - return 0; -} - -static int ctrl_get_input(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->input_val; - return 0; -} - -static int ctrl_check_input(struct pvr2_ctrl *cptr,int v) -{ - return ((1 << v) & cptr->hdw->input_allowed_mask) != 0; -} - -static int ctrl_set_input(struct pvr2_ctrl *cptr,int m,int v) -{ - return pvr2_hdw_set_input(cptr->hdw,v); -} - -static int ctrl_isdirty_input(struct pvr2_ctrl *cptr) -{ - return cptr->hdw->input_dirty != 0; -} - -static void ctrl_cleardirty_input(struct pvr2_ctrl *cptr) -{ - cptr->hdw->input_dirty = 0; -} - - -static int ctrl_freq_max_get(struct pvr2_ctrl *cptr, int *vp) -{ - unsigned long fv; - struct pvr2_hdw *hdw = cptr->hdw; - if (hdw->tuner_signal_stale) { - pvr2_hdw_status_poll(hdw); - } - fv = hdw->tuner_signal_info.rangehigh; - if (!fv) { - /* Safety fallback */ - *vp = TV_MAX_FREQ; - return 0; - } - if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) { - fv = (fv * 125) / 2; - } else { - fv = fv * 62500; - } - *vp = fv; - return 0; -} - -static int ctrl_freq_min_get(struct pvr2_ctrl *cptr, int *vp) -{ - unsigned long fv; - struct pvr2_hdw *hdw = cptr->hdw; - if (hdw->tuner_signal_stale) { - pvr2_hdw_status_poll(hdw); - } - fv = hdw->tuner_signal_info.rangelow; - if (!fv) { - /* Safety fallback */ - *vp = TV_MIN_FREQ; - return 0; - } - if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) { - fv = (fv * 125) / 2; - } else { - fv = fv * 62500; - } - *vp = fv; - return 0; -} - -static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr) -{ - return cptr->hdw->enc_stale != 0; -} - -static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr) -{ - cptr->hdw->enc_stale = 0; - cptr->hdw->enc_unsafe_stale = 0; -} - -static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp) -{ - int ret; - struct v4l2_ext_controls cs; - struct v4l2_ext_control c1; - memset(&cs,0,sizeof(cs)); - memset(&c1,0,sizeof(c1)); - cs.controls = &c1; - cs.count = 1; - c1.id = cptr->info->v4l_id; - ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state, 0, &cs, - VIDIOC_G_EXT_CTRLS); - if (ret) return ret; - *vp = c1.value; - return 0; -} - -static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v) -{ - int ret; - struct pvr2_hdw *hdw = cptr->hdw; - struct v4l2_ext_controls cs; - struct v4l2_ext_control c1; - memset(&cs,0,sizeof(cs)); - memset(&c1,0,sizeof(c1)); - cs.controls = &c1; - cs.count = 1; - c1.id = cptr->info->v4l_id; - c1.value = v; - ret = cx2341x_ext_ctrls(&hdw->enc_ctl_state, - hdw->state_encoder_run, &cs, - VIDIOC_S_EXT_CTRLS); - if (ret == -EBUSY) { - /* Oops. cx2341x is telling us it's not safe to change - this control while we're capturing. Make a note of this - fact so that the pipeline will be stopped the next time - controls are committed. Then go on ahead and store this - change anyway. */ - ret = cx2341x_ext_ctrls(&hdw->enc_ctl_state, - 0, &cs, - VIDIOC_S_EXT_CTRLS); - if (!ret) hdw->enc_unsafe_stale = !0; - } - if (ret) return ret; - hdw->enc_stale = !0; - return 0; -} - -static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr) -{ - struct v4l2_queryctrl qctrl; - struct pvr2_ctl_info *info; - qctrl.id = cptr->info->v4l_id; - cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl); - /* Strip out the const so we can adjust a function pointer. It's - OK to do this here because we know this is a dynamically created - control, so the underlying storage for the info pointer is (a) - private to us, and (b) not in read-only storage. Either we do - this or we significantly complicate the underlying control - implementation. */ - info = (struct pvr2_ctl_info *)(cptr->info); - if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) { - if (info->set_value) { - info->set_value = NULL; - } - } else { - if (!(info->set_value)) { - info->set_value = ctrl_cx2341x_set; - } - } - return qctrl.flags; -} - -static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->state_pipeline_req; - return 0; -} - -static int ctrl_masterstate_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->master_state; - return 0; -} - -static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp) -{ - int result = pvr2_hdw_is_hsm(cptr->hdw); - *vp = PVR2_CVAL_HSM_FULL; - if (result < 0) *vp = PVR2_CVAL_HSM_FAIL; - if (result) *vp = PVR2_CVAL_HSM_HIGH; - return 0; -} - -static int ctrl_stddetect_get(struct pvr2_ctrl *cptr, int *vp) -{ - *vp = pvr2_hdw_get_detected_std(cptr->hdw); - return 0; -} - -static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->std_mask_avail; - return 0; -} - -static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v) -{ - struct pvr2_hdw *hdw = cptr->hdw; - v4l2_std_id ns; - ns = hdw->std_mask_avail; - ns = (ns & ~m) | (v & m); - if (ns == hdw->std_mask_avail) return 0; - hdw->std_mask_avail = ns; - hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail; - return 0; -} - -static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val, - char *bufPtr,unsigned int bufSize, - unsigned int *len) -{ - *len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val); - return 0; -} - -static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr, - const char *bufPtr,unsigned int bufSize, - int *mskp,int *valp) -{ - int ret; - v4l2_std_id id; - ret = pvr2_std_str_to_id(&id,bufPtr,bufSize); - if (ret < 0) return ret; - if (mskp) *mskp = id; - if (valp) *valp = id; - return 0; -} - -static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->std_mask_cur; - return 0; -} - -static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v) -{ - struct pvr2_hdw *hdw = cptr->hdw; - v4l2_std_id ns; - ns = hdw->std_mask_cur; - ns = (ns & ~m) | (v & m); - if (ns == hdw->std_mask_cur) return 0; - hdw->std_mask_cur = ns; - hdw->std_dirty = !0; - return 0; -} - -static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr) -{ - return cptr->hdw->std_dirty != 0; -} - -static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr) -{ - cptr->hdw->std_dirty = 0; -} - -static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp) -{ - struct pvr2_hdw *hdw = cptr->hdw; - pvr2_hdw_status_poll(hdw); - *vp = hdw->tuner_signal_info.signal; - return 0; -} - -static int ctrl_audio_modes_present_get(struct pvr2_ctrl *cptr,int *vp) -{ - int val = 0; - unsigned int subchan; - struct pvr2_hdw *hdw = cptr->hdw; - pvr2_hdw_status_poll(hdw); - subchan = hdw->tuner_signal_info.rxsubchans; - if (subchan & V4L2_TUNER_SUB_MONO) { - val |= (1 << V4L2_TUNER_MODE_MONO); - } - if (subchan & V4L2_TUNER_SUB_STEREO) { - val |= (1 << V4L2_TUNER_MODE_STEREO); - } - if (subchan & V4L2_TUNER_SUB_LANG1) { - val |= (1 << V4L2_TUNER_MODE_LANG1); - } - if (subchan & V4L2_TUNER_SUB_LANG2) { - val |= (1 << V4L2_TUNER_MODE_LANG2); - } - *vp = val; - return 0; -} - - -#define DEFINT(vmin,vmax) \ - .type = pvr2_ctl_int, \ - .def.type_int.min_value = vmin, \ - .def.type_int.max_value = vmax - -#define DEFENUM(tab) \ - .type = pvr2_ctl_enum, \ - .def.type_enum.count = ARRAY_SIZE(tab), \ - .def.type_enum.value_names = tab - -#define DEFBOOL \ - .type = pvr2_ctl_bool - -#define DEFMASK(msk,tab) \ - .type = pvr2_ctl_bitmask, \ - .def.type_bitmask.valid_bits = msk, \ - .def.type_bitmask.bit_names = tab - -#define DEFREF(vname) \ - .set_value = ctrl_set_##vname, \ - .get_value = ctrl_get_##vname, \ - .is_dirty = ctrl_isdirty_##vname, \ - .clear_dirty = ctrl_cleardirty_##vname - - -#define VCREATE_FUNCS(vname) \ -static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \ -{*vp = cptr->hdw->vname##_val; return 0;} \ -static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \ -{cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \ -static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \ -{return cptr->hdw->vname##_dirty != 0;} \ -static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \ -{cptr->hdw->vname##_dirty = 0;} - -VCREATE_FUNCS(brightness) -VCREATE_FUNCS(contrast) -VCREATE_FUNCS(saturation) -VCREATE_FUNCS(hue) -VCREATE_FUNCS(volume) -VCREATE_FUNCS(balance) -VCREATE_FUNCS(bass) -VCREATE_FUNCS(treble) -VCREATE_FUNCS(mute) -VCREATE_FUNCS(cropl) -VCREATE_FUNCS(cropt) -VCREATE_FUNCS(cropw) -VCREATE_FUNCS(croph) -VCREATE_FUNCS(audiomode) -VCREATE_FUNCS(res_hor) -VCREATE_FUNCS(res_ver) -VCREATE_FUNCS(srate) - -/* Table definition of all controls which can be manipulated */ -static const struct pvr2_ctl_info control_defs[] = { - { - .v4l_id = V4L2_CID_BRIGHTNESS, - .desc = "Brightness", - .name = "brightness", - .default_value = 128, - DEFREF(brightness), - DEFINT(0,255), - },{ - .v4l_id = V4L2_CID_CONTRAST, - .desc = "Contrast", - .name = "contrast", - .default_value = 68, - DEFREF(contrast), - DEFINT(0,127), - },{ - .v4l_id = V4L2_CID_SATURATION, - .desc = "Saturation", - .name = "saturation", - .default_value = 64, - DEFREF(saturation), - DEFINT(0,127), - },{ - .v4l_id = V4L2_CID_HUE, - .desc = "Hue", - .name = "hue", - .default_value = 0, - DEFREF(hue), - DEFINT(-128,127), - },{ - .v4l_id = V4L2_CID_AUDIO_VOLUME, - .desc = "Volume", - .name = "volume", - .default_value = 62000, - DEFREF(volume), - DEFINT(0,65535), - },{ - .v4l_id = V4L2_CID_AUDIO_BALANCE, - .desc = "Balance", - .name = "balance", - .default_value = 0, - DEFREF(balance), - DEFINT(-32768,32767), - },{ - .v4l_id = V4L2_CID_AUDIO_BASS, - .desc = "Bass", - .name = "bass", - .default_value = 0, - DEFREF(bass), - DEFINT(-32768,32767), - },{ - .v4l_id = V4L2_CID_AUDIO_TREBLE, - .desc = "Treble", - .name = "treble", - .default_value = 0, - DEFREF(treble), - DEFINT(-32768,32767), - },{ - .v4l_id = V4L2_CID_AUDIO_MUTE, - .desc = "Mute", - .name = "mute", - .default_value = 0, - DEFREF(mute), - DEFBOOL, - }, { - .desc = "Capture crop left margin", - .name = "crop_left", - .internal_id = PVR2_CID_CROPL, - .default_value = 0, - DEFREF(cropl), - DEFINT(-129, 340), - .get_min_value = ctrl_cropl_min_get, - .get_max_value = ctrl_cropl_max_get, - .get_def_value = ctrl_get_cropcapdl, - }, { - .desc = "Capture crop top margin", - .name = "crop_top", - .internal_id = PVR2_CID_CROPT, - .default_value = 0, - DEFREF(cropt), - DEFINT(-35, 544), - .get_min_value = ctrl_cropt_min_get, - .get_max_value = ctrl_cropt_max_get, - .get_def_value = ctrl_get_cropcapdt, - }, { - .desc = "Capture crop width", - .name = "crop_width", - .internal_id = PVR2_CID_CROPW, - .default_value = 720, - DEFREF(cropw), - DEFINT(0, 864), - .get_max_value = ctrl_cropw_max_get, - .get_def_value = ctrl_get_cropcapdw, - }, { - .desc = "Capture crop height", - .name = "crop_height", - .internal_id = PVR2_CID_CROPH, - .default_value = 480, - DEFREF(croph), - DEFINT(0, 576), - .get_max_value = ctrl_croph_max_get, - .get_def_value = ctrl_get_cropcapdh, - }, { - .desc = "Capture capability pixel aspect numerator", - .name = "cropcap_pixel_numerator", - .internal_id = PVR2_CID_CROPCAPPAN, - .get_value = ctrl_get_cropcappan, - }, { - .desc = "Capture capability pixel aspect denominator", - .name = "cropcap_pixel_denominator", - .internal_id = PVR2_CID_CROPCAPPAD, - .get_value = ctrl_get_cropcappad, - }, { - .desc = "Capture capability bounds top", - .name = "cropcap_bounds_top", - .internal_id = PVR2_CID_CROPCAPBT, - .get_value = ctrl_get_cropcapbt, - }, { - .desc = "Capture capability bounds left", - .name = "cropcap_bounds_left", - .internal_id = PVR2_CID_CROPCAPBL, - .get_value = ctrl_get_cropcapbl, - }, { - .desc = "Capture capability bounds width", - .name = "cropcap_bounds_width", - .internal_id = PVR2_CID_CROPCAPBW, - .get_value = ctrl_get_cropcapbw, - }, { - .desc = "Capture capability bounds height", - .name = "cropcap_bounds_height", - .internal_id = PVR2_CID_CROPCAPBH, - .get_value = ctrl_get_cropcapbh, - },{ - .desc = "Video Source", - .name = "input", - .internal_id = PVR2_CID_INPUT, - .default_value = PVR2_CVAL_INPUT_TV, - .check_value = ctrl_check_input, - DEFREF(input), - DEFENUM(control_values_input), - },{ - .desc = "Audio Mode", - .name = "audio_mode", - .internal_id = PVR2_CID_AUDIOMODE, - .default_value = V4L2_TUNER_MODE_STEREO, - DEFREF(audiomode), - DEFENUM(control_values_audiomode), - },{ - .desc = "Horizontal capture resolution", - .name = "resolution_hor", - .internal_id = PVR2_CID_HRES, - .default_value = 720, - DEFREF(res_hor), - DEFINT(19,720), - },{ - .desc = "Vertical capture resolution", - .name = "resolution_ver", - .internal_id = PVR2_CID_VRES, - .default_value = 480, - DEFREF(res_ver), - DEFINT(17,576), - /* Hook in check for video standard and adjust maximum - depending on the standard. */ - .get_max_value = ctrl_vres_max_get, - .get_min_value = ctrl_vres_min_get, - },{ - .v4l_id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ, - .default_value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, - .desc = "Audio Sampling Frequency", - .name = "srate", - DEFREF(srate), - DEFENUM(control_values_srate), - },{ - .desc = "Tuner Frequency (Hz)", - .name = "frequency", - .internal_id = PVR2_CID_FREQUENCY, - .default_value = 0, - .set_value = ctrl_freq_set, - .get_value = ctrl_freq_get, - .is_dirty = ctrl_freq_is_dirty, - .clear_dirty = ctrl_freq_clear_dirty, - DEFINT(0,0), - /* Hook in check for input value (tv/radio) and adjust - max/min values accordingly */ - .get_max_value = ctrl_freq_max_get, - .get_min_value = ctrl_freq_min_get, - },{ - .desc = "Channel", - .name = "channel", - .set_value = ctrl_channel_set, - .get_value = ctrl_channel_get, - DEFINT(0,FREQTABLE_SIZE), - },{ - .desc = "Channel Program Frequency", - .name = "freq_table_value", - .set_value = ctrl_channelfreq_set, - .get_value = ctrl_channelfreq_get, - DEFINT(0,0), - /* Hook in check for input value (tv/radio) and adjust - max/min values accordingly */ - .get_max_value = ctrl_freq_max_get, - .get_min_value = ctrl_freq_min_get, - },{ - .desc = "Channel Program ID", - .name = "freq_table_channel", - .set_value = ctrl_channelprog_set, - .get_value = ctrl_channelprog_get, - DEFINT(0,FREQTABLE_SIZE), - },{ - .desc = "Streaming Enabled", - .name = "streaming_enabled", - .get_value = ctrl_streamingenabled_get, - DEFBOOL, - },{ - .desc = "USB Speed", - .name = "usb_speed", - .get_value = ctrl_hsm_get, - DEFENUM(control_values_hsm), - },{ - .desc = "Master State", - .name = "master_state", - .get_value = ctrl_masterstate_get, - DEFENUM(pvr2_state_names), - },{ - .desc = "Signal Present", - .name = "signal_present", - .get_value = ctrl_signal_get, - DEFINT(0,65535), - },{ - .desc = "Audio Modes Present", - .name = "audio_modes_present", - .get_value = ctrl_audio_modes_present_get, - /* For this type we "borrow" the V4L2_TUNER_MODE enum from - v4l. Nothing outside of this module cares about this, - but I reuse it in order to also reuse the - control_values_audiomode string table. */ - DEFMASK(((1 << V4L2_TUNER_MODE_MONO)| - (1 << V4L2_TUNER_MODE_STEREO)| - (1 << V4L2_TUNER_MODE_LANG1)| - (1 << V4L2_TUNER_MODE_LANG2)), - control_values_audiomode), - },{ - .desc = "Video Standards Available Mask", - .name = "video_standard_mask_available", - .internal_id = PVR2_CID_STDAVAIL, - .skip_init = !0, - .get_value = ctrl_stdavail_get, - .set_value = ctrl_stdavail_set, - .val_to_sym = ctrl_std_val_to_sym, - .sym_to_val = ctrl_std_sym_to_val, - .type = pvr2_ctl_bitmask, - },{ - .desc = "Video Standards In Use Mask", - .name = "video_standard_mask_active", - .internal_id = PVR2_CID_STDCUR, - .skip_init = !0, - .get_value = ctrl_stdcur_get, - .set_value = ctrl_stdcur_set, - .is_dirty = ctrl_stdcur_is_dirty, - .clear_dirty = ctrl_stdcur_clear_dirty, - .val_to_sym = ctrl_std_val_to_sym, - .sym_to_val = ctrl_std_sym_to_val, - .type = pvr2_ctl_bitmask, - },{ - .desc = "Video Standards Detected Mask", - .name = "video_standard_mask_detected", - .internal_id = PVR2_CID_STDDETECT, - .skip_init = !0, - .get_value = ctrl_stddetect_get, - .val_to_sym = ctrl_std_val_to_sym, - .sym_to_val = ctrl_std_sym_to_val, - .type = pvr2_ctl_bitmask, - } -}; - -#define CTRLDEF_COUNT ARRAY_SIZE(control_defs) - - -const char *pvr2_config_get_name(enum pvr2_config cfg) -{ - switch (cfg) { - case pvr2_config_empty: return "empty"; - case pvr2_config_mpeg: return "mpeg"; - case pvr2_config_vbi: return "vbi"; - case pvr2_config_pcm: return "pcm"; - case pvr2_config_rawvideo: return "raw video"; - } - return "<unknown>"; -} - - -struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *hdw) -{ - return hdw->usb_dev; -} - - -unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw) -{ - return hdw->serial_number; -} - - -const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *hdw) -{ - return hdw->bus_info; -} - - -const char *pvr2_hdw_get_device_identifier(struct pvr2_hdw *hdw) -{ - return hdw->identifier; -} - - -unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw) -{ - return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio; -} - -/* Set the currently tuned frequency and account for all possible - driver-core side effects of this action. */ -static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *hdw,unsigned long val) -{ - if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) { - if (hdw->freqSelector) { - /* Swing over to radio frequency selection */ - hdw->freqSelector = 0; - hdw->freqDirty = !0; - } - if (hdw->freqValRadio != val) { - hdw->freqValRadio = val; - hdw->freqSlotRadio = 0; - hdw->freqDirty = !0; - } - } else { - if (!(hdw->freqSelector)) { - /* Swing over to television frequency selection */ - hdw->freqSelector = 1; - hdw->freqDirty = !0; - } - if (hdw->freqValTelevision != val) { - hdw->freqValTelevision = val; - hdw->freqSlotTelevision = 0; - hdw->freqDirty = !0; - } - } -} - -int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw) -{ - return hdw->unit_number; -} - - -/* Attempt to locate one of the given set of files. Messages are logged - appropriate to what has been found. The return value will be 0 or - greater on success (it will be the index of the file name found) and - fw_entry will be filled in. Otherwise a negative error is returned on - failure. If the return value is -ENOENT then no viable firmware file - could be located. */ -static int pvr2_locate_firmware(struct pvr2_hdw *hdw, - const struct firmware **fw_entry, - const char *fwtypename, - unsigned int fwcount, - const char *fwnames[]) -{ - unsigned int idx; - int ret = -EINVAL; - for (idx = 0; idx < fwcount; idx++) { - ret = request_firmware(fw_entry, - fwnames[idx], - &hdw->usb_dev->dev); - if (!ret) { - trace_firmware("Located %s firmware: %s;" - " uploading...", - fwtypename, - fwnames[idx]); - return idx; - } - if (ret == -ENOENT) continue; - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "request_firmware fatal error with code=%d",ret); - return ret; - } - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "***WARNING***" - " Device %s firmware" - " seems to be missing.", - fwtypename); - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Did you install the pvrusb2 firmware files" - " in their proper location?"); - if (fwcount == 1) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "request_firmware unable to locate %s file %s", - fwtypename,fwnames[0]); - } else { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "request_firmware unable to locate" - " one of the following %s files:", - fwtypename); - for (idx = 0; idx < fwcount; idx++) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "request_firmware: Failed to find %s", - fwnames[idx]); - } - } - return ret; -} - - -/* - * pvr2_upload_firmware1(). - * - * Send the 8051 firmware to the device. After the upload, arrange for - * device to re-enumerate. - * - * NOTE : the pointer to the firmware data given by request_firmware() - * is not suitable for an usb transaction. - * - */ -static int pvr2_upload_firmware1(struct pvr2_hdw *hdw) -{ - const struct firmware *fw_entry = NULL; - void *fw_ptr; - unsigned int pipe; - unsigned int fwsize; - int ret; - u16 address; - - if (!hdw->hdw_desc->fx2_firmware.cnt) { - hdw->fw1_state = FW1_STATE_OK; - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Connected device type defines" - " no firmware to upload; ignoring firmware"); - return -ENOTTY; - } - - hdw->fw1_state = FW1_STATE_FAILED; // default result - - trace_firmware("pvr2_upload_firmware1"); - - ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller", - hdw->hdw_desc->fx2_firmware.cnt, - hdw->hdw_desc->fx2_firmware.lst); - if (ret < 0) { - if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING; - return ret; - } - - usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f)); - - pipe = usb_sndctrlpipe(hdw->usb_dev, 0); - fwsize = fw_entry->size; - - if ((fwsize != 0x2000) && - (!(hdw->hdw_desc->flag_fx2_16kb && (fwsize == 0x4000)))) { - if (hdw->hdw_desc->flag_fx2_16kb) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Wrong fx2 firmware size" - " (expected 8192 or 16384, got %u)", - fwsize); - } else { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Wrong fx2 firmware size" - " (expected 8192, got %u)", - fwsize); - } - release_firmware(fw_entry); - return -ENOMEM; - } - - fw_ptr = kmalloc(0x800, GFP_KERNEL); - if (fw_ptr == NULL){ - release_firmware(fw_entry); - return -ENOMEM; - } - - /* We have to hold the CPU during firmware upload. */ - pvr2_hdw_cpureset_assert(hdw,1); - - /* upload the firmware to address 0000-1fff in 2048 (=0x800) bytes - chunk. */ - - ret = 0; - for (address = 0; address < fwsize; address += 0x800) { - memcpy(fw_ptr, fw_entry->data + address, 0x800); - ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address, - 0, fw_ptr, 0x800, HZ); - } - - trace_firmware("Upload done, releasing device's CPU"); - - /* Now release the CPU. It will disconnect and reconnect later. */ - pvr2_hdw_cpureset_assert(hdw,0); - - kfree(fw_ptr); - release_firmware(fw_entry); - - trace_firmware("Upload done (%d bytes sent)",ret); - - /* We should have written fwsize bytes */ - if (ret == fwsize) { - hdw->fw1_state = FW1_STATE_RELOAD; - return 0; - } - - return -EIO; -} - - -/* - * pvr2_upload_firmware2() - * - * This uploads encoder firmware on endpoint 2. - * - */ - -int pvr2_upload_firmware2(struct pvr2_hdw *hdw) -{ - const struct firmware *fw_entry = NULL; - void *fw_ptr; - unsigned int pipe, fw_len, fw_done, bcnt, icnt; - int actual_length; - int ret = 0; - int fwidx; - static const char *fw_files[] = { - CX2341X_FIRM_ENC_FILENAME, - }; - - if (hdw->hdw_desc->flag_skip_cx23416_firmware) { - return 0; - } - - trace_firmware("pvr2_upload_firmware2"); - - ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder", - ARRAY_SIZE(fw_files), fw_files); - if (ret < 0) return ret; - fwidx = ret; - ret = 0; - /* Since we're about to completely reinitialize the encoder, - invalidate our cached copy of its configuration state. Next - time we configure the encoder, then we'll fully configure it. */ - hdw->enc_cur_valid = 0; - - /* Encoder is about to be reset so note that as far as we're - concerned now, the encoder has never been run. */ - del_timer_sync(&hdw->encoder_run_timer); - if (hdw->state_encoder_runok) { - hdw->state_encoder_runok = 0; - trace_stbit("state_encoder_runok",hdw->state_encoder_runok); - } - - /* First prepare firmware loading */ - ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/ - ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/ - ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/ - ret |= pvr2_hdw_cmd_deep_reset(hdw); - ret |= pvr2_write_register(hdw, 0xa064, 0x00000000); /*APU command*/ - ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000408); /*gpio dir*/ - ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/ - ret |= pvr2_write_register(hdw, 0x9058, 0xffffffed); /*VPU ctrl*/ - ret |= pvr2_write_register(hdw, 0x9054, 0xfffffffd); /*reset hw blocks*/ - ret |= pvr2_write_register(hdw, 0x07f8, 0x80000800); /*encoder SDRAM refresh*/ - ret |= pvr2_write_register(hdw, 0x07fc, 0x0000001a); /*encoder SDRAM pre-charge*/ - ret |= pvr2_write_register(hdw, 0x0700, 0x00000000); /*I2C clock*/ - ret |= pvr2_write_register(hdw, 0xaa00, 0x00000000); /*unknown*/ - ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/ - ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/ - ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/ - ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_FWPOST1); - ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_MEMSEL | (1 << 8) | (0 << 16)); - - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "firmware2 upload prep failed, ret=%d",ret); - release_firmware(fw_entry); - goto done; - } - - /* Now send firmware */ - - fw_len = fw_entry->size; - - if (fw_len % sizeof(u32)) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "size of %s firmware" - " must be a multiple of %zu bytes", - fw_files[fwidx],sizeof(u32)); - release_firmware(fw_entry); - ret = -EINVAL; - goto done; - } - - fw_ptr = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL); - if (fw_ptr == NULL){ - release_firmware(fw_entry); - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "failed to allocate memory for firmware2 upload"); - ret = -ENOMEM; - goto done; - } - - pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT); - - fw_done = 0; - for (fw_done = 0; fw_done < fw_len;) { - bcnt = fw_len - fw_done; - if (bcnt > FIRMWARE_CHUNK_SIZE) bcnt = FIRMWARE_CHUNK_SIZE; - memcpy(fw_ptr, fw_entry->data + fw_done, bcnt); - /* Usbsnoop log shows that we must swap bytes... */ - /* Some background info: The data being swapped here is a - firmware image destined for the mpeg encoder chip that - lives at the other end of a USB endpoint. The encoder - chip always talks in 32 bit chunks and its storage is - organized into 32 bit words. However from the file - system to the encoder chip everything is purely a byte - stream. The firmware file's contents are always 32 bit - swapped from what the encoder expects. Thus the need - always exists to swap the bytes regardless of the endian - type of the host processor and therefore swab32() makes - the most sense. */ - for (icnt = 0; icnt < bcnt/4 ; icnt++) - ((u32 *)fw_ptr)[icnt] = swab32(((u32 *)fw_ptr)[icnt]); - - ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt, - &actual_length, HZ); - ret |= (actual_length != bcnt); - if (ret) break; - fw_done += bcnt; - } - - trace_firmware("upload of %s : %i / %i ", - fw_files[fwidx],fw_done,fw_len); - - kfree(fw_ptr); - release_firmware(fw_entry); - - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "firmware2 upload transfer failure"); - goto done; - } - - /* Finish upload */ - - ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/ - ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/ - ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_MEMSEL | (1 << 8) | (0 << 16)); - - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "firmware2 upload post-proc failure"); - } - - done: - if (hdw->hdw_desc->signal_routing_scheme == - PVR2_ROUTING_SCHEME_GOTVIEW) { - /* Ensure that GPIO 11 is set to output for GOTVIEW - hardware. */ - pvr2_hdw_gpio_chg_dir(hdw,(1 << 11),~0); - } - return ret; -} - - -static const char *pvr2_get_state_name(unsigned int st) -{ - if (st < ARRAY_SIZE(pvr2_state_names)) { - return pvr2_state_names[st]; - } - return "???"; -} - -static int pvr2_decoder_enable(struct pvr2_hdw *hdw,int enablefl) -{ - /* Even though we really only care about the video decoder chip at - this point, we'll broadcast stream on/off to all sub-devices - anyway, just in case somebody else wants to hear the - command... */ - pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 stream=%s", - (enablefl ? "on" : "off")); - v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_stream, enablefl); - v4l2_device_call_all(&hdw->v4l2_dev, 0, audio, s_stream, enablefl); - if (hdw->decoder_client_id) { - /* We get here if the encoder has been noticed. Otherwise - we'll issue a warning to the user (which should - normally never happen). */ - return 0; - } - if (!hdw->flag_decoder_missed) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "WARNING: No decoder present"); - hdw->flag_decoder_missed = !0; - trace_stbit("flag_decoder_missed", - hdw->flag_decoder_missed); - } - return -EIO; -} - - -int pvr2_hdw_get_state(struct pvr2_hdw *hdw) -{ - return hdw->master_state; -} - - -static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *hdw) -{ - if (!hdw->flag_tripped) return 0; - hdw->flag_tripped = 0; - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Clearing driver error statuss"); - return !0; -} - - -int pvr2_hdw_untrip(struct pvr2_hdw *hdw) -{ - int fl; - LOCK_TAKE(hdw->big_lock); do { - fl = pvr2_hdw_untrip_unlocked(hdw); - } while (0); LOCK_GIVE(hdw->big_lock); - if (fl) pvr2_hdw_state_sched(hdw); - return 0; -} - - - - -int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw) -{ - return hdw->state_pipeline_req != 0; -} - - -int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag) -{ - int ret,st; - LOCK_TAKE(hdw->big_lock); do { - pvr2_hdw_untrip_unlocked(hdw); - if ((!enable_flag) != !(hdw->state_pipeline_req)) { - hdw->state_pipeline_req = enable_flag != 0; - pvr2_trace(PVR2_TRACE_START_STOP, - "/*--TRACE_STREAM--*/ %s", - enable_flag ? "enable" : "disable"); - } - pvr2_hdw_state_sched(hdw); - } while (0); LOCK_GIVE(hdw->big_lock); - if ((ret = pvr2_hdw_wait(hdw,0)) < 0) return ret; - if (enable_flag) { - while ((st = hdw->master_state) != PVR2_STATE_RUN) { - if (st != PVR2_STATE_READY) return -EIO; - if ((ret = pvr2_hdw_wait(hdw,st)) < 0) return ret; - } - } - return 0; -} - - -int pvr2_hdw_set_stream_type(struct pvr2_hdw *hdw,enum pvr2_config config) -{ - int fl; - LOCK_TAKE(hdw->big_lock); - if ((fl = (hdw->desired_stream_type != config)) != 0) { - hdw->desired_stream_type = config; - hdw->state_pipeline_config = 0; - trace_stbit("state_pipeline_config", - hdw->state_pipeline_config); - pvr2_hdw_state_sched(hdw); - } - LOCK_GIVE(hdw->big_lock); - if (fl) return 0; - return pvr2_hdw_wait(hdw,0); -} - - -static int get_default_tuner_type(struct pvr2_hdw *hdw) -{ - int unit_number = hdw->unit_number; - int tp = -1; - if ((unit_number >= 0) && (unit_number < PVR_NUM)) { - tp = tuner[unit_number]; - } - if (tp < 0) return -EINVAL; - hdw->tuner_type = tp; - hdw->tuner_updated = !0; - return 0; -} - - -static v4l2_std_id get_default_standard(struct pvr2_hdw *hdw) -{ - int unit_number = hdw->unit_number; - int tp = 0; - if ((unit_number >= 0) && (unit_number < PVR_NUM)) { - tp = video_std[unit_number]; - if (tp) return tp; - } - return 0; -} - - -static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw) -{ - int unit_number = hdw->unit_number; - int tp = 0; - if ((unit_number >= 0) && (unit_number < PVR_NUM)) { - tp = tolerance[unit_number]; - } - return tp; -} - - -static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw) -{ - /* Try a harmless request to fetch the eeprom's address over - endpoint 1. See what happens. Only the full FX2 image can - respond to this. If this probe fails then likely the FX2 - firmware needs be loaded. */ - int result; - LOCK_TAKE(hdw->ctl_lock); do { - hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR; - result = pvr2_send_request_ex(hdw,HZ*1,!0, - hdw->cmd_buffer,1, - hdw->cmd_buffer,1); - if (result < 0) break; - } while(0); LOCK_GIVE(hdw->ctl_lock); - if (result) { - pvr2_trace(PVR2_TRACE_INIT, - "Probe of device endpoint 1 result status %d", - result); - } else { - pvr2_trace(PVR2_TRACE_INIT, - "Probe of device endpoint 1 succeeded"); - } - return result == 0; -} - -struct pvr2_std_hack { - v4l2_std_id pat; /* Pattern to match */ - v4l2_std_id msk; /* Which bits we care about */ - v4l2_std_id std; /* What additional standards or default to set */ -}; - -/* This data structure labels specific combinations of standards from - tveeprom that we'll try to recognize. If we recognize one, then assume - a specified default standard to use. This is here because tveeprom only - tells us about available standards not the intended default standard (if - any) for the device in question. We guess the default based on what has - been reported as available. Note that this is only for guessing a - default - which can always be overridden explicitly - and if the user - has otherwise named a default then that default will always be used in - place of this table. */ -static const struct pvr2_std_hack std_eeprom_maps[] = { - { /* PAL(B/G) */ - .pat = V4L2_STD_B|V4L2_STD_GH, - .std = V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_PAL_G, - }, - { /* NTSC(M) */ - .pat = V4L2_STD_MN, - .std = V4L2_STD_NTSC_M, - }, - { /* PAL(I) */ - .pat = V4L2_STD_PAL_I, - .std = V4L2_STD_PAL_I, - }, - { /* SECAM(L/L') */ - .pat = V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC, - .std = V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC, - }, - { /* PAL(D/D1/K) */ - .pat = V4L2_STD_DK, - .std = V4L2_STD_PAL_D|V4L2_STD_PAL_D1|V4L2_STD_PAL_K, - }, -}; - -static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw) -{ - char buf[40]; - unsigned int bcnt; - v4l2_std_id std1,std2,std3; - - std1 = get_default_standard(hdw); - std3 = std1 ? 0 : hdw->hdw_desc->default_std_mask; - - bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom); - pvr2_trace(PVR2_TRACE_STD, - "Supported video standard(s) reported available" - " in hardware: %.*s", - bcnt,buf); - - hdw->std_mask_avail = hdw->std_mask_eeprom; - - std2 = (std1|std3) & ~hdw->std_mask_avail; - if (std2) { - bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2); - pvr2_trace(PVR2_TRACE_STD, - "Expanding supported video standards" - " to include: %.*s", - bcnt,buf); - hdw->std_mask_avail |= std2; - } - - hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail; - - if (std1) { - bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1); - pvr2_trace(PVR2_TRACE_STD, - "Initial video standard forced to %.*s", - bcnt,buf); - hdw->std_mask_cur = std1; - hdw->std_dirty = !0; - return; - } - if (std3) { - bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std3); - pvr2_trace(PVR2_TRACE_STD, - "Initial video standard" - " (determined by device type): %.*s",bcnt,buf); - hdw->std_mask_cur = std3; - hdw->std_dirty = !0; - return; - } - - { - unsigned int idx; - for (idx = 0; idx < ARRAY_SIZE(std_eeprom_maps); idx++) { - if (std_eeprom_maps[idx].msk ? - ((std_eeprom_maps[idx].pat ^ - hdw->std_mask_eeprom) & - std_eeprom_maps[idx].msk) : - (std_eeprom_maps[idx].pat != - hdw->std_mask_eeprom)) continue; - bcnt = pvr2_std_id_to_str(buf,sizeof(buf), - std_eeprom_maps[idx].std); - pvr2_trace(PVR2_TRACE_STD, - "Initial video standard guessed as %.*s", - bcnt,buf); - hdw->std_mask_cur = std_eeprom_maps[idx].std; - hdw->std_dirty = !0; - return; - } - } - -} - - -static unsigned int pvr2_copy_i2c_addr_list( - unsigned short *dst, const unsigned char *src, - unsigned int dst_max) -{ - unsigned int cnt = 0; - if (!src) return 0; - while (src[cnt] && (cnt + 1) < dst_max) { - dst[cnt] = src[cnt]; - cnt++; - } - dst[cnt] = I2C_CLIENT_END; - return cnt; -} - - -static void pvr2_hdw_cx25840_vbi_hack(struct pvr2_hdw *hdw) -{ - /* - Mike Isely <isely@pobox.com> 19-Nov-2006 - This bit of nuttiness - for cx25840 causes that module to correctly set up its video - scaling. This is really a problem in the cx25840 module itself, - but we work around it here. The problem has not been seen in - ivtv because there VBI is supported and set up. We don't do VBI - here (at least not yet) and thus we never attempted to even set - it up. - */ - struct v4l2_format fmt; - if (hdw->decoder_client_id != PVR2_CLIENT_ID_CX25840) { - /* We're not using a cx25840 so don't enable the hack */ - return; - } - - pvr2_trace(PVR2_TRACE_INIT, - "Module ID %u:" - " Executing cx25840 VBI hack", - hdw->decoder_client_id); - memset(&fmt, 0, sizeof(fmt)); - fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; - fmt.fmt.sliced.service_lines[0][21] = V4L2_SLICED_CAPTION_525; - fmt.fmt.sliced.service_lines[1][21] = V4L2_SLICED_CAPTION_525; - v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id, - vbi, s_sliced_fmt, &fmt.fmt.sliced); -} - - -static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw, - const struct pvr2_device_client_desc *cd) -{ - const char *fname; - unsigned char mid; - struct v4l2_subdev *sd; - unsigned int i2ccnt; - const unsigned char *p; - /* Arbitrary count - max # i2c addresses we will probe */ - unsigned short i2caddr[25]; - - mid = cd->module_id; - fname = (mid < ARRAY_SIZE(module_names)) ? module_names[mid] : NULL; - if (!fname) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Module ID %u for device %s has no name?" - " The driver might have a configuration problem.", - mid, - hdw->hdw_desc->description); - return -EINVAL; - } - pvr2_trace(PVR2_TRACE_INIT, - "Module ID %u (%s) for device %s being loaded...", - mid, fname, - hdw->hdw_desc->description); - - i2ccnt = pvr2_copy_i2c_addr_list(i2caddr, cd->i2c_address_list, - ARRAY_SIZE(i2caddr)); - if (!i2ccnt && ((p = (mid < ARRAY_SIZE(module_i2c_addresses)) ? - module_i2c_addresses[mid] : NULL) != NULL)) { - /* Second chance: Try default i2c address list */ - i2ccnt = pvr2_copy_i2c_addr_list(i2caddr, p, - ARRAY_SIZE(i2caddr)); - if (i2ccnt) { - pvr2_trace(PVR2_TRACE_INIT, - "Module ID %u:" - " Using default i2c address list", - mid); - } - } - - if (!i2ccnt) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Module ID %u (%s) for device %s:" - " No i2c addresses." - " The driver might have a configuration problem.", - mid, fname, hdw->hdw_desc->description); - return -EINVAL; - } - - if (i2ccnt == 1) { - pvr2_trace(PVR2_TRACE_INIT, - "Module ID %u:" - " Setting up with specified i2c address 0x%x", - mid, i2caddr[0]); - sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap, - fname, i2caddr[0], NULL); - } else { - pvr2_trace(PVR2_TRACE_INIT, - "Module ID %u:" - " Setting up with address probe list", - mid); - sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap, - fname, 0, i2caddr); - } - - if (!sd) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Module ID %u (%s) for device %s failed to load." - " Possible missing sub-device kernel module or" - " initialization failure within module.", - mid, fname, hdw->hdw_desc->description); - return -EIO; - } - - /* Tag this sub-device instance with the module ID we know about. - In other places we'll use that tag to determine if the instance - requires special handling. */ - sd->grp_id = mid; - - pvr2_trace(PVR2_TRACE_INFO, "Attached sub-driver %s", fname); - - - /* client-specific setup... */ - switch (mid) { - case PVR2_CLIENT_ID_CX25840: - case PVR2_CLIENT_ID_SAA7115: - hdw->decoder_client_id = mid; - break; - default: break; - } - - return 0; -} - - -static void pvr2_hdw_load_modules(struct pvr2_hdw *hdw) -{ - unsigned int idx; - const struct pvr2_string_table *cm; - const struct pvr2_device_client_table *ct; - int okFl = !0; - - cm = &hdw->hdw_desc->client_modules; - for (idx = 0; idx < cm->cnt; idx++) { - request_module(cm->lst[idx]); - } - - ct = &hdw->hdw_desc->client_table; - for (idx = 0; idx < ct->cnt; idx++) { - if (pvr2_hdw_load_subdev(hdw, &ct->lst[idx]) < 0) okFl = 0; - } - if (!okFl) { - hdw->flag_modulefail = !0; - pvr2_hdw_render_useless(hdw); - } -} - - -static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) -{ - int ret; - unsigned int idx; - struct pvr2_ctrl *cptr; - int reloadFl = 0; - if (hdw->hdw_desc->fx2_firmware.cnt) { - if (!reloadFl) { - reloadFl = - (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints - == 0); - if (reloadFl) { - pvr2_trace(PVR2_TRACE_INIT, - "USB endpoint config looks strange" - "; possibly firmware needs to be" - " loaded"); - } - } - if (!reloadFl) { - reloadFl = !pvr2_hdw_check_firmware(hdw); - if (reloadFl) { - pvr2_trace(PVR2_TRACE_INIT, - "Check for FX2 firmware failed" - "; possibly firmware needs to be" - " loaded"); - } - } - if (reloadFl) { - if (pvr2_upload_firmware1(hdw) != 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failure uploading firmware1"); - } - return; - } - } - hdw->fw1_state = FW1_STATE_OK; - - if (!pvr2_hdw_dev_ok(hdw)) return; - - hdw->force_dirty = !0; - - if (!hdw->hdw_desc->flag_no_powerup) { - pvr2_hdw_cmd_powerup(hdw); - if (!pvr2_hdw_dev_ok(hdw)) return; - } - - /* Take the IR chip out of reset, if appropriate */ - if (hdw->ir_scheme_active == PVR2_IR_SCHEME_ZILOG) { - pvr2_issue_simple_cmd(hdw, - FX2CMD_HCW_ZILOG_RESET | - (1 << 8) | - ((0) << 16)); - } - - // This step MUST happen after the earlier powerup step. - pvr2_i2c_core_init(hdw); - if (!pvr2_hdw_dev_ok(hdw)) return; - - pvr2_hdw_load_modules(hdw); - if (!pvr2_hdw_dev_ok(hdw)) return; - - v4l2_device_call_all(&hdw->v4l2_dev, 0, core, load_fw); - - for (idx = 0; idx < CTRLDEF_COUNT; idx++) { - cptr = hdw->controls + idx; - if (cptr->info->skip_init) continue; - if (!cptr->info->set_value) continue; - cptr->info->set_value(cptr,~0,cptr->info->default_value); - } - - pvr2_hdw_cx25840_vbi_hack(hdw); - - /* Set up special default values for the television and radio - frequencies here. It's not really important what these defaults - are, but I set them to something usable in the Chicago area just - to make driver testing a little easier. */ - - hdw->freqValTelevision = default_tv_freq; - hdw->freqValRadio = default_radio_freq; - - // Do not use pvr2_reset_ctl_endpoints() here. It is not - // thread-safe against the normal pvr2_send_request() mechanism. - // (We should make it thread safe). - - if (hdw->hdw_desc->flag_has_hauppauge_rom) { - ret = pvr2_hdw_get_eeprom_addr(hdw); - if (!pvr2_hdw_dev_ok(hdw)) return; - if (ret < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Unable to determine location of eeprom," - " skipping"); - } else { - hdw->eeprom_addr = ret; - pvr2_eeprom_analyze(hdw); - if (!pvr2_hdw_dev_ok(hdw)) return; - } - } else { - hdw->tuner_type = hdw->hdw_desc->default_tuner_type; - hdw->tuner_updated = !0; - hdw->std_mask_eeprom = V4L2_STD_ALL; - } - - if (hdw->serial_number) { - idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1, - "sn-%lu", hdw->serial_number); - } else if (hdw->unit_number >= 0) { - idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1, - "unit-%c", - hdw->unit_number + 'a'); - } else { - idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1, - "unit-??"); - } - hdw->identifier[idx] = 0; - - pvr2_hdw_setup_std(hdw); - - if (!get_default_tuner_type(hdw)) { - pvr2_trace(PVR2_TRACE_INIT, - "pvr2_hdw_setup: Tuner type overridden to %d", - hdw->tuner_type); - } - - - if (!pvr2_hdw_dev_ok(hdw)) return; - - if (hdw->hdw_desc->signal_routing_scheme == - PVR2_ROUTING_SCHEME_GOTVIEW) { - /* Ensure that GPIO 11 is set to output for GOTVIEW - hardware. */ - pvr2_hdw_gpio_chg_dir(hdw,(1 << 11),~0); - } - - pvr2_hdw_commit_setup(hdw); - - hdw->vid_stream = pvr2_stream_create(); - if (!pvr2_hdw_dev_ok(hdw)) return; - pvr2_trace(PVR2_TRACE_INIT, - "pvr2_hdw_setup: video stream is %p",hdw->vid_stream); - if (hdw->vid_stream) { - idx = get_default_error_tolerance(hdw); - if (idx) { - pvr2_trace(PVR2_TRACE_INIT, - "pvr2_hdw_setup: video stream %p" - " setting tolerance %u", - hdw->vid_stream,idx); - } - pvr2_stream_setup(hdw->vid_stream,hdw->usb_dev, - PVR2_VID_ENDPOINT,idx); - } - - if (!pvr2_hdw_dev_ok(hdw)) return; - - hdw->flag_init_ok = !0; - - pvr2_hdw_state_sched(hdw); -} - - -/* Set up the structure and attempt to put the device into a usable state. - This can be a time-consuming operation, which is why it is not done - internally as part of the create() step. */ -static void pvr2_hdw_setup(struct pvr2_hdw *hdw) -{ - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) begin",hdw); - do { - pvr2_hdw_setup_low(hdw); - pvr2_trace(PVR2_TRACE_INIT, - "pvr2_hdw_setup(hdw=%p) done, ok=%d init_ok=%d", - hdw,pvr2_hdw_dev_ok(hdw),hdw->flag_init_ok); - if (pvr2_hdw_dev_ok(hdw)) { - if (hdw->flag_init_ok) { - pvr2_trace( - PVR2_TRACE_INFO, - "Device initialization" - " completed successfully."); - break; - } - if (hdw->fw1_state == FW1_STATE_RELOAD) { - pvr2_trace( - PVR2_TRACE_INFO, - "Device microcontroller firmware" - " (re)loaded; it should now reset" - " and reconnect."); - break; - } - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Device initialization was not successful."); - if (hdw->fw1_state == FW1_STATE_MISSING) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Giving up since device" - " microcontroller firmware" - " appears to be missing."); - break; - } - } - if (hdw->flag_modulefail) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "***WARNING*** pvrusb2 driver initialization" - " failed due to the failure of one or more" - " sub-device kernel modules."); - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "You need to resolve the failing condition" - " before this driver can function. There" - " should be some earlier messages giving more" - " information about the problem."); - break; - } - if (procreload) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Attempting pvrusb2 recovery by reloading" - " primary firmware."); - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "If this works, device should disconnect" - " and reconnect in a sane state."); - hdw->fw1_state = FW1_STATE_UNKNOWN; - pvr2_upload_firmware1(hdw); - } else { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "***WARNING*** pvrusb2 device hardware" - " appears to be jammed" - " and I can't clear it."); - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "You might need to power cycle" - " the pvrusb2 device" - " in order to recover."); - } - } while (0); - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw); -} - - -/* Perform second stage initialization. Set callback pointer first so that - we can avoid a possible initialization race (if the kernel thread runs - before the callback has been set). */ -int pvr2_hdw_initialize(struct pvr2_hdw *hdw, - void (*callback_func)(void *), - void *callback_data) -{ - LOCK_TAKE(hdw->big_lock); do { - if (hdw->flag_disconnected) { - /* Handle a race here: If we're already - disconnected by this point, then give up. If we - get past this then we'll remain connected for - the duration of initialization since the entire - initialization sequence is now protected by the - big_lock. */ - break; - } - hdw->state_data = callback_data; - hdw->state_func = callback_func; - pvr2_hdw_setup(hdw); - } while (0); LOCK_GIVE(hdw->big_lock); - return hdw->flag_init_ok; -} - - -/* Create, set up, and return a structure for interacting with the - underlying hardware. */ -struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, - const struct usb_device_id *devid) -{ - unsigned int idx,cnt1,cnt2,m; - struct pvr2_hdw *hdw = NULL; - int valid_std_mask; - struct pvr2_ctrl *cptr; - struct usb_device *usb_dev; - const struct pvr2_device_desc *hdw_desc; - __u8 ifnum; - struct v4l2_queryctrl qctrl; - struct pvr2_ctl_info *ciptr; - - usb_dev = interface_to_usbdev(intf); - - hdw_desc = (const struct pvr2_device_desc *)(devid->driver_info); - - if (hdw_desc == NULL) { - pvr2_trace(PVR2_TRACE_INIT, "pvr2_hdw_create:" - " No device description pointer," - " unable to continue."); - pvr2_trace(PVR2_TRACE_INIT, "If you have a new device type," - " please contact Mike Isely <isely@pobox.com>" - " to get it included in the driver\n"); - goto fail; - } - - hdw = kzalloc(sizeof(*hdw),GFP_KERNEL); - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"", - hdw,hdw_desc->description); - pvr2_trace(PVR2_TRACE_INFO, "Hardware description: %s", - hdw_desc->description); - if (hdw_desc->flag_is_experimental) { - pvr2_trace(PVR2_TRACE_INFO, "**********"); - pvr2_trace(PVR2_TRACE_INFO, - "WARNING: Support for this device (%s) is" - " experimental.", hdw_desc->description); - pvr2_trace(PVR2_TRACE_INFO, - "Important functionality might not be" - " entirely working."); - pvr2_trace(PVR2_TRACE_INFO, - "Please consider contacting the driver author to" - " help with further stabilization of the driver."); - pvr2_trace(PVR2_TRACE_INFO, "**********"); - } - if (!hdw) goto fail; - - init_timer(&hdw->quiescent_timer); - hdw->quiescent_timer.data = (unsigned long)hdw; - hdw->quiescent_timer.function = pvr2_hdw_quiescent_timeout; - - init_timer(&hdw->decoder_stabilization_timer); - hdw->decoder_stabilization_timer.data = (unsigned long)hdw; - hdw->decoder_stabilization_timer.function = - pvr2_hdw_decoder_stabilization_timeout; - - init_timer(&hdw->encoder_wait_timer); - hdw->encoder_wait_timer.data = (unsigned long)hdw; - hdw->encoder_wait_timer.function = pvr2_hdw_encoder_wait_timeout; - - init_timer(&hdw->encoder_run_timer); - hdw->encoder_run_timer.data = (unsigned long)hdw; - hdw->encoder_run_timer.function = pvr2_hdw_encoder_run_timeout; - - hdw->master_state = PVR2_STATE_DEAD; - - init_waitqueue_head(&hdw->state_wait_data); - - hdw->tuner_signal_stale = !0; - cx2341x_fill_defaults(&hdw->enc_ctl_state); - - /* Calculate which inputs are OK */ - m = 0; - if (hdw_desc->flag_has_analogtuner) m |= 1 << PVR2_CVAL_INPUT_TV; - if (hdw_desc->digital_control_scheme != PVR2_DIGITAL_SCHEME_NONE) { - m |= 1 << PVR2_CVAL_INPUT_DTV; - } - if (hdw_desc->flag_has_svideo) m |= 1 << PVR2_CVAL_INPUT_SVIDEO; - if (hdw_desc->flag_has_composite) m |= 1 << PVR2_CVAL_INPUT_COMPOSITE; - if (hdw_desc->flag_has_fmradio) m |= 1 << PVR2_CVAL_INPUT_RADIO; - hdw->input_avail_mask = m; - hdw->input_allowed_mask = hdw->input_avail_mask; - - /* If not a hybrid device, pathway_state never changes. So - initialize it here to what it should forever be. */ - if (!(hdw->input_avail_mask & (1 << PVR2_CVAL_INPUT_DTV))) { - hdw->pathway_state = PVR2_PATHWAY_ANALOG; - } else if (!(hdw->input_avail_mask & (1 << PVR2_CVAL_INPUT_TV))) { - hdw->pathway_state = PVR2_PATHWAY_DIGITAL; - } - - hdw->control_cnt = CTRLDEF_COUNT; - hdw->control_cnt += MPEGDEF_COUNT; - hdw->controls = kzalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt, - GFP_KERNEL); - if (!hdw->controls) goto fail; - hdw->hdw_desc = hdw_desc; - hdw->ir_scheme_active = hdw->hdw_desc->ir_scheme; - for (idx = 0; idx < hdw->control_cnt; idx++) { - cptr = hdw->controls + idx; - cptr->hdw = hdw; - } - for (idx = 0; idx < 32; idx++) { - hdw->std_mask_ptrs[idx] = hdw->std_mask_names[idx]; - } - for (idx = 0; idx < CTRLDEF_COUNT; idx++) { - cptr = hdw->controls + idx; - cptr->info = control_defs+idx; - } - - /* Ensure that default input choice is a valid one. */ - m = hdw->input_avail_mask; - if (m) for (idx = 0; idx < (sizeof(m) << 3); idx++) { - if (!((1 << idx) & m)) continue; - hdw->input_val = idx; - break; - } - - /* Define and configure additional controls from cx2341x module. */ - hdw->mpeg_ctrl_info = kcalloc(MPEGDEF_COUNT, - sizeof(*(hdw->mpeg_ctrl_info)), - GFP_KERNEL); - if (!hdw->mpeg_ctrl_info) goto fail; - for (idx = 0; idx < MPEGDEF_COUNT; idx++) { - cptr = hdw->controls + idx + CTRLDEF_COUNT; - ciptr = &(hdw->mpeg_ctrl_info[idx].info); - ciptr->desc = hdw->mpeg_ctrl_info[idx].desc; - ciptr->name = mpeg_ids[idx].strid; - ciptr->v4l_id = mpeg_ids[idx].id; - ciptr->skip_init = !0; - ciptr->get_value = ctrl_cx2341x_get; - ciptr->get_v4lflags = ctrl_cx2341x_getv4lflags; - ciptr->is_dirty = ctrl_cx2341x_is_dirty; - if (!idx) ciptr->clear_dirty = ctrl_cx2341x_clear_dirty; - qctrl.id = ciptr->v4l_id; - cx2341x_ctrl_query(&hdw->enc_ctl_state,&qctrl); - if (!(qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) { - ciptr->set_value = ctrl_cx2341x_set; - } - strncpy(hdw->mpeg_ctrl_info[idx].desc,qctrl.name, - PVR2_CTLD_INFO_DESC_SIZE); - hdw->mpeg_ctrl_info[idx].desc[PVR2_CTLD_INFO_DESC_SIZE-1] = 0; - ciptr->default_value = qctrl.default_value; - switch (qctrl.type) { - default: - case V4L2_CTRL_TYPE_INTEGER: - ciptr->type = pvr2_ctl_int; - ciptr->def.type_int.min_value = qctrl.minimum; - ciptr->def.type_int.max_value = qctrl.maximum; - break; - case V4L2_CTRL_TYPE_BOOLEAN: - ciptr->type = pvr2_ctl_bool; - break; - case V4L2_CTRL_TYPE_MENU: - ciptr->type = pvr2_ctl_enum; - ciptr->def.type_enum.value_names = - cx2341x_ctrl_get_menu(&hdw->enc_ctl_state, - ciptr->v4l_id); - for (cnt1 = 0; - ciptr->def.type_enum.value_names[cnt1] != NULL; - cnt1++) { } - ciptr->def.type_enum.count = cnt1; - break; - } - cptr->info = ciptr; - } - - // Initialize control data regarding video standard masks - valid_std_mask = pvr2_std_get_usable(); - for (idx = 0; idx < 32; idx++) { - if (!(valid_std_mask & (1 << idx))) continue; - cnt1 = pvr2_std_id_to_str( - hdw->std_mask_names[idx], - sizeof(hdw->std_mask_names[idx])-1, - 1 << idx); - hdw->std_mask_names[idx][cnt1] = 0; - } - cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL); - if (cptr) { - memcpy(&hdw->std_info_avail,cptr->info, - sizeof(hdw->std_info_avail)); - cptr->info = &hdw->std_info_avail; - hdw->std_info_avail.def.type_bitmask.bit_names = - hdw->std_mask_ptrs; - hdw->std_info_avail.def.type_bitmask.valid_bits = - valid_std_mask; - } - cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR); - if (cptr) { - memcpy(&hdw->std_info_cur,cptr->info, - sizeof(hdw->std_info_cur)); - cptr->info = &hdw->std_info_cur; - hdw->std_info_cur.def.type_bitmask.bit_names = - hdw->std_mask_ptrs; - hdw->std_info_cur.def.type_bitmask.valid_bits = - valid_std_mask; - } - cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDDETECT); - if (cptr) { - memcpy(&hdw->std_info_detect,cptr->info, - sizeof(hdw->std_info_detect)); - cptr->info = &hdw->std_info_detect; - hdw->std_info_detect.def.type_bitmask.bit_names = - hdw->std_mask_ptrs; - hdw->std_info_detect.def.type_bitmask.valid_bits = - valid_std_mask; - } - - hdw->cropcap_stale = !0; - hdw->eeprom_addr = -1; - hdw->unit_number = -1; - hdw->v4l_minor_number_video = -1; - hdw->v4l_minor_number_vbi = -1; - hdw->v4l_minor_number_radio = -1; - hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL); - if (!hdw->ctl_write_buffer) goto fail; - hdw->ctl_read_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL); - if (!hdw->ctl_read_buffer) goto fail; - hdw->ctl_write_urb = usb_alloc_urb(0,GFP_KERNEL); - if (!hdw->ctl_write_urb) goto fail; - hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL); - if (!hdw->ctl_read_urb) goto fail; - - if (v4l2_device_register(&intf->dev, &hdw->v4l2_dev) != 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Error registering with v4l core, giving up"); - goto fail; - } - mutex_lock(&pvr2_unit_mtx); do { - for (idx = 0; idx < PVR_NUM; idx++) { - if (unit_pointers[idx]) continue; - hdw->unit_number = idx; - unit_pointers[idx] = hdw; - break; - } - } while (0); mutex_unlock(&pvr2_unit_mtx); - - cnt1 = 0; - cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2"); - cnt1 += cnt2; - if (hdw->unit_number >= 0) { - cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"_%c", - ('a' + hdw->unit_number)); - cnt1 += cnt2; - } - if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1; - hdw->name[cnt1] = 0; - - hdw->workqueue = create_singlethread_workqueue(hdw->name); - INIT_WORK(&hdw->workpoll,pvr2_hdw_worker_poll); - - pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s", - hdw->unit_number,hdw->name); - - hdw->tuner_type = -1; - hdw->flag_ok = !0; - - hdw->usb_intf = intf; - hdw->usb_dev = usb_dev; - - usb_make_path(hdw->usb_dev, hdw->bus_info, sizeof(hdw->bus_info)); - - ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber; - usb_set_interface(hdw->usb_dev,ifnum,0); - - mutex_init(&hdw->ctl_lock_mutex); - mutex_init(&hdw->big_lock_mutex); - - return hdw; - fail: - if (hdw) { - del_timer_sync(&hdw->quiescent_timer); - del_timer_sync(&hdw->decoder_stabilization_timer); - del_timer_sync(&hdw->encoder_run_timer); - del_timer_sync(&hdw->encoder_wait_timer); - if (hdw->workqueue) { - flush_workqueue(hdw->workqueue); - destroy_workqueue(hdw->workqueue); - hdw->workqueue = NULL; - } - usb_free_urb(hdw->ctl_read_urb); - usb_free_urb(hdw->ctl_write_urb); - kfree(hdw->ctl_read_buffer); - kfree(hdw->ctl_write_buffer); - kfree(hdw->controls); - kfree(hdw->mpeg_ctrl_info); - kfree(hdw); - } - return NULL; -} - - -/* Remove _all_ associations between this driver and the underlying USB - layer. */ -static void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw) -{ - if (hdw->flag_disconnected) return; - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_remove_usb_stuff: hdw=%p",hdw); - if (hdw->ctl_read_urb) { - usb_kill_urb(hdw->ctl_read_urb); - usb_free_urb(hdw->ctl_read_urb); - hdw->ctl_read_urb = NULL; - } - if (hdw->ctl_write_urb) { - usb_kill_urb(hdw->ctl_write_urb); - usb_free_urb(hdw->ctl_write_urb); - hdw->ctl_write_urb = NULL; - } - if (hdw->ctl_read_buffer) { - kfree(hdw->ctl_read_buffer); - hdw->ctl_read_buffer = NULL; - } - if (hdw->ctl_write_buffer) { - kfree(hdw->ctl_write_buffer); - hdw->ctl_write_buffer = NULL; - } - hdw->flag_disconnected = !0; - /* If we don't do this, then there will be a dangling struct device - reference to our disappearing device persisting inside the V4L - core... */ - v4l2_device_disconnect(&hdw->v4l2_dev); - hdw->usb_dev = NULL; - hdw->usb_intf = NULL; - pvr2_hdw_render_useless(hdw); -} - - -/* Destroy hardware interaction structure */ -void pvr2_hdw_destroy(struct pvr2_hdw *hdw) -{ - if (!hdw) return; - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw); - if (hdw->workqueue) { - flush_workqueue(hdw->workqueue); - destroy_workqueue(hdw->workqueue); - hdw->workqueue = NULL; - } - del_timer_sync(&hdw->quiescent_timer); - del_timer_sync(&hdw->decoder_stabilization_timer); - del_timer_sync(&hdw->encoder_run_timer); - del_timer_sync(&hdw->encoder_wait_timer); - if (hdw->fw_buffer) { - kfree(hdw->fw_buffer); - hdw->fw_buffer = NULL; - } - if (hdw->vid_stream) { - pvr2_stream_destroy(hdw->vid_stream); - hdw->vid_stream = NULL; - } - pvr2_i2c_core_done(hdw); - v4l2_device_unregister(&hdw->v4l2_dev); - pvr2_hdw_remove_usb_stuff(hdw); - mutex_lock(&pvr2_unit_mtx); do { - if ((hdw->unit_number >= 0) && - (hdw->unit_number < PVR_NUM) && - (unit_pointers[hdw->unit_number] == hdw)) { - unit_pointers[hdw->unit_number] = NULL; - } - } while (0); mutex_unlock(&pvr2_unit_mtx); - kfree(hdw->controls); - kfree(hdw->mpeg_ctrl_info); - kfree(hdw); -} - - -int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw) -{ - return (hdw && hdw->flag_ok); -} - - -/* Called when hardware has been unplugged */ -void pvr2_hdw_disconnect(struct pvr2_hdw *hdw) -{ - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw); - LOCK_TAKE(hdw->big_lock); - LOCK_TAKE(hdw->ctl_lock); - pvr2_hdw_remove_usb_stuff(hdw); - LOCK_GIVE(hdw->ctl_lock); - LOCK_GIVE(hdw->big_lock); -} - - -/* Get the number of defined controls */ -unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw) -{ - return hdw->control_cnt; -} - - -/* Retrieve a control handle given its index (0..count-1) */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw, - unsigned int idx) -{ - if (idx >= hdw->control_cnt) return NULL; - return hdw->controls + idx; -} - - -/* Retrieve a control handle given its index (0..count-1) */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw, - unsigned int ctl_id) -{ - struct pvr2_ctrl *cptr; - unsigned int idx; - int i; - - /* This could be made a lot more efficient, but for now... */ - for (idx = 0; idx < hdw->control_cnt; idx++) { - cptr = hdw->controls + idx; - i = cptr->info->internal_id; - if (i && (i == ctl_id)) return cptr; - } - return NULL; -} - - -/* Given a V4L ID, retrieve the control structure associated with it. */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsigned int ctl_id) -{ - struct pvr2_ctrl *cptr; - unsigned int idx; - int i; - - /* This could be made a lot more efficient, but for now... */ - for (idx = 0; idx < hdw->control_cnt; idx++) { - cptr = hdw->controls + idx; - i = cptr->info->v4l_id; - if (i && (i == ctl_id)) return cptr; - } - return NULL; -} - - -/* Given a V4L ID for its immediate predecessor, retrieve the control - structure associated with it. */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *hdw, - unsigned int ctl_id) -{ - struct pvr2_ctrl *cptr,*cp2; - unsigned int idx; - int i; - - /* This could be made a lot more efficient, but for now... */ - cp2 = NULL; - for (idx = 0; idx < hdw->control_cnt; idx++) { - cptr = hdw->controls + idx; - i = cptr->info->v4l_id; - if (!i) continue; - if (i <= ctl_id) continue; - if (cp2 && (cp2->info->v4l_id < i)) continue; - cp2 = cptr; - } - return cp2; - return NULL; -} - - -static const char *get_ctrl_typename(enum pvr2_ctl_type tp) -{ - switch (tp) { - case pvr2_ctl_int: return "integer"; - case pvr2_ctl_enum: return "enum"; - case pvr2_ctl_bool: return "boolean"; - case pvr2_ctl_bitmask: return "bitmask"; - } - return ""; -} - - -static void pvr2_subdev_set_control(struct pvr2_hdw *hdw, int id, - const char *name, int val) -{ - struct v4l2_control ctrl; - pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 %s=%d", name, val); - memset(&ctrl, 0, sizeof(ctrl)); - ctrl.id = id; - ctrl.value = val; - v4l2_device_call_all(&hdw->v4l2_dev, 0, core, s_ctrl, &ctrl); -} - -#define PVR2_SUBDEV_SET_CONTROL(hdw, id, lab) \ - if ((hdw)->lab##_dirty || (hdw)->force_dirty) { \ - pvr2_subdev_set_control(hdw, id, #lab, (hdw)->lab##_val); \ - } - -v4l2_std_id pvr2_hdw_get_detected_std(struct pvr2_hdw *hdw) -{ - v4l2_std_id std; - std = (v4l2_std_id)hdw->std_mask_avail; - v4l2_device_call_all(&hdw->v4l2_dev, 0, - video, querystd, &std); - return std; -} - -/* Execute whatever commands are required to update the state of all the - sub-devices so that they match our current control values. */ -static void pvr2_subdev_update(struct pvr2_hdw *hdw) -{ - struct v4l2_subdev *sd; - unsigned int id; - pvr2_subdev_update_func fp; - - pvr2_trace(PVR2_TRACE_CHIPS, "subdev update..."); - - if (hdw->tuner_updated || hdw->force_dirty) { - struct tuner_setup setup; - pvr2_trace(PVR2_TRACE_CHIPS, "subdev tuner set_type(%d)", - hdw->tuner_type); - if (((int)(hdw->tuner_type)) >= 0) { - memset(&setup, 0, sizeof(setup)); - setup.addr = ADDR_UNSET; - setup.type = hdw->tuner_type; - setup.mode_mask = T_RADIO | T_ANALOG_TV; - v4l2_device_call_all(&hdw->v4l2_dev, 0, - tuner, s_type_addr, &setup); - } - } - - if (hdw->input_dirty || hdw->std_dirty || hdw->force_dirty) { - pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_standard"); - if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) { - v4l2_device_call_all(&hdw->v4l2_dev, 0, - tuner, s_radio); - } else { - v4l2_std_id vs; - vs = hdw->std_mask_cur; - v4l2_device_call_all(&hdw->v4l2_dev, 0, - core, s_std, vs); - pvr2_hdw_cx25840_vbi_hack(hdw); - } - hdw->tuner_signal_stale = !0; - hdw->cropcap_stale = !0; - } - - PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_BRIGHTNESS, brightness); - PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_CONTRAST, contrast); - PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_SATURATION, saturation); - PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_HUE, hue); - PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_MUTE, mute); - PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_VOLUME, volume); - PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_BALANCE, balance); - PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_BASS, bass); - PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_TREBLE, treble); - - if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) { - struct v4l2_tuner vt; - memset(&vt, 0, sizeof(vt)); - vt.type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ? - V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; - vt.audmode = hdw->audiomode_val; - v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt); - } - - if (hdw->freqDirty || hdw->force_dirty) { - unsigned long fv; - struct v4l2_frequency freq; - fv = pvr2_hdw_get_cur_freq(hdw); - pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_freq(%lu)", fv); - if (hdw->tuner_signal_stale) pvr2_hdw_status_poll(hdw); - memset(&freq, 0, sizeof(freq)); - if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) { - /* ((fv * 1000) / 62500) */ - freq.frequency = (fv * 2) / 125; - } else { - freq.frequency = fv / 62500; - } - /* tuner-core currently doesn't seem to care about this, but - let's set it anyway for completeness. */ - if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) { - freq.type = V4L2_TUNER_RADIO; - } else { - freq.type = V4L2_TUNER_ANALOG_TV; - } - freq.tuner = 0; - v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, - s_frequency, &freq); - } - - if (hdw->res_hor_dirty || hdw->res_ver_dirty || hdw->force_dirty) { - struct v4l2_mbus_framefmt fmt; - memset(&fmt, 0, sizeof(fmt)); - fmt.width = hdw->res_hor_val; - fmt.height = hdw->res_ver_val; - fmt.code = V4L2_MBUS_FMT_FIXED; - pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_size(%dx%d)", - fmt.width, fmt.height); - v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_mbus_fmt, &fmt); - } - - if (hdw->srate_dirty || hdw->force_dirty) { - u32 val; - pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_audio %d", - hdw->srate_val); - switch (hdw->srate_val) { - default: - case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000: - val = 48000; - break; - case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100: - val = 44100; - break; - case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000: - val = 32000; - break; - } - v4l2_device_call_all(&hdw->v4l2_dev, 0, - audio, s_clock_freq, val); - } - - /* Unable to set crop parameters; there is apparently no equivalent - for VIDIOC_S_CROP */ - - v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) { - id = sd->grp_id; - if (id >= ARRAY_SIZE(pvr2_module_update_functions)) continue; - fp = pvr2_module_update_functions[id]; - if (!fp) continue; - (*fp)(hdw, sd); - } - - if (hdw->tuner_signal_stale || hdw->cropcap_stale) { - pvr2_hdw_status_poll(hdw); - } -} - - -/* Figure out if we need to commit control changes. If so, mark internal - state flags to indicate this fact and return true. Otherwise do nothing - else and return false. */ -static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw) -{ - unsigned int idx; - struct pvr2_ctrl *cptr; - int value; - int commit_flag = hdw->force_dirty; - char buf[100]; - unsigned int bcnt,ccnt; - - for (idx = 0; idx < hdw->control_cnt; idx++) { - cptr = hdw->controls + idx; - if (!cptr->info->is_dirty) continue; - if (!cptr->info->is_dirty(cptr)) continue; - commit_flag = !0; - - if (!(pvrusb2_debug & PVR2_TRACE_CTL)) continue; - bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ", - cptr->info->name); - value = 0; - cptr->info->get_value(cptr,&value); - pvr2_ctrl_value_to_sym_internal(cptr,~0,value, - buf+bcnt, - sizeof(buf)-bcnt,&ccnt); - bcnt += ccnt; - bcnt += scnprintf(buf+bcnt,sizeof(buf)-bcnt," <%s>", - get_ctrl_typename(cptr->info->type)); - pvr2_trace(PVR2_TRACE_CTL, - "/*--TRACE_COMMIT--*/ %.*s", - bcnt,buf); - } - - if (!commit_flag) { - /* Nothing has changed */ - return 0; - } - - hdw->state_pipeline_config = 0; - trace_stbit("state_pipeline_config",hdw->state_pipeline_config); - pvr2_hdw_state_sched(hdw); - - return !0; -} - - -/* Perform all operations needed to commit all control changes. This must - be performed in synchronization with the pipeline state and is thus - expected to be called as part of the driver's worker thread. Return - true if commit successful, otherwise return false to indicate that - commit isn't possible at this time. */ -static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw) -{ - unsigned int idx; - struct pvr2_ctrl *cptr; - int disruptive_change; - - if (hdw->input_dirty && hdw->state_pathway_ok && - (((hdw->input_val == PVR2_CVAL_INPUT_DTV) ? - PVR2_PATHWAY_DIGITAL : PVR2_PATHWAY_ANALOG) != - hdw->pathway_state)) { - /* Change of mode being asked for... */ - hdw->state_pathway_ok = 0; - trace_stbit("state_pathway_ok", hdw->state_pathway_ok); - } - if (!hdw->state_pathway_ok) { - /* Can't commit anything until pathway is ok. */ - return 0; - } - - /* Handle some required side effects when the video standard is - changed.... */ - if (hdw->std_dirty) { - int nvres; - int gop_size; - if (hdw->std_mask_cur & V4L2_STD_525_60) { - nvres = 480; - gop_size = 15; - } else { - nvres = 576; - gop_size = 12; - } - /* Rewrite the vertical resolution to be appropriate to the - video standard that has been selected. */ - if (nvres != hdw->res_ver_val) { - hdw->res_ver_val = nvres; - hdw->res_ver_dirty = !0; - } - /* Rewrite the GOP size to be appropriate to the video - standard that has been selected. */ - if (gop_size != hdw->enc_ctl_state.video_gop_size) { - struct v4l2_ext_controls cs; - struct v4l2_ext_control c1; - memset(&cs, 0, sizeof(cs)); - memset(&c1, 0, sizeof(c1)); - cs.controls = &c1; - cs.count = 1; - c1.id = V4L2_CID_MPEG_VIDEO_GOP_SIZE; - c1.value = gop_size; - cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs, - VIDIOC_S_EXT_CTRLS); - } - } - - /* The broadcast decoder can only scale down, so if - * res_*_dirty && crop window < output format ==> enlarge crop. - * - * The mpeg encoder receives fields of res_hor_val dots and - * res_ver_val halflines. Limits: hor<=720, ver<=576. - */ - if (hdw->res_hor_dirty && hdw->cropw_val < hdw->res_hor_val) { - hdw->cropw_val = hdw->res_hor_val; - hdw->cropw_dirty = !0; - } else if (hdw->cropw_dirty) { - hdw->res_hor_dirty = !0; /* must rescale */ - hdw->res_hor_val = min(720, hdw->cropw_val); - } - if (hdw->res_ver_dirty && hdw->croph_val < hdw->res_ver_val) { - hdw->croph_val = hdw->res_ver_val; - hdw->croph_dirty = !0; - } else if (hdw->croph_dirty) { - int nvres = hdw->std_mask_cur & V4L2_STD_525_60 ? 480 : 576; - hdw->res_ver_dirty = !0; - hdw->res_ver_val = min(nvres, hdw->croph_val); - } - - /* If any of the below has changed, then we can't do the update - while the pipeline is running. Pipeline must be paused first - and decoder -> encoder connection be made quiescent before we - can proceed. */ - disruptive_change = - (hdw->std_dirty || - hdw->enc_unsafe_stale || - hdw->srate_dirty || - hdw->res_ver_dirty || - hdw->res_hor_dirty || - hdw->cropw_dirty || - hdw->croph_dirty || - hdw->input_dirty || - (hdw->active_stream_type != hdw->desired_stream_type)); - if (disruptive_change && !hdw->state_pipeline_idle) { - /* Pipeline is not idle; we can't proceed. Arrange to - cause pipeline to stop so that we can try this again - later.... */ - hdw->state_pipeline_pause = !0; - return 0; - } - - if (hdw->srate_dirty) { - /* Write new sample rate into control structure since - * the master copy is stale. We must track srate - * separate from the mpeg control structure because - * other logic also uses this value. */ - struct v4l2_ext_controls cs; - struct v4l2_ext_control c1; - memset(&cs,0,sizeof(cs)); - memset(&c1,0,sizeof(c1)); - cs.controls = &c1; - cs.count = 1; - c1.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ; - c1.value = hdw->srate_val; - cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs,VIDIOC_S_EXT_CTRLS); - } - - if (hdw->active_stream_type != hdw->desired_stream_type) { - /* Handle any side effects of stream config here */ - hdw->active_stream_type = hdw->desired_stream_type; - } - - if (hdw->hdw_desc->signal_routing_scheme == - PVR2_ROUTING_SCHEME_GOTVIEW) { - u32 b; - /* Handle GOTVIEW audio switching */ - pvr2_hdw_gpio_get_out(hdw,&b); - if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) { - /* Set GPIO 11 */ - pvr2_hdw_gpio_chg_out(hdw,(1 << 11),~0); - } else { - /* Clear GPIO 11 */ - pvr2_hdw_gpio_chg_out(hdw,(1 << 11),0); - } - } - - /* Check and update state for all sub-devices. */ - pvr2_subdev_update(hdw); - - hdw->tuner_updated = 0; - hdw->force_dirty = 0; - for (idx = 0; idx < hdw->control_cnt; idx++) { - cptr = hdw->controls + idx; - if (!cptr->info->clear_dirty) continue; - cptr->info->clear_dirty(cptr); - } - - if ((hdw->pathway_state == PVR2_PATHWAY_ANALOG) && - hdw->state_encoder_run) { - /* If encoder isn't running or it can't be touched, then - this will get worked out later when we start the - encoder. */ - if (pvr2_encoder_adjust(hdw) < 0) return !0; - } - - hdw->state_pipeline_config = !0; - /* Hardware state may have changed in a way to cause the cropping - capabilities to have changed. So mark it stale, which will - cause a later re-fetch. */ - trace_stbit("state_pipeline_config",hdw->state_pipeline_config); - return !0; -} - - -int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw) -{ - int fl; - LOCK_TAKE(hdw->big_lock); - fl = pvr2_hdw_commit_setup(hdw); - LOCK_GIVE(hdw->big_lock); - if (!fl) return 0; - return pvr2_hdw_wait(hdw,0); -} - - -static void pvr2_hdw_worker_poll(struct work_struct *work) -{ - int fl = 0; - struct pvr2_hdw *hdw = container_of(work,struct pvr2_hdw,workpoll); - LOCK_TAKE(hdw->big_lock); do { - fl = pvr2_hdw_state_eval(hdw); - } while (0); LOCK_GIVE(hdw->big_lock); - if (fl && hdw->state_func) { - hdw->state_func(hdw->state_data); - } -} - - -static int pvr2_hdw_wait(struct pvr2_hdw *hdw,int state) -{ - return wait_event_interruptible( - hdw->state_wait_data, - (hdw->state_stale == 0) && - (!state || (hdw->master_state != state))); -} - - -/* Return name for this driver instance */ -const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw) -{ - return hdw->name; -} - - -const char *pvr2_hdw_get_desc(struct pvr2_hdw *hdw) -{ - return hdw->hdw_desc->description; -} - - -const char *pvr2_hdw_get_type(struct pvr2_hdw *hdw) -{ - return hdw->hdw_desc->shortname; -} - - -int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw) -{ - int result; - LOCK_TAKE(hdw->ctl_lock); do { - hdw->cmd_buffer[0] = FX2CMD_GET_USB_SPEED; - result = pvr2_send_request(hdw, - hdw->cmd_buffer,1, - hdw->cmd_buffer,1); - if (result < 0) break; - result = (hdw->cmd_buffer[0] != 0); - } while(0); LOCK_GIVE(hdw->ctl_lock); - return result; -} - - -/* Execute poll of tuner status */ -void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *hdw) -{ - LOCK_TAKE(hdw->big_lock); do { - pvr2_hdw_status_poll(hdw); - } while (0); LOCK_GIVE(hdw->big_lock); -} - - -static int pvr2_hdw_check_cropcap(struct pvr2_hdw *hdw) -{ - if (!hdw->cropcap_stale) { - return 0; - } - pvr2_hdw_status_poll(hdw); - if (hdw->cropcap_stale) { - return -EIO; - } - return 0; -} - - -/* Return information about cropping capabilities */ -int pvr2_hdw_get_cropcap(struct pvr2_hdw *hdw, struct v4l2_cropcap *pp) -{ - int stat = 0; - LOCK_TAKE(hdw->big_lock); - stat = pvr2_hdw_check_cropcap(hdw); - if (!stat) { - memcpy(pp, &hdw->cropcap_info, sizeof(hdw->cropcap_info)); - } - LOCK_GIVE(hdw->big_lock); - return stat; -} - - -/* Return information about the tuner */ -int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp) -{ - LOCK_TAKE(hdw->big_lock); do { - if (hdw->tuner_signal_stale) { - pvr2_hdw_status_poll(hdw); - } - memcpy(vtp,&hdw->tuner_signal_info,sizeof(struct v4l2_tuner)); - } while (0); LOCK_GIVE(hdw->big_lock); - return 0; -} - - -/* Get handle to video output stream */ -struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp) -{ - return hp->vid_stream; -} - - -void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw) -{ - int nr = pvr2_hdw_get_unit_number(hdw); - LOCK_TAKE(hdw->big_lock); do { - printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr); - v4l2_device_call_all(&hdw->v4l2_dev, 0, core, log_status); - pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:"); - cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2"); - pvr2_hdw_state_log_state(hdw); - printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr); - } while (0); LOCK_GIVE(hdw->big_lock); -} - - -/* Grab EEPROM contents, needed for direct method. */ -#define EEPROM_SIZE 8192 -#define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__) -static u8 *pvr2_full_eeprom_fetch(struct pvr2_hdw *hdw) -{ - struct i2c_msg msg[2]; - u8 *eeprom; - u8 iadd[2]; - u8 addr; - u16 eepromSize; - unsigned int offs; - int ret; - int mode16 = 0; - unsigned pcnt,tcnt; - eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL); - if (!eeprom) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to allocate memory" - " required to read eeprom"); - return NULL; - } - - trace_eeprom("Value for eeprom addr from controller was 0x%x", - hdw->eeprom_addr); - addr = hdw->eeprom_addr; - /* Seems that if the high bit is set, then the *real* eeprom - address is shifted right now bit position (noticed this in - newer PVR USB2 hardware) */ - if (addr & 0x80) addr >>= 1; - - /* FX2 documentation states that a 16bit-addressed eeprom is - expected if the I2C address is an odd number (yeah, this is - strange but it's what they do) */ - mode16 = (addr & 1); - eepromSize = (mode16 ? EEPROM_SIZE : 256); - trace_eeprom("Examining %d byte eeprom at location 0x%x" - " using %d bit addressing",eepromSize,addr, - mode16 ? 16 : 8); - - msg[0].addr = addr; - msg[0].flags = 0; - msg[0].len = mode16 ? 2 : 1; - msg[0].buf = iadd; - msg[1].addr = addr; - msg[1].flags = I2C_M_RD; - - /* We have to do the actual eeprom data fetch ourselves, because - (1) we're only fetching part of the eeprom, and (2) if we were - getting the whole thing our I2C driver can't grab it in one - pass - which is what tveeprom is otherwise going to attempt */ - memset(eeprom,0,EEPROM_SIZE); - for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) { - pcnt = 16; - if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt; - offs = tcnt + (eepromSize - EEPROM_SIZE); - if (mode16) { - iadd[0] = offs >> 8; - iadd[1] = offs; - } else { - iadd[0] = offs; - } - msg[1].len = pcnt; - msg[1].buf = eeprom+tcnt; - if ((ret = i2c_transfer(&hdw->i2c_adap, - msg,ARRAY_SIZE(msg))) != 2) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "eeprom fetch set offs err=%d",ret); - kfree(eeprom); - return NULL; - } - } - return eeprom; -} - - -void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, - int mode, - int enable_flag) -{ - int ret; - u16 address; - unsigned int pipe; - LOCK_TAKE(hdw->big_lock); do { - if ((hdw->fw_buffer == NULL) == !enable_flag) break; - - if (!enable_flag) { - pvr2_trace(PVR2_TRACE_FIRMWARE, - "Cleaning up after CPU firmware fetch"); - kfree(hdw->fw_buffer); - hdw->fw_buffer = NULL; - hdw->fw_size = 0; - if (hdw->fw_cpu_flag) { - /* Now release the CPU. It will disconnect - and reconnect later. */ - pvr2_hdw_cpureset_assert(hdw,0); - } - break; - } - - hdw->fw_cpu_flag = (mode != 2); - if (hdw->fw_cpu_flag) { - hdw->fw_size = (mode == 1) ? 0x4000 : 0x2000; - pvr2_trace(PVR2_TRACE_FIRMWARE, - "Preparing to suck out CPU firmware" - " (size=%u)", hdw->fw_size); - hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL); - if (!hdw->fw_buffer) { - hdw->fw_size = 0; - break; - } - - /* We have to hold the CPU during firmware upload. */ - pvr2_hdw_cpureset_assert(hdw,1); - - /* download the firmware from address 0000-1fff in 2048 - (=0x800) bytes chunk. */ - - pvr2_trace(PVR2_TRACE_FIRMWARE, - "Grabbing CPU firmware"); - pipe = usb_rcvctrlpipe(hdw->usb_dev, 0); - for(address = 0; address < hdw->fw_size; - address += 0x800) { - ret = usb_control_msg(hdw->usb_dev,pipe, - 0xa0,0xc0, - address,0, - hdw->fw_buffer+address, - 0x800,HZ); - if (ret < 0) break; - } - - pvr2_trace(PVR2_TRACE_FIRMWARE, - "Done grabbing CPU firmware"); - } else { - pvr2_trace(PVR2_TRACE_FIRMWARE, - "Sucking down EEPROM contents"); - hdw->fw_buffer = pvr2_full_eeprom_fetch(hdw); - if (!hdw->fw_buffer) { - pvr2_trace(PVR2_TRACE_FIRMWARE, - "EEPROM content suck failed."); - break; - } - hdw->fw_size = EEPROM_SIZE; - pvr2_trace(PVR2_TRACE_FIRMWARE, - "Done sucking down EEPROM contents"); - } - - } while (0); LOCK_GIVE(hdw->big_lock); -} - - -/* Return true if we're in a mode for retrieval CPU firmware */ -int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw) -{ - return hdw->fw_buffer != NULL; -} - - -int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs, - char *buf,unsigned int cnt) -{ - int ret = -EINVAL; - LOCK_TAKE(hdw->big_lock); do { - if (!buf) break; - if (!cnt) break; - - if (!hdw->fw_buffer) { - ret = -EIO; - break; - } - - if (offs >= hdw->fw_size) { - pvr2_trace(PVR2_TRACE_FIRMWARE, - "Read firmware data offs=%d EOF", - offs); - ret = 0; - break; - } - - if (offs + cnt > hdw->fw_size) cnt = hdw->fw_size - offs; - - memcpy(buf,hdw->fw_buffer+offs,cnt); - - pvr2_trace(PVR2_TRACE_FIRMWARE, - "Read firmware data offs=%d cnt=%d", - offs,cnt); - ret = cnt; - } while (0); LOCK_GIVE(hdw->big_lock); - - return ret; -} - - -int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw, - enum pvr2_v4l_type index) -{ - switch (index) { - case pvr2_v4l_type_video: return hdw->v4l_minor_number_video; - case pvr2_v4l_type_vbi: return hdw->v4l_minor_number_vbi; - case pvr2_v4l_type_radio: return hdw->v4l_minor_number_radio; - default: return -1; - } -} - - -/* Store a v4l minor device number */ -void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw, - enum pvr2_v4l_type index,int v) -{ - switch (index) { - case pvr2_v4l_type_video: hdw->v4l_minor_number_video = v; - case pvr2_v4l_type_vbi: hdw->v4l_minor_number_vbi = v; - case pvr2_v4l_type_radio: hdw->v4l_minor_number_radio = v; - default: break; - } -} - - -static void pvr2_ctl_write_complete(struct urb *urb) -{ - struct pvr2_hdw *hdw = urb->context; - hdw->ctl_write_pend_flag = 0; - if (hdw->ctl_read_pend_flag) return; - complete(&hdw->ctl_done); -} - - -static void pvr2_ctl_read_complete(struct urb *urb) -{ - struct pvr2_hdw *hdw = urb->context; - hdw->ctl_read_pend_flag = 0; - if (hdw->ctl_write_pend_flag) return; - complete(&hdw->ctl_done); -} - - -static void pvr2_ctl_timeout(unsigned long data) -{ - struct pvr2_hdw *hdw = (struct pvr2_hdw *)data; - if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) { - hdw->ctl_timeout_flag = !0; - if (hdw->ctl_write_pend_flag) - usb_unlink_urb(hdw->ctl_write_urb); - if (hdw->ctl_read_pend_flag) - usb_unlink_urb(hdw->ctl_read_urb); - } -} - - -/* Issue a command and get a response from the device. This extended - version includes a probe flag (which if set means that device errors - should not be logged or treated as fatal) and a timeout in jiffies. - This can be used to non-lethally probe the health of endpoint 1. */ -static int pvr2_send_request_ex(struct pvr2_hdw *hdw, - unsigned int timeout,int probe_fl, - void *write_data,unsigned int write_len, - void *read_data,unsigned int read_len) -{ - unsigned int idx; - int status = 0; - struct timer_list timer; - if (!hdw->ctl_lock_held) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Attempted to execute control transfer" - " without lock!!"); - return -EDEADLK; - } - if (!hdw->flag_ok && !probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Attempted to execute control transfer" - " when device not ok"); - return -EIO; - } - if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) { - if (!probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Attempted to execute control transfer" - " when USB is disconnected"); - } - return -ENOTTY; - } - - /* Ensure that we have sane parameters */ - if (!write_data) write_len = 0; - if (!read_data) read_len = 0; - if (write_len > PVR2_CTL_BUFFSIZE) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Attempted to execute %d byte" - " control-write transfer (limit=%d)", - write_len,PVR2_CTL_BUFFSIZE); - return -EINVAL; - } - if (read_len > PVR2_CTL_BUFFSIZE) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Attempted to execute %d byte" - " control-read transfer (limit=%d)", - write_len,PVR2_CTL_BUFFSIZE); - return -EINVAL; - } - if ((!write_len) && (!read_len)) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Attempted to execute null control transfer?"); - return -EINVAL; - } - - - hdw->cmd_debug_state = 1; - if (write_len) { - hdw->cmd_debug_code = ((unsigned char *)write_data)[0]; - } else { - hdw->cmd_debug_code = 0; - } - hdw->cmd_debug_write_len = write_len; - hdw->cmd_debug_read_len = read_len; - - /* Initialize common stuff */ - init_completion(&hdw->ctl_done); - hdw->ctl_timeout_flag = 0; - hdw->ctl_write_pend_flag = 0; - hdw->ctl_read_pend_flag = 0; - init_timer(&timer); - timer.expires = jiffies + timeout; - timer.data = (unsigned long)hdw; - timer.function = pvr2_ctl_timeout; - - if (write_len) { - hdw->cmd_debug_state = 2; - /* Transfer write data to internal buffer */ - for (idx = 0; idx < write_len; idx++) { - hdw->ctl_write_buffer[idx] = - ((unsigned char *)write_data)[idx]; - } - /* Initiate a write request */ - usb_fill_bulk_urb(hdw->ctl_write_urb, - hdw->usb_dev, - usb_sndbulkpipe(hdw->usb_dev, - PVR2_CTL_WRITE_ENDPOINT), - hdw->ctl_write_buffer, - write_len, - pvr2_ctl_write_complete, - hdw); - hdw->ctl_write_urb->actual_length = 0; - hdw->ctl_write_pend_flag = !0; - status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL); - if (status < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to submit write-control" - " URB status=%d",status); - hdw->ctl_write_pend_flag = 0; - goto done; - } - } - - if (read_len) { - hdw->cmd_debug_state = 3; - memset(hdw->ctl_read_buffer,0x43,read_len); - /* Initiate a read request */ - usb_fill_bulk_urb(hdw->ctl_read_urb, - hdw->usb_dev, - usb_rcvbulkpipe(hdw->usb_dev, - PVR2_CTL_READ_ENDPOINT), - hdw->ctl_read_buffer, - read_len, - pvr2_ctl_read_complete, - hdw); - hdw->ctl_read_urb->actual_length = 0; - hdw->ctl_read_pend_flag = !0; - status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL); - if (status < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to submit read-control" - " URB status=%d",status); - hdw->ctl_read_pend_flag = 0; - goto done; - } - } - - /* Start timer */ - add_timer(&timer); - - /* Now wait for all I/O to complete */ - hdw->cmd_debug_state = 4; - while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) { - wait_for_completion(&hdw->ctl_done); - } - hdw->cmd_debug_state = 5; - - /* Stop timer */ - del_timer_sync(&timer); - - hdw->cmd_debug_state = 6; - status = 0; - - if (hdw->ctl_timeout_flag) { - status = -ETIMEDOUT; - if (!probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Timed out control-write"); - } - goto done; - } - - if (write_len) { - /* Validate results of write request */ - if ((hdw->ctl_write_urb->status != 0) && - (hdw->ctl_write_urb->status != -ENOENT) && - (hdw->ctl_write_urb->status != -ESHUTDOWN) && - (hdw->ctl_write_urb->status != -ECONNRESET)) { - /* USB subsystem is reporting some kind of failure - on the write */ - status = hdw->ctl_write_urb->status; - if (!probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-write URB failure," - " status=%d", - status); - } - goto done; - } - if (hdw->ctl_write_urb->actual_length < write_len) { - /* Failed to write enough data */ - status = -EIO; - if (!probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-write URB short," - " expected=%d got=%d", - write_len, - hdw->ctl_write_urb->actual_length); - } - goto done; - } - } - if (read_len) { - /* Validate results of read request */ - if ((hdw->ctl_read_urb->status != 0) && - (hdw->ctl_read_urb->status != -ENOENT) && - (hdw->ctl_read_urb->status != -ESHUTDOWN) && - (hdw->ctl_read_urb->status != -ECONNRESET)) { - /* USB subsystem is reporting some kind of failure - on the read */ - status = hdw->ctl_read_urb->status; - if (!probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-read URB failure," - " status=%d", - status); - } - goto done; - } - if (hdw->ctl_read_urb->actual_length < read_len) { - /* Failed to read enough data */ - status = -EIO; - if (!probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-read URB short," - " expected=%d got=%d", - read_len, - hdw->ctl_read_urb->actual_length); - } - goto done; - } - /* Transfer retrieved data out from internal buffer */ - for (idx = 0; idx < read_len; idx++) { - ((unsigned char *)read_data)[idx] = - hdw->ctl_read_buffer[idx]; - } - } - - done: - - hdw->cmd_debug_state = 0; - if ((status < 0) && (!probe_fl)) { - pvr2_hdw_render_useless(hdw); - } - return status; -} - - -int pvr2_send_request(struct pvr2_hdw *hdw, - void *write_data,unsigned int write_len, - void *read_data,unsigned int read_len) -{ - return pvr2_send_request_ex(hdw,HZ*4,0, - write_data,write_len, - read_data,read_len); -} - - -static int pvr2_issue_simple_cmd(struct pvr2_hdw *hdw,u32 cmdcode) -{ - int ret; - unsigned int cnt = 1; - unsigned int args = 0; - LOCK_TAKE(hdw->ctl_lock); - hdw->cmd_buffer[0] = cmdcode & 0xffu; - args = (cmdcode >> 8) & 0xffu; - args = (args > 2) ? 2 : args; - if (args) { - cnt += args; - hdw->cmd_buffer[1] = (cmdcode >> 16) & 0xffu; - if (args > 1) { - hdw->cmd_buffer[2] = (cmdcode >> 24) & 0xffu; - } - } - if (pvrusb2_debug & PVR2_TRACE_INIT) { - unsigned int idx; - unsigned int ccnt,bcnt; - char tbuf[50]; - cmdcode &= 0xffu; - bcnt = 0; - ccnt = scnprintf(tbuf+bcnt, - sizeof(tbuf)-bcnt, - "Sending FX2 command 0x%x",cmdcode); - bcnt += ccnt; - for (idx = 0; idx < ARRAY_SIZE(pvr2_fx2cmd_desc); idx++) { - if (pvr2_fx2cmd_desc[idx].id == cmdcode) { - ccnt = scnprintf(tbuf+bcnt, - sizeof(tbuf)-bcnt, - " \"%s\"", - pvr2_fx2cmd_desc[idx].desc); - bcnt += ccnt; - break; - } - } - if (args) { - ccnt = scnprintf(tbuf+bcnt, - sizeof(tbuf)-bcnt, - " (%u",hdw->cmd_buffer[1]); - bcnt += ccnt; - if (args > 1) { - ccnt = scnprintf(tbuf+bcnt, - sizeof(tbuf)-bcnt, - ",%u",hdw->cmd_buffer[2]); - bcnt += ccnt; - } - ccnt = scnprintf(tbuf+bcnt, - sizeof(tbuf)-bcnt, - ")"); - bcnt += ccnt; - } - pvr2_trace(PVR2_TRACE_INIT,"%.*s",bcnt,tbuf); - } - ret = pvr2_send_request(hdw,hdw->cmd_buffer,cnt,NULL,0); - LOCK_GIVE(hdw->ctl_lock); - return ret; -} - - -int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data) -{ - int ret; - - LOCK_TAKE(hdw->ctl_lock); - - hdw->cmd_buffer[0] = FX2CMD_REG_WRITE; /* write register prefix */ - PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data); - hdw->cmd_buffer[5] = 0; - hdw->cmd_buffer[6] = (reg >> 8) & 0xff; - hdw->cmd_buffer[7] = reg & 0xff; - - - ret = pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 0); - - LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - - -static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data) -{ - int ret = 0; - - LOCK_TAKE(hdw->ctl_lock); - - hdw->cmd_buffer[0] = FX2CMD_REG_READ; /* read register prefix */ - hdw->cmd_buffer[1] = 0; - hdw->cmd_buffer[2] = 0; - hdw->cmd_buffer[3] = 0; - hdw->cmd_buffer[4] = 0; - hdw->cmd_buffer[5] = 0; - hdw->cmd_buffer[6] = (reg >> 8) & 0xff; - hdw->cmd_buffer[7] = reg & 0xff; - - ret |= pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 4); - *data = PVR2_COMPOSE_LE(hdw->cmd_buffer,0); - - LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - - -void pvr2_hdw_render_useless(struct pvr2_hdw *hdw) -{ - if (!hdw->flag_ok) return; - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Device being rendered inoperable"); - if (hdw->vid_stream) { - pvr2_stream_setup(hdw->vid_stream,NULL,0,0); - } - hdw->flag_ok = 0; - trace_stbit("flag_ok",hdw->flag_ok); - pvr2_hdw_state_sched(hdw); -} - - -void pvr2_hdw_device_reset(struct pvr2_hdw *hdw) -{ - int ret; - pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset..."); - ret = usb_lock_device_for_reset(hdw->usb_dev,NULL); - if (ret == 0) { - ret = usb_reset_device(hdw->usb_dev); - usb_unlock_device(hdw->usb_dev); - } else { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to lock USB device ret=%d",ret); - } - if (init_pause_msec) { - pvr2_trace(PVR2_TRACE_INFO, - "Waiting %u msec for hardware to settle", - init_pause_msec); - msleep(init_pause_msec); - } - -} - - -void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val) -{ - char *da; - unsigned int pipe; - int ret; - - if (!hdw->usb_dev) return; - - da = kmalloc(16, GFP_KERNEL); - - if (da == NULL) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Unable to allocate memory to control CPU reset"); - return; - } - - pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val); - - da[0] = val ? 0x01 : 0x00; - - /* Write the CPUCS register on the 8051. The lsb of the register - is the reset bit; a 1 asserts reset while a 0 clears it. */ - pipe = usb_sndctrlpipe(hdw->usb_dev, 0); - ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ); - if (ret < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "cpureset_assert(%d) error=%d",val,ret); - pvr2_hdw_render_useless(hdw); - } - - kfree(da); -} - - -int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw) -{ - return pvr2_issue_simple_cmd(hdw,FX2CMD_DEEP_RESET); -} - - -int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw) -{ - return pvr2_issue_simple_cmd(hdw,FX2CMD_POWER_ON); -} - - -int pvr2_hdw_cmd_powerdown(struct pvr2_hdw *hdw) -{ - return pvr2_issue_simple_cmd(hdw,FX2CMD_POWER_OFF); -} - - -int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw) -{ - pvr2_trace(PVR2_TRACE_INIT, - "Requesting decoder reset"); - if (hdw->decoder_client_id) { - v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id, - core, reset, 0); - pvr2_hdw_cx25840_vbi_hack(hdw); - return 0; - } - pvr2_trace(PVR2_TRACE_INIT, - "Unable to reset decoder: nothing attached"); - return -ENOTTY; -} - - -static int pvr2_hdw_cmd_hcw_demod_reset(struct pvr2_hdw *hdw, int onoff) -{ - hdw->flag_ok = !0; - return pvr2_issue_simple_cmd(hdw, - FX2CMD_HCW_DEMOD_RESETIN | - (1 << 8) | - ((onoff ? 1 : 0) << 16)); -} - - -static int pvr2_hdw_cmd_onair_fe_power_ctrl(struct pvr2_hdw *hdw, int onoff) -{ - hdw->flag_ok = !0; - return pvr2_issue_simple_cmd(hdw,(onoff ? - FX2CMD_ONAIR_DTV_POWER_ON : - FX2CMD_ONAIR_DTV_POWER_OFF)); -} - - -static int pvr2_hdw_cmd_onair_digital_path_ctrl(struct pvr2_hdw *hdw, - int onoff) -{ - return pvr2_issue_simple_cmd(hdw,(onoff ? - FX2CMD_ONAIR_DTV_STREAMING_ON : - FX2CMD_ONAIR_DTV_STREAMING_OFF)); -} - - -static void pvr2_hdw_cmd_modeswitch(struct pvr2_hdw *hdw,int digitalFl) -{ - int cmode; - /* Compare digital/analog desired setting with current setting. If - they don't match, fix it... */ - cmode = (digitalFl ? PVR2_PATHWAY_DIGITAL : PVR2_PATHWAY_ANALOG); - if (cmode == hdw->pathway_state) { - /* They match; nothing to do */ - return; - } - - switch (hdw->hdw_desc->digital_control_scheme) { - case PVR2_DIGITAL_SCHEME_HAUPPAUGE: - pvr2_hdw_cmd_hcw_demod_reset(hdw,digitalFl); - if (cmode == PVR2_PATHWAY_ANALOG) { - /* If moving to analog mode, also force the decoder - to reset. If no decoder is attached, then it's - ok to ignore this because if/when the decoder - attaches, it will reset itself at that time. */ - pvr2_hdw_cmd_decoder_reset(hdw); - } - break; - case PVR2_DIGITAL_SCHEME_ONAIR: - /* Supposedly we should always have the power on whether in - digital or analog mode. But for now do what appears to - work... */ - pvr2_hdw_cmd_onair_fe_power_ctrl(hdw,digitalFl); - break; - default: break; - } - - pvr2_hdw_untrip_unlocked(hdw); - hdw->pathway_state = cmode; -} - - -static void pvr2_led_ctrl_hauppauge(struct pvr2_hdw *hdw, int onoff) -{ - /* change some GPIO data - * - * note: bit d7 of dir appears to control the LED, - * so we shut it off here. - * - */ - if (onoff) { - pvr2_hdw_gpio_chg_dir(hdw, 0xffffffff, 0x00000481); - } else { - pvr2_hdw_gpio_chg_dir(hdw, 0xffffffff, 0x00000401); - } - pvr2_hdw_gpio_chg_out(hdw, 0xffffffff, 0x00000000); -} - - -typedef void (*led_method_func)(struct pvr2_hdw *,int); - -static led_method_func led_methods[] = { - [PVR2_LED_SCHEME_HAUPPAUGE] = pvr2_led_ctrl_hauppauge, -}; - - -/* Toggle LED */ -static void pvr2_led_ctrl(struct pvr2_hdw *hdw,int onoff) -{ - unsigned int scheme_id; - led_method_func fp; - - if ((!onoff) == (!hdw->led_on)) return; - - hdw->led_on = onoff != 0; - - scheme_id = hdw->hdw_desc->led_scheme; - if (scheme_id < ARRAY_SIZE(led_methods)) { - fp = led_methods[scheme_id]; - } else { - fp = NULL; - } - - if (fp) (*fp)(hdw,onoff); -} - - -/* Stop / start video stream transport */ -static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl) -{ - int ret; - - /* If we're in analog mode, then just issue the usual analog - command. */ - if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) { - return pvr2_issue_simple_cmd(hdw, - (runFl ? - FX2CMD_STREAMING_ON : - FX2CMD_STREAMING_OFF)); - /*Note: Not reached */ - } - - if (hdw->pathway_state != PVR2_PATHWAY_DIGITAL) { - /* Whoops, we don't know what mode we're in... */ - return -EINVAL; - } - - /* To get here we have to be in digital mode. The mechanism here - is unfortunately different for different vendors. So we switch - on the device's digital scheme attribute in order to figure out - what to do. */ - switch (hdw->hdw_desc->digital_control_scheme) { - case PVR2_DIGITAL_SCHEME_HAUPPAUGE: - return pvr2_issue_simple_cmd(hdw, - (runFl ? - FX2CMD_HCW_DTV_STREAMING_ON : - FX2CMD_HCW_DTV_STREAMING_OFF)); - case PVR2_DIGITAL_SCHEME_ONAIR: - ret = pvr2_issue_simple_cmd(hdw, - (runFl ? - FX2CMD_STREAMING_ON : - FX2CMD_STREAMING_OFF)); - if (ret) return ret; - return pvr2_hdw_cmd_onair_digital_path_ctrl(hdw,runFl); - default: - return -EINVAL; - } -} - - -/* Evaluate whether or not state_pathway_ok can change */ -static int state_eval_pathway_ok(struct pvr2_hdw *hdw) -{ - if (hdw->state_pathway_ok) { - /* Nothing to do if pathway is already ok */ - return 0; - } - if (!hdw->state_pipeline_idle) { - /* Not allowed to change anything if pipeline is not idle */ - return 0; - } - pvr2_hdw_cmd_modeswitch(hdw,hdw->input_val == PVR2_CVAL_INPUT_DTV); - hdw->state_pathway_ok = !0; - trace_stbit("state_pathway_ok",hdw->state_pathway_ok); - return !0; -} - - -/* Evaluate whether or not state_encoder_ok can change */ -static int state_eval_encoder_ok(struct pvr2_hdw *hdw) -{ - if (hdw->state_encoder_ok) return 0; - if (hdw->flag_tripped) return 0; - if (hdw->state_encoder_run) return 0; - if (hdw->state_encoder_config) return 0; - if (hdw->state_decoder_run) return 0; - if (hdw->state_usbstream_run) return 0; - if (hdw->pathway_state == PVR2_PATHWAY_DIGITAL) { - if (!hdw->hdw_desc->flag_digital_requires_cx23416) return 0; - } else if (hdw->pathway_state != PVR2_PATHWAY_ANALOG) { - return 0; - } - - if (pvr2_upload_firmware2(hdw) < 0) { - hdw->flag_tripped = !0; - trace_stbit("flag_tripped",hdw->flag_tripped); - return !0; - } - hdw->state_encoder_ok = !0; - trace_stbit("state_encoder_ok",hdw->state_encoder_ok); - return !0; -} - - -/* Evaluate whether or not state_encoder_config can change */ -static int state_eval_encoder_config(struct pvr2_hdw *hdw) -{ - if (hdw->state_encoder_config) { - if (hdw->state_encoder_ok) { - if (hdw->state_pipeline_req && - !hdw->state_pipeline_pause) return 0; - } - hdw->state_encoder_config = 0; - hdw->state_encoder_waitok = 0; - trace_stbit("state_encoder_waitok",hdw->state_encoder_waitok); - /* paranoia - solve race if timer just completed */ - del_timer_sync(&hdw->encoder_wait_timer); - } else { - if (!hdw->state_pathway_ok || - (hdw->pathway_state != PVR2_PATHWAY_ANALOG) || - !hdw->state_encoder_ok || - !hdw->state_pipeline_idle || - hdw->state_pipeline_pause || - !hdw->state_pipeline_req || - !hdw->state_pipeline_config) { - /* We must reset the enforced wait interval if - anything has happened that might have disturbed - the encoder. This should be a rare case. */ - if (timer_pending(&hdw->encoder_wait_timer)) { - del_timer_sync(&hdw->encoder_wait_timer); - } - if (hdw->state_encoder_waitok) { - /* Must clear the state - therefore we did - something to a state bit and must also - return true. */ - hdw->state_encoder_waitok = 0; - trace_stbit("state_encoder_waitok", - hdw->state_encoder_waitok); - return !0; - } - return 0; - } - if (!hdw->state_encoder_waitok) { - if (!timer_pending(&hdw->encoder_wait_timer)) { - /* waitok flag wasn't set and timer isn't - running. Check flag once more to avoid - a race then start the timer. This is - the point when we measure out a minimal - quiet interval before doing something to - the encoder. */ - if (!hdw->state_encoder_waitok) { - hdw->encoder_wait_timer.expires = - jiffies + - (HZ * TIME_MSEC_ENCODER_WAIT - / 1000); - add_timer(&hdw->encoder_wait_timer); - } - } - /* We can't continue until we know we have been - quiet for the interval measured by this - timer. */ - return 0; - } - pvr2_encoder_configure(hdw); - if (hdw->state_encoder_ok) hdw->state_encoder_config = !0; - } - trace_stbit("state_encoder_config",hdw->state_encoder_config); - return !0; -} - - -/* Return true if the encoder should not be running. */ -static int state_check_disable_encoder_run(struct pvr2_hdw *hdw) -{ - if (!hdw->state_encoder_ok) { - /* Encoder isn't healthy at the moment, so stop it. */ - return !0; - } - if (!hdw->state_pathway_ok) { - /* Mode is not understood at the moment (i.e. it wants to - change), so encoder must be stopped. */ - return !0; - } - - switch (hdw->pathway_state) { - case PVR2_PATHWAY_ANALOG: - if (!hdw->state_decoder_run) { - /* We're in analog mode and the decoder is not - running; thus the encoder should be stopped as - well. */ - return !0; - } - break; - case PVR2_PATHWAY_DIGITAL: - if (hdw->state_encoder_runok) { - /* This is a funny case. We're in digital mode so - really the encoder should be stopped. However - if it really is running, only kill it after - runok has been set. This gives a chance for the - onair quirk to function (encoder must run - briefly first, at least once, before onair - digital streaming can work). */ - return !0; - } - break; - default: - /* Unknown mode; so encoder should be stopped. */ - return !0; - } - - /* If we get here, we haven't found a reason to stop the - encoder. */ - return 0; -} - - -/* Return true if the encoder should be running. */ -static int state_check_enable_encoder_run(struct pvr2_hdw *hdw) -{ - if (!hdw->state_encoder_ok) { - /* Don't run the encoder if it isn't healthy... */ - return 0; - } - if (!hdw->state_pathway_ok) { - /* Don't run the encoder if we don't (yet) know what mode - we need to be in... */ - return 0; - } - - switch (hdw->pathway_state) { - case PVR2_PATHWAY_ANALOG: - if (hdw->state_decoder_run && hdw->state_decoder_ready) { - /* In analog mode, if the decoder is running, then - run the encoder. */ - return !0; - } - break; - case PVR2_PATHWAY_DIGITAL: - if ((hdw->hdw_desc->digital_control_scheme == - PVR2_DIGITAL_SCHEME_ONAIR) && - !hdw->state_encoder_runok) { - /* This is a quirk. OnAir hardware won't stream - digital until the encoder has been run at least - once, for a minimal period of time (empiricially - measured to be 1/4 second). So if we're on - OnAir hardware and the encoder has never been - run at all, then start the encoder. Normal - state machine logic in the driver will - automatically handle the remaining bits. */ - return !0; - } - break; - default: - /* For completeness (unknown mode; encoder won't run ever) */ - break; - } - /* If we get here, then we haven't found any reason to run the - encoder, so don't run it. */ - return 0; -} - - -/* Evaluate whether or not state_encoder_run can change */ -static int state_eval_encoder_run(struct pvr2_hdw *hdw) -{ - if (hdw->state_encoder_run) { - if (!state_check_disable_encoder_run(hdw)) return 0; - if (hdw->state_encoder_ok) { - del_timer_sync(&hdw->encoder_run_timer); - if (pvr2_encoder_stop(hdw) < 0) return !0; - } - hdw->state_encoder_run = 0; - } else { - if (!state_check_enable_encoder_run(hdw)) return 0; - if (pvr2_encoder_start(hdw) < 0) return !0; - hdw->state_encoder_run = !0; - if (!hdw->state_encoder_runok) { - hdw->encoder_run_timer.expires = - jiffies + (HZ * TIME_MSEC_ENCODER_OK / 1000); - add_timer(&hdw->encoder_run_timer); - } - } - trace_stbit("state_encoder_run",hdw->state_encoder_run); - return !0; -} - - -/* Timeout function for quiescent timer. */ -static void pvr2_hdw_quiescent_timeout(unsigned long data) -{ - struct pvr2_hdw *hdw = (struct pvr2_hdw *)data; - hdw->state_decoder_quiescent = !0; - trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent); - hdw->state_stale = !0; - queue_work(hdw->workqueue,&hdw->workpoll); -} - - -/* Timeout function for decoder stabilization timer. */ -static void pvr2_hdw_decoder_stabilization_timeout(unsigned long data) -{ - struct pvr2_hdw *hdw = (struct pvr2_hdw *)data; - hdw->state_decoder_ready = !0; - trace_stbit("state_decoder_ready", hdw->state_decoder_ready); - hdw->state_stale = !0; - queue_work(hdw->workqueue, &hdw->workpoll); -} - - -/* Timeout function for encoder wait timer. */ -static void pvr2_hdw_encoder_wait_timeout(unsigned long data) -{ - struct pvr2_hdw *hdw = (struct pvr2_hdw *)data; - hdw->state_encoder_waitok = !0; - trace_stbit("state_encoder_waitok",hdw->state_encoder_waitok); - hdw->state_stale = !0; - queue_work(hdw->workqueue,&hdw->workpoll); -} - - -/* Timeout function for encoder run timer. */ -static void pvr2_hdw_encoder_run_timeout(unsigned long data) -{ - struct pvr2_hdw *hdw = (struct pvr2_hdw *)data; - if (!hdw->state_encoder_runok) { - hdw->state_encoder_runok = !0; - trace_stbit("state_encoder_runok",hdw->state_encoder_runok); - hdw->state_stale = !0; - queue_work(hdw->workqueue,&hdw->workpoll); - } -} - - -/* Evaluate whether or not state_decoder_run can change */ -static int state_eval_decoder_run(struct pvr2_hdw *hdw) -{ - if (hdw->state_decoder_run) { - if (hdw->state_encoder_ok) { - if (hdw->state_pipeline_req && - !hdw->state_pipeline_pause && - hdw->state_pathway_ok) return 0; - } - if (!hdw->flag_decoder_missed) { - pvr2_decoder_enable(hdw,0); - } - hdw->state_decoder_quiescent = 0; - hdw->state_decoder_run = 0; - /* paranoia - solve race if timer(s) just completed */ - del_timer_sync(&hdw->quiescent_timer); - /* Kill the stabilization timer, in case we're killing the - encoder before the previous stabilization interval has - been properly timed. */ - del_timer_sync(&hdw->decoder_stabilization_timer); - hdw->state_decoder_ready = 0; - } else { - if (!hdw->state_decoder_quiescent) { - if (!timer_pending(&hdw->quiescent_timer)) { - /* We don't do something about the - quiescent timer until right here because - we also want to catch cases where the - decoder was already not running (like - after initialization) as opposed to - knowing that we had just stopped it. - The second flag check is here to cover a - race - the timer could have run and set - this flag just after the previous check - but before we did the pending check. */ - if (!hdw->state_decoder_quiescent) { - hdw->quiescent_timer.expires = - jiffies + - (HZ * TIME_MSEC_DECODER_WAIT - / 1000); - add_timer(&hdw->quiescent_timer); - } - } - /* Don't allow decoder to start again until it has - been quiesced first. This little detail should - hopefully further stabilize the encoder. */ - return 0; - } - if (!hdw->state_pathway_ok || - (hdw->pathway_state != PVR2_PATHWAY_ANALOG) || - !hdw->state_pipeline_req || - hdw->state_pipeline_pause || - !hdw->state_pipeline_config || - !hdw->state_encoder_config || - !hdw->state_encoder_ok) return 0; - del_timer_sync(&hdw->quiescent_timer); - if (hdw->flag_decoder_missed) return 0; - if (pvr2_decoder_enable(hdw,!0) < 0) return 0; - hdw->state_decoder_quiescent = 0; - hdw->state_decoder_ready = 0; - hdw->state_decoder_run = !0; - if (hdw->decoder_client_id == PVR2_CLIENT_ID_SAA7115) { - hdw->decoder_stabilization_timer.expires = - jiffies + - (HZ * TIME_MSEC_DECODER_STABILIZATION_WAIT / - 1000); - add_timer(&hdw->decoder_stabilization_timer); - } else { - hdw->state_decoder_ready = !0; - } - } - trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent); - trace_stbit("state_decoder_run",hdw->state_decoder_run); - trace_stbit("state_decoder_ready", hdw->state_decoder_ready); - return !0; -} - - -/* Evaluate whether or not state_usbstream_run can change */ -static int state_eval_usbstream_run(struct pvr2_hdw *hdw) -{ - if (hdw->state_usbstream_run) { - int fl = !0; - if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) { - fl = (hdw->state_encoder_ok && - hdw->state_encoder_run); - } else if ((hdw->pathway_state == PVR2_PATHWAY_DIGITAL) && - (hdw->hdw_desc->flag_digital_requires_cx23416)) { - fl = hdw->state_encoder_ok; - } - if (fl && - hdw->state_pipeline_req && - !hdw->state_pipeline_pause && - hdw->state_pathway_ok) { - return 0; - } - pvr2_hdw_cmd_usbstream(hdw,0); - hdw->state_usbstream_run = 0; - } else { - if (!hdw->state_pipeline_req || - hdw->state_pipeline_pause || - !hdw->state_pathway_ok) return 0; - if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) { - if (!hdw->state_encoder_ok || - !hdw->state_encoder_run) return 0; - } else if ((hdw->pathway_state == PVR2_PATHWAY_DIGITAL) && - (hdw->hdw_desc->flag_digital_requires_cx23416)) { - if (!hdw->state_encoder_ok) return 0; - if (hdw->state_encoder_run) return 0; - if (hdw->hdw_desc->digital_control_scheme == - PVR2_DIGITAL_SCHEME_ONAIR) { - /* OnAir digital receivers won't stream - unless the analog encoder has run first. - Why? I have no idea. But don't even - try until we know the analog side is - known to have run. */ - if (!hdw->state_encoder_runok) return 0; - } - } - if (pvr2_hdw_cmd_usbstream(hdw,!0) < 0) return 0; - hdw->state_usbstream_run = !0; - } - trace_stbit("state_usbstream_run",hdw->state_usbstream_run); - return !0; -} - - -/* Attempt to configure pipeline, if needed */ -static int state_eval_pipeline_config(struct pvr2_hdw *hdw) -{ - if (hdw->state_pipeline_config || - hdw->state_pipeline_pause) return 0; - pvr2_hdw_commit_execute(hdw); - return !0; -} - - -/* Update pipeline idle and pipeline pause tracking states based on other - inputs. This must be called whenever the other relevant inputs have - changed. */ -static int state_update_pipeline_state(struct pvr2_hdw *hdw) -{ - unsigned int st; - int updatedFl = 0; - /* Update pipeline state */ - st = !(hdw->state_encoder_run || - hdw->state_decoder_run || - hdw->state_usbstream_run || - (!hdw->state_decoder_quiescent)); - if (!st != !hdw->state_pipeline_idle) { - hdw->state_pipeline_idle = st; - updatedFl = !0; - } - if (hdw->state_pipeline_idle && hdw->state_pipeline_pause) { - hdw->state_pipeline_pause = 0; - updatedFl = !0; - } - return updatedFl; -} - - -typedef int (*state_eval_func)(struct pvr2_hdw *); - -/* Set of functions to be run to evaluate various states in the driver. */ -static const state_eval_func eval_funcs[] = { - state_eval_pathway_ok, - state_eval_pipeline_config, - state_eval_encoder_ok, - state_eval_encoder_config, - state_eval_decoder_run, - state_eval_encoder_run, - state_eval_usbstream_run, -}; - - -/* Process various states and return true if we did anything interesting. */ -static int pvr2_hdw_state_update(struct pvr2_hdw *hdw) -{ - unsigned int i; - int state_updated = 0; - int check_flag; - - if (!hdw->state_stale) return 0; - if ((hdw->fw1_state != FW1_STATE_OK) || - !hdw->flag_ok) { - hdw->state_stale = 0; - return !0; - } - /* This loop is the heart of the entire driver. It keeps trying to - evaluate various bits of driver state until nothing changes for - one full iteration. Each "bit of state" tracks some global - aspect of the driver, e.g. whether decoder should run, if - pipeline is configured, usb streaming is on, etc. We separately - evaluate each of those questions based on other driver state to - arrive at the correct running configuration. */ - do { - check_flag = 0; - state_update_pipeline_state(hdw); - /* Iterate over each bit of state */ - for (i = 0; (i<ARRAY_SIZE(eval_funcs)) && hdw->flag_ok; i++) { - if ((*eval_funcs[i])(hdw)) { - check_flag = !0; - state_updated = !0; - state_update_pipeline_state(hdw); - } - } - } while (check_flag && hdw->flag_ok); - hdw->state_stale = 0; - trace_stbit("state_stale",hdw->state_stale); - return state_updated; -} - - -static unsigned int print_input_mask(unsigned int msk, - char *buf,unsigned int acnt) -{ - unsigned int idx,ccnt; - unsigned int tcnt = 0; - for (idx = 0; idx < ARRAY_SIZE(control_values_input); idx++) { - if (!((1 << idx) & msk)) continue; - ccnt = scnprintf(buf+tcnt, - acnt-tcnt, - "%s%s", - (tcnt ? ", " : ""), - control_values_input[idx]); - tcnt += ccnt; - } - return tcnt; -} - - -static const char *pvr2_pathway_state_name(int id) -{ - switch (id) { - case PVR2_PATHWAY_ANALOG: return "analog"; - case PVR2_PATHWAY_DIGITAL: return "digital"; - default: return "unknown"; - } -} - - -static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which, - char *buf,unsigned int acnt) -{ - switch (which) { - case 0: - return scnprintf( - buf,acnt, - "driver:%s%s%s%s%s <mode=%s>", - (hdw->flag_ok ? " <ok>" : " <fail>"), - (hdw->flag_init_ok ? " <init>" : " <uninitialized>"), - (hdw->flag_disconnected ? " <disconnected>" : - " <connected>"), - (hdw->flag_tripped ? " <tripped>" : ""), - (hdw->flag_decoder_missed ? " <no decoder>" : ""), - pvr2_pathway_state_name(hdw->pathway_state)); - - case 1: - return scnprintf( - buf,acnt, - "pipeline:%s%s%s%s", - (hdw->state_pipeline_idle ? " <idle>" : ""), - (hdw->state_pipeline_config ? - " <configok>" : " <stale>"), - (hdw->state_pipeline_req ? " <req>" : ""), - (hdw->state_pipeline_pause ? " <pause>" : "")); - case 2: - return scnprintf( - buf,acnt, - "worker:%s%s%s%s%s%s%s", - (hdw->state_decoder_run ? - (hdw->state_decoder_ready ? - "<decode:run>" : " <decode:start>") : - (hdw->state_decoder_quiescent ? - "" : " <decode:stop>")), - (hdw->state_decoder_quiescent ? - " <decode:quiescent>" : ""), - (hdw->state_encoder_ok ? - "" : " <encode:init>"), - (hdw->state_encoder_run ? - (hdw->state_encoder_runok ? - " <encode:run>" : - " <encode:firstrun>") : - (hdw->state_encoder_runok ? - " <encode:stop>" : - " <encode:virgin>")), - (hdw->state_encoder_config ? - " <encode:configok>" : - (hdw->state_encoder_waitok ? - "" : " <encode:waitok>")), - (hdw->state_usbstream_run ? - " <usb:run>" : " <usb:stop>"), - (hdw->state_pathway_ok ? - " <pathway:ok>" : "")); - case 3: - return scnprintf( - buf,acnt, - "state: %s", - pvr2_get_state_name(hdw->master_state)); - case 4: { - unsigned int tcnt = 0; - unsigned int ccnt; - - ccnt = scnprintf(buf, - acnt, - "Hardware supported inputs: "); - tcnt += ccnt; - tcnt += print_input_mask(hdw->input_avail_mask, - buf+tcnt, - acnt-tcnt); - if (hdw->input_avail_mask != hdw->input_allowed_mask) { - ccnt = scnprintf(buf+tcnt, - acnt-tcnt, - "; allowed inputs: "); - tcnt += ccnt; - tcnt += print_input_mask(hdw->input_allowed_mask, - buf+tcnt, - acnt-tcnt); - } - return tcnt; - } - case 5: { - struct pvr2_stream_stats stats; - if (!hdw->vid_stream) break; - pvr2_stream_get_stats(hdw->vid_stream, - &stats, - 0); - return scnprintf( - buf,acnt, - "Bytes streamed=%u" - " URBs: queued=%u idle=%u ready=%u" - " processed=%u failed=%u", - stats.bytes_processed, - stats.buffers_in_queue, - stats.buffers_in_idle, - stats.buffers_in_ready, - stats.buffers_processed, - stats.buffers_failed); - } - case 6: { - unsigned int id = hdw->ir_scheme_active; - return scnprintf(buf, acnt, "ir scheme: id=%d %s", id, - (id >= ARRAY_SIZE(ir_scheme_names) ? - "?" : ir_scheme_names[id])); - } - default: break; - } - return 0; -} - - -/* Generate report containing info about attached sub-devices and attached - i2c clients, including an indication of which attached i2c clients are - actually sub-devices. */ -static unsigned int pvr2_hdw_report_clients(struct pvr2_hdw *hdw, - char *buf, unsigned int acnt) -{ - struct v4l2_subdev *sd; - unsigned int tcnt = 0; - unsigned int ccnt; - struct i2c_client *client; - const char *p; - unsigned int id; - - ccnt = scnprintf(buf, acnt, "Associated v4l2-subdev drivers and I2C clients:\n"); - tcnt += ccnt; - v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) { - id = sd->grp_id; - p = NULL; - if (id < ARRAY_SIZE(module_names)) p = module_names[id]; - if (p) { - ccnt = scnprintf(buf + tcnt, acnt - tcnt, " %s:", p); - tcnt += ccnt; - } else { - ccnt = scnprintf(buf + tcnt, acnt - tcnt, - " (unknown id=%u):", id); - tcnt += ccnt; - } - client = v4l2_get_subdevdata(sd); - if (client) { - ccnt = scnprintf(buf + tcnt, acnt - tcnt, - " %s @ %02x\n", client->name, - client->addr); - tcnt += ccnt; - } else { - ccnt = scnprintf(buf + tcnt, acnt - tcnt, - " no i2c client\n"); - tcnt += ccnt; - } - } - return tcnt; -} - - -unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw, - char *buf,unsigned int acnt) -{ - unsigned int bcnt,ccnt,idx; - bcnt = 0; - LOCK_TAKE(hdw->big_lock); - for (idx = 0; ; idx++) { - ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,acnt); - if (!ccnt) break; - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - if (!acnt) break; - buf[0] = '\n'; ccnt = 1; - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - } - ccnt = pvr2_hdw_report_clients(hdw, buf, acnt); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - LOCK_GIVE(hdw->big_lock); - return bcnt; -} - - -static void pvr2_hdw_state_log_state(struct pvr2_hdw *hdw) -{ - char buf[256]; - unsigned int idx, ccnt; - unsigned int lcnt, ucnt; - - for (idx = 0; ; idx++) { - ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,sizeof(buf)); - if (!ccnt) break; - printk(KERN_INFO "%s %.*s\n",hdw->name,ccnt,buf); - } - ccnt = pvr2_hdw_report_clients(hdw, buf, sizeof(buf)); - ucnt = 0; - while (ucnt < ccnt) { - lcnt = 0; - while ((lcnt + ucnt < ccnt) && (buf[lcnt + ucnt] != '\n')) { - lcnt++; - } - printk(KERN_INFO "%s %.*s\n", hdw->name, lcnt, buf + ucnt); - ucnt += lcnt + 1; - } -} - - -/* Evaluate and update the driver's current state, taking various actions - as appropriate for the update. */ -static int pvr2_hdw_state_eval(struct pvr2_hdw *hdw) -{ - unsigned int st; - int state_updated = 0; - int callback_flag = 0; - int analog_mode; - - pvr2_trace(PVR2_TRACE_STBITS, - "Drive state check START"); - if (pvrusb2_debug & PVR2_TRACE_STBITS) { - pvr2_hdw_state_log_state(hdw); - } - - /* Process all state and get back over disposition */ - state_updated = pvr2_hdw_state_update(hdw); - - analog_mode = (hdw->pathway_state != PVR2_PATHWAY_DIGITAL); - - /* Update master state based upon all other states. */ - if (!hdw->flag_ok) { - st = PVR2_STATE_DEAD; - } else if (hdw->fw1_state != FW1_STATE_OK) { - st = PVR2_STATE_COLD; - } else if ((analog_mode || - hdw->hdw_desc->flag_digital_requires_cx23416) && - !hdw->state_encoder_ok) { - st = PVR2_STATE_WARM; - } else if (hdw->flag_tripped || - (analog_mode && hdw->flag_decoder_missed)) { - st = PVR2_STATE_ERROR; - } else if (hdw->state_usbstream_run && - (!analog_mode || - (hdw->state_encoder_run && hdw->state_decoder_run))) { - st = PVR2_STATE_RUN; - } else { - st = PVR2_STATE_READY; - } - if (hdw->master_state != st) { - pvr2_trace(PVR2_TRACE_STATE, - "Device state change from %s to %s", - pvr2_get_state_name(hdw->master_state), - pvr2_get_state_name(st)); - pvr2_led_ctrl(hdw,st == PVR2_STATE_RUN); - hdw->master_state = st; - state_updated = !0; - callback_flag = !0; - } - if (state_updated) { - /* Trigger anyone waiting on any state changes here. */ - wake_up(&hdw->state_wait_data); - } - - if (pvrusb2_debug & PVR2_TRACE_STBITS) { - pvr2_hdw_state_log_state(hdw); - } - pvr2_trace(PVR2_TRACE_STBITS, - "Drive state check DONE callback=%d",callback_flag); - - return callback_flag; -} - - -/* Cause kernel thread to check / update driver state */ -static void pvr2_hdw_state_sched(struct pvr2_hdw *hdw) -{ - if (hdw->state_stale) return; - hdw->state_stale = !0; - trace_stbit("state_stale",hdw->state_stale); - queue_work(hdw->workqueue,&hdw->workpoll); -} - - -int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp) -{ - return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp); -} - - -int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *dp) -{ - return pvr2_read_register(hdw,PVR2_GPIO_OUT,dp); -} - - -int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *dp) -{ - return pvr2_read_register(hdw,PVR2_GPIO_IN,dp); -} - - -int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val) -{ - u32 cval,nval; - int ret; - if (~msk) { - ret = pvr2_read_register(hdw,PVR2_GPIO_DIR,&cval); - if (ret) return ret; - nval = (cval & ~msk) | (val & msk); - pvr2_trace(PVR2_TRACE_GPIO, - "GPIO direction changing 0x%x:0x%x" - " from 0x%x to 0x%x", - msk,val,cval,nval); - } else { - nval = val; - pvr2_trace(PVR2_TRACE_GPIO, - "GPIO direction changing to 0x%x",nval); - } - return pvr2_write_register(hdw,PVR2_GPIO_DIR,nval); -} - - -int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val) -{ - u32 cval,nval; - int ret; - if (~msk) { - ret = pvr2_read_register(hdw,PVR2_GPIO_OUT,&cval); - if (ret) return ret; - nval = (cval & ~msk) | (val & msk); - pvr2_trace(PVR2_TRACE_GPIO, - "GPIO output changing 0x%x:0x%x from 0x%x to 0x%x", - msk,val,cval,nval); - } else { - nval = val; - pvr2_trace(PVR2_TRACE_GPIO, - "GPIO output changing to 0x%x",nval); - } - return pvr2_write_register(hdw,PVR2_GPIO_OUT,nval); -} - - -void pvr2_hdw_status_poll(struct pvr2_hdw *hdw) -{ - struct v4l2_tuner *vtp = &hdw->tuner_signal_info; - memset(vtp, 0, sizeof(*vtp)); - vtp->type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ? - V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; - hdw->tuner_signal_stale = 0; - /* Note: There apparently is no replacement for VIDIOC_CROPCAP - using v4l2-subdev - therefore we can't support that AT ALL right - now. (Of course, no sub-drivers seem to implement it either. - But now it's a a chicken and egg problem...) */ - v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, g_tuner, vtp); - pvr2_trace(PVR2_TRACE_CHIPS, "subdev status poll" - " type=%u strength=%u audio=0x%x cap=0x%x" - " low=%u hi=%u", - vtp->type, - vtp->signal, vtp->rxsubchans, vtp->capability, - vtp->rangelow, vtp->rangehigh); - - /* We have to do this to avoid getting into constant polling if - there's nobody to answer a poll of cropcap info. */ - hdw->cropcap_stale = 0; -} - - -unsigned int pvr2_hdw_get_input_available(struct pvr2_hdw *hdw) -{ - return hdw->input_avail_mask; -} - - -unsigned int pvr2_hdw_get_input_allowed(struct pvr2_hdw *hdw) -{ - return hdw->input_allowed_mask; -} - - -static int pvr2_hdw_set_input(struct pvr2_hdw *hdw,int v) -{ - if (hdw->input_val != v) { - hdw->input_val = v; - hdw->input_dirty = !0; - } - - /* Handle side effects - if we switch to a mode that needs the RF - tuner, then select the right frequency choice as well and mark - it dirty. */ - if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) { - hdw->freqSelector = 0; - hdw->freqDirty = !0; - } else if ((hdw->input_val == PVR2_CVAL_INPUT_TV) || - (hdw->input_val == PVR2_CVAL_INPUT_DTV)) { - hdw->freqSelector = 1; - hdw->freqDirty = !0; - } - return 0; -} - - -int pvr2_hdw_set_input_allowed(struct pvr2_hdw *hdw, - unsigned int change_mask, - unsigned int change_val) -{ - int ret = 0; - unsigned int nv,m,idx; - LOCK_TAKE(hdw->big_lock); - do { - nv = hdw->input_allowed_mask & ~change_mask; - nv |= (change_val & change_mask); - nv &= hdw->input_avail_mask; - if (!nv) { - /* No legal modes left; return error instead. */ - ret = -EPERM; - break; - } - hdw->input_allowed_mask = nv; - if ((1 << hdw->input_val) & hdw->input_allowed_mask) { - /* Current mode is still in the allowed mask, so - we're done. */ - break; - } - /* Select and switch to a mode that is still in the allowed - mask */ - if (!hdw->input_allowed_mask) { - /* Nothing legal; give up */ - break; - } - m = hdw->input_allowed_mask; - for (idx = 0; idx < (sizeof(m) << 3); idx++) { - if (!((1 << idx) & m)) continue; - pvr2_hdw_set_input(hdw,idx); - break; - } - } while (0); - LOCK_GIVE(hdw->big_lock); - return ret; -} - - -/* Find I2C address of eeprom */ -static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw) -{ - int result; - LOCK_TAKE(hdw->ctl_lock); do { - hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR; - result = pvr2_send_request(hdw, - hdw->cmd_buffer,1, - hdw->cmd_buffer,1); - if (result < 0) break; - result = hdw->cmd_buffer[0]; - } while(0); LOCK_GIVE(hdw->ctl_lock); - return result; -} - - -int pvr2_hdw_register_access(struct pvr2_hdw *hdw, - struct v4l2_dbg_match *match, u64 reg_id, - int setFl, u64 *val_ptr) -{ -#ifdef CONFIG_VIDEO_ADV_DEBUG - struct v4l2_dbg_register req; - int stat = 0; - int okFl = 0; - - if (!capable(CAP_SYS_ADMIN)) return -EPERM; - - req.match = *match; - req.reg = reg_id; - if (setFl) req.val = *val_ptr; - /* It would be nice to know if a sub-device answered the request */ - v4l2_device_call_all(&hdw->v4l2_dev, 0, core, g_register, &req); - if (!setFl) *val_ptr = req.val; - if (okFl) { - return stat; - } - return -EINVAL; -#else - return -ENOSYS; -#endif -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h deleted file mode 100644 index 8060fc666eeb..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ /dev/null @@ -1,360 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ -#ifndef __PVRUSB2_HDW_H -#define __PVRUSB2_HDW_H - -#include <linux/usb.h> -#include <linux/videodev2.h> -#include "pvrusb2-io.h" -#include "pvrusb2-ctrl.h" - - -/* Private internal control ids, look these up with - pvr2_hdw_get_ctrl_by_id() - these are NOT visible in V4L */ -#define PVR2_CID_STDCUR 2 -#define PVR2_CID_STDAVAIL 3 -#define PVR2_CID_INPUT 4 -#define PVR2_CID_AUDIOMODE 5 -#define PVR2_CID_FREQUENCY 6 -#define PVR2_CID_HRES 7 -#define PVR2_CID_VRES 8 -#define PVR2_CID_CROPL 9 -#define PVR2_CID_CROPT 10 -#define PVR2_CID_CROPW 11 -#define PVR2_CID_CROPH 12 -#define PVR2_CID_CROPCAPPAN 13 -#define PVR2_CID_CROPCAPPAD 14 -#define PVR2_CID_CROPCAPBL 15 -#define PVR2_CID_CROPCAPBT 16 -#define PVR2_CID_CROPCAPBW 17 -#define PVR2_CID_CROPCAPBH 18 -#define PVR2_CID_STDDETECT 19 - -/* Legal values for the INPUT state variable */ -#define PVR2_CVAL_INPUT_TV 0 -#define PVR2_CVAL_INPUT_DTV 1 -#define PVR2_CVAL_INPUT_COMPOSITE 2 -#define PVR2_CVAL_INPUT_SVIDEO 3 -#define PVR2_CVAL_INPUT_RADIO 4 - -enum pvr2_config { - pvr2_config_empty, /* No configuration */ - pvr2_config_mpeg, /* Encoded / compressed video */ - pvr2_config_vbi, /* Standard vbi info */ - pvr2_config_pcm, /* Audio raw pcm stream */ - pvr2_config_rawvideo, /* Video raw frames */ -}; - -enum pvr2_v4l_type { - pvr2_v4l_type_video, - pvr2_v4l_type_vbi, - pvr2_v4l_type_radio, -}; - -/* Major states that we can be in: - * - * DEAD - Device is in an unusable state and cannot be recovered. This - * can happen if we completely lose the ability to communicate with it - * (but it might still on the bus). In this state there's nothing we can - * do; it must be replugged in order to recover. - * - * COLD - Device is in an unusable state, needs microcontroller firmware. - * - * WARM - We can communicate with the device and the proper - * microcontroller firmware is running, but other device initialization is - * still needed (e.g. encoder firmware). - * - * ERROR - A problem prevents capture operation (e.g. encoder firmware - * missing). - * - * READY - Device is operational, but not streaming. - * - * RUN - Device is streaming. - * - */ -#define PVR2_STATE_NONE 0 -#define PVR2_STATE_DEAD 1 -#define PVR2_STATE_COLD 2 -#define PVR2_STATE_WARM 3 -#define PVR2_STATE_ERROR 4 -#define PVR2_STATE_READY 5 -#define PVR2_STATE_RUN 6 - -/* Translate configuration enum to a string label */ -const char *pvr2_config_get_name(enum pvr2_config); - -struct pvr2_hdw; - -/* Create and return a structure for interacting with the underlying - hardware */ -struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, - const struct usb_device_id *devid); - -/* Perform second stage initialization, passing in a notification callback - for when the master state changes. */ -int pvr2_hdw_initialize(struct pvr2_hdw *, - void (*callback_func)(void *), - void *callback_data); - -/* Destroy hardware interaction structure */ -void pvr2_hdw_destroy(struct pvr2_hdw *); - -/* Return true if in the ready (normal) state */ -int pvr2_hdw_dev_ok(struct pvr2_hdw *); - -/* Return small integer number [1..N] for logical instance number of this - device. This is useful for indexing array-valued module parameters. */ -int pvr2_hdw_get_unit_number(struct pvr2_hdw *); - -/* Get pointer to underlying USB device */ -struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *); - -/* Retrieve serial number of device */ -unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *); - -/* Retrieve bus location info of device */ -const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *); - -/* Retrieve per-instance string identifier for this specific device */ -const char *pvr2_hdw_get_device_identifier(struct pvr2_hdw *); - -/* Called when hardware has been unplugged */ -void pvr2_hdw_disconnect(struct pvr2_hdw *); - -/* Get the number of defined controls */ -unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *); - -/* Retrieve a control handle given its index (0..count-1) */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *,unsigned int); - -/* Retrieve a control handle given its internal ID (if any) */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *,unsigned int); - -/* Retrieve a control handle given its V4L ID (if any) */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *,unsigned int ctl_id); - -/* Retrieve a control handle given its immediate predecessor V4L ID (if any) */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *, - unsigned int ctl_id); - -/* Commit all control changes made up to this point */ -int pvr2_hdw_commit_ctl(struct pvr2_hdw *); - -/* Return a bit mask of valid input selections for this device. Mask bits - * will be according to PVR_CVAL_INPUT_xxxx definitions. */ -unsigned int pvr2_hdw_get_input_available(struct pvr2_hdw *); - -/* Return a bit mask of allowed input selections for this device. Mask bits - * will be according to PVR_CVAL_INPUT_xxxx definitions. */ -unsigned int pvr2_hdw_get_input_allowed(struct pvr2_hdw *); - -/* Change the set of allowed input selections for this device. Both - change_mask and change_valu are mask bits according to - PVR_CVAL_INPUT_xxxx definitions. The change_mask parameter indicate - which settings are being changed and the change_val parameter indicates - whether corresponding settings are being set or cleared. */ -int pvr2_hdw_set_input_allowed(struct pvr2_hdw *, - unsigned int change_mask, - unsigned int change_val); - -/* Return name for this driver instance */ -const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *); - -/* Mark tuner status stale so that it will be re-fetched */ -void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *); - -/* Return information about the tuner */ -int pvr2_hdw_get_tuner_status(struct pvr2_hdw *,struct v4l2_tuner *); - -/* Return information about cropping capabilities */ -int pvr2_hdw_get_cropcap(struct pvr2_hdw *, struct v4l2_cropcap *); - -/* Query device and see if it thinks it is on a high-speed USB link */ -int pvr2_hdw_is_hsm(struct pvr2_hdw *); - -/* Return a string token representative of the hardware type */ -const char *pvr2_hdw_get_type(struct pvr2_hdw *); - -/* Return a single line description of the hardware type */ -const char *pvr2_hdw_get_desc(struct pvr2_hdw *); - -/* Turn streaming on/off */ -int pvr2_hdw_set_streaming(struct pvr2_hdw *,int); - -/* Find out if streaming is on */ -int pvr2_hdw_get_streaming(struct pvr2_hdw *); - -/* Retrieve driver overall state */ -int pvr2_hdw_get_state(struct pvr2_hdw *); - -/* Configure the type of stream to generate */ -int pvr2_hdw_set_stream_type(struct pvr2_hdw *, enum pvr2_config); - -/* Get handle to video output stream */ -struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *); - -/* Enable / disable retrieval of CPU firmware or prom contents. This must - be enabled before pvr2_hdw_cpufw_get() will function. Note that doing - this may prevent the device from running (and leaving this mode may - imply a device reset). */ -void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *, - int mode, /* 0=8KB FX2, 1=16KB FX2, 2=PROM */ - int enable_flag); - -/* Return true if we're in a mode for retrieval CPU firmware */ -int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *); - -/* Retrieve a piece of the CPU's firmware at the given offset. Return - value is the number of bytes retrieved or zero if we're past the end or - an error otherwise (e.g. if firmware retrieval is not enabled). */ -int pvr2_hdw_cpufw_get(struct pvr2_hdw *,unsigned int offs, - char *buf,unsigned int cnt); - -/* Retrieve a previously stored v4l minor device number */ -int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *,enum pvr2_v4l_type index); - -/* Store a v4l minor device number */ -void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *, - enum pvr2_v4l_type index,int); - -/* Direct read/write access to chip's registers: - match - specify criteria to identify target chip (this is a v4l dbg struct) - reg_id - register number to access - setFl - true to set the register, false to read it - val_ptr - storage location for source / result. */ -int pvr2_hdw_register_access(struct pvr2_hdw *, - struct v4l2_dbg_match *match, u64 reg_id, - int setFl, u64 *val_ptr); - -/* The following entry points are all lower level things you normally don't - want to worry about. */ - -/* Issue a command and get a response from the device. LOTS of higher - level stuff is built on this. */ -int pvr2_send_request(struct pvr2_hdw *, - void *write_ptr,unsigned int write_len, - void *read_ptr,unsigned int read_len); - -/* Slightly higher level device communication functions. */ -int pvr2_write_register(struct pvr2_hdw *, u16, u32); - -/* Call if for any reason we can't talk to the hardware anymore - this will - cause the driver to stop flailing on the device. */ -void pvr2_hdw_render_useless(struct pvr2_hdw *); - -/* Set / clear 8051's reset bit */ -void pvr2_hdw_cpureset_assert(struct pvr2_hdw *,int); - -/* Execute a USB-commanded device reset */ -void pvr2_hdw_device_reset(struct pvr2_hdw *); - -/* Reset worker's error trapping circuit breaker */ -int pvr2_hdw_untrip(struct pvr2_hdw *); - -/* Execute hard reset command (after this point it's likely that the - encoder will have to be reconfigured). This also clears the "useless" - state. */ -int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *); - -/* Execute simple reset command */ -int pvr2_hdw_cmd_powerup(struct pvr2_hdw *); - -/* suspend */ -int pvr2_hdw_cmd_powerdown(struct pvr2_hdw *); - -/* Order decoder to reset */ -int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *); - -/* Direct manipulation of GPIO bits */ -int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *); -int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *); -int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *); -int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val); -int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val); - -/* This data structure is specifically for the next function... */ -struct pvr2_hdw_debug_info { - int big_lock_held; - int ctl_lock_held; - int flag_disconnected; - int flag_init_ok; - int flag_ok; - int fw1_state; - int flag_decoder_missed; - int flag_tripped; - int state_encoder_ok; - int state_encoder_run; - int state_decoder_run; - int state_decoder_ready; - int state_usbstream_run; - int state_decoder_quiescent; - int state_pipeline_config; - int state_pipeline_req; - int state_pipeline_pause; - int state_pipeline_idle; - int cmd_debug_state; - int cmd_debug_write_len; - int cmd_debug_read_len; - int cmd_debug_write_pend; - int cmd_debug_read_pend; - int cmd_debug_timeout; - int cmd_debug_rstatus; - int cmd_debug_wstatus; - unsigned char cmd_code; -}; - -/* Non-intrusively retrieve internal state info - this is useful for - diagnosing lockups. Note that this operation is completed without any - kind of locking and so it is not atomic and may yield inconsistent - results. This is *purely* a debugging aid. */ -void pvr2_hdw_get_debug_info_unlocked(const struct pvr2_hdw *hdw, - struct pvr2_hdw_debug_info *); - -/* Intrusively retrieve internal state info - this is useful for - diagnosing overall driver state. This operation synchronizes against - the overall driver mutex - so if there are locking problems this will - likely hang! This is *purely* a debugging aid. */ -void pvr2_hdw_get_debug_info_locked(struct pvr2_hdw *hdw, - struct pvr2_hdw_debug_info *); - -/* Report out several lines of text that describes driver internal state. - Results are written into the passed-in buffer. */ -unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw, - char *buf_ptr,unsigned int buf_size); - -/* Cause modules to log their state once */ -void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw); - -/* Cause encoder firmware to be uploaded into the device. This is normally - done autonomously, but the interface is exported here because it is also - a debugging aid. */ -int pvr2_upload_firmware2(struct pvr2_hdw *hdw); - -#endif /* __PVRUSB2_HDW_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c deleted file mode 100644 index 885ce11f222d..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ /dev/null @@ -1,698 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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/i2c.h> -#include <linux/module.h> -#include <media/ir-kbd-i2c.h> -#include "pvrusb2-i2c-core.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include "pvrusb2-fx2-cmd.h" -#include "pvrusb2.h" - -#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__) - -/* - - This module attempts to implement a compliant I2C adapter for the pvrusb2 - device. - -*/ - -static unsigned int i2c_scan; -module_param(i2c_scan, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); - -static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 }; -module_param_array(ir_mode, int, NULL, 0444); -MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR"); - -static int pvr2_disable_ir_video; -module_param_named(disable_autoload_ir_video, pvr2_disable_ir_video, - int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(disable_autoload_ir_video, - "1=do not try to autoload ir_video IR receiver"); - -static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ - u8 i2c_addr, /* I2C address we're talking to */ - u8 *data, /* Data to write */ - u16 length) /* Size of data to write */ -{ - /* Return value - default 0 means success */ - int ret; - - - if (!data) length = 0; - if (length > (sizeof(hdw->cmd_buffer) - 3)) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Killing an I2C write to %u that is too large" - " (desired=%u limit=%u)", - i2c_addr, - length,(unsigned int)(sizeof(hdw->cmd_buffer) - 3)); - return -ENOTSUPP; - } - - LOCK_TAKE(hdw->ctl_lock); - - /* Clear the command buffer (likely to be paranoia) */ - memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer)); - - /* Set up command buffer for an I2C write */ - hdw->cmd_buffer[0] = FX2CMD_I2C_WRITE; /* write prefix */ - hdw->cmd_buffer[1] = i2c_addr; /* i2c addr of chip */ - hdw->cmd_buffer[2] = length; /* length of what follows */ - if (length) memcpy(hdw->cmd_buffer + 3, data, length); - - /* Do the operation */ - ret = pvr2_send_request(hdw, - hdw->cmd_buffer, - length + 3, - hdw->cmd_buffer, - 1); - if (!ret) { - if (hdw->cmd_buffer[0] != 8) { - ret = -EIO; - if (hdw->cmd_buffer[0] != 7) { - trace_i2c("unexpected status" - " from i2_write[%d]: %d", - i2c_addr,hdw->cmd_buffer[0]); - } - } - } - - LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - -static int pvr2_i2c_read(struct pvr2_hdw *hdw, /* Context */ - u8 i2c_addr, /* I2C address we're talking to */ - u8 *data, /* Data to write */ - u16 dlen, /* Size of data to write */ - u8 *res, /* Where to put data we read */ - u16 rlen) /* Amount of data to read */ -{ - /* Return value - default 0 means success */ - int ret; - - - if (!data) dlen = 0; - if (dlen > (sizeof(hdw->cmd_buffer) - 4)) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Killing an I2C read to %u that has wlen too large" - " (desired=%u limit=%u)", - i2c_addr, - dlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 4)); - return -ENOTSUPP; - } - if (res && (rlen > (sizeof(hdw->cmd_buffer) - 1))) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Killing an I2C read to %u that has rlen too large" - " (desired=%u limit=%u)", - i2c_addr, - rlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 1)); - return -ENOTSUPP; - } - - LOCK_TAKE(hdw->ctl_lock); - - /* Clear the command buffer (likely to be paranoia) */ - memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer)); - - /* Set up command buffer for an I2C write followed by a read */ - hdw->cmd_buffer[0] = FX2CMD_I2C_READ; /* read prefix */ - hdw->cmd_buffer[1] = dlen; /* arg length */ - hdw->cmd_buffer[2] = rlen; /* answer length. Device will send one - more byte (status). */ - hdw->cmd_buffer[3] = i2c_addr; /* i2c addr of chip */ - if (dlen) memcpy(hdw->cmd_buffer + 4, data, dlen); - - /* Do the operation */ - ret = pvr2_send_request(hdw, - hdw->cmd_buffer, - 4 + dlen, - hdw->cmd_buffer, - rlen + 1); - if (!ret) { - if (hdw->cmd_buffer[0] != 8) { - ret = -EIO; - if (hdw->cmd_buffer[0] != 7) { - trace_i2c("unexpected status" - " from i2_read[%d]: %d", - i2c_addr,hdw->cmd_buffer[0]); - } - } - } - - /* Copy back the result */ - if (res && rlen) { - if (ret) { - /* Error, just blank out the return buffer */ - memset(res, 0, rlen); - } else { - memcpy(res, hdw->cmd_buffer + 1, rlen); - } - } - - LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - -/* This is the common low level entry point for doing I2C operations to the - hardware. */ -static int pvr2_i2c_basic_op(struct pvr2_hdw *hdw, - u8 i2c_addr, - u8 *wdata, - u16 wlen, - u8 *rdata, - u16 rlen) -{ - if (!rdata) rlen = 0; - if (!wdata) wlen = 0; - if (rlen || !wlen) { - return pvr2_i2c_read(hdw,i2c_addr,wdata,wlen,rdata,rlen); - } else { - return pvr2_i2c_write(hdw,i2c_addr,wdata,wlen); - } -} - - -/* This is a special entry point for cases of I2C transaction attempts to - the IR receiver. The implementation here simulates the IR receiver by - issuing a command to the FX2 firmware and using that response to return - what the real I2C receiver would have returned. We use this for 24xxx - devices, where the IR receiver chip has been removed and replaced with - FX2 related logic. */ -static int i2c_24xxx_ir(struct pvr2_hdw *hdw, - u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen) -{ - u8 dat[4]; - unsigned int stat; - - if (!(rlen || wlen)) { - /* This is a probe attempt. Just let it succeed. */ - return 0; - } - - /* We don't understand this kind of transaction */ - if ((wlen != 0) || (rlen == 0)) return -EIO; - - if (rlen < 3) { - /* Mike Isely <isely@pobox.com> Appears to be a probe - attempt from lirc. Just fill in zeroes and return. If - we try instead to do the full transaction here, then bad - things seem to happen within the lirc driver module - (version 0.8.0-7 sources from Debian, when run under - vanilla 2.6.17.6 kernel) - and I don't have the patience - to chase it down. */ - if (rlen > 0) rdata[0] = 0; - if (rlen > 1) rdata[1] = 0; - return 0; - } - - /* Issue a command to the FX2 to read the IR receiver. */ - LOCK_TAKE(hdw->ctl_lock); do { - hdw->cmd_buffer[0] = FX2CMD_GET_IR_CODE; - stat = pvr2_send_request(hdw, - hdw->cmd_buffer,1, - hdw->cmd_buffer,4); - dat[0] = hdw->cmd_buffer[0]; - dat[1] = hdw->cmd_buffer[1]; - dat[2] = hdw->cmd_buffer[2]; - dat[3] = hdw->cmd_buffer[3]; - } while (0); LOCK_GIVE(hdw->ctl_lock); - - /* Give up if that operation failed. */ - if (stat != 0) return stat; - - /* Mangle the results into something that looks like the real IR - receiver. */ - rdata[2] = 0xc1; - if (dat[0] != 1) { - /* No code received. */ - rdata[0] = 0; - rdata[1] = 0; - } else { - u16 val; - /* Mash the FX2 firmware-provided IR code into something - that the normal i2c chip-level driver expects. */ - val = dat[1]; - val <<= 8; - val |= dat[2]; - val >>= 1; - val &= ~0x0003; - val |= 0x8000; - rdata[0] = (val >> 8) & 0xffu; - rdata[1] = val & 0xffu; - } - - return 0; -} - -/* This is a special entry point that is entered if an I2C operation is - attempted to a wm8775 chip on model 24xxx hardware. Autodetect of this - part doesn't work, but we know it is really there. So let's look for - the autodetect attempt and just return success if we see that. */ -static int i2c_hack_wm8775(struct pvr2_hdw *hdw, - u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen) -{ - if (!(rlen || wlen)) { - // This is a probe attempt. Just let it succeed. - return 0; - } - return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen); -} - -/* This is an entry point designed to always fail any attempt to perform a - transfer. We use this to cause certain I2C addresses to not be - probed. */ -static int i2c_black_hole(struct pvr2_hdw *hdw, - u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen) -{ - return -EIO; -} - -/* This is a special entry point that is entered if an I2C operation is - attempted to a cx25840 chip on model 24xxx hardware. This chip can - sometimes wedge itself. Worse still, when this happens msp3400 can - falsely detect this part and then the system gets hosed up after msp3400 - gets confused and dies. What we want to do here is try to keep msp3400 - away and also try to notice if the chip is wedged and send a warning to - the system log. */ -static int i2c_hack_cx25840(struct pvr2_hdw *hdw, - u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen) -{ - int ret; - unsigned int subaddr; - u8 wbuf[2]; - int state = hdw->i2c_cx25840_hack_state; - - if (!(rlen || wlen)) { - // Probe attempt - always just succeed and don't bother the - // hardware (this helps to make the state machine further - // down somewhat easier). - return 0; - } - - if (state == 3) { - return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen); - } - - /* We're looking for the exact pattern where the revision register - is being read. The cx25840 module will always look at the - revision register first. Any other pattern of access therefore - has to be a probe attempt from somebody else so we'll reject it. - Normally we could just let each client just probe the part - anyway, but when the cx25840 is wedged, msp3400 will get a false - positive and that just screws things up... */ - - if (wlen == 0) { - switch (state) { - case 1: subaddr = 0x0100; break; - case 2: subaddr = 0x0101; break; - default: goto fail; - } - } else if (wlen == 2) { - subaddr = (wdata[0] << 8) | wdata[1]; - switch (subaddr) { - case 0x0100: state = 1; break; - case 0x0101: state = 2; break; - default: goto fail; - } - } else { - goto fail; - } - if (!rlen) goto success; - state = 0; - if (rlen != 1) goto fail; - - /* If we get to here then we have a legitimate read for one of the - two revision bytes, so pass it through. */ - wbuf[0] = subaddr >> 8; - wbuf[1] = subaddr; - ret = pvr2_i2c_basic_op(hdw,i2c_addr,wbuf,2,rdata,rlen); - - if ((ret != 0) || (*rdata == 0x04) || (*rdata == 0x0a)) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "WARNING: Detected a wedged cx25840 chip;" - " the device will not work."); - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "WARNING: Try power cycling the pvrusb2 device."); - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "WARNING: Disabling further access to the device" - " to prevent other foul-ups."); - // This blocks all further communication with the part. - hdw->i2c_func[0x44] = NULL; - pvr2_hdw_render_useless(hdw); - goto fail; - } - - /* Success! */ - pvr2_trace(PVR2_TRACE_CHIPS,"cx25840 appears to be OK."); - state = 3; - - success: - hdw->i2c_cx25840_hack_state = state; - return 0; - - fail: - hdw->i2c_cx25840_hack_state = state; - return -EIO; -} - -/* This is a very, very limited I2C adapter implementation. We can only - support what we actually know will work on the device... */ -static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg msgs[], - int num) -{ - int ret = -ENOTSUPP; - pvr2_i2c_func funcp = NULL; - struct pvr2_hdw *hdw = (struct pvr2_hdw *)(i2c_adap->algo_data); - - if (!num) { - ret = -EINVAL; - goto done; - } - if (msgs[0].addr < PVR2_I2C_FUNC_CNT) { - funcp = hdw->i2c_func[msgs[0].addr]; - } - if (!funcp) { - ret = -EIO; - goto done; - } - - if (num == 1) { - if (msgs[0].flags & I2C_M_RD) { - /* Simple read */ - u16 tcnt,bcnt,offs; - if (!msgs[0].len) { - /* Length == 0 read. This is a probe. */ - if (funcp(hdw,msgs[0].addr,NULL,0,NULL,0)) { - ret = -EIO; - goto done; - } - ret = 1; - goto done; - } - /* If the read is short enough we'll do the whole - thing atomically. Otherwise we have no choice - but to break apart the reads. */ - tcnt = msgs[0].len; - offs = 0; - while (tcnt) { - bcnt = tcnt; - if (bcnt > sizeof(hdw->cmd_buffer)-1) { - bcnt = sizeof(hdw->cmd_buffer)-1; - } - if (funcp(hdw,msgs[0].addr,NULL,0, - msgs[0].buf+offs,bcnt)) { - ret = -EIO; - goto done; - } - offs += bcnt; - tcnt -= bcnt; - } - ret = 1; - goto done; - } else { - /* Simple write */ - ret = 1; - if (funcp(hdw,msgs[0].addr, - msgs[0].buf,msgs[0].len,NULL,0)) { - ret = -EIO; - } - goto done; - } - } else if (num == 2) { - if (msgs[0].addr != msgs[1].addr) { - trace_i2c("i2c refusing 2 phase transfer with" - " conflicting target addresses"); - ret = -ENOTSUPP; - goto done; - } - if ((!((msgs[0].flags & I2C_M_RD))) && - (msgs[1].flags & I2C_M_RD)) { - u16 tcnt,bcnt,wcnt,offs; - /* Write followed by atomic read. If the read - portion is short enough we'll do the whole thing - atomically. Otherwise we have no choice but to - break apart the reads. */ - tcnt = msgs[1].len; - wcnt = msgs[0].len; - offs = 0; - while (tcnt || wcnt) { - bcnt = tcnt; - if (bcnt > sizeof(hdw->cmd_buffer)-1) { - bcnt = sizeof(hdw->cmd_buffer)-1; - } - if (funcp(hdw,msgs[0].addr, - msgs[0].buf,wcnt, - msgs[1].buf+offs,bcnt)) { - ret = -EIO; - goto done; - } - offs += bcnt; - tcnt -= bcnt; - wcnt = 0; - } - ret = 2; - goto done; - } else { - trace_i2c("i2c refusing complex transfer" - " read0=%d read1=%d", - (msgs[0].flags & I2C_M_RD), - (msgs[1].flags & I2C_M_RD)); - } - } else { - trace_i2c("i2c refusing %d phase transfer",num); - } - - done: - if (pvrusb2_debug & PVR2_TRACE_I2C_TRAF) { - unsigned int idx,offs,cnt; - for (idx = 0; idx < num; idx++) { - cnt = msgs[idx].len; - printk(KERN_INFO - "pvrusb2 i2c xfer %u/%u:" - " addr=0x%x len=%d %s", - idx+1,num, - msgs[idx].addr, - cnt, - (msgs[idx].flags & I2C_M_RD ? - "read" : "write")); - if ((ret > 0) || !(msgs[idx].flags & I2C_M_RD)) { - if (cnt > 8) cnt = 8; - printk(" ["); - for (offs = 0; offs < (cnt>8?8:cnt); offs++) { - if (offs) printk(" "); - printk("%02x",msgs[idx].buf[offs]); - } - if (offs < cnt) printk(" ..."); - printk("]"); - } - if (idx+1 == num) { - printk(" result=%d",ret); - } - printk("\n"); - } - if (!num) { - printk(KERN_INFO - "pvrusb2 i2c xfer null transfer result=%d\n", - ret); - } - } - return ret; -} - -static u32 pvr2_i2c_functionality(struct i2c_adapter *adap) -{ - return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; -} - -static struct i2c_algorithm pvr2_i2c_algo_template = { - .master_xfer = pvr2_i2c_xfer, - .functionality = pvr2_i2c_functionality, -}; - -static struct i2c_adapter pvr2_i2c_adap_template = { - .owner = THIS_MODULE, - .class = 0, -}; - - -/* Return true if device exists at given address */ -static int do_i2c_probe(struct pvr2_hdw *hdw, int addr) -{ - struct i2c_msg msg[1]; - int rc; - msg[0].addr = 0; - msg[0].flags = I2C_M_RD; - msg[0].len = 0; - msg[0].buf = NULL; - msg[0].addr = addr; - rc = i2c_transfer(&hdw->i2c_adap, msg, ARRAY_SIZE(msg)); - return rc == 1; -} - -static void do_i2c_scan(struct pvr2_hdw *hdw) -{ - int i; - printk(KERN_INFO "%s: i2c scan beginning\n", hdw->name); - for (i = 0; i < 128; i++) { - if (do_i2c_probe(hdw, i)) { - printk(KERN_INFO "%s: i2c scan: found device @ 0x%x\n", - hdw->name, i); - } - } - printk(KERN_INFO "%s: i2c scan done.\n", hdw->name); -} - -static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw) -{ - struct i2c_board_info info; - struct IR_i2c_init_data *init_data = &hdw->ir_init_data; - if (pvr2_disable_ir_video) { - pvr2_trace(PVR2_TRACE_INFO, - "Automatic binding of ir_video has been disabled."); - return; - } - memset(&info, 0, sizeof(struct i2c_board_info)); - switch (hdw->ir_scheme_active) { - case PVR2_IR_SCHEME_24XXX: /* FX2-controlled IR */ - case PVR2_IR_SCHEME_29XXX: /* Original 29xxx device */ - init_data->ir_codes = RC_MAP_HAUPPAUGE; - init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP; - init_data->type = RC_TYPE_RC5; - init_data->name = hdw->hdw_desc->description; - init_data->polling_interval = 100; /* ms From ir-kbd-i2c */ - /* IR Receiver */ - info.addr = 0x18; - info.platform_data = init_data; - strlcpy(info.type, "ir_video", I2C_NAME_SIZE); - pvr2_trace(PVR2_TRACE_INFO, "Binding %s to i2c address 0x%02x.", - info.type, info.addr); - i2c_new_device(&hdw->i2c_adap, &info); - break; - case PVR2_IR_SCHEME_ZILOG: /* HVR-1950 style */ - case PVR2_IR_SCHEME_24XXX_MCE: /* 24xxx MCE device */ - init_data->ir_codes = RC_MAP_HAUPPAUGE; - init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; - init_data->type = RC_TYPE_RC5; - init_data->name = hdw->hdw_desc->description; - /* IR Receiver */ - info.addr = 0x71; - info.platform_data = init_data; - strlcpy(info.type, "ir_rx_z8f0811_haup", I2C_NAME_SIZE); - pvr2_trace(PVR2_TRACE_INFO, "Binding %s to i2c address 0x%02x.", - info.type, info.addr); - i2c_new_device(&hdw->i2c_adap, &info); - /* IR Trasmitter */ - info.addr = 0x70; - info.platform_data = init_data; - strlcpy(info.type, "ir_tx_z8f0811_haup", I2C_NAME_SIZE); - pvr2_trace(PVR2_TRACE_INFO, "Binding %s to i2c address 0x%02x.", - info.type, info.addr); - i2c_new_device(&hdw->i2c_adap, &info); - break; - default: - /* The device either doesn't support I2C-based IR or we - don't know (yet) how to operate IR on the device. */ - break; - } -} - -void pvr2_i2c_core_init(struct pvr2_hdw *hdw) -{ - unsigned int idx; - - /* The default action for all possible I2C addresses is just to do - the transfer normally. */ - for (idx = 0; idx < PVR2_I2C_FUNC_CNT; idx++) { - hdw->i2c_func[idx] = pvr2_i2c_basic_op; - } - - /* However, deal with various special cases for 24xxx hardware. */ - if (ir_mode[hdw->unit_number] == 0) { - printk(KERN_INFO "%s: IR disabled\n",hdw->name); - hdw->i2c_func[0x18] = i2c_black_hole; - } else if (ir_mode[hdw->unit_number] == 1) { - if (hdw->ir_scheme_active == PVR2_IR_SCHEME_24XXX) { - /* Set up translation so that our IR looks like a - 29xxx device */ - hdw->i2c_func[0x18] = i2c_24xxx_ir; - } - } - if (hdw->hdw_desc->flag_has_cx25840) { - hdw->i2c_func[0x44] = i2c_hack_cx25840; - } - if (hdw->hdw_desc->flag_has_wm8775) { - hdw->i2c_func[0x1b] = i2c_hack_wm8775; - } - - // Configure the adapter and set up everything else related to it. - memcpy(&hdw->i2c_adap,&pvr2_i2c_adap_template,sizeof(hdw->i2c_adap)); - memcpy(&hdw->i2c_algo,&pvr2_i2c_algo_template,sizeof(hdw->i2c_algo)); - strlcpy(hdw->i2c_adap.name,hdw->name,sizeof(hdw->i2c_adap.name)); - hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev; - hdw->i2c_adap.algo = &hdw->i2c_algo; - hdw->i2c_adap.algo_data = hdw; - hdw->i2c_linked = !0; - i2c_set_adapdata(&hdw->i2c_adap, &hdw->v4l2_dev); - i2c_add_adapter(&hdw->i2c_adap); - if (hdw->i2c_func[0x18] == i2c_24xxx_ir) { - /* Probe for a different type of IR receiver on this - device. This is really the only way to differentiate - older 24xxx devices from 24xxx variants that include an - IR blaster. If the IR blaster is present, the IR - receiver is part of that chip and thus we must disable - the emulated IR receiver. */ - if (do_i2c_probe(hdw, 0x71)) { - pvr2_trace(PVR2_TRACE_INFO, - "Device has newer IR hardware;" - " disabling unneeded virtual IR device"); - hdw->i2c_func[0x18] = NULL; - /* Remember that this is a different device... */ - hdw->ir_scheme_active = PVR2_IR_SCHEME_24XXX_MCE; - } - } - if (i2c_scan) do_i2c_scan(hdw); - - pvr2_i2c_register_ir(hdw); -} - -void pvr2_i2c_core_done(struct pvr2_hdw *hdw) -{ - if (hdw->i2c_linked) { - i2c_del_adapter(&hdw->i2c_adap); - hdw->i2c_linked = 0; - } -} - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h deleted file mode 100644 index 6a75769200bd..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ -#ifndef __PVRUSB2_I2C_CORE_H -#define __PVRUSB2_I2C_CORE_H - -struct pvr2_hdw; - -void pvr2_i2c_core_init(struct pvr2_hdw *); -void pvr2_i2c_core_done(struct pvr2_hdw *); - - -#endif /* __PVRUSB2_I2C_ADAPTER_H */ - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.c b/drivers/media/video/pvrusb2/pvrusb2-io.c deleted file mode 100644 index 20b6ae0bb40d..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-io.c +++ /dev/null @@ -1,695 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 "pvrusb2-io.h" -#include "pvrusb2-debug.h" -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/mutex.h> - -static const char *pvr2_buffer_state_decode(enum pvr2_buffer_state); - -#define BUFFER_SIG 0x47653271 - -// #define SANITY_CHECK_BUFFERS - - -#ifdef SANITY_CHECK_BUFFERS -#define BUFFER_CHECK(bp) do { \ - if ((bp)->signature != BUFFER_SIG) { \ - pvr2_trace(PVR2_TRACE_ERROR_LEGS, \ - "Buffer %p is bad at %s:%d", \ - (bp),__FILE__,__LINE__); \ - pvr2_buffer_describe(bp,"BadSig"); \ - BUG(); \ - } \ -} while (0) -#else -#define BUFFER_CHECK(bp) do {} while(0) -#endif - -struct pvr2_stream { - /* Buffers queued for reading */ - struct list_head queued_list; - unsigned int q_count; - unsigned int q_bcount; - /* Buffers with retrieved data */ - struct list_head ready_list; - unsigned int r_count; - unsigned int r_bcount; - /* Buffers available for use */ - struct list_head idle_list; - unsigned int i_count; - unsigned int i_bcount; - /* Pointers to all buffers */ - struct pvr2_buffer **buffers; - /* Array size of buffers */ - unsigned int buffer_slot_count; - /* Total buffers actually in circulation */ - unsigned int buffer_total_count; - /* Designed number of buffers to be in circulation */ - unsigned int buffer_target_count; - /* Executed when ready list become non-empty */ - pvr2_stream_callback callback_func; - void *callback_data; - /* Context for transfer endpoint */ - struct usb_device *dev; - int endpoint; - /* Overhead for mutex enforcement */ - spinlock_t list_lock; - struct mutex mutex; - /* Tracking state for tolerating errors */ - unsigned int fail_count; - unsigned int fail_tolerance; - - unsigned int buffers_processed; - unsigned int buffers_failed; - unsigned int bytes_processed; -}; - -struct pvr2_buffer { - int id; - int signature; - enum pvr2_buffer_state state; - void *ptr; /* Pointer to storage area */ - unsigned int max_count; /* Size of storage area */ - unsigned int used_count; /* Amount of valid data in storage area */ - int status; /* Transfer result status */ - struct pvr2_stream *stream; - struct list_head list_overhead; - struct urb *purb; -}; - -static const char *pvr2_buffer_state_decode(enum pvr2_buffer_state st) -{ - switch (st) { - case pvr2_buffer_state_none: return "none"; - case pvr2_buffer_state_idle: return "idle"; - case pvr2_buffer_state_queued: return "queued"; - case pvr2_buffer_state_ready: return "ready"; - } - return "unknown"; -} - -#ifdef SANITY_CHECK_BUFFERS -static void pvr2_buffer_describe(struct pvr2_buffer *bp,const char *msg) -{ - pvr2_trace(PVR2_TRACE_INFO, - "buffer%s%s %p state=%s id=%d status=%d" - " stream=%p purb=%p sig=0x%x", - (msg ? " " : ""), - (msg ? msg : ""), - bp, - (bp ? pvr2_buffer_state_decode(bp->state) : "(invalid)"), - (bp ? bp->id : 0), - (bp ? bp->status : 0), - (bp ? bp->stream : NULL), - (bp ? bp->purb : NULL), - (bp ? bp->signature : 0)); -} -#endif /* SANITY_CHECK_BUFFERS */ - -static void pvr2_buffer_remove(struct pvr2_buffer *bp) -{ - unsigned int *cnt; - unsigned int *bcnt; - unsigned int ccnt; - struct pvr2_stream *sp = bp->stream; - switch (bp->state) { - case pvr2_buffer_state_idle: - cnt = &sp->i_count; - bcnt = &sp->i_bcount; - ccnt = bp->max_count; - break; - case pvr2_buffer_state_queued: - cnt = &sp->q_count; - bcnt = &sp->q_bcount; - ccnt = bp->max_count; - break; - case pvr2_buffer_state_ready: - cnt = &sp->r_count; - bcnt = &sp->r_bcount; - ccnt = bp->used_count; - break; - default: - return; - } - list_del_init(&bp->list_overhead); - (*cnt)--; - (*bcnt) -= ccnt; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/" - " bufferPool %8s dec cap=%07d cnt=%02d", - pvr2_buffer_state_decode(bp->state),*bcnt,*cnt); - bp->state = pvr2_buffer_state_none; -} - -static void pvr2_buffer_set_none(struct pvr2_buffer *bp) -{ - unsigned long irq_flags; - struct pvr2_stream *sp; - BUFFER_CHECK(bp); - sp = bp->stream; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s", - bp, - pvr2_buffer_state_decode(bp->state), - pvr2_buffer_state_decode(pvr2_buffer_state_none)); - spin_lock_irqsave(&sp->list_lock,irq_flags); - pvr2_buffer_remove(bp); - spin_unlock_irqrestore(&sp->list_lock,irq_flags); -} - -static int pvr2_buffer_set_ready(struct pvr2_buffer *bp) -{ - int fl; - unsigned long irq_flags; - struct pvr2_stream *sp; - BUFFER_CHECK(bp); - sp = bp->stream; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s", - bp, - pvr2_buffer_state_decode(bp->state), - pvr2_buffer_state_decode(pvr2_buffer_state_ready)); - spin_lock_irqsave(&sp->list_lock,irq_flags); - fl = (sp->r_count == 0); - pvr2_buffer_remove(bp); - list_add_tail(&bp->list_overhead,&sp->ready_list); - bp->state = pvr2_buffer_state_ready; - (sp->r_count)++; - sp->r_bcount += bp->used_count; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/" - " bufferPool %8s inc cap=%07d cnt=%02d", - pvr2_buffer_state_decode(bp->state), - sp->r_bcount,sp->r_count); - spin_unlock_irqrestore(&sp->list_lock,irq_flags); - return fl; -} - -static void pvr2_buffer_set_idle(struct pvr2_buffer *bp) -{ - unsigned long irq_flags; - struct pvr2_stream *sp; - BUFFER_CHECK(bp); - sp = bp->stream; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s", - bp, - pvr2_buffer_state_decode(bp->state), - pvr2_buffer_state_decode(pvr2_buffer_state_idle)); - spin_lock_irqsave(&sp->list_lock,irq_flags); - pvr2_buffer_remove(bp); - list_add_tail(&bp->list_overhead,&sp->idle_list); - bp->state = pvr2_buffer_state_idle; - (sp->i_count)++; - sp->i_bcount += bp->max_count; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/" - " bufferPool %8s inc cap=%07d cnt=%02d", - pvr2_buffer_state_decode(bp->state), - sp->i_bcount,sp->i_count); - spin_unlock_irqrestore(&sp->list_lock,irq_flags); -} - -static void pvr2_buffer_set_queued(struct pvr2_buffer *bp) -{ - unsigned long irq_flags; - struct pvr2_stream *sp; - BUFFER_CHECK(bp); - sp = bp->stream; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s", - bp, - pvr2_buffer_state_decode(bp->state), - pvr2_buffer_state_decode(pvr2_buffer_state_queued)); - spin_lock_irqsave(&sp->list_lock,irq_flags); - pvr2_buffer_remove(bp); - list_add_tail(&bp->list_overhead,&sp->queued_list); - bp->state = pvr2_buffer_state_queued; - (sp->q_count)++; - sp->q_bcount += bp->max_count; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/" - " bufferPool %8s inc cap=%07d cnt=%02d", - pvr2_buffer_state_decode(bp->state), - sp->q_bcount,sp->q_count); - spin_unlock_irqrestore(&sp->list_lock,irq_flags); -} - -static void pvr2_buffer_wipe(struct pvr2_buffer *bp) -{ - if (bp->state == pvr2_buffer_state_queued) { - usb_kill_urb(bp->purb); - } -} - -static int pvr2_buffer_init(struct pvr2_buffer *bp, - struct pvr2_stream *sp, - unsigned int id) -{ - memset(bp,0,sizeof(*bp)); - bp->signature = BUFFER_SIG; - bp->id = id; - pvr2_trace(PVR2_TRACE_BUF_POOL, - "/*---TRACE_FLOW---*/ bufferInit %p stream=%p",bp,sp); - bp->stream = sp; - bp->state = pvr2_buffer_state_none; - INIT_LIST_HEAD(&bp->list_overhead); - bp->purb = usb_alloc_urb(0,GFP_KERNEL); - if (! bp->purb) return -ENOMEM; -#ifdef SANITY_CHECK_BUFFERS - pvr2_buffer_describe(bp,"create"); -#endif - return 0; -} - -static void pvr2_buffer_done(struct pvr2_buffer *bp) -{ -#ifdef SANITY_CHECK_BUFFERS - pvr2_buffer_describe(bp,"delete"); -#endif - pvr2_buffer_wipe(bp); - pvr2_buffer_set_none(bp); - bp->signature = 0; - bp->stream = NULL; - usb_free_urb(bp->purb); - pvr2_trace(PVR2_TRACE_BUF_POOL,"/*---TRACE_FLOW---*/" - " bufferDone %p",bp); -} - -static int pvr2_stream_buffer_count(struct pvr2_stream *sp,unsigned int cnt) -{ - int ret; - unsigned int scnt; - - /* Allocate buffers pointer array in multiples of 32 entries */ - if (cnt == sp->buffer_total_count) return 0; - - pvr2_trace(PVR2_TRACE_BUF_POOL, - "/*---TRACE_FLOW---*/ poolResize " - " stream=%p cur=%d adj=%+d", - sp, - sp->buffer_total_count, - cnt-sp->buffer_total_count); - - scnt = cnt & ~0x1f; - if (cnt > scnt) scnt += 0x20; - - if (cnt > sp->buffer_total_count) { - if (scnt > sp->buffer_slot_count) { - struct pvr2_buffer **nb; - nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL); - if (!nb) return -ENOMEM; - if (sp->buffer_slot_count) { - memcpy(nb,sp->buffers, - sp->buffer_slot_count * sizeof(*nb)); - kfree(sp->buffers); - } - sp->buffers = nb; - sp->buffer_slot_count = scnt; - } - while (sp->buffer_total_count < cnt) { - struct pvr2_buffer *bp; - bp = kmalloc(sizeof(*bp),GFP_KERNEL); - if (!bp) return -ENOMEM; - ret = pvr2_buffer_init(bp,sp,sp->buffer_total_count); - if (ret) { - kfree(bp); - return -ENOMEM; - } - sp->buffers[sp->buffer_total_count] = bp; - (sp->buffer_total_count)++; - pvr2_buffer_set_idle(bp); - } - } else { - while (sp->buffer_total_count > cnt) { - struct pvr2_buffer *bp; - bp = sp->buffers[sp->buffer_total_count - 1]; - /* Paranoia */ - sp->buffers[sp->buffer_total_count - 1] = NULL; - (sp->buffer_total_count)--; - pvr2_buffer_done(bp); - kfree(bp); - } - if (scnt < sp->buffer_slot_count) { - struct pvr2_buffer **nb = NULL; - if (scnt) { - nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL); - if (!nb) return -ENOMEM; - memcpy(nb,sp->buffers,scnt * sizeof(*nb)); - } - kfree(sp->buffers); - sp->buffers = nb; - sp->buffer_slot_count = scnt; - } - } - return 0; -} - -static int pvr2_stream_achieve_buffer_count(struct pvr2_stream *sp) -{ - struct pvr2_buffer *bp; - unsigned int cnt; - - if (sp->buffer_total_count == sp->buffer_target_count) return 0; - - pvr2_trace(PVR2_TRACE_BUF_POOL, - "/*---TRACE_FLOW---*/" - " poolCheck stream=%p cur=%d tgt=%d", - sp,sp->buffer_total_count,sp->buffer_target_count); - - if (sp->buffer_total_count < sp->buffer_target_count) { - return pvr2_stream_buffer_count(sp,sp->buffer_target_count); - } - - cnt = 0; - while ((sp->buffer_total_count - cnt) > sp->buffer_target_count) { - bp = sp->buffers[sp->buffer_total_count - (cnt + 1)]; - if (bp->state != pvr2_buffer_state_idle) break; - cnt++; - } - if (cnt) { - pvr2_stream_buffer_count(sp,sp->buffer_total_count - cnt); - } - - return 0; -} - -static void pvr2_stream_internal_flush(struct pvr2_stream *sp) -{ - struct list_head *lp; - struct pvr2_buffer *bp1; - while ((lp = sp->queued_list.next) != &sp->queued_list) { - bp1 = list_entry(lp,struct pvr2_buffer,list_overhead); - pvr2_buffer_wipe(bp1); - /* At this point, we should be guaranteed that no - completion callback may happen on this buffer. But it's - possible that it might have completed after we noticed - it but before we wiped it. So double check its status - here first. */ - if (bp1->state != pvr2_buffer_state_queued) continue; - pvr2_buffer_set_idle(bp1); - } - if (sp->buffer_total_count != sp->buffer_target_count) { - pvr2_stream_achieve_buffer_count(sp); - } -} - -static void pvr2_stream_init(struct pvr2_stream *sp) -{ - spin_lock_init(&sp->list_lock); - mutex_init(&sp->mutex); - INIT_LIST_HEAD(&sp->queued_list); - INIT_LIST_HEAD(&sp->ready_list); - INIT_LIST_HEAD(&sp->idle_list); -} - -static void pvr2_stream_done(struct pvr2_stream *sp) -{ - mutex_lock(&sp->mutex); do { - pvr2_stream_internal_flush(sp); - pvr2_stream_buffer_count(sp,0); - } while (0); mutex_unlock(&sp->mutex); -} - -static void buffer_complete(struct urb *urb) -{ - struct pvr2_buffer *bp = urb->context; - struct pvr2_stream *sp; - unsigned long irq_flags; - BUFFER_CHECK(bp); - sp = bp->stream; - bp->used_count = 0; - bp->status = 0; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/ bufferComplete %p stat=%d cnt=%d", - bp,urb->status,urb->actual_length); - spin_lock_irqsave(&sp->list_lock,irq_flags); - if ((!(urb->status)) || - (urb->status == -ENOENT) || - (urb->status == -ECONNRESET) || - (urb->status == -ESHUTDOWN)) { - (sp->buffers_processed)++; - sp->bytes_processed += urb->actual_length; - bp->used_count = urb->actual_length; - if (sp->fail_count) { - pvr2_trace(PVR2_TRACE_TOLERANCE, - "stream %p transfer ok" - " - fail count reset",sp); - sp->fail_count = 0; - } - } else if (sp->fail_count < sp->fail_tolerance) { - // We can tolerate this error, because we're below the - // threshold... - (sp->fail_count)++; - (sp->buffers_failed)++; - pvr2_trace(PVR2_TRACE_TOLERANCE, - "stream %p ignoring error %d" - " - fail count increased to %u", - sp,urb->status,sp->fail_count); - } else { - (sp->buffers_failed)++; - bp->status = urb->status; - } - spin_unlock_irqrestore(&sp->list_lock,irq_flags); - pvr2_buffer_set_ready(bp); - if (sp && sp->callback_func) { - sp->callback_func(sp->callback_data); - } -} - -struct pvr2_stream *pvr2_stream_create(void) -{ - struct pvr2_stream *sp; - sp = kzalloc(sizeof(*sp),GFP_KERNEL); - if (!sp) return sp; - pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_create: sp=%p",sp); - pvr2_stream_init(sp); - return sp; -} - -void pvr2_stream_destroy(struct pvr2_stream *sp) -{ - if (!sp) return; - pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_destroy: sp=%p",sp); - pvr2_stream_done(sp); - kfree(sp); -} - -void pvr2_stream_setup(struct pvr2_stream *sp, - struct usb_device *dev, - int endpoint, - unsigned int tolerance) -{ - mutex_lock(&sp->mutex); do { - pvr2_stream_internal_flush(sp); - sp->dev = dev; - sp->endpoint = endpoint; - sp->fail_tolerance = tolerance; - } while(0); mutex_unlock(&sp->mutex); -} - -void pvr2_stream_set_callback(struct pvr2_stream *sp, - pvr2_stream_callback func, - void *data) -{ - unsigned long irq_flags; - mutex_lock(&sp->mutex); do { - spin_lock_irqsave(&sp->list_lock,irq_flags); - sp->callback_data = data; - sp->callback_func = func; - spin_unlock_irqrestore(&sp->list_lock,irq_flags); - } while(0); mutex_unlock(&sp->mutex); -} - -void pvr2_stream_get_stats(struct pvr2_stream *sp, - struct pvr2_stream_stats *stats, - int zero_counts) -{ - unsigned long irq_flags; - spin_lock_irqsave(&sp->list_lock,irq_flags); - if (stats) { - stats->buffers_in_queue = sp->q_count; - stats->buffers_in_idle = sp->i_count; - stats->buffers_in_ready = sp->r_count; - stats->buffers_processed = sp->buffers_processed; - stats->buffers_failed = sp->buffers_failed; - stats->bytes_processed = sp->bytes_processed; - } - if (zero_counts) { - sp->buffers_processed = 0; - sp->buffers_failed = 0; - sp->bytes_processed = 0; - } - spin_unlock_irqrestore(&sp->list_lock,irq_flags); -} - -/* Query / set the nominal buffer count */ -int pvr2_stream_get_buffer_count(struct pvr2_stream *sp) -{ - return sp->buffer_target_count; -} - -int pvr2_stream_set_buffer_count(struct pvr2_stream *sp,unsigned int cnt) -{ - int ret; - if (sp->buffer_target_count == cnt) return 0; - mutex_lock(&sp->mutex); do { - sp->buffer_target_count = cnt; - ret = pvr2_stream_achieve_buffer_count(sp); - } while(0); mutex_unlock(&sp->mutex); - return ret; -} - -struct pvr2_buffer *pvr2_stream_get_idle_buffer(struct pvr2_stream *sp) -{ - struct list_head *lp = sp->idle_list.next; - if (lp == &sp->idle_list) return NULL; - return list_entry(lp,struct pvr2_buffer,list_overhead); -} - -struct pvr2_buffer *pvr2_stream_get_ready_buffer(struct pvr2_stream *sp) -{ - struct list_head *lp = sp->ready_list.next; - if (lp == &sp->ready_list) return NULL; - return list_entry(lp,struct pvr2_buffer,list_overhead); -} - -struct pvr2_buffer *pvr2_stream_get_buffer(struct pvr2_stream *sp,int id) -{ - if (id < 0) return NULL; - if (id >= sp->buffer_total_count) return NULL; - return sp->buffers[id]; -} - -int pvr2_stream_get_ready_count(struct pvr2_stream *sp) -{ - return sp->r_count; -} - -void pvr2_stream_kill(struct pvr2_stream *sp) -{ - struct pvr2_buffer *bp; - mutex_lock(&sp->mutex); do { - pvr2_stream_internal_flush(sp); - while ((bp = pvr2_stream_get_ready_buffer(sp)) != NULL) { - pvr2_buffer_set_idle(bp); - } - if (sp->buffer_total_count != sp->buffer_target_count) { - pvr2_stream_achieve_buffer_count(sp); - } - } while(0); mutex_unlock(&sp->mutex); -} - -int pvr2_buffer_queue(struct pvr2_buffer *bp) -{ -#undef SEED_BUFFER -#ifdef SEED_BUFFER - unsigned int idx; - unsigned int val; -#endif - int ret = 0; - struct pvr2_stream *sp; - if (!bp) return -EINVAL; - sp = bp->stream; - mutex_lock(&sp->mutex); do { - pvr2_buffer_wipe(bp); - if (!sp->dev) { - ret = -EIO; - break; - } - pvr2_buffer_set_queued(bp); -#ifdef SEED_BUFFER - for (idx = 0; idx < (bp->max_count) / 4; idx++) { - val = bp->id << 24; - val |= idx; - ((unsigned int *)(bp->ptr))[idx] = val; - } -#endif - bp->status = -EINPROGRESS; - usb_fill_bulk_urb(bp->purb, // struct urb *urb - sp->dev, // struct usb_device *dev - // endpoint (below) - usb_rcvbulkpipe(sp->dev,sp->endpoint), - bp->ptr, // void *transfer_buffer - bp->max_count, // int buffer_length - buffer_complete, - bp); - usb_submit_urb(bp->purb,GFP_KERNEL); - } while(0); mutex_unlock(&sp->mutex); - return ret; -} - -int pvr2_buffer_set_buffer(struct pvr2_buffer *bp,void *ptr,unsigned int cnt) -{ - int ret = 0; - unsigned long irq_flags; - struct pvr2_stream *sp; - if (!bp) return -EINVAL; - sp = bp->stream; - mutex_lock(&sp->mutex); do { - spin_lock_irqsave(&sp->list_lock,irq_flags); - if (bp->state != pvr2_buffer_state_idle) { - ret = -EPERM; - } else { - bp->ptr = ptr; - bp->stream->i_bcount -= bp->max_count; - bp->max_count = cnt; - bp->stream->i_bcount += bp->max_count; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/ bufferPool " - " %8s cap cap=%07d cnt=%02d", - pvr2_buffer_state_decode( - pvr2_buffer_state_idle), - bp->stream->i_bcount,bp->stream->i_count); - } - spin_unlock_irqrestore(&sp->list_lock,irq_flags); - } while(0); mutex_unlock(&sp->mutex); - return ret; -} - -unsigned int pvr2_buffer_get_count(struct pvr2_buffer *bp) -{ - return bp->used_count; -} - -int pvr2_buffer_get_status(struct pvr2_buffer *bp) -{ - return bp->status; -} - -int pvr2_buffer_get_id(struct pvr2_buffer *bp) -{ - return bp->id; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.h b/drivers/media/video/pvrusb2/pvrusb2-io.h deleted file mode 100644 index afb7e87c0394..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-io.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ -#ifndef __PVRUSB2_IO_H -#define __PVRUSB2_IO_H - -#include <linux/usb.h> -#include <linux/list.h> - -typedef void (*pvr2_stream_callback)(void *); - -enum pvr2_buffer_state { - pvr2_buffer_state_none = 0, // Not on any list - pvr2_buffer_state_idle = 1, // Buffer is ready to be used again - pvr2_buffer_state_queued = 2, // Buffer has been queued for filling - pvr2_buffer_state_ready = 3, // Buffer has data available -}; - -struct pvr2_stream; -struct pvr2_buffer; - -struct pvr2_stream_stats { - unsigned int buffers_in_queue; - unsigned int buffers_in_idle; - unsigned int buffers_in_ready; - unsigned int buffers_processed; - unsigned int buffers_failed; - unsigned int bytes_processed; -}; - -/* Initialize / tear down stream structure */ -struct pvr2_stream *pvr2_stream_create(void); -void pvr2_stream_destroy(struct pvr2_stream *); -void pvr2_stream_setup(struct pvr2_stream *, - struct usb_device *dev,int endpoint, - unsigned int tolerance); -void pvr2_stream_set_callback(struct pvr2_stream *, - pvr2_stream_callback func, - void *data); -void pvr2_stream_get_stats(struct pvr2_stream *, - struct pvr2_stream_stats *, - int zero_counts); - -/* Query / set the nominal buffer count */ -int pvr2_stream_get_buffer_count(struct pvr2_stream *); -int pvr2_stream_set_buffer_count(struct pvr2_stream *,unsigned int); - -/* Get a pointer to a buffer that is either idle, ready, or is specified - named. */ -struct pvr2_buffer *pvr2_stream_get_idle_buffer(struct pvr2_stream *); -struct pvr2_buffer *pvr2_stream_get_ready_buffer(struct pvr2_stream *); -struct pvr2_buffer *pvr2_stream_get_buffer(struct pvr2_stream *sp,int id); - -/* Find out how many buffers are idle or ready */ -int pvr2_stream_get_ready_count(struct pvr2_stream *); - - -/* Kill all pending buffers and throw away any ready buffers as well */ -void pvr2_stream_kill(struct pvr2_stream *); - -/* Set up the actual storage for a buffer */ -int pvr2_buffer_set_buffer(struct pvr2_buffer *,void *ptr,unsigned int cnt); - -/* Find out size of data in the given ready buffer */ -unsigned int pvr2_buffer_get_count(struct pvr2_buffer *); - -/* Retrieve completion code for given ready buffer */ -int pvr2_buffer_get_status(struct pvr2_buffer *); - -/* Retrieve ID of given buffer */ -int pvr2_buffer_get_id(struct pvr2_buffer *); - -/* Start reading into given buffer (kill it if needed) */ -int pvr2_buffer_queue(struct pvr2_buffer *); - -#endif /* __PVRUSB2_IO_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.c b/drivers/media/video/pvrusb2/pvrusb2-ioread.c deleted file mode 100644 index bba6115c9ae8..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-ioread.c +++ /dev/null @@ -1,512 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 "pvrusb2-ioread.h" -#include "pvrusb2-debug.h" -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/slab.h> -#include <linux/mutex.h> -#include <asm/uaccess.h> - -#define BUFFER_COUNT 32 -#define BUFFER_SIZE PAGE_ALIGN(0x4000) - -struct pvr2_ioread { - struct pvr2_stream *stream; - char *buffer_storage[BUFFER_COUNT]; - char *sync_key_ptr; - unsigned int sync_key_len; - unsigned int sync_buf_offs; - unsigned int sync_state; - unsigned int sync_trashed_count; - int enabled; // Streaming is on - int spigot_open; // OK to pass data to client - int stream_running; // Passing data to client now - - /* State relevant to current buffer being read */ - struct pvr2_buffer *c_buf; - char *c_data_ptr; - unsigned int c_data_len; - unsigned int c_data_offs; - struct mutex mutex; -}; - -static int pvr2_ioread_init(struct pvr2_ioread *cp) -{ - unsigned int idx; - - cp->stream = NULL; - mutex_init(&cp->mutex); - - for (idx = 0; idx < BUFFER_COUNT; idx++) { - cp->buffer_storage[idx] = kmalloc(BUFFER_SIZE,GFP_KERNEL); - if (!(cp->buffer_storage[idx])) break; - } - - if (idx < BUFFER_COUNT) { - // An allocation appears to have failed - for (idx = 0; idx < BUFFER_COUNT; idx++) { - if (!(cp->buffer_storage[idx])) continue; - kfree(cp->buffer_storage[idx]); - } - return -ENOMEM; - } - return 0; -} - -static void pvr2_ioread_done(struct pvr2_ioread *cp) -{ - unsigned int idx; - - pvr2_ioread_setup(cp,NULL); - for (idx = 0; idx < BUFFER_COUNT; idx++) { - if (!(cp->buffer_storage[idx])) continue; - kfree(cp->buffer_storage[idx]); - } -} - -struct pvr2_ioread *pvr2_ioread_create(void) -{ - struct pvr2_ioread *cp; - cp = kzalloc(sizeof(*cp),GFP_KERNEL); - if (!cp) return NULL; - pvr2_trace(PVR2_TRACE_STRUCT,"pvr2_ioread_create id=%p",cp); - if (pvr2_ioread_init(cp) < 0) { - kfree(cp); - return NULL; - } - return cp; -} - -void pvr2_ioread_destroy(struct pvr2_ioread *cp) -{ - if (!cp) return; - pvr2_ioread_done(cp); - pvr2_trace(PVR2_TRACE_STRUCT,"pvr2_ioread_destroy id=%p",cp); - if (cp->sync_key_ptr) { - kfree(cp->sync_key_ptr); - cp->sync_key_ptr = NULL; - } - kfree(cp); -} - -void pvr2_ioread_set_sync_key(struct pvr2_ioread *cp, - const char *sync_key_ptr, - unsigned int sync_key_len) -{ - if (!cp) return; - - if (!sync_key_ptr) sync_key_len = 0; - if ((sync_key_len == cp->sync_key_len) && - ((!sync_key_len) || - (!memcmp(sync_key_ptr,cp->sync_key_ptr,sync_key_len)))) return; - - if (sync_key_len != cp->sync_key_len) { - if (cp->sync_key_ptr) { - kfree(cp->sync_key_ptr); - cp->sync_key_ptr = NULL; - } - cp->sync_key_len = 0; - if (sync_key_len) { - cp->sync_key_ptr = kmalloc(sync_key_len,GFP_KERNEL); - if (cp->sync_key_ptr) { - cp->sync_key_len = sync_key_len; - } - } - } - if (!cp->sync_key_len) return; - memcpy(cp->sync_key_ptr,sync_key_ptr,cp->sync_key_len); -} - -static void pvr2_ioread_stop(struct pvr2_ioread *cp) -{ - if (!(cp->enabled)) return; - pvr2_trace(PVR2_TRACE_START_STOP, - "/*---TRACE_READ---*/ pvr2_ioread_stop id=%p",cp); - pvr2_stream_kill(cp->stream); - cp->c_buf = NULL; - cp->c_data_ptr = NULL; - cp->c_data_len = 0; - cp->c_data_offs = 0; - cp->enabled = 0; - cp->stream_running = 0; - cp->spigot_open = 0; - if (cp->sync_state) { - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/ sync_state <== 0"); - cp->sync_state = 0; - } -} - -static int pvr2_ioread_start(struct pvr2_ioread *cp) -{ - int stat; - struct pvr2_buffer *bp; - if (cp->enabled) return 0; - if (!(cp->stream)) return 0; - pvr2_trace(PVR2_TRACE_START_STOP, - "/*---TRACE_READ---*/ pvr2_ioread_start id=%p",cp); - while ((bp = pvr2_stream_get_idle_buffer(cp->stream)) != NULL) { - stat = pvr2_buffer_queue(bp); - if (stat < 0) { - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " pvr2_ioread_start id=%p" - " error=%d", - cp,stat); - pvr2_ioread_stop(cp); - return stat; - } - } - cp->enabled = !0; - cp->c_buf = NULL; - cp->c_data_ptr = NULL; - cp->c_data_len = 0; - cp->c_data_offs = 0; - cp->stream_running = 0; - if (cp->sync_key_len) { - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/ sync_state <== 1"); - cp->sync_state = 1; - cp->sync_trashed_count = 0; - cp->sync_buf_offs = 0; - } - cp->spigot_open = 0; - return 0; -} - -struct pvr2_stream *pvr2_ioread_get_stream(struct pvr2_ioread *cp) -{ - return cp->stream; -} - -int pvr2_ioread_setup(struct pvr2_ioread *cp,struct pvr2_stream *sp) -{ - int ret; - unsigned int idx; - struct pvr2_buffer *bp; - - mutex_lock(&cp->mutex); do { - if (cp->stream) { - pvr2_trace(PVR2_TRACE_START_STOP, - "/*---TRACE_READ---*/" - " pvr2_ioread_setup (tear-down) id=%p",cp); - pvr2_ioread_stop(cp); - pvr2_stream_kill(cp->stream); - if (pvr2_stream_get_buffer_count(cp->stream)) { - pvr2_stream_set_buffer_count(cp->stream,0); - } - cp->stream = NULL; - } - if (sp) { - pvr2_trace(PVR2_TRACE_START_STOP, - "/*---TRACE_READ---*/" - " pvr2_ioread_setup (setup) id=%p",cp); - pvr2_stream_kill(sp); - ret = pvr2_stream_set_buffer_count(sp,BUFFER_COUNT); - if (ret < 0) { - mutex_unlock(&cp->mutex); - return ret; - } - for (idx = 0; idx < BUFFER_COUNT; idx++) { - bp = pvr2_stream_get_buffer(sp,idx); - pvr2_buffer_set_buffer(bp, - cp->buffer_storage[idx], - BUFFER_SIZE); - } - cp->stream = sp; - } - } while (0); mutex_unlock(&cp->mutex); - - return 0; -} - -int pvr2_ioread_set_enabled(struct pvr2_ioread *cp,int fl) -{ - int ret = 0; - if ((!fl) == (!(cp->enabled))) return ret; - - mutex_lock(&cp->mutex); do { - if (fl) { - ret = pvr2_ioread_start(cp); - } else { - pvr2_ioread_stop(cp); - } - } while (0); mutex_unlock(&cp->mutex); - return ret; -} - -static int pvr2_ioread_get_buffer(struct pvr2_ioread *cp) -{ - int stat; - - while (cp->c_data_len <= cp->c_data_offs) { - if (cp->c_buf) { - // Flush out current buffer first. - stat = pvr2_buffer_queue(cp->c_buf); - if (stat < 0) { - // Streaming error... - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " pvr2_ioread_read id=%p" - " queue_error=%d", - cp,stat); - pvr2_ioread_stop(cp); - return 0; - } - cp->c_buf = NULL; - cp->c_data_ptr = NULL; - cp->c_data_len = 0; - cp->c_data_offs = 0; - } - // Now get a freshly filled buffer. - cp->c_buf = pvr2_stream_get_ready_buffer(cp->stream); - if (!cp->c_buf) break; // Nothing ready; done. - cp->c_data_len = pvr2_buffer_get_count(cp->c_buf); - if (!cp->c_data_len) { - // Nothing transferred. Was there an error? - stat = pvr2_buffer_get_status(cp->c_buf); - if (stat < 0) { - // Streaming error... - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " pvr2_ioread_read id=%p" - " buffer_error=%d", - cp,stat); - pvr2_ioread_stop(cp); - // Give up. - return 0; - } - // Start over... - continue; - } - cp->c_data_offs = 0; - cp->c_data_ptr = cp->buffer_storage[ - pvr2_buffer_get_id(cp->c_buf)]; - } - return !0; -} - -static void pvr2_ioread_filter(struct pvr2_ioread *cp) -{ - unsigned int idx; - if (!cp->enabled) return; - if (cp->sync_state != 1) return; - - // Search the stream for our synchronization key. This is made - // complicated by the fact that in order to be honest with - // ourselves here we must search across buffer boundaries... - mutex_lock(&cp->mutex); while (1) { - // Ensure we have a buffer - if (!pvr2_ioread_get_buffer(cp)) break; - if (!cp->c_data_len) break; - - // Now walk the buffer contents until we match the key or - // run out of buffer data. - for (idx = cp->c_data_offs; idx < cp->c_data_len; idx++) { - if (cp->sync_buf_offs >= cp->sync_key_len) break; - if (cp->c_data_ptr[idx] == - cp->sync_key_ptr[cp->sync_buf_offs]) { - // Found the next key byte - (cp->sync_buf_offs)++; - } else { - // Whoops, mismatched. Start key over... - cp->sync_buf_offs = 0; - } - } - - // Consume what we've walked through - cp->c_data_offs += idx; - cp->sync_trashed_count += idx; - - // If we've found the key, then update state and get out. - if (cp->sync_buf_offs >= cp->sync_key_len) { - cp->sync_trashed_count -= cp->sync_key_len; - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " sync_state <== 2 (skipped %u bytes)", - cp->sync_trashed_count); - cp->sync_state = 2; - cp->sync_buf_offs = 0; - break; - } - - if (cp->c_data_offs < cp->c_data_len) { - // Sanity check - should NEVER get here - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "ERROR: pvr2_ioread filter sync problem" - " len=%u offs=%u", - cp->c_data_len,cp->c_data_offs); - // Get out so we don't get stuck in an infinite - // loop. - break; - } - - continue; // (for clarity) - } mutex_unlock(&cp->mutex); -} - -int pvr2_ioread_avail(struct pvr2_ioread *cp) -{ - int ret; - if (!(cp->enabled)) { - // Stream is not enabled; so this is an I/O error - return -EIO; - } - - if (cp->sync_state == 1) { - pvr2_ioread_filter(cp); - if (cp->sync_state == 1) return -EAGAIN; - } - - ret = 0; - if (cp->stream_running) { - if (!pvr2_stream_get_ready_count(cp->stream)) { - // No data available at all right now. - ret = -EAGAIN; - } - } else { - if (pvr2_stream_get_ready_count(cp->stream) < BUFFER_COUNT/2) { - // Haven't buffered up enough yet; try again later - ret = -EAGAIN; - } - } - - if ((!(cp->spigot_open)) != (!(ret == 0))) { - cp->spigot_open = (ret == 0); - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/ data is %s", - cp->spigot_open ? "available" : "pending"); - } - - return ret; -} - -int pvr2_ioread_read(struct pvr2_ioread *cp,void __user *buf,unsigned int cnt) -{ - unsigned int copied_cnt; - unsigned int bcnt; - const char *src; - int stat; - int ret = 0; - unsigned int req_cnt = cnt; - - if (!cnt) { - pvr2_trace(PVR2_TRACE_TRAP, - "/*---TRACE_READ---*/ pvr2_ioread_read id=%p" - " ZERO Request? Returning zero.",cp); - return 0; - } - - stat = pvr2_ioread_avail(cp); - if (stat < 0) return stat; - - cp->stream_running = !0; - - mutex_lock(&cp->mutex); do { - - // Suck data out of the buffers and copy to the user - copied_cnt = 0; - if (!buf) cnt = 0; - while (1) { - if (!pvr2_ioread_get_buffer(cp)) { - ret = -EIO; - break; - } - - if (!cnt) break; - - if (cp->sync_state == 2) { - // We're repeating the sync key data into - // the stream. - src = cp->sync_key_ptr + cp->sync_buf_offs; - bcnt = cp->sync_key_len - cp->sync_buf_offs; - } else { - // Normal buffer copy - src = cp->c_data_ptr + cp->c_data_offs; - bcnt = cp->c_data_len - cp->c_data_offs; - } - - if (!bcnt) break; - - // Don't run past user's buffer - if (bcnt > cnt) bcnt = cnt; - - if (copy_to_user(buf,src,bcnt)) { - // User supplied a bad pointer? - // Give up - this *will* cause data - // to be lost. - ret = -EFAULT; - break; - } - cnt -= bcnt; - buf += bcnt; - copied_cnt += bcnt; - - if (cp->sync_state == 2) { - // Update offset inside sync key that we're - // repeating back out. - cp->sync_buf_offs += bcnt; - if (cp->sync_buf_offs >= cp->sync_key_len) { - // Consumed entire key; switch mode - // to normal. - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " sync_state <== 0"); - cp->sync_state = 0; - } - } else { - // Update buffer offset. - cp->c_data_offs += bcnt; - } - } - - } while (0); mutex_unlock(&cp->mutex); - - if (!ret) { - if (copied_cnt) { - // If anything was copied, return that count - ret = copied_cnt; - } else { - // Nothing copied; suggest to caller that another - // attempt should be tried again later - ret = -EAGAIN; - } - } - - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/ pvr2_ioread_read" - " id=%p request=%d result=%d", - cp,req_cnt,ret); - return ret; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.h b/drivers/media/video/pvrusb2/pvrusb2-ioread.h deleted file mode 100644 index 100e0780e1aa..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-ioread.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ -#ifndef __PVRUSB2_IOREAD_H -#define __PVRUSB2_IOREAD_H - -#include "pvrusb2-io.h" - -struct pvr2_ioread; - -struct pvr2_ioread *pvr2_ioread_create(void); -void pvr2_ioread_destroy(struct pvr2_ioread *); -int pvr2_ioread_setup(struct pvr2_ioread *,struct pvr2_stream *); -struct pvr2_stream *pvr2_ioread_get_stream(struct pvr2_ioread *); -void pvr2_ioread_set_sync_key(struct pvr2_ioread *, - const char *sync_key_ptr, - unsigned int sync_key_len); -int pvr2_ioread_set_enabled(struct pvr2_ioread *,int fl); -int pvr2_ioread_read(struct pvr2_ioread *,void __user *buf,unsigned int cnt); -int pvr2_ioread_avail(struct pvr2_ioread *); - -#endif /* __PVRUSB2_IOREAD_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c deleted file mode 100644 index c1d9bb61cd77..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-main.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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/errno.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/videodev2.h> - -#include "pvrusb2-hdw.h" -#include "pvrusb2-devattr.h" -#include "pvrusb2-context.h" -#include "pvrusb2-debug.h" -#include "pvrusb2-v4l2.h" -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS -#include "pvrusb2-sysfs.h" -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ - -#define DRIVER_AUTHOR "Mike Isely <isely@pobox.com>" -#define DRIVER_DESC "Hauppauge WinTV-PVR-USB2 MPEG2 Encoder/Tuner" -#define DRIVER_VERSION "V4L in-tree version" - -#define DEFAULT_DEBUG_MASK (PVR2_TRACE_ERROR_LEGS| \ - PVR2_TRACE_INFO| \ - PVR2_TRACE_STD| \ - PVR2_TRACE_TOLERANCE| \ - PVR2_TRACE_TRAP| \ - 0) - -int pvrusb2_debug = DEFAULT_DEBUG_MASK; - -module_param_named(debug,pvrusb2_debug,int,S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(debug, "Debug trace mask"); - -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS -static struct pvr2_sysfs_class *class_ptr = NULL; -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ - -static void pvr_setup_attach(struct pvr2_context *pvr) -{ - /* Create association with v4l layer */ - pvr2_v4l2_create(pvr); -#ifdef CONFIG_VIDEO_PVRUSB2_DVB - /* Create association with dvb layer */ - pvr2_dvb_create(pvr); -#endif -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS - pvr2_sysfs_create(pvr,class_ptr); -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ -} - -static int pvr_probe(struct usb_interface *intf, - const struct usb_device_id *devid) -{ - struct pvr2_context *pvr; - - /* Create underlying hardware interface */ - pvr = pvr2_context_create(intf,devid,pvr_setup_attach); - if (!pvr) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to create hdw handler"); - return -ENOMEM; - } - - pvr2_trace(PVR2_TRACE_INIT,"pvr_probe(pvr=%p)",pvr); - - usb_set_intfdata(intf, pvr); - - return 0; -} - -/* - * pvr_disconnect() - * - */ -static void pvr_disconnect(struct usb_interface *intf) -{ - struct pvr2_context *pvr = usb_get_intfdata(intf); - - pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) BEGIN",pvr); - - usb_set_intfdata (intf, NULL); - pvr2_context_disconnect(pvr); - - pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) DONE",pvr); - -} - -static struct usb_driver pvr_driver = { - .name = "pvrusb2", - .id_table = pvr2_device_table, - .probe = pvr_probe, - .disconnect = pvr_disconnect -}; - -/* - * pvr_init() / pvr_exit() - * - * This code is run to initialize/exit the driver. - * - */ -static int __init pvr_init(void) -{ - int ret; - - pvr2_trace(PVR2_TRACE_INIT,"pvr_init"); - - ret = pvr2_context_global_init(); - if (ret != 0) { - pvr2_trace(PVR2_TRACE_INIT,"pvr_init failure code=%d",ret); - return ret; - } - -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS - class_ptr = pvr2_sysfs_class_create(); -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ - - ret = usb_register(&pvr_driver); - - if (ret == 0) - printk(KERN_INFO "pvrusb2: " DRIVER_VERSION ":" - DRIVER_DESC "\n"); - if (pvrusb2_debug) - printk(KERN_INFO "pvrusb2: Debug mask is %d (0x%x)\n", - pvrusb2_debug,pvrusb2_debug); - - pvr2_trace(PVR2_TRACE_INIT,"pvr_init complete"); - - return ret; -} - -static void __exit pvr_exit(void) -{ - pvr2_trace(PVR2_TRACE_INIT,"pvr_exit"); - - usb_deregister(&pvr_driver); - - pvr2_context_global_done(); - -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS - pvr2_sysfs_class_destroy(class_ptr); -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ - - pvr2_trace(PVR2_TRACE_INIT,"pvr_exit complete"); -} - -module_init(pvr_init); -module_exit(pvr_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); -MODULE_VERSION("0.9.1"); - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.c b/drivers/media/video/pvrusb2/pvrusb2-std.c deleted file mode 100644 index 453627b07833..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-std.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 "pvrusb2-std.h" -#include "pvrusb2-debug.h" -#include <asm/string.h> -#include <linux/slab.h> - -struct std_name { - const char *name; - v4l2_std_id id; -}; - - -#define CSTD_PAL \ - (V4L2_STD_PAL_B| \ - V4L2_STD_PAL_B1| \ - V4L2_STD_PAL_G| \ - V4L2_STD_PAL_H| \ - V4L2_STD_PAL_I| \ - V4L2_STD_PAL_D| \ - V4L2_STD_PAL_D1| \ - V4L2_STD_PAL_K| \ - V4L2_STD_PAL_M| \ - V4L2_STD_PAL_N| \ - V4L2_STD_PAL_Nc| \ - V4L2_STD_PAL_60) - -#define CSTD_NTSC \ - (V4L2_STD_NTSC_M| \ - V4L2_STD_NTSC_M_JP| \ - V4L2_STD_NTSC_M_KR| \ - V4L2_STD_NTSC_443) - -#define CSTD_ATSC \ - (V4L2_STD_ATSC_8_VSB| \ - V4L2_STD_ATSC_16_VSB) - -#define CSTD_SECAM \ - (V4L2_STD_SECAM_B| \ - V4L2_STD_SECAM_D| \ - V4L2_STD_SECAM_G| \ - V4L2_STD_SECAM_H| \ - V4L2_STD_SECAM_K| \ - V4L2_STD_SECAM_K1| \ - V4L2_STD_SECAM_L| \ - V4L2_STD_SECAM_LC) - -#define TSTD_B (V4L2_STD_PAL_B|V4L2_STD_SECAM_B) -#define TSTD_B1 (V4L2_STD_PAL_B1) -#define TSTD_D (V4L2_STD_PAL_D|V4L2_STD_SECAM_D) -#define TSTD_D1 (V4L2_STD_PAL_D1) -#define TSTD_G (V4L2_STD_PAL_G|V4L2_STD_SECAM_G) -#define TSTD_H (V4L2_STD_PAL_H|V4L2_STD_SECAM_H) -#define TSTD_I (V4L2_STD_PAL_I) -#define TSTD_K (V4L2_STD_PAL_K|V4L2_STD_SECAM_K) -#define TSTD_K1 (V4L2_STD_SECAM_K1) -#define TSTD_L (V4L2_STD_SECAM_L) -#define TSTD_M (V4L2_STD_PAL_M|V4L2_STD_NTSC_M) -#define TSTD_N (V4L2_STD_PAL_N) -#define TSTD_Nc (V4L2_STD_PAL_Nc) -#define TSTD_60 (V4L2_STD_PAL_60) - -#define CSTD_ALL (CSTD_PAL|CSTD_NTSC|CSTD_ATSC|CSTD_SECAM) - -/* Mapping of standard bits to color system */ -static const struct std_name std_groups[] = { - {"PAL",CSTD_PAL}, - {"NTSC",CSTD_NTSC}, - {"SECAM",CSTD_SECAM}, - {"ATSC",CSTD_ATSC}, -}; - -/* Mapping of standard bits to modulation system */ -static const struct std_name std_items[] = { - {"B",TSTD_B}, - {"B1",TSTD_B1}, - {"D",TSTD_D}, - {"D1",TSTD_D1}, - {"G",TSTD_G}, - {"H",TSTD_H}, - {"I",TSTD_I}, - {"K",TSTD_K}, - {"K1",TSTD_K1}, - {"L",TSTD_L}, - {"LC",V4L2_STD_SECAM_LC}, - {"M",TSTD_M}, - {"Mj",V4L2_STD_NTSC_M_JP}, - {"443",V4L2_STD_NTSC_443}, - {"Mk",V4L2_STD_NTSC_M_KR}, - {"N",TSTD_N}, - {"Nc",TSTD_Nc}, - {"60",TSTD_60}, - {"8VSB",V4L2_STD_ATSC_8_VSB}, - {"16VSB",V4L2_STD_ATSC_16_VSB}, -}; - - -// Search an array of std_name structures and return a pointer to the -// element with the matching name. -static const struct std_name *find_std_name(const struct std_name *arrPtr, - unsigned int arrSize, - const char *bufPtr, - unsigned int bufSize) -{ - unsigned int idx; - const struct std_name *p; - for (idx = 0; idx < arrSize; idx++) { - p = arrPtr + idx; - if (strlen(p->name) != bufSize) continue; - if (!memcmp(bufPtr,p->name,bufSize)) return p; - } - return NULL; -} - - -int pvr2_std_str_to_id(v4l2_std_id *idPtr,const char *bufPtr, - unsigned int bufSize) -{ - v4l2_std_id id = 0; - v4l2_std_id cmsk = 0; - v4l2_std_id t; - int mMode = 0; - unsigned int cnt; - char ch; - const struct std_name *sp; - - while (bufSize) { - if (!mMode) { - cnt = 0; - while ((cnt < bufSize) && (bufPtr[cnt] != '-')) cnt++; - if (cnt >= bufSize) return 0; // No more characters - sp = find_std_name(std_groups, ARRAY_SIZE(std_groups), - bufPtr,cnt); - if (!sp) return 0; // Illegal color system name - cnt++; - bufPtr += cnt; - bufSize -= cnt; - mMode = !0; - cmsk = sp->id; - continue; - } - cnt = 0; - while (cnt < bufSize) { - ch = bufPtr[cnt]; - if (ch == ';') { - mMode = 0; - break; - } - if (ch == '/') break; - cnt++; - } - sp = find_std_name(std_items, ARRAY_SIZE(std_items), - bufPtr,cnt); - if (!sp) return 0; // Illegal modulation system ID - t = sp->id & cmsk; - if (!t) return 0; // Specific color + modulation system illegal - id |= t; - if (cnt < bufSize) cnt++; - bufPtr += cnt; - bufSize -= cnt; - } - - if (idPtr) *idPtr = id; - return !0; -} - - -unsigned int pvr2_std_id_to_str(char *bufPtr, unsigned int bufSize, - v4l2_std_id id) -{ - unsigned int idx1,idx2; - const struct std_name *ip,*gp; - int gfl,cfl; - unsigned int c1,c2; - cfl = 0; - c1 = 0; - for (idx1 = 0; idx1 < ARRAY_SIZE(std_groups); idx1++) { - gp = std_groups + idx1; - gfl = 0; - for (idx2 = 0; idx2 < ARRAY_SIZE(std_items); idx2++) { - ip = std_items + idx2; - if (!(gp->id & ip->id & id)) continue; - if (!gfl) { - if (cfl) { - c2 = scnprintf(bufPtr,bufSize,";"); - c1 += c2; - bufSize -= c2; - bufPtr += c2; - } - cfl = !0; - c2 = scnprintf(bufPtr,bufSize, - "%s-",gp->name); - gfl = !0; - } else { - c2 = scnprintf(bufPtr,bufSize,"/"); - } - c1 += c2; - bufSize -= c2; - bufPtr += c2; - c2 = scnprintf(bufPtr,bufSize, - ip->name); - c1 += c2; - bufSize -= c2; - bufPtr += c2; - } - } - return c1; -} - - -// Template data for possible enumerated video standards. Here we group -// standards which share common frame rates and resolution. -static struct v4l2_standard generic_standards[] = { - { - .id = (TSTD_B|TSTD_B1| - TSTD_D|TSTD_D1| - TSTD_G| - TSTD_H| - TSTD_I| - TSTD_K|TSTD_K1| - TSTD_L| - V4L2_STD_SECAM_LC | - TSTD_N|TSTD_Nc), - .frameperiod = - { - .numerator = 1, - .denominator= 25 - }, - .framelines = 625, - .reserved = {0,0,0,0} - }, { - .id = (TSTD_M| - V4L2_STD_NTSC_M_JP| - V4L2_STD_NTSC_M_KR), - .frameperiod = - { - .numerator = 1001, - .denominator= 30000 - }, - .framelines = 525, - .reserved = {0,0,0,0} - }, { // This is a total wild guess - .id = (TSTD_60), - .frameperiod = - { - .numerator = 1001, - .denominator= 30000 - }, - .framelines = 525, - .reserved = {0,0,0,0} - }, { // This is total wild guess - .id = V4L2_STD_NTSC_443, - .frameperiod = - { - .numerator = 1001, - .denominator= 30000 - }, - .framelines = 525, - .reserved = {0,0,0,0} - } -}; - -static struct v4l2_standard *match_std(v4l2_std_id id) -{ - unsigned int idx; - for (idx = 0; idx < ARRAY_SIZE(generic_standards); idx++) { - if (generic_standards[idx].id & id) { - return generic_standards + idx; - } - } - return NULL; -} - -static int pvr2_std_fill(struct v4l2_standard *std,v4l2_std_id id) -{ - struct v4l2_standard *template; - int idx; - unsigned int bcnt; - template = match_std(id); - if (!template) return 0; - idx = std->index; - memcpy(std,template,sizeof(*template)); - std->index = idx; - std->id = id; - bcnt = pvr2_std_id_to_str(std->name,sizeof(std->name)-1,id); - std->name[bcnt] = 0; - pvr2_trace(PVR2_TRACE_STD,"Set up standard idx=%u name=%s", - std->index,std->name); - return !0; -} - -/* These are special cases of combined standards that we should enumerate - separately if the component pieces are present. */ -static v4l2_std_id std_mixes[] = { - V4L2_STD_PAL_B | V4L2_STD_PAL_G, - V4L2_STD_PAL_D | V4L2_STD_PAL_K, - V4L2_STD_SECAM_B | V4L2_STD_SECAM_G, - V4L2_STD_SECAM_D | V4L2_STD_SECAM_K, -}; - -struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr, - v4l2_std_id id) -{ - unsigned int std_cnt = 0; - unsigned int idx,bcnt,idx2; - v4l2_std_id idmsk,cmsk,fmsk; - struct v4l2_standard *stddefs; - - if (pvrusb2_debug & PVR2_TRACE_STD) { - char buf[100]; - bcnt = pvr2_std_id_to_str(buf,sizeof(buf),id); - pvr2_trace( - PVR2_TRACE_STD,"Mapping standards mask=0x%x (%.*s)", - (int)id,bcnt,buf); - } - - *countptr = 0; - std_cnt = 0; - fmsk = 0; - for (idmsk = 1, cmsk = id; cmsk; idmsk <<= 1) { - if (!(idmsk & cmsk)) continue; - cmsk &= ~idmsk; - if (match_std(idmsk)) { - std_cnt++; - continue; - } - fmsk |= idmsk; - } - - for (idx2 = 0; idx2 < ARRAY_SIZE(std_mixes); idx2++) { - if ((id & std_mixes[idx2]) == std_mixes[idx2]) std_cnt++; - } - - /* Don't complain about ATSC standard values */ - fmsk &= ~CSTD_ATSC; - - if (fmsk) { - char buf[100]; - bcnt = pvr2_std_id_to_str(buf,sizeof(buf),fmsk); - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "WARNING:" - " Failed to classify the following standard(s): %.*s", - bcnt,buf); - } - - pvr2_trace(PVR2_TRACE_STD,"Setting up %u unique standard(s)", - std_cnt); - if (!std_cnt) return NULL; // paranoia - - stddefs = kzalloc(sizeof(struct v4l2_standard) * std_cnt, - GFP_KERNEL); - if (!stddefs) - return NULL; - - for (idx = 0; idx < std_cnt; idx++) - stddefs[idx].index = idx; - - idx = 0; - - /* Enumerate potential special cases */ - for (idx2 = 0; (idx2 < ARRAY_SIZE(std_mixes)) && (idx < std_cnt); - idx2++) { - if (!(id & std_mixes[idx2])) continue; - if (pvr2_std_fill(stddefs+idx,std_mixes[idx2])) idx++; - } - /* Now enumerate individual pieces */ - for (idmsk = 1, cmsk = id; cmsk && (idx < std_cnt); idmsk <<= 1) { - if (!(idmsk & cmsk)) continue; - cmsk &= ~idmsk; - if (!pvr2_std_fill(stddefs+idx,idmsk)) continue; - idx++; - } - - *countptr = std_cnt; - return stddefs; -} - -v4l2_std_id pvr2_std_get_usable(void) -{ - return CSTD_ALL; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.h b/drivers/media/video/pvrusb2/pvrusb2-std.h deleted file mode 100644 index a35c53d0b320..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-std.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ -#ifndef __PVRUSB2_STD_H -#define __PVRUSB2_STD_H - -#include <linux/videodev2.h> - -// Convert string describing one or more video standards into a mask of V4L -// standard bits. Return true if conversion succeeds otherwise return -// false. String is expected to be of the form: C1-x/y;C2-a/b where C1 and -// C2 are color system names (e.g. "PAL", "NTSC") and x, y, a, and b are -// modulation schemes (e.g. "M", "B", "G", etc). -int pvr2_std_str_to_id(v4l2_std_id *idPtr,const char *bufPtr, - unsigned int bufSize); - -// Convert any arbitrary set of video standard bits into an unambiguous -// readable string. Return value is the number of bytes consumed in the -// buffer. The formatted string is of a form that can be parsed by our -// sibling std_std_to_id() function. -unsigned int pvr2_std_id_to_str(char *bufPtr, unsigned int bufSize, - v4l2_std_id id); - -// Create an array of suitable v4l2_standard structures given a bit mask of -// video standards to support. The array is allocated from the heap, and -// the number of elements is returned in the first argument. -struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr, - v4l2_std_id id); - -// Return mask of which video standard bits are valid -v4l2_std_id pvr2_std_get_usable(void); - -#endif /* __PVRUSB2_STD_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c deleted file mode 100644 index 6ef1335b2858..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ /dev/null @@ -1,861 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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/string.h> -#include <linux/slab.h> -#include "pvrusb2-sysfs.h" -#include "pvrusb2-hdw.h" -#include "pvrusb2-debug.h" -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC -#include "pvrusb2-debugifc.h" -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ - -#define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__) - -struct pvr2_sysfs { - struct pvr2_channel channel; - struct device *class_dev; -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC - struct pvr2_sysfs_debugifc *debugifc; -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ - struct pvr2_sysfs_ctl_item *item_first; - struct pvr2_sysfs_ctl_item *item_last; - struct device_attribute attr_v4l_minor_number; - struct device_attribute attr_v4l_radio_minor_number; - struct device_attribute attr_unit_number; - struct device_attribute attr_bus_info; - struct device_attribute attr_hdw_name; - struct device_attribute attr_hdw_desc; - int v4l_minor_number_created_ok; - int v4l_radio_minor_number_created_ok; - int unit_number_created_ok; - int bus_info_created_ok; - int hdw_name_created_ok; - int hdw_desc_created_ok; -}; - -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC -struct pvr2_sysfs_debugifc { - struct device_attribute attr_debugcmd; - struct device_attribute attr_debuginfo; - int debugcmd_created_ok; - int debuginfo_created_ok; -}; -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ - -struct pvr2_sysfs_ctl_item { - struct device_attribute attr_name; - struct device_attribute attr_type; - struct device_attribute attr_min; - struct device_attribute attr_max; - struct device_attribute attr_def; - struct device_attribute attr_enum; - struct device_attribute attr_bits; - struct device_attribute attr_val; - struct device_attribute attr_custom; - struct pvr2_ctrl *cptr; - int ctl_id; - struct pvr2_sysfs *chptr; - struct pvr2_sysfs_ctl_item *item_next; - struct attribute *attr_gen[8]; - struct attribute_group grp; - int created_ok; - char name[80]; -}; - -struct pvr2_sysfs_class { - struct class class; -}; - -static ssize_t show_name(struct device *class_dev, - struct device_attribute *attr, - char *buf) -{ - struct pvr2_sysfs_ctl_item *cip; - const char *name; - cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_name); - name = pvr2_ctrl_get_desc(cip->cptr); - pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s", - cip->chptr, cip->ctl_id, name); - if (!name) return -EINVAL; - return scnprintf(buf, PAGE_SIZE, "%s\n", name); -} - -static ssize_t show_type(struct device *class_dev, - struct device_attribute *attr, - char *buf) -{ - struct pvr2_sysfs_ctl_item *cip; - const char *name; - enum pvr2_ctl_type tp; - cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_type); - tp = pvr2_ctrl_get_type(cip->cptr); - switch (tp) { - case pvr2_ctl_int: name = "integer"; break; - case pvr2_ctl_enum: name = "enum"; break; - case pvr2_ctl_bitmask: name = "bitmask"; break; - case pvr2_ctl_bool: name = "boolean"; break; - default: name = "?"; break; - } - pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s", - cip->chptr, cip->ctl_id, name); - if (!name) return -EINVAL; - return scnprintf(buf, PAGE_SIZE, "%s\n", name); -} - -static ssize_t show_min(struct device *class_dev, - struct device_attribute *attr, - char *buf) -{ - struct pvr2_sysfs_ctl_item *cip; - long val; - cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_min); - val = pvr2_ctrl_get_min(cip->cptr); - pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld", - cip->chptr, cip->ctl_id, val); - return scnprintf(buf, PAGE_SIZE, "%ld\n", val); -} - -static ssize_t show_max(struct device *class_dev, - struct device_attribute *attr, - char *buf) -{ - struct pvr2_sysfs_ctl_item *cip; - long val; - cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_max); - val = pvr2_ctrl_get_max(cip->cptr); - pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld", - cip->chptr, cip->ctl_id, val); - return scnprintf(buf, PAGE_SIZE, "%ld\n", val); -} - -static ssize_t show_def(struct device *class_dev, - struct device_attribute *attr, - char *buf) -{ - struct pvr2_sysfs_ctl_item *cip; - int val; - int ret; - unsigned int cnt = 0; - cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_def); - ret = pvr2_ctrl_get_def(cip->cptr, &val); - if (ret < 0) return ret; - ret = pvr2_ctrl_value_to_sym(cip->cptr, ~0, val, - buf, PAGE_SIZE - 1, &cnt); - pvr2_sysfs_trace("pvr2_sysfs(%p) show_def(cid=%d) is %.*s (%d)", - cip->chptr, cip->ctl_id, cnt, buf, val); - buf[cnt] = '\n'; - return cnt + 1; -} - -static ssize_t show_val_norm(struct device *class_dev, - struct device_attribute *attr, - char *buf) -{ - struct pvr2_sysfs_ctl_item *cip; - int val; - int ret; - unsigned int cnt = 0; - cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_val); - ret = pvr2_ctrl_get_value(cip->cptr, &val); - if (ret < 0) return ret; - ret = pvr2_ctrl_value_to_sym(cip->cptr, ~0, val, - buf, PAGE_SIZE - 1, &cnt); - pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)", - cip->chptr, cip->ctl_id, cnt, buf, val); - buf[cnt] = '\n'; - return cnt+1; -} - -static ssize_t show_val_custom(struct device *class_dev, - struct device_attribute *attr, - char *buf) -{ - struct pvr2_sysfs_ctl_item *cip; - int val; - int ret; - unsigned int cnt = 0; - cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_custom); - ret = pvr2_ctrl_get_value(cip->cptr, &val); - if (ret < 0) return ret; - ret = pvr2_ctrl_custom_value_to_sym(cip->cptr, ~0, val, - buf, PAGE_SIZE - 1, &cnt); - pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)", - cip->chptr, cip->ctl_id, cnt, buf, val); - buf[cnt] = '\n'; - return cnt+1; -} - -static ssize_t show_enum(struct device *class_dev, - struct device_attribute *attr, - char *buf) -{ - struct pvr2_sysfs_ctl_item *cip; - long val; - unsigned int bcnt, ccnt, ecnt; - cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_enum); - ecnt = pvr2_ctrl_get_cnt(cip->cptr); - bcnt = 0; - for (val = 0; val < ecnt; val++) { - pvr2_ctrl_get_valname(cip->cptr, val, buf + bcnt, - PAGE_SIZE - bcnt, &ccnt); - if (!ccnt) continue; - bcnt += ccnt; - if (bcnt >= PAGE_SIZE) break; - buf[bcnt] = '\n'; - bcnt++; - } - pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)", - cip->chptr, cip->ctl_id); - return bcnt; -} - -static ssize_t show_bits(struct device *class_dev, - struct device_attribute *attr, - char *buf) -{ - struct pvr2_sysfs_ctl_item *cip; - int valid_bits, msk; - unsigned int bcnt, ccnt; - cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_bits); - valid_bits = pvr2_ctrl_get_mask(cip->cptr); - bcnt = 0; - for (msk = 1; valid_bits; msk <<= 1) { - if (!(msk & valid_bits)) continue; - valid_bits &= ~msk; - pvr2_ctrl_get_valname(cip->cptr, msk, buf + bcnt, - PAGE_SIZE - bcnt, &ccnt); - bcnt += ccnt; - if (bcnt >= PAGE_SIZE) break; - buf[bcnt] = '\n'; - bcnt++; - } - pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)", - cip->chptr, cip->ctl_id); - return bcnt; -} - -static int store_val_any(struct pvr2_sysfs_ctl_item *cip, int customfl, - const char *buf,unsigned int count) -{ - int ret; - int mask,val; - if (customfl) { - ret = pvr2_ctrl_custom_sym_to_value(cip->cptr, buf, count, - &mask, &val); - } else { - ret = pvr2_ctrl_sym_to_value(cip->cptr, buf, count, - &mask, &val); - } - if (ret < 0) return ret; - ret = pvr2_ctrl_set_mask_value(cip->cptr, mask, val); - pvr2_hdw_commit_ctl(cip->chptr->channel.hdw); - return ret; -} - -static ssize_t store_val_norm(struct device *class_dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct pvr2_sysfs_ctl_item *cip; - int ret; - cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_val); - pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_norm(cid=%d) \"%.*s\"", - cip->chptr, cip->ctl_id, (int)count, buf); - ret = store_val_any(cip, 0, buf, count); - if (!ret) ret = count; - return ret; -} - -static ssize_t store_val_custom(struct device *class_dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct pvr2_sysfs_ctl_item *cip; - int ret; - cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_custom); - pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_custom(cid=%d) \"%.*s\"", - cip->chptr, cip->ctl_id, (int)count, buf); - ret = store_val_any(cip, 1, buf, count); - if (!ret) ret = count; - return ret; -} - -static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) -{ - struct pvr2_sysfs_ctl_item *cip; - struct pvr2_ctrl *cptr; - unsigned int cnt,acnt; - int ret; - - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id); - if (!cptr) return; - - cip = kzalloc(sizeof(*cip),GFP_KERNEL); - if (!cip) return; - pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip); - - cip->cptr = cptr; - cip->ctl_id = ctl_id; - - cip->chptr = sfp; - cip->item_next = NULL; - if (sfp->item_last) { - sfp->item_last->item_next = cip; - } else { - sfp->item_first = cip; - } - sfp->item_last = cip; - - sysfs_attr_init(&cip->attr_name.attr); - cip->attr_name.attr.name = "name"; - cip->attr_name.attr.mode = S_IRUGO; - cip->attr_name.show = show_name; - - sysfs_attr_init(&cip->attr_type.attr); - cip->attr_type.attr.name = "type"; - cip->attr_type.attr.mode = S_IRUGO; - cip->attr_type.show = show_type; - - sysfs_attr_init(&cip->attr_min.attr); - cip->attr_min.attr.name = "min_val"; - cip->attr_min.attr.mode = S_IRUGO; - cip->attr_min.show = show_min; - - sysfs_attr_init(&cip->attr_max.attr); - cip->attr_max.attr.name = "max_val"; - cip->attr_max.attr.mode = S_IRUGO; - cip->attr_max.show = show_max; - - sysfs_attr_init(&cip->attr_def.attr); - cip->attr_def.attr.name = "def_val"; - cip->attr_def.attr.mode = S_IRUGO; - cip->attr_def.show = show_def; - - sysfs_attr_init(&cip->attr_val.attr); - cip->attr_val.attr.name = "cur_val"; - cip->attr_val.attr.mode = S_IRUGO; - - sysfs_attr_init(&cip->attr_custom.attr); - cip->attr_custom.attr.name = "custom_val"; - cip->attr_custom.attr.mode = S_IRUGO; - - sysfs_attr_init(&cip->attr_enum.attr); - cip->attr_enum.attr.name = "enum_val"; - cip->attr_enum.attr.mode = S_IRUGO; - cip->attr_enum.show = show_enum; - - sysfs_attr_init(&cip->attr_bits.attr); - cip->attr_bits.attr.name = "bit_val"; - cip->attr_bits.attr.mode = S_IRUGO; - cip->attr_bits.show = show_bits; - - if (pvr2_ctrl_is_writable(cptr)) { - cip->attr_val.attr.mode |= S_IWUSR|S_IWGRP; - cip->attr_custom.attr.mode |= S_IWUSR|S_IWGRP; - } - - acnt = 0; - cip->attr_gen[acnt++] = &cip->attr_name.attr; - cip->attr_gen[acnt++] = &cip->attr_type.attr; - cip->attr_gen[acnt++] = &cip->attr_val.attr; - cip->attr_gen[acnt++] = &cip->attr_def.attr; - cip->attr_val.show = show_val_norm; - cip->attr_val.store = store_val_norm; - if (pvr2_ctrl_has_custom_symbols(cptr)) { - cip->attr_gen[acnt++] = &cip->attr_custom.attr; - cip->attr_custom.show = show_val_custom; - cip->attr_custom.store = store_val_custom; - } - switch (pvr2_ctrl_get_type(cptr)) { - case pvr2_ctl_enum: - // Control is an enumeration - cip->attr_gen[acnt++] = &cip->attr_enum.attr; - break; - case pvr2_ctl_int: - // Control is an integer - cip->attr_gen[acnt++] = &cip->attr_min.attr; - cip->attr_gen[acnt++] = &cip->attr_max.attr; - break; - case pvr2_ctl_bitmask: - // Control is an bitmask - cip->attr_gen[acnt++] = &cip->attr_bits.attr; - break; - default: break; - } - - cnt = scnprintf(cip->name,sizeof(cip->name)-1,"ctl_%s", - pvr2_ctrl_get_name(cptr)); - cip->name[cnt] = 0; - cip->grp.name = cip->name; - cip->grp.attrs = cip->attr_gen; - - ret = sysfs_create_group(&sfp->class_dev->kobj,&cip->grp); - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "sysfs_create_group error: %d", - ret); - return; - } - cip->created_ok = !0; -} - -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC -static ssize_t debuginfo_show(struct device *, struct device_attribute *, - char *); -static ssize_t debugcmd_show(struct device *, struct device_attribute *, - char *); -static ssize_t debugcmd_store(struct device *, struct device_attribute *, - const char *, size_t count); - -static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp) -{ - struct pvr2_sysfs_debugifc *dip; - int ret; - - dip = kzalloc(sizeof(*dip),GFP_KERNEL); - if (!dip) return; - sysfs_attr_init(&dip->attr_debugcmd.attr); - dip->attr_debugcmd.attr.name = "debugcmd"; - dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP; - dip->attr_debugcmd.show = debugcmd_show; - dip->attr_debugcmd.store = debugcmd_store; - sysfs_attr_init(&dip->attr_debuginfo.attr); - dip->attr_debuginfo.attr.name = "debuginfo"; - dip->attr_debuginfo.attr.mode = S_IRUGO; - dip->attr_debuginfo.show = debuginfo_show; - sfp->debugifc = dip; - ret = device_create_file(sfp->class_dev,&dip->attr_debugcmd); - if (ret < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "device_create_file error: %d", - ret); - } else { - dip->debugcmd_created_ok = !0; - } - ret = device_create_file(sfp->class_dev,&dip->attr_debuginfo); - if (ret < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "device_create_file error: %d", - ret); - } else { - dip->debuginfo_created_ok = !0; - } -} - - -static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp) -{ - if (!sfp->debugifc) return; - if (sfp->debugifc->debuginfo_created_ok) { - device_remove_file(sfp->class_dev, - &sfp->debugifc->attr_debuginfo); - } - if (sfp->debugifc->debugcmd_created_ok) { - device_remove_file(sfp->class_dev, - &sfp->debugifc->attr_debugcmd); - } - kfree(sfp->debugifc); - sfp->debugifc = NULL; -} -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ - - -static void pvr2_sysfs_add_controls(struct pvr2_sysfs *sfp) -{ - unsigned int idx,cnt; - cnt = pvr2_hdw_get_ctrl_count(sfp->channel.hdw); - for (idx = 0; idx < cnt; idx++) { - pvr2_sysfs_add_control(sfp,idx); - } -} - - -static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs *sfp) -{ - struct pvr2_sysfs_ctl_item *cip1,*cip2; - for (cip1 = sfp->item_first; cip1; cip1 = cip2) { - cip2 = cip1->item_next; - if (cip1->created_ok) { - sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp); - } - pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1); - kfree(cip1); - } -} - - -static void pvr2_sysfs_class_release(struct class *class) -{ - struct pvr2_sysfs_class *clp; - clp = container_of(class,struct pvr2_sysfs_class,class); - pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp); - kfree(clp); -} - - -static void pvr2_sysfs_release(struct device *class_dev) -{ - pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev); - kfree(class_dev); -} - - -static void class_dev_destroy(struct pvr2_sysfs *sfp) -{ - struct device *dev; - if (!sfp->class_dev) return; -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC - pvr2_sysfs_tear_down_debugifc(sfp); -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ - pvr2_sysfs_tear_down_controls(sfp); - if (sfp->hdw_desc_created_ok) { - device_remove_file(sfp->class_dev, - &sfp->attr_hdw_desc); - } - if (sfp->hdw_name_created_ok) { - device_remove_file(sfp->class_dev, - &sfp->attr_hdw_name); - } - if (sfp->bus_info_created_ok) { - device_remove_file(sfp->class_dev, - &sfp->attr_bus_info); - } - if (sfp->v4l_minor_number_created_ok) { - device_remove_file(sfp->class_dev, - &sfp->attr_v4l_minor_number); - } - if (sfp->v4l_radio_minor_number_created_ok) { - device_remove_file(sfp->class_dev, - &sfp->attr_v4l_radio_minor_number); - } - if (sfp->unit_number_created_ok) { - device_remove_file(sfp->class_dev, - &sfp->attr_unit_number); - } - pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev); - dev_set_drvdata(sfp->class_dev, NULL); - dev = sfp->class_dev->parent; - sfp->class_dev->parent = NULL; - put_device(dev); - device_unregister(sfp->class_dev); - sfp->class_dev = NULL; -} - - -static ssize_t v4l_minor_number_show(struct device *class_dev, - struct device_attribute *attr, char *buf) -{ - struct pvr2_sysfs *sfp; - sfp = dev_get_drvdata(class_dev); - if (!sfp) return -EINVAL; - return scnprintf(buf,PAGE_SIZE,"%d\n", - pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw, - pvr2_v4l_type_video)); -} - - -static ssize_t bus_info_show(struct device *class_dev, - struct device_attribute *attr, char *buf) -{ - struct pvr2_sysfs *sfp; - sfp = dev_get_drvdata(class_dev); - if (!sfp) return -EINVAL; - return scnprintf(buf,PAGE_SIZE,"%s\n", - pvr2_hdw_get_bus_info(sfp->channel.hdw)); -} - - -static ssize_t hdw_name_show(struct device *class_dev, - struct device_attribute *attr, char *buf) -{ - struct pvr2_sysfs *sfp; - sfp = dev_get_drvdata(class_dev); - if (!sfp) return -EINVAL; - return scnprintf(buf,PAGE_SIZE,"%s\n", - pvr2_hdw_get_type(sfp->channel.hdw)); -} - - -static ssize_t hdw_desc_show(struct device *class_dev, - struct device_attribute *attr, char *buf) -{ - struct pvr2_sysfs *sfp; - sfp = dev_get_drvdata(class_dev); - if (!sfp) return -EINVAL; - return scnprintf(buf,PAGE_SIZE,"%s\n", - pvr2_hdw_get_desc(sfp->channel.hdw)); -} - - -static ssize_t v4l_radio_minor_number_show(struct device *class_dev, - struct device_attribute *attr, - char *buf) -{ - struct pvr2_sysfs *sfp; - sfp = dev_get_drvdata(class_dev); - if (!sfp) return -EINVAL; - return scnprintf(buf,PAGE_SIZE,"%d\n", - pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw, - pvr2_v4l_type_radio)); -} - - -static ssize_t unit_number_show(struct device *class_dev, - struct device_attribute *attr, char *buf) -{ - struct pvr2_sysfs *sfp; - sfp = dev_get_drvdata(class_dev); - if (!sfp) return -EINVAL; - return scnprintf(buf,PAGE_SIZE,"%d\n", - pvr2_hdw_get_unit_number(sfp->channel.hdw)); -} - - -static void class_dev_create(struct pvr2_sysfs *sfp, - struct pvr2_sysfs_class *class_ptr) -{ - struct usb_device *usb_dev; - struct device *class_dev; - int ret; - - usb_dev = pvr2_hdw_get_dev(sfp->channel.hdw); - if (!usb_dev) return; - class_dev = kzalloc(sizeof(*class_dev),GFP_KERNEL); - if (!class_dev) return; - - pvr2_sysfs_trace("Creating class_dev id=%p",class_dev); - - class_dev->class = &class_ptr->class; - - dev_set_name(class_dev, "%s", - pvr2_hdw_get_device_identifier(sfp->channel.hdw)); - - class_dev->parent = get_device(&usb_dev->dev); - - sfp->class_dev = class_dev; - dev_set_drvdata(class_dev, sfp); - ret = device_register(class_dev); - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "device_register failed"); - put_device(class_dev); - return; - } - - sysfs_attr_init(&sfp->attr_v4l_minor_number.attr); - sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number"; - sfp->attr_v4l_minor_number.attr.mode = S_IRUGO; - sfp->attr_v4l_minor_number.show = v4l_minor_number_show; - sfp->attr_v4l_minor_number.store = NULL; - ret = device_create_file(sfp->class_dev, - &sfp->attr_v4l_minor_number); - if (ret < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "device_create_file error: %d", - ret); - } else { - sfp->v4l_minor_number_created_ok = !0; - } - - sysfs_attr_init(&sfp->attr_v4l_radio_minor_number.attr); - sfp->attr_v4l_radio_minor_number.attr.name = "v4l_radio_minor_number"; - sfp->attr_v4l_radio_minor_number.attr.mode = S_IRUGO; - sfp->attr_v4l_radio_minor_number.show = v4l_radio_minor_number_show; - sfp->attr_v4l_radio_minor_number.store = NULL; - ret = device_create_file(sfp->class_dev, - &sfp->attr_v4l_radio_minor_number); - if (ret < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "device_create_file error: %d", - ret); - } else { - sfp->v4l_radio_minor_number_created_ok = !0; - } - - sysfs_attr_init(&sfp->attr_unit_number.attr); - sfp->attr_unit_number.attr.name = "unit_number"; - sfp->attr_unit_number.attr.mode = S_IRUGO; - sfp->attr_unit_number.show = unit_number_show; - sfp->attr_unit_number.store = NULL; - ret = device_create_file(sfp->class_dev,&sfp->attr_unit_number); - if (ret < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "device_create_file error: %d", - ret); - } else { - sfp->unit_number_created_ok = !0; - } - - sysfs_attr_init(&sfp->attr_bus_info.attr); - sfp->attr_bus_info.attr.name = "bus_info_str"; - sfp->attr_bus_info.attr.mode = S_IRUGO; - sfp->attr_bus_info.show = bus_info_show; - sfp->attr_bus_info.store = NULL; - ret = device_create_file(sfp->class_dev, - &sfp->attr_bus_info); - if (ret < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "device_create_file error: %d", - ret); - } else { - sfp->bus_info_created_ok = !0; - } - - sysfs_attr_init(&sfp->attr_hdw_name.attr); - sfp->attr_hdw_name.attr.name = "device_hardware_type"; - sfp->attr_hdw_name.attr.mode = S_IRUGO; - sfp->attr_hdw_name.show = hdw_name_show; - sfp->attr_hdw_name.store = NULL; - ret = device_create_file(sfp->class_dev, - &sfp->attr_hdw_name); - if (ret < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "device_create_file error: %d", - ret); - } else { - sfp->hdw_name_created_ok = !0; - } - - sysfs_attr_init(&sfp->attr_hdw_desc.attr); - sfp->attr_hdw_desc.attr.name = "device_hardware_description"; - sfp->attr_hdw_desc.attr.mode = S_IRUGO; - sfp->attr_hdw_desc.show = hdw_desc_show; - sfp->attr_hdw_desc.store = NULL; - ret = device_create_file(sfp->class_dev, - &sfp->attr_hdw_desc); - if (ret < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "device_create_file error: %d", - ret); - } else { - sfp->hdw_desc_created_ok = !0; - } - - pvr2_sysfs_add_controls(sfp); -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC - pvr2_sysfs_add_debugifc(sfp); -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ -} - - -static void pvr2_sysfs_internal_check(struct pvr2_channel *chp) -{ - struct pvr2_sysfs *sfp; - sfp = container_of(chp,struct pvr2_sysfs,channel); - if (!sfp->channel.mc_head->disconnect_flag) return; - pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_sysfs id=%p",sfp); - class_dev_destroy(sfp); - pvr2_channel_done(&sfp->channel); - kfree(sfp); -} - - -struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp, - struct pvr2_sysfs_class *class_ptr) -{ - struct pvr2_sysfs *sfp; - sfp = kzalloc(sizeof(*sfp),GFP_KERNEL); - if (!sfp) return sfp; - pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_sysfs id=%p",sfp); - pvr2_channel_init(&sfp->channel,mp); - sfp->channel.check_func = pvr2_sysfs_internal_check; - - class_dev_create(sfp,class_ptr); - return sfp; -} - - - -struct pvr2_sysfs_class *pvr2_sysfs_class_create(void) -{ - struct pvr2_sysfs_class *clp; - clp = kzalloc(sizeof(*clp),GFP_KERNEL); - if (!clp) return clp; - pvr2_sysfs_trace("Creating and registering pvr2_sysfs_class id=%p", - clp); - clp->class.name = "pvrusb2"; - clp->class.class_release = pvr2_sysfs_class_release; - clp->class.dev_release = pvr2_sysfs_release; - if (class_register(&clp->class)) { - pvr2_sysfs_trace( - "Registration failed for pvr2_sysfs_class id=%p",clp); - kfree(clp); - clp = NULL; - } - return clp; -} - - -void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp) -{ - pvr2_sysfs_trace("Unregistering pvr2_sysfs_class id=%p", clp); - class_unregister(&clp->class); -} - - -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC -static ssize_t debuginfo_show(struct device *class_dev, - struct device_attribute *attr, char *buf) -{ - struct pvr2_sysfs *sfp; - sfp = dev_get_drvdata(class_dev); - if (!sfp) return -EINVAL; - pvr2_hdw_trigger_module_log(sfp->channel.hdw); - return pvr2_debugifc_print_info(sfp->channel.hdw,buf,PAGE_SIZE); -} - - -static ssize_t debugcmd_show(struct device *class_dev, - struct device_attribute *attr, char *buf) -{ - struct pvr2_sysfs *sfp; - sfp = dev_get_drvdata(class_dev); - if (!sfp) return -EINVAL; - return pvr2_debugifc_print_status(sfp->channel.hdw,buf,PAGE_SIZE); -} - - -static ssize_t debugcmd_store(struct device *class_dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct pvr2_sysfs *sfp; - int ret; - - sfp = dev_get_drvdata(class_dev); - if (!sfp) return -EINVAL; - - ret = pvr2_debugifc_docmd(sfp->channel.hdw,buf,count); - if (ret < 0) return ret; - return count; -} -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.h b/drivers/media/video/pvrusb2/pvrusb2-sysfs.h deleted file mode 100644 index 6d875bfe7991..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ -#ifndef __PVRUSB2_SYSFS_H -#define __PVRUSB2_SYSFS_H - -#include <linux/list.h> -#include <linux/sysfs.h> -#include "pvrusb2-context.h" - -struct pvr2_sysfs; -struct pvr2_sysfs_class; - -struct pvr2_sysfs_class *pvr2_sysfs_class_create(void); -void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *); - -struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *, - struct pvr2_sysfs_class *); - -#endif /* __PVRUSB2_SYSFS_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-util.h b/drivers/media/video/pvrusb2/pvrusb2-util.h deleted file mode 100644 index 92b75544ee2e..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-util.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ -#ifndef __PVRUSB2_UTIL_H -#define __PVRUSB2_UTIL_H - -#define PVR2_DECOMPOSE_LE(t,i,d) \ - do { \ - (t)[i] = (d) & 0xff;\ - (t)[i+1] = ((d) >> 8) & 0xff;\ - (t)[i+2] = ((d) >> 16) & 0xff;\ - (t)[i+3] = ((d) >> 24) & 0xff;\ - } while(0) - -#define PVR2_DECOMPOSE_BE(t,i,d) \ - do { \ - (t)[i+3] = (d) & 0xff;\ - (t)[i+2] = ((d) >> 8) & 0xff;\ - (t)[i+1] = ((d) >> 16) & 0xff;\ - (t)[i] = ((d) >> 24) & 0xff;\ - } while(0) - -#define PVR2_COMPOSE_LE(t,i) \ - ((((u32)((t)[i+3])) << 24) | \ - (((u32)((t)[i+2])) << 16) | \ - (((u32)((t)[i+1])) << 8) | \ - ((u32)((t)[i]))) - -#define PVR2_COMPOSE_BE(t,i) \ - ((((u32)((t)[i])) << 24) | \ - (((u32)((t)[i+1])) << 16) | \ - (((u32)((t)[i+2])) << 8) | \ - ((u32)((t)[i+3]))) - - -#endif /* __PVRUSB2_UTIL_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c deleted file mode 100644 index f344aed32a93..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ /dev/null @@ -1,1413 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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/slab.h> -#include <linux/version.h> -#include "pvrusb2-context.h" -#include "pvrusb2-hdw.h" -#include "pvrusb2.h" -#include "pvrusb2-debug.h" -#include "pvrusb2-v4l2.h" -#include "pvrusb2-ioread.h" -#include <linux/videodev2.h> -#include <linux/module.h> -#include <media/v4l2-dev.h> -#include <media/v4l2-common.h> -#include <media/v4l2-ioctl.h> - -struct pvr2_v4l2_dev; -struct pvr2_v4l2_fh; -struct pvr2_v4l2; - -struct pvr2_v4l2_dev { - struct video_device devbase; /* MUST be first! */ - struct pvr2_v4l2 *v4lp; - struct pvr2_context_stream *stream; - /* Information about this device: */ - enum pvr2_config config; /* Expected stream format */ - int v4l_type; /* V4L defined type for this device node */ - enum pvr2_v4l_type minor_type; /* pvr2-understood minor device type */ -}; - -struct pvr2_v4l2_fh { - struct pvr2_channel channel; - struct pvr2_v4l2_dev *pdi; - enum v4l2_priority prio; - struct pvr2_ioread *rhp; - struct file *file; - struct pvr2_v4l2 *vhead; - struct pvr2_v4l2_fh *vnext; - struct pvr2_v4l2_fh *vprev; - wait_queue_head_t wait_data; - int fw_mode_flag; - /* Map contiguous ordinal value to input id */ - unsigned char *input_map; - unsigned int input_cnt; -}; - -struct pvr2_v4l2 { - struct pvr2_channel channel; - struct pvr2_v4l2_fh *vfirst; - struct pvr2_v4l2_fh *vlast; - - struct v4l2_prio_state prio; - - /* streams - Note that these must be separately, individually, - * allocated pointers. This is because the v4l core is going to - * manage their deletion - separately, individually... */ - struct pvr2_v4l2_dev *dev_video; - struct pvr2_v4l2_dev *dev_radio; -}; - -static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1}; -module_param_array(video_nr, int, NULL, 0444); -MODULE_PARM_DESC(video_nr, "Offset for device's video dev minor"); -static int radio_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1}; -module_param_array(radio_nr, int, NULL, 0444); -MODULE_PARM_DESC(radio_nr, "Offset for device's radio dev minor"); -static int vbi_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1}; -module_param_array(vbi_nr, int, NULL, 0444); -MODULE_PARM_DESC(vbi_nr, "Offset for device's vbi dev minor"); - -static struct v4l2_capability pvr_capability ={ - .driver = "pvrusb2", - .card = "Hauppauge WinTV pvr-usb2", - .bus_info = "usb", - .version = LINUX_VERSION_CODE, - .capabilities = (V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | - V4L2_CAP_READWRITE), -}; - -static struct v4l2_fmtdesc pvr_fmtdesc [] = { - { - .index = 0, - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .flags = V4L2_FMT_FLAG_COMPRESSED, - .description = "MPEG1/2", - // This should really be V4L2_PIX_FMT_MPEG, but xawtv - // breaks when I do that. - .pixelformat = 0, // V4L2_PIX_FMT_MPEG, - } -}; - -#define PVR_FORMAT_PIX 0 -#define PVR_FORMAT_VBI 1 - -static struct v4l2_format pvr_format [] = { - [PVR_FORMAT_PIX] = { - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .fmt = { - .pix = { - .width = 720, - .height = 576, - // This should really be V4L2_PIX_FMT_MPEG, - // but xawtv breaks when I do that. - .pixelformat = 0, // V4L2_PIX_FMT_MPEG, - .field = V4L2_FIELD_INTERLACED, - .bytesperline = 0, // doesn't make sense - // here - //FIXME : Don't know what to put here... - .sizeimage = (32*1024), - .colorspace = 0, // doesn't make sense here - .priv = 0 - } - } - }, - [PVR_FORMAT_VBI] = { - .type = V4L2_BUF_TYPE_VBI_CAPTURE, - .fmt = { - .vbi = { - .sampling_rate = 27000000, - .offset = 248, - .samples_per_line = 1443, - .sample_format = V4L2_PIX_FMT_GREY, - .start = { 0, 0 }, - .count = { 0, 0 }, - .flags = 0, - } - } - } -}; - - - -/* - * This is part of Video 4 Linux API. These procedures handle ioctl() calls. - */ -static int pvr2_querycap(struct file *file, void *priv, struct v4l2_capability *cap) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - - memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability)); - strlcpy(cap->bus_info, pvr2_hdw_get_bus_info(hdw), - sizeof(cap->bus_info)); - strlcpy(cap->card, pvr2_hdw_get_desc(hdw), sizeof(cap->card)); - return 0; -} - -static int pvr2_g_priority(struct file *file, void *priv, enum v4l2_priority *p) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_v4l2 *vp = fh->vhead; - - *p = v4l2_prio_max(&vp->prio); - return 0; -} - -static int pvr2_s_priority(struct file *file, void *priv, enum v4l2_priority prio) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_v4l2 *vp = fh->vhead; - - return v4l2_prio_change(&vp->prio, &fh->prio, prio); -} - -static int pvr2_g_std(struct file *file, void *priv, v4l2_std_id *std) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - int val = 0; - int ret; - - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_STDCUR), &val); - *std = val; - return ret; -} - -int pvr2_s_std(struct file *file, void *priv, v4l2_std_id *std) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - - return pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_STDCUR), *std); -} - -static int pvr2_querystd(struct file *file, void *priv, v4l2_std_id *std) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - int val = 0; - int ret; - - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_STDDETECT), &val); - *std = val; - return ret; -} - -static int pvr2_enum_input(struct file *file, void *priv, struct v4l2_input *vi) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - struct pvr2_ctrl *cptr; - struct v4l2_input tmp; - unsigned int cnt; - int val; - - cptr = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT); - - memset(&tmp, 0, sizeof(tmp)); - tmp.index = vi->index; - if (vi->index >= fh->input_cnt) - return -EINVAL; - val = fh->input_map[vi->index]; - switch (val) { - case PVR2_CVAL_INPUT_TV: - case PVR2_CVAL_INPUT_DTV: - case PVR2_CVAL_INPUT_RADIO: - tmp.type = V4L2_INPUT_TYPE_TUNER; - break; - case PVR2_CVAL_INPUT_SVIDEO: - case PVR2_CVAL_INPUT_COMPOSITE: - tmp.type = V4L2_INPUT_TYPE_CAMERA; - break; - default: - return -EINVAL; - } - - cnt = 0; - pvr2_ctrl_get_valname(cptr, val, - tmp.name, sizeof(tmp.name) - 1, &cnt); - tmp.name[cnt] = 0; - - /* Don't bother with audioset, since this driver currently - always switches the audio whenever the video is - switched. */ - - /* Handling std is a tougher problem. It doesn't make - sense in cases where a device might be multi-standard. - We could just copy out the current value for the - standard, but it can change over time. For now just - leave it zero. */ - *vi = tmp; - return 0; -} - -static int pvr2_g_input(struct file *file, void *priv, unsigned int *i) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - unsigned int idx; - struct pvr2_ctrl *cptr; - int val; - int ret; - - cptr = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT); - val = 0; - ret = pvr2_ctrl_get_value(cptr, &val); - *i = 0; - for (idx = 0; idx < fh->input_cnt; idx++) { - if (fh->input_map[idx] == val) { - *i = idx; - break; - } - } - return ret; -} - -static int pvr2_s_input(struct file *file, void *priv, unsigned int inp) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - - if (inp >= fh->input_cnt) - return -EINVAL; - return pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT), - fh->input_map[inp]); -} - -static int pvr2_enumaudio(struct file *file, void *priv, struct v4l2_audio *vin) -{ - /* pkt: FIXME: We are returning one "fake" input here - which could very well be called "whatever_we_like". - This is for apps that want to see an audio input - just to feel comfortable, as well as to test if - it can do stereo or sth. There is actually no guarantee - that the actual audio input cannot change behind the app's - back, but most applications should not mind that either. - - Hopefully, mplayer people will work with us on this (this - whole mess is to support mplayer pvr://), or Hans will come - up with a more standard way to say "we have inputs but we - don 't want you to change them independent of video" which - will sort this mess. - */ - - if (vin->index > 0) - return -EINVAL; - strncpy(vin->name, "PVRUSB2 Audio", 14); - vin->capability = V4L2_AUDCAP_STEREO; - return 0; -} - -static int pvr2_g_audio(struct file *file, void *priv, struct v4l2_audio *vin) -{ - /* pkt: FIXME: see above comment (VIDIOC_ENUMAUDIO) */ - vin->index = 0; - strncpy(vin->name, "PVRUSB2 Audio", 14); - vin->capability = V4L2_AUDCAP_STEREO; - return 0; -} - -static int pvr2_s_audio(struct file *file, void *priv, struct v4l2_audio *vout) -{ - if (vout->index) - return -EINVAL; - return 0; -} - -static int pvr2_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - - if (vt->index != 0) - return -EINVAL; /* Only answer for the 1st tuner */ - - pvr2_hdw_execute_tuner_poll(hdw); - return pvr2_hdw_get_tuner_status(hdw, vt); -} - -static int pvr2_s_tuner(struct file *file, void *priv, struct v4l2_tuner *vt) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - - if (vt->index != 0) - return -EINVAL; - - return pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_AUDIOMODE), - vt->audmode); -} - -int pvr2_s_frequency(struct file *file, void *priv, struct v4l2_frequency *vf) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - unsigned long fv; - struct v4l2_tuner vt; - int cur_input; - struct pvr2_ctrl *ctrlp; - int ret; - - ret = pvr2_hdw_get_tuner_status(hdw, &vt); - if (ret != 0) - return ret; - ctrlp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT); - ret = pvr2_ctrl_get_value(ctrlp, &cur_input); - if (ret != 0) - return ret; - if (vf->type == V4L2_TUNER_RADIO) { - if (cur_input != PVR2_CVAL_INPUT_RADIO) - pvr2_ctrl_set_value(ctrlp, PVR2_CVAL_INPUT_RADIO); - } else { - if (cur_input == PVR2_CVAL_INPUT_RADIO) - pvr2_ctrl_set_value(ctrlp, PVR2_CVAL_INPUT_TV); - } - fv = vf->frequency; - if (vt.capability & V4L2_TUNER_CAP_LOW) - fv = (fv * 125) / 2; - else - fv = fv * 62500; - return pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),fv); -} - -static int pvr2_g_frequency(struct file *file, void *priv, struct v4l2_frequency *vf) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - int val = 0; - int cur_input; - struct v4l2_tuner vt; - int ret; - - ret = pvr2_hdw_get_tuner_status(hdw, &vt); - if (ret != 0) - return ret; - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_FREQUENCY), - &val); - if (ret != 0) - return ret; - pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT), - &cur_input); - if (cur_input == PVR2_CVAL_INPUT_RADIO) - vf->type = V4L2_TUNER_RADIO; - else - vf->type = V4L2_TUNER_ANALOG_TV; - if (vt.capability & V4L2_TUNER_CAP_LOW) - val = (val * 2) / 125; - else - val /= 62500; - vf->frequency = val; - return 0; -} - -static int pvr2_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *fd) -{ - /* Only one format is supported : mpeg.*/ - if (fd->index != 0) - return -EINVAL; - - memcpy(fd, pvr_fmtdesc, sizeof(struct v4l2_fmtdesc)); - return 0; -} - -static int pvr2_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - int val; - - memcpy(vf, &pvr_format[PVR_FORMAT_PIX], sizeof(struct v4l2_format)); - val = 0; - pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_HRES), - &val); - vf->fmt.pix.width = val; - val = 0; - pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_VRES), - &val); - vf->fmt.pix.height = val; - return 0; -} - -static int pvr2_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - int lmin, lmax, ldef; - struct pvr2_ctrl *hcp, *vcp; - int h = vf->fmt.pix.height; - int w = vf->fmt.pix.width; - - hcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_HRES); - vcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_VRES); - - lmin = pvr2_ctrl_get_min(hcp); - lmax = pvr2_ctrl_get_max(hcp); - pvr2_ctrl_get_def(hcp, &ldef); - if (w == -1) - w = ldef; - else if (w < lmin) - w = lmin; - else if (w > lmax) - w = lmax; - lmin = pvr2_ctrl_get_min(vcp); - lmax = pvr2_ctrl_get_max(vcp); - pvr2_ctrl_get_def(vcp, &ldef); - if (h == -1) - h = ldef; - else if (h < lmin) - h = lmin; - else if (h > lmax) - h = lmax; - - memcpy(vf, &pvr_format[PVR_FORMAT_PIX], - sizeof(struct v4l2_format)); - vf->fmt.pix.width = w; - vf->fmt.pix.height = h; - return 0; -} - -static int pvr2_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - struct pvr2_ctrl *hcp, *vcp; - int ret = pvr2_try_fmt_vid_cap(file, fh, vf); - - if (ret) - return ret; - hcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_HRES); - vcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_VRES); - pvr2_ctrl_set_value(hcp, vf->fmt.pix.width); - pvr2_ctrl_set_value(vcp, vf->fmt.pix.height); - return 0; -} - -static int pvr2_streamon(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - struct pvr2_v4l2_dev *pdi = fh->pdi; - int ret; - - if (!fh->pdi->stream) { - /* No stream defined for this node. This means - that we're not currently allowed to stream from - this node. */ - return -EPERM; - } - ret = pvr2_hdw_set_stream_type(hdw, pdi->config); - if (ret < 0) - return ret; - return pvr2_hdw_set_streaming(hdw, !0); -} - -static int pvr2_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - - if (!fh->pdi->stream) { - /* No stream defined for this node. This means - that we're not currently allowed to stream from - this node. */ - return -EPERM; - } - return pvr2_hdw_set_streaming(hdw, 0); -} - -static int pvr2_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *vc) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - struct pvr2_ctrl *cptr; - int val; - - if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) { - cptr = pvr2_hdw_get_ctrl_nextv4l( - hdw, (vc->id & ~V4L2_CTRL_FLAG_NEXT_CTRL)); - if (cptr) - vc->id = pvr2_ctrl_get_v4lid(cptr); - } else { - cptr = pvr2_hdw_get_ctrl_v4l(hdw, vc->id); - } - if (!cptr) { - pvr2_trace(PVR2_TRACE_V4LIOCTL, - "QUERYCTRL id=0x%x not implemented here", - vc->id); - return -EINVAL; - } - - pvr2_trace(PVR2_TRACE_V4LIOCTL, - "QUERYCTRL id=0x%x mapping name=%s (%s)", - vc->id, pvr2_ctrl_get_name(cptr), - pvr2_ctrl_get_desc(cptr)); - strlcpy(vc->name, pvr2_ctrl_get_desc(cptr), sizeof(vc->name)); - vc->flags = pvr2_ctrl_get_v4lflags(cptr); - pvr2_ctrl_get_def(cptr, &val); - vc->default_value = val; - switch (pvr2_ctrl_get_type(cptr)) { - case pvr2_ctl_enum: - vc->type = V4L2_CTRL_TYPE_MENU; - vc->minimum = 0; - vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1; - vc->step = 1; - break; - case pvr2_ctl_bool: - vc->type = V4L2_CTRL_TYPE_BOOLEAN; - vc->minimum = 0; - vc->maximum = 1; - vc->step = 1; - break; - case pvr2_ctl_int: - vc->type = V4L2_CTRL_TYPE_INTEGER; - vc->minimum = pvr2_ctrl_get_min(cptr); - vc->maximum = pvr2_ctrl_get_max(cptr); - vc->step = 1; - break; - default: - pvr2_trace(PVR2_TRACE_V4LIOCTL, - "QUERYCTRL id=0x%x name=%s not mappable", - vc->id, pvr2_ctrl_get_name(cptr)); - return -EINVAL; - } - return 0; -} - -static int pvr2_querymenu(struct file *file, void *priv, struct v4l2_querymenu *vm) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - unsigned int cnt = 0; - int ret; - - ret = pvr2_ctrl_get_valname(pvr2_hdw_get_ctrl_v4l(hdw, vm->id), - vm->index, - vm->name, sizeof(vm->name) - 1, - &cnt); - vm->name[cnt] = 0; - return ret; -} - -static int pvr2_g_ctrl(struct file *file, void *priv, struct v4l2_control *vc) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - int val = 0; - int ret; - - ret = pvr2_ctrl_get_value(pvr2_hdw_get_ctrl_v4l(hdw, vc->id), - &val); - vc->value = val; - return ret; -} - -static int pvr2_s_ctrl(struct file *file, void *priv, struct v4l2_control *vc) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - - return pvr2_ctrl_set_value(pvr2_hdw_get_ctrl_v4l(hdw, vc->id), - vc->value); -} - -static int pvr2_g_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctls) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - struct v4l2_ext_control *ctrl; - unsigned int idx; - int val; - int ret; - - ret = 0; - for (idx = 0; idx < ctls->count; idx++) { - ctrl = ctls->controls + idx; - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id), &val); - if (ret) { - ctls->error_idx = idx; - return ret; - } - /* Ensure that if read as a 64 bit value, the user - will still get a hopefully sane value */ - ctrl->value64 = 0; - ctrl->value = val; - } - return 0; -} - -static int pvr2_s_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctls) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - struct v4l2_ext_control *ctrl; - unsigned int idx; - int ret; - - ret = 0; - for (idx = 0; idx < ctls->count; idx++) { - ctrl = ctls->controls + idx; - ret = pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id), - ctrl->value); - if (ret) { - ctls->error_idx = idx; - return ret; - } - } - return 0; -} - -static int pvr2_try_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctls) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - struct v4l2_ext_control *ctrl; - struct pvr2_ctrl *pctl; - unsigned int idx; - - /* For the moment just validate that the requested control - actually exists. */ - for (idx = 0; idx < ctls->count; idx++) { - ctrl = ctls->controls + idx; - pctl = pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id); - if (!pctl) { - ctls->error_idx = idx; - return -EINVAL; - } - } - return 0; -} - -static int pvr2_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cap) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - int ret; - - if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - ret = pvr2_hdw_get_cropcap(hdw, cap); - cap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* paranoia */ - return ret; -} - -static int pvr2_g_crop(struct file *file, void *priv, struct v4l2_crop *crop) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - int val = 0; - int ret; - - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), &val); - if (ret != 0) - return -EINVAL; - crop->c.left = val; - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT), &val); - if (ret != 0) - return -EINVAL; - crop->c.top = val; - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW), &val); - if (ret != 0) - return -EINVAL; - crop->c.width = val; - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH), &val); - if (ret != 0) - return -EINVAL; - crop->c.height = val; - return 0; -} - -static int pvr2_s_crop(struct file *file, void *priv, struct v4l2_crop *crop) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - int ret; - - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - ret = pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), - crop->c.left); - if (ret != 0) - return -EINVAL; - ret = pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT), - crop->c.top); - if (ret != 0) - return -EINVAL; - ret = pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW), - crop->c.width); - if (ret != 0) - return -EINVAL; - ret = pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH), - crop->c.height); - if (ret != 0) - return -EINVAL; - return 0; -} - -static int pvr2_log_status(struct file *file, void *priv) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - - pvr2_hdw_trigger_module_log(hdw); - return 0; -} - -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int pvr2_g_register(struct file *file, void *priv, struct v4l2_dbg_register *req) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - u64 val; - int ret; - - ret = pvr2_hdw_register_access( - hdw, &req->match, req->reg, - 0, &val); - req->val = val; - return ret; -} - -static int pvr2_s_register(struct file *file, void *priv, struct v4l2_dbg_register *req) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - u64 val; - int ret; - - val = req->val; - ret = pvr2_hdw_register_access( - hdw, &req->match, req->reg, - 1, &val); - return ret; -} -#endif - -static const struct v4l2_ioctl_ops pvr2_ioctl_ops = { - .vidioc_querycap = pvr2_querycap, - .vidioc_g_priority = pvr2_g_priority, - .vidioc_s_priority = pvr2_s_priority, - .vidioc_s_audio = pvr2_s_audio, - .vidioc_g_audio = pvr2_g_audio, - .vidioc_enumaudio = pvr2_enumaudio, - .vidioc_enum_input = pvr2_enum_input, - .vidioc_cropcap = pvr2_cropcap, - .vidioc_s_crop = pvr2_s_crop, - .vidioc_g_crop = pvr2_g_crop, - .vidioc_g_input = pvr2_g_input, - .vidioc_s_input = pvr2_s_input, - .vidioc_g_frequency = pvr2_g_frequency, - .vidioc_s_frequency = pvr2_s_frequency, - .vidioc_s_tuner = pvr2_s_tuner, - .vidioc_g_tuner = pvr2_g_tuner, - .vidioc_g_std = pvr2_g_std, - .vidioc_s_std = pvr2_s_std, - .vidioc_querystd = pvr2_querystd, - .vidioc_log_status = pvr2_log_status, - .vidioc_enum_fmt_vid_cap = pvr2_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = pvr2_g_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = pvr2_s_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = pvr2_try_fmt_vid_cap, - .vidioc_streamon = pvr2_streamon, - .vidioc_streamoff = pvr2_streamoff, - .vidioc_queryctrl = pvr2_queryctrl, - .vidioc_querymenu = pvr2_querymenu, - .vidioc_g_ctrl = pvr2_g_ctrl, - .vidioc_s_ctrl = pvr2_s_ctrl, - .vidioc_g_ext_ctrls = pvr2_g_ext_ctrls, - .vidioc_s_ext_ctrls = pvr2_s_ext_ctrls, - .vidioc_try_ext_ctrls = pvr2_try_ext_ctrls, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .vidioc_g_register = pvr2_g_register, - .vidioc_s_register = pvr2_s_register, -#endif -}; - -static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) -{ - struct pvr2_hdw *hdw = dip->v4lp->channel.mc_head->hdw; - enum pvr2_config cfg = dip->config; - char msg[80]; - unsigned int mcnt; - - /* Construct the unregistration message *before* we actually - perform the unregistration step. By doing it this way we don't - have to worry about potentially touching deleted resources. */ - mcnt = scnprintf(msg, sizeof(msg) - 1, - "pvrusb2: unregistered device %s [%s]", - video_device_node_name(&dip->devbase), - pvr2_config_get_name(cfg)); - msg[mcnt] = 0; - - pvr2_hdw_v4l_store_minor_number(hdw,dip->minor_type,-1); - - /* Paranoia */ - dip->v4lp = NULL; - dip->stream = NULL; - - /* Actual deallocation happens later when all internal references - are gone. */ - video_unregister_device(&dip->devbase); - - printk(KERN_INFO "%s\n", msg); - -} - - -static void pvr2_v4l2_dev_disassociate_parent(struct pvr2_v4l2_dev *dip) -{ - if (!dip) return; - if (!dip->devbase.parent) return; - dip->devbase.parent = NULL; - device_move(&dip->devbase.dev, NULL, DPM_ORDER_NONE); -} - - -static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp) -{ - if (vp->dev_video) { - pvr2_v4l2_dev_destroy(vp->dev_video); - vp->dev_video = NULL; - } - if (vp->dev_radio) { - pvr2_v4l2_dev_destroy(vp->dev_radio); - vp->dev_radio = NULL; - } - - pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp); - pvr2_channel_done(&vp->channel); - kfree(vp); -} - - -static void pvr2_video_device_release(struct video_device *vdev) -{ - struct pvr2_v4l2_dev *dev; - dev = container_of(vdev,struct pvr2_v4l2_dev,devbase); - kfree(dev); -} - - -static void pvr2_v4l2_internal_check(struct pvr2_channel *chp) -{ - struct pvr2_v4l2 *vp; - vp = container_of(chp,struct pvr2_v4l2,channel); - if (!vp->channel.mc_head->disconnect_flag) return; - pvr2_v4l2_dev_disassociate_parent(vp->dev_video); - pvr2_v4l2_dev_disassociate_parent(vp->dev_radio); - if (vp->vfirst) return; - pvr2_v4l2_destroy_no_lock(vp); -} - - -static long pvr2_v4l2_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_v4l2 *vp = fh->vhead; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - long ret = -EINVAL; - - if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) - v4l_printk_ioctl(pvr2_hdw_get_driver_name(hdw), cmd); - - if (!pvr2_hdw_dev_ok(hdw)) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "ioctl failed - bad or no context"); - return -EFAULT; - } - - /* check priority */ - switch (cmd) { - case VIDIOC_S_CTRL: - case VIDIOC_S_STD: - case VIDIOC_S_INPUT: - case VIDIOC_S_TUNER: - case VIDIOC_S_FREQUENCY: - ret = v4l2_prio_check(&vp->prio, fh->prio); - if (ret) - return ret; - } - - ret = video_ioctl2(file, cmd, arg); - - pvr2_hdw_commit_ctl(hdw); - - if (ret < 0) { - if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { - pvr2_trace(PVR2_TRACE_V4LIOCTL, - "pvr2_v4l2_do_ioctl failure, ret=%ld", ret); - } else { - if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { - pvr2_trace(PVR2_TRACE_V4LIOCTL, - "pvr2_v4l2_do_ioctl failure, ret=%ld" - " command was:", ret); - v4l_printk_ioctl(pvr2_hdw_get_driver_name(hdw), - cmd); - } - } - } else { - pvr2_trace(PVR2_TRACE_V4LIOCTL, - "pvr2_v4l2_do_ioctl complete, ret=%ld (0x%lx)", - ret, ret); - } - return ret; - -} - - -static int pvr2_v4l2_release(struct file *file) -{ - struct pvr2_v4l2_fh *fhp = file->private_data; - struct pvr2_v4l2 *vp = fhp->vhead; - struct pvr2_hdw *hdw = fhp->channel.mc_head->hdw; - - pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release"); - - if (fhp->rhp) { - struct pvr2_stream *sp; - pvr2_hdw_set_streaming(hdw,0); - sp = pvr2_ioread_get_stream(fhp->rhp); - if (sp) pvr2_stream_set_callback(sp,NULL,NULL); - pvr2_ioread_destroy(fhp->rhp); - fhp->rhp = NULL; - } - - v4l2_prio_close(&vp->prio, fhp->prio); - file->private_data = NULL; - - if (fhp->vnext) { - fhp->vnext->vprev = fhp->vprev; - } else { - vp->vlast = fhp->vprev; - } - if (fhp->vprev) { - fhp->vprev->vnext = fhp->vnext; - } else { - vp->vfirst = fhp->vnext; - } - fhp->vnext = NULL; - fhp->vprev = NULL; - fhp->vhead = NULL; - pvr2_channel_done(&fhp->channel); - pvr2_trace(PVR2_TRACE_STRUCT, - "Destroying pvr_v4l2_fh id=%p",fhp); - if (fhp->input_map) { - kfree(fhp->input_map); - fhp->input_map = NULL; - } - kfree(fhp); - if (vp->channel.mc_head->disconnect_flag && !vp->vfirst) { - pvr2_v4l2_destroy_no_lock(vp); - } - return 0; -} - - -static int pvr2_v4l2_open(struct file *file) -{ - struct pvr2_v4l2_dev *dip; /* Our own context pointer */ - struct pvr2_v4l2_fh *fhp; - struct pvr2_v4l2 *vp; - struct pvr2_hdw *hdw; - unsigned int input_mask = 0; - unsigned int input_cnt,idx; - int ret = 0; - - dip = container_of(video_devdata(file),struct pvr2_v4l2_dev,devbase); - - vp = dip->v4lp; - hdw = vp->channel.hdw; - - pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_open"); - - if (!pvr2_hdw_dev_ok(hdw)) { - pvr2_trace(PVR2_TRACE_OPEN_CLOSE, - "pvr2_v4l2_open: hardware not ready"); - return -EIO; - } - - fhp = kzalloc(sizeof(*fhp),GFP_KERNEL); - if (!fhp) { - return -ENOMEM; - } - - init_waitqueue_head(&fhp->wait_data); - fhp->pdi = dip; - - pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp); - pvr2_channel_init(&fhp->channel,vp->channel.mc_head); - - if (dip->v4l_type == VFL_TYPE_RADIO) { - /* Opening device as a radio, legal input selection subset - is just the radio. */ - input_mask = (1 << PVR2_CVAL_INPUT_RADIO); - } else { - /* Opening the main V4L device, legal input selection - subset includes all analog inputs. */ - input_mask = ((1 << PVR2_CVAL_INPUT_RADIO) | - (1 << PVR2_CVAL_INPUT_TV) | - (1 << PVR2_CVAL_INPUT_COMPOSITE) | - (1 << PVR2_CVAL_INPUT_SVIDEO)); - } - ret = pvr2_channel_limit_inputs(&fhp->channel,input_mask); - if (ret) { - pvr2_channel_done(&fhp->channel); - pvr2_trace(PVR2_TRACE_STRUCT, - "Destroying pvr_v4l2_fh id=%p (input mask error)", - fhp); - - kfree(fhp); - return ret; - } - - input_mask &= pvr2_hdw_get_input_available(hdw); - input_cnt = 0; - for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) { - if (input_mask & (1 << idx)) input_cnt++; - } - fhp->input_cnt = input_cnt; - fhp->input_map = kzalloc(input_cnt,GFP_KERNEL); - if (!fhp->input_map) { - pvr2_channel_done(&fhp->channel); - pvr2_trace(PVR2_TRACE_STRUCT, - "Destroying pvr_v4l2_fh id=%p (input map failure)", - fhp); - kfree(fhp); - return -ENOMEM; - } - input_cnt = 0; - for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) { - if (!(input_mask & (1 << idx))) continue; - fhp->input_map[input_cnt++] = idx; - } - - fhp->vnext = NULL; - fhp->vprev = vp->vlast; - if (vp->vlast) { - vp->vlast->vnext = fhp; - } else { - vp->vfirst = fhp; - } - vp->vlast = fhp; - fhp->vhead = vp; - - fhp->file = file; - file->private_data = fhp; - v4l2_prio_open(&vp->prio, &fhp->prio); - - fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw); - - return 0; -} - - -static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp) -{ - wake_up(&fhp->wait_data); -} - -static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh) -{ - int ret; - struct pvr2_stream *sp; - struct pvr2_hdw *hdw; - if (fh->rhp) return 0; - - if (!fh->pdi->stream) { - /* No stream defined for this node. This means that we're - not currently allowed to stream from this node. */ - return -EPERM; - } - - /* First read() attempt. Try to claim the stream and start - it... */ - if ((ret = pvr2_channel_claim_stream(&fh->channel, - fh->pdi->stream)) != 0) { - /* Someone else must already have it */ - return ret; - } - - fh->rhp = pvr2_channel_create_mpeg_stream(fh->pdi->stream); - if (!fh->rhp) { - pvr2_channel_claim_stream(&fh->channel,NULL); - return -ENOMEM; - } - - hdw = fh->channel.mc_head->hdw; - sp = fh->pdi->stream->stream; - pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh); - pvr2_hdw_set_stream_type(hdw,fh->pdi->config); - if ((ret = pvr2_hdw_set_streaming(hdw,!0)) < 0) return ret; - return pvr2_ioread_set_enabled(fh->rhp,!0); -} - - -static ssize_t pvr2_v4l2_read(struct file *file, - char __user *buff, size_t count, loff_t *ppos) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - int ret; - - if (fh->fw_mode_flag) { - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - char *tbuf; - int c1,c2; - int tcnt = 0; - unsigned int offs = *ppos; - - tbuf = kmalloc(PAGE_SIZE,GFP_KERNEL); - if (!tbuf) return -ENOMEM; - - while (count) { - c1 = count; - if (c1 > PAGE_SIZE) c1 = PAGE_SIZE; - c2 = pvr2_hdw_cpufw_get(hdw,offs,tbuf,c1); - if (c2 < 0) { - tcnt = c2; - break; - } - if (!c2) break; - if (copy_to_user(buff,tbuf,c2)) { - tcnt = -EFAULT; - break; - } - offs += c2; - tcnt += c2; - buff += c2; - count -= c2; - *ppos += c2; - } - kfree(tbuf); - return tcnt; - } - - if (!fh->rhp) { - ret = pvr2_v4l2_iosetup(fh); - if (ret) { - return ret; - } - } - - for (;;) { - ret = pvr2_ioread_read(fh->rhp,buff,count); - if (ret >= 0) break; - if (ret != -EAGAIN) break; - if (file->f_flags & O_NONBLOCK) break; - /* Doing blocking I/O. Wait here. */ - ret = wait_event_interruptible( - fh->wait_data, - pvr2_ioread_avail(fh->rhp) >= 0); - if (ret < 0) break; - } - - return ret; -} - - -static unsigned int pvr2_v4l2_poll(struct file *file, poll_table *wait) -{ - unsigned int mask = 0; - struct pvr2_v4l2_fh *fh = file->private_data; - int ret; - - if (fh->fw_mode_flag) { - mask |= POLLIN | POLLRDNORM; - return mask; - } - - if (!fh->rhp) { - ret = pvr2_v4l2_iosetup(fh); - if (ret) return POLLERR; - } - - poll_wait(file,&fh->wait_data,wait); - - if (pvr2_ioread_avail(fh->rhp) >= 0) { - mask |= POLLIN | POLLRDNORM; - } - - return mask; -} - - -static const struct v4l2_file_operations vdev_fops = { - .owner = THIS_MODULE, - .open = pvr2_v4l2_open, - .release = pvr2_v4l2_release, - .read = pvr2_v4l2_read, - .ioctl = pvr2_v4l2_ioctl, - .poll = pvr2_v4l2_poll, -}; - - -static struct video_device vdev_template = { - .fops = &vdev_fops, -}; - - -static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, - struct pvr2_v4l2 *vp, - int v4l_type) -{ - struct usb_device *usbdev; - int mindevnum; - int unit_number; - struct pvr2_hdw *hdw; - int *nr_ptr = NULL; - dip->v4lp = vp; - - hdw = vp->channel.mc_head->hdw; - usbdev = pvr2_hdw_get_dev(hdw); - dip->v4l_type = v4l_type; - switch (v4l_type) { - case VFL_TYPE_GRABBER: - dip->stream = &vp->channel.mc_head->video_stream; - dip->config = pvr2_config_mpeg; - dip->minor_type = pvr2_v4l_type_video; - nr_ptr = video_nr; - if (!dip->stream) { - pr_err(KBUILD_MODNAME - ": Failed to set up pvrusb2 v4l video dev" - " due to missing stream instance\n"); - return; - } - break; - case VFL_TYPE_VBI: - dip->config = pvr2_config_vbi; - dip->minor_type = pvr2_v4l_type_vbi; - nr_ptr = vbi_nr; - break; - case VFL_TYPE_RADIO: - dip->stream = &vp->channel.mc_head->video_stream; - dip->config = pvr2_config_mpeg; - dip->minor_type = pvr2_v4l_type_radio; - nr_ptr = radio_nr; - break; - default: - /* Bail out (this should be impossible) */ - pr_err(KBUILD_MODNAME ": Failed to set up pvrusb2 v4l dev" - " due to unrecognized config\n"); - return; - } - - memcpy(&dip->devbase,&vdev_template,sizeof(vdev_template)); - dip->devbase.release = pvr2_video_device_release; - dip->devbase.ioctl_ops = &pvr2_ioctl_ops; - { - int val; - pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw, - PVR2_CID_STDAVAIL), &val); - dip->devbase.tvnorms = (v4l2_std_id)val; - } - - mindevnum = -1; - unit_number = pvr2_hdw_get_unit_number(hdw); - if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) { - mindevnum = nr_ptr[unit_number]; - } - dip->devbase.parent = &usbdev->dev; - if ((video_register_device(&dip->devbase, - dip->v4l_type, mindevnum) < 0) && - (video_register_device(&dip->devbase, - dip->v4l_type, -1) < 0)) { - pr_err(KBUILD_MODNAME - ": Failed to register pvrusb2 v4l device\n"); - } - - printk(KERN_INFO "pvrusb2: registered device %s [%s]\n", - video_device_node_name(&dip->devbase), - pvr2_config_get_name(dip->config)); - - pvr2_hdw_v4l_store_minor_number(hdw, - dip->minor_type,dip->devbase.minor); -} - - -struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp) -{ - struct pvr2_v4l2 *vp; - - vp = kzalloc(sizeof(*vp),GFP_KERNEL); - if (!vp) return vp; - pvr2_channel_init(&vp->channel,mnp); - pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp); - - vp->channel.check_func = pvr2_v4l2_internal_check; - - /* register streams */ - vp->dev_video = kzalloc(sizeof(*vp->dev_video),GFP_KERNEL); - if (!vp->dev_video) goto fail; - pvr2_v4l2_dev_init(vp->dev_video,vp,VFL_TYPE_GRABBER); - if (pvr2_hdw_get_input_available(vp->channel.mc_head->hdw) & - (1 << PVR2_CVAL_INPUT_RADIO)) { - vp->dev_radio = kzalloc(sizeof(*vp->dev_radio),GFP_KERNEL); - if (!vp->dev_radio) goto fail; - pvr2_v4l2_dev_init(vp->dev_radio,vp,VFL_TYPE_RADIO); - } - - return vp; - fail: - pvr2_trace(PVR2_TRACE_STRUCT,"Failure creating pvr2_v4l2 id=%p",vp); - pvr2_v4l2_destroy_no_lock(vp); - return NULL; -} - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.h b/drivers/media/video/pvrusb2/pvrusb2-v4l2.h deleted file mode 100644 index 34c011a7b107..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ -#ifndef __PVRUSB2_V4L2_H -#define __PVRUSB2_V4L2_H - -#include "pvrusb2-context.h" - -struct pvr2_v4l2; - -struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *); - -#endif /* __PVRUSB2_V4L2_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c deleted file mode 100644 index 2e205c99eb96..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 source file is specifically designed to interface with the - saa711x support that is available in the v4l available starting - with linux 2.6.15. - -*/ - -#include "pvrusb2-video-v4l.h" - - - -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include <linux/videodev2.h> -#include <media/v4l2-common.h> -#include <media/saa7115.h> -#include <linux/errno.h> - -struct routing_scheme { - const int *def; - unsigned int cnt; -}; - - -static const int routing_scheme0[] = { - [PVR2_CVAL_INPUT_TV] = SAA7115_COMPOSITE4, - /* In radio mode, we mute the video, but point at one - spot just to stay consistent */ - [PVR2_CVAL_INPUT_RADIO] = SAA7115_COMPOSITE5, - [PVR2_CVAL_INPUT_COMPOSITE] = SAA7115_COMPOSITE5, - [PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2, -}; - -static const struct routing_scheme routing_def0 = { - .def = routing_scheme0, - .cnt = ARRAY_SIZE(routing_scheme0), -}; - -static const int routing_scheme1[] = { - [PVR2_CVAL_INPUT_TV] = SAA7115_COMPOSITE4, - [PVR2_CVAL_INPUT_RADIO] = SAA7115_COMPOSITE5, - [PVR2_CVAL_INPUT_COMPOSITE] = SAA7115_COMPOSITE3, - [PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2, /* or SVIDEO0, it seems */ -}; - -static const struct routing_scheme routing_def1 = { - .def = routing_scheme1, - .cnt = ARRAY_SIZE(routing_scheme1), -}; - -static const struct routing_scheme *routing_schemes[] = { - [PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0, - [PVR2_ROUTING_SCHEME_ONAIR] = &routing_def1, -}; - -void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) -{ - if (hdw->input_dirty || hdw->force_dirty) { - const struct routing_scheme *sp; - unsigned int sid = hdw->hdw_desc->signal_routing_scheme; - u32 input; - - pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)", - hdw->input_val); - - sp = (sid < ARRAY_SIZE(routing_schemes)) ? - routing_schemes[sid] : NULL; - if ((sp == NULL) || - (hdw->input_val < 0) || - (hdw->input_val >= sp->cnt)) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "*** WARNING *** subdev v4l2 set_input:" - " Invalid routing scheme (%u)" - " and/or input (%d)", - sid, hdw->input_val); - return; - } - input = sp->def[hdw->input_val]; - sd->ops->video->s_routing(sd, input, 0, 0); - } -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h deleted file mode 100644 index 3b0bd5db602b..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ - -#ifndef __PVRUSB2_VIDEO_V4L_H -#define __PVRUSB2_VIDEO_V4L_H - -/* - - This module connects the pvrusb2 driver to the I2C chip level - driver which handles device video processing. This interface is - used internally by the driver; higher level code should only - interact through the interface provided by pvrusb2-hdw.h. - -*/ - - -#include "pvrusb2-hdw-internal.h" -void pvr2_saa7115_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *); - -#endif /* __PVRUSB2_VIDEO_V4L_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c deleted file mode 100644 index 3ac8d751a5c0..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 source file is specifically designed to interface with the - wm8775. - -*/ - -#include "pvrusb2-wm8775.h" - - -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include <linux/videodev2.h> -#include <media/v4l2-common.h> -#include <linux/errno.h> - -void pvr2_wm8775_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) -{ - if (hdw->input_dirty || hdw->force_dirty) { - u32 input; - - switch (hdw->input_val) { - case PVR2_CVAL_INPUT_RADIO: - input = 1; - break; - default: - /* All other cases just use the second input */ - input = 2; - break; - } - pvr2_trace(PVR2_TRACE_CHIPS, "subdev wm8775" - " set_input(val=%d route=0x%x)", - hdw->input_val, input); - - sd->ops->audio->s_routing(sd, input, 0, 0); - } -} - - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.h b/drivers/media/video/pvrusb2/pvrusb2-wm8775.h deleted file mode 100644 index 0577bc7246fb..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ - -#ifndef __PVRUSB2_WM8775_H -#define __PVRUSB2_WM8775_H - -/* - - This module connects the pvrusb2 driver to the I2C chip level - driver which performs analog -> digital audio conversion for - external audio inputs. This interface is used internally by the - driver; higher level code should only interact through the - interface provided by pvrusb2-hdw.h. - -*/ - - - -#include "pvrusb2-hdw-internal.h" - -void pvr2_wm8775_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd); - - -#endif /* __PVRUSB2_WM8775_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/drivers/media/video/pvrusb2/pvrusb2.h b/drivers/media/video/pvrusb2/pvrusb2.h deleted file mode 100644 index 240de9b35661..000000000000 --- a/drivers/media/video/pvrusb2/pvrusb2.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely <isely@pobox.com> - * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * 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 - * - */ - -#ifndef __PVRUSB2_H -#define __PVRUSB2_H - -/* Maximum number of pvrusb2 instances we can track at once. You - might want to increase this - however the driver operation will not - be impaired if it is too small. Instead additional units just - won't have an ID assigned and it might not be possible to specify - module parameters for those extra units. */ -#define PVR_NUM 20 - -#endif /* __PVRUSB2_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ |