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-i2c-cmd-v4l2.o \
- pvrusb2-i2c-track.o \
- pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \
+pvrusb2-objs := pvrusb2-i2c-core.o \
+ pvrusb2-audio.o \
pvrusb2-encoder.o pvrusb2-video-v4l.o \
- pvrusb2-eeprom.o pvrusb2-tuner.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 \
},
};
-
-struct pvr2_msp3400_handler {
- struct pvr2_hdw *hdw;
- struct pvr2_i2c_client *client;
- struct pvr2_i2c_handler i2c_handler;
- unsigned long stale_mask;
-};
-
-
-
-
-/* This function selects the correct audio input source */
-static void set_stereo(struct pvr2_msp3400_handler *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- struct v4l2_routing route;
- const struct routing_scheme *sp;
- unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
-
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c msp3400 v4l2 set_stereo");
-
- if ((sid < ARRAY_SIZE(routing_schemes)) &&
- ((sp = routing_schemes + sid) != NULL) &&
- (hdw->input_val >= 0) &&
- (hdw->input_val < sp->cnt)) {
- route.input = sp->def[hdw->input_val];
- } else {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "*** WARNING *** i2c msp3400 v4l2 set_stereo:"
- " Invalid routing scheme (%u) and/or input (%d)",
- sid,hdw->input_val);
- return;
- }
- route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
-}
-
-
-static int check_stereo(struct pvr2_msp3400_handler *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- return hdw->input_dirty;
-}
-
-
-struct pvr2_msp3400_ops {
- void (*update)(struct pvr2_msp3400_handler *);
- int (*check)(struct pvr2_msp3400_handler *);
-};
-
-
-static const struct pvr2_msp3400_ops msp3400_ops[] = {
- { .update = set_stereo, .check = check_stereo},
-};
-
-
-static int msp3400_check(struct pvr2_msp3400_handler *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(msp3400_ops); idx++) {
- msk = 1 << idx;
- if (ctxt->stale_mask & msk) continue;
- if (msp3400_ops[idx].check(ctxt)) {
- ctxt->stale_mask |= msk;
- }
- }
- return ctxt->stale_mask != 0;
-}
-
-
-static void msp3400_update(struct pvr2_msp3400_handler *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(msp3400_ops); idx++) {
- msk = 1 << idx;
- if (!(ctxt->stale_mask & msk)) continue;
- ctxt->stale_mask &= ~msk;
- msp3400_ops[idx].update(ctxt);
- }
-}
-
-
-static void pvr2_msp3400_detach(struct pvr2_msp3400_handler *ctxt)
-{
- ctxt->client->handler = NULL;
- kfree(ctxt);
-}
-
-
-static unsigned int pvr2_msp3400_describe(struct pvr2_msp3400_handler *ctxt,
- char *buf,unsigned int cnt)
-{
- return scnprintf(buf,cnt,"handler: pvrusb2-audio v4l2");
-}
-
-
-static const struct pvr2_i2c_handler_functions msp3400_funcs = {
- .detach = (void (*)(void *))pvr2_msp3400_detach,
- .check = (int (*)(void *))msp3400_check,
- .update = (void (*)(void *))msp3400_update,
- .describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_msp3400_describe,
-};
-
-
-int pvr2_i2c_msp3400_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
-{
- struct pvr2_msp3400_handler *ctxt;
- if (cp->handler) return 0;
-
- ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
- if (!ctxt) return 0;
-
- ctxt->i2c_handler.func_data = ctxt;
- ctxt->i2c_handler.func_table = &msp3400_funcs;
- ctxt->client = cp;
- ctxt->hdw = hdw;
- ctxt->stale_mask = (1 << ARRAY_SIZE(msp3400_ops)) - 1;
- cp->handler = &ctxt->i2c_handler;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x msp3400 V4L2 handler set up",
- cp->client->addr);
- return !0;
-}
-
void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{
if (hdw->input_dirty || hdw->force_dirty) {
#ifndef __PVRUSB2_AUDIO_H
#define __PVRUSB2_AUDIO_H
-#include "pvrusb2-i2c-track.h"
-
-int pvr2_i2c_msp3400_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
-
#include "pvrusb2-hdw-internal.h"
void pvr2_msp3400_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *);
#endif /* __PVRUSB2_AUDIO_H */
#include "pvrusb2-cx2584x-v4l.h"
#include "pvrusb2-video-v4l.h"
-#include "pvrusb2-i2c-cmd-v4l2.h"
#include "pvrusb2-hdw-internal.h"
},
};
-struct pvr2_v4l_cx2584x {
- struct pvr2_i2c_handler handler;
- struct pvr2_decoder_ctrl ctrl;
- struct pvr2_i2c_client *client;
- struct pvr2_hdw *hdw;
- unsigned long stale_mask;
-};
-
-
-static void set_input(struct pvr2_v4l_cx2584x *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- struct v4l2_routing route;
- 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;
-
- memset(&route,0,sizeof(route));
-
- if ((sid < ARRAY_SIZE(routing_schemes)) &&
- ((sp = routing_schemes + sid) != NULL) &&
- (hdw->input_val >= 0) &&
- (hdw->input_val < sp->cnt)) {
- vid_input = sp->def[hdw->input_val].vid;
- aud_input = sp->def[hdw->input_val].aud;
- } else {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "*** WARNING *** i2c cx2584x set_input:"
- " Invalid routing scheme (%u) and/or input (%d)",
- sid,hdw->input_val);
- return;
- }
-
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_input vid=0x%x aud=0x%x",
- vid_input,aud_input);
- route.input = (u32)vid_input;
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route);
- route.input = (u32)aud_input;
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
-}
-
-
-static int check_input(struct pvr2_v4l_cx2584x *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- return hdw->input_dirty != 0;
-}
-
-
-static void set_audio(struct pvr2_v4l_cx2584x *ctxt)
-{
- u32 val;
- struct pvr2_hdw *hdw = ctxt->hdw;
-
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x 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;
- }
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val);
-}
-
-
-static int check_audio(struct pvr2_v4l_cx2584x *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- return hdw->srate_dirty != 0;
-}
-
-
-struct pvr2_v4l_cx2584x_ops {
- void (*update)(struct pvr2_v4l_cx2584x *);
- int (*check)(struct pvr2_v4l_cx2584x *);
-};
-
-
-static const struct pvr2_v4l_cx2584x_ops decoder_ops[] = {
- { .update = set_input, .check = check_input},
- { .update = set_audio, .check = check_audio},
-};
-
-
-static void decoder_detach(struct pvr2_v4l_cx2584x *ctxt)
-{
- ctxt->client->handler = NULL;
- pvr2_hdw_set_decoder(ctxt->hdw,NULL);
- kfree(ctxt);
-}
-
-
-static int decoder_check(struct pvr2_v4l_cx2584x *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
- msk = 1 << idx;
- if (ctxt->stale_mask & msk) continue;
- if (decoder_ops[idx].check(ctxt)) {
- ctxt->stale_mask |= msk;
- }
- }
- return ctxt->stale_mask != 0;
-}
-
-
-static void decoder_update(struct pvr2_v4l_cx2584x *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
- msk = 1 << idx;
- if (!(ctxt->stale_mask & msk)) continue;
- ctxt->stale_mask &= ~msk;
- decoder_ops[idx].update(ctxt);
- }
-}
-
-
-static void decoder_enable(struct pvr2_v4l_cx2584x *ctxt,int fl)
-{
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_enable(%d)",fl);
- pvr2_v4l2_cmd_stream(ctxt->client,fl);
-}
-
-
-static int decoder_detect(struct pvr2_i2c_client *cp)
-{
- int ret;
- /* Attempt to query the decoder - let's see if it will answer */
- struct v4l2_queryctrl qc;
-
- memset(&qc,0,sizeof(qc));
-
- qc.id = V4L2_CID_BRIGHTNESS;
-
- ret = pvr2_i2c_client_cmd(cp,VIDIOC_QUERYCTRL,&qc);
- return ret == 0; /* Return true if it answered */
-}
-
-
-static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt,
- char *buf,unsigned int cnt)
-{
- return scnprintf(buf,cnt,"handler: pvrusb2-cx2584x-v4l");
-}
-
-
-static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt)
-{
- int ret;
- ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,NULL);
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret);
-}
-
-
-static const struct pvr2_i2c_handler_functions hfuncs = {
- .detach = (void (*)(void *))decoder_detach,
- .check = (int (*)(void *))decoder_check,
- .update = (void (*)(void *))decoder_update,
- .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe,
-};
-
-
-int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *hdw,
- struct pvr2_i2c_client *cp)
-{
- struct pvr2_v4l_cx2584x *ctxt;
-
- if (hdw->decoder_ctrl) return 0;
- if (cp->handler) return 0;
- if (!decoder_detect(cp)) return 0;
-
- ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
- if (!ctxt) return 0;
-
- ctxt->handler.func_data = ctxt;
- ctxt->handler.func_table = &hfuncs;
- ctxt->ctrl.ctxt = ctxt;
- ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
- ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
- ctxt->ctrl.force_reset = (void (*)(void*))decoder_reset;
- ctxt->client = cp;
- ctxt->hdw = hdw;
- ctxt->stale_mask = (1 << ARRAY_SIZE(decoder_ops)) - 1;
- pvr2_hdw_set_decoder(hdw,&ctxt->ctrl);
- cp->handler = &ctxt->handler;
- {
- /*
- 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;
- memset(&fmt,0,sizeof(fmt));
- fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_FMT,&fmt);
- }
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x cx2584x V4L2 handler set up",
- cp->client->addr);
- return !0;
-}
-
-
void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{
pvr2_trace(PVR2_TRACE_CHIPS, "subdev cx2584x update...");
-#include "pvrusb2-i2c-track.h"
-
-int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
-
-
#include "pvrusb2-hdw-internal.h"
void pvr2_cx25840_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd);
#include "pvrusb2-debugifc.h"
#include "pvrusb2-hdw.h"
#include "pvrusb2-debug.h"
-#include "pvrusb2-i2c-track.h"
struct debugifc_mask_item {
const char *name;
bcnt += ccnt; acnt -= ccnt; buf += ccnt;
ccnt = pvr2_hdw_state_report(hdw,buf,acnt);
bcnt += ccnt; acnt -= ccnt; buf += ccnt;
- ccnt = scnprintf(buf, acnt, "Attached old-style I2C modules:\n");
- bcnt += ccnt; acnt -= ccnt; buf += ccnt;
- ccnt = pvr2_i2c_report(hdw,buf,acnt);
- bcnt += ccnt; acnt -= ccnt; buf += ccnt;
return bcnt;
}
};
-struct pvr2_decoder_ctrl {
- void *ctxt;
- void (*detach)(void *);
- void (*enable)(void *,int);
- void (*force_reset)(void *);
-};
-
-#define PVR2_I2C_PEND_DETECT 0x01 /* Need to detect a client type */
-#define PVR2_I2C_PEND_CLIENT 0x02 /* Client needs a specific update */
-#define PVR2_I2C_PEND_REFRESH 0x04 /* Client has specific pending bits */
-#define PVR2_I2C_PEND_STALE 0x08 /* Broadcast pending bits */
-
-#define PVR2_I2C_PEND_ALL (PVR2_I2C_PEND_DETECT |\
- PVR2_I2C_PEND_CLIENT |\
- PVR2_I2C_PEND_REFRESH |\
- PVR2_I2C_PEND_STALE)
/* Disposition of firmware1 loading situation */
#define FW1_STATE_UNKNOWN 0
/* Kernel worker thread handling */
struct workqueue_struct *workqueue;
struct work_struct workpoll; /* Update driver state */
- struct work_struct worki2csync; /* Update i2c clients */
/* Video spigot */
struct pvr2_stream *vid_stream;
pvr2_i2c_func i2c_func[PVR2_I2C_FUNC_CNT];
int i2c_cx25840_hack_state;
int i2c_linked;
- unsigned int i2c_pend_types; /* Which types of update are needed */
- unsigned long i2c_pend_mask; /* Change bits we need to scan */
- unsigned long i2c_stale_mask; /* Pending broadcast change bits */
- unsigned long i2c_active_mask; /* All change bits currently in use */
- struct list_head i2c_clients;
- struct mutex i2c_list_lock;
/* Frequency table */
unsigned int freqTable[FREQTABLE_SIZE];
int flag_decoder_missed;/* We've noticed missing decoder */
int flag_tripped; /* Indicates overall failure to start */
- struct pvr2_decoder_ctrl *decoder_ctrl;
unsigned int decoder_client_id;
// CPU firmware info (used to help find / save firmware data)
unsigned int fw_size;
int fw_cpu_flag; /* True if we are dealing with the CPU */
- // True if there is a request to trigger logging of state in each
- // module.
- int log_requested;
-
/* Tuner / frequency control stuff */
unsigned int tuner_type;
int tuner_updated;
/* This function gets the current frequency */
unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *);
-void pvr2_hdw_set_decoder(struct pvr2_hdw *,struct pvr2_decoder_ctrl *);
void pvr2_hdw_status_poll(struct pvr2_hdw *);
#include "pvrusb2-util.h"
#include "pvrusb2-hdw.h"
#include "pvrusb2-i2c-core.h"
-#include "pvrusb2-i2c-track.h"
-#include "pvrusb2-tuner.h"
#include "pvrusb2-eeprom.h"
#include "pvrusb2-hdw-internal.h"
#include "pvrusb2-encoder.h"
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_i2c(struct work_struct *work);
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 int pvr2_decoder_enable(struct pvr2_hdw *hdw,int enablefl)
{
- if (hdw->decoder_ctrl) {
- hdw->decoder_ctrl->enable(hdw->decoder_ctrl->ctxt, enablefl);
- return 0;
- }
/* 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
}
-void pvr2_hdw_set_decoder(struct pvr2_hdw *hdw,struct pvr2_decoder_ctrl *ptr)
-{
- if (hdw->decoder_ctrl == ptr) return;
- hdw->decoder_ctrl = ptr;
- if (hdw->decoder_ctrl && hdw->flag_decoder_missed) {
- hdw->flag_decoder_missed = 0;
- trace_stbit("flag_decoder_missed",
- hdw->flag_decoder_missed);
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Decoder has appeared");
- pvr2_hdw_state_sched(hdw);
- }
-}
-
-
int pvr2_hdw_get_state(struct pvr2_hdw *hdw)
{
return hdw->master_state;
* and every other place where I can find examples of this, the
* "chipid" appears to just be the module name again. So here we
* just do the same thing. */
- hdw->i2c_adap.class = 0;
if (i2ccnt == 1) {
pvr2_trace(PVR2_TRACE_INIT,
"Module ID %u:"
fname, fname,
i2caddr);
}
- hdw->i2c_adap.class = I2C_CLASS_TV_ANALOG;
if (!sd) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
requires special handling. */
sd->grp_id = mid;
- /* If we have both old and new i2c layers enabled, make sure that
- old layer isn't also tracking this module. This is a debugging
- aid, in normal situations there's no reason for both mechanisms
- to be enabled. */
- pvr2_i2c_untrack_subdev(hdw, sd);
pvr2_trace(PVR2_TRACE_INFO, "Attached sub-driver %s", fname);
}
// This step MUST happen after the earlier powerup step.
- pvr2_i2c_track_init(hdw);
pvr2_i2c_core_init(hdw);
if (!pvr2_hdw_dev_ok(hdw)) return;
hdw->tuner_type);
}
- pvr2_i2c_core_check_stale(hdw);
if (!pvr2_hdw_dev_ok(hdw)) return;
hdw->workqueue = create_singlethread_workqueue(hdw->name);
INIT_WORK(&hdw->workpoll,pvr2_hdw_worker_poll);
- INIT_WORK(&hdw->worki2csync,pvr2_hdw_worker_i2c);
pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s",
hdw->unit_number,hdw->name);
pvr2_stream_destroy(hdw->vid_stream);
hdw->vid_stream = NULL;
}
- if (hdw->decoder_ctrl) {
- hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt);
- }
pvr2_i2c_core_done(hdw);
- pvr2_i2c_track_done(hdw);
v4l2_device_unregister(&hdw->v4l2_dev);
pvr2_hdw_remove_usb_stuff(hdw);
mutex_lock(&pvr2_unit_mtx); do {
cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs,VIDIOC_S_EXT_CTRLS);
}
- /* Scan i2c core at this point - before we clear all the dirty
- bits. Various parts of the i2c core will notice dirty bits as
- appropriate and arrange to broadcast or directly send updates to
- the client drivers in order to keep everything in sync */
- pvr2_i2c_core_check_stale(hdw);
-
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;
cptr->info->clear_dirty(cptr);
}
- /* Now execute i2c core update */
- pvr2_i2c_core_sync(hdw);
-
if ((hdw->pathway_state == PVR2_PATHWAY_ANALOG) &&
hdw->state_encoder_run) {
/* If encoder isn't running or it can't be touched, then
}
-static void pvr2_hdw_worker_i2c(struct work_struct *work)
-{
- struct pvr2_hdw *hdw = container_of(work,struct pvr2_hdw,worki2csync);
- LOCK_TAKE(hdw->big_lock); do {
- pvr2_i2c_core_sync(hdw);
- } while (0); LOCK_GIVE(hdw->big_lock);
-}
-
-
static void pvr2_hdw_worker_poll(struct work_struct *work)
{
int fl = 0;
int nr = pvr2_hdw_get_unit_number(hdw);
LOCK_TAKE(hdw->big_lock); do {
printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
- hdw->log_requested = !0;
- pvr2_i2c_core_check_stale(hdw);
- pvr2_i2c_core_sync(hdw);
- hdw->log_requested = 0;
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_trace(PVR2_TRACE_INIT,
"Requesting decoder reset");
- if (hdw->decoder_ctrl) {
- if (!hdw->decoder_ctrl->force_reset) {
- pvr2_trace(PVR2_TRACE_INIT,
- "Unable to reset decoder: not implemented");
- return -ENOTTY;
- }
- hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt);
- return 0;
- } else {
- }
if (hdw->decoder_client_id) {
v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id,
core, reset, 0);
struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
memset(vtp, 0, sizeof(*vtp));
hdw->tuner_signal_stale = 0;
- pvr2_i2c_core_status_poll(hdw);
/* 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.
int setFl, u64 *val_ptr)
{
#ifdef CONFIG_VIDEO_ADV_DEBUG
- struct pvr2_i2c_client *cp;
struct v4l2_dbg_register req;
int stat = 0;
int okFl = 0;
/* 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) mutex_lock(&hdw->i2c_list_lock); do {
- list_for_each_entry(cp, &hdw->i2c_clients, list) {
- if (!v4l2_chip_match_i2c_client(
- cp->client,
- &req.match)) {
- continue;
- }
- stat = pvr2_i2c_client_cmd(
- cp,(setFl ? VIDIOC_DBG_S_REGISTER :
- VIDIOC_DBG_G_REGISTER),&req);
- if (!setFl) *val_ptr = req.val;
- okFl = !0;
- break;
- }
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
if (okFl) {
return stat;
}
+++ /dev/null
-/*
- *
- *
- * 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/kernel.h>
-#include "pvrusb2-i2c-track.h"
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-#include "pvrusb2-i2c-cmd-v4l2.h"
-#include "pvrusb2-audio.h"
-#include "pvrusb2-tuner.h"
-#include "pvrusb2-video-v4l.h"
-#include "pvrusb2-cx2584x-v4l.h"
-#include "pvrusb2-wm8775.h"
-
-
-#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
-
-#define OP_INIT 0 /* MUST come first so it is run first */
-#define OP_STANDARD 1
-#define OP_AUDIOMODE 2
-#define OP_BCSH 3
-#define OP_VOLUME 4
-#define OP_FREQ 5
-#define OP_AUDIORATE 6
-#define OP_CROP 7
-#define OP_SIZE 8
-#define OP_LOG 9
-
-static const struct pvr2_i2c_op * const ops[] = {
- [OP_INIT] = &pvr2_i2c_op_v4l2_init,
- [OP_STANDARD] = &pvr2_i2c_op_v4l2_standard,
- [OP_AUDIOMODE] = &pvr2_i2c_op_v4l2_audiomode,
- [OP_BCSH] = &pvr2_i2c_op_v4l2_bcsh,
- [OP_VOLUME] = &pvr2_i2c_op_v4l2_volume,
- [OP_FREQ] = &pvr2_i2c_op_v4l2_frequency,
- [OP_CROP] = &pvr2_i2c_op_v4l2_crop,
- [OP_SIZE] = &pvr2_i2c_op_v4l2_size,
- [OP_LOG] = &pvr2_i2c_op_v4l2_log,
-};
-
-void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
-{
- int id;
- id = cp->client->driver->id;
- cp->ctl_mask = ((1 << OP_INIT) |
- (1 << OP_STANDARD) |
- (1 << OP_AUDIOMODE) |
- (1 << OP_BCSH) |
- (1 << OP_VOLUME) |
- (1 << OP_FREQ) |
- (1 << OP_CROP) |
- (1 << OP_SIZE) |
- (1 << OP_LOG));
- cp->status_poll = pvr2_v4l2_cmd_status_poll;
-
- if (id == I2C_DRIVERID_MSP3400) {
- if (pvr2_i2c_msp3400_setup(hdw,cp)) {
- return;
- }
- }
- if (id == I2C_DRIVERID_TUNER) {
- if (pvr2_i2c_tuner_setup(hdw,cp)) {
- return;
- }
- }
- if (id == I2C_DRIVERID_CX25840) {
- if (pvr2_i2c_cx2584x_v4l_setup(hdw,cp)) {
- return;
- }
- }
- if (id == I2C_DRIVERID_WM8775) {
- if (pvr2_i2c_wm8775_setup(hdw,cp)) {
- return;
- }
- }
- if (id == I2C_DRIVERID_SAA711X) {
- if (pvr2_i2c_decoder_v4l_setup(hdw,cp)) {
- return;
- }
- }
-}
-
-
-const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx)
-{
- if (idx >= ARRAY_SIZE(ops))
- return NULL;
- return ops[idx];
-}
-
-
-
-/*
- 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: ***
- */
+++ /dev/null
-/*
- *
- *
- * 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-i2c-cmd-v4l2.h"
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-
-
-static void execute_init(struct pvr2_hdw *hdw)
-{
- u32 dummy = 0;
- pvr2_trace(PVR2_TRACE_CHIPS, "i2c v4l2 init");
- pvr2_i2c_core_cmd(hdw, VIDIOC_INT_INIT, &dummy);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_init = {
- .update = execute_init,
- .name = "v4l2_init",
-};
-
-
-static void set_standard(struct pvr2_hdw *hdw)
-{
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_standard");
-
- if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
- pvr2_i2c_core_cmd(hdw,AUDC_SET_RADIO,NULL);
- } else {
- v4l2_std_id vs;
- vs = hdw->std_mask_cur;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs);
- }
- hdw->tuner_signal_stale = !0;
- hdw->cropcap_stale = !0;
-}
-
-
-static int check_standard(struct pvr2_hdw *hdw)
-{
- return (hdw->input_dirty != 0) || (hdw->std_dirty != 0);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard = {
- .check = check_standard,
- .update = set_standard,
- .name = "v4l2_standard",
-};
-
-
-static void set_bcsh(struct pvr2_hdw *hdw)
-{
- struct v4l2_control ctrl;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_bcsh"
- " b=%d c=%d s=%d h=%d",
- hdw->brightness_val,hdw->contrast_val,
- hdw->saturation_val,hdw->hue_val);
- memset(&ctrl,0,sizeof(ctrl));
- ctrl.id = V4L2_CID_BRIGHTNESS;
- ctrl.value = hdw->brightness_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_CONTRAST;
- ctrl.value = hdw->contrast_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_SATURATION;
- ctrl.value = hdw->saturation_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_HUE;
- ctrl.value = hdw->hue_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
-}
-
-
-static int check_bcsh(struct pvr2_hdw *hdw)
-{
- return (hdw->brightness_dirty ||
- hdw->contrast_dirty ||
- hdw->saturation_dirty ||
- hdw->hue_dirty);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh = {
- .check = check_bcsh,
- .update = set_bcsh,
- .name = "v4l2_bcsh",
-};
-
-
-static void set_volume(struct pvr2_hdw *hdw)
-{
- struct v4l2_control ctrl;
- pvr2_trace(PVR2_TRACE_CHIPS,
- "i2c v4l2 set_volume"
- "(vol=%d bal=%d bas=%d treb=%d mute=%d)",
- hdw->volume_val,
- hdw->balance_val,
- hdw->bass_val,
- hdw->treble_val,
- hdw->mute_val);
- memset(&ctrl,0,sizeof(ctrl));
- ctrl.id = V4L2_CID_AUDIO_MUTE;
- ctrl.value = hdw->mute_val ? 1 : 0;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_AUDIO_VOLUME;
- ctrl.value = hdw->volume_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_AUDIO_BALANCE;
- ctrl.value = hdw->balance_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_AUDIO_BASS;
- ctrl.value = hdw->bass_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_AUDIO_TREBLE;
- ctrl.value = hdw->treble_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
-}
-
-
-static int check_volume(struct pvr2_hdw *hdw)
-{
- return (hdw->volume_dirty ||
- hdw->balance_dirty ||
- hdw->bass_dirty ||
- hdw->treble_dirty ||
- hdw->mute_dirty);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume = {
- .check = check_volume,
- .update = set_volume,
- .name = "v4l2_volume",
-};
-
-
-static void set_audiomode(struct pvr2_hdw *hdw)
-{
- struct v4l2_tuner vt;
- memset(&vt,0,sizeof(vt));
- vt.audmode = hdw->audiomode_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_TUNER,&vt);
-}
-
-
-static int check_audiomode(struct pvr2_hdw *hdw)
-{
- return (hdw->input_dirty ||
- hdw->audiomode_dirty);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_audiomode = {
- .check = check_audiomode,
- .update = set_audiomode,
- .name = "v4l2_audiomode",
-};
-
-
-static void set_frequency(struct pvr2_hdw *hdw)
-{
- unsigned long fv;
- struct v4l2_frequency freq;
- fv = pvr2_hdw_get_cur_freq(hdw);
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c 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;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_FREQUENCY,&freq);
-}
-
-
-static int check_frequency(struct pvr2_hdw *hdw)
-{
- return hdw->freqDirty != 0;
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency = {
- .check = check_frequency,
- .update = set_frequency,
- .name = "v4l2_freq",
-};
-
-
-static void set_size(struct pvr2_hdw *hdw)
-{
- struct v4l2_format fmt;
-
- memset(&fmt,0,sizeof(fmt));
-
- fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- fmt.fmt.pix.width = hdw->res_hor_val;
- fmt.fmt.pix.height = hdw->res_ver_val;
-
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_size(%dx%d)",
- fmt.fmt.pix.width,fmt.fmt.pix.height);
-
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_FMT,&fmt);
-}
-
-
-static int check_size(struct pvr2_hdw *hdw)
-{
- return (hdw->res_hor_dirty || hdw->res_ver_dirty);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size = {
- .check = check_size,
- .update = set_size,
- .name = "v4l2_size",
-};
-
-
-static void set_crop(struct pvr2_hdw *hdw)
-{
- struct v4l2_crop crop;
-
- memset(&crop, 0, sizeof crop);
- crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- crop.c.left = hdw->cropl_val;
- crop.c.top = hdw->cropt_val;
- crop.c.height = hdw->croph_val;
- crop.c.width = hdw->cropw_val;
-
- pvr2_trace(PVR2_TRACE_CHIPS,
- "i2c v4l2 set_crop crop=%d:%d:%d:%d",
- crop.c.width, crop.c.height, crop.c.left, crop.c.top);
-
- pvr2_i2c_core_cmd(hdw, VIDIOC_S_CROP, &crop);
-}
-
-static int check_crop(struct pvr2_hdw *hdw)
-{
- return (hdw->cropl_dirty || hdw->cropt_dirty ||
- hdw->cropw_dirty || hdw->croph_dirty);
-}
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_crop = {
- .check = check_crop,
- .update = set_crop,
- .name = "v4l2_crop",
-};
-
-
-static void do_log(struct pvr2_hdw *hdw)
-{
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 do_log()");
- pvr2_i2c_core_cmd(hdw,VIDIOC_LOG_STATUS,NULL);
-
-}
-
-
-static int check_log(struct pvr2_hdw *hdw)
-{
- return hdw->log_requested != 0;
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log = {
- .check = check_log,
- .update = do_log,
- .name = "v4l2_log",
-};
-
-
-void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *cp,int fl)
-{
- pvr2_i2c_client_cmd(cp,
- (fl ? VIDIOC_STREAMON : VIDIOC_STREAMOFF),NULL);
-}
-
-
-void pvr2_v4l2_cmd_status_poll(struct pvr2_i2c_client *cp)
-{
- int stat;
- struct pvr2_hdw *hdw = cp->hdw;
- if (hdw->cropcap_stale) {
- hdw->cropcap_info.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- stat = pvr2_i2c_client_cmd(cp, VIDIOC_CROPCAP,
- &hdw->cropcap_info);
- if (stat == 0) {
- /* Check was successful, so the data is no
- longer considered stale. */
- hdw->cropcap_stale = 0;
- }
- }
- pvr2_i2c_client_cmd(cp, VIDIOC_G_TUNER, &hdw->tuner_signal_info);
-}
-
-
-
-/*
- 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: ***
- */
+++ /dev/null
-/*
- *
- *
- * 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_CMD_V4L2_H
-#define __PVRUSB2_CMD_V4L2_H
-
-#include "pvrusb2-i2c-track.h"
-
-
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_init;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_radio;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_crop;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_audiomode;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log;
-
-void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *,int);
-void pvr2_v4l2_cmd_status_poll(struct pvr2_i2c_client *);
-
-
-#endif /* __PVRUSB2_CMD_V4L2_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: ***
- */
#include <linux/i2c.h>
#include "pvrusb2-i2c-core.h"
-#include "pvrusb2-i2c-track.h"
#include "pvrusb2-hdw-internal.h"
#include "pvrusb2-debug.h"
#include "pvrusb2-fx2-cmd.h"
static int pvr2_i2c_attach_inform(struct i2c_client *client)
{
- pvr2_i2c_track_attach_inform(client);
return 0;
}
static int pvr2_i2c_detach_inform(struct i2c_client *client)
{
- pvr2_i2c_track_detach_inform(client);
return 0;
}
hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev;
hdw->i2c_adap.algo = &hdw->i2c_algo;
hdw->i2c_adap.algo_data = hdw;
- hdw->i2c_adap.class = I2C_CLASS_TV_ANALOG;
hdw->i2c_linked = !0;
i2c_set_adapdata(&hdw->i2c_adap, &hdw->v4l2_dev);
i2c_add_adapter(&hdw->i2c_adap);
+++ /dev/null
-/*
- *
- *
- * 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-i2c-track.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 implements the foundation of a rather large architecture for
- tracking state in all the various V4L I2C modules. This is obsolete with
- kernels later than roughly 2.6.24, but it is still present in the
- standalone pvrusb2 driver to allow continued operation with older
- kernel.
-
-*/
-
-static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp,
- unsigned int detail,
- char *buf,unsigned int maxlen);
-
-static int pvr2_i2c_core_singleton(struct i2c_client *cp,
- unsigned int cmd,void *arg)
-{
- int stat;
- if (!cp) return -EINVAL;
- if (!(cp->driver)) return -EINVAL;
- if (!(cp->driver->command)) return -EINVAL;
- if (!try_module_get(cp->driver->driver.owner)) return -EAGAIN;
- stat = cp->driver->command(cp,cmd,arg);
- module_put(cp->driver->driver.owner);
- return stat;
-}
-
-int pvr2_i2c_client_cmd(struct pvr2_i2c_client *cp,unsigned int cmd,void *arg)
-{
- int stat;
- if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) {
- char buf[100];
- unsigned int cnt;
- cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG,
- buf,sizeof(buf));
- pvr2_trace(PVR2_TRACE_I2C_CMD,
- "i2c COMMAND (code=%u 0x%x) to %.*s",
- cmd,cmd,cnt,buf);
- }
- stat = pvr2_i2c_core_singleton(cp->client,cmd,arg);
- if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) {
- char buf[100];
- unsigned int cnt;
- cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG,
- buf,sizeof(buf));
- pvr2_trace(PVR2_TRACE_I2C_CMD,
- "i2c COMMAND to %.*s (ret=%d)",cnt,buf,stat);
- }
- return stat;
-}
-
-int pvr2_i2c_core_cmd(struct pvr2_hdw *hdw,unsigned int cmd,void *arg)
-{
- struct pvr2_i2c_client *cp, *ncp;
- int stat = -EINVAL;
-
- if (!hdw) return stat;
-
- mutex_lock(&hdw->i2c_list_lock);
- list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) {
- if (!cp->recv_enable) continue;
- mutex_unlock(&hdw->i2c_list_lock);
- stat = pvr2_i2c_client_cmd(cp,cmd,arg);
- mutex_lock(&hdw->i2c_list_lock);
- }
- mutex_unlock(&hdw->i2c_list_lock);
- return stat;
-}
-
-
-static int handler_check(struct pvr2_i2c_client *cp)
-{
- struct pvr2_i2c_handler *hp = cp->handler;
- if (!hp) return 0;
- if (!hp->func_table->check) return 0;
- return hp->func_table->check(hp->func_data) != 0;
-}
-
-#define BUFSIZE 500
-
-
-void pvr2_i2c_core_status_poll(struct pvr2_hdw *hdw)
-{
- struct pvr2_i2c_client *cp;
- mutex_lock(&hdw->i2c_list_lock); do {
- list_for_each_entry(cp, &hdw->i2c_clients, list) {
- if (!cp->detected_flag) continue;
- if (!cp->status_poll) continue;
- cp->status_poll(cp);
- }
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
-}
-
-
-/* Issue various I2C operations to bring chip-level drivers into sync with
- state stored in this driver. */
-void pvr2_i2c_core_sync(struct pvr2_hdw *hdw)
-{
- unsigned long msk;
- unsigned int idx;
- struct pvr2_i2c_client *cp, *ncp;
-
- if (!hdw->i2c_linked) return;
- if (!(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL)) {
- return;
- }
- mutex_lock(&hdw->i2c_list_lock); do {
- pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync BEGIN");
- if (hdw->i2c_pend_types & PVR2_I2C_PEND_DETECT) {
- /* One or more I2C clients have attached since we
- last synced. So scan the list and identify the
- new clients. */
- char *buf;
- unsigned int cnt;
- unsigned long amask = 0;
- buf = kmalloc(BUFSIZE,GFP_KERNEL);
- pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_DETECT");
- hdw->i2c_pend_types &= ~PVR2_I2C_PEND_DETECT;
- list_for_each_entry(cp, &hdw->i2c_clients, list) {
- if (!cp->detected_flag) {
- cp->ctl_mask = 0;
- pvr2_i2c_probe(hdw,cp);
- cp->detected_flag = !0;
- msk = cp->ctl_mask;
- cnt = 0;
- if (buf) {
- cnt = pvr2_i2c_client_describe(
- cp,
- PVR2_I2C_DETAIL_ALL,
- buf,BUFSIZE);
- }
- trace_i2c("Probed: %.*s",cnt,buf);
- if (handler_check(cp)) {
- hdw->i2c_pend_types |=
- PVR2_I2C_PEND_CLIENT;
- }
- cp->pend_mask = msk;
- hdw->i2c_pend_mask |= msk;
- hdw->i2c_pend_types |=
- PVR2_I2C_PEND_REFRESH;
- }
- amask |= cp->ctl_mask;
- }
- hdw->i2c_active_mask = amask;
- if (buf) kfree(buf);
- }
- if (hdw->i2c_pend_types & PVR2_I2C_PEND_STALE) {
- /* Need to do one or more global updates. Arrange
- for this to happen. */
- unsigned long m2;
- pvr2_trace(PVR2_TRACE_I2C_CORE,
- "i2c: PEND_STALE (0x%lx)",
- hdw->i2c_stale_mask);
- hdw->i2c_pend_types &= ~PVR2_I2C_PEND_STALE;
- list_for_each_entry(cp, &hdw->i2c_clients, list) {
- m2 = hdw->i2c_stale_mask;
- m2 &= cp->ctl_mask;
- m2 &= ~cp->pend_mask;
- if (m2) {
- pvr2_trace(PVR2_TRACE_I2C_CORE,
- "i2c: cp=%p setting 0x%lx",
- cp,m2);
- cp->pend_mask |= m2;
- }
- }
- hdw->i2c_pend_mask |= hdw->i2c_stale_mask;
- hdw->i2c_stale_mask = 0;
- hdw->i2c_pend_types |= PVR2_I2C_PEND_REFRESH;
- }
- if (hdw->i2c_pend_types & PVR2_I2C_PEND_CLIENT) {
- /* One or more client handlers are asking for an
- update. Run through the list of known clients
- and update each one. */
- pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_CLIENT");
- hdw->i2c_pend_types &= ~PVR2_I2C_PEND_CLIENT;
- list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients,
- list) {
- if (!cp->handler) continue;
- if (!cp->handler->func_table->update) continue;
- pvr2_trace(PVR2_TRACE_I2C_CORE,
- "i2c: cp=%p update",cp);
- mutex_unlock(&hdw->i2c_list_lock);
- cp->handler->func_table->update(
- cp->handler->func_data);
- mutex_lock(&hdw->i2c_list_lock);
- /* If client's update function set some
- additional pending bits, account for that
- here. */
- if (cp->pend_mask & ~hdw->i2c_pend_mask) {
- hdw->i2c_pend_mask |= cp->pend_mask;
- hdw->i2c_pend_types |=
- PVR2_I2C_PEND_REFRESH;
- }
- }
- }
- if (hdw->i2c_pend_types & PVR2_I2C_PEND_REFRESH) {
- const struct pvr2_i2c_op *opf;
- unsigned long pm;
- /* Some actual updates are pending. Walk through
- each update type and perform it. */
- pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_REFRESH"
- " (0x%lx)",hdw->i2c_pend_mask);
- hdw->i2c_pend_types &= ~PVR2_I2C_PEND_REFRESH;
- pm = hdw->i2c_pend_mask;
- hdw->i2c_pend_mask = 0;
- for (idx = 0, msk = 1; pm; idx++, msk <<= 1) {
- if (!(pm & msk)) continue;
- pm &= ~msk;
- list_for_each_entry(cp, &hdw->i2c_clients,
- list) {
- if (cp->pend_mask & msk) {
- cp->pend_mask &= ~msk;
- cp->recv_enable = !0;
- } else {
- cp->recv_enable = 0;
- }
- }
- opf = pvr2_i2c_get_op(idx);
- if (!opf) continue;
- mutex_unlock(&hdw->i2c_list_lock);
- opf->update(hdw);
- mutex_lock(&hdw->i2c_list_lock);
- }
- }
- pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync END");
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
-}
-
-int pvr2_i2c_core_check_stale(struct pvr2_hdw *hdw)
-{
- unsigned long msk,sm,pm;
- unsigned int idx;
- const struct pvr2_i2c_op *opf;
- struct pvr2_i2c_client *cp;
- unsigned int pt = 0;
-
- pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale BEGIN");
-
- pm = hdw->i2c_active_mask;
- sm = 0;
- for (idx = 0, msk = 1; pm; idx++, msk <<= 1) {
- if (!(msk & pm)) continue;
- pm &= ~msk;
- opf = pvr2_i2c_get_op(idx);
- if (!(opf && opf->check)) continue;
- if (opf->check(hdw)) {
- sm |= msk;
- }
- }
- if (sm) pt |= PVR2_I2C_PEND_STALE;
-
- list_for_each_entry(cp, &hdw->i2c_clients, list)
- if (handler_check(cp))
- pt |= PVR2_I2C_PEND_CLIENT;
-
- if (pt) {
- mutex_lock(&hdw->i2c_list_lock); do {
- hdw->i2c_pend_types |= pt;
- hdw->i2c_stale_mask |= sm;
- hdw->i2c_pend_mask |= hdw->i2c_stale_mask;
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
- }
-
- pvr2_trace(PVR2_TRACE_I2C_CORE,
- "i2c: types=0x%x stale=0x%lx pend=0x%lx",
- hdw->i2c_pend_types,
- hdw->i2c_stale_mask,
- hdw->i2c_pend_mask);
- pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale END");
-
- return (hdw->i2c_pend_types & PVR2_I2C_PEND_ALL) != 0;
-}
-
-static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp,
- unsigned int detail,
- char *buf,unsigned int maxlen)
-{
- unsigned int ccnt,bcnt;
- int spcfl = 0;
- const struct pvr2_i2c_op *opf;
-
- ccnt = 0;
- if (detail & PVR2_I2C_DETAIL_DEBUG) {
- bcnt = scnprintf(buf,maxlen,
- "ctxt=%p ctl_mask=0x%lx",
- cp,cp->ctl_mask);
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- spcfl = !0;
- }
- bcnt = scnprintf(buf,maxlen,
- "%s%s @ 0x%x",
- (spcfl ? " " : ""),
- cp->client->name,
- cp->client->addr);
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- if ((detail & PVR2_I2C_DETAIL_HANDLER) &&
- cp->handler && cp->handler->func_table->describe) {
- bcnt = scnprintf(buf,maxlen," (");
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- bcnt = cp->handler->func_table->describe(
- cp->handler->func_data,buf,maxlen);
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- bcnt = scnprintf(buf,maxlen,")");
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- }
- if ((detail & PVR2_I2C_DETAIL_CTLMASK) && cp->ctl_mask) {
- unsigned int idx;
- unsigned long msk,sm;
-
- bcnt = scnprintf(buf,maxlen," [");
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- sm = 0;
- spcfl = 0;
- for (idx = 0, msk = 1; msk; idx++, msk <<= 1) {
- if (!(cp->ctl_mask & msk)) continue;
- opf = pvr2_i2c_get_op(idx);
- if (opf) {
- bcnt = scnprintf(buf,maxlen,"%s%s",
- spcfl ? " " : "",
- opf->name);
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- spcfl = !0;
- } else {
- sm |= msk;
- }
- }
- if (sm) {
- bcnt = scnprintf(buf,maxlen,"%s%lx",
- idx != 0 ? " " : "",sm);
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- }
- bcnt = scnprintf(buf,maxlen,"]");
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- }
- return ccnt;
-}
-
-unsigned int pvr2_i2c_report(struct pvr2_hdw *hdw,
- char *buf,unsigned int maxlen)
-{
- unsigned int ccnt,bcnt;
- struct pvr2_i2c_client *cp;
- ccnt = 0;
- mutex_lock(&hdw->i2c_list_lock); do {
- list_for_each_entry(cp, &hdw->i2c_clients, list) {
- bcnt = pvr2_i2c_client_describe(
- cp,
- (PVR2_I2C_DETAIL_HANDLER|
- PVR2_I2C_DETAIL_CTLMASK),
- buf,maxlen);
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- bcnt = scnprintf(buf,maxlen,"\n");
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- }
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
- return ccnt;
-}
-
-void pvr2_i2c_track_attach_inform(struct i2c_client *client)
-{
- struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data);
- struct pvr2_i2c_client *cp;
- int fl = !(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL);
- cp = kzalloc(sizeof(*cp),GFP_KERNEL);
- trace_i2c("i2c_attach [client=%s @ 0x%x ctxt=%p]",
- client->name,
- client->addr,cp);
- if (!cp) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Unable to allocate tracking memory for incoming"
- " i2c module; ignoring module. This is likely"
- " going to be a problem.");
- return;
- }
- cp->hdw = hdw;
- INIT_LIST_HEAD(&cp->list);
- cp->client = client;
- mutex_lock(&hdw->i2c_list_lock); do {
- hdw->cropcap_stale = !0;
- list_add_tail(&cp->list,&hdw->i2c_clients);
- hdw->i2c_pend_types |= PVR2_I2C_PEND_DETECT;
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
- if (fl) queue_work(hdw->workqueue,&hdw->worki2csync);
-}
-
-static void pvr2_i2c_client_disconnect(struct pvr2_i2c_client *cp)
-{
- if (cp->handler && cp->handler->func_table->detach) {
- cp->handler->func_table->detach(cp->handler->func_data);
- }
- list_del(&cp->list);
- kfree(cp);
-}
-
-void pvr2_i2c_track_detach_inform(struct i2c_client *client)
-{
- struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data);
- struct pvr2_i2c_client *cp, *ncp;
- unsigned long amask = 0;
- int foundfl = 0;
- mutex_lock(&hdw->i2c_list_lock);
- hdw->cropcap_stale = !0;
- list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) {
- if (cp->client == client) {
- trace_i2c("pvr2_i2c_detach"
- " [client=%s @ 0x%x ctxt=%p]",
- client->name,
- client->addr, cp);
- pvr2_i2c_client_disconnect(cp);
- foundfl = !0;
- continue;
- }
- amask |= cp->ctl_mask;
- }
- hdw->i2c_active_mask = amask;
- mutex_unlock(&hdw->i2c_list_lock);
- if (!foundfl) {
- trace_i2c("pvr2_i2c_detach [client=%s @ 0x%x ctxt=<unknown>]",
- client->name, client->addr);
- }
-}
-
-/* This function is used to remove an i2c client from our tracking
- structure if the client happens to be the specified v4l2 sub-device.
- The idea here is to ensure that sub-devices are not also tracked with
- the old tracking mechanism - it's one or the other not both. This is
- only for debugging. In a "real" environment, only one of these two
- mechanisms should even be compiled in. But by enabling both we can
- incrementally test control of each sub-device. */
-void pvr2_i2c_untrack_subdev(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
-{
- struct i2c_client *client;
- struct pvr2_i2c_client *cp, *ncp;
- unsigned long amask = 0;
- mutex_lock(&hdw->i2c_list_lock);
- list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) {
- client = cp->client;
- if (i2c_get_clientdata(client) == sd) {
- trace_i2c("pvr2_i2c_detach (subdev active)"
- " [client=%s @ 0x%x ctxt=%p]",
- client->name, client->addr, cp);
- pvr2_i2c_client_disconnect(cp);
- continue;
- }
- amask |= cp->ctl_mask;
- }
- hdw->i2c_active_mask = amask;
- mutex_unlock(&hdw->i2c_list_lock);
-}
-
-void pvr2_i2c_track_init(struct pvr2_hdw *hdw)
-{
- hdw->i2c_pend_mask = 0;
- hdw->i2c_stale_mask = 0;
- hdw->i2c_active_mask = 0;
- INIT_LIST_HEAD(&hdw->i2c_clients);
- mutex_init(&hdw->i2c_list_lock);
-}
-
-void pvr2_i2c_track_done(struct pvr2_hdw *hdw)
-{
- /* Empty for now */
-}
-
-
-/*
- 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: ***
- */
+++ /dev/null
-/*
- *
- *
- * 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_TRACK_H
-#define __PVRUSB2_I2C_TRACK_H
-
-#include <linux/list.h>
-#include <linux/i2c.h>
-#include <media/v4l2-device.h>
-
-
-struct pvr2_hdw;
-struct pvr2_i2c_client;
-struct pvr2_i2c_handler;
-struct pvr2_i2c_handler_functions;
-struct pvr2_i2c_op;
-struct pvr2_i2c_op_functions;
-
-struct pvr2_i2c_client {
- struct i2c_client *client;
- struct pvr2_i2c_handler *handler;
- struct list_head list;
- struct pvr2_hdw *hdw;
- int detected_flag;
- int recv_enable;
- unsigned long pend_mask;
- unsigned long ctl_mask;
- void (*status_poll)(struct pvr2_i2c_client *);
-};
-
-struct pvr2_i2c_handler {
- void *func_data;
- const struct pvr2_i2c_handler_functions *func_table;
-};
-
-struct pvr2_i2c_handler_functions {
- void (*detach)(void *);
- int (*check)(void *);
- void (*update)(void *);
- unsigned int (*describe)(void *,char *,unsigned int);
-};
-
-struct pvr2_i2c_op {
- int (*check)(struct pvr2_hdw *);
- void (*update)(struct pvr2_hdw *);
- const char *name;
-};
-
-void pvr2_i2c_track_init(struct pvr2_hdw *);
-void pvr2_i2c_track_done(struct pvr2_hdw *);
-void pvr2_i2c_track_attach_inform(struct i2c_client *);
-void pvr2_i2c_track_detach_inform(struct i2c_client *);
-
-int pvr2_i2c_client_cmd(struct pvr2_i2c_client *,unsigned int cmd,void *arg);
-int pvr2_i2c_core_cmd(struct pvr2_hdw *,unsigned int cmd,void *arg);
-
-int pvr2_i2c_core_check_stale(struct pvr2_hdw *);
-void pvr2_i2c_core_sync(struct pvr2_hdw *);
-void pvr2_i2c_core_status_poll(struct pvr2_hdw *);
-unsigned int pvr2_i2c_report(struct pvr2_hdw *,char *buf,unsigned int maxlen);
-#define PVR2_I2C_DETAIL_DEBUG 0x0001
-#define PVR2_I2C_DETAIL_HANDLER 0x0002
-#define PVR2_I2C_DETAIL_CTLMASK 0x0004
-#define PVR2_I2C_DETAIL_ALL (\
- PVR2_I2C_DETAIL_DEBUG |\
- PVR2_I2C_DETAIL_HANDLER |\
- PVR2_I2C_DETAIL_CTLMASK)
-
-void pvr2_i2c_probe(struct pvr2_hdw *,struct pvr2_i2c_client *);
-const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx);
-
-void pvr2_i2c_untrack_subdev(struct pvr2_hdw *, struct v4l2_subdev *sd);
-
-
-#endif /* __PVRUSB2_I2C_CORE_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: ***
- */
+++ /dev/null
-/*
- *
- *
- * 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.h"
-#include "pvrusb2-util.h"
-#include "pvrusb2-tuner.h"
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-#include <linux/videodev2.h>
-#include <media/tuner.h>
-#include <media/v4l2-common.h>
-
-
-struct pvr2_tuner_handler {
- struct pvr2_hdw *hdw;
- struct pvr2_i2c_client *client;
- struct pvr2_i2c_handler i2c_handler;
- int type_update_fl;
-};
-
-
-static void set_type(struct pvr2_tuner_handler *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- struct tuner_setup setup;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c tuner set_type(%d)",hdw->tuner_type);
- if (((int)(hdw->tuner_type)) < 0) return;
-
- setup.addr = ADDR_UNSET;
- setup.type = hdw->tuner_type;
- setup.mode_mask = T_RADIO | T_ANALOG_TV;
- /* We may really want mode_mask to be T_ANALOG_TV for now */
- pvr2_i2c_client_cmd(ctxt->client,TUNER_SET_TYPE_ADDR,&setup);
- ctxt->type_update_fl = 0;
-}
-
-
-static int tuner_check(struct pvr2_tuner_handler *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- if (hdw->tuner_updated) ctxt->type_update_fl = !0;
- return ctxt->type_update_fl != 0;
-}
-
-
-static void tuner_update(struct pvr2_tuner_handler *ctxt)
-{
- if (ctxt->type_update_fl) set_type(ctxt);
-}
-
-
-static void pvr2_tuner_detach(struct pvr2_tuner_handler *ctxt)
-{
- ctxt->client->handler = NULL;
- kfree(ctxt);
-}
-
-
-static unsigned int pvr2_tuner_describe(struct pvr2_tuner_handler *ctxt,char *buf,unsigned int cnt)
-{
- return scnprintf(buf,cnt,"handler: pvrusb2-tuner");
-}
-
-
-static const struct pvr2_i2c_handler_functions tuner_funcs = {
- .detach = (void (*)(void *))pvr2_tuner_detach,
- .check = (int (*)(void *))tuner_check,
- .update = (void (*)(void *))tuner_update,
- .describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_tuner_describe,
-};
-
-
-int pvr2_i2c_tuner_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
-{
- struct pvr2_tuner_handler *ctxt;
- if (cp->handler) return 0;
-
- ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
- if (!ctxt) return 0;
-
- ctxt->i2c_handler.func_data = ctxt;
- ctxt->i2c_handler.func_table = &tuner_funcs;
- ctxt->type_update_fl = !0;
- ctxt->client = cp;
- ctxt->hdw = hdw;
- cp->handler = &ctxt->i2c_handler;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x tuner handler set up",
- cp->client->addr);
- 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: ***
- */
+++ /dev/null
-/*
- *
- *
- * 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_TUNER_H
-#define __PVRUSB2_TUNER_H
-
-#include "pvrusb2-i2c-track.h"
-
-int pvr2_i2c_tuner_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
-
-#endif /* __PVRUSB2_TUNER_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: ***
- */
#include "pvrusb2-video-v4l.h"
-#include "pvrusb2-i2c-cmd-v4l2.h"
#include "pvrusb2-hdw-internal.h"
#include "pvrusb2-debug.h"
},
};
-struct pvr2_v4l_decoder {
- struct pvr2_i2c_handler handler;
- struct pvr2_decoder_ctrl ctrl;
- struct pvr2_i2c_client *client;
- struct pvr2_hdw *hdw;
- unsigned long stale_mask;
-};
-
-
-
-static void set_input(struct pvr2_v4l_decoder *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- struct v4l2_routing route;
- const struct routing_scheme *sp;
- unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
-
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_input(%d)",hdw->input_val);
-
- if ((sid < ARRAY_SIZE(routing_schemes)) &&
- ((sp = routing_schemes + sid) != NULL) &&
- (hdw->input_val >= 0) &&
- (hdw->input_val < sp->cnt)) {
- route.input = sp->def[hdw->input_val];
- } else {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "*** WARNING *** i2c v4l2 set_input:"
- " Invalid routing scheme (%u) and/or input (%d)",
- sid,hdw->input_val);
- return;
- }
-
- route.output = 0;
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route);
-}
-
-
-static int check_input(struct pvr2_v4l_decoder *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- return hdw->input_dirty != 0;
-}
-
-
-static void set_audio(struct pvr2_v4l_decoder *ctxt)
-{
- u32 val;
- struct pvr2_hdw *hdw = ctxt->hdw;
-
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c 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;
- }
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val);
-}
-
-
-static int check_audio(struct pvr2_v4l_decoder *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- return hdw->srate_dirty != 0;
-}
-
-
-struct pvr2_v4l_decoder_ops {
- void (*update)(struct pvr2_v4l_decoder *);
- int (*check)(struct pvr2_v4l_decoder *);
-};
-
-
-static const struct pvr2_v4l_decoder_ops decoder_ops[] = {
- { .update = set_input, .check = check_input},
- { .update = set_audio, .check = check_audio},
-};
-
-
-static void decoder_detach(struct pvr2_v4l_decoder *ctxt)
-{
- ctxt->client->handler = NULL;
- pvr2_hdw_set_decoder(ctxt->hdw,NULL);
- kfree(ctxt);
-}
-
-
-static int decoder_check(struct pvr2_v4l_decoder *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
- msk = 1 << idx;
- if (ctxt->stale_mask & msk) continue;
- if (decoder_ops[idx].check(ctxt)) {
- ctxt->stale_mask |= msk;
- }
- }
- return ctxt->stale_mask != 0;
-}
-
-
-static void decoder_update(struct pvr2_v4l_decoder *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
- msk = 1 << idx;
- if (!(ctxt->stale_mask & msk)) continue;
- ctxt->stale_mask &= ~msk;
- decoder_ops[idx].update(ctxt);
- }
-}
-
-
-static int decoder_detect(struct pvr2_i2c_client *cp)
-{
- /* Attempt to query the decoder - let's see if it will answer */
- struct v4l2_tuner vt;
- int ret;
-
- memset(&vt,0,sizeof(vt));
- ret = pvr2_i2c_client_cmd(cp,VIDIOC_G_TUNER,&vt);
- return ret == 0; /* Return true if it answered */
-}
-
-
-static void decoder_enable(struct pvr2_v4l_decoder *ctxt,int fl)
-{
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 decoder_enable(%d)",fl);
- pvr2_v4l2_cmd_stream(ctxt->client,fl);
-}
-
-
-static unsigned int decoder_describe(struct pvr2_v4l_decoder *ctxt,char *buf,unsigned int cnt)
-{
- return scnprintf(buf,cnt,"handler: pvrusb2-video-v4l");
-}
-
-
-static const struct pvr2_i2c_handler_functions hfuncs = {
- .detach = (void (*)(void *))decoder_detach,
- .check = (int (*)(void *))decoder_check,
- .update = (void (*)(void *))decoder_update,
- .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe,
-};
-
-
-int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *hdw,
- struct pvr2_i2c_client *cp)
-{
- struct pvr2_v4l_decoder *ctxt;
-
- if (hdw->decoder_ctrl) return 0;
- if (cp->handler) return 0;
- if (!decoder_detect(cp)) return 0;
-
- ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
- if (!ctxt) return 0;
-
- ctxt->handler.func_data = ctxt;
- ctxt->handler.func_table = &hfuncs;
- ctxt->ctrl.ctxt = ctxt;
- ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
- ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
- ctxt->client = cp;
- ctxt->hdw = hdw;
- ctxt->stale_mask = (1 << ARRAY_SIZE(decoder_ops)) - 1;
- pvr2_hdw_set_decoder(hdw,&ctxt->ctrl);
- cp->handler = &ctxt->handler;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x saa711x V4L2 handler set up",
- cp->client->addr);
- return !0;
-}
-
-
void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{
if (hdw->input_dirty || hdw->force_dirty) {
*/
-
-#include "pvrusb2-i2c-track.h"
-
-int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
-
#include "pvrusb2-hdw-internal.h"
void pvr2_saa7115_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *);
*/
#include "pvrusb2-wm8775.h"
-#include "pvrusb2-i2c-cmd-v4l2.h"
#include "pvrusb2-hdw-internal.h"
#include <linux/errno.h>
#include <linux/slab.h>
-
-
-struct pvr2_v4l_wm8775 {
- struct pvr2_i2c_handler handler;
- struct pvr2_i2c_client *client;
- struct pvr2_hdw *hdw;
- unsigned long stale_mask;
-};
-
-
-static void set_input(struct pvr2_v4l_wm8775 *ctxt)
-{
- struct v4l2_routing route;
- struct pvr2_hdw *hdw = ctxt->hdw;
-
- memset(&route,0,sizeof(route));
-
- switch(hdw->input_val) {
- case PVR2_CVAL_INPUT_RADIO:
- route.input = 1;
- break;
- default:
- /* All other cases just use the second input */
- route.input = 2;
- break;
- }
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c wm8775 set_input(val=%d route=0x%x)",
- hdw->input_val,route.input);
-
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
-}
-
-static int check_input(struct pvr2_v4l_wm8775 *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- return hdw->input_dirty != 0;
-}
-
-
-struct pvr2_v4l_wm8775_ops {
- void (*update)(struct pvr2_v4l_wm8775 *);
- int (*check)(struct pvr2_v4l_wm8775 *);
-};
-
-
-static const struct pvr2_v4l_wm8775_ops wm8775_ops[] = {
- { .update = set_input, .check = check_input},
-};
-
-
-static unsigned int wm8775_describe(struct pvr2_v4l_wm8775 *ctxt,
- char *buf,unsigned int cnt)
-{
- return scnprintf(buf,cnt,"handler: pvrusb2-wm8775");
-}
-
-
-static void wm8775_detach(struct pvr2_v4l_wm8775 *ctxt)
-{
- ctxt->client->handler = NULL;
- kfree(ctxt);
-}
-
-
-static int wm8775_check(struct pvr2_v4l_wm8775 *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(wm8775_ops); idx++) {
- msk = 1 << idx;
- if (ctxt->stale_mask & msk) continue;
- if (wm8775_ops[idx].check(ctxt)) {
- ctxt->stale_mask |= msk;
- }
- }
- return ctxt->stale_mask != 0;
-}
-
-
-static void wm8775_update(struct pvr2_v4l_wm8775 *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(wm8775_ops); idx++) {
- msk = 1 << idx;
- if (!(ctxt->stale_mask & msk)) continue;
- ctxt->stale_mask &= ~msk;
- wm8775_ops[idx].update(ctxt);
- }
-}
-
-
-static const struct pvr2_i2c_handler_functions hfuncs = {
- .detach = (void (*)(void *))wm8775_detach,
- .check = (int (*)(void *))wm8775_check,
- .update = (void (*)(void *))wm8775_update,
- .describe = (unsigned int (*)(void *,char *,unsigned int))wm8775_describe,
-};
-
-
-int pvr2_i2c_wm8775_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
-{
- struct pvr2_v4l_wm8775 *ctxt;
-
- if (cp->handler) return 0;
-
- ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
- if (!ctxt) return 0;
-
- ctxt->handler.func_data = ctxt;
- ctxt->handler.func_table = &hfuncs;
- ctxt->client = cp;
- ctxt->hdw = hdw;
- ctxt->stale_mask = (1 << ARRAY_SIZE(wm8775_ops)) - 1;
- cp->handler = &ctxt->handler;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x wm8775 V4L2 handler set up",
- cp->client->addr);
- return !0;
-}
-
-
void pvr2_wm8775_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{
if (hdw->input_dirty || hdw->force_dirty) {
-#include "pvrusb2-i2c-track.h"
-
-int pvr2_i2c_wm8775_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
#include "pvrusb2-hdw-internal.h"
void pvr2_wm8775_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd);