Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

 tas2552.c   Interaktion und
PortierbarkeitC

 

// SPDX-License-Identifier: GPL-2.0-only
/*
 * tas2552.c - ALSA SoC Texas Instruments TAS2552 Mono Audio Amplifier
 *
 * Copyright (C) 2014 - 2024 Texas Instruments Incorporated -
 * https://www.ti.com
 *
 * Author: Dan Murphy <dmurphy@ti.com>
 */


#include <linux/module.h>
#include <linux/errno.h>
#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/slab.h>

#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>

#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <sound/tas2552-plat.h>
#include <dt-bindings/sound/tas2552.h>

#include "tas2552.h"

static const struct reg_default tas2552_reg_defs[] = {
 {TAS2552_CFG_1, 0x22},
 {TAS2552_CFG_3, 0x80},
 {TAS2552_DOUT, 0x00},
 {TAS2552_OUTPUT_DATA, 0xc0},
 {TAS2552_PDM_CFG, 0x01},
 {TAS2552_PGA_GAIN, 0x00},
 {TAS2552_BOOST_APT_CTRL, 0x0f},
 {TAS2552_RESERVED_0D, 0xbe},
 {TAS2552_LIMIT_RATE_HYS, 0x08},
 {TAS2552_CFG_2, 0xef},
 {TAS2552_SER_CTRL_1, 0x00},
 {TAS2552_SER_CTRL_2, 0x00},
 {TAS2552_PLL_CTRL_1, 0x10},
 {TAS2552_PLL_CTRL_2, 0x00},
 {TAS2552_PLL_CTRL_3, 0x00},
 {TAS2552_BTIP, 0x8f},
 {TAS2552_BTS_CTRL, 0x80},
 {TAS2552_LIMIT_RELEASE, 0x04},
 {TAS2552_LIMIT_INT_COUNT, 0x00},
 {TAS2552_EDGE_RATE_CTRL, 0x40},
 {TAS2552_VBAT_DATA, 0x00},
};

#define TAS2552_NUM_SUPPLIES 3
static const char *tas2552_supply_names[TAS2552_NUM_SUPPLIES] = {
 "vbat",  /* vbat voltage */
 "iovdd", /* I/O Voltage */
 "avdd",  /* Analog DAC Voltage */
};

struct tas2552_data {
 struct snd_soc_component *component;
 struct regmap *regmap;
 struct i2c_client *tas2552_client;
 struct regulator_bulk_data supplies[TAS2552_NUM_SUPPLIES];
 struct gpio_desc *enable_gpio;
 unsigned char regs[TAS2552_VBAT_DATA];
 unsigned int pll_clkin;
 int pll_clk_id;
 unsigned int pdm_clk;
 int pdm_clk_id;

 unsigned int dai_fmt;
 unsigned int tdm_delay;
};

static int tas2552_post_event(struct snd_soc_dapm_widget *w,
         struct snd_kcontrol *kcontrol, int event)
{
 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);

 switch (event) {
 case SND_SOC_DAPM_POST_PMU:
  snd_soc_component_write(component, TAS2552_RESERVED_0D, 0xc0);
  snd_soc_component_update_bits(component, TAS2552_LIMIT_RATE_HYS, (1 << 5),
        (1 << 5));
  snd_soc_component_update_bits(component, TAS2552_CFG_2, 1, 0);
  snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_SWS, 0);
  break;
 case SND_SOC_DAPM_POST_PMD:
  snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_SWS,
        TAS2552_SWS);
  snd_soc_component_update_bits(component, TAS2552_CFG_2, 1, 1);
  snd_soc_component_update_bits(component, TAS2552_LIMIT_RATE_HYS, (1 << 5), 0);
  snd_soc_component_write(component, TAS2552_RESERVED_0D, 0xbe);
  break;
 }
 return 0;
}

/* Input mux controls */
static const char * const tas2552_input_texts[] = {
 "Digital", "Analog" };
static SOC_ENUM_SINGLE_DECL(tas2552_input_mux_enum, TAS2552_CFG_3, 7,
       tas2552_input_texts);

static const struct snd_kcontrol_new tas2552_input_mux_control =
 SOC_DAPM_ENUM("Route", tas2552_input_mux_enum);

static const struct snd_soc_dapm_widget tas2552_dapm_widgets[] =
{
 SND_SOC_DAPM_INPUT("IN"),

 /* MUX Controls */
 SND_SOC_DAPM_MUX("Input selection", SND_SOC_NOPM, 0, 0,
    &tas2552_input_mux_control),

 SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0),
 SND_SOC_DAPM_AIF_OUT("ASI OUT", "DAC Capture", 0, SND_SOC_NOPM, 0, 0),
 SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
 SND_SOC_DAPM_OUT_DRV("ClassD", TAS2552_CFG_2, 7, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("PLL", TAS2552_CFG_2, 3, 0, NULL, 0),
 SND_SOC_DAPM_POST("Post Event", tas2552_post_event),

 SND_SOC_DAPM_OUTPUT("OUT"),
 SND_SOC_DAPM_INPUT("DMIC")
};

static const struct snd_soc_dapm_route tas2552_audio_map[] = {
 {"DAC", NULL, "DAC IN"},
 {"Input selection", "Digital", "DAC"},
 {"Input selection", "Analog", "IN"},
 {"ClassD", NULL, "Input selection"},
 {"OUT", NULL, "ClassD"},
 {"ClassD", NULL, "PLL"},
 {"ASI OUT", NULL, "DMIC"}
};

static void tas2552_sw_shutdown(struct tas2552_data *tas2552, int sw_shutdown)
{
 u8 cfg1_reg = 0;

 if (!tas2552->component)
  return;

 if (sw_shutdown)
  cfg1_reg = TAS2552_SWS;

 snd_soc_component_update_bits(tas2552->component, TAS2552_CFG_1, TAS2552_SWS,
       cfg1_reg);
}

static int tas2552_setup_pll(struct snd_soc_component *component,
        struct snd_pcm_hw_params *params)
{
 struct tas2552_data *tas2552 = dev_get_drvdata(component->dev);
 bool bypass_pll = false;
 unsigned int pll_clk = params_rate(params) * 512;
 unsigned int pll_clkin = tas2552->pll_clkin;
 u8 pll_enable;

 if (!pll_clkin) {
  if (tas2552->pll_clk_id != TAS2552_PLL_CLKIN_BCLK)
   return -EINVAL;

  pll_clkin = snd_soc_params_to_bclk(params);
  pll_clkin += tas2552->tdm_delay;
 }

 pll_enable = snd_soc_component_read(component, TAS2552_CFG_2) & TAS2552_PLL_ENABLE;
 snd_soc_component_update_bits(component, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0);

 if (pll_clkin == pll_clk)
  bypass_pll = true;

 if (bypass_pll) {
  /* By pass the PLL configuration */
  snd_soc_component_update_bits(component, TAS2552_PLL_CTRL_2,
        TAS2552_PLL_BYPASS, TAS2552_PLL_BYPASS);
 } else {
  /* Fill in the PLL control registers for J & D
   * pll_clk = (.5 * pll_clkin * J.D) / 2^p
   * Need to fill in J and D here based on incoming freq
 */

  unsigned int d, q, t;
  u8 j;
  u8 pll_sel = (tas2552->pll_clk_id << 3) & TAS2552_PLL_SRC_MASK;
  u8 p = snd_soc_component_read(component, TAS2552_PLL_CTRL_1);

  p = (p >> 7);

recalc:
  t = (pll_clk * 2) << p;
  j = t / pll_clkin;
  d = t % pll_clkin;
  t = pll_clkin / 10000;
  q = d / (t + 1);
  d = q + ((9999 - pll_clkin % 10000) * (d / t - q)) / 10000;

  if (d && (pll_clkin < 512000 || pll_clkin > 9200000)) {
   if (tas2552->pll_clk_id == TAS2552_PLL_CLKIN_BCLK) {
    pll_clkin = 1800000;
    pll_sel = (TAS2552_PLL_CLKIN_1_8_FIXED << 3) &
       TAS2552_PLL_SRC_MASK;
   } else {
    pll_clkin = snd_soc_params_to_bclk(params);
    pll_clkin += tas2552->tdm_delay;
    pll_sel = (TAS2552_PLL_CLKIN_BCLK << 3) &
       TAS2552_PLL_SRC_MASK;
   }
   goto recalc;
  }

  snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_PLL_SRC_MASK,
        pll_sel);

  snd_soc_component_update_bits(component, TAS2552_PLL_CTRL_1,
        TAS2552_PLL_J_MASK, j);
  /* Will clear the PLL_BYPASS bit */
  snd_soc_component_write(component, TAS2552_PLL_CTRL_2,
         TAS2552_PLL_D_UPPER(d));
  snd_soc_component_write(component, TAS2552_PLL_CTRL_3,
         TAS2552_PLL_D_LOWER(d));
 }

 /* Restore PLL status */
 snd_soc_component_update_bits(component, TAS2552_CFG_2, TAS2552_PLL_ENABLE,
       pll_enable);

 return 0;
}

static int tas2552_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params,
        struct snd_soc_dai *dai)
{
 struct snd_soc_component *component = dai->component;
 struct tas2552_data *tas2552 = dev_get_drvdata(component->dev);
 int cpf;
 u8 ser_ctrl1_reg, wclk_rate;

 switch (params_width(params)) {
 case 16:
  ser_ctrl1_reg = TAS2552_WORDLENGTH_16BIT;
  cpf = 32 + tas2552->tdm_delay;
  break;
 case 20:
  ser_ctrl1_reg = TAS2552_WORDLENGTH_20BIT;
  cpf = 64 + tas2552->tdm_delay;
  break;
 case 24:
  ser_ctrl1_reg = TAS2552_WORDLENGTH_24BIT;
  cpf = 64 + tas2552->tdm_delay;
  break;
 case 32:
  ser_ctrl1_reg = TAS2552_WORDLENGTH_32BIT;
  cpf = 64 + tas2552->tdm_delay;
  break;
 default:
  dev_err(component->dev, "Not supported sample size: %d\n",
   params_width(params));
  return -EINVAL;
 }

 if (cpf <= 32)
  ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_32;
 else if (cpf <= 64)
  ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_64;
 else if (cpf <= 128)
  ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_128;
 else
  ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_256;

 snd_soc_component_update_bits(component, TAS2552_SER_CTRL_1,
       TAS2552_WORDLENGTH_MASK | TAS2552_CLKSPERFRAME_MASK,
       ser_ctrl1_reg);

 switch (params_rate(params)) {
 case 8000:
  wclk_rate = TAS2552_WCLK_FREQ_8KHZ;
  break;
 case 11025:
 case 12000:
  wclk_rate = TAS2552_WCLK_FREQ_11_12KHZ;
  break;
 case 16000:
  wclk_rate = TAS2552_WCLK_FREQ_16KHZ;
  break;
 case 22050:
 case 24000:
  wclk_rate = TAS2552_WCLK_FREQ_22_24KHZ;
  break;
 case 32000:
  wclk_rate = TAS2552_WCLK_FREQ_32KHZ;
  break;
 case 44100:
 case 48000:
  wclk_rate = TAS2552_WCLK_FREQ_44_48KHZ;
  break;
 case 88200:
 case 96000:
  wclk_rate = TAS2552_WCLK_FREQ_88_96KHZ;
  break;
 case 176400:
 case 192000:
  wclk_rate = TAS2552_WCLK_FREQ_176_192KHZ;
  break;
 default:
  dev_err(component->dev, "Not supported sample rate: %d\n",
   params_rate(params));
  return -EINVAL;
 }

 snd_soc_component_update_bits(component, TAS2552_CFG_3, TAS2552_WCLK_FREQ_MASK,
       wclk_rate);

 return tas2552_setup_pll(component, params);
}

#define TAS2552_DAI_FMT_MASK (TAS2552_BCLKDIR | \
     TAS2552_WCLKDIR | \
     TAS2552_DATAFORMAT_MASK)
static int tas2552_prepare(struct snd_pcm_substream *substream,
      struct snd_soc_dai *dai)
{
 struct snd_soc_component *component = dai->component;
 struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
 int delay = 0;

 /* TDM slot selection only valid in DSP_A/_B mode */
 if (tas2552->dai_fmt == java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 2
   + 1)java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
  if(tas2552> =SND_SOC_DAIFMT_DSP_B)
  delay += tas2552->tdm_delay;

 /* Configure data delay */
 snd_soc_component_write(component, TAS2552_SER_CTRL_2, delay);

 return 0;
}

static int tas2552_set_dai_fmth
java.lang.StringIndexOutOfBoundsException: Range [1, 2) out of bounds for length 1
 structjava.lang.StringIndexOutOfBoundsException: Range [27, 25) out of bounds for length 54
structtas2552_data tas2552=java.lang.StringIndexOutOfBoundsException: Range [48, 47) out of bounds for length 64
u ;

 java.lang.StringIndexOutOfBoundsException: Range [32, 7) out of bounds for length 52
 TAS2552_SER_CTRL_2,0,
  serial_format = 0x00;
  break;
  SND_SOC_DAIFMT_CBC_CFP
 java.lang.StringIndexOutOfBoundsException: Range [18, 15) out of bounds for length 34

 caseTAS2552_LIMIT_INT_COUNT,0,
  serial_format = TAS2552_BCLKDIR;
 break;
 case SND_SOC_DAIFMT_CBP_CFP:
  serial_format = (TAS2552_BCLKDIR | TAS2552_WCLKDIR;
 java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
 "" / java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 28
  dev_vdbg;
r EINVAL;
 }

 switch (fmt & (struct regmap *regmap
         SND_SOC_DAIFMT_INV_MASK){
 case (SND_SOC_DAIFMT_I2S | struct regulator_bulk_data supplies[TAS2552_NUM_SUPPLIES];
 java.lang.StringIndexOutOfBoundsException: Range [8, 9) out of bounds for length 8
 nt pll_clk_id;
 case (SND_SOC_DAIFMT_DSP_B |  pdm_clk_id
  serial_format |unsignedinttdm_delay
  ;
 Sjava.lang.StringIndexOutOfBoundsException: Range [32, 29) out of bounds for length 54
=;
  break;
 case (SND_SOC_DAIFMT_LEFT_Jjava.lang.StringIndexOutOfBoundsException: Range [52, 51) out of bounds for length 53
 serial_format | java.lang.StringIndexOutOfBoundsException: Range [45, 44) out of bounds for length 45
  break;
 default:
 java.lang.StringIndexOutOfBoundsException: Range [11, 10) out of bounds for length 56
  -java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
 }
 tas2552->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;

 snd_soc_component_update_bits( TAS2552_SER_CTRL_1component,, AS2552_SWS,
 );
  0;
}

static int tas2552_set_dai_sysclk(struct snd_soc_component_write(component, TAS2552_RESERVED_0D, 0xbe);
  intfreq,int dir
{
 structsnd_soc_component *=dai-component;
 struct tas2552_data *tas2552 = dev_get_drvdata"","nalog };
 u8reg,mask, ;

 switch (clk_id) {
LK:
  TAS2552_PLL_CLKIN_IVCLKIN:
   SOC_DAPM_ENUM("Route",)java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
  /
   dev_warn(component->dev
 (Input , SND_SOC_NOPM,0,0,
  clk_id =
  0;
  java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
  ;
 casejava.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 29
 OUT)
 =java.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 30
  val {" ,"java.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 25
  reg ={,","IN}java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
 tas2552> = ;
 tas2552-pll_clkin freq
 break
 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 case java.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 30
 case TAS2552_PDM_CLK_BCLK:
 casejava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
  mask =java.lang.StringIndexOutOfBoundsException: Range [36, 35) out of bounds for length 50
  val l_enable
  java.lang.StringIndexOutOfBoundsException: Range [18, 5) out of bounds for length 24
  tas2552-pdm_clk_id=clk_id;
   returnEINVAL;
   ;
 defaultjava.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
 );
  return -EINVAL;
 }

 snd_soc_component_update_bits(component, reg, mask, java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 20

 return snd_soc_component_update_bitscomponent, TAS2552_PLL_CTRL_2
}

static java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
   unsigned int   rx_mask,
        int slots, int slot_width)
{
 struct snd_soc_component *component = dai->component;
 struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
 unsigned int lsb;

 if (unlikely(!tx_mask)) {
  dev_err(component->dev, "tx masks need to be non 0\n") * Need tofill Dhere onincoming freq
  return -EINVAL;
 }

 /* TDM based on DSP mode requires slots to be adjacent */
 lsb = __ffs(tx_mask);
 if ((lsb + 1) != __fls(tx_mask)) {
  dev_err(component->dev, "Invalid mask, slots must be adjacent\n");
  return -EINVAL;
 }

 tas2552->tdm_delay = lsb * slot_width;

 /* DOUT in high-impedance on inactive bit clocks */
 snd_soc_component_update_bits(component, TAS2552_DOUT,
       TAS2552_SDOUT_TRISTATE, TAS2552_SDOUT_TRISTATE);

 return 0;
}

static int tas2552_mute(struct snd_soc_dai *dai, int mute, int direction)
{
 u8 cfg1_reg = 0;
 struct snd_soc_component *component = dai->component;

 if (mute)
  cfg1_reg |= TAS2552_MUTE;

 snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_MUTE, cfg1_reg);

 return 0;
}

static int tas2552_runtime_suspend(struct device *dev)
{
 struct tas2552_data *tas2552 = dev_get_drvdata(dev);

 tas2552_sw_shutdown(tas2552, 1);

 regcache_cache_only(tas2552->regmap, true);
 regcache_mark_dirty(tas2552->regmap);

 gpiod_set_value(tas2552->enable_gpio, 0);

 return 0;
}

static int tas2552_runtime_resume(struct device *dev)
{
 struct tas2552_data *tas2552 = dev_get_drvdata(dev);

 gpiod_set_value(tas2552->enable_gpio, 1);

 tas2552_sw_shutdown(tas2552, 0);

 regcache_cache_only(tas2552->regmap, false);
 regcache_sync(tas2552->regmap);

 return 0;
}

static const struct dev_pm_ops tas2552_pm = {
 RUNTIME_PM_OPS(tas2552_runtime_suspend, tas2552_runtime_resume, NULL)
};

static const struct snd_soc_dai_ops tas2552_speaker_dai_ops = {
 .hw_params = tas2552_hw_params,
 .prepare = tas2552_prepare,
 .set_sysclk = tas2552_set_dai_sysclk,
 .set_fmt = tas2552_set_dai_fmt,
 .set_tdm_slot = tas2552_set_dai_tdm_slot,
 .mute_stream = tas2552_mute,
 .no_capture_mute = 1,
};

/* Formats supported by TAS2552 driver. */
#define TAS2552_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
    SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)

/* TAS2552 dai structure. */
static struct snd_soc_dai_driver tas2552_dai[] = {
 {
  .name = "tas2552-amplifier",
  .playback = {
   .stream_name = "Playback",
   .channels_min = 2,
   .channels_max = 2,
   .rates = SNDRV_PCM_RATE_8000_192000,
   .formats = TAS2552_FORMATS,
  },
  .capture = {
   .stream_name = "Capture",
   .channels_min = 2,
   .channels_max = 2,
   .rates = SNDRV_PCM_RATE_8000_192000,
   .formats = TAS2552_FORMATS,
  },
  .ops = &tas2552_speaker_dai_ops,
 },
};

/*
 * DAC digital volumes. From -7 to 24 dB in 1 dB steps
 */

static DECLARE_TLV_DB_SCALE(dac_tlv, -700, 100, 0);

static const char * const tas2552_din_source_select[] = {
 "Muted",
 "Left",
 "Right",
 ",
}
static SOC_ENUM_SINGLE_DECL(java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 0
       java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
       struct tas2552_data *tas2552snd_soc_component_get_drvdata(component)

static java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
("Speaker Driver Playback Volume",
    TAS2552_PGA_GAIN, 0, 0x1f, 0, dac_tlv),
 SOC_ENUM(DIN source" )java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
};

static int /* Configure data delay */
{
 struct java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 10
iret;

 tas2552->component = component;

 ->supplies),
        tas2552->supplies structtas2552_data tas2552 = ev_get_drvdatacomponent->;

  ret ! ){
  dev_err(component->dev, "Failed to enable supplies:
 ret)java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
   ret;
 }

 java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 8

 ret = pm_runtime_resume_and_get(component->dev);
 if  ase SND_SOC_DAIFMT_CBP_CFC:
 dev_err(omponent->ev "nabling failed:%\n"java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
  ret;
  goto probe_fail;
 }

  dev_vdbg(component>dev,"DAI Format masterisnot\n";
snd_soc_component_writecomponent, TAS2552_CFG_3 TAS2552_I2S_OUT_SEL java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72
         TAS2552_DIN_SRC_SEL_AVG_L_R);
 snd_soc_component_write(component, TAS2552_OUTPUT_DATA,
        TAS2552_PDM_DATA_SEL_V_I |
        TAS2552_R_DATA_OUT(TAS2552_DATA_OUT_V_DATA));
 snd_soc_component_write(component, TAS2552_BOOST_APT_CTRL, TAS2552_APT_DELAY_200 |
           TAS2552_APT_THRESH_20_17);

 snd_soc_component_write(component, TAS2552_CFG_2, TAS2552_BOOST_EN | TAS2552_APT_EN |
         TAS2552_LIM_EN);

 return 0;

probe_fail:
 pm_runtime_put_noidle(component->dev);
 gpiod_set_value(tas2552->enable_gpio, 0);

 regulator_bulk_disable(ARRAY_SIZE(tas2552->supplies),
     tas2552->supplies);
 return ret;
}

static void tas2552_component_remove
{
 struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);

 pm_runtime_put(component->dev);

 gpiod_set_value(tas2552->enable_gpio, 0);
};

#ifdef CONFIG_PM
static int tas2552_suspend(struct snd_soc_component *component)
{
 struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
 int ret;

 ret = regulator_bulk_disable(ARRAY_SIZE(tas2552->supplies),
     tas2552->supplies);

 if (ret != 0)
  dev_err(component->dev, "Failed to disable supplies: %d\n",
   ret);
 return ret;
}

static int tas2552_resume(struct snd_soc_component *component)
{
 struct tas2552_data *tas2552 = java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 37
int ret;

 ret = ret = devm_snd_soc_register_component(&client->dev,
        tas2552->supplies);

 if (ret != 0) {
  dev_err(component->dev, "Failed to enable supplies: %d\n",
   ret);
 }

 return ret;
}
#else
#define tas2552_suspend NULL
#define tas2552_resume NULL
#endif

static const struct snd_soc_component_driver soc_component_dev_tas2552 = {
 .probe   = tas2552_component_probe,
 .remove   = tas2552_component_remove,
 .suspend  = tas2552_suspend,
 .resume   = tas2552_resume,
 .controls  =        &soc_component_dev_tas255
 num_controls  = java.lang.StringIndexOutOfBoundsException: Range [18, 28) out of bounds for length 15
 .dapm_widgets  =   (client>ev);
 .num_dapm_widgets = ARRAY_SIZE(tas2552_dapm_widgets),
 .dapm_routes  = tas2552_audio_map,
 .num_dapm_routes = java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 0
 .idle_bias_on  = 1,
 .endianness  = 1,
};

static const struct regmap_config tas2552_regmap_config = {
 .reg_bits = 8,
 .val_bits = 8,

 .max_register = TAS2552_MAX_REG,
 .reg_defaults = tas2552_reg_defs,
 .num_reg_defaults = ARRAY_SIZE(tas2552_reg_defs),
 .cache_type = REGCACHE_RBTREE,
};

static int tas2552_probe(struct i2c_client *client)
{
 struct 
 struct tas2552_data *data;
  ret
 int i{

 dev = &client->dev;
 data = devm_kzalloc(&client->dev, sizeof( pm_runtime_disable(client-d;
 if (data == NULL)
  returnjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

 data->enable_gpio = devm_gpiod_get_optional(dev, "enable",
        GPIOD_OUT_LOW;
 if (IS_ERR(data->enable_gpio))
    }

 data->tas2552_client = MODULE_DEVICE_TABLE(i2c, tas255id)java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
 data->regmap = devm_regmap_init_i2cstaticconst   tas2552_of_match[  {
 if.compatible ="i,,}java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
  ret = PTR_ERR(of,java.lang.StringIndexOutOfBoundsException: Range [41, 40) out of bounds for length 42
  dev_err(&client->static struct i2c_driver tas2552_i2c_driver = {
   ret);
   ret;
 }

 for(  ; iARRAY_SIZE(ata>); +)
  data->supplies[i]. pm= pm_ptr(tas2552_pm,

 ret = devm_regulator_bulk_get(dev, 
          data->supplies);
 if (.probe = tas2552_probe
 ( Failedtorequestsuppliesdn,ret);
  return ret;
 }

 pm_runtime_set_active(&client->dev);
 pm_runtime_set_autosuspend_delay
 pm_runtime_use_autosuspend&-dev)java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
 pm_runtime_enable(&client->dev);
 pm_runtime_put_sync_autosuspend(&client->dev);

 ev_set_drvdata(client->ev data);

 ret = devm_snd_soc_register_componentMODULE_LICENSE(GPL");
          &soc_component_dev_tas2552,
          tas2552_dai, ARRAY_SIZE(tas2552_dai));
 if (ret < 0) {
  dev_err(&client->dev, "Failed to register component: %d\n", ret);
  pm_runtime_get_noresume(&client->dev);
 }

 return ret;
}

static void tas2552_i2c_remove(struct i2c_client *client)
{
 pm_runtime_disable(&client->dev);
}

static const struct i2c_device_id tas2552_id[] = {
 { "tas2552" },
 { }
};
MODULE_DEVICE_TABLE(i2c, tas2552_id);

#if IS_ENABLED(CONFIG_OF)
static const struct of_device_id tas2552_of_match[] = {
 { .compatible = "ti,tas2552", },
 {},
};
MODULE_DEVICE_TABLE(of, tas2552_of_match);
#endif

static struct i2c_driver tas2552_i2c_driver = {
 .driver = {
  .name = "tas2552",
  .of_match_table = of_match_ptr(tas2552_of_match),
  .pm = pm_ptr(&tas2552_pm),
 },
 .probe = tas2552_probe,
 .remove = tas2552_i2c_remove,
 .id_table = tas2552_id,
};

module_i2c_driver(tas2552_i2c_driver);

MODULE_AUTHOR("Dan Muprhy <dmurphy@ti.com>");
MODULE_DESCRIPTION("TAS2552 Audio amplifier driver");
MODULE_LICENSE("GPL");

Messung V0.5 in Prozent
C=98 H=98 G=97

¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.108Angebot  (Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-10-14) ¤

*Eine klare Vorstellung vom Zielzustand






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

letze Version des Elbe Quellennavigators


Jenseits des Üblichen ....
    

Besucher

Besucher

Statistik
#Sources=234370
#Domains=75368