pvrusb2-video-v4l.c revision ca545f7c39476c6c4c6e639452180a2b38342669
1/* 2 * 3 * $Id$ 4 * 5 * Copyright (C) 2005 Mike Isely <isely@pobox.com> 6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> 7 * 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 11 * 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. 16 * 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 20 * 21 */ 22 23/* 24 25 This source file is specifically designed to interface with the 26 saa711x support that is available in the v4l available starting 27 with linux 2.6.15. 28 29*/ 30 31#include "pvrusb2-video-v4l.h" 32#include "pvrusb2-i2c-cmd-v4l2.h" 33 34 35#include "pvrusb2-hdw-internal.h" 36#include "pvrusb2-debug.h" 37#include <linux/videodev2.h> 38#include <media/v4l2-common.h> 39#include <media/saa7115.h> 40#include <linux/errno.h> 41#include <linux/slab.h> 42 43struct pvr2_v4l_decoder { 44 struct pvr2_i2c_handler handler; 45 struct pvr2_decoder_ctrl ctrl; 46 struct pvr2_i2c_client *client; 47 struct pvr2_hdw *hdw; 48 unsigned long stale_mask; 49}; 50 51 52static void set_input(struct pvr2_v4l_decoder *ctxt) 53{ 54 struct pvr2_hdw *hdw = ctxt->hdw; 55 struct v4l2_routing route; 56 57 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_input(%d)",hdw->input_val); 58 switch(hdw->input_val) { 59 case PVR2_CVAL_INPUT_TV: 60 route.input = SAA7115_COMPOSITE4; 61 break; 62 case PVR2_CVAL_INPUT_COMPOSITE: 63 route.input = SAA7115_COMPOSITE5; 64 break; 65 case PVR2_CVAL_INPUT_SVIDEO: 66 route.input = SAA7115_SVIDEO2; 67 break; 68 case PVR2_CVAL_INPUT_RADIO: 69 // In radio mode, we mute the video, but point at one 70 // spot just to stay consistent 71 route.input = SAA7115_COMPOSITE5; 72 default: 73 return; 74 } 75 route.output = 0; 76 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route); 77} 78 79 80static int check_input(struct pvr2_v4l_decoder *ctxt) 81{ 82 struct pvr2_hdw *hdw = ctxt->hdw; 83 return hdw->input_dirty != 0; 84} 85 86 87static void set_audio(struct pvr2_v4l_decoder *ctxt) 88{ 89 u32 val; 90 struct pvr2_hdw *hdw = ctxt->hdw; 91 92 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_audio %d", 93 hdw->srate_val); 94 switch (hdw->srate_val) { 95 default: 96 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000: 97 val = 48000; 98 break; 99 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100: 100 val = 44100; 101 break; 102 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000: 103 val = 32000; 104 break; 105 } 106 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val); 107} 108 109 110static int check_audio(struct pvr2_v4l_decoder *ctxt) 111{ 112 struct pvr2_hdw *hdw = ctxt->hdw; 113 return hdw->srate_dirty != 0; 114} 115 116 117struct pvr2_v4l_decoder_ops { 118 void (*update)(struct pvr2_v4l_decoder *); 119 int (*check)(struct pvr2_v4l_decoder *); 120}; 121 122 123static const struct pvr2_v4l_decoder_ops decoder_ops[] = { 124 { .update = set_input, .check = check_input}, 125 { .update = set_audio, .check = check_audio}, 126}; 127 128 129static void decoder_detach(struct pvr2_v4l_decoder *ctxt) 130{ 131 ctxt->client->handler = NULL; 132 ctxt->hdw->decoder_ctrl = NULL; 133 kfree(ctxt); 134} 135 136 137static int decoder_check(struct pvr2_v4l_decoder *ctxt) 138{ 139 unsigned long msk; 140 unsigned int idx; 141 142 for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) { 143 msk = 1 << idx; 144 if (ctxt->stale_mask & msk) continue; 145 if (decoder_ops[idx].check(ctxt)) { 146 ctxt->stale_mask |= msk; 147 } 148 } 149 return ctxt->stale_mask != 0; 150} 151 152 153static void decoder_update(struct pvr2_v4l_decoder *ctxt) 154{ 155 unsigned long msk; 156 unsigned int idx; 157 158 for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) { 159 msk = 1 << idx; 160 if (!(ctxt->stale_mask & msk)) continue; 161 ctxt->stale_mask &= ~msk; 162 decoder_ops[idx].update(ctxt); 163 } 164} 165 166 167static int decoder_detect(struct pvr2_i2c_client *cp) 168{ 169 /* Attempt to query the decoder - let's see if it will answer */ 170 struct v4l2_tuner vt; 171 int ret; 172 173 memset(&vt,0,sizeof(vt)); 174 ret = pvr2_i2c_client_cmd(cp,VIDIOC_G_TUNER,&vt); 175 return ret == 0; /* Return true if it answered */ 176} 177 178 179static void decoder_enable(struct pvr2_v4l_decoder *ctxt,int fl) 180{ 181 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 decoder_enable(%d)",fl); 182 pvr2_v4l2_cmd_stream(ctxt->client,fl); 183} 184 185 186static unsigned int decoder_describe(struct pvr2_v4l_decoder *ctxt,char *buf,unsigned int cnt) 187{ 188 return scnprintf(buf,cnt,"handler: pvrusb2-video-v4l"); 189} 190 191 192static const struct pvr2_i2c_handler_functions hfuncs = { 193 .detach = (void (*)(void *))decoder_detach, 194 .check = (int (*)(void *))decoder_check, 195 .update = (void (*)(void *))decoder_update, 196 .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe, 197}; 198 199 200int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *hdw, 201 struct pvr2_i2c_client *cp) 202{ 203 struct pvr2_v4l_decoder *ctxt; 204 205 if (hdw->decoder_ctrl) return 0; 206 if (cp->handler) return 0; 207 if (!decoder_detect(cp)) return 0; 208 209 ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL); 210 if (!ctxt) return 0; 211 212 ctxt->handler.func_data = ctxt; 213 ctxt->handler.func_table = &hfuncs; 214 ctxt->ctrl.ctxt = ctxt; 215 ctxt->ctrl.detach = (void (*)(void *))decoder_detach; 216 ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable; 217 ctxt->client = cp; 218 ctxt->hdw = hdw; 219 ctxt->stale_mask = (1 << ARRAY_SIZE(decoder_ops)) - 1; 220 hdw->decoder_ctrl = &ctxt->ctrl; 221 cp->handler = &ctxt->handler; 222 pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x saa711x V4L2 handler set up", 223 cp->client->addr); 224 return !0; 225} 226 227 228 229 230/* 231 Stuff for Emacs to see, in order to encourage consistent editing style: 232 *** Local Variables: *** 233 *** mode: c *** 234 *** fill-column: 70 *** 235 *** tab-width: 8 *** 236 *** c-basic-offset: 8 *** 237 *** End: *** 238 */ 239