piSmasher Configuration Libraries
piSmasher peripheral device configuration libraries

Functions

int tda998x_aud_set_port_enable (struct tda998x_dev *dev, uint8_t en)
 Set Audio Port Enable. More...
 
int tda998x_aud_set_clk_enable (struct tda998x_dev *dev, uint8_t en)
 Set Audio Clock Port Enable. More...
 
int tda998x_aud_reset_cts (struct tda998x_dev *dev)
 Reset Audio CTS. More...
 
static int tda998x_aud_set_config (struct tda998x_dev *dev, enum tda998x_aud_fmt aud_fmt, enum tda998x_aud_i2s_fmt i2s_fmt, uint8_t i2s_chan, uint8_t dsd_chan, enum tda998x_clkpol_dsd dsd_clkpol, enum tda998x_swap_dsd dsd_swap, uint8_t layout, uint16_t latency, enum tda998x_dst_rate dst_rate)
 Set Audio Input Configuration. More...
 
static int tda998x_aud_set_cts (struct tda998x_dev *dev, enum tda998x_cts_ref cts_ref, enum tda998x_aud_rate afs, enum tda998x_vid_fmt vout_fmt, enum tda998x_vert_freq vout_freq, uint32_t cts, uint16_t ctsX, enum tda998x_ctsk ctsK, enum tda998x_ctsm ctsM, enum tda998x_dst_rate dst_rate)
 Set Audio CTS. More...
 
static int tda998x_aud_set_chan_status (struct tda998x_dev *dev, uint8_t pcm_id, uint8_t fmt_info, uint8_t copyright, uint8_t categoryCode, enum tda998x_aud_rate samp_freq, uint8_t clk_acc, uint8_t maxword_len, uint8_t word_len, uint8_t origsamp_freq)
 Set Audio Output Channel Status. More...
 
static int tda998x_aud_set_chan_status_mapping (struct tda998x_dev *dev, uint8_t src_left[4], uint8_t chan_left[4], uint8_t src_right[4], uint8_t chan_right[4])
 Set Audio Channel Status Mapping. More...
 
static int tda998x_aud_set_mute (struct tda998x_dev *dev, bool mute)
 Set Audio Mute. More...
 
int tda998x_aud_set_input (struct tda998x_dev *dev, struct tda998x_audin_cfg *audin_cfg)
 

Detailed Description

Function Documentation

◆ tda998x_aud_reset_cts()

int tda998x_aud_reset_cts ( struct tda998x_dev dev)

#include <projects/lib/tda998x.c>

Reset Audio CTS.

Todo:
Finish register mask write sequence to reset CTS
Parameters
devTDA998x device structure pointer
Returns
0 on success, non-zero error status otherwise
Todo:
Define reset register table
1974 {
1975  /* Reset and release the CTS generator */
1979 // return write_reg_mask_table(dev, &kResetCtsGenerator[0]);
1980  return 0;
1981 }

◆ tda998x_aud_set_chan_status()

static int tda998x_aud_set_chan_status ( struct tda998x_dev dev,
uint8_t  pcm_id,
uint8_t  fmt_info,
uint8_t  copyright,
uint8_t  categoryCode,
enum tda998x_aud_rate  samp_freq,
uint8_t  clk_acc,
uint8_t  maxword_len,
uint8_t  word_len,
uint8_t  origsamp_freq 
)
static

#include <projects/lib/tda998x.c>

Set Audio Output Channel Status.

Parameters
devTDA998x device structure pointer
Returns
0 on success, non-zero error status otherwise
2354 {
2355  int ret;
2356  uint8_t buf[4];
2357  const uint8_t freq[] = {
2358  3, /* 32k */
2359  0, /* 44.1k */
2360  2, /* 48k */
2361  8, /* 88.2k */
2362  10, /* 96k */
2363  12, /* 176.4k */
2364  14, /* 192k */
2365  9, /* 768k */
2366  1, /* Not indicated */
2367  };
2368 
2369  /* Return if sink is not an HDMI device */
2370  if (dev->sink != SINK_HDMI)
2371  return ERR_NOT_PERMITTED;
2372 
2373  buf[0] = ((uint8_t) fmt_info << 3) |
2374  ((uint8_t) copyright << 2) |
2375  ((uint8_t) pcm_id << 1);
2376  buf[1] = categoryCode;
2377  buf[2] = ((uint8_t) clk_acc << 4) | freq[samp_freq];
2378  buf[3] = ((uint8_t) origsamp_freq << 4) |
2379  ((uint8_t) word_len << 1) |
2380  (uint8_t) maxword_len;
2381 
2382  /* Write 4 Channel Status bytes */
2383  ret = tda998x_write(dev, CH_STAT_B_0, 4, &buf[0]);
2384  if (ret < 0)
2385  return ret;
2386 
2387  return 0;
2388 }
static int tda998x_write(struct tda998x_dev *dev, enum tda998x_hdmi_reg reg, uint8_t len, uint8_t *data)
Write Data.
Definition: tda998x.c:1247
Definition: tda998x.h:65

◆ tda998x_aud_set_chan_status_mapping()

static int tda998x_aud_set_chan_status_mapping ( struct tda998x_dev dev,
uint8_t  src_left[4],
uint8_t  chan_left[4],
uint8_t  src_right[4],
uint8_t  chan_right[4] 
)
static

#include <projects/lib/tda998x.c>

Set Audio Channel Status Mapping.

Parameters
devTDA998x device structure pointer
src_leftLeft channel source
chan_leftLeft channel output
src_rightRight channel source
chan_rightRight channel output
Returns
0 on success, non-zero error status otherwise
2406 {
2407  int ret;
2408  uint8_t buf[2];
2409 
2410  if (dev->sink != SINK_HDMI)
2411  return ERR_NOT_PERMITTED;
2412 
2413  buf[0] = (chan_left[0] << 4) | (src_left[0] & 0xFF);
2414  buf[1] = (chan_right[0] << 4) | (src_right[0] & 0xFF);
2415 
2416  ret = tda998x_write(dev, CH_STAT_B_2_AP0_L, 2, &buf[0]);
2417  if (ret < 0)
2418  return ret;
2419 
2420  return 0;
2421 }
static int tda998x_write(struct tda998x_dev *dev, enum tda998x_hdmi_reg reg, uint8_t len, uint8_t *data)
Write Data.
Definition: tda998x.c:1247
Definition: tda998x.h:65

◆ tda998x_aud_set_clk_enable()

int tda998x_aud_set_clk_enable ( struct tda998x_dev dev,
uint8_t  en 
)

#include <projects/lib/tda998x.c>

Set Audio Clock Port Enable.

Parameters
devTDA998x device structure pointer
enClock port enable register value
Returns
0 on success, non-zero error status otherwise
1951 {
1952  int ret;
1953 
1954  /* Check parameter */
1955  if (dev == NULL)
1956  return ERR_NULL_PARAM;
1957 
1958  ret = write_reg(dev, ENA_ACLK, en);
1959  if (ret < 0)
1960  return ret;
1961 
1962  return 0;
1963 }
static int write_reg(struct tda998x_dev *dev, enum tda998x_hdmi_reg reg, uint8_t data)
Write Register.
Definition: tda998x.c:1283

◆ tda998x_aud_set_config()

static int tda998x_aud_set_config ( struct tda998x_dev dev,
enum tda998x_aud_fmt  aud_fmt,
enum tda998x_aud_i2s_fmt  i2s_fmt,
uint8_t  i2s_chan,
uint8_t  dsd_chan,
enum tda998x_clkpol_dsd  dsd_clkpol,
enum tda998x_swap_dsd  dsd_swap,
uint8_t  layout,
uint16_t  latency,
enum tda998x_dst_rate  dst_rate 
)
static

#include <projects/lib/tda998x.c>

Set Audio Input Configuration.

Parameters
devTDA998x device structure pointer
Returns
0 on success, non-zero error status otherwise
2000 {
2001  int ret;
2002  uint8_t reg_val;
2003 
2004  switch (aud_fmt) {
2005  case AFMT_SPDIF:
2006  reg_val = (uint8_t) REG_VAL_SEL_AIP_SPDIF;
2007 
2008  /* configure MUX_AP */
2009  ret = write_reg(dev, MUX_AP, MUX_AP_SELECT_SPDIF);
2010  if (ret < 0)
2011  return ret;
2012 
2013  break;
2014 
2015  case AFMT_I2S:
2016  reg_val = (uint8_t) REG_VAL_SEL_AIP_I2S;
2017 
2018  /* configure MUX_AP */
2019  ret = write_reg(dev, MUX_AP, MUX_AP_SELECT_I2S);
2020  if (ret < 0)
2021  return ret;
2022 
2023  break;
2024 
2025  case AFMT_OBA:
2026  reg_val = (uint8_t) REG_VAL_SEL_AIP_OBA;
2027  break;
2028 
2029  case AFMT_HBR:
2030  reg_val = (uint8_t) REG_VAL_SEL_AIP_HBR;
2031  break;
2032 
2033  default:
2034  return ERR_BAD_PARAM;
2035  }
2036 
2037  /* Set the audio input processor format to aud_fmt. AIP_CLKSEL_sel_aip */
2038  ret = write_reg_mask(dev, AIP_CLKSEL, 0x38U, reg_val << 3);
2039  if (ret < 0)
2040  return ret;
2041 
2042  /* Channel status on 1 channel */
2043  ret = write_reg_mask(dev, CA_I2S, CA_I2S_HBR_CHSTAT_4, 0);
2044  if (ret < 0)
2045  return ret;
2046 
2047  /* Select the audio format */
2048  if (aud_fmt == AFMT_I2S) {
2049  if (i2s_chan != 32) {
2050  ret = write_reg_mask(dev,
2051  CA_I2S,
2052  CA_I2S_CA_I2S_MASK,
2053  (uint8_t) i2s_chan);
2054  }
2055 
2056  /* Select the I2S format */
2057  ret = write_reg_mask(dev,
2058  I2S_FORMAT,
2059  I2S_FORMAT_I2S_FORMAT_MASK,
2060  (uint8_t) i2s_fmt);
2061  if (ret < 0)
2062  return ret;
2063 
2064  } else if (aud_fmt == AFMT_OBA) {
2065  ret = write_reg(dev, CA_DSD, dsd_chan);
2066  if (ret < 0)
2067  return ret;
2068 
2069  ret = write_reg_mask(dev,
2070  AIP_CLKSEL,
2071  AIP_CLKSEL_SEL_POL_CLK,
2072  (uint8_t) dsd_clkpol);
2073  if (ret < 0)
2074  return ret;
2075 
2076  ret = write_reg_mask(dev,
2077  AIP_CNTRL_0,
2078  AIP_CNTRL_0_SWAP,
2079  (uint8_t) dsd_swap);
2080  if (ret < 0)
2081  return ret;
2082  }
2083 
2084  /* Set layout and latency */
2085  ret = write_reg_mask(dev,
2086  AIP_CNTRL_0,
2087  AIP_CNTRL_0_LAYOUT,
2088  layout << 2);
2089  if (ret < 0)
2090  return ret;
2091 
2092  ret = write_reg(dev, LATENCY_RD, (uint8_t) latency);
2093  if (ret < 0)
2094  return ret;
2095 
2096  return 0;
2097 }
static int write_reg(struct tda998x_dev *dev, enum tda998x_hdmi_reg reg, uint8_t data)
Write Register.
Definition: tda998x.c:1283
Definition: tda998x.h:339
Definition: tda998x.h:338
static int write_reg_mask(struct tda998x_dev *dev, enum tda998x_hdmi_reg reg, uint8_t mask, uint8_t val)
Register Mask Write Write a value with mask bits to a register.
Definition: tda998x.c:1371
Definition: tda998x.h:341
Definition: tda998x.h:337

◆ tda998x_aud_set_cts()

static int tda998x_aud_set_cts ( struct tda998x_dev dev,
enum tda998x_cts_ref  cts_ref,
enum tda998x_aud_rate  afs,
enum tda998x_vid_fmt  vout_fmt,
enum tda998x_vert_freq  vout_freq,
uint32_t  cts,
uint16_t  ctsX,
enum tda998x_ctsk  ctsK,
enum tda998x_ctsm  ctsM,
enum tda998x_dst_rate  dst_rate 
)
static

#include <projects/lib/tda998x.c>

Set Audio CTS.

Parameters
devTDA998x device structure pointer
Returns
0 on success, non-zero error status otherwise
Todo:
Define CTS values
Todo:
Reset and release the CTS generator
2116 {
2117  int ret;
2118  uint8_t reg_val;
2119  uint8_t pixClk; /* Pixel clock index */
2120  uint32_t acrN; /* Audio clock recovery N */
2121 
2122  /* Return if sink is not an HDMI device */
2123  if (dev->sink != SINK_HDMI)
2124  return ERR_NOT_PERMITTED;
2125 
2126  if ((vout_fmt >= VFMT_01_640x480p_60Hz) &&
2127  (vout_fmt <= VFMT_62_1280x720p_30Hz)) {
2128  if (vout_freq == VFREQ_50Hz) {
2129  if ((vout_fmt < VFMT_17_720x576p_50Hz) ||
2130  (vout_fmt > VFMT_31_1920x1080p_50Hz))
2131  return ERR_ILLEGAL_PARAMS;
2132 
2133  } else if (vout_freq == VFREQ_24Hz) {
2134  if ((vout_fmt != VFMT_32_1920x1080p_24Hz) &&
2135  (vout_fmt != VFMT_60_1280x720p_24Hz))
2136  return ERR_ILLEGAL_PARAMS;
2137  } else if (vout_freq == VFREQ_25Hz) {
2138  if ((vout_fmt != VFMT_33_1920x1080p_25Hz) &&
2139  (vout_fmt != VFMT_20_1920x1080i_50Hz) &&
2140  (vout_fmt != VFMT_61_1280x720p_25Hz))
2141  return ERR_ILLEGAL_PARAMS;
2142  } else if (vout_freq == VFREQ_30Hz) {
2143  if ((vout_fmt != VFMT_34_1920x1080p_30Hz) &&
2144  (vout_fmt != VFMT_05_1920x1080i_60Hz) &&
2145  (vout_fmt != VFMT_62_1280x720p_30Hz))
2146  return ERR_ILLEGAL_PARAMS;
2147  } else {
2148  if (vout_fmt >= VFMT_17_720x576p_50Hz)
2149  return ERR_ILLEGAL_PARAMS;
2150  }
2151  }
2152 
2153  /* Check for auto or manual CTS */
2154  if (cts == 0) {
2155  /* Auto */
2156  ret = write_reg_mask(dev, AIP_CNTRL_0, AIP_CNTRL_0_ACR_MAN, 0);
2157  if (ret < 0)
2158  return ret;
2159  } else {
2160  /* Manual */
2161  ret = write_reg_mask(dev,
2162  AIP_CNTRL_0,
2163  AIP_CNTRL_0_ACR_MAN,
2164  AIP_CNTRL_0_ACR_MAN);
2165  if (ret < 0)
2166  return ret;
2167  }
2168 
2169  /* Derive M and K from X? */
2170  if ((ctsM == CTSMTS_USE_CTSX) ||
2171  (ctsK == CTSK_USE_CTSX)) {
2175 // ctsM = (enum tda998x_ctsm) kCtsXToMK[ctsX][0];
2176 // ctsK = (enum tda998x_ctsk) kCtsXToMK[ctsX][1];
2177  }
2178 
2179  /* Set the Post-divider measured timestamp factor */
2180  reg_val = (uint8_t) ctsM;
2181  ret = write_reg_mask(dev,
2182  CTS_N_RW,
2183  CTS_N_M_SEL_MASK,
2184  reg_val << 4);
2185  if (ret < 0)
2186  return ret;
2187 
2188  /* Set the predivider scale */
2189  ret = write_reg_mask (dev,
2190  CTS_N_RW,
2191  CTS_N_K_SEL_MASK,
2192  (uint8_t) ctsK);
2193  if (ret < 0)
2194  return ret;
2195 
2196  /*
2197  * Use vout_fmt and vout_freq to index into a lookup table to get
2198  * the current pixel clock value.
2199  */
2200  set_pix_clk(vout_fmt, vout_freq, &pixClk);
2201 
2202  /*
2203  * Set the Audio Clock Recovery N multiplier based on the audio sample
2204  * frequency afs and current pixel clock.
2205  */
2206 // acrN = kPixClkToAcrN[pixClk][afs];
2207 // /* HDMITX_AFS_32k _AFS_48K _AFS_96K _AFS_192K */
2208 // /* _AFS_44_1k _AFS_88_2K _AFS_176_4K */
2209 // { 4576, 7007, 6864, 14014, 13728, 28028, 27456}, /* E_PIXCLK_25175 */
2210 // { 4096, 6272, 6144, 12544, 12288, 25088, 24576}, /* E_PIXCLK_25200 */
2211 // { 4096, 6272, 6144, 12544, 12288, 25088, 24576}, /* E_PIXCLK_27000 */
2212 // { 4096, 6272, 6144, 12544, 12288, 25088, 24576}, /* E_PIXCLK_27027 */
2213 // { 4096, 6272, 6144, 12544, 12288, 25088, 24576}, /* E_PIXCLK_54000 */
2214 // { 4096, 6272, 6144, 12544, 12288, 25088, 24576}, /* E_PIXCLK_54054 */
2215 // { 4096, 6272, 6144, 12544, 12288, 25088, 24576}, /* E_PIXCLK_59400 */
2216 // {11648, 17836, 11648, 35672, 23296, 71344, 46592}, /* E_PIXCLK_74175 */
2217 // { 4096, 6272, 6144, 12544, 12288, 25088, 24576}, /* E_PIXCLK_74250 */
2218 // {11648, 8918, 5824, 17836, 11648, 35672, 23296}, /* E_PIXCLK_148350*/
2219 // { 4096, 6272, 6144, 12544, 12288, 25088, 24576} /* E_PIXCLK_148500*/
2220 // #ifdef FORMAT_PC
2221 // ,{ 4096, 6272, 6144, 12544, 12288, 25088, 24576}, /* E_PIXCLK_31500 */
2222 // { 4096, 6272, 6144, 12544, 12288, 25088, 24576}, /* E_PIXCLK_36000 */
2223 // { 4096, 6272, 6144, 12544, 12288, 25088, 24576}, /* E_PIXCLK_40000 */
2224 // { 4096, 6272, 6144, 12544, 12288, 25088, 24576}, /* E_PIXCLK_49500 */
2225 // { 4096, 6272, 6144, 12544, 12288, 25088, 24576}, /* E_PIXCLK_50000 */
2226 // { 4096, 6272, 6144, 12544, 12288, 25088, 24576}, /* E_PIXCLK_56250 */
2227 // { 4096, 6272, 6144, 12544, 12288, 25088, 24576}, /* E_PIXCLK_65000 */
2228 // { 4096, 6272, 6144, 12544, 12288, 25088, 24576}, /* E_PIXCLK_75000 */
2229 // { 4096, 6272, 6144, 12544, 12288, 25088, 24576}, /* E_PIXCLK_78750 */
2230 // { 4096, 6272, 6144, 12544, 12288, 25088, 24576}, /* E_PIXCLK_162000*/
2231 // { 4096, 6272, 6144, 12544, 12288, 25088, 24576} /* E_PIXCLK_157500*/
2232 // #endif /* FORMAT_PC */
2233 // };
2234 
2235  acrN = 6272;
2236  /* Set ACR N multiplier [19 to 16] */
2237  reg_val = (uint8_t) (acrN >> 16);
2238  ret = write_reg (dev, ACR_N_2, reg_val);
2239  if (ret < 0)
2240  return ret;
2241 
2242  /* Set ACR N multiplier [15 to 8] */
2243  reg_val = (uint8_t) (acrN >> 8);
2244  ret = write_reg (dev, ACR_N_1, reg_val);
2245  if (ret < 0)
2246  return ret;
2247 
2248  /* Set ACR N multiplier [7 to 0] */
2249  reg_val = (uint8_t) acrN;
2250  ret = write_reg (dev, ACR_N_0, reg_val);
2251  if (ret < 0)
2252  return ret;
2253 
2254  /*
2255  * Set the CDC Audio Divider register based on the audio sample frequency
2256  * afs and current pixel clock.
2257  */
2258 // reg_val = kPixClkToAdiv[pixClk][afs];
2259 // {
2260 // /* HDMITX_AFS_32k _AFS_48K _AFS_96K _AFS_192K */
2261 // /* _AFS_44_1k _AFS_88_2K _AFS_176_4K */
2262 // {2, 2, 2, 1, 1, 0, 0}, /* E_PIXCLK_25175 */
2263 // {2, 2, 2, 1, 1, 0, 0}, /* E_PIXCLK_25200 */
2264 // {2, 2, 2, 1, 1, 0, 0}, /* E_PIXCLK_27000 */
2265 // {2, 2, 2, 1, 1, 0, 0}, /* E_PIXCLK_27027 */
2266 // {3, 3, 3, 2, 2, 1, 1}, /* E_PIXCLK_54000 */
2267 // {3, 3, 3, 2, 2, 1, 1}, /* E_PIXCLK_54054 */
2268 // {3, 3, 3, 2, 2, 1, 1}, /* E_PIXCLK_59400 */
2269 // {4, 3, 3, 2, 2, 1, 1}, /* E_PIXCLK_74175 */
2270 // {4, 3, 3, 2, 2, 1, 1}, /* E_PIXCLK_74250 */
2271 // {5, 4, 4, 3, 3, 2, 2}, /* E_PIXCLK_148350 */
2272 // {5, 4, 4, 3, 3, 2, 2} /* E_PIXCLK_148500 */
2273 // #ifdef FORMAT_PC
2274 // ,{2, 2, 2, 1, 1, 0, 0}, /* E_PIXCLK_31500 */
2275 // {3, 2, 2, 1, 1, 0, 0}, /* E_PIXCLK_36000 */
2276 // {3, 2, 2, 1, 1, 0, 0}, /* E_PIXCLK_40000 */
2277 // {3, 3, 3, 2, 2, 1, 1}, /* E_PIXCLK_49500 */
2278 // {3, 3, 3, 2, 2, 1, 1}, /* E_PIXCLK_50000 */
2279 // {3, 3, 3, 2, 2, 1, 1}, /* E_PIXCLK_56250 */
2280 // {4, 3, 3, 2, 2, 1, 1}, /* E_PIXCLK_65000 */
2281 // {4, 3, 3, 2, 2, 1, 1}, /* E_PIXCLK_75000 */
2282 // {4, 3, 3, 2, 2, 1, 1}, /* E_PIXCLK_78750 */
2283 // {5, 4, 4, 3, 3, 2, 2}, /* E_PIXCLK_162000 */
2284 // {5, 4, 4, 3, 3, 2, 2} /* E_PIXCLK_157500 */
2285 // #endif /* FORMAT_PC */
2286 // };
2287 
2288  ret = write_reg(dev, AUDIO_DIV, 4);
2289  if (ret < 0)
2290  return ret;
2291 
2292  /*
2293  * If auto CTS, get CTS value based on the audio sample
2294  * frequency afs and current pixel clock.
2295  */
2296 // if (cts == 0)
2297 // cts = kPixClkToAcrCts[pixClk][afs];
2298 
2299  /* Set manual or pixel clock CTS */
2300  if (cts != 0) {
2301  /* Set manual ACR CTS [19 to 16] */
2302  reg_val = (uint8_t) (cts >> 16);
2303  ret = write_reg (dev, ACR_CTS_2, reg_val);
2304  if (ret < 0)
2305  return ret;
2306 
2307  /* Set manual ACR CTS [15 to 8] */
2308  reg_val = (uint8_t) (cts >> 8);
2309  ret = write_reg (dev, ACR_CTS_1, reg_val);
2310  if (ret < 0)
2311  return ret;
2312 
2313  /* Set manual ACR CTS [7 to 0] */
2314  reg_val = (uint8_t) cts;
2315  ret = write_reg (dev, ACR_CTS_0, reg_val);
2316  if (ret < 0)
2317  return ret;
2318  }
2319 
2320  /* Set the CTS clock reference register according to cts_ref */
2321  reg_val = (uint8_t) cts_ref;
2322  ret = write_reg_mask(dev,
2323  AIP_CLKSEL,
2324  AIP_CLKSEL_SEL_FS_MASK,
2325  reg_val);
2326  if (ret < 0)
2327  return ret;
2328 
2332 // ret = write_reg_mask_table(dev, &kResetCtsGenerator[0]);
2333 
2334  return ret;
2335 }
Definition: tda998x.h:113
Definition: tda998x.h:114
Definition: tda998x.h:74
Definition: tda998x.c:926
Definition: tda998x.c:925
Definition: tda998x.h:107
static int write_reg(struct tda998x_dev *dev, enum tda998x_hdmi_reg reg, uint8_t data)
Write Register.
Definition: tda998x.c:1283
Definition: tda998x.c:924
Definition: tda998x.c:923
Definition: tda998x.h:112
static int write_reg_mask(struct tda998x_dev *dev, enum tda998x_hdmi_reg reg, uint8_t mask, uint8_t val)
Register Mask Write Write a value with mask bits to a register.
Definition: tda998x.c:1371
Definition: tda998x.h:65
Definition: tda998x.h:78
Definition: tda998x.h:93
Definition: tda998x.h:358
Definition: tda998x.h:105
Definition: tda998x.h:106
Definition: tda998x.h:90
Definition: tda998x.h:104
Definition: tda998x.h:367

◆ tda998x_aud_set_input()

int tda998x_aud_set_input ( struct tda998x_dev dev,
struct tda998x_audin_cfg audin_cfg 
)

#include <projects/lib/tda998x.c>

Todo:
Rework the audio configuration

< Number of channels - 1
< Channel allocation code

2467 {
2468  int ret;
2469  uint8_t reg_val;
2470  uint8_t buf[4];
2471  uint8_t layout; /* 0 or 1 */
2472  uint16_t uCtsX; /* CtsX value */
2473  uint32_t acrN;
2474  struct tda998x_aud_if_pkt aif_pkt; /* Audio infoframe packet */
2475 
2476  ret = write_reg(dev, ENA_AP, 0xFF);
2477  if (ret < 0)
2478  return ret;
2479 
2480  ret = write_reg(dev, ENA_ACLK, 0x01);
2481  if (ret < 0)
2482  return ret;
2483 
2484  /* configure MUX_AP */
2485  ret = write_reg(dev, MUX_AP, 0x64);
2486  if (ret < 0)
2487  return ret;
2488 
2489  /* Set the audio input processor format to aFmt. */
2490  ret = write_reg_mask(dev, AIP_CLKSEL, 0x38, 0x08);
2491  if (ret < 0)
2492  return ret;
2493 
2494  /* Channel status on 1 channel */
2495  ret = write_reg_mask(dev, CA_I2S, (1 << 5), 0);
2496  if (ret < 0)
2497  return ret;
2498 
2499  ret = write_reg_mask(dev, CA_I2S, 0x1F, 0x1F);
2500  if (ret < 0)
2501  return ret;
2502 
2503  /* Select the I2S format */
2504  ret = write_reg_mask(dev, I2S_FORMAT, 0x0F, 0x0E);
2505  if (ret < 0)
2506  return ret;
2507 
2508  ret = write_reg_mask(dev, AIP_CNTRL_0, (1 << 2), (1 << 2));
2509  if (ret < 0)
2510  return ret;
2511 
2512  ret = write_reg(dev, LATENCY_RD, 0x80);
2513  if (ret < 0)
2514  return ret;
2515 
2516  /* Auto */
2517  ret = write_reg_mask(dev, AIP_CNTRL_0, (1 << 5), 0);
2518  if (ret < 0)
2519  return ret;
2520 
2521  /* Set the Post-divider measured timestamp factor */
2522  ret = write_reg_mask(dev, CTS_N_RW, 0x30, 0x10);
2523  if (ret < 0)
2524  return ret;
2525 
2526  /* Set the Pre-divider scale */
2527  ret = write_reg_mask(dev, CTS_N_RW, 0x07, 0x01);
2528  if (ret < 0)
2529  return ret;
2530 
2531  /* Set ACR N multiplier [19 to 16] */
2532  ret = write_reg(dev, ACR_N_2, 0x00);
2533  if (ret < 0)
2534  return ret;
2535 
2536  /* Set ACR N multiplier [15 to 8] */
2537  ret = write_reg(dev, ACR_N_1, 0x18);
2538  if (ret < 0)
2539  return ret;
2540 
2541  ret = write_reg(dev, ACR_N_0, 0x00);
2542  if (ret < 0)
2543  return ret;
2544 
2545  /*
2546  * Set the CDC Audio Divider register based on the audio sample
2547  * frequency afs and current pixel clock
2548  */
2549  ret = write_reg(dev, AUDIO_DIV, 0x04);
2550  if (ret < 0)
2551  return ret;
2552 
2553  /* Set the CTS clock reference register according to ctsRef */
2554  ret = write_reg_mask(dev, AIP_CLKSEL, 0x03, 0);
2555  if (ret < 0)
2556  return ret;
2557 
2558  /* Reset and release the CTS generator */
2559  ret = write_reg_mask(dev, AIP_CNTRL_0, (1 << 6), (1 << 6));
2560  if (ret < 0)
2561  return ret;
2562 
2563  ret = write_reg_mask(dev, AIP_CNTRL_0, (1 << 6), 0);
2564  if (ret < 0)
2565  return ret;
2566 
2567  /* Prepare Byte 0 */
2568  buf[0] = 0x00; // ((UInt8)formatInfo << 3) | ((UInt8)copyright << 2) | ((UInt8)pcmIdentification<< 1);
2569 
2570  /* Prepare Byte 1 */
2571  buf[1] = 0x00; // categoryCode;
2572 
2573  /* Prepare Byte 3 - note Byte 2 not in sequence in TDA9983 register map */
2574  buf[2] = 0x02; // ((UInt8)clockAccuracy << 4) | 0x02;
2575 
2576  /* Prepare Byte 4 */
2577  buf[3] = (13 << 4) | (1 << 1);
2578 
2579  ret = tda998x_write(dev, CH_STAT_B_0, 4, &buf[0]);
2580  if (ret < 0)
2581  return ret;
2582 
2583  ret = tda998x_aud_set_mute(dev, true);
2584  if (ret < 0)
2585  return ret;
2586 
2587  /* Wait 20ms */
2588  usleep(1000 * 20);
2589 
2590  ret = tda998x_aud_set_mute(dev, false);
2591  if (ret < 0)
2592  return ret;
2593 
2594  aif_pkt.nchan = 7;
2595  aif_pkt.type = 0; /* refer to stream header */
2596  aif_pkt.samp_size = 0; /* refer to stream header */
2597  aif_pkt.chan_alloc = audin_cfg->ch_alloc;
2598  aif_pkt.lvl_shift = 0; /* 0dB level shift */
2599  aif_pkt.dmix_inhib = 0; /* down-mix stereo permitted */
2600  aif_pkt.samp_freq = 0; /* refer to stream header */
2601 
2602  ret = tda998x_aud_set_pkt_infoframe(dev, &aif_pkt, true);
2603  if (ret < 0)
2604  return ret;
2605 
2606  return 0;
2607 }
static int tda998x_aud_set_pkt_infoframe(struct tda998x_dev *dev, struct tda998x_aud_if_pkt *pkt, bool en)
Set Audio Infoframe Packet.
Definition: tda998x.c:3984
static int write_reg(struct tda998x_dev *dev, enum tda998x_hdmi_reg reg, uint8_t data)
Write Register.
Definition: tda998x.c:1283
static int tda998x_write(struct tda998x_dev *dev, enum tda998x_hdmi_reg reg, uint8_t len, uint8_t *data)
Write Data.
Definition: tda998x.c:1247
static int write_reg_mask(struct tda998x_dev *dev, enum tda998x_hdmi_reg reg, uint8_t mask, uint8_t val)
Register Mask Write Write a value with mask bits to a register.
Definition: tda998x.c:1371
Definition: tda998x.h:436
uint8_t ch_alloc
Definition: tda998x.h:452
static int tda998x_aud_set_mute(struct tda998x_dev *dev, bool mute)
Set Audio Mute.
Definition: tda998x.c:2431

◆ tda998x_aud_set_mute()

static int tda998x_aud_set_mute ( struct tda998x_dev dev,
bool  mute 
)
static

#include <projects/lib/tda998x.c>

Set Audio Mute.

Parameters
devTDA998x device structure pointer
muteMute enable value
Returns
0 on success, non-zero error status otherwise
2432 {
2433  int ret;
2434 
2435  if (dev->sink != SINK_HDMI)
2436  return ERR_NOT_PERMITTED;
2437 
2438  if (mute) {
2439  ret = write_reg_mask(dev,
2440  SR_REG,
2441  SR_REG_SR_AUDIO,
2442  SR_REG_SR_AUDIO);
2443  if (ret < 0)
2444  return ret;
2445 
2446  ret = write_reg_mask(dev, SR_REG, SR_REG_SR_AUDIO, 0);
2447  if (ret < 0)
2448  return ret;
2449  }
2450 
2451  ret = write_reg_mask(dev,
2452  AIP_CNTRL_0,
2453  AIP_CNTRL_0_RST_FIFO,
2454  mute ? AIP_CNTRL_0_RST_FIFO : 0);
2455  if (ret < 0)
2456  return ret;
2457 
2458  return 0;
2459 }
static int write_reg_mask(struct tda998x_dev *dev, enum tda998x_hdmi_reg reg, uint8_t mask, uint8_t val)
Register Mask Write Write a value with mask bits to a register.
Definition: tda998x.c:1371
Definition: tda998x.h:65

◆ tda998x_aud_set_port_enable()

int tda998x_aud_set_port_enable ( struct tda998x_dev dev,
uint8_t  en 
)

#include <projects/lib/tda998x.c>

Set Audio Port Enable.

Lookup table for each pixel clock frequency's CTS value in kHz according to SCS table "Audio Clock Recovery CTS Values" Lookup table for each pixel clock frequency's Audio Clock Regeneration N, according to SCS Table "Audio Clock Recovery N Values" Lookup table for each pixel clock frequency's Audio Divider, according to SCS Table "Audio Clock Recovery Divider Values" Lookup table for converting a sampling frequency into the values required in channel status byte 3 according to IEC60958-3 Lookup table for each CTS X factor's k and m register values Table of registers to reset and release the CTS generator

Parameters
devTDA998x device structure pointer
enAudio port enable register value
Returns
0 on success, non-zero error status otherwise
1928 {
1929  int ret;
1930 
1931  /* Check parameter */
1932  if (dev == NULL)
1933  return ERR_NULL_PARAM;
1934 
1935  ret = write_reg(dev, ENA_AP, en);
1936  if (ret < 0)
1937  return ret;
1938 
1939  return 0;
1940 }
static int write_reg(struct tda998x_dev *dev, enum tda998x_hdmi_reg reg, uint8_t data)
Write Register.
Definition: tda998x.c:1283