Commit 5a3bab8e authored by Mike Isely's avatar Mike Isely Committed by Mauro Carvalho Chehab

V4L/DVB (11204): pvrusb2: Remove old i2c layer; we use v4l2-subdev now

This change removes the old i2c module controlling layer from the
pvrusb2 driver.  This is code that first had appeared in the driver
back in December 2005.  It's history.  Now we use v4l2-subdev.  Please
note also that with this change, the driver will no longer be usable
in kernels older that 2.6.22.
Signed-off-by: default avatarMike Isely <isely@pobox.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 2eb563b7
...@@ -2,11 +2,10 @@ obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o ...@@ -2,11 +2,10 @@ obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o
obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o
obj-pvrusb2-dvb-$(CONFIG_VIDEO_PVRUSB2_DVB) := pvrusb2-dvb.o obj-pvrusb2-dvb-$(CONFIG_VIDEO_PVRUSB2_DVB) := pvrusb2-dvb.o
pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \ pvrusb2-objs := pvrusb2-i2c-core.o \
pvrusb2-i2c-track.o \ pvrusb2-audio.o \
pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \
pvrusb2-encoder.o pvrusb2-video-v4l.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-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \
pvrusb2-ctrl.o pvrusb2-std.o pvrusb2-devattr.o \ pvrusb2-ctrl.o pvrusb2-std.o pvrusb2-devattr.o \
pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \ pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \
......
...@@ -55,133 +55,6 @@ static const struct routing_scheme routing_schemes[] = { ...@@ -55,133 +55,6 @@ static const struct routing_scheme routing_schemes[] = {
}, },
}; };
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) void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{ {
if (hdw->input_dirty || hdw->force_dirty) { if (hdw->input_dirty || hdw->force_dirty) {
......
...@@ -22,10 +22,6 @@ ...@@ -22,10 +22,6 @@
#ifndef __PVRUSB2_AUDIO_H #ifndef __PVRUSB2_AUDIO_H
#define __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" #include "pvrusb2-hdw-internal.h"
void pvr2_msp3400_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *); void pvr2_msp3400_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *);
#endif /* __PVRUSB2_AUDIO_H */ #endif /* __PVRUSB2_AUDIO_H */
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
#include "pvrusb2-cx2584x-v4l.h" #include "pvrusb2-cx2584x-v4l.h"
#include "pvrusb2-video-v4l.h" #include "pvrusb2-video-v4l.h"
#include "pvrusb2-i2c-cmd-v4l2.h"
#include "pvrusb2-hdw-internal.h" #include "pvrusb2-hdw-internal.h"
...@@ -102,226 +101,6 @@ static const struct routing_scheme routing_schemes[] = { ...@@ -102,226 +101,6 @@ static const struct routing_scheme routing_schemes[] = {
}, },
}; };
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) void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{ {
pvr2_trace(PVR2_TRACE_CHIPS, "subdev cx2584x update..."); pvr2_trace(PVR2_TRACE_CHIPS, "subdev cx2584x update...");
......
...@@ -34,11 +34,6 @@ ...@@ -34,11 +34,6 @@
#include "pvrusb2-i2c-track.h"
int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
#include "pvrusb2-hdw-internal.h" #include "pvrusb2-hdw-internal.h"
void pvr2_cx25840_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd); void pvr2_cx25840_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd);
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include "pvrusb2-debugifc.h" #include "pvrusb2-debugifc.h"
#include "pvrusb2-hdw.h" #include "pvrusb2-hdw.h"
#include "pvrusb2-debug.h" #include "pvrusb2-debug.h"
#include "pvrusb2-i2c-track.h"
struct debugifc_mask_item { struct debugifc_mask_item {
const char *name; const char *name;
...@@ -147,10 +146,6 @@ int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt) ...@@ -147,10 +146,6 @@ int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt)
bcnt += ccnt; acnt -= ccnt; buf += ccnt; bcnt += ccnt; acnt -= ccnt; buf += ccnt;
ccnt = pvr2_hdw_state_report(hdw,buf,acnt); ccnt = pvr2_hdw_state_report(hdw,buf,acnt);
bcnt += ccnt; acnt -= ccnt; buf += ccnt; 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; return bcnt;
} }
......
...@@ -138,22 +138,6 @@ struct pvr2_ctrl { ...@@ -138,22 +138,6 @@ struct pvr2_ctrl {
}; };
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 */ /* Disposition of firmware1 loading situation */
#define FW1_STATE_UNKNOWN 0 #define FW1_STATE_UNKNOWN 0
...@@ -187,7 +171,6 @@ struct pvr2_hdw { ...@@ -187,7 +171,6 @@ struct pvr2_hdw {
/* Kernel worker thread handling */ /* Kernel worker thread handling */
struct workqueue_struct *workqueue; struct workqueue_struct *workqueue;
struct work_struct workpoll; /* Update driver state */ struct work_struct workpoll; /* Update driver state */
struct work_struct worki2csync; /* Update i2c clients */
/* Video spigot */ /* Video spigot */
struct pvr2_stream *vid_stream; struct pvr2_stream *vid_stream;
...@@ -216,12 +199,6 @@ struct pvr2_hdw { ...@@ -216,12 +199,6 @@ struct pvr2_hdw {
pvr2_i2c_func i2c_func[PVR2_I2C_FUNC_CNT]; pvr2_i2c_func i2c_func[PVR2_I2C_FUNC_CNT];
int i2c_cx25840_hack_state; int i2c_cx25840_hack_state;
int i2c_linked; 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 */ /* Frequency table */
unsigned int freqTable[FREQTABLE_SIZE]; unsigned int freqTable[FREQTABLE_SIZE];
...@@ -297,7 +274,6 @@ struct pvr2_hdw { ...@@ -297,7 +274,6 @@ struct pvr2_hdw {
int flag_decoder_missed;/* We've noticed missing decoder */ int flag_decoder_missed;/* We've noticed missing decoder */
int flag_tripped; /* Indicates overall failure to start */ int flag_tripped; /* Indicates overall failure to start */
struct pvr2_decoder_ctrl *decoder_ctrl;
unsigned int decoder_client_id; unsigned int decoder_client_id;
// CPU firmware info (used to help find / save firmware data) // CPU firmware info (used to help find / save firmware data)
...@@ -305,10 +281,6 @@ struct pvr2_hdw { ...@@ -305,10 +281,6 @@ struct pvr2_hdw {
unsigned int fw_size; unsigned int fw_size;
int fw_cpu_flag; /* True if we are dealing with the CPU */ 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 */ /* Tuner / frequency control stuff */
unsigned int tuner_type; unsigned int tuner_type;
int tuner_updated; int tuner_updated;
...@@ -406,7 +378,6 @@ struct pvr2_hdw { ...@@ -406,7 +378,6 @@ struct pvr2_hdw {
/* This function gets the current frequency */ /* This function gets the current frequency */
unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *); 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 *); void pvr2_hdw_status_poll(struct pvr2_hdw *);
......
...@@ -30,8 +30,6 @@ ...@@ -30,8 +30,6 @@
#include "pvrusb2-util.h" #include "pvrusb2-util.h"
#include "pvrusb2-hdw.h" #include "pvrusb2-hdw.h"
#include "pvrusb2-i2c-core.h" #include "pvrusb2-i2c-core.h"
#include "pvrusb2-i2c-track.h"
#include "pvrusb2-tuner.h"
#include "pvrusb2-eeprom.h" #include "pvrusb2-eeprom.h"
#include "pvrusb2-hdw-internal.h" #include "pvrusb2-hdw-internal.h"
#include "pvrusb2-encoder.h" #include "pvrusb2-encoder.h"
...@@ -313,7 +311,6 @@ static int pvr2_hdw_set_input(struct pvr2_hdw *hdw,int v); ...@@ -313,7 +311,6 @@ static int pvr2_hdw_set_input(struct pvr2_hdw *hdw,int v);
static void pvr2_hdw_state_sched(struct pvr2_hdw *); static void pvr2_hdw_state_sched(struct pvr2_hdw *);
static int pvr2_hdw_state_eval(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_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 void pvr2_hdw_worker_poll(struct work_struct *work);
static int pvr2_hdw_wait(struct pvr2_hdw *,int state); static int pvr2_hdw_wait(struct pvr2_hdw *,int state);
static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *); static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *);
...@@ -1676,10 +1673,6 @@ static const char *pvr2_get_state_name(unsigned int st) ...@@ -1676,10 +1673,6 @@ static const char *pvr2_get_state_name(unsigned int st)
static int pvr2_decoder_enable(struct pvr2_hdw *hdw,int enablefl) 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 /* Even though we really only care about the video decoder chip at
this point, we'll broadcast stream on/off to all sub-devices this point, we'll broadcast stream on/off to all sub-devices
anyway, just in case somebody else wants to hear the anyway, just in case somebody else wants to hear the
...@@ -1704,21 +1697,6 @@ static int pvr2_decoder_enable(struct pvr2_hdw *hdw,int enablefl) ...@@ -1704,21 +1697,6 @@ static int pvr2_decoder_enable(struct pvr2_hdw *hdw,int enablefl)
} }
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) int pvr2_hdw_get_state(struct pvr2_hdw *hdw)
{ {
return hdw->master_state; return hdw->master_state;
...@@ -2052,7 +2030,6 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw, ...@@ -2052,7 +2030,6 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
* and every other place where I can find examples of this, the * and every other place where I can find examples of this, the
* "chipid" appears to just be the module name again. So here we * "chipid" appears to just be the module name again. So here we
* just do the same thing. */ * just do the same thing. */
hdw->i2c_adap.class = 0;
if (i2ccnt == 1) { if (i2ccnt == 1) {
pvr2_trace(PVR2_TRACE_INIT, pvr2_trace(PVR2_TRACE_INIT,
"Module ID %u:" "Module ID %u:"
...@@ -2070,7 +2047,6 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw, ...@@ -2070,7 +2047,6 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
fname, fname, fname, fname,
i2caddr); i2caddr);
} }
hdw->i2c_adap.class = I2C_CLASS_TV_ANALOG;
if (!sd) { if (!sd) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, pvr2_trace(PVR2_TRACE_ERROR_LEGS,
...@@ -2084,11 +2060,6 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw, ...@@ -2084,11 +2060,6 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
requires special handling. */ requires special handling. */
sd->grp_id = mid; 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); pvr2_trace(PVR2_TRACE_INFO, "Attached sub-driver %s", fname);
...@@ -2204,7 +2175,6 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) ...@@ -2204,7 +2175,6 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
} }
// This step MUST happen after the earlier powerup step. // This step MUST happen after the earlier powerup step.
pvr2_i2c_track_init(hdw);
pvr2_i2c_core_init(hdw); pvr2_i2c_core_init(hdw);
if (!pvr2_hdw_dev_ok(hdw)) return; if (!pvr2_hdw_dev_ok(hdw)) return;
...@@ -2271,7 +2241,6 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) ...@@ -2271,7 +2241,6 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
hdw->tuner_type); hdw->tuner_type);
} }
pvr2_i2c_core_check_stale(hdw);
if (!pvr2_hdw_dev_ok(hdw)) return; if (!pvr2_hdw_dev_ok(hdw)) return;
...@@ -2628,7 +2597,6 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, ...@@ -2628,7 +2597,6 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
hdw->workqueue = create_singlethread_workqueue(hdw->name); hdw->workqueue = create_singlethread_workqueue(hdw->name);
INIT_WORK(&hdw->workpoll,pvr2_hdw_worker_poll); 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", pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s",
hdw->unit_number,hdw->name); hdw->unit_number,hdw->name);
...@@ -2731,11 +2699,7 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) ...@@ -2731,11 +2699,7 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
pvr2_stream_destroy(hdw->vid_stream); pvr2_stream_destroy(hdw->vid_stream);
hdw->vid_stream = NULL; hdw->vid_stream = NULL;
} }
if (hdw->decoder_ctrl) {
hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt);
}
pvr2_i2c_core_done(hdw); pvr2_i2c_core_done(hdw);
pvr2_i2c_track_done(hdw);
v4l2_device_unregister(&hdw->v4l2_dev); v4l2_device_unregister(&hdw->v4l2_dev);
pvr2_hdw_remove_usb_stuff(hdw); pvr2_hdw_remove_usb_stuff(hdw);
mutex_lock(&pvr2_unit_mtx); do { mutex_lock(&pvr2_unit_mtx); do {
...@@ -3238,12 +3202,6 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw) ...@@ -3238,12 +3202,6 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw)
cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs,VIDIOC_S_EXT_CTRLS); 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) { if (hdw->active_stream_type != hdw->desired_stream_type) {
/* Handle any side effects of stream config here */ /* Handle any side effects of stream config here */
hdw->active_stream_type = hdw->desired_stream_type; hdw->active_stream_type = hdw->desired_stream_type;
...@@ -3274,9 +3232,6 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw) ...@@ -3274,9 +3232,6 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw)
cptr->info->clear_dirty(cptr); cptr->info->clear_dirty(cptr);
} }
/* Now execute i2c core update */
pvr2_i2c_core_sync(hdw);
if ((hdw->pathway_state == PVR2_PATHWAY_ANALOG) && if ((hdw->pathway_state == PVR2_PATHWAY_ANALOG) &&
hdw->state_encoder_run) { hdw->state_encoder_run) {
/* If encoder isn't running or it can't be touched, then /* If encoder isn't running or it can't be touched, then
...@@ -3305,15 +3260,6 @@ int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw) ...@@ -3305,15 +3260,6 @@ int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw)
} }
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) static void pvr2_hdw_worker_poll(struct work_struct *work)
{ {
int fl = 0; int fl = 0;
...@@ -3431,10 +3377,6 @@ void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw) ...@@ -3431,10 +3377,6 @@ void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
int nr = pvr2_hdw_get_unit_number(hdw); int nr = pvr2_hdw_get_unit_number(hdw);
LOCK_TAKE(hdw->big_lock); do { LOCK_TAKE(hdw->big_lock); do {
printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr); 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); v4l2_device_call_all(&hdw->v4l2_dev, 0, core, log_status);
pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:"); pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2"); cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
...@@ -4120,16 +4062,6 @@ int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw) ...@@ -4120,16 +4062,6 @@ int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
{ {
pvr2_trace(PVR2_TRACE_INIT, pvr2_trace(PVR2_TRACE_INIT,
"Requesting decoder reset"); "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) { if (hdw->decoder_client_id) {
v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id, v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id,
core, reset, 0); core, reset, 0);
...@@ -5138,7 +5070,6 @@ void pvr2_hdw_status_poll(struct pvr2_hdw *hdw) ...@@ -5138,7 +5070,6 @@ void pvr2_hdw_status_poll(struct pvr2_hdw *hdw)
struct v4l2_tuner *vtp = &hdw->tuner_signal_info; struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
memset(vtp, 0, sizeof(*vtp)); memset(vtp, 0, sizeof(*vtp));
hdw->tuner_signal_stale = 0; hdw->tuner_signal_stale = 0;
pvr2_i2c_core_status_poll(hdw);
/* Note: There apparently is no replacement for VIDIOC_CROPCAP /* Note: There apparently is no replacement for VIDIOC_CROPCAP
using v4l2-subdev - therefore we can't support that AT ALL right using v4l2-subdev - therefore we can't support that AT ALL right
now. (Of course, no sub-drivers seem to implement it either. now. (Of course, no sub-drivers seem to implement it either.
...@@ -5253,7 +5184,6 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw, ...@@ -5253,7 +5184,6 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
int setFl, u64 *val_ptr) int setFl, u64 *val_ptr)
{ {
#ifdef CONFIG_VIDEO_ADV_DEBUG #ifdef CONFIG_VIDEO_ADV_DEBUG
struct pvr2_i2c_client *cp;
struct v4l2_dbg_register req; struct v4l2_dbg_register req;
int stat = 0; int stat = 0;
int okFl = 0; int okFl = 0;
...@@ -5266,21 +5196,6 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw, ...@@ -5266,21 +5196,6 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
/* It would be nice to know if a sub-device answered the request */ /* 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); v4l2_device_call_all(&hdw->v4l2_dev, 0, core, g_register, &req);
if (!setFl) *val_ptr = req.val; 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) { if (okFl) {
return stat; return stat;
} }
......
/*
*
*
* 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: ***
*/
/*
*
*
* 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: ***
*/
/*
*
*
* 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: ***
*/
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include "pvrusb2-i2c-core.h" #include "pvrusb2-i2c-core.h"
#include "pvrusb2-i2c-track.h"
#include "pvrusb2-hdw-internal.h" #include "pvrusb2-hdw-internal.h"
#include "pvrusb2-debug.h" #include "pvrusb2-debug.h"
#include "pvrusb2-fx2-cmd.h" #include "pvrusb2-fx2-cmd.h"
...@@ -523,13 +522,11 @@ static u32 pvr2_i2c_functionality(struct i2c_adapter *adap) ...@@ -523,13 +522,11 @@ static u32 pvr2_i2c_functionality(struct i2c_adapter *adap)
static int pvr2_i2c_attach_inform(struct i2c_client *client) static int pvr2_i2c_attach_inform(struct i2c_client *client)
{ {
pvr2_i2c_track_attach_inform(client);
return 0; return 0;
} }
static int pvr2_i2c_detach_inform(struct i2c_client *client) static int pvr2_i2c_detach_inform(struct i2c_client *client)
{ {
pvr2_i2c_track_detach_inform(client);
return 0; return 0;
} }
...@@ -607,7 +604,6 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw) ...@@ -607,7 +604,6 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev; hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev;
hdw->i2c_adap.algo = &hdw->i2c_algo; hdw->i2c_adap.algo = &hdw->i2c_algo;
hdw->i2c_adap.algo_data = hdw; hdw->i2c_adap.algo_data = hdw;
hdw->i2c_adap.class = I2C_CLASS_TV_ANALOG;
hdw->i2c_linked = !0; hdw->i2c_linked = !0;
i2c_set_adapdata(&hdw->i2c_adap, &hdw->v4l2_dev); i2c_set_adapdata(&hdw->i2c_adap, &hdw->v4l2_dev);
i2c_add_adapter(&hdw->i2c_adap); i2c_add_adapter(&hdw->i2c_adap);
......
This diff is collapsed.
/*
*
*
* 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: ***
*/
/*
*
*
* 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: ***
*/
/*
*
*
* 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: ***
*/
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include "pvrusb2-video-v4l.h" #include "pvrusb2-video-v4l.h"
#include "pvrusb2-i2c-cmd-v4l2.h"
#include "pvrusb2-hdw-internal.h" #include "pvrusb2-hdw-internal.h"
#include "pvrusb2-debug.h" #include "pvrusb2-debug.h"
...@@ -62,191 +61,6 @@ static const struct routing_scheme routing_schemes[] = { ...@@ -62,191 +61,6 @@ static const struct routing_scheme routing_schemes[] = {
}, },
}; };
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) void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{ {
if (hdw->input_dirty || hdw->force_dirty) { if (hdw->input_dirty || hdw->force_dirty) {
......
...@@ -32,11 +32,6 @@ ...@@ -32,11 +32,6 @@
*/ */
#include "pvrusb2-i2c-track.h"
int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
#include "pvrusb2-hdw-internal.h" #include "pvrusb2-hdw-internal.h"
void pvr2_saa7115_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *); void pvr2_saa7115_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *);
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
*/ */
#include "pvrusb2-wm8775.h" #include "pvrusb2-wm8775.h"
#include "pvrusb2-i2c-cmd-v4l2.h"
#include "pvrusb2-hdw-internal.h" #include "pvrusb2-hdw-internal.h"
...@@ -37,129 +36,6 @@ ...@@ -37,129 +36,6 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/slab.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) void pvr2_wm8775_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{ {
if (hdw->input_dirty || hdw->force_dirty) { if (hdw->input_dirty || hdw->force_dirty) {
......
...@@ -34,9 +34,6 @@ ...@@ -34,9 +34,6 @@
#include "pvrusb2-i2c-track.h"
int pvr2_i2c_wm8775_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
#include "pvrusb2-hdw-internal.h" #include "pvrusb2-hdw-internal.h"
void pvr2_wm8775_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd); void pvr2_wm8775_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment