79 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * cx18 audio-related functions4 *5 * Derived from ivtv-audio.c6 *7 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>8 */9 10#include "cx18-driver.h"11#include "cx18-io.h"12#include "cx18-cards.h"13#include "cx18-audio.h"14 15#define CX18_AUDIO_ENABLE 0xc7201416#define CX18_AI1_MUX_MASK 0x3017#define CX18_AI1_MUX_I2S1 0x0018#define CX18_AI1_MUX_I2S2 0x1019#define CX18_AI1_MUX_843_I2S 0x2020 21/* Selects the audio input and output according to the current22 settings. */23int cx18_audio_set_io(struct cx18 *cx)24{25 const struct cx18_card_audio_input *in;26 u32 u, v;27 int err;28 29 /* Determine which input to use */30 if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))31 in = &cx->card->radio_input;32 else33 in = &cx->card->audio_inputs[cx->audio_input];34 35 /* handle muxer chips */36 v4l2_subdev_call(cx->sd_extmux, audio, s_routing,37 (u32) in->muxer_input, 0, 0);38 39 err = cx18_call_hw_err(cx, cx->card->hw_audio_ctrl,40 audio, s_routing, in->audio_input, 0, 0);41 if (err)42 return err;43 44 /* FIXME - this internal mux should be abstracted to a subdev */45 u = cx18_read_reg(cx, CX18_AUDIO_ENABLE);46 v = u & ~CX18_AI1_MUX_MASK;47 switch (in->audio_input) {48 case CX18_AV_AUDIO_SERIAL1:49 v |= CX18_AI1_MUX_I2S1;50 break;51 case CX18_AV_AUDIO_SERIAL2:52 v |= CX18_AI1_MUX_I2S2;53 break;54 default:55 v |= CX18_AI1_MUX_843_I2S;56 break;57 }58 if (v == u) {59 /* force a toggle of some AI1 MUX control bits */60 u &= ~CX18_AI1_MUX_MASK;61 switch (in->audio_input) {62 case CX18_AV_AUDIO_SERIAL1:63 u |= CX18_AI1_MUX_843_I2S;64 break;65 case CX18_AV_AUDIO_SERIAL2:66 u |= CX18_AI1_MUX_843_I2S;67 break;68 default:69 u |= CX18_AI1_MUX_I2S1;70 break;71 }72 cx18_write_reg_expect(cx, u | 0xb00, CX18_AUDIO_ENABLE,73 u, CX18_AI1_MUX_MASK);74 }75 cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,76 v, CX18_AI1_MUX_MASK);77 return 0;78}79