Quantcast
Channel: Forums - Recent Threads
Viewing all 262198 articles
Browse latest View live

Linux/AM5728: C66x cannot deal with the interrupts from PWM with 16Khz

$
0
0

Part Number: AM5728

Tool/software: Linux

Hello,

The experiment environment:

  • AM5728 IDK Board
  • ti-processor_sdk_rtos_am57xx_4_03_00_05 and CSL ePWM examples for C66 and M4
  • PROCESSOR-SDK-LINUX-RT-AM57X for A15

The experiment step:

  1. Boot the board and stop at UBoot
  2. Release C66 and load code of ePWM (attached in the end)
  3. Use UBoot command to
    1. enable epwm interrupt
    2. wait for 10 sec
    3. disable epwm interrupt
  4. Check the value of the counter, which is 0x40301000, to get the numbers of the ePWM interrupt handled by C66x.

The following figure has shown C66x cannot deal with 16Khz interrupts from ePWM. However, it seems easy for M4 to deal with 50Khz interrupt from ePWM. I have put everything (code, data, stack, ..) into internal SRAM to make C66x as busy as possible. Could someone provide any comment?

/*
 *  Copyright (c) Texas Instruments Incorporated 2017
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

/**
 *  \file     epwm_app.c
 *
 *  \brief    This file contains PWM test application which sets a particular
 *            duty cycle in PWMSS1 output A (EHRPWM1A) which can be verified
 *            through external pin probing.
 */

/* ========================================================================== */
/*                             Include Files                                  */
/* ========================================================================== */

#include "epwm_app.h"

/* ========================================================================== */
/*                                Macros                                      */
/* ========================================================================== */

/*
 * Configurable parameters
 */
/**
 *  \brief PWM instance base address.
 *
 *  Note: If changed to other instance, PRCM and pinmux changes needs to be
 *  taken care in the application.
 */
#define APP_EHRPWM_INST_BASE_ADDR       (SOC_PWMSS1_IPWMSS_BASE)

/**
 *  \brief Output channel - A or B.
 *
 *  Note: If changed to channel B, pinmux changes needs to be taken care
 *  in the application.
 */
#define APP_EHRPWM_OUTPUT_CH            (CSL_EPWM_OUTPUT_CH_A)

/** \brief Frequency of PWM output signal in Hz - 1 KHz is selected */
#define APP_EHRPWM_OUT_FREQ             50000 //(1U * 1000U)

/** \brief Duty Cycle of PWM output signal in % - give value from 0 to 100 */
#define APP_EHRPWM_DUTY_CYCLE           (25U)

/** \brief APP run time in seconds */
#define APP_RUN_TIME                    (10U)

/** \brief APP run count in event equal zero ISR count */
#define APP_RUN_TIME_ISRCOUNT           (APP_RUN_TIME * APP_EHRPWM_OUT_FREQ)

/**
 *  \brief Functional clock to the PWMSS.
 *  Fixed for the platform - can't be changed.
 */
#define SOC_EHRPWM_MODULE_FREQ          (133U * 1000U * 1000U)

/** \brief TB frequency in Hz - so that /4 divider is used */
#define APP_EHRPWM_TB_FREQ              (SOC_EHRPWM_MODULE_FREQ / 4U)

/**
 *  \brief PRD value - this determines the period
 *
 *  PRD = (TBCLK/PWM FREQ) / 2
 *  NOTE: /2 is added becasue up&down counter is selected. So period is 2 times
 */
#define APP_EHRPWM_PRD_VAL              ((APP_EHRPWM_TB_FREQ                   \
                                            / APP_EHRPWM_OUT_FREQ) / 2U)
/**
 *  \brief COMPA value - this determines the duty cycle
 *
 *  COMPA = (PRD - ((dutycycle * PRD) / 100)
 */
#define APP_EHRPWM_COMPA_VAL            (APP_EHRPWM_PRD_VAL -                  \
                                            ((APP_EHRPWM_DUTY_CYCLE *          \
                                                APP_EHRPWM_PRD_VAL) / 100U))

/*
#define APP_EHRPWM_INT                  (32U)
#define APP_EHRPWM_XBAR_CPU             (CSL_XBAR_IRQ_CPU_ID_IPU1)
#define APP_EHRPWM_XBAR_INST            (CSL_XBAR_INST_IPU1_IRQ_32)
#define APP_EHRPWM_XBAR_INTR_SOURCE     (CSL_XBAR_PWMSS1_IRQ_ePWM0INT)
*/

#define APP_EHRPWM_INT                  (32U)
#define APP_EHRPWM_XBAR_CPU             (CSL_XBAR_IRQ_CPU_ID_DSP1)
#define APP_EHRPWM_XBAR_INST            (CSL_XBAR_INST_DSP1_IRQ_32)
#define APP_EHRPWM_XBAR_INTR_SOURCE     (CSL_XBAR_PWMSS1_IRQ_ePWM0INT)
 

/* ========================================================================== */
/*                            Global Variables                                */
/* ========================================================================== */

/** \brief IP default configuration */
static CSL_EpwmAppPwmObj_t gAppPwmObj =
{
    APP_EHRPWM_OUTPUT_CH,                       /* pwmCh */
    APP_EHRPWM_INST_BASE_ADDR,                  /* instAddr */
    SOC_EHRPWM_MODULE_FREQ,                     /* funcClk */
    FALSE,                                      /* enableDeadband */
    FALSE,                                      /* enableChopper */
    FALSE,                                      /* enableTripzone */
    TRUE,                                       /* enableEventTrigger */
    FALSE,                                      /* enableHighResolution */
    /* CSL_EpwmAppPwmCfg_t*/
    {
        /* CSL_EpwmTimebaseCfg_t */
        {
            APP_EHRPWM_TB_FREQ,                 /* tbClk */
            APP_EHRPWM_OUT_FREQ,                /* pwmtbCounterFreqPrd */
            CSL_EPWM_TB_COUNTER_DIR_UP_DOWN,    /* tbCntrDirection */
            FALSE,                              /* enableSynchronization */
            PWMSS_EPWM_TBCTL_PHSDIR_COUNT_DOWN, /* cntDirAfterSync */
            0U,                                 /* phsCountAfterSync */
            PWMSS_EPWM_TBCTL_SYNCOSEL_EPWMXSYNC /* syncOutSrc */
        },
        /* CSL_EpwmCounterCmpCfg_t */
        {
            APP_EHRPWM_COMPA_VAL,               /* cmpAValue */
            APP_EHRPWM_COMPA_VAL                /* cmpBValue */
        },
        /* CSL_EpwmAqActionCfg_t */
        {
            CSL_EPWM_AQ_ACTION_DONOTHING,       /* zeroAction */
            CSL_EPWM_AQ_ACTION_DONOTHING,       /* prdAction */
            CSL_EPWM_AQ_ACTION_HIGH,            /* cmpAUpAction */
            CSL_EPWM_AQ_ACTION_LOW,             /* cmpADownAction */
            CSL_EPWM_AQ_ACTION_HIGH,            /* cmpBUpAction */
            CSL_EPWM_AQ_ACTION_LOW              /* cmpBDownAction */
        },
        /* CSL_EpwmDeadbandCfg_t */
        {
            CSL_EPWM_DB_IN_MODE_A_RED_A_FED,    /* inputMode */
            CSL_EPWM_DB_OUT_MODE_BYPASS,        /* outputMode */
            CSL_EPWM_DB_POL_SEL_ACTV_HIGH,      /* polaritySelect */
            0U,                                 /* risingEdgeDelay */
            0U                                  /* fallingEdgeDelay */
        },
        /* CSL_EpwmChopperCfg_t */
        {
            CSL_EPWM_CHP_DUTY_CYCLE_PERC_12PNT5,    /* dutyCycle */
            CSL_EPWM_CHP_CLK_FREQ_DIV_BY_1,         /* clkFrequency */
            CSL_EPWM_CHP_OSHT_WIDTH_1XSYSOUT_BY_8   /* oneShotPulseWidth */
        },
        /* CSL_EpwmTripzoneCfg_t */
        {
            CSL_EPWM_TZ_TRIP_ACTION_DO_NOTHING, /* tripAction */
            CSL_EPWM_TZ_EVENT_ONE_SHOT,         /* tripEvtType */
            0U,                                 /* tripPin */
            FALSE                               /* enableTripIntr */
        },
        /* CSL_EpwmEtCfg_t */
        {
            CSL_EPWM_ET_INTR_EVT_CNT_EQ_ZRO,    /* intrEvtSource */
            CSL_EPWM_ET_INTR_PERIOD_FIRST_EVT   /* intrPrd */
        }
    }
};

static volatile uint32_t gNumIsr = 0U;
volatile uint32_t *gNumIsr2 = (volatile uint32_t*)0x40301000;

#if defined (SOC_TDA2XX) || defined (SOC_TDA2PX) || defined (SOC_DRA75x) || defined (SOC_TDA2EX) || defined (SOC_DRA72x)
static uint32_t uartBaseAddr = SOC_UART1_BASE;
#endif
#if defined (SOC_TDA3XX) || defined (SOC_DRA78x)
static uint32_t uartBaseAddr = SOC_UART3_BASE;
#endif
static uint32_t uartBaseAddr = SOC_UART3_BASE;

/* ========================================================================== */
/*                 Internal Function Declarations                             */
/* ========================================================================== */

static void AppPwmIntrISR(void *handle);

static void CSL_epwmAppPwmCfg(CSL_EpwmAppPwmObj_t *pObj);
static void EpwmAppTimebaseModuleCfg(uint32_t baseAddr,
                                     uint32_t pwmFuncClk,
                                     CSL_EpwmTimebaseCfg_t *pTbCfg);
static void EpwmAppCounterComparatorCfg(uint32_t baseAddr,
                                        CSL_EpwmCounterCmpCfg_t *pCcCfg);

static void padConfig_prcmEnable(void);

/* ========================================================================== */
/*                          Function Definitions                              */
/* ========================================================================== */

int32_t main(void)
{
    CSL_EpwmAppPwmObj_t *pObj = &gAppPwmObj;

    /* Do pad config amd PRCM enable for UART and PWM */
    padConfig_prcmEnable();

    /* Initialize the UART Instance */
    UARTConfigInit(uartBaseAddr, BAUD_RATE_115200,
                   UART_WORD_LENGTH_8, UART_STOP_BIT_1,
                   UART_NO_PARITY, UART_16x_MODE);
    UARTConfigPuts(uartBaseAddr,
        "\nStarting EPWM duty cycle test application...\n", -1);
    UARTConfigPuts(
        uartBaseAddr, "Probe the PWM signal to verify...\n"
        "App will wait for 10 seconds (using  PWM period ISR)...\n", -1);
    UARTConfigPuts(uartBaseAddr,
        "Probe "
#if defined (SOC_TDA2XX) || defined (SOC_TDA2PX) || defined (SOC_DRA75x) || defined (SOC_TDA2EX) || defined (SOC_DRA72x)
        "VIN2A_VSYNC0 pin (RU19 pin 12) "
#endif
#if defined (SOC_TDA3XX) || defined (SOC_DRA78x)
        "GPMC_BEN0 pin (R9017/M1 of VISU connector) "
#endif
        "for 1KHz @ 25% duty cycle waveform...\n", -1);

    /* Enable clocks for EPWM module inside the PWM sub system. */
    CSL_epwmClockEnable(pObj->instAddr);

    /* EPWM channel configuration */
    CSL_epwmAppPwmCfg(pObj);

    *gNumIsr2 = 0;

    /* Wait for ISR count */
    //while (gNumIsr < APP_RUN_TIME_ISRCOUNT);
    while(1);

    //UARTConfigPuts(uartBaseAddr, "\nApplication is completed!!\n", -1);
    //return 0;
}

static void AppPwmIntrISR(void *handle)
{
    uint16_t status = CSL_epwmEtIntrStatus(APP_EHRPWM_INST_BASE_ADDR);

    CSL_epwmEtIntrClear(APP_EHRPWM_INST_BASE_ADDR);
    //gNumIsr++;
    *gNumIsr2 = (*gNumIsr2) + 1;
    return;
}

/**
 * \brief   This API configures the ePWM module
 *
 * \param   pObj             pointer to the ePwm object data structure.
 */
static void CSL_epwmAppPwmCfg(CSL_EpwmAppPwmObj_t *pObj)
{
    uint32_t baseAddr = pObj->instAddr;
    uint32_t pwmCh    = pObj->pwmCh;
    uint32_t pwmFuncClk = pObj->funcClk;
    CSL_EpwmAppPwmCfg_t *pPwmCfg = &pObj->pwmCfg;

    /* Configure the Time base Sub-Module */
    EpwmAppTimebaseModuleCfg(baseAddr, pwmFuncClk, &pPwmCfg->tbCfg);

    /* Counter-Comparator Sub-Module Configuration */
    EpwmAppCounterComparatorCfg(baseAddr, &pPwmCfg->ccCfg);

    /* Configure Action Qualifier */
    CSL_epwmAqActionOnOutputCfg(baseAddr, pwmCh, &pPwmCfg->aqCfg);

    /* Dead band sub-module configuration */
    if (TRUE == pObj->enableDeadband)
    {
       /* Enable and configure dead band sub module */
       CSL_epwmDeadbandCfg(baseAddr, &pPwmCfg->dbCfg);
    }
    else
    {
        /* Bypass dead band sub module */
        CSL_epwmDeadbandBypass(baseAddr);
    }

    /* Chopper sub-module configuration */
    if (TRUE == pObj->enableChopper)
    {
        /* Configure chopper sub - module */
        CSL_epwmChopperCfg(baseAddr, &pPwmCfg->chpCfg);

        /* Enable Chopper */
        CSL_epwmChopperEnable(baseAddr, TRUE);
    }
    else
    {
        /* Disable Chopper */
        CSL_epwmChopperEnable(baseAddr, FALSE);
    }

    /* Trip Zone Sub-Module Configuration */
    if (TRUE == pObj->enableTripZone)
    {
        /* Configure the Trip action */
        CSL_epwmTzTriggerTripAction(
            baseAddr, CSL_EPWM_TZ_TRIP_ACTION_HIGH, pwmCh);

        /* Enable the Trip event */
        CSL_epwmTzTripEventEnable(
            baseAddr, pPwmCfg->tzCfg.tripEvtType, pPwmCfg->tzCfg.tripPin);
    }
    else
    {
        /* Disable trip zone event handling and ignore all trip zone events */
        CSL_epwmTzTripEventDisable(
            baseAddr, CSL_EPWM_TZ_EVENT_ONE_SHOT, pPwmCfg->tzCfg.tripPin);
        CSL_epwmTzTripEventDisable(
            baseAddr, CSL_EPWM_TZ_EVENT_CYCLE_BY_CYCLE, pPwmCfg->tzCfg.tripPin);
    }

    /* Event trigger sub - module configuration */
    if (TRUE == pObj->enableEventTrigger)
    {
        /* Configure the Event trigger processing */
        CSL_epwmEtIntrCfg(
            baseAddr, pPwmCfg->etCfg.intrEvtSource, pPwmCfg->etCfg.intrPrd);
        CSL_epwmEtIntrEnable(baseAddr);
    }
    else
    {
        /* Disable Event trigger interrupts */
        CSL_epwmEtIntrDisable(baseAddr);
    }

    /**
     * High resolution feature is supported only on PWM A channel. If channel
     * is A then proceed with High Resolution processing.
     */
    if (CSL_EPWM_OUTPUT_CH_A == pwmCh)
    {
        if (TRUE == pObj->enableHighResolution)
        {
            /* configure high resolution feature */
            CSL_epwmHighResolutionCfg(
                baseAddr,
                pPwmCfg->hrCfg.delayBusSelect,
                pPwmCfg->hrCfg.delayMode);

            if (CSL_EPWM_HR_DELAY_BUS_SEL_CMPAHR ==
               pPwmCfg->hrCfg.delayBusSelect)
            {
                /* Load comparator A High-resolution counter value */
                CSL_epwmHrLoadCmpAHrValue(
                    baseAddr,
                    pPwmCfg->hrCfg.cmpAHighResVal,
                    CSL_EPWM_HR_REG_ACT_LOAD_CNT_ZRO_PULSE);
            }
            else  /* CSL_EPWM_HR_DELAY_BUS_SEL_TBPHSHR */
            {
                /* Load Timebase phase high resolution value */
                CSL_epwmHrLoadTbPhaseHrValue(
                    baseAddr, pPwmCfg->hrCfg.tbPhaseHighResVal);
            }
        }
        else
        {
            /* Disable High Resolution Feature */
            CSL_epwmHighResolutionDisable(baseAddr);
        }
    }

    return;
}

/**
 * \brief   This API configures the Timebase Sub-module.
 *
 * \param   baseAddr        Base address of PWMSS instance used
 * \param   pwmFuncClk      PWM functional clock value in Hz
 * \param   pTbCfg          Pointer to the Time base sub-module configuration
 *                          data structure
 */
static void EpwmAppTimebaseModuleCfg(uint32_t baseAddr,
                                     uint32_t pwmFuncClk,
                                     CSL_EpwmTimebaseCfg_t *pTbCfg)
{
    /* Configure Time base clock */
    CSL_epwmTbTimebaseClkCfg(baseAddr, pTbCfg->tbClk, pwmFuncClk);

    /* Configure PWM time base counter frequency and direction */
    CSL_epwmTbPwmFreqCfg(
        baseAddr,
        pTbCfg->tbClk,
        pTbCfg->pwmtbCounterFreqPrd,
        pTbCfg->tbCntrDirection,
        CSL_EPWM_SHADOW_REG_CTRL_ENABLE);

    if (TRUE == pTbCfg->enableSynchronization)
    {
        /* Enable Synchronization */
        CSL_epwmTbSyncEnable(
            baseAddr, pTbCfg->phsCountAfterSync, pTbCfg->cntDirAfterSync);
    }
    else
    {
        /* Disable Synchronization */
        CSL_epwmTbSyncDisable(baseAddr);
    }

    /* Configure Sync out signal */
    CSL_epwmTbSetSyncOutMode(baseAddr, pTbCfg->syncOutSrc);

    /* Configure the emulation behaviour */
    CSL_epwmTbSetEmulationMode(baseAddr, EPWM_TB_EMU_MODE_FREE_RUN);

    return;
}

/**
 * \brief   This API configures the Counter-Comparator Sub-module.
 *
 * \param   baseAddr    Base address of PWMSS instance used
 * \param   pCcCfg      Pointer to the Counter-Comparator Sub-module
 *                      configuration data structure
 */
static void EpwmAppCounterComparatorCfg(uint32_t baseAddr,
                                        CSL_EpwmCounterCmpCfg_t *pCcCfg)
{
    /* Counter Comparator A configuration */
    CSL_epwmCounterComparatorCfg(
        baseAddr,
        CSL_EPWM_CC_CMP_A,
        pCcCfg->cmpAValue,
        CSL_EPWM_SHADOW_REG_CTRL_ENABLE,
        CSL_EPWM_CC_CMP_LOAD_MODE_CNT_EQ_ZERO,
        TRUE);

    /* Counter Comparator B configuration */
    CSL_epwmCounterComparatorCfg(
        baseAddr,
        CSL_EPWM_CC_CMP_B,
        pCcCfg->cmpBValue,
        CSL_EPWM_SHADOW_REG_CTRL_ENABLE,
        CSL_EPWM_CC_CMP_LOAD_MODE_CNT_EQ_ZERO,
        TRUE);

    return;
}

static void padConfig_prcmEnable(void)
{
#if defined (SOC_TDA2XX) || defined (SOC_TDA2PX) || defined (SOC_DRA75x) || defined (SOC_TDA2EX) || defined (SOC_DRA72x)
    /* UART Pad configurations */
    HW_WR_REG32(
        SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_UART1_RXD, 0x00040000);
    HW_WR_REG32(
        SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_UART1_TXD, 0x00000000);

    /* PWM Pad configurations - VIN2A_VSYNC0 -> EHRPWM1A */
    HW_WR_REG32(
        SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_VIN2A_VSYNC0, 0x0000000A);
#endif
#if defined (SOC_TDA3XX) || defined (SOC_DRA78x)
    /* UART Pad configurations */
    HW_WR_REG32(
        SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_IO_SPI1_SCLK, 0x00040001);
    HW_WR_REG32(
        SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_IO_SPI1_CS0, 0x00000001);

    /* PWM Pad configurations - GPMC_BEN0 -> EHRPWM1A */
    HW_WR_REG32(
        SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_IO_GPMC_BEN0, 0x00000004);
#endif

    /* Enable PRCM for PWMSS1 */
    HW_WR_REG32(SOC_L4PER_CM_CORE_BASE + CM_L4PER2_PWMSS1_CLKCTRL, 0x2);
    while ((HW_RD_REG32(SOC_L4PER_CM_CORE_BASE +
                        CM_L4PER2_PWMSS1_CLKCTRL) & (0x00030000)) != 0x0) ;
    /* Time base clock for PWMSS1 module */
    HW_WR_FIELD32(
        SOC_CTRL_MODULE_CORE_CORE_REGISTERS_BASE + CTRL_CORE_CONTROL_IO_2,
        CTRL_CORE_CONTROL_IO_2_PWMSS1_TBCLKEN,
        1);

    /* XBar configuration */
    CSL_xbarIrqConfigure(
        APP_EHRPWM_XBAR_CPU, APP_EHRPWM_XBAR_INST, APP_EHRPWM_XBAR_INTR_SOURCE);

    /* Enable periodic interrupts for PWM period */
    Intc_Init();
    Intc_IntEnable(APP_EHRPWM_INT);

    /* Register ISR */
    Intc_IntRegister(APP_EHRPWM_INT, (IntrFuncPtr) AppPwmIntrISR, 0);
    Intc_IntPrioritySet(APP_EHRPWM_INT, 1, 0);
    Intc_SystemEnable(APP_EHRPWM_INT);

    return;
}
-stack  0x1000                             /* SOFTWARE STACK SIZE           */
-heap   0x2000                             /* HEAP AREA SIZE                */

/* SPECIFY THE SYSTEM MEMORY MAP */

MEMORY
{
        RST_START:      org = 0x00800000  len = 0x0300
        IRAM_MEM:       org = 0x00800300  len = 0x7c00
        MMU_TLB:		ORIGIN = 0x4031C000  LENGTH = 0x000004000
		/*SBL will use 1 KB of space from address 0x80000000 for EVE */
        DDR3_A8:		org = 0x80000400 len = (0x0B000000 - 0x400)    /* 176 MB */
        DDR3_BOOT:      org = 0x8B000000 len = 0x00010000    /* 32 MB */
		DDR3_DSP:		org = 0x8B010000 len = 0x01FF0000    /* 32 MB */
		DDR3_M3VPSS:	org = 0x8D000000 len = 0x01000000    /* 16 MB */
		DDR3_M3VIDEO:	org = 0x8E000000 len = 0x01000000    /* 16 MB */
		DDR3_SR0:		org = 0x8F000000 len = 0x01000000    /* 16 MB */
}

/* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY */

SECTIONS
{
	boot :
	{
	 rts*.lib<boot.obj>(.text)
	}load > DDR3_BOOT

	.cachetest_ddrbuf > IRAM_MEM
    GROUP: load > IRAM_MEM
    {
        .bss:       /* UNINITIALIZED OR ZERO INITIALIZED */
        .neardata:
        .rodata:
    }
    BOARD_IO_DELAY_DATA : load > IRAM_MEM
    BOARD_IO_DELAY_CODE : load > IRAM_MEM
    .csl_vect : load > RST_START
    .vects : load > IRAM_MEM
    .l2_int  : load > IRAM_MEM
    .pmIdleFunc : load > IRAM_MEM
    .init    : load > IRAM_MEM
    .cio     : load > IRAM_MEM

    .text 	 : load > IRAM_MEM              /* CODE                         */
    .data    : load > IRAM_MEM              /* INITIALIZED GLOBAL AND STATIC VARIABLES. */
                                            /* GLOBAL & STATIC VARIABLES.   */
                    RUN_START(bss_start)
                    RUN_END(bss_end)
    .const   : load > IRAM_MEM              /* GLOBAL CONSTANTS             */
    .cinit   : load > IRAM_MEM
    .stack   : load > IRAM_MEM            /* SOFTWARE SYSTEM STACK        */
	.far	 : load > IRAM_MEM
	.plt     : load > IRAM_MEM
	.fardata : load > IRAM_MEM
	.switch	 : load > IRAM_MEM
	.my_sect_ddr : load > IRAM_MEM
	.sysmem : load > IRAM_MEM
}


TMP75: The scl and sda of TMP75 is not monotonous

$
0
0

Part Number: TMP75

Hi

In my project,the waveform of TMP75 is not monotonous,a little stage on the falling edge,the width is about 4ns,the voltage of the stage is about 2.2V,is it ok for TMP75?I am worrying it will be multi-edges sampled by TMP75,and sample wrong data。

In the datasheet of TMP75,The SDA and SCL pins feature integrated spike suppression filters and Schmitt triggers to minimize the effects of input spikes and bus noise.

thanks



WEBENCH® Tools/TPS54560B: Compensation parameters calculate issue

$
0
0

Part Number: TPS54560B

Tool/software: WEBENCH® Design Tools

Hi team,

Now I'm calculating the compensation parameters of TPS54560B. But I found the parameters(Rcomp, Ccomp, Ccomp2) designed by webench and by excel calculate tool TPS54360-361FAMILY_CALC_TOOL_REVE are totally different. I have changed the Co and Resr in excel tools to be the same in the webench.

Can you tell me why the results are so different? And which one should I choose?  My Vin is range from 18-32V, Vout=12.8V, Iout=5A.

Thanks.

CCS/CC1352P: Simplelink_cc13x2_26x2_sdk_3_20_00_68 is compile error

$
0
0

Part Number: CC1352P

Tool/software: Code Composer Studio

Dear sir

My name is lee

I have a problem (ccs compile error)

I used software version is same blow

ccs : 9.1

sdk : simplelink_cc13x2_26x2_sdk_3_20_00_68

I try import and compile use C:\ti\simplelink_cc13x2_26x2_sdk_3_20_00_68\examples\syscfg_preview\rtos\CC1352P1_LAUNCHXL\ti154stack\sensor 

No error(not changed anything)

but change board configuration, used sensor.syscfg file in ccs 

1.remove switch(in Preferences & Actions option)

2.changed GPIO port and UART, I2C, I2S, SPI  pin number, => DIO_xx (xx is DIO Number)

3.and compile but i have error 

**** Build of configuration Release for project sensor_CC1352P1_LAUNCHXL_tirtos_ccs_syscfg ****

"C:\\ti\\ccs910\\ccs\\utils\\bin\\gmake" -k -j 2 all -O
 
making ../src/sysbios/rom_sysbios.aem4f ...
Building file: "../sensor.syscfg"
Invoking: SysConfig
"C:/ti/ccs910/ccs/utils/sysconfig/sysconfig_cli.bat" -b "/ti/boards/.meta/CC1352P1_LAUNCHXL" -s "C:/ti/simplelink_cc13x2_26x2_sdk_3_20_00_68/.metadata/product.json" -o "syscfg" "../sensor.syscfg"
gmake[1]: Nothing to be done for 'all'.
Running script...
subdir_rules.mk:33: recipe for target 'build-416924177-inproc' failed
Error: cannot set '$assign' to 'DIO_12': No option named DIO_12 defined, valid options are   <<-- error
Any
DIO_11
17
boosterpack.18
DIO11
DIO_16
26
boosterpack.32
DIO16
DIO_17
27
boosterpack.31
DIO17
DIO_18
28
boosterpack.36
DIO18
DIO_19
29
boosterpack.19
DIO19
DIO_21
31
boosterpack.9
DIO21
DIO_22
32
boosterpack.5
DIO22
DIO_23
36
boosterpack.2
DIO23
DIO_24
37
boosterpack.6
DIO24
DIO_25
38
boosterpack.23
DIO25
DIO_26
39
boosterpack.24
DIO26
DIO_27
40
boosterpack.25
DIO27
DIO_5
10
boosterpack.10
DIO5
    at Object.set (C:\ti\ccs910\ccs\utils\sysconfig\dist\cli.js:105:30593)
    at eval (C:\Users\WIN7\workspace_v9\sensor_CC1352P1_LAUNCHXL_tirtos_ccs_syscfg\sensor.syscfg:41:26)
    at n.each (C:\ti\ccs910\ccs\utils\sysconfig\dist\cli.js:105:323229)
    at Jt (C:\ti\ccs910\ccs\utils\sysconfig\dist\cli.js:9:5263)
    at Function.Gs (C:\ti\ccs910\ccs\utils\sysconfig\dist\cli.js:9:40233)
    at i.getSysConfig.then.r (C:\ti\ccs910\ccs\utils\sysconfig\dist\cli.js:105:323113)
    at <anonymous>
subdir_rules.mk:30: recipe for target 'build-416924177' failed
gmake[1]: *** [build-416924177-inproc] Error 1
gmake: *** [build-416924177] Error 2
gmake: Target 'all' not remade because of errors.

**** Build Finished ****

And i try used C:\ti\simplelink_cc13x2_26x2_sdk_3_20_00_68\examples\syscfg_preview\rtos\CC1352P1_LAUNCHXL\drivers\empty

and change board configuration, used empty.syscfg file in ccs 

 1.remove switch(in Preferences & Actions option)

2.changed GPIO port and UART, I2C, I2S, SPI  pin number, => DIO_xx (xx is DIO Number)

3.and compile but i have no error 

I don't know difference between sensor.syscfg and empty.syscfg file 

and i want know that how to use collect  and sensor project  (in C:\ti\simplelink_cc13x2_26x2_sdk_3_20_00_68\examples\syscfg_preview\rtos\CC1352P1_LAUNCHXL\ti154stack folder)

I want develop that audio broadcasting equipment use ti154stack and SUB-1GHz(so i think that collect is master and sensor is slaver)

First my objective is master is trans voice & audio data used mic or external audio player, slaver is receive voice & audio data and display by speaker  

Second my object is bi-direction communication voice and sensor data

but i am not walk one step for one month because compile error and not understand this problem.

please tel me how to good job!

thank you sir

UCC21710-Q1: How to design to ensure the accuracy of the sampling of analog quantity

$
0
0

Part Number: UCC21710-Q1

1 Since ucc21710-q1 integrates Isolated Isolated to PWM Signal Function internally,
when sampling voltage or current,
 how to design to ensure the accuracy of sampling quantity
2  ALSO, the frequency of APWM output ranges from 360k hz to 440k hz,
and the pulse width fluctuates by 0.05.
 How to design to ensure the accuracy of the sampling of analog quantity

LMR14020: Conventional BUCK Converter for Duty Cycle Problems in BUCK-BOOST Topologies

$
0
0

Part Number: LMR14020

LMR14020 This chip I want to use as BUCK-BOOST topology, output negative voltage, input +18 to 30V output negative 24V, so need a relatively large duty cycle range, up to 0.6 or so, the specification says that when the switching frequency is 200kHz I can get the maximum duty cycle. I want to know the maximum duty cycle that this chip can provide at the highest switching frequency. Because I want to reduce the inductance, I want to use a chip with a higher switching frequency. Which more suitable models are recommended for me? Please give me some advice, thank you very much!

LDC2114EVM: Can regiser be saved what I want after power on agian ?

$
0
0

Part Number: LDC2114EVM

Hello,

This is Fang from GREE in Zhuhai city.

LDC2114 EVM is used. How to save before value after power on again ? Some steps are below:


1. I chage LC_DIVIDER`s value 0X02(now is 0X02) to 0X04 with GUI tool, it works, and the value I read is correct.
2. But register LC_DIVIDER change back to0X02 (but not default value 0X03) after power on/off. It looks that I can not rewrite.
I try the other registers, the same situation. I am sure I write successfully because I read before power off.

My questions are:
1. Shold all registers refresh the default value after EVM brd power on again? Or it just change back to before value not default?
2. Your mention need MCU if I want. So can some register`s vaule be fixed from factory ? Value will be kept,we dont want to change with I2C.
3. What different between “Registers”tap and “Configureation”tap ?

BR
Thank you

BQ27542-G1: Does BQ27542 have condition to clear accumulated discharge without Cycle Count?

$
0
0

Part Number: BQ27542-G1

Hello,

Following yellow words is condition to clear accumulated discharge in TRM.  What else do you have any condition to clear accumulated discharge?

TRM(SLUUB65A)  "6.1.1.2 Cycle Count One cycle occurs when accumulated discharge ≥ CC Threshold. " and  TRM(SLUUB65A) "6.1.1.3 Cycle Count Threshold The internal register that accumulates the discharge is not cleared at any time except when the internal accumulating register equals the CC Threshold, and increments CycleCount()." 

Regards,


Resume a file in CCS,but it doesn't stop

$
0
0

Part Number: tda2pxevm

Tool/software: TI C/C++ Compiler

Hello everyone!

     I have a question, when I run the file, the console window does not output any informations. For this point, are there some settings about console I did't finish? In the file,I use "AppUtils_printf" to print somethings and include the headfile"app_utils.h". So, what can I do to solve this question? And at the same time, the programe doesn't stop itself.Why is it?

Please help me, thanks!

    

TPS82130: output voltage range

$
0
0

Part Number: TPS82130

Hi Team,

From datasheet, Vref of TPS82130 is 0.8V but recommended output range is from 0.9V min. So just want to check with you if it can output 0.8V to 0.9V and what the reason is if it can only output 0.9V min. Thanks. 

BRs

Given 

Compiler/TDA2PXEVM: Resume a file in CCS,but it doesn't stop

$
0
0

Part Number: TDA2PXEVM

Tool/software: TI C/C++ Compiler

Hi everybody,

       I load a file (.xa15fg) in CCSv7 and resume it, but it doesn't stop. So I try to run it step by step, the program keeps in running without stopping at the code "status=PMLIBCpuIdle(PMHAL_PRCM_PD_STATE_RETENTION)".This file is an example of the SDK, so is the state of this infinite loop normal? If there are something wrong in it ,what can I do to solve it?

Thanks very much!

AWR1843: AWR1843 ORCAD file

$
0
0

Part Number: AWR1843

Dear,

we need AWR1843 ORCAD file, could share to us?

if any, Please advise me.

Thanks,

Best regards,

Tom

DP83TC811R-Q1: can it replace the TJA1101AHN ?

$
0
0

Part Number: DP83TC811R-Q1

hello

we are using TJA1101AHN, if we can use DP83TC811R-Q1 to replace TJA1101AHN completely?

what is the diffrence between them?

Please refer to the enclosure for TJA1101AHN datasheet!

Thanks a lot!

AM3351: Question related to Analog IR Camera Solution

$
0
0

Part Number: AM3351

Hello,

This is Bobby Youn who are working in WPGK.

i have question related to Analog IR Camera Solution for Sitara Processor.

i found link below for Analog Security Camera solution.

www.ti.com/.../camera_surveillance_analog

i think we can't get technical document for link.

is this solution has a EVK and price? if not, is there any Analog IR Camera Soution that has a EVK?

Best Regards,

Bobby Youn,

LM43603-Q1: Maximum value of Tss (Internal soft start time)

$
0
0

Part Number: LM43603-Q1

Hi team 

I don't check Tss maximum value of the LM43603-Q1 as the below.

If I don't apply Css, what is the maximum value of Tss?


INA186: Over voltage on start-up when changing from INA214 to INA186

$
0
0

Part Number: INA186

Hi expert,

My customer is using INA214 for low side current sensing in LLC output, when they switched to INA186 issue occurs.

They have below hardware design for INA214 and INA186 (same hardware):

Rsense=0.5mohm, Rprotect=5ohm, Differential capacitor removed

When using INA186, higher output voltage will be raised and will cause an over-voltage condition in their system (INA214 in the same circuit will not).

They have tried other Rprotect such as 5ohm, 100ohm, 500ohm and 1Kohm but do no hlep.

Output voltage measured on INA output is shown below:

On start up, LLC's DC output voltage raise up to 200V and come back to 0V, INA's output will raise up to 2.58V which will trigger 2V OVP.

CH1 INV+ / CH2 OUT

Thanks

Sheldon

TLV320AIC3254:TLV320AIC3254 driver problem

$
0
0

Part Number: TLV320AIC3254

This side of the main control is RK3288,I2C,I2S is connected, the sound card is also registered. Use EVM board and I2C to write configuration, there is sound out, unplug it. Prove that the hardware is connected, the main problem is driving here.

 

The following is the schematic and code, which of you have done this chip, please give some advice?

/*
 * linux/sound/soc/codecs/tlv320aic32x4.c
 *
 * Copyright 2011 Vista Silicon S.L.
 *
 * Author: Javier Martin <javier.martin@vista-silicon.com>
 *
 * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/i2c.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/regulator/consumer.h>

#include <sound/tlv320aic32x4.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>

#include "tlv320aic32x4.h"

struct aic32x4_rate_divs {
	u32 mclk;
	u32 rate;
	u8 p_val;
	u8 pll_j;
	u16 pll_d;
	u16 dosr;
	u8 ndac;
	u8 mdac;
	u8 aosr;
	u8 nadc;
	u8 madc;
	u8 blck_N;
};

struct aic32x4_priv {
	struct regmap *regmap;
	u32 sysclk;
	u32 power_cfg;
	u32 micpga_routing;
	bool swapdacs;
	int rstn_gpio;
	struct clk *mclk;

	struct regulator *supply_ldo;
	struct regulator *supply_iov;
	struct regulator *supply_dv;
	struct regulator *supply_av;
};

/* 0dB min, 0.5dB steps */
static DECLARE_TLV_DB_SCALE(tlv_step_0_5, 0, 50, 0);
/* -63.5dB min, 0.5dB steps */
static DECLARE_TLV_DB_SCALE(tlv_pcm, -6350, 50, 0);
/* -6dB min, 1dB steps */
static DECLARE_TLV_DB_SCALE(tlv_driver_gain, -600, 100, 0);
/* -12dB min, 0.5dB steps */
static DECLARE_TLV_DB_SCALE(tlv_adc_vol, -1200, 50, 0);

static const struct snd_kcontrol_new aic32x4_snd_controls[] = {
	SOC_DOUBLE_R_S_TLV("PCM Playback Volume", AIC32X4_LDACVOL,
			AIC32X4_RDACVOL, 0, -0x7f, 0x30, 7, 0, tlv_pcm),
	SOC_DOUBLE_R_S_TLV("HP Driver Gain Volume", AIC32X4_HPLGAIN,
			AIC32X4_HPRGAIN, 0, -0x6, 0x1d, 5, 0,
			tlv_driver_gain),
	SOC_DOUBLE_R_S_TLV("LO Driver Gain Volume", AIC32X4_LOLGAIN,
			AIC32X4_LORGAIN, 0, -0x6, 0x1d, 5, 0,
			tlv_driver_gain),
	SOC_DOUBLE_R("HP DAC Playback Switch", AIC32X4_HPLGAIN,
			AIC32X4_HPRGAIN, 6, 0x01, 1),
	SOC_DOUBLE_R("LO DAC Playback Switch", AIC32X4_LOLGAIN,
			AIC32X4_LORGAIN, 6, 0x01, 1),
	SOC_DOUBLE_R("Mic PGA Switch", AIC32X4_LMICPGAVOL,
			AIC32X4_RMICPGAVOL, 7, 0x01, 1),

	SOC_SINGLE("ADCFGA Left Mute Switch", AIC32X4_ADCFGA, 7, 1, 0),
	SOC_SINGLE("ADCFGA Right Mute Switch", AIC32X4_ADCFGA, 3, 1, 0),

	SOC_DOUBLE_R_S_TLV("ADC Level Volume", AIC32X4_LADCVOL,
			AIC32X4_RADCVOL, 0, -0x18, 0x28, 6, 0, tlv_adc_vol),
	SOC_DOUBLE_R_TLV("PGA Level Volume", AIC32X4_LMICPGAVOL,
			AIC32X4_RMICPGAVOL, 0, 0x5f, 0, tlv_step_0_5),

	SOC_SINGLE("Auto-mute Switch", AIC32X4_DACMUTE, 4, 7, 0),

	SOC_SINGLE("AGC Left Switch", AIC32X4_LAGC1, 7, 1, 0),
	SOC_SINGLE("AGC Right Switch", AIC32X4_RAGC1, 7, 1, 0),
	SOC_DOUBLE_R("AGC Target Level", AIC32X4_LAGC1, AIC32X4_RAGC1,
			4, 0x07, 0),
	SOC_DOUBLE_R("AGC Gain Hysteresis", AIC32X4_LAGC1, AIC32X4_RAGC1,
			0, 0x03, 0),
	SOC_DOUBLE_R("AGC Hysteresis", AIC32X4_LAGC2, AIC32X4_RAGC2,
			6, 0x03, 0),
	SOC_DOUBLE_R("AGC Noise Threshold", AIC32X4_LAGC2, AIC32X4_RAGC2,
			1, 0x1F, 0),
	SOC_DOUBLE_R("AGC Max PGA", AIC32X4_LAGC3, AIC32X4_RAGC3,
			0, 0x7F, 0),
	SOC_DOUBLE_R("AGC Attack Time", AIC32X4_LAGC4, AIC32X4_RAGC4,
			3, 0x1F, 0),
	SOC_DOUBLE_R("AGC Decay Time", AIC32X4_LAGC5, AIC32X4_RAGC5,
			3, 0x1F, 0),
	SOC_DOUBLE_R("AGC Noise Debounce", AIC32X4_LAGC6, AIC32X4_RAGC6,
			0, 0x1F, 0),
	SOC_DOUBLE_R("AGC Signal Debounce", AIC32X4_LAGC7, AIC32X4_RAGC7,
			0, 0x0F, 0),
};

static const struct aic32x4_rate_divs aic32x4_divs[] = {
	/*mclk;rate;p_val;pll_j;pll_d;dosr;ndac;mdac;aosr;nadc;madc;blck_N;*/
	/* 8k rate */
	{AIC32X4_FREQ_12000000, 8000, 1, 7, 6800, 768, 5, 3, 128, 5, 18, 24},
	{AIC32X4_FREQ_24000000, 8000, 2, 7, 6800, 768, 15, 1, 64, 45, 4, 24},
	{AIC32X4_FREQ_25000000, 8000, 2, 7, 3728, 768, 15, 1, 64, 45, 4, 24},
	{AIC32X4_FREQ_11289600, 8000, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},
	{AIC32X4_FREQ_12288000, 8000, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},

	/* 11.025k rate */
	{AIC32X4_FREQ_12000000, 11025, 1, 7, 5264, 512, 8, 2, 128, 8, 8, 16},
	{AIC32X4_FREQ_24000000, 11025, 2, 7, 5264, 512, 16, 1, 64, 32, 4, 16},
	{AIC32X4_FREQ_11289600, 11025, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},
	{AIC32X4_FREQ_12288000, 11025, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},

	/* 16k rate */
	{AIC32X4_FREQ_12000000, 16000, 1, 7, 6800, 384, 5, 3, 128, 5, 9, 12},
	{AIC32X4_FREQ_24000000, 16000, 2, 7, 6800, 384, 15, 1, 64, 18, 5, 12},
	{AIC32X4_FREQ_25000000, 16000, 2, 7, 3728, 384, 15, 1, 64, 18, 5, 12},
	{AIC32X4_FREQ_11289600, 16000, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},
	{AIC32X4_FREQ_12288000, 16000, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},

	/* 22.05k rate */
	{AIC32X4_FREQ_12000000, 22050, 1, 7, 5264, 256, 4, 4, 128, 4, 8, 8},
	{AIC32X4_FREQ_24000000, 22050, 2, 7, 5264, 256, 16, 1, 64, 16, 4, 8},
	{AIC32X4_FREQ_25000000, 22050, 2, 7, 2253, 256, 16, 1, 64, 16, 4, 8},
	{AIC32X4_FREQ_11289600, 22000, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},
	{AIC32X4_FREQ_12288000, 22000, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},

	/* 32k rate */
	{AIC32X4_FREQ_12000000, 32000, 1, 7, 1680, 192, 2, 7, 64, 2, 21, 6},
	{AIC32X4_FREQ_24000000, 32000, 2, 7, 1680, 192, 7, 2, 64, 7, 6, 6},
	{AIC32X4_FREQ_11289600, 32000, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},
	{AIC32X4_FREQ_12288000, 32000, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},

	/* 44.1k rate */
	{AIC32X4_FREQ_12000000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},
	{AIC32X4_FREQ_24000000, 44100, 2, 7, 5264, 128, 8, 2, 64, 8, 4, 4},
	{AIC32X4_FREQ_25000000, 44100, 2, 7, 2253, 128, 8, 2, 64, 8, 4, 4},
	{AIC32X4_FREQ_11289600, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},
	{AIC32X4_FREQ_12288000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},

	/* 48k rate */
	{AIC32X4_FREQ_12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4},
	{AIC32X4_FREQ_24000000, 48000, 2, 8, 1920, 128, 8, 2, 64, 8, 4, 4},
	{AIC32X4_FREQ_25000000, 48000, 2, 7, 8643, 128, 8, 2, 64, 8, 4, 4},
	{AIC32X4_FREQ_11289600, 48000, 1, 8, 5264, 128, 2, 8, 128, 2, 8, 4},
	{AIC32X4_FREQ_12288000, 48000, 1, 8, 5264, 128, 2, 8, 128, 2, 8, 4},

};

static const struct snd_kcontrol_new hpl_output_mixer_controls[] = {
	SOC_DAPM_SINGLE("L_DAC Switch", AIC32X4_HPLROUTE, 3, 1, 0),
	SOC_DAPM_SINGLE("IN1_L Switch", AIC32X4_HPLROUTE, 2, 1, 0),
};

static const struct snd_kcontrol_new hpr_output_mixer_controls[] = {
	SOC_DAPM_SINGLE("R_DAC Switch", AIC32X4_HPRROUTE, 3, 1, 0),
	SOC_DAPM_SINGLE("IN1_R Switch", AIC32X4_HPRROUTE, 2, 1, 0),
};

static const struct snd_kcontrol_new lol_output_mixer_controls[] = {
	SOC_DAPM_SINGLE("L_DAC Switch", AIC32X4_LOLROUTE, 3, 1, 0),
};

static const struct snd_kcontrol_new lor_output_mixer_controls[] = {
	SOC_DAPM_SINGLE("R_DAC Switch", AIC32X4_LORROUTE, 3, 1, 0),
};

static const struct snd_kcontrol_new left_input_mixer_controls[] = {
	SOC_DAPM_SINGLE("IN1_L P Switch", AIC32X4_LMICPGAPIN, 6, 1, 0),
	SOC_DAPM_SINGLE("IN2_L P Switch", AIC32X4_LMICPGAPIN, 4, 1, 0),
	SOC_DAPM_SINGLE("IN3_L P Switch", AIC32X4_LMICPGAPIN, 2, 1, 0),
};

static const struct snd_kcontrol_new right_input_mixer_controls[] = {
	SOC_DAPM_SINGLE("IN1_R P Switch", AIC32X4_RMICPGAPIN, 6, 1, 0),
	SOC_DAPM_SINGLE("IN2_R P Switch", AIC32X4_RMICPGAPIN, 4, 1, 0),
	SOC_DAPM_SINGLE("IN3_R P Switch", AIC32X4_RMICPGAPIN, 2, 1, 0),
};

static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = {
	SND_SOC_DAPM_DAC("Left DAC", "Left Playback", AIC32X4_DACSETUP, 7, 0),
	SND_SOC_DAPM_MIXER("HPL Output Mixer", SND_SOC_NOPM, 0, 0,
			   &hpl_output_mixer_controls[0],
			   ARRAY_SIZE(hpl_output_mixer_controls)),
	SND_SOC_DAPM_PGA("HPL Power", AIC32X4_OUTPWRCTL, 5, 0, NULL, 0),

	SND_SOC_DAPM_MIXER("LOL Output Mixer", SND_SOC_NOPM, 0, 0,
			   &lol_output_mixer_controls[0],
			   ARRAY_SIZE(lol_output_mixer_controls)),
	SND_SOC_DAPM_PGA("LOL Power", AIC32X4_OUTPWRCTL, 3, 0, NULL, 0),

	SND_SOC_DAPM_DAC("Right DAC", "Right Playback", AIC32X4_DACSETUP, 6, 0),
	SND_SOC_DAPM_MIXER("HPR Output Mixer", SND_SOC_NOPM, 0, 0,
			   &hpr_output_mixer_controls[0],
			   ARRAY_SIZE(hpr_output_mixer_controls)),
	SND_SOC_DAPM_PGA("HPR Power", AIC32X4_OUTPWRCTL, 4, 0, NULL, 0),
	SND_SOC_DAPM_MIXER("LOR Output Mixer", SND_SOC_NOPM, 0, 0,
			   &lor_output_mixer_controls[0],
			   ARRAY_SIZE(lor_output_mixer_controls)),
	SND_SOC_DAPM_PGA("LOR Power", AIC32X4_OUTPWRCTL, 2, 0, NULL, 0),
	SND_SOC_DAPM_MIXER("Left Input Mixer", SND_SOC_NOPM, 0, 0,
			   &left_input_mixer_controls[0],
			   ARRAY_SIZE(left_input_mixer_controls)),
	SND_SOC_DAPM_MIXER("Right Input Mixer", SND_SOC_NOPM, 0, 0,
			   &right_input_mixer_controls[0],
			   ARRAY_SIZE(right_input_mixer_controls)),
	SND_SOC_DAPM_ADC("Left ADC", "Left Capture", AIC32X4_ADCSETUP, 7, 0),
	SND_SOC_DAPM_ADC("Right ADC", "Right Capture", AIC32X4_ADCSETUP, 6, 0),
	SND_SOC_DAPM_MICBIAS("Mic Bias", AIC32X4_MICBIAS, 6, 0),

	SND_SOC_DAPM_OUTPUT("HPL"),
	SND_SOC_DAPM_OUTPUT("HPR"),
	SND_SOC_DAPM_OUTPUT("LOL"),
	SND_SOC_DAPM_OUTPUT("LOR"),
	SND_SOC_DAPM_INPUT("IN1_L"),
	SND_SOC_DAPM_INPUT("IN1_R"),
	SND_SOC_DAPM_INPUT("IN2_L"),
	SND_SOC_DAPM_INPUT("IN2_R"),
	SND_SOC_DAPM_INPUT("IN3_L"),
	SND_SOC_DAPM_INPUT("IN3_R"),
};

static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = {
	/* Left Output */
	{"HPL Output Mixer", "L_DAC Switch", "Left DAC"},
	{"HPL Output Mixer", "IN1_L Switch", "IN1_L"},

	{"HPL Power", NULL, "HPL Output Mixer"},
	{"HPL", NULL, "HPL Power"},

	{"LOL Output Mixer", "L_DAC Switch", "Left DAC"},

	{"LOL Power", NULL, "LOL Output Mixer"},
	{"LOL", NULL, "LOL Power"},

	/* Right Output */
	{"HPR Output Mixer", "R_DAC Switch", "Right DAC"},
	{"HPR Output Mixer", "IN1_R Switch", "IN1_R"},

	{"HPR Power", NULL, "HPR Output Mixer"},
	{"HPR", NULL, "HPR Power"},

	{"LOR Output Mixer", "R_DAC Switch", "Right DAC"},

	{"LOR Power", NULL, "LOR Output Mixer"},
	{"LOR", NULL, "LOR Power"},

	/* Left input */
	{"Left Input Mixer", "IN1_L P Switch", "IN1_L"},
	{"Left Input Mixer", "IN2_L P Switch", "IN2_L"},
	{"Left Input Mixer", "IN3_L P Switch", "IN3_L"},

	{"Left ADC", NULL, "Left Input Mixer"},

	/* Right Input */
	{"Right Input Mixer", "IN1_R P Switch", "IN1_R"},
	{"Right Input Mixer", "IN2_R P Switch", "IN2_R"},
	{"Right Input Mixer", "IN3_R P Switch", "IN3_R"},

	{"Right ADC", NULL, "Right Input Mixer"},
};

static const struct regmap_range_cfg aic32x4_regmap_pages[] = {
	{
		.selector_reg = 0,
		.selector_mask  = 0xff,
		.window_start = 0,
		.window_len = 128,
		.range_min = 0,
		.range_max = AIC32X4_RMICPGAVOL,
	},
};

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

	.max_register = AIC32X4_RMICPGAVOL,
	.ranges = aic32x4_regmap_pages,
	.num_ranges = ARRAY_SIZE(aic32x4_regmap_pages),
};

static inline int aic32x4_get_divs(int mclk, int rate)
{
	int i;
	
	printk(KERN_ERR "audio mclk is %d \n",mclk);
	printk(KERN_ERR "audio rate is %d \n",rate);

	for (i = 0; i < ARRAY_SIZE(aic32x4_divs); i++) {
		if ((aic32x4_divs[i].rate == rate)
		    && (aic32x4_divs[i].mclk == mclk)) {
			return i;
		}
	}
	printk(KERN_ERR "aic32x4: master clock and sample rate is not supported\n");
	return -EINVAL;
}

static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai,
				  int clk_id, unsigned int freq, int dir)
{
	struct snd_soc_codec *codec = codec_dai->codec;
	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);

	switch (freq) {
	case AIC32X4_FREQ_12000000:
	case AIC32X4_FREQ_24000000:
	case AIC32X4_FREQ_25000000:
	case AIC32X4_FREQ_11289600:
	case AIC32X4_FREQ_12288000:

		aic32x4->sysclk = freq;
		return 0;
	}
	printk(KERN_ERR "aic32x4: invalid frequency to set DAI system clock\n");
	printk(KERN_ERR "audio freq is %d \n",freq);//11289600
	return -EINVAL;
}

static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
{
	struct snd_soc_codec *codec = codec_dai->codec;
	u8 iface_reg_1;
	u8 iface_reg_2;
	u8 iface_reg_3;
	printk(KERN_ERR "aic32x4_set_dai_fmt\n");
	iface_reg_1 = snd_soc_read(codec, AIC32X4_IFACE1);
	iface_reg_1 = iface_reg_1 & ~(3 << 6 | 3 << 2);
	iface_reg_2 = snd_soc_read(codec, AIC32X4_IFACE2);
	iface_reg_2 = 0;
	iface_reg_3 = snd_soc_read(codec, AIC32X4_IFACE3);
	iface_reg_3 = iface_reg_3 & ~(1 << 3);

	/* set master/slave audio interface */
	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBM_CFM:
		iface_reg_1 |= AIC32X4_BCLKMASTER | AIC32X4_WCLKMASTER;
		break;
	case SND_SOC_DAIFMT_CBS_CFS:
		break;
	default:
		printk(KERN_ERR "aic32x4: invalid DAI master/slave interface\n");
		return -EINVAL;
	}

	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		break;
	case SND_SOC_DAIFMT_DSP_A:
		iface_reg_1 |= (AIC32X4_DSP_MODE << AIC32X4_PLLJ_SHIFT);
		iface_reg_3 |= (1 << 3); /* invert bit clock */
		iface_reg_2 = 0x01; /* add offset 1 */
		break;
	case SND_SOC_DAIFMT_DSP_B:
		iface_reg_1 |= (AIC32X4_DSP_MODE << AIC32X4_PLLJ_SHIFT);
		iface_reg_3 |= (1 << 3); /* invert bit clock */
		break;
	case SND_SOC_DAIFMT_RIGHT_J:
		iface_reg_1 |=
			(AIC32X4_RIGHT_JUSTIFIED_MODE << AIC32X4_PLLJ_SHIFT);
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		iface_reg_1 |=
			(AIC32X4_LEFT_JUSTIFIED_MODE << AIC32X4_PLLJ_SHIFT);
		break;
	default:
		printk(KERN_ERR "aic32x4: invalid DAI interface format\n");
		return -EINVAL;
	}

	snd_soc_write(codec, AIC32X4_IFACE1, iface_reg_1);
	snd_soc_write(codec, AIC32X4_IFACE2, iface_reg_2);
	snd_soc_write(codec, AIC32X4_IFACE3, iface_reg_3);

	printk(KERN_ERR "aic32x4_set_dai_fmt\n");
	return 0;
}

static int aic32x4_hw_params(struct snd_pcm_substream *substream,
			     struct snd_pcm_hw_params *params,
			     struct snd_soc_dai *dai)
{
	struct snd_soc_codec *codec = dai->codec;
	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
	u8 data;
	int i;

	i = aic32x4_get_divs(aic32x4->sysclk, params_rate(params));
	if (i < 0) {
		printk(KERN_ERR "aic32x4: sampling rate not supported\n");
		return i;
	}

	/* Use PLL as CODEC_CLKIN and DAC_MOD_CLK as BDIV_CLKIN */
	snd_soc_write(codec, AIC32X4_CLKMUX, AIC32X4_PLLCLKIN);
	snd_soc_write(codec, AIC32X4_IFACE3, AIC32X4_DACMOD2BCLK);

	/* We will fix R value to 1 and will make P & J=K.D as varialble */
	data = snd_soc_read(codec, AIC32X4_PLLPR);
	data &= ~(7 << 4);
	snd_soc_write(codec, AIC32X4_PLLPR,
		      (data | (aic32x4_divs[i].p_val << 4) | 0x01));

	snd_soc_write(codec, AIC32X4_PLLJ, aic32x4_divs[i].pll_j);

	snd_soc_write(codec, AIC32X4_PLLDMSB, (aic32x4_divs[i].pll_d >> 8));
	snd_soc_write(codec, AIC32X4_PLLDLSB,
		      (aic32x4_divs[i].pll_d & 0xff));

	/* NDAC divider value */
	data = snd_soc_read(codec, AIC32X4_NDAC);
	data &= ~(0x7f);
	snd_soc_write(codec, AIC32X4_NDAC, data | aic32x4_divs[i].ndac);

	/* MDAC divider value */
	data = snd_soc_read(codec, AIC32X4_MDAC);
	data &= ~(0x7f);
	snd_soc_write(codec, AIC32X4_MDAC, data | aic32x4_divs[i].mdac);

	/* DOSR MSB & LSB values */
	snd_soc_write(codec, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8);
	snd_soc_write(codec, AIC32X4_DOSRLSB,
		      (aic32x4_divs[i].dosr & 0xff));

	/* NADC divider value */
	data = snd_soc_read(codec, AIC32X4_NADC);
	data &= ~(0x7f);
	snd_soc_write(codec, AIC32X4_NADC, data | aic32x4_divs[i].nadc);

	/* MADC divider value */
	data = snd_soc_read(codec, AIC32X4_MADC);
	data &= ~(0x7f);
	snd_soc_write(codec, AIC32X4_MADC, data | aic32x4_divs[i].madc);

	/* AOSR value */
	snd_soc_write(codec, AIC32X4_AOSR, aic32x4_divs[i].aosr);

	/* BCLK N divider */
	data = snd_soc_read(codec, AIC32X4_BCLKN);
	data &= ~(0x7f);
	snd_soc_write(codec, AIC32X4_BCLKN, data | aic32x4_divs[i].blck_N);

	data = snd_soc_read(codec, AIC32X4_IFACE1);
	data = data & ~(3 << 4);
	switch (params_width(params)) {
	case 16:
		break;
	case 20:
		data |= (AIC32X4_WORD_LEN_20BITS << AIC32X4_DOSRMSB_SHIFT);
		break;
	case 24:
		data |= (AIC32X4_WORD_LEN_24BITS << AIC32X4_DOSRMSB_SHIFT);
		break;
	case 32:
		data |= (AIC32X4_WORD_LEN_32BITS << AIC32X4_DOSRMSB_SHIFT);
		break;
	}
	snd_soc_write(codec, AIC32X4_IFACE1, data);

	if (params_channels(params) == 1) {
		data = AIC32X4_RDAC2LCHN | AIC32X4_LDAC2LCHN;
	} else {
		if (aic32x4->swapdacs)
			data = AIC32X4_RDAC2LCHN | AIC32X4_LDAC2RCHN;
		else
			data = AIC32X4_LDAC2LCHN | AIC32X4_RDAC2RCHN;
	}
	snd_soc_update_bits(codec, AIC32X4_DACSETUP, AIC32X4_DAC_CHAN_MASK,
			data);
	printk(KERN_ERR "data1 is %x \n",data);
	// snd_soc_write(codec, AIC32X4_DACSETUP, 0xD6);
	//printk(KERN_ERR "data2 is %d \n",data);

	printk(KERN_ERR "aic32x4_hw_params\n");
	return 0;
}

static int aic32x4_mute(struct snd_soc_dai *dai, int mute)
{
	struct snd_soc_codec *codec = dai->codec;
	u8 dac_reg;
	printk(KERN_ERR "aic32x4_mute, %d\n", mute);
	dac_reg = snd_soc_read(codec, AIC32X4_DACMUTE) & ~AIC32X4_MUTEON;
	if (mute)
		snd_soc_write(codec, AIC32X4_DACMUTE, dac_reg | AIC32X4_MUTEON);
	else
		snd_soc_write(codec, AIC32X4_DACMUTE, dac_reg);

	return 0;
}

static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
				  enum snd_soc_bias_level level)
{
	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
	int ret;

	switch (level) {
	case SND_SOC_BIAS_ON:
		/* Switch on master clock */
		ret = clk_prepare_enable(aic32x4->mclk);
		if (ret) {
			dev_err(codec->dev, "Failed to enable master clock\n");
			return ret;
		}

		/* Switch on PLL */
		snd_soc_update_bits(codec, AIC32X4_PLLPR,
				    AIC32X4_PLLEN, AIC32X4_PLLEN);

		/* Switch on NDAC Divider */
		snd_soc_update_bits(codec, AIC32X4_NDAC,
				    AIC32X4_NDACEN, AIC32X4_NDACEN);

		/* Switch on MDAC Divider */
		snd_soc_update_bits(codec, AIC32X4_MDAC,
				    AIC32X4_MDACEN, AIC32X4_MDACEN);

		/* Switch on NADC Divider */
		snd_soc_update_bits(codec, AIC32X4_NADC,
				    AIC32X4_NADCEN, AIC32X4_NADCEN);

		/* Switch on MADC Divider */
		snd_soc_update_bits(codec, AIC32X4_MADC,
				    AIC32X4_MADCEN, AIC32X4_MADCEN);

		/* Switch on BCLK_N Divider */
		snd_soc_update_bits(codec, AIC32X4_BCLKN,
				    AIC32X4_BCLKEN, AIC32X4_BCLKEN);
		break;
	case SND_SOC_BIAS_PREPARE:
		break;
	case SND_SOC_BIAS_STANDBY:
		/* Switch off BCLK_N Divider */
		snd_soc_update_bits(codec, AIC32X4_BCLKN,
				    AIC32X4_BCLKEN, 0);

		/* Switch off MADC Divider */
		snd_soc_update_bits(codec, AIC32X4_MADC,
				    AIC32X4_MADCEN, 0);

		/* Switch off NADC Divider */
		snd_soc_update_bits(codec, AIC32X4_NADC,
				    AIC32X4_NADCEN, 0);

		/* Switch off MDAC Divider */
		snd_soc_update_bits(codec, AIC32X4_MDAC,
				    AIC32X4_MDACEN, 0);

		/* Switch off NDAC Divider */
		snd_soc_update_bits(codec, AIC32X4_NDAC,
				    AIC32X4_NDACEN, 0);

		/* Switch off PLL */
		snd_soc_update_bits(codec, AIC32X4_PLLPR,
				    AIC32X4_PLLEN, 0);

		/* Switch off master clock */
		clk_disable_unprepare(aic32x4->mclk);
		break;
	case SND_SOC_BIAS_OFF:
		break;
	}


	printk(KERN_ERR "aic32x4_set_bias_level\n");
	return 0;
}

#define AIC32X4_RATES	SNDRV_PCM_RATE_8000_48000
#define AIC32X4_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
			 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)

static const struct snd_soc_dai_ops aic32x4_ops = {
	.hw_params = aic32x4_hw_params,
	.digital_mute = aic32x4_mute,
	.set_fmt = aic32x4_set_dai_fmt,
	.set_sysclk = aic32x4_set_dai_sysclk,
};

static struct snd_soc_dai_driver aic32x4_dai = {
	.name = "tlv320aic32x4-hifi",
	.playback = {
		     .stream_name = "Playback",
		     .channels_min = 1,
		     .channels_max = 2,
		     .rates = AIC32X4_RATES,
		     .formats = AIC32X4_FORMATS,},
	.capture = {
		    .stream_name = "Capture",
		    .channels_min = 1,
		    .channels_max = 2,
		    .rates = AIC32X4_RATES,
		    .formats = AIC32X4_FORMATS,},
	.ops = &aic32x4_ops,
	.symmetric_rates = 1,
};

static int aic32x4_probe(struct snd_soc_codec *codec)
{
	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
	u32 tmp_reg;

	if (gpio_is_valid(aic32x4->rstn_gpio)) {
		ndelay(10);
		gpio_set_value(aic32x4->rstn_gpio, 1);
	}

	snd_soc_write(codec, AIC32X4_RESET, 0x01);

	/* Power platform configuration */
	if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) {
		snd_soc_write(codec, AIC32X4_MICBIAS, AIC32X4_MICBIAS_LDOIN |
						      AIC32X4_MICBIAS_2075V);
	}
	if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE)
		snd_soc_write(codec, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE);

	tmp_reg = (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) ?
			AIC32X4_LDOCTLEN : 0;
	snd_soc_write(codec, AIC32X4_LDOCTL, tmp_reg);

	tmp_reg = snd_soc_read(codec, AIC32X4_CMMODE);
	if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36)
		tmp_reg |= AIC32X4_LDOIN_18_36;
	if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED)
		tmp_reg |= AIC32X4_LDOIN2HP;
	snd_soc_write(codec, AIC32X4_CMMODE, tmp_reg);

	/* Mic PGA routing */
	if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K)
		snd_soc_write(codec, AIC32X4_LMICPGANIN,
				AIC32X4_LMICPGANIN_IN2R_10K);
	else
		snd_soc_write(codec, AIC32X4_LMICPGANIN,
				AIC32X4_LMICPGANIN_CM1L_10K);
	if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K)
		snd_soc_write(codec, AIC32X4_RMICPGANIN,
				AIC32X4_RMICPGANIN_IN1L_10K);
	else
		snd_soc_write(codec, AIC32X4_RMICPGANIN,
				AIC32X4_RMICPGANIN_CM1R_10K);

	/*
	 * Workaround: for an unknown reason, the ADC needs to be powered up
	 * and down for the first capture to work properly. It seems related to
	 * a HW BUG or some kind of behavior not documented in the datasheet.
	 */
	tmp_reg = snd_soc_read(codec, AIC32X4_ADCSETUP);
	snd_soc_write(codec, AIC32X4_ADCSETUP, tmp_reg |
				AIC32X4_LADC_EN | AIC32X4_RADC_EN);
	snd_soc_write(codec, AIC32X4_ADCSETUP, tmp_reg);


	/* beep*/
	snd_soc_write(codec, 0x49, 0xff);
	snd_soc_write(codec, 0x4a, 0xff);
	snd_soc_write(codec, 0x47, 0x80);

		/*from EVM code */
	snd_soc_write(codec, 0x00, 0x00);
	snd_soc_write(codec, 0x01, 0x01);
	snd_soc_write(codec, 0x00, 0x00);
	snd_soc_write(codec, 0x0b, 0x81);
	snd_soc_write(codec, 0x0c, 0x82);
	snd_soc_write(codec, 0x00, 0x00);
	snd_soc_write(codec, 0x3c, 0x08);
	snd_soc_write(codec, 0x00, 0x01);
	snd_soc_write(codec, 0x01, 0x08);
	snd_soc_write(codec, 0x02, 0x00);
	snd_soc_write(codec, 0x47, 0x32);
	snd_soc_write(codec, 0x7b, 0x01);
	snd_soc_write(codec, 0x00, 0x01);
	snd_soc_write(codec, 0x14, 0x25);
	snd_soc_write(codec, 0x0c, 0x08);
	snd_soc_write(codec, 0x0d, 0x08);
	snd_soc_write(codec, 0x0e, 0x08);
	snd_soc_write(codec, 0x0f, 0x08);
	snd_soc_write(codec, 0x09, 0x3c);
	snd_soc_write(codec, 0x10, 0x00);
	snd_soc_write(codec, 0x11, 0x00);
	snd_soc_write(codec, 0x12, 0x00);
	snd_soc_write(codec, 0x13, 0x00);
	snd_soc_write(codec, 0x00, 0x00);
	snd_soc_write(codec, 0x41, 0x00);
	snd_soc_write(codec, 0x42, 0x00);
	snd_soc_write(codec, 0x3f, 0xd6);
	snd_soc_write(codec, 0x40, 0x00);

	printk(KERN_ERR "aic32x4_probe\n");
	return 0;
}

static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = {
	.probe = aic32x4_probe,
	.set_bias_level = aic32x4_set_bias_level,
	.suspend_bias_off = true,

	.controls = aic32x4_snd_controls,
	.num_controls = ARRAY_SIZE(aic32x4_snd_controls),
	.dapm_widgets = aic32x4_dapm_widgets,
	.num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets),
	.dapm_routes = aic32x4_dapm_routes,
	.num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes),
};

static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4,
		struct device_node *np)
{
	aic32x4->swapdacs = false;
	aic32x4->micpga_routing = 0;
	aic32x4->rstn_gpio = of_get_named_gpio(np, "reset-gpios", 0);

	return 0;
}

static void aic32x4_disable_regulators(struct aic32x4_priv *aic32x4)
{
	regulator_disable(aic32x4->supply_iov);

	if (!IS_ERR(aic32x4->supply_ldo))
		regulator_disable(aic32x4->supply_ldo);

	if (!IS_ERR(aic32x4->supply_dv))
		regulator_disable(aic32x4->supply_dv);

	if (!IS_ERR(aic32x4->supply_av))
		regulator_disable(aic32x4->supply_av);
}

static int aic32x4_setup_regulators(struct device *dev,
		struct aic32x4_priv *aic32x4)
{
	int ret = 0;

	aic32x4->supply_ldo = devm_regulator_get_optional(dev, "ldoin");
	aic32x4->supply_iov = devm_regulator_get(dev, "iov");
	aic32x4->supply_dv = devm_regulator_get_optional(dev, "dv");
	aic32x4->supply_av = devm_regulator_get_optional(dev, "av");

	/* Check if the regulator requirements are fulfilled */

	if (IS_ERR(aic32x4->supply_iov)) {
		dev_err(dev, "Missing supply 'iov'\n");
		return PTR_ERR(aic32x4->supply_iov);
	}

	if (IS_ERR(aic32x4->supply_ldo)) {
		if (PTR_ERR(aic32x4->supply_ldo) == -EPROBE_DEFER)
			return -EPROBE_DEFER;

		if (IS_ERR(aic32x4->supply_dv)) {
			dev_err(dev, "Missing supply 'dv' or 'ldoin'\n");
			return PTR_ERR(aic32x4->supply_dv);
		}
		if (IS_ERR(aic32x4->supply_av)) {
			dev_err(dev, "Missing supply 'av' or 'ldoin'\n");
			return PTR_ERR(aic32x4->supply_av);
		}
	} else {
		if (IS_ERR(aic32x4->supply_dv) &&
				PTR_ERR(aic32x4->supply_dv) == -EPROBE_DEFER)
			return -EPROBE_DEFER;
		if (IS_ERR(aic32x4->supply_av) &&
				PTR_ERR(aic32x4->supply_av) == -EPROBE_DEFER)
			return -EPROBE_DEFER;
	}

	ret = regulator_enable(aic32x4->supply_iov);
	if (ret) {
		dev_err(dev, "Failed to enable regulator iov\n");
		return ret;
	}

	if (!IS_ERR(aic32x4->supply_ldo)) {
		ret = regulator_enable(aic32x4->supply_ldo);
		if (ret) {
			dev_err(dev, "Failed to enable regulator ldo\n");
			goto error_ldo;
		}
	}

	if (!IS_ERR(aic32x4->supply_dv)) {
		ret = regulator_enable(aic32x4->supply_dv);
		if (ret) {
			dev_err(dev, "Failed to enable regulator dv\n");
			goto error_dv;
		}
	}

	if (!IS_ERR(aic32x4->supply_av)) {
		ret = regulator_enable(aic32x4->supply_av);
		if (ret) {
			dev_err(dev, "Failed to enable regulator av\n");
			goto error_av;
		}
	}

	if (!IS_ERR(aic32x4->supply_ldo) && IS_ERR(aic32x4->supply_av))
		aic32x4->power_cfg |= AIC32X4_PWR_AIC32X4_LDO_ENABLE;

	return 0;

error_av:
	if (!IS_ERR(aic32x4->supply_dv))
		regulator_disable(aic32x4->supply_dv);

error_dv:
	if (!IS_ERR(aic32x4->supply_ldo))
		regulator_disable(aic32x4->supply_ldo);

error_ldo:
	regulator_disable(aic32x4->supply_iov);
	return ret;
}

static int aic32x4_i2c_probe(struct i2c_client *i2c,
			     const struct i2c_device_id *id)
{
	struct aic32x4_pdata *pdata = i2c->dev.platform_data;
	struct aic32x4_priv *aic32x4;
	struct device_node *np = i2c->dev.of_node;
	int ret;

	aic32x4 = devm_kzalloc(&i2c->dev, sizeof(struct aic32x4_priv),
			       GFP_KERNEL);
	if (aic32x4 == NULL)
		return -ENOMEM;

	aic32x4->regmap = devm_regmap_init_i2c(i2c, &aic32x4_regmap);
	if (IS_ERR(aic32x4->regmap))
		return PTR_ERR(aic32x4->regmap);

	i2c_set_clientdata(i2c, aic32x4);

	if (pdata) {
		aic32x4->power_cfg = pdata->power_cfg;
		aic32x4->swapdacs = pdata->swapdacs;
		aic32x4->micpga_routing = pdata->micpga_routing;
		aic32x4->rstn_gpio = pdata->rstn_gpio;
	} else if (np) {
		ret = aic32x4_parse_dt(aic32x4, np);
		if (ret) {
			dev_err(&i2c->dev, "Failed to parse DT node\n");
			return ret;
		}
	} else {
		aic32x4->power_cfg = 0;
		aic32x4->swapdacs = false;
		aic32x4->micpga_routing = 0;
		aic32x4->rstn_gpio = -1;
	}

	aic32x4->mclk = devm_clk_get(&i2c->dev, "mclk");
	if (IS_ERR(aic32x4->mclk)) {
		dev_err(&i2c->dev, "Failed getting the mclk. The current implementation does not support the usage of this codec without mclk\n");
		return PTR_ERR(aic32x4->mclk);
	}

	if (gpio_is_valid(aic32x4->rstn_gpio)) {
		ret = devm_gpio_request_one(&i2c->dev, aic32x4->rstn_gpio,
				GPIOF_OUT_INIT_LOW, "tlv320aic32x4 rstn");
		if (ret != 0)
			return ret;
	}

	ret = aic32x4_setup_regulators(&i2c->dev, aic32x4);
	if (ret) {
		dev_err(&i2c->dev, "Failed to setup regulators\n");
		return ret;
	}

	ret = snd_soc_register_codec(&i2c->dev,
			&soc_codec_dev_aic32x4, &aic32x4_dai, 1);
	if (ret) {
		dev_err(&i2c->dev, "Failed to register codec\n");
		aic32x4_disable_regulators(aic32x4);
		return ret;
	}

	i2c_set_clientdata(i2c, aic32x4);
	return 0;
}

static int aic32x4_i2c_remove(struct i2c_client *client)
{
	struct aic32x4_priv *aic32x4 = i2c_get_clientdata(client);

	aic32x4_disable_regulators(aic32x4);

	snd_soc_unregister_codec(&client->dev);
	return 0;
}

static const struct i2c_device_id aic32x4_i2c_id[] = {
	{ "tlv320aic32x4", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, aic32x4_i2c_id);

static const struct of_device_id aic32x4_of_id[] = {
	{ .compatible = "ti,tlv320aic32x4", },
	{ /* senitel */ }
};
MODULE_DEVICE_TABLE(of, aic32x4_of_id);

static struct i2c_driver aic32x4_i2c_driver = {
	.driver = {
		.name = "tlv320aic32x4",
		.of_match_table = aic32x4_of_id,
	},
	.probe =    aic32x4_i2c_probe,
	.remove =   aic32x4_i2c_remove,
	.id_table = aic32x4_i2c_id,
};

module_i2c_driver(aic32x4_i2c_driver);

MODULE_DESCRIPTION("ASoC tlv320aic32x4 codec driver");
MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
MODULE_LICENSE("GPL");

 

TCAN1042HGV: TCAN1042HGV IF Vcc dely to VIO 100ms will be shunt down

$
0
0

Part Number: TCAN1042HGV

Dear,

We find some question about TCAN1042HGV , IF Vcc dely to VIO 100ms will be shunt down.

below as schematic:

If any  suggestion, Please advise me.

Thanks,

Best regards,

Tom

MSP432P401R: Trouble sourcing example source code

$
0
0

Part Number: MSP432P401R

Hi, I'm trying to do things pretty similar to the OP in the linked thread, but the source code it links to is no longer at that URL (I'm guessing the maintenance error message is misleading), how can I get a copy of that source code?

Link for reference:

software-dl.ti.com/.../MSP432BSL_1_00_00_00.zip

TAS5805MEVM: TAS5805EVM board PPC3 using problem

$
0
0

Part Number: TAS5805MEVM

Hi,

I encounter a problem of using PPC3 :(mono 1.1 mode is selected)

1. How to fractional frequency between the high and low pitch tones? Woofer is used for low pitch tones, can use crossover to adjust, and tweetier is used for high pitch tones. However, there is no crossover option but EQ. So how to adjust high pitch tones?

2. If EQ is used to regulate high-pitched tones, then EQ regulation will affect the regulation of woofer's crossover. How to solve this problem?

3. If woofer connect to high pitch tones(use EQ to adjust), and tweetier connect to low pitch tones(use crossover to adjust), these two will not affect each other, will there be any problem with this testing method?

Thank you very much!

Best regards

Mason

Viewing all 262198 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>