5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "pvrusb2-audio.h"
24 #include "pvrusb2-hdw-internal.h"
25 #include "pvrusb2-debug.h"
26 #include <linux/videodev2.h>
27 #include <media/msp3400.h>
28 #include <media/v4l2-common.h>
30 struct pvr2_msp3400_handler
{
32 struct pvr2_i2c_client
*client
;
33 struct pvr2_i2c_handler i2c_handler
;
34 struct pvr2_audio_stat astat
;
35 unsigned long stale_mask
;
39 /* This function selects the correct audio input source */
40 static void set_stereo(struct pvr2_msp3400_handler
*ctxt
)
42 struct pvr2_hdw
*hdw
= ctxt
->hdw
;
43 struct v4l2_routing route
;
45 pvr2_trace(PVR2_TRACE_CHIPS
,"i2c msp3400 v4l2 set_stereo");
47 if (hdw
->input_val
== PVR2_CVAL_INPUT_TV
) {
49 memset(&vt
,0,sizeof(vt
));
50 vt
.audmode
= hdw
->audiomode_val
;
51 pvr2_i2c_client_cmd(ctxt
->client
,VIDIOC_S_TUNER
,&vt
);
54 route
.input
= MSP_INPUT_DEFAULT
;
55 route
.output
= MSP_OUTPUT(MSP_SC_IN_DSP_SCART1
);
56 switch (hdw
->input_val
) {
57 case PVR2_CVAL_INPUT_TV
:
59 case PVR2_CVAL_INPUT_RADIO
:
60 /* Assume that msp34xx also handle FM decoding, in which case
61 we're still using the tuner. */
62 /* HV: actually it is more likely to be the SCART2 input if
63 the ivtv experience is any indication. */
64 route
.input
= MSP_INPUT(MSP_IN_SCART2
, MSP_IN_TUNER1
,
65 MSP_DSP_IN_SCART
, MSP_DSP_IN_SCART
);
67 case PVR2_CVAL_INPUT_SVIDEO
:
68 case PVR2_CVAL_INPUT_COMPOSITE
:
70 route
.input
= MSP_INPUT(MSP_IN_SCART1
, MSP_IN_TUNER1
,
71 MSP_DSP_IN_SCART
, MSP_DSP_IN_SCART
);
74 pvr2_i2c_client_cmd(ctxt
->client
,VIDIOC_INT_S_AUDIO_ROUTING
,&route
);
78 static int check_stereo(struct pvr2_msp3400_handler
*ctxt
)
80 struct pvr2_hdw
*hdw
= ctxt
->hdw
;
81 return (hdw
->input_dirty
||
82 hdw
->audiomode_dirty
);
86 struct pvr2_msp3400_ops
{
87 void (*update
)(struct pvr2_msp3400_handler
*);
88 int (*check
)(struct pvr2_msp3400_handler
*);
92 static const struct pvr2_msp3400_ops msp3400_ops
[] = {
93 { .update
= set_stereo
, .check
= check_stereo
},
97 static int msp3400_check(struct pvr2_msp3400_handler
*ctxt
)
102 for (idx
= 0; idx
< sizeof(msp3400_ops
)/sizeof(msp3400_ops
[0]);
105 if (ctxt
->stale_mask
& msk
) continue;
106 if (msp3400_ops
[idx
].check(ctxt
)) {
107 ctxt
->stale_mask
|= msk
;
110 return ctxt
->stale_mask
!= 0;
114 static void msp3400_update(struct pvr2_msp3400_handler
*ctxt
)
119 for (idx
= 0; idx
< sizeof(msp3400_ops
)/sizeof(msp3400_ops
[0]);
122 if (!(ctxt
->stale_mask
& msk
)) continue;
123 ctxt
->stale_mask
&= ~msk
;
124 msp3400_ops
[idx
].update(ctxt
);
129 /* This reads back the current signal type */
130 static int get_audio_status(struct pvr2_msp3400_handler
*ctxt
)
132 struct v4l2_tuner vt
;
135 memset(&vt
,0,sizeof(vt
));
136 stat
= pvr2_i2c_client_cmd(ctxt
->client
,VIDIOC_G_TUNER
,&vt
);
137 if (stat
< 0) return stat
;
139 ctxt
->hdw
->flag_stereo
= (vt
.audmode
& V4L2_TUNER_MODE_STEREO
) != 0;
140 ctxt
->hdw
->flag_bilingual
=
141 (vt
.audmode
& V4L2_TUNER_MODE_LANG2
) != 0;
146 static void pvr2_msp3400_detach(struct pvr2_msp3400_handler
*ctxt
)
148 ctxt
->client
->handler
= NULL
;
149 ctxt
->hdw
->audio_stat
= NULL
;
154 static unsigned int pvr2_msp3400_describe(struct pvr2_msp3400_handler
*ctxt
,
155 char *buf
,unsigned int cnt
)
157 return scnprintf(buf
,cnt
,"handler: pvrusb2-audio v4l2");
161 static const struct pvr2_i2c_handler_functions msp3400_funcs
= {
162 .detach
= (void (*)(void *))pvr2_msp3400_detach
,
163 .check
= (int (*)(void *))msp3400_check
,
164 .update
= (void (*)(void *))msp3400_update
,
165 .describe
= (unsigned int (*)(void *,char *,unsigned int))pvr2_msp3400_describe
,
169 int pvr2_i2c_msp3400_setup(struct pvr2_hdw
*hdw
,struct pvr2_i2c_client
*cp
)
171 struct pvr2_msp3400_handler
*ctxt
;
172 if (hdw
->audio_stat
) return 0;
173 if (cp
->handler
) return 0;
175 ctxt
= kmalloc(sizeof(*ctxt
),GFP_KERNEL
);
177 memset(ctxt
,0,sizeof(*ctxt
));
179 ctxt
->i2c_handler
.func_data
= ctxt
;
180 ctxt
->i2c_handler
.func_table
= &msp3400_funcs
;
183 ctxt
->astat
.ctxt
= ctxt
;
184 ctxt
->astat
.status
= (int (*)(void *))get_audio_status
;
185 ctxt
->astat
.detach
= (void (*)(void *))pvr2_msp3400_detach
;
186 ctxt
->stale_mask
= (1 << (sizeof(msp3400_ops
)/
187 sizeof(msp3400_ops
[0]))) - 1;
188 cp
->handler
= &ctxt
->i2c_handler
;
189 hdw
->audio_stat
= &ctxt
->astat
;
190 pvr2_trace(PVR2_TRACE_CHIPS
,"i2c 0x%x msp3400 V4L2 handler set up",
197 Stuff for Emacs to see, in order to encourage consistent editing style:
198 *** Local Variables: ***
200 *** fill-column: 70 ***
202 *** c-basic-offset: 8 ***