blob: cecc5e3a2638f5b49dade943d12e3db6b4a76de4 [file] [log] [blame]
# Copyright 2014 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Audio codec modules."""
import logging
import time
from chameleond.utils import i2c
from . import chameleon_common # pylint: disable=W0611, C0411
class CodecInput(object):
"""Available audio codec input options."""
NONE = "None"
MIC = "Mic"
LINEIN = "LineIn"
class CodecOutput(object):
"""Available audio codec output options."""
LINEOUT = "LineOut"
class AudioCodecException(Exception):
"""Exception raised when any error in AudioCodec."""
pass
class AudioCodec(i2c.I2cSlave):
"""A class to control SSM2603 audio codec on chameleon."""
SLAVE_ADDRESSES = (0x1A,)
def Initialize(self):
"""Runs the initialization sequence for the chip."""
if self._Enabled():
logging.info("Already enabled")
self._SelectInputNone()
return
logging.info("Initialize audio codec chip.")
self.Set(0x17, 0x0C) # power on clock, crystal, dac
self.Set(0x12, 0x08) # select dac, no line-in bypass
self.Set(0x00, 0x0A) # dac no mute
self.Set(0x00, 0x10) # SR=0000, 48k, MCLK/256
time.sleep(0.073) # 10.1uF on VMID, 73ms needed
self.Set(0x01, 0x12) # activate digital core
self.Set(0x07, 0x0C) # power on output
logging.info("Wait for audio codec chip to turn on...")
while not self._Enabled():
time.sleep(0.1)
logging.info("Audio codec chip turned on")
self._SelectInputNone()
def _Enabled(self):
"""Checks if codec is already enabled."""
return (self.Get(0x0C) & 0x80) == 0
def SelectInput(self, input_path):
"""Selects an input path.
By selecting an input path, codec will start recording data from that path
and output to CODEC input of AudioRouteController.
Args:
input_path: NONE, MIC, or LINEIN in CodecInput
Raises:
AudioCodecException if input_path is not valid.
"""
logging.info("Select codec input path to %r", input_path)
if not self._Enabled():
raise AudioCodecException("Codec is not initialized")
if input_path == CodecInput.NONE:
self._SelectInputNone()
elif input_path == CodecInput.MIC:
self._SelectInputMic()
elif input_path == CodecInput.LINEIN:
self._SelectInputLineIn()
else:
raise AudioCodecException("%s is not a valid input" % input_path)
def _SelectInputNone(self):
"""Disables recording from MIC nor LINEIN."""
logging.info("Select input to NONE on codec chip.")
self.Set(0x97, 0x00) # mute left linein
self.Set(0x97, 0x02) # mute right linein
self.Set(0x12, 0x08) # select linein
self.Set(0x07, 0x0C) # disable adc/mic/linein
def _SelectInputMic(self):
"""Starts recording from MIC."""
logging.info("Select input to MIC on codec chip.")
self.Set(0x97, 0x00) # mute left linein
self.Set(0x97, 0x02) # mute right linein
self.Set(0x14, 0x08) # select mic
self.Set(0x01, 0x0C) # enable adc and mic
def _SelectInputLineIn(self):
"""Starts recording from LINEIN."""
logging.info("Select input to LINEIN on codec chip.")
self.Set(0x17, 0x00) # enable left linein
self.Set(0x17, 0x02) # enable right linein
self.Set(0x12, 0x08) # select linein
self.Set(0x02, 0x0C) # enable adc and linein