cx18-audio.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * cx18 audio-related functions
  4. *
  5. * Derived from ivtv-audio.c
  6. *
  7. * Copyright (C) 2007 Hans Verkuil <[email protected]>
  8. */
  9. #include "cx18-driver.h"
  10. #include "cx18-io.h"
  11. #include "cx18-cards.h"
  12. #include "cx18-audio.h"
  13. #define CX18_AUDIO_ENABLE 0xc72014
  14. #define CX18_AI1_MUX_MASK 0x30
  15. #define CX18_AI1_MUX_I2S1 0x00
  16. #define CX18_AI1_MUX_I2S2 0x10
  17. #define CX18_AI1_MUX_843_I2S 0x20
  18. /* Selects the audio input and output according to the current
  19. settings. */
  20. int cx18_audio_set_io(struct cx18 *cx)
  21. {
  22. const struct cx18_card_audio_input *in;
  23. u32 u, v;
  24. int err;
  25. /* Determine which input to use */
  26. if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
  27. in = &cx->card->radio_input;
  28. else
  29. in = &cx->card->audio_inputs[cx->audio_input];
  30. /* handle muxer chips */
  31. v4l2_subdev_call(cx->sd_extmux, audio, s_routing,
  32. (u32) in->muxer_input, 0, 0);
  33. err = cx18_call_hw_err(cx, cx->card->hw_audio_ctrl,
  34. audio, s_routing, in->audio_input, 0, 0);
  35. if (err)
  36. return err;
  37. /* FIXME - this internal mux should be abstracted to a subdev */
  38. u = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
  39. v = u & ~CX18_AI1_MUX_MASK;
  40. switch (in->audio_input) {
  41. case CX18_AV_AUDIO_SERIAL1:
  42. v |= CX18_AI1_MUX_I2S1;
  43. break;
  44. case CX18_AV_AUDIO_SERIAL2:
  45. v |= CX18_AI1_MUX_I2S2;
  46. break;
  47. default:
  48. v |= CX18_AI1_MUX_843_I2S;
  49. break;
  50. }
  51. if (v == u) {
  52. /* force a toggle of some AI1 MUX control bits */
  53. u &= ~CX18_AI1_MUX_MASK;
  54. switch (in->audio_input) {
  55. case CX18_AV_AUDIO_SERIAL1:
  56. u |= CX18_AI1_MUX_843_I2S;
  57. break;
  58. case CX18_AV_AUDIO_SERIAL2:
  59. u |= CX18_AI1_MUX_843_I2S;
  60. break;
  61. default:
  62. u |= CX18_AI1_MUX_I2S1;
  63. break;
  64. }
  65. cx18_write_reg_expect(cx, u | 0xb00, CX18_AUDIO_ENABLE,
  66. u, CX18_AI1_MUX_MASK);
  67. }
  68. cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
  69. v, CX18_AI1_MUX_MASK);
  70. return 0;
  71. }