1/* 2 * cx18 audio-related functions 3 * 4 * Derived from ivtv-audio.c 5 * 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 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, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 21 * 02111-1307 USA 22 */ 23 24#include "cx18-driver.h" 25#include "cx18-io.h" 26#include "cx18-cards.h" 27#include "cx18-audio.h" 28 29#define CX18_AUDIO_ENABLE 0xc72014 30#define CX18_AI1_MUX_MASK 0x30 31#define CX18_AI1_MUX_I2S1 0x00 32#define CX18_AI1_MUX_I2S2 0x10 33#define CX18_AI1_MUX_843_I2S 0x20 34 35/* Selects the audio input and output according to the current 36 settings. */ 37int cx18_audio_set_io(struct cx18 *cx) 38{ 39 const struct cx18_card_audio_input *in; 40 u32 u, v; 41 int err; 42 43 /* Determine which input to use */ 44 if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) 45 in = &cx->card->radio_input; 46 else 47 in = &cx->card->audio_inputs[cx->audio_input]; 48 49 /* handle muxer chips */ 50 v4l2_subdev_call(cx->sd_extmux, audio, s_routing, 51 (u32) in->muxer_input, 0, 0); 52 53 err = cx18_call_hw_err(cx, cx->card->hw_audio_ctrl, 54 audio, s_routing, in->audio_input, 0, 0); 55 if (err) 56 return err; 57 58 /* FIXME - this internal mux should be abstracted to a subdev */ 59 u = cx18_read_reg(cx, CX18_AUDIO_ENABLE); 60 v = u & ~CX18_AI1_MUX_MASK; 61 switch (in->audio_input) { 62 case CX18_AV_AUDIO_SERIAL1: 63 v |= CX18_AI1_MUX_I2S1; 64 break; 65 case CX18_AV_AUDIO_SERIAL2: 66 v |= CX18_AI1_MUX_I2S2; 67 break; 68 default: 69 v |= CX18_AI1_MUX_843_I2S; 70 break; 71 } 72 if (v == u) { 73 /* force a toggle of some AI1 MUX control bits */ 74 u &= ~CX18_AI1_MUX_MASK; 75 switch (in->audio_input) { 76 case CX18_AV_AUDIO_SERIAL1: 77 u |= CX18_AI1_MUX_843_I2S; 78 break; 79 case CX18_AV_AUDIO_SERIAL2: 80 u |= CX18_AI1_MUX_843_I2S; 81 break; 82 default: 83 u |= CX18_AI1_MUX_I2S1; 84 break; 85 } 86 cx18_write_reg_expect(cx, u | 0xb00, CX18_AUDIO_ENABLE, 87 u, CX18_AI1_MUX_MASK); 88 } 89 cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE, 90 v, CX18_AI1_MUX_MASK); 91 return 0; 92} 93