X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fmedia%2Fvideo%2Fpvrusb2%2Fpvrusb2-audio.c;h=9a7c8e9c3e8ba3ef33ab19b4f449e64791c43a79;hb=d685a483b8c92e3d0580b6c28e2ed531391c8c46;hp=313d2dcf9e4bfbd90c04e5f2cd573385ce6ca25f;hpb=03529d9f66b7995c67ddceb8f83258df3c9915da;p=linux-2.6-omap-h63xx.git diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c index 313d2dcf9e4..9a7c8e9c3e8 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-audio.c +++ b/drivers/media/video/pvrusb2/pvrusb2-audio.c @@ -31,46 +31,62 @@ struct pvr2_msp3400_handler { struct pvr2_hdw *hdw; struct pvr2_i2c_client *client; struct pvr2_i2c_handler i2c_handler; - struct pvr2_audio_stat astat; unsigned long stale_mask; }; + +struct routing_scheme { + const int *def; + unsigned int cnt; +}; + +static const int routing_scheme0[] = { + [PVR2_CVAL_INPUT_TV] = MSP_INPUT_DEFAULT, + [PVR2_CVAL_INPUT_RADIO] = MSP_INPUT(MSP_IN_SCART2, + MSP_IN_TUNER1, + MSP_DSP_IN_SCART, + MSP_DSP_IN_SCART), + [PVR2_CVAL_INPUT_COMPOSITE] = MSP_INPUT(MSP_IN_SCART1, + MSP_IN_TUNER1, + MSP_DSP_IN_SCART, + MSP_DSP_IN_SCART), + [PVR2_CVAL_INPUT_SVIDEO] = MSP_INPUT(MSP_IN_SCART1, + MSP_IN_TUNER1, + MSP_DSP_IN_SCART, + MSP_DSP_IN_SCART), +}; + +static const struct routing_scheme routing_schemes[] = { + [PVR2_ROUTING_SCHEME_HAUPPAUGE] = { + .def = routing_scheme0, + .cnt = ARRAY_SIZE(routing_scheme0), + }, +}; + /* 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 (hdw->input_val == PVR2_CVAL_INPUT_TV) { - struct v4l2_tuner vt; - memset(&vt,0,sizeof(vt)); - vt.audmode = hdw->audiomode_val; - pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_TUNER,&vt); + if ((sid < ARRAY_SIZE(routing_schemes)) && + ((sp = routing_schemes + sid) != 0) && + (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.input = MSP_INPUT_DEFAULT; route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1); - switch (hdw->input_val) { - case PVR2_CVAL_INPUT_TV: - break; - case PVR2_CVAL_INPUT_RADIO: - /* Assume that msp34xx also handle FM decoding, in which case - we're still using the tuner. */ - /* HV: actually it is more likely to be the SCART2 input if - the ivtv experience is any indication. */ - route.input = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, - MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); - break; - case PVR2_CVAL_INPUT_SVIDEO: - case PVR2_CVAL_INPUT_COMPOSITE: - /* SCART 1 input */ - route.input = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, - MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); - break; - } pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route); } @@ -78,8 +94,7 @@ static void set_stereo(struct pvr2_msp3400_handler *ctxt) static int check_stereo(struct pvr2_msp3400_handler *ctxt) { struct pvr2_hdw *hdw = ctxt->hdw; - return (hdw->input_dirty || - hdw->audiomode_dirty); + return hdw->input_dirty; } @@ -99,8 +114,7 @@ static int msp3400_check(struct pvr2_msp3400_handler *ctxt) unsigned long msk; unsigned int idx; - for (idx = 0; idx < sizeof(msp3400_ops)/sizeof(msp3400_ops[0]); - 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)) { @@ -116,8 +130,7 @@ static void msp3400_update(struct pvr2_msp3400_handler *ctxt) unsigned long msk; unsigned int idx; - for (idx = 0; idx < sizeof(msp3400_ops)/sizeof(msp3400_ops[0]); - idx++) { + for (idx = 0; idx < ARRAY_SIZE(msp3400_ops); idx++) { msk = 1 << idx; if (!(ctxt->stale_mask & msk)) continue; ctxt->stale_mask &= ~msk; @@ -126,27 +139,9 @@ static void msp3400_update(struct pvr2_msp3400_handler *ctxt) } -/* This reads back the current signal type */ -static int get_audio_status(struct pvr2_msp3400_handler *ctxt) -{ - struct v4l2_tuner vt; - int stat; - - memset(&vt,0,sizeof(vt)); - stat = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt); - if (stat < 0) return stat; - - ctxt->hdw->flag_stereo = (vt.audmode & V4L2_TUNER_MODE_STEREO) != 0; - ctxt->hdw->flag_bilingual = - (vt.audmode & V4L2_TUNER_MODE_LANG2) != 0; - return 0; -} - - static void pvr2_msp3400_detach(struct pvr2_msp3400_handler *ctxt) { - ctxt->client->handler = 0; - ctxt->hdw->audio_stat = 0; + ctxt->client->handler = NULL; kfree(ctxt); } @@ -158,7 +153,7 @@ static unsigned int pvr2_msp3400_describe(struct pvr2_msp3400_handler *ctxt, } -const static struct pvr2_i2c_handler_functions msp3400_funcs = { +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, @@ -169,24 +164,17 @@ const static struct pvr2_i2c_handler_functions msp3400_funcs = { int pvr2_i2c_msp3400_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) { struct pvr2_msp3400_handler *ctxt; - if (hdw->audio_stat) return 0; if (cp->handler) return 0; - ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); + ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL); if (!ctxt) return 0; - memset(ctxt,0,sizeof(*ctxt)); ctxt->i2c_handler.func_data = ctxt; ctxt->i2c_handler.func_table = &msp3400_funcs; ctxt->client = cp; ctxt->hdw = hdw; - ctxt->astat.ctxt = ctxt; - ctxt->astat.status = (int (*)(void *))get_audio_status; - ctxt->astat.detach = (void (*)(void *))pvr2_msp3400_detach; - ctxt->stale_mask = (1 << (sizeof(msp3400_ops)/ - sizeof(msp3400_ops[0]))) - 1; + ctxt->stale_mask = (1 << ARRAY_SIZE(msp3400_ops)) - 1; cp->handler = &ctxt->i2c_handler; - hdw->audio_stat = &ctxt->astat; pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x msp3400 V4L2 handler set up", cp->client->addr); return !0;